package com.rj.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.rj.dto.LbFanSimulateLoginRequest; import com.rj.dto.hxr.HxrUserLoginApiContext; import com.rj.entity.LbFanManagement; import com.rj.mapper.LbFanManagementMapper; import com.rj.service.HxrAdminUserLoginService; import com.rj.service.ILbFanManagementService; import com.rj.service.ILbThirdIntegrationConfigService; import com.rj.tenant.TenantContextHolder; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; /** * 粉丝管理服务实现 */ @Slf4j @Service public class LbFanManagementServiceImpl extends ServiceImpl implements ILbFanManagementService { @Autowired private ILbThirdIntegrationConfigService lbThirdIntegrationConfigService; @Autowired private HxrAdminUserLoginService hxrAdminUserLoginService; private static final String DEFAULT_SIMULATE_LOGIN_PASSWORD = "123456"; private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Override public Map add(LbFanManagement entity) { Map result = new HashMap<>(); try { trimStringFields(entity); fillTenantIdIfAbsent(entity); Map keyError = validateCompositeKey(entity); if (keyError != null) { return keyError; } Map idTenantError = fillAndValidateIdTenantId(entity); if (idTenantError != null) { return idTenantError; } if (existsByIdTenantId(entity.getIdTenantId())) { result.put("success", false); result.put("message", "唯一ID已存在:" + entity.getIdTenantId()); return result; } if (entity.getShareNum() == null) { entity.setShareNum(0); } if (entity.getCreatedAt() == null) { entity.setCreatedAt(LocalDateTime.now()); } boolean ok = this.save(entity); result.put("success", ok); result.put("message", ok ? "新增成功" : "新增失败"); if (ok) { result.put("data", entity); } return result; } catch (DuplicateKeyException e) { log.warn("粉丝管理新增重复键, idTenantId={}", entity.getIdTenantId()); result.put("success", false); result.put("message", "唯一ID已存在:" + entity.getIdTenantId()); return result; } catch (Exception e) { log.error("粉丝管理新增异常", e); result.put("success", false); result.put("message", "新增异常:" + e.getMessage()); return result; } } @Override public Map update(LbFanManagement entity) { Map result = new HashMap<>(); try { trimStringFields(entity); fillTenantIdIfAbsent(entity); Map keyError = validateCompositeKey(entity); if (keyError != null) { return keyError; } Map idTenantError = fillAndValidateIdTenantId(entity); if (idTenantError != null) { return idTenantError; } LbFanManagement existing = this.getById(entity.getIdTenantId()); if (existing == null) { result.put("success", false); result.put("message", "记录不存在,id_tenant_id=" + entity.getIdTenantId()); return result; } if (entity.getCreatedAt() == null) { entity.setCreatedAt(existing.getCreatedAt()); } // 唯一主键与联合键字段不可变更 entity.setIdTenantId(existing.getIdTenantId()); entity.setTenantId(existing.getTenantId()); entity.setId(existing.getId()); boolean ok = this.updateById(entity); result.put("success", ok); result.put("message", ok ? "修改成功" : "修改失败"); if (ok) { result.put("data", this.getById(entity.getIdTenantId())); } return result; } catch (Exception e) { log.error("粉丝管理修改异常", e); result.put("success", false); result.put("message", "修改异常:" + e.getMessage()); return result; } } @Override public Map deleteByIdTenantId(String idTenantId) { Map result = new HashMap<>(); try { if (idTenantId == null || idTenantId.trim().isEmpty()) { result.put("success", false); result.put("message", "唯一ID(id_tenant_id)不能为空"); return result; } String key = idTenantId.trim(); boolean ok = this.removeById(key); result.put("success", ok); result.put("message", ok ? "删除成功" : "删除失败,记录可能不存在"); return result; } catch (Exception e) { log.error("粉丝管理删除异常, idTenantId={}", idTenantId, e); result.put("success", false); result.put("message", "删除异常:" + e.getMessage()); return result; } } @Override public Map pageQuery(Integer current, Integer size, String nickname, String mobile, Integer shareNumMin, Integer shareNumMax, String createdAtStart, String createdAtEnd) { Map result = new HashMap<>(); try { if (current == null || current < 1) { current = 1; } if (size == null || size < 1) { size = 10; } LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); if (nickname != null && !nickname.trim().isEmpty()) { queryWrapper.like(LbFanManagement::getNickname, nickname.trim()); } if (mobile != null && !mobile.trim().isEmpty()) { queryWrapper.like(LbFanManagement::getMobile, mobile.trim()); } if (shareNumMin != null) { queryWrapper.ge(LbFanManagement::getShareNum, shareNumMin); } if (shareNumMax != null) { queryWrapper.le(LbFanManagement::getShareNum, shareNumMax); } LocalDateTime start = parseDateTime(createdAtStart); if (createdAtStart != null && !createdAtStart.trim().isEmpty() && start == null) { result.put("success", false); result.put("message", "createdAtStart 格式错误,请使用 yyyy-MM-dd HH:mm:ss"); return result; } LocalDateTime end = parseDateTime(createdAtEnd); if (createdAtEnd != null && !createdAtEnd.trim().isEmpty() && end == null) { result.put("success", false); result.put("message", "createdAtEnd 格式错误,请使用 yyyy-MM-dd HH:mm:ss"); return result; } if (start != null) { queryWrapper.ge(LbFanManagement::getCreatedAt, start); } if (end != null) { queryWrapper.le(LbFanManagement::getCreatedAt, end); } queryWrapper.orderByDesc(LbFanManagement::getCreatedAt); Page page = this.page(new Page<>(current, size), queryWrapper); result.put("success", true); result.put("message", "查询成功"); result.put("data", page.getRecords()); result.put("total", page.getTotal()); result.put("current", page.getCurrent()); result.put("size", page.getSize()); result.put("pages", page.getPages()); return result; } catch (Exception e) { log.error("粉丝管理分页查询异常", e); result.put("success", false); result.put("message", "查询异常:" + e.getMessage()); return result; } } @Override public Map simulateLogin(LbFanSimulateLoginRequest request) { Map result = new HashMap<>(); try { if (request == null) { result.put("success", false); result.put("message", "请求体不能为空"); return result; } if (request.getTenantId() == null || request.getTenantId().trim().isEmpty()) { result.put("success", false); result.put("message", "tenantId不能为空"); return result; } if (request.getMobiles() == null || request.getMobiles().isEmpty()) { result.put("success", false); result.put("message", "手机号列表不能为空"); return result; } String tenantId = request.getTenantId().trim(); Optional ctxOpt = lbThirdIntegrationConfigService.resolveUserLoginApiContext(tenantId); if (ctxOpt.isEmpty()) { result.put("success", false); result.put("message", "未找到该租户的第三方集成配置,或配置未启用、URL 不完整(请检查 lb_third_integration_config)"); return result; } HxrUserLoginApiContext ctx = ctxOpt.get(); List> items = new ArrayList<>(); int successCount = 0; int failCount = 0; String requestPassword = request.getPassword() != null ? request.getPassword().trim() : ""; for (String rawMobile : request.getMobiles()) { Map item = new LinkedHashMap<>(); if (rawMobile == null || rawMobile.trim().isEmpty()) { item.put("mobile", rawMobile); item.put("loginSuccess", false); item.put("apiCode", -1); item.put("apiMsg", "手机号为空"); items.add(item); failCount++; continue; } String mobile = rawMobile.trim(); item.put("mobile", mobile); String password = !requestPassword.isEmpty() ? requestPassword : DEFAULT_SIMULATE_LOGIN_PASSWORD; try { HxrAdminUserLoginService.LoginApiResult loginResult = hxrAdminUserLoginService.login(mobile, password, ctx); item.put("httpStatus", loginResult.httpStatus()); item.put("apiCode", loginResult.apiCode()); item.put("apiMsg", loginResult.apiMsg()); item.put("loginSuccess", loginResult.success()); item.put("parsed", loginResult.parsed()); if (loginResult.success()) { successCount++; } else { failCount++; } } catch (Exception e) { log.warn("粉丝模拟登录异常 mobile={} tenantId={}", mobile, tenantId, e); item.put("loginSuccess", false); item.put("apiCode", -1); item.put("apiMsg", "请求异常:" + e.getMessage()); failCount++; } items.add(item); } result.put("success", true); result.put("message", "模拟登录完成"); result.put("data", items); result.put("successCount", successCount); result.put("failCount", failCount); result.put("loginApiUrl", ctx.loginApiUrl()); return result; } catch (Exception e) { log.error("粉丝模拟登录异常", e); result.put("success", false); result.put("message", "模拟登录异常:" + e.getMessage()); return result; } } /** * 生成唯一ID:id + '_' + tenant_id */ public static String buildIdTenantId(Long id, String tenantId) { return id + "_" + tenantId; } private Map validateCompositeKey(LbFanManagement entity) { Map result = new HashMap<>(); if (entity.getTenantId() == null || entity.getTenantId().trim().isEmpty()) { result.put("success", false); result.put("message", "租户ID不能为空"); return result; } if (entity.getId() == null) { result.put("success", false); result.put("message", "粉丝ID不能为空"); return result; } return null; } /** * 填充 id_tenant_id,并与传入值校验一致。 */ private Map fillAndValidateIdTenantId(LbFanManagement entity) { Map result = new HashMap<>(); String expected = buildIdTenantId(entity.getId(), entity.getTenantId()); if (entity.getIdTenantId() == null || entity.getIdTenantId().trim().isEmpty()) { entity.setIdTenantId(expected); return null; } String actual = entity.getIdTenantId().trim(); if (!expected.equals(actual)) { result.put("success", false); result.put("message", "id_tenant_id 与 id、tenant_id 不一致,应为:" + expected); return result; } entity.setIdTenantId(actual); return null; } private boolean existsByIdTenantId(String idTenantId) { return this.getById(idTenantId) != null; } private void fillTenantIdIfAbsent(LbFanManagement entity) { if (entity.getTenantId() == null || entity.getTenantId().trim().isEmpty()) { String tenantId = TenantContextHolder.getTenantId(); if (tenantId != null && !tenantId.trim().isEmpty()) { entity.setTenantId(tenantId.trim()); } } } private void trimStringFields(LbFanManagement entity) { if (entity.getIdTenantId() != null) { entity.setIdTenantId(entity.getIdTenantId().trim()); } if (entity.getTenantId() != null) { entity.setTenantId(entity.getTenantId().trim()); } if (entity.getAvatar() != null) { entity.setAvatar(entity.getAvatar().trim()); } if (entity.getNickname() != null) { entity.setNickname(entity.getNickname().trim()); } if (entity.getMobile() != null) { entity.setMobile(entity.getMobile().trim()); } } private LocalDateTime parseDateTime(String text) { if (text == null || text.trim().isEmpty()) { return null; } try { return LocalDateTime.parse(text.trim(), DATE_TIME_FORMATTER); } catch (Exception e) { return null; } } }