0318-海宁菜单调整+北仑客群部分开发
This commit is contained in:
@@ -50,14 +50,14 @@ public class CustGroupController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客群详情
|
||||
* 根据ID查询客群详情
|
||||
*/
|
||||
@ApiOperation("获取客群详情")
|
||||
@Log(title = "客群管理-获取客群详情")
|
||||
@ApiOperation("根据ID查询客群详情")
|
||||
@Log(title = "客群管理-查询客群详情")
|
||||
@GetMapping("/{id}")
|
||||
public AjaxResult getCustGroup(@PathVariable Long id) {
|
||||
CustGroupVO vo = custGroupService.getCustGroup(id);
|
||||
return AjaxResult.success(vo);
|
||||
CustGroupVO custGroup = custGroupService.getCustGroup(id);
|
||||
return AjaxResult.success(custGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,17 +83,6 @@ public class CustGroupController extends BaseController {
|
||||
return AjaxResult.success(custGroupService.createCustGroupByTemplate(custGroup, file));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新客群
|
||||
*/
|
||||
@ApiOperation("更新客群")
|
||||
@Log(title = "客群管理-更新客群", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
public AjaxResult updateCustGroup(@RequestBody @Valid CustGroup custGroup) {
|
||||
String result = custGroupService.updateCustGroup(custGroup);
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新客群(网格导入)
|
||||
*/
|
||||
@@ -150,15 +139,4 @@ public class CustGroupController extends BaseController {
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动移除客群客户
|
||||
*/
|
||||
@ApiOperation("手动移除客群客户")
|
||||
@Log(title = "客群管理-手动移除客户", businessType = BusinessType.DELETE)
|
||||
@PostMapping("/removeMembers")
|
||||
public AjaxResult removeMembers(@RequestParam Long groupId, @RequestBody List<Long> memberIds) {
|
||||
String result = custGroupService.removeMembers(groupId, memberIds);
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.ruoyi.group.controller;
|
||||
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.group.domain.dto.CustGroupMemberQueryDTO;
|
||||
import com.ruoyi.group.domain.vo.CustGroupMemberVO;
|
||||
import com.ruoyi.group.service.ICustGroupMemberService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 客群客户Controller
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Api(tags = "客群客户接口")
|
||||
@RestController
|
||||
@RequestMapping("/group/member")
|
||||
public class CustGroupMemberController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private ICustGroupMemberService custGroupMemberService;
|
||||
|
||||
/**
|
||||
* 分页查询客群客户列表
|
||||
*/
|
||||
@ApiOperation("分页查询客群客户列表")
|
||||
@Log(title = "客群客户-查询客户列表")
|
||||
@GetMapping("/list/{groupId}")
|
||||
public TableDataInfo listCustGroupMembers(@PathVariable Long groupId,
|
||||
CustGroupMemberQueryDTO dto) {
|
||||
startPage();
|
||||
List<CustGroupMemberVO> list = custGroupMemberService.listCustGroupMembers(groupId, dto);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动移除客群客户
|
||||
*/
|
||||
@ApiOperation("手动移除客群客户")
|
||||
@Log(title = "客群客户-手动移除客户", businessType = BusinessType.DELETE)
|
||||
@PostMapping("/remove")
|
||||
public AjaxResult removeMembers(@RequestParam Long groupId, @RequestBody List<Long> memberIds) {
|
||||
String result = custGroupMemberService.removeMembers(groupId, memberIds);
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.ruoyi.group.domain.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 客群客户查询DTO
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Data
|
||||
@ApiModel(description = "客群客户查询条件")
|
||||
public class CustGroupMemberQueryDTO {
|
||||
|
||||
/**
|
||||
* 客户类型:0=个人, 1=商户, 2=企业
|
||||
*/
|
||||
@ApiModelProperty(value = "客户类型")
|
||||
private String custType;
|
||||
|
||||
/**
|
||||
* 客户姓名
|
||||
*/
|
||||
@ApiModelProperty(value = "客户姓名")
|
||||
private String custName;
|
||||
}
|
||||
@@ -59,7 +59,6 @@ public class CustGroup {
|
||||
* 所属机构ID
|
||||
*/
|
||||
@ApiModelProperty(value = "所属机构ID", name = "deptId")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
@@ -74,13 +73,6 @@ public class CustGroup {
|
||||
@ApiModelProperty(value = "可见部门ID列表(逗号分隔)", name = "shareDeptIds")
|
||||
private String shareDeptIds;
|
||||
|
||||
/**
|
||||
* 共享部门ID列表(非表字段,用于接收前端传参)
|
||||
*/
|
||||
@ApiModelProperty(value = "共享部门ID列表", name = "shareDeptIdList")
|
||||
@TableField(exist = false)
|
||||
private List<Long> shareDeptIdList;
|
||||
|
||||
/**
|
||||
* 客群状态:0=正常, 1=已禁用
|
||||
*/
|
||||
@@ -109,14 +101,12 @@ public class CustGroup {
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
|
||||
@@ -63,14 +63,12 @@ public class CustGroupMember {
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
|
||||
@@ -65,10 +65,10 @@ public class CustGroupVO {
|
||||
private Integer shareEnabled;
|
||||
|
||||
/**
|
||||
* 可见部门ID列表
|
||||
* 可见部门ID列表(逗号分隔)
|
||||
*/
|
||||
@ApiModelProperty(value = "可见部门ID列表", name = "shareDeptIds")
|
||||
private List<Long> shareDeptIds;
|
||||
@ApiModelProperty(value = "可见部门ID列表(逗号分隔)", name = "shareDeptIds")
|
||||
private String shareDeptIds;
|
||||
|
||||
/**
|
||||
* 客群状态:0=正常, 1=已禁用
|
||||
@@ -114,6 +114,49 @@ public class CustGroupVO {
|
||||
@ApiModelProperty(value = "备注", name = "remark")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 有效期截止时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@ApiModelProperty(value = "有效期截止时间", name = "validTime")
|
||||
private Date validTime;
|
||||
|
||||
/**
|
||||
* 创建状态:0=创建中, 1=创建成功, 2=创建失败
|
||||
*/
|
||||
@ApiModelProperty(value = "创建状态:0=创建中, 1=创建成功, 2=创建失败", name = "createStatus")
|
||||
private String createStatus;
|
||||
|
||||
/**
|
||||
* 网格类型:0=绩效网格, 1=地理网格, 2=绘制网格
|
||||
*/
|
||||
@ApiModelProperty(value = "网格类型", name = "gridType")
|
||||
private String gridType;
|
||||
|
||||
/**
|
||||
* 绩效业务类型:retail=零售, corporate=公司
|
||||
*/
|
||||
@ApiModelProperty(value = "绩效业务类型", name = "cmpmBizType")
|
||||
private String cmpmBizType;
|
||||
|
||||
/**
|
||||
* 客户经理列表(逗号分隔)
|
||||
*/
|
||||
@ApiModelProperty(value = "客户经理列表", name = "gridUserNames")
|
||||
private String gridUserNames;
|
||||
|
||||
/**
|
||||
* 地理网格ID列表(逗号分隔)
|
||||
*/
|
||||
@ApiModelProperty(value = "地理网格ID列表", name = "regionGridIds")
|
||||
private String regionGridIds;
|
||||
|
||||
/**
|
||||
* 绘制网格ID列表(逗号分隔)
|
||||
*/
|
||||
@ApiModelProperty(value = "绘制网格ID列表", name = "drawGridIds")
|
||||
private String drawGridIds;
|
||||
|
||||
/**
|
||||
* 客户列表
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.ruoyi.group.domain.dto.CustGroupQueryDTO;
|
||||
import com.ruoyi.group.domain.entity.CustGroup;
|
||||
import com.ruoyi.group.domain.vo.CustGroupVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
@@ -13,6 +14,7 @@ import java.util.List;
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Mapper
|
||||
public interface CustGroupMapper extends BaseMapper<CustGroup> {
|
||||
|
||||
/**
|
||||
@@ -31,4 +33,12 @@ public interface CustGroupMapper extends BaseMapper<CustGroup> {
|
||||
* @return 客群VO列表
|
||||
*/
|
||||
List<CustGroupVO> selectCustGroupList(@Param("dto") CustGroupQueryDTO dto);
|
||||
|
||||
/**
|
||||
* 根据ID查询客群详情
|
||||
*
|
||||
* @param id 客群ID
|
||||
* @return 客群VO
|
||||
*/
|
||||
CustGroupVO selectCustGroupById(@Param("id") Long id);
|
||||
}
|
||||
@@ -1,21 +1,36 @@
|
||||
package com.ruoyi.group.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.ruoyi.group.domain.dto.CustGroupMemberQueryDTO;
|
||||
import com.ruoyi.group.domain.entity.CustGroupMember;
|
||||
import com.ruoyi.group.domain.vo.CustGroupMemberVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 客群客户关联Mapper接口
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Mapper
|
||||
public interface CustGroupMemberMapper extends BaseMapper<CustGroupMember> {
|
||||
|
||||
/**
|
||||
* 查询客群客户数量
|
||||
* 分页查询客群客户列表
|
||||
*
|
||||
* @param groupId 客群ID
|
||||
* @return 数量
|
||||
* @param dto 查询条件
|
||||
* @return 客户列表
|
||||
*/
|
||||
Long countByGroupId(@Param("groupId") Long groupId);
|
||||
List<CustGroupMemberVO> selectCustGroupMemberList(@Param("groupId") Long groupId,
|
||||
@Param("dto") CustGroupMemberQueryDTO dto);
|
||||
|
||||
/**
|
||||
* 批量插入客群客户(INSERT IGNORE,遇到重复键自动跳过)
|
||||
*
|
||||
* @param memberList 客户列表
|
||||
*/
|
||||
void batchInsertMembers(@Param("list") List<CustGroupMember> memberList);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.ruoyi.group.service;
|
||||
|
||||
import com.ruoyi.group.domain.dto.CustGroupMemberQueryDTO;
|
||||
import com.ruoyi.group.domain.vo.CustGroupMemberVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 客群客户服务接口
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ICustGroupMemberService {
|
||||
|
||||
/**
|
||||
* 分页查询客群客户列表
|
||||
*
|
||||
* @param groupId 客群ID
|
||||
* @param dto 查询条件
|
||||
* @return 客户列表
|
||||
*/
|
||||
List<CustGroupMemberVO> listCustGroupMembers(Long groupId, CustGroupMemberQueryDTO dto);
|
||||
|
||||
/**
|
||||
* 手动移除客群客户
|
||||
*
|
||||
* @param groupId 客群ID
|
||||
* @param memberIds 客户ID列表
|
||||
* @return 结果
|
||||
*/
|
||||
String removeMembers(Long groupId, List<Long> memberIds);
|
||||
}
|
||||
@@ -23,6 +23,14 @@ public interface ICustGroupService {
|
||||
*/
|
||||
List<CustGroupVO> listCustGroup(CustGroupQueryDTO dto);
|
||||
|
||||
/**
|
||||
* 根据ID查询客群详情
|
||||
*
|
||||
* @param id 客群ID
|
||||
* @return 客群VO
|
||||
*/
|
||||
CustGroupVO getCustGroup(Long id);
|
||||
|
||||
/**
|
||||
* 异步创建客群(模板导入)
|
||||
*
|
||||
@@ -57,14 +65,6 @@ public interface ICustGroupService {
|
||||
*/
|
||||
String updateCustGroupByTemplate(CustGroup custGroup, MultipartFile file);
|
||||
|
||||
/**
|
||||
* 更新客群
|
||||
*
|
||||
* @param custGroup 客群实体
|
||||
* @return 结果消息
|
||||
*/
|
||||
String updateCustGroup(CustGroup custGroup);
|
||||
|
||||
/**
|
||||
* 删除客群
|
||||
*
|
||||
@@ -73,14 +73,6 @@ public interface ICustGroupService {
|
||||
*/
|
||||
String deleteCustGroup(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 获取客群详情
|
||||
*
|
||||
* @param id 客群ID
|
||||
* @return 客群VO
|
||||
*/
|
||||
CustGroupVO getCustGroup(Long id);
|
||||
|
||||
/**
|
||||
* 检查客群名称是否存在
|
||||
*
|
||||
@@ -97,15 +89,6 @@ public interface ICustGroupService {
|
||||
*/
|
||||
String getCreateStatus(Long id);
|
||||
|
||||
/**
|
||||
* 手动移除客群客户
|
||||
*
|
||||
* @param groupId 客群ID
|
||||
* @param memberIds 客群成员ID列表
|
||||
* @return 结果消息
|
||||
*/
|
||||
String removeMembers(Long groupId, List<Long> memberIds);
|
||||
|
||||
/**
|
||||
* 更新动态客群(定时任务调用)
|
||||
* 根据原始导入条件重新查询并更新客户列表
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.ruoyi.group.service.impl;
|
||||
|
||||
import com.ruoyi.group.domain.dto.CustGroupMemberQueryDTO;
|
||||
import com.ruoyi.group.domain.entity.CustGroup;
|
||||
import com.ruoyi.group.domain.entity.CustGroupMember;
|
||||
import com.ruoyi.group.domain.vo.CustGroupMemberVO;
|
||||
import com.ruoyi.group.mapper.CustGroupMapper;
|
||||
import com.ruoyi.group.mapper.CustGroupMemberMapper;
|
||||
import com.ruoyi.group.service.ICustGroupMemberService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 客群客户服务实现类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
public class CustGroupMemberServiceImpl implements ICustGroupMemberService {
|
||||
|
||||
@Resource
|
||||
private CustGroupMemberMapper custGroupMemberMapper;
|
||||
|
||||
@Resource
|
||||
private CustGroupMapper custGroupMapper;
|
||||
|
||||
@Override
|
||||
public List<CustGroupMemberVO> listCustGroupMembers(Long groupId, CustGroupMemberQueryDTO dto) {
|
||||
return custGroupMemberMapper.selectCustGroupMemberList(groupId, dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String removeMembers(Long groupId, List<Long> memberIds) {
|
||||
// 检查客群是否存在
|
||||
CustGroup custGroup = custGroupMapper.selectById(groupId);
|
||||
if (custGroup == null) {
|
||||
return "客群不存在";
|
||||
}
|
||||
|
||||
// 删除客户关联
|
||||
memberIds.forEach(memberId -> {
|
||||
CustGroupMember member = custGroupMemberMapper.selectById(memberId);
|
||||
if (member != null && member.getGroupId().equals(groupId)) {
|
||||
// 设置手动移除标识
|
||||
member.setManualRemove(1);
|
||||
// 逻辑删除
|
||||
custGroupMemberMapper.deleteById(memberId);
|
||||
}
|
||||
});
|
||||
|
||||
return "移除成功";
|
||||
}
|
||||
}
|
||||
@@ -2,36 +2,28 @@ package com.ruoyi.group.service.impl;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.system.mapper.SysDeptMapper;
|
||||
import com.ruoyi.ibs.cmpm.domain.entity.GridCmpm;
|
||||
import com.ruoyi.ibs.cmpm.mapper.GridCmpmMapper;
|
||||
import com.ruoyi.ibs.draw.domain.entity.DrawGridShapeRelate;
|
||||
import com.ruoyi.ibs.draw.domain.entity.DrawShapeCust;
|
||||
import com.ruoyi.ibs.draw.mapper.DrawGridShapeRelateMapper;
|
||||
import com.ruoyi.ibs.draw.mapper.DrawShapeCustMapper;
|
||||
import com.ruoyi.ibs.grid.domain.vo.CustVO;
|
||||
import com.ruoyi.ibs.cmpm.domain.vo.GridCmpmVO;
|
||||
import com.ruoyi.ibs.cmpm.service.GridCmpmService;
|
||||
import com.ruoyi.ibs.draw.mapper.DrawGridCustUserUnbindMapper;
|
||||
import com.ruoyi.ibs.grid.service.RegionGridListService;
|
||||
import com.ruoyi.group.domain.dto.CustGroupMemberTemplate;
|
||||
import com.ruoyi.group.domain.dto.CustGroupQueryDTO;
|
||||
import com.ruoyi.group.domain.dto.GridImportDTO;
|
||||
import com.ruoyi.group.domain.entity.CustGroup;
|
||||
import com.ruoyi.group.domain.entity.CustGroupMember;
|
||||
import com.ruoyi.group.domain.vo.CustGroupMemberVO;
|
||||
import com.ruoyi.group.domain.vo.CustGroupVO;
|
||||
import com.ruoyi.group.mapper.CustGroupMapper;
|
||||
import com.ruoyi.group.mapper.CustGroupMemberMapper;
|
||||
import com.ruoyi.group.service.ICustGroupService;
|
||||
import com.ruoyi.ibs.grid.domain.entity.RegionCustUser;
|
||||
import com.ruoyi.ibs.grid.domain.entity.RegionGrid;
|
||||
import com.ruoyi.ibs.grid.mapper.RegionCustUserMapper;
|
||||
import com.ruoyi.ibs.grid.mapper.RegionGridMapper;
|
||||
import com.ruoyi.ibs.handler.DynamicTableNameHelper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import lombok.val;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -61,31 +53,31 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
private ExecutorService executorService;
|
||||
|
||||
@Resource
|
||||
private GridCmpmMapper gridCmpmMapper;
|
||||
|
||||
@Resource
|
||||
private RegionCustUserMapper regionCustUserMapper;
|
||||
|
||||
@Resource
|
||||
private RegionGridMapper regionGridMapper;
|
||||
private GridCmpmService gridCmpmService;
|
||||
|
||||
@Resource
|
||||
private RegionGridListService regionGridListService;
|
||||
|
||||
@Resource
|
||||
private DrawShapeCustMapper drawShapeCustMapper;
|
||||
private DrawGridCustUserUnbindMapper drawGridCustUserUnbindMapper;
|
||||
|
||||
@Resource
|
||||
private DrawGridShapeRelateMapper drawGridShapeRelateMapper;
|
||||
|
||||
@Resource
|
||||
private SysDeptMapper sysDeptMapper;
|
||||
private TransactionTemplate transactionTemplate;
|
||||
|
||||
@Override
|
||||
public List<CustGroupVO> listCustGroup(CustGroupQueryDTO dto) {
|
||||
return custGroupMapper.selectCustGroupList(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustGroupVO getCustGroup(Long id) {
|
||||
CustGroupVO custGroup = custGroupMapper.selectCustGroupById(id);
|
||||
if (custGroup == null) {
|
||||
throw new ServiceException("客群不存在");
|
||||
}
|
||||
return custGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String createCustGroupByTemplate(CustGroup custGroup, MultipartFile file) {
|
||||
@@ -176,21 +168,6 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
return String.valueOf(custGroup.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String updateCustGroup(CustGroup custGroup) {
|
||||
CustGroup existGroup = custGroupMapper.selectById(custGroup.getId());
|
||||
if (existGroup == null) {
|
||||
throw new ServiceException("客群不存在");
|
||||
}
|
||||
// 检查客群名称是否存在(排除自己)
|
||||
if (!existGroup.getGroupName().equals(custGroup.getGroupName()) && checkGroupNameExist(custGroup.getGroupName())) {
|
||||
throw new ServiceException("客群名称已存在");
|
||||
}
|
||||
custGroupMapper.updateById(custGroup);
|
||||
return "客群更新成功";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String updateCustGroupByGrid(GridImportDTO gridImportDTO) {
|
||||
@@ -200,10 +177,17 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
if (existGroup == null) {
|
||||
throw new ServiceException("客群不存在");
|
||||
}
|
||||
// 检查客群是否正在创建或更新
|
||||
if ("0".equals(existGroup.getCreateStatus())) {
|
||||
throw new ServiceException("客群正在处理中,请稍后再试");
|
||||
}
|
||||
// 更新客群基本信息
|
||||
if (!existGroup.getGroupName().equals(custGroup.getGroupName()) && checkGroupNameExist(custGroup.getGroupName())) {
|
||||
throw new ServiceException("客群名称已存在");
|
||||
}
|
||||
// 检查网格条件是否发生变化
|
||||
boolean gridConditionChanged = isGridConditionChanged(existGroup, gridImportDTO);
|
||||
|
||||
// 重新查询数据库,获取最新状态
|
||||
CustGroup latestGroup = custGroupMapper.selectById(custGroup.getId());
|
||||
latestGroup.setGroupName(custGroup.getGroupName());
|
||||
@@ -212,7 +196,48 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
latestGroup.setValidTime(custGroup.getValidTime());
|
||||
latestGroup.setShareEnabled(custGroup.getShareEnabled());
|
||||
latestGroup.setShareDeptIds(custGroup.getShareDeptIds());
|
||||
|
||||
// 保存新的网格导入条件
|
||||
String gridType = gridImportDTO.getGridType();
|
||||
latestGroup.setGridType(gridType);
|
||||
if ("0".equals(gridType)) {
|
||||
latestGroup.setCmpmBizType(gridImportDTO.getCmpmBizType());
|
||||
if (gridImportDTO.getUserNames() != null && !gridImportDTO.getUserNames().isEmpty()) {
|
||||
latestGroup.setGridUserNames(String.join(",", gridImportDTO.getUserNames()));
|
||||
} else {
|
||||
latestGroup.setGridUserNames(null);
|
||||
}
|
||||
} else if ("1".equals(gridType)) {
|
||||
if (gridImportDTO.getRegionGridIds() != null && !gridImportDTO.getRegionGridIds().isEmpty()) {
|
||||
latestGroup.setRegionGridIds(gridImportDTO.getRegionGridIds().stream()
|
||||
.map(String::valueOf).collect(Collectors.joining(",")));
|
||||
} else {
|
||||
latestGroup.setRegionGridIds(null);
|
||||
}
|
||||
} else if ("2".equals(gridType)) {
|
||||
if (gridImportDTO.getDrawGridIds() != null && !gridImportDTO.getDrawGridIds().isEmpty()) {
|
||||
latestGroup.setDrawGridIds(gridImportDTO.getDrawGridIds().stream()
|
||||
.map(String::valueOf).collect(Collectors.joining(",")));
|
||||
} else {
|
||||
latestGroup.setDrawGridIds(null);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新数据库
|
||||
latestGroup.setUpdateBy(SecurityUtils.getUsername());
|
||||
latestGroup.setUpdateTime(new Date());
|
||||
custGroupMapper.updateById(latestGroup);
|
||||
|
||||
// 如果网格条件没有变化,直接返回成功
|
||||
if (!gridConditionChanged) {
|
||||
log.info("客群网格条件未变化,跳过客户重新导入,客群ID:{}", custGroup.getId());
|
||||
return "客群更新成功(客户列表无需变更)";
|
||||
}
|
||||
|
||||
// 网格条件发生变化,需要重新导入客户
|
||||
log.info("客群网格条件已变化,开始重新导入客户,客群ID:{}", custGroup.getId());
|
||||
// 设置更新状态为"更新中"
|
||||
latestGroup.setCreateStatus("0");
|
||||
custGroupMapper.updateById(latestGroup);
|
||||
// 重新设置回DTO(确保异步线程能获取到正确的ID和状态)
|
||||
gridImportDTO.setCustGroup(latestGroup);
|
||||
@@ -223,6 +248,80 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
return "客群更新中";
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查网格条件是否发生变化
|
||||
*/
|
||||
private boolean isGridConditionChanged(CustGroup existGroup, GridImportDTO gridImportDTO) {
|
||||
// 首先检查网格类型是否变化
|
||||
String newGridType = gridImportDTO.getGridType();
|
||||
String oldGridType = existGroup.getGridType();
|
||||
|
||||
// 如果旧记录没有网格类型信息,说明需要导入
|
||||
if (oldGridType == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 网格类型变化
|
||||
if (!newGridType.equals(oldGridType)) {
|
||||
log.info("网格类型变化:旧={}, 新={}", oldGridType, newGridType);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 根据网格类型检查具体条件
|
||||
if ("0".equals(newGridType)) {
|
||||
// 绩效网格:比较业务类型和客户经理列表
|
||||
String oldBizType = existGroup.getCmpmBizType();
|
||||
String newBizType = gridImportDTO.getCmpmBizType();
|
||||
List<String> newUserNames = gridImportDTO.getUserNames();
|
||||
|
||||
if (!Objects.equals(oldBizType, newBizType)) {
|
||||
log.info("绩效业务类型变化:旧={}, 新={}", oldBizType, newBizType);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 比较客户经理列表
|
||||
String oldUserNames = existGroup.getGridUserNames();
|
||||
String newUserNamesStr = newUserNames == null || newUserNames.isEmpty()
|
||||
? null : String.join(",", newUserNames);
|
||||
if (!Objects.equals(oldUserNames, newUserNamesStr)) {
|
||||
log.info("客户经理列表变化:旧={}, 新={}", oldUserNames, newUserNamesStr);
|
||||
return true;
|
||||
}
|
||||
} else if ("1".equals(newGridType)) {
|
||||
// 地理网格:比较网格ID列表
|
||||
String oldRegionIds = existGroup.getRegionGridIds();
|
||||
List<Long> newRegionIds = gridImportDTO.getRegionGridIds();
|
||||
String newRegionIdsStr = newRegionIds == null || newRegionIds.isEmpty()
|
||||
? null : newRegionIds.stream().map(String::valueOf).sorted().collect(Collectors.joining(","));
|
||||
|
||||
// 归一化比较(排序后比较)
|
||||
String oldRegionIdsSorted = oldRegionIds == null ? null :
|
||||
Arrays.stream(oldRegionIds.split(",")).sorted().collect(Collectors.joining(","));
|
||||
|
||||
if (!Objects.equals(oldRegionIdsSorted, newRegionIdsStr)) {
|
||||
log.info("地理网格ID列表变化:旧={}, 新={}", oldRegionIdsSorted, newRegionIdsStr);
|
||||
return true;
|
||||
}
|
||||
} else if ("2".equals(newGridType)) {
|
||||
// 绘制网格:比较网格ID列表
|
||||
String oldDrawIds = existGroup.getDrawGridIds();
|
||||
List<Long> newDrawIds = gridImportDTO.getDrawGridIds();
|
||||
String newDrawIdsStr = newDrawIds == null || newDrawIds.isEmpty()
|
||||
? null : newDrawIds.stream().map(String::valueOf).sorted().collect(Collectors.joining(","));
|
||||
|
||||
// 归一化比较(排序后比较)
|
||||
String oldDrawIdsSorted = oldDrawIds == null ? null :
|
||||
Arrays.stream(oldDrawIds.split(",")).sorted().collect(Collectors.joining(","));
|
||||
|
||||
if (!Objects.equals(oldDrawIdsSorted, newDrawIdsStr)) {
|
||||
log.info("绘制网格ID列表变化:旧={}, 新={}", oldDrawIdsSorted, newDrawIdsStr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String updateCustGroupByTemplate(CustGroup custGroup, MultipartFile file) {
|
||||
@@ -231,6 +330,10 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
if (existGroup == null) {
|
||||
throw new ServiceException("客群不存在");
|
||||
}
|
||||
// 检查客群是否正在创建或更新
|
||||
if ("0".equals(existGroup.getCreateStatus())) {
|
||||
throw new ServiceException("客群正在处理中,请稍后再试");
|
||||
}
|
||||
// 更新客群基本信息
|
||||
if (!existGroup.getGroupName().equals(custGroup.getGroupName()) && checkGroupNameExist(custGroup.getGroupName())) {
|
||||
throw new ServiceException("客群名称已存在");
|
||||
@@ -243,7 +346,11 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
latestGroup.setValidTime(custGroup.getValidTime());
|
||||
latestGroup.setShareEnabled(custGroup.getShareEnabled());
|
||||
latestGroup.setShareDeptIds(custGroup.getShareDeptIds());
|
||||
// 设置更新状态为"更新中"
|
||||
latestGroup.setCreateStatus("0");
|
||||
// 更新数据库
|
||||
latestGroup.setUpdateBy(SecurityUtils.getUsername());
|
||||
latestGroup.setUpdateTime(new Date());
|
||||
custGroupMapper.updateById(latestGroup);
|
||||
// 获取当前用户部门编码(异步线程中无法获取)
|
||||
String headId = SecurityUtils.getHeadId();
|
||||
@@ -269,82 +376,6 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
return "客群删除成功";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String removeMembers(Long groupId, List<Long> memberIds) {
|
||||
if (memberIds == null || memberIds.isEmpty()) {
|
||||
throw new ServiceException("请选择要移除的客户");
|
||||
}
|
||||
// 检查客群是否存在
|
||||
CustGroup custGroup = custGroupMapper.selectById(groupId);
|
||||
if (custGroup == null) {
|
||||
throw new ServiceException("客群不存在");
|
||||
}
|
||||
// 标记为手动移除(软删除)
|
||||
for (Long memberId : memberIds) {
|
||||
CustGroupMember member = custGroupMemberMapper.selectById(memberId);
|
||||
if (member != null && member.getGroupId().equals(groupId)) {
|
||||
member.setManualRemove(1);
|
||||
member.setDelFlag(1);
|
||||
custGroupMemberMapper.updateById(member);
|
||||
}
|
||||
}
|
||||
return "成功移除 " + memberIds.size() + " 个客户";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustGroupVO getCustGroup(Long id) {
|
||||
CustGroup custGroup = custGroupMapper.selectById(id);
|
||||
if (custGroup == null) {
|
||||
throw new ServiceException("客群不存在");
|
||||
}
|
||||
CustGroupVO vo = new CustGroupVO();
|
||||
vo.setId(custGroup.getId());
|
||||
vo.setGroupName(custGroup.getGroupName());
|
||||
vo.setGroupMode(custGroup.getGroupMode());
|
||||
vo.setCreateMode(custGroup.getCreateMode());
|
||||
vo.setUserName(custGroup.getUserName());
|
||||
vo.setNickName(custGroup.getNickName());
|
||||
vo.setDeptId(custGroup.getDeptId());
|
||||
vo.setShareEnabled(custGroup.getShareEnabled());
|
||||
vo.setGroupStatus(custGroup.getGroupStatus());
|
||||
vo.setRemark(custGroup.getRemark());
|
||||
vo.setCreateBy(custGroup.getCreateBy());
|
||||
vo.setCreateTime(custGroup.getCreateTime());
|
||||
vo.setUpdateBy(custGroup.getUpdateBy());
|
||||
vo.setUpdateTime(custGroup.getUpdateTime());
|
||||
// 处理共享部门ID列表
|
||||
if (StringUtils.isNotEmpty(custGroup.getShareDeptIds())) {
|
||||
List<Long> deptIds = new ArrayList<>();
|
||||
for (String idStr : custGroup.getShareDeptIds().split(",")) {
|
||||
if (StringUtils.isNotEmpty(idStr)) {
|
||||
deptIds.add(Long.valueOf(idStr));
|
||||
}
|
||||
}
|
||||
vo.setShareDeptIds(deptIds);
|
||||
}
|
||||
// 查询客户列表
|
||||
LambdaQueryWrapper<CustGroupMember> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(CustGroupMember::getGroupId, id);
|
||||
List<CustGroupMember> memberList = custGroupMemberMapper.selectList(wrapper);
|
||||
List<CustGroupMemberVO> memberVOList = new ArrayList<>();
|
||||
for (CustGroupMember member : memberList) {
|
||||
CustGroupMemberVO memberVO = new CustGroupMemberVO();
|
||||
memberVO.setId(member.getId());
|
||||
memberVO.setGroupId(member.getGroupId());
|
||||
memberVO.setCustType(member.getCustType());
|
||||
memberVO.setCustId(member.getCustId());
|
||||
memberVO.setCustName(member.getCustName());
|
||||
memberVO.setCustIdc(member.getCustIdc());
|
||||
memberVO.setSocialCreditCode(member.getSocialCreditCode());
|
||||
memberVO.setCreateTime(member.getCreateTime());
|
||||
memberVOList.add(memberVO);
|
||||
}
|
||||
vo.setCustList(memberVOList);
|
||||
vo.setCustCount(memberVOList.size());
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkGroupNameExist(String groupName) {
|
||||
LambdaQueryWrapper<CustGroup> wrapper = new LambdaQueryWrapper<>();
|
||||
@@ -486,14 +517,14 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
gridImportDTO.setRegionGridIds(Arrays.stream(custGroup.getRegionGridIds().split(","))
|
||||
.map(Long::valueOf).collect(Collectors.toList()));
|
||||
}
|
||||
newMemberList.addAll(importFromRegionGrid(custGroup, gridImportDTO));
|
||||
newMemberList.addAll(importFromRegionGrid(custGroup, gridImportDTO, headId));
|
||||
} else if ("2".equals(gridType)) {
|
||||
// 绘制网格
|
||||
if (StringUtils.isNotEmpty(custGroup.getDrawGridIds())) {
|
||||
gridImportDTO.setDrawGridIds(Arrays.stream(custGroup.getDrawGridIds().split(","))
|
||||
.map(Long::valueOf).collect(Collectors.toList()));
|
||||
}
|
||||
newMemberList.addAll(importFromDrawGrid(custGroup, gridImportDTO));
|
||||
newMemberList.addAll(importFromDrawGrid(custGroup, gridImportDTO, headId));
|
||||
}
|
||||
|
||||
// 计算差异
|
||||
@@ -601,51 +632,71 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
}
|
||||
memberList.add(member);
|
||||
}
|
||||
// 批量插入
|
||||
int batchSize = 1000;
|
||||
int successCount = 0;
|
||||
int skippedCount = 0;
|
||||
int restoredCount = 0;
|
||||
for (int i = 0; i < memberList.size(); i += batchSize) {
|
||||
int endIndex = Math.min(i + batchSize, memberList.size());
|
||||
List<CustGroupMember> batchList = memberList.subList(i, endIndex);
|
||||
for (CustGroupMember member : batchList) {
|
||||
try {
|
||||
custGroupMemberMapper.insert(member);
|
||||
successCount++;
|
||||
} catch (DuplicateKeyException e) {
|
||||
// 客户已存在,检查是否是被手动移除的
|
||||
LambdaQueryWrapper<CustGroupMember> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustGroupMember::getGroupId, member.getGroupId())
|
||||
.eq(CustGroupMember::getCustId, member.getCustId())
|
||||
.eq(CustGroupMember::getCustType, member.getCustType());
|
||||
CustGroupMember existMember = custGroupMemberMapper.selectOne(queryWrapper);
|
||||
if (existMember != null && existMember.getManualRemove() != null && existMember.getManualRemove() == 1) {
|
||||
// 是被手动移除的客户,清除标记并恢复
|
||||
existMember.setManualRemove(0);
|
||||
existMember.setDelFlag(0);
|
||||
existMember.setCustName(member.getCustName());
|
||||
custGroupMemberMapper.updateById(existMember);
|
||||
restoredCount++;
|
||||
log.debug("恢复手动移除的客户:groupId={}, custId={}", member.getGroupId(), member.getCustId());
|
||||
} else {
|
||||
// 正常存在的客户,跳过
|
||||
skippedCount++;
|
||||
log.debug("客户已存在,跳过:groupId={}, custId={}", member.getGroupId(), member.getCustId());
|
||||
|
||||
// 使用编程式事务:先删除旧客户,再插入新客户
|
||||
transactionTemplate.executeWithoutResult(status -> {
|
||||
// 删除该客群的所有旧客户
|
||||
log.info("开始删除客群旧客户(模板导入),客群ID:{}", custGroup.getId());
|
||||
LambdaQueryWrapper<CustGroupMember> memberWrapper = new LambdaQueryWrapper<>();
|
||||
memberWrapper.eq(CustGroupMember::getGroupId, custGroup.getId());
|
||||
custGroupMemberMapper.delete(memberWrapper);
|
||||
log.info("客群旧客户删除完成(模板导入),客群ID:{}", custGroup.getId());
|
||||
|
||||
// 批量插入新客户
|
||||
log.info("开始批量插入客户(模板导入),客群ID:{},客户总数:{}", custGroup.getId(), memberList.size());
|
||||
int batchSize = 1000;
|
||||
int successCount = 0;
|
||||
int skippedCount = 0;
|
||||
int restoredCount = 0;
|
||||
for (int i = 0; i < memberList.size(); i += batchSize) {
|
||||
int endIndex = Math.min(i + batchSize, memberList.size());
|
||||
List<CustGroupMember> batchList = memberList.subList(i, endIndex);
|
||||
log.info("处理批次 [{}/{}],本批大小:{}", i / batchSize + 1, (memberList.size() + batchSize - 1) / batchSize, batchList.size());
|
||||
for (CustGroupMember member : batchList) {
|
||||
try {
|
||||
custGroupMemberMapper.insert(member);
|
||||
successCount++;
|
||||
} catch (DuplicateKeyException e) {
|
||||
// 客户已存在,检查是否是被手动移除的
|
||||
LambdaQueryWrapper<CustGroupMember> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustGroupMember::getGroupId, member.getGroupId())
|
||||
.eq(CustGroupMember::getCustId, member.getCustId())
|
||||
.eq(CustGroupMember::getCustType, member.getCustType());
|
||||
CustGroupMember existMember = custGroupMemberMapper.selectOne(queryWrapper);
|
||||
if (existMember != null && existMember.getManualRemove() != null && existMember.getManualRemove() == 1) {
|
||||
// 是被手动移除的客户,清除标记并恢复
|
||||
existMember.setManualRemove(0);
|
||||
existMember.setDelFlag(0);
|
||||
existMember.setCustName(member.getCustName());
|
||||
custGroupMemberMapper.updateById(existMember);
|
||||
restoredCount++;
|
||||
log.debug("恢复手动移除的客户:groupId={}, custId={}", member.getGroupId(), member.getCustId());
|
||||
} else {
|
||||
// 正常存在的客户,跳过
|
||||
skippedCount++;
|
||||
log.debug("客户已存在,跳过:groupId={}, custId={}", member.getGroupId(), member.getCustId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
log.info("客群客户导入完成(模板),客群ID:{},成功:{},跳过重复:{},恢复:{}",
|
||||
custGroup.getId(), successCount, skippedCount, restoredCount);
|
||||
// 更新创建状态为成功
|
||||
custGroup.setCreateStatus("1");
|
||||
custGroupMapper.updateById(custGroup);
|
||||
log.info("客群客户导入完成(模板),客群ID:{},成功:{},跳过重复:{},恢复:{}",
|
||||
custGroup.getId(), successCount, skippedCount, restoredCount);
|
||||
// 更新创建状态为成功
|
||||
custGroup.setCreateStatus("1");
|
||||
custGroup.setUpdateBy(custGroup.getCreateBy());
|
||||
custGroup.setUpdateTime(new Date());
|
||||
custGroupMapper.updateById(custGroup);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.error("客群客户导入失败,客群ID:{},异常:{}", custGroup.getId(), e.getMessage(), e);
|
||||
|
||||
// 注意:由于删除和插入在同一事务中,插入失败会自动回滚删除操作,无需手动清理
|
||||
|
||||
// 更新创建状态为失败
|
||||
custGroup.setCreateStatus("2");
|
||||
custGroup.setUpdateBy(custGroup.getCreateBy());
|
||||
custGroup.setUpdateTime(new Date());
|
||||
custGroupMapper.updateById(custGroup);
|
||||
log.error("客群客户导入失败,客群ID:{}", custGroup.getId(), e);
|
||||
throw new ServiceException("客群客户导入失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -664,63 +715,122 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
memberList.addAll(importFromCmpmGrid(custGroup, gridImportDTO, headId));
|
||||
} else if ("1".equals(gridType)) {
|
||||
// 地理网格
|
||||
memberList.addAll(importFromRegionGrid(custGroup, gridImportDTO));
|
||||
memberList.addAll(importFromRegionGrid(custGroup, gridImportDTO, headId));
|
||||
} else if ("2".equals(gridType)) {
|
||||
// 绘制网格
|
||||
memberList.addAll(importFromDrawGrid(custGroup, gridImportDTO));
|
||||
memberList.addAll(importFromDrawGrid(custGroup, gridImportDTO, headId));
|
||||
}
|
||||
if (memberList.isEmpty()) {
|
||||
throw new ServiceException("未查询到任何客户");
|
||||
}
|
||||
// 批量插入
|
||||
int batchSize = 1000;
|
||||
int successCount = 0;
|
||||
int skippedCount = 0;
|
||||
int restoredCount = 0;
|
||||
for (int i = 0; i < memberList.size(); i += batchSize) {
|
||||
int endIndex = Math.min(i + batchSize, memberList.size());
|
||||
List<CustGroupMember> batchList = memberList.subList(i, endIndex);
|
||||
for (CustGroupMember member : batchList) {
|
||||
try {
|
||||
custGroupMemberMapper.insert(member);
|
||||
successCount++;
|
||||
} catch (DuplicateKeyException e) {
|
||||
// 客户已存在,检查是否是被手动移除的
|
||||
LambdaQueryWrapper<CustGroupMember> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustGroupMember::getGroupId, member.getGroupId())
|
||||
.eq(CustGroupMember::getCustId, member.getCustId())
|
||||
.eq(CustGroupMember::getCustType, member.getCustType());
|
||||
CustGroupMember existMember = custGroupMemberMapper.selectOne(queryWrapper);
|
||||
if (existMember != null && existMember.getManualRemove() != null && existMember.getManualRemove() == 1) {
|
||||
// 是被手动移除的客户,清除标记并恢复
|
||||
existMember.setManualRemove(0);
|
||||
existMember.setDelFlag(0);
|
||||
existMember.setCustName(member.getCustName());
|
||||
custGroupMemberMapper.updateById(existMember);
|
||||
restoredCount++;
|
||||
log.debug("恢复手动移除的客户:groupId={}, custId={}", member.getGroupId(), member.getCustId());
|
||||
} else {
|
||||
// 正常存在的客户,跳过
|
||||
skippedCount++;
|
||||
log.debug("客户已存在,跳过:groupId={}, custId={}", member.getGroupId(), member.getCustId());
|
||||
|
||||
// 使用编程式事务:先删除旧客户,再插入新客户
|
||||
transactionTemplate.executeWithoutResult(status -> {
|
||||
// 删除该客群的所有旧客户
|
||||
log.info("开始删除客群旧客户,客群ID:{}", custGroup.getId());
|
||||
LambdaQueryWrapper<CustGroupMember> memberWrapper = new LambdaQueryWrapper<>();
|
||||
memberWrapper.eq(CustGroupMember::getGroupId, custGroup.getId());
|
||||
custGroupMemberMapper.delete(memberWrapper);
|
||||
log.info("客群旧客户删除完成,客群ID:{}", custGroup.getId());
|
||||
|
||||
// 批量插入新客户
|
||||
log.info("开始批量插入客户,客群ID:{},客户总数:{}", custGroup.getId(), memberList.size());
|
||||
|
||||
// 分批批量插入(每批1000条)
|
||||
int batchSize = 1000;
|
||||
int totalInserted = 0;
|
||||
int totalRestored = 0;
|
||||
int totalSkipped = 0;
|
||||
|
||||
for (int i = 0; i < memberList.size(); i += batchSize) {
|
||||
int endIndex = Math.min(i + batchSize, memberList.size());
|
||||
List<CustGroupMember> batchList = memberList.subList(i, endIndex);
|
||||
log.info("处理批次 [{}/{}],本批大小:{}", i / batchSize + 1,
|
||||
(memberList.size() + batchSize - 1) / batchSize, batchList.size());
|
||||
|
||||
// SQL层面的批量插入
|
||||
custGroupMemberMapper.batchInsertMembers(batchList);
|
||||
|
||||
// 查询本批中被手动移除的客户,需要恢复
|
||||
List<CustGroupMember> toRestore = findManualRemovedToRestore(custGroup.getId(), batchList);
|
||||
if (!toRestore.isEmpty()) {
|
||||
// 恢复被手动移除的客户
|
||||
for (CustGroupMember m : toRestore) {
|
||||
batchList.stream()
|
||||
.filter(b -> b.getCustId().equals(m.getCustId()) && b.getCustType().equals(m.getCustType()))
|
||||
.findFirst()
|
||||
.ifPresent(origin -> m.setCustName(origin.getCustName()));
|
||||
m.setManualRemove(0);
|
||||
custGroupMemberMapper.updateById(m);
|
||||
}
|
||||
log.info("本批恢复被手动移除的客户:{} 条", toRestore.size());
|
||||
totalRestored += toRestore.size();
|
||||
}
|
||||
|
||||
totalInserted += batchList.size() - toRestore.size();
|
||||
totalSkipped += toRestore.size();
|
||||
}
|
||||
}
|
||||
log.info("客群客户导入完成(网格),客群ID:{},成功:{},跳过重复:{},恢复:{}",
|
||||
custGroup.getId(), successCount, skippedCount, restoredCount);
|
||||
// 更新创建状态为成功
|
||||
custGroup.setCreateStatus("1");
|
||||
custGroupMapper.updateById(custGroup);
|
||||
|
||||
log.info("客群客户导入完成(网格),客群ID:{},插入:{},恢复:{},跳过:{}",
|
||||
custGroup.getId(), totalInserted, totalRestored, totalSkipped);
|
||||
|
||||
// 更新创建状态为成功
|
||||
custGroup.setCreateStatus("1");
|
||||
custGroup.setUpdateBy(custGroup.getCreateBy());
|
||||
custGroup.setUpdateTime(new Date());
|
||||
log.info("准备更新客群状态为成功,客群ID:{}", custGroup.getId());
|
||||
custGroupMapper.updateById(custGroup);
|
||||
log.info("客群状态更新成功完成,客群ID:{}", custGroup.getId());
|
||||
});
|
||||
} catch (Exception e) {
|
||||
// 先记录原始异常(必须第一时间记录,避免后续异常覆盖)
|
||||
log.error("==========客群客户导入异常========== 客群ID:{},异常类型:{},异常消息:{}",
|
||||
custGroup.getId(), e.getClass().getName(), e.getMessage(), e);
|
||||
|
||||
// 注意:由于删除和插入在同一事务中,插入失败会自动回滚删除操作,无需手动清理
|
||||
|
||||
// 更新创建状态为失败
|
||||
custGroup.setCreateStatus("2");
|
||||
custGroupMapper.updateById(custGroup);
|
||||
log.error("客群客户导入失败,客群ID:{}", custGroup.getId(), e);
|
||||
try {
|
||||
custGroup.setCreateStatus("2");
|
||||
custGroup.setUpdateBy(custGroup.getCreateBy());
|
||||
custGroup.setUpdateTime(new Date());
|
||||
log.info("准备更新客群状态为失败,客群ID:{}", custGroup.getId());
|
||||
custGroupMapper.updateById(custGroup);
|
||||
log.info("客群状态更新为失败完成,客群ID:{}", custGroup.getId());
|
||||
} catch (Exception updateException) {
|
||||
log.error("==========更新客群状态为失败也异常了========== 客群ID:{},异常类型:{},异常消息:{}",
|
||||
custGroup.getId(), updateException.getClass().getName(), updateException.getMessage(), updateException);
|
||||
}
|
||||
throw new ServiceException("客群客户导入失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找需要恢复的被手动移除的客户
|
||||
*
|
||||
* @param groupId 客群ID
|
||||
* @param batchList 本批导入的客户列表
|
||||
* @return 需要恢复的客户列表
|
||||
*/
|
||||
private List<CustGroupMember> findManualRemovedToRestore(Long groupId, List<CustGroupMember> batchList) {
|
||||
// 构建本批客户的 (custId, custType) 集合
|
||||
Set<String> batchKeys = batchList.stream()
|
||||
.map(m -> m.getCustId() + "|" + m.getCustType())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 查询该客群所有被手动移除的客户
|
||||
LambdaQueryWrapper<CustGroupMember> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustGroupMember::getGroupId, groupId)
|
||||
.eq(CustGroupMember::getManualRemove, 1)
|
||||
.eq(CustGroupMember::getDelFlag, 0);
|
||||
List<CustGroupMember> manualRemovedList = custGroupMemberMapper.selectList(queryWrapper);
|
||||
|
||||
// 筛选出本批中需要恢复的
|
||||
return manualRemovedList.stream()
|
||||
.filter(m -> batchKeys.contains(m.getCustId() + "|" + m.getCustType()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 从绩效网格导入客户
|
||||
*/
|
||||
@@ -735,13 +845,13 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
gridTypes.add("corporate");
|
||||
gridTypes.add("corporate_account");
|
||||
} else {
|
||||
throw new ServiceException("请选择绩效网格业务类型(零售/公司)");
|
||||
throw new ServiceException("请选择绩效网格业务类型(零售/对公/对公账户)");
|
||||
}
|
||||
// 查询客户
|
||||
for (String userName : gridImportDTO.getUserNames()) {
|
||||
for (String gridType : gridTypes) {
|
||||
List<GridCmpm> cmpmList = gridCmpmMapper.getGridCmpmByUserName(userName, headId, gridType);
|
||||
for (GridCmpm cmpm : cmpmList) {
|
||||
List<GridCmpmVO> cmpmList = gridCmpmService.selectManageListForImport(gridType, userName, headId);
|
||||
for (GridCmpmVO cmpm : cmpmList) {
|
||||
CustGroupMember member = new CustGroupMember();
|
||||
member.setGroupId(custGroup.getId());
|
||||
member.setCustId(cmpm.getCustId());
|
||||
@@ -760,25 +870,21 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
/**
|
||||
* 从地理网格导入客户
|
||||
*/
|
||||
private List<CustGroupMember> importFromRegionGrid(CustGroup custGroup, GridImportDTO gridImportDTO) {
|
||||
private List<CustGroupMember> importFromRegionGrid(CustGroup custGroup, GridImportDTO gridImportDTO, String headId) {
|
||||
List<CustGroupMember> memberList = new ArrayList<>();
|
||||
// 查询地理网格获取编码
|
||||
if (gridImportDTO.getRegionGridIds() == null || gridImportDTO.getRegionGridIds().isEmpty()) {
|
||||
throw new ServiceException("请选择地理网格");
|
||||
}
|
||||
List<RegionGrid> regionGrids = regionGridMapper.selectBatchIds(gridImportDTO.getRegionGridIds());
|
||||
// 使用 selectAllCustFromGrid 方法查询所有客户(不限制客户类型)
|
||||
for (RegionGrid regionGrid : regionGrids) {
|
||||
List<RegionCustUser> custUsers = regionGridListService.selectAllCustFromGrid(regionGrid);
|
||||
for (RegionCustUser custUser : custUsers) {
|
||||
CustGroupMember member = new CustGroupMember();
|
||||
member.setGroupId(custGroup.getId());
|
||||
member.setCustId(custUser.getCustId());
|
||||
member.setCustName(custUser.getCustName());
|
||||
member.setCustType(custUser.getCustType());
|
||||
member.setCreateTime(new Date());
|
||||
memberList.add(member);
|
||||
}
|
||||
// 直接根据网格ID列表批量查询所有客户(SQL中直接拼接headId,绕过MyBatis-Plus拦截器)
|
||||
List<RegionCustUser> custUsers = regionGridListService.selectAllCustByGridIds(gridImportDTO.getRegionGridIds(), headId);
|
||||
for (RegionCustUser custUser : custUsers) {
|
||||
CustGroupMember member = new CustGroupMember();
|
||||
member.setGroupId(custGroup.getId());
|
||||
member.setCustId(custUser.getCustId());
|
||||
member.setCustName(custUser.getCustName());
|
||||
member.setCustType(custUser.getCustType());
|
||||
member.setCreateTime(new Date());
|
||||
memberList.add(member);
|
||||
}
|
||||
return memberList;
|
||||
}
|
||||
@@ -786,27 +892,21 @@ public class CustGroupServiceImpl implements ICustGroupService {
|
||||
/**
|
||||
* 从绘制网格导入客户
|
||||
*/
|
||||
private List<CustGroupMember> importFromDrawGrid(CustGroup custGroup, GridImportDTO gridImportDTO) {
|
||||
private List<CustGroupMember> importFromDrawGrid(CustGroup custGroup, GridImportDTO gridImportDTO, String headId) {
|
||||
List<CustGroupMember> memberList = new ArrayList<>();
|
||||
if (gridImportDTO.getDrawGridIds() == null || gridImportDTO.getDrawGridIds().isEmpty()) {
|
||||
throw new ServiceException("请选择绘制网格");
|
||||
}
|
||||
// 查询绘制网格关联的图形ID
|
||||
// 使用 selectCustByDrawGridId 方法(直接在SQL中拼接headId,绕过拦截器)
|
||||
for (Long gridId : gridImportDTO.getDrawGridIds()) {
|
||||
LambdaQueryWrapper<DrawGridShapeRelate> relateWrapper = new LambdaQueryWrapper<>();
|
||||
relateWrapper.eq(DrawGridShapeRelate::getGridId, gridId);
|
||||
List<DrawGridShapeRelate> relates = drawGridShapeRelateMapper.selectList(relateWrapper);
|
||||
for (DrawGridShapeRelate relate : relates) {
|
||||
// 根据图形ID查询客户
|
||||
LambdaQueryWrapper<DrawShapeCust> custWrapper = new LambdaQueryWrapper<>();
|
||||
custWrapper.eq(DrawShapeCust::getShapeId, relate.getShapeId());
|
||||
List<DrawShapeCust> shapeCusts = drawShapeCustMapper.selectList(custWrapper);
|
||||
for (DrawShapeCust shapeCust : shapeCusts) {
|
||||
List<RegionCustUser> custUsers = drawGridCustUserUnbindMapper.selectCustByDrawGridId(gridId, headId);
|
||||
if (custUsers != null && !custUsers.isEmpty()) {
|
||||
for (RegionCustUser custUser : custUsers) {
|
||||
CustGroupMember member = new CustGroupMember();
|
||||
member.setGroupId(custGroup.getId());
|
||||
member.setCustId(shapeCust.getCustId());
|
||||
member.setCustName(shapeCust.getCustName());
|
||||
member.setCustType(shapeCust.getCustType());
|
||||
member.setCustId(custUser.getCustId());
|
||||
member.setCustName(custUser.getCustName());
|
||||
member.setCustType(custUser.getCustType());
|
||||
member.setCreateTime(new Date());
|
||||
memberList.add(member);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user