|
|
|
|
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.time.ZoneOffset;
|
|
|
|
|
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分钟执行一次
|
|
|
|
|
*/
|
|
|
|
|
@Scheduled(cron = "0 */15 * * * ?")// 每15分钟执行一次
|
|
|
|
|
@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(ZoneOffset.UTC).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(ZoneOffset.UTC)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
// 🔥 关键修改:确保负责人信息保留
|
|
|
|
|
if (currentManager != null) {
|
|
|
|
|
// 更新负责人信息的更新时间,但不改变负责人本身
|
|
|
|
|
boolean managerUpdated = supplyUsersManagementsMapper.updateManagerUpdateTime(
|
|
|
|
|
customer.getUserId(), LocalDateTime.now(ZoneOffset.UTC));
|
|
|
|
|
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(ZoneOffset.UTC).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(ZoneOffset.UTC)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
// 🔥 关键修改:确保负责人信息保留
|
|
|
|
|
if (currentManager != null) {
|
|
|
|
|
// 更新负责人信息的更新时间,但不改变负责人本身
|
|
|
|
|
boolean managerUpdated = supplyUsersManagementsMapper.updateManagerUpdateTime(
|
|
|
|
|
customer.getUserId(), LocalDateTime.now(ZoneOffset.UTC));
|
|
|
|
|
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(ZoneOffset.UTC).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;
|
|
|
|
|
}
|
|
|
|
|
}
|