You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
9.0 KiB

3 months ago
package com.example.web.service;
import com.example.web.dto.UserProductCartDTO;
import com.example.web.entity.UsersManagements;
import com.example.web.mapper.SupplyUsersMapper;
import com.example.web.mapper.SupplyUsersManagementsMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.time.LocalDateTime;
import java.util.List;
@Service
@RequiredArgsConstructor
public class SupplyCustomerRecycleService {
private static final Logger log = LoggerFactory.getLogger(SupplyCustomerRecycleService.class);
@Autowired
private SupplyUsersManagementsMapper supplyUsersManagementsMapper;
@Autowired
private SupplyUsersMapper supplyUsersMapper;
// 从配置文件注入回流时间配置
@Value("${app.recycle.unclassified-to-organization-days:30}")
private int unclassifiedToOrganizationDays;
@Value("${app.recycle.organization-to-department-days:30}")
private int organizationToDepartmentDays;
/**
* 客户回流定时任务 - 每15分钟执行一次
3 months ago
*/
@Scheduled(cron = "0 */15 * * * ?")
3 months ago
@Transactional(rollbackFor = Exception.class)
public void autoRecycleCustomers() {
log.info("🎯 开始执行客户回流任务...");
log.info("📅 回流配置 - 未分级->组织公海池: {}天, 组织->部门公海池: {}天",
unclassifiedToOrganizationDays, organizationToDepartmentDays);
try {
// 1. 未分级客户回流到组织公海池
recycleUnclassifiedToOrganization();
// 2. 组织公海池客户回流到部门公海池
recycleOrganizationToDepartment();
log.info("✅ 客户回流任务执行完成");
} catch (Exception e) {
log.error("❌ 客户回流任务执行失败", e);
throw e; // 抛出异常确保事务回滚
}
}
/**
* 未分级客户回流到组织公海池 - 修复保留负责人信息
*/
private void recycleUnclassifiedToOrganization() {
log.info("🔄 开始处理未分级客户回流...");
LocalDateTime thresholdTime = LocalDateTime.now().minusDays(unclassifiedToOrganizationDays);
// 查询超过指定天数未更新的未分级客户
List<UserProductCartDTO> unclassifiedCustomers = supplyUsersMapper.findUnclassifiedCustomersOlderThan(thresholdTime);
log.info("📊 找到 {} 个需要回流的未分级客户 (阈值: {}天前)",
unclassifiedCustomers.size(), unclassifiedToOrganizationDays);
int recycledCount = 0;
for (UserProductCartDTO customer : unclassifiedCustomers) {
try {
// 🔥 关键修改:先查询当前的负责人信息
UsersManagements currentManager = supplyUsersManagementsMapper.findByUserId(customer.getUserId());
log.info("🔍 客户 {} 当前负责人信息: {}", customer.getUserId(),
currentManager != null ? currentManager.getUserName() : "无负责人");
// 更新客户等级为组织公海池
boolean success = supplyUsersMapper.updateCustomerLevel(
customer.getUserId(),
"organization-sea-pools",
LocalDateTime.now()
);
if (success) {
// 🔥 关键修改:确保负责人信息保留
if (currentManager != null) {
// 更新负责人信息的更新时间,但不改变负责人本身
boolean managerUpdated = supplyUsersManagementsMapper.updateManagerUpdateTime(
customer.getUserId(), LocalDateTime.now());
log.info("✅ 客户 {} 负责人信息已保留: {}", customer.getUserId(),
managerUpdated ? "成功" : "失败");
}
recycledCount++;
log.info("🔄 客户 {} 从未分级回流到组织公海池, 负责人: {}",
customer.getUserId(),
currentManager != null ? currentManager.getUserName() : "无");
}
} catch (Exception e) {
log.error("❌ 回流客户失败: {}", customer.getUserId(), e);
}
}
log.info("✅ 未分级客户回流完成: {} 个客户已回流到组织公海池", recycledCount);
}
/**
* 组织公海池客户回流到部门公海池 - 修复保留负责人信息
*/
private void recycleOrganizationToDepartment() {
log.info("🔄 开始处理组织公海池客户回流...");
LocalDateTime thresholdTime = LocalDateTime.now().minusDays(organizationToDepartmentDays);
// 查询超过指定天数未更新的组织公海池客户
List<UserProductCartDTO> organizationCustomers = supplyUsersMapper.findOrganizationSeaPoolsCustomersOlderThan(thresholdTime);
log.info("📊 找到 {} 个需要回流的组织公海池客户 (阈值: {}天前)",
organizationCustomers.size(), organizationToDepartmentDays);
int recycledCount = 0;
for (UserProductCartDTO customer : organizationCustomers) {
try {
// 🔥 关键修改:先查询当前的负责人信息
UsersManagements currentManager = supplyUsersManagementsMapper.findByUserId(customer.getUserId());
log.info("🔍 客户 {} 当前负责人信息: {}", customer.getUserId(),
currentManager != null ? currentManager.getUserName() : "无负责人");
// 更新客户等级为部门公海池
boolean success = supplyUsersMapper.updateCustomerLevel(
customer.getUserId(),
"department-sea-pools",
LocalDateTime.now()
);
if (success) {
// 🔥 关键修改:确保负责人信息保留
if (currentManager != null) {
// 更新负责人信息的更新时间,但不改变负责人本身
boolean managerUpdated = supplyUsersManagementsMapper.updateManagerUpdateTime(
customer.getUserId(), LocalDateTime.now());
log.info("✅ 客户 {} 负责人信息已保留: {}", customer.getUserId(),
managerUpdated ? "成功" : "失败");
}
recycledCount++;
log.info("🔄 客户 {} 从组织公海池回流到部门公海池, 负责人: {}",
customer.getUserId(),
currentManager != null ? currentManager.getUserName() : "无");
}
} catch (Exception e) {
log.error("❌ 回流客户失败: {}", customer.getUserId(), e);
}
}
log.info("✅ 组织公海池客户回流完成: {} 个客户已回流到部门公海池", recycledCount);
}
/**
* 手动触发回流任务用于测试或手动执行
*/
public void manualRecycle() {
log.info("🔧 手动触发客户回流任务...");
autoRecycleCustomers();
}
/**
* 获取当前回流配置信息用于调试或监控
*/
public String getRecycleConfigInfo() {
return String.format("回流配置 - 未分级->组织公海池: %d天, 组织->部门公海池: %d天",
unclassifiedToOrganizationDays, organizationToDepartmentDays);
}
/**
* 🔥 新增获取回流客户完整信息用于前端显示
*/
public List<UserProductCartDTO> getRecycledCustomersWithManagerInfo() {
log.info("🔍 获取回流客户完整信息(包含负责人信息)");
// 获取最近回流的客户(例如最近1天内回流的)
LocalDateTime sinceTime = LocalDateTime.now().minusDays(1);
List<UserProductCartDTO> recycledCustomers = supplyUsersMapper.findRecentlyRecycledCustomers(sinceTime);
// 为每个客户加载负责人信息
for (UserProductCartDTO customer : recycledCustomers) {
UsersManagements manager = supplyUsersManagementsMapper.findByUserId(customer.getUserId());
if (manager != null) {
// 将负责人信息设置到DTO中(需要扩展UserProductCartDTO或使用其他方式)
log.info("✅ 客户 {} 回流后负责人信息: {}", customer.getUserId(), manager.getUserName());
}
}
log.info("📊 获取到 {} 个回流客户的完整信息", recycledCustomers.size());
return recycledCustomers;
}
}