0410-海宁预警转发+北仑客群优化+海宁aum报表导出下载

This commit is contained in:
2026-04-10 17:40:38 +08:00
parent 803dbf2aa5
commit dd4c2fc1df
36 changed files with 1632 additions and 250 deletions

View File

@@ -5,6 +5,7 @@ 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.TableDataPageInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.ibs.cmpm.domain.dto.CustLevelDTO;
import com.ruoyi.ibs.cmpm.domain.dto.CustManagerDTO;
@@ -104,6 +105,17 @@ public class GridCmpmController extends BaseController {
return success(gridCmpmService.getCustLevelListForManager());
}
@PostMapping("/custManager/export")
@Log(title = "绩效网格-管户报表异步导出", businessType = BusinessType.EXPORT)
@ApiOperation("管户报表异步导出")
public AjaxResult exportCustManager(@RequestBody(required = false) CustManagerDTO custManagerDTO) {
if (custManagerDTO == null) {
custManagerDTO = new CustManagerDTO();
}
String taskId = gridCmpmService.exportCustManagerAsync(custManagerDTO);
return AjaxResult.success("导出任务创建成功,请稍后前往下载中心下载", taskId);
}
@GetMapping("/custLevel/count")
@Log(title = "绩效网格-查询客户分层等级")
@ApiOperation("查询客户分层等级")

View File

@@ -1,7 +1,6 @@
package com.ruoyi.ibs.cmpm.domain.vo;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -24,74 +23,92 @@ public class DwbRetailCustLevelManagerDetailVO {
/** 网点号 */
@ApiModelProperty(value = "网点号")
@ExcelProperty("网点号")
private String outletId;
/** 网点名 */
@ApiModelProperty(value = "网点名")
@ExcelProperty("网点名")
private String outletName;
/** 支行号 */
@ApiModelProperty(value = "支行号")
@ExcelProperty("支行号")
private String branchId;
/** 支行名 */
@ApiModelProperty(value = "支行名")
@ExcelProperty("支行名")
private String branchName;
/** 客户名称 */
@ApiModelProperty(value = "客户名称")
@ExcelProperty("客户名称")
private String custName;
/** 客户证件号 */
@ApiModelProperty(value = "客户证件号")
@ExcelProperty("客户证件号")
private String custIdc;
/** 客户内码 */
@ApiModelProperty(value = "客户内码")
@ExcelProperty("客户内码")
private String custIsn;
/** 年龄 */
@ApiModelProperty(value = "年龄")
@ExcelProperty("年龄")
private String custAge;
/** 性别 */
@ApiModelProperty(value = "性别")
@ExcelProperty("性别")
private String custSex;
/** 联系电话 */
@ApiModelProperty(value = "联系电话")
@ExcelProperty("联系电话")
private String custPhone;
/** 联系地址 */
@ApiModelProperty(value = "联系地址")
@ExcelProperty("联系地址")
private String custAddress;
/** 总资产余额 */
@ApiModelProperty(value = "总资产余额")
@ExcelProperty("总资产余额")
private BigDecimal custAumBal;
/** 总资产余额较上月变动 */
@ApiModelProperty(value = "总资产余额较上月变动")
@ExcelProperty("总资产余额较上月变动")
private BigDecimal aumBalCompLm;
/** 总资产月日均 */
@ApiModelProperty(value = "总资产月日均")
@ExcelProperty("总资产余额月日均")
private BigDecimal custAumMonthAvg;
/** 客户星级 */
@ApiModelProperty(value = "客户星级")
@ExcelProperty("客户星级")
private String custLevel;
/** 星级较上月变动 */
@ApiModelProperty(value = "星级较上月变动")
@ExcelProperty("星级较上月变动")
private String custLevelCompLm;
/** 责任人 */
@ApiModelProperty(value = "责任人")
@ExcelProperty("责任人")
private String managerName;
/** 责任人柜员号 */
@ApiModelProperty(value = "责任人柜员号")
@ExcelProperty("责任人柜员号")
private String managerId;
}

View File

@@ -47,6 +47,11 @@ public interface GridCmpmMapper {
List<DwbRetailCustLevelManagerDetailVO> getCustManagerList(CustManagerDTO custManagerDTO);
List<DwbRetailCustLevelManagerDetailVO> getCustManagerListByPage(@Param("dto") CustManagerDTO custManagerDTO,
@Param("headId") String headId,
@Param("offset") Integer offset,
@Param("pageSize") Integer pageSize);
int getCustLevelCount(CustManagerDTO custManagerDTO);
List<CustBaseInfo> selectCustInfoFromGridCmpm(CustBaseInfo custBaseInfo);

View File

@@ -1,11 +1,15 @@
package com.ruoyi.ibs.cmpm.service;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.ibs.cmpm.domain.dto.CustLevelDTO;
import com.ruoyi.ibs.cmpm.domain.dto.CustManagerDTO;
import com.ruoyi.ibs.cmpm.domain.dto.GridCmpmListDTO;
@@ -14,11 +18,19 @@ import com.ruoyi.ibs.cmpm.domain.vo.DwbRetailCustLevelManagerDetailVO;
import com.ruoyi.ibs.cmpm.domain.vo.DwbRetailResultVO;
import com.ruoyi.ibs.cmpm.domain.vo.GridCmpmVO;
import com.ruoyi.ibs.cmpm.mapper.GridCmpmMapper;
import com.ruoyi.ibs.task.domain.entity.ImportExportTask;
import com.ruoyi.ibs.task.mapper.ImportExportTaskMapper;
import com.ruoyi.system.enums.OssFileEnum;
import com.ruoyi.system.service.OssFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.File;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -27,6 +39,7 @@ import java.util.stream.Collectors;
* @Date 2025/10/15
**/
@Service
@Slf4j
public class GridCmpmService {
@@ -39,6 +52,15 @@ public class GridCmpmService {
@Resource
private RedisCache redisCache;
@Resource
private ImportExportTaskMapper importExportTaskMapper;
@Resource
private OssFileService ossFileService;
@Resource(name = "excelExportExecutor")
private ExecutorService executorService;
private final String CUST_LEVEL_COUNT_KEY = "GRID_CMPM_CUST_LEVEL_COUNT_";
public List<GridCmpmVO> selectManageList(GridCmpmListDTO gridCmpmRetailListDTO){
@@ -94,33 +116,32 @@ public class GridCmpmService {
}
public List<DwbRetailCustLevelManagerDetailVO> selectCustManagerList(CustManagerDTO custManagerDTO) {
String userRole = SecurityUtils.userRole();
if (userRole.equals("manager")){
//客户经理查自己
custManagerDTO.setManagerId(SecurityUtils.getUsername());
}else if (userRole.equals("outlet")){
//网点管理员查网点
custManagerDTO.setOutletId(String.valueOf(SecurityUtils.getDeptId()));
}else if (userRole.equals("branch")){
//支行管理员查支行
custManagerDTO.setBranchId(String.valueOf(SecurityUtils.getDeptId()));
}
//其他角色查全部
applyCustManagerScope(custManagerDTO);
return gridCmpmMapper.getCustManagerList(custManagerDTO);
}
public String exportCustManagerAsync(CustManagerDTO custManagerDTO) {
applyCustManagerScope(custManagerDTO);
String headId = SecurityUtils.getHeadId();
ImportExportTask task = new ImportExportTask();
String taskId = IdUtils.randomUUID();
task.setId(taskId);
task.setStatus("0");
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
task.setFileName(sdf.format(now) + "管户报表导出");
task.setUserName(SecurityUtils.getUsername());
task.setCreateTime(now);
importExportTaskMapper.insert(task);
String userName = SecurityUtils.getUsername();
executorService.submit(() -> doExportCustManager(taskId, custManagerDTO, userName, headId));
return taskId;
}
public int custLevelCount(CustManagerDTO custManagerDTO) {
String userRole = SecurityUtils.userRole();
if (userRole.equals("manager")){
//客户经理查自己
custManagerDTO.setManagerId(SecurityUtils.getUsername());
}else if (userRole.equals("outlet")){
//网点管理员查网点
custManagerDTO.setOutletId(String.valueOf(SecurityUtils.getDeptId()));
}else if (userRole.equals("branch")){
//支行管理员查支行
custManagerDTO.setBranchId(String.valueOf(SecurityUtils.getDeptId()));
}
applyCustManagerScope(custManagerDTO);
return gridCmpmMapper.getCustLevelCount(custManagerDTO);
}
@@ -274,6 +295,64 @@ public class GridCmpmService {
return custLevelCountMap;
}
private void applyCustManagerScope(CustManagerDTO custManagerDTO) {
String userRole = SecurityUtils.userRole();
if (userRole.equals("manager")) {
custManagerDTO.setManagerId(SecurityUtils.getUsername());
} else if (userRole.equals("outlet")) {
custManagerDTO.setOutletId(String.valueOf(SecurityUtils.getDeptId()));
} else if (userRole.equals("branch")) {
custManagerDTO.setBranchId(String.valueOf(SecurityUtils.getDeptId()));
}
}
private void doExportCustManager(String taskId, CustManagerDTO custManagerDTO, String userName, String headId) {
ImportExportTask task = importExportTaskMapper.selectById(taskId);
File tempFile = null;
try {
tempFile = File.createTempFile("管户报表导出_" + taskId + "-", ".xlsx");
ExcelWriter excelWriter = EasyExcel.write(tempFile, DwbRetailCustLevelManagerDetailVO.class).build();
WriteSheet writeSheet = EasyExcel.writerSheet("管户报表").build();
int pageSize = 1000;
int pageNum = 0;
List<DwbRetailCustLevelManagerDetailVO> pageData;
do {
pageData = gridCmpmMapper.getCustManagerListByPage(custManagerDTO, headId, pageNum * pageSize, pageSize);
if (!pageData.isEmpty()) {
excelWriter.write(pageData, writeSheet);
}
pageNum++;
} while (pageData.size() == pageSize);
excelWriter.finish();
String ossUUId = ossFileService.uploadFileToOss(
OssFileEnum.CUST_MANAGER_REPORT,
tempFile,
"管户报表导出_" + taskId + ".xlsx",
userName
);
task.setStatus("1");
task.setFileUrl(ossUUId);
task.setFinishTime(new Date());
importExportTaskMapper.updateById(task);
} catch (Exception e) {
task.setStatus("2");
task.setFinishTime(new Date());
task.setErrorMsg(e.getMessage());
importExportTaskMapper.updateById(task);
} finally {
if (Objects.nonNull(tempFile)) {
boolean deleted = tempFile.delete();
if (!deleted) {
log.warn("临时文件删除失败: {}", tempFile.getAbsolutePath());
}
}
}
}
// 计算客户等级变化情况
private Map<String, Integer> calculateLevelChanges(Map<String, Integer> historyMap, Map<String, Integer> currentMap) {
Map<String, Integer> changesMap = new HashMap<>();

View File

@@ -1,12 +1,15 @@
package com.ruoyi.ibs.task.controller;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import com.github.pagehelper.Page;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.page.TableDataPageInfo;
import com.ruoyi.ibs.task.domain.dto.AlterForwardRequest;
import com.ruoyi.ibs.task.domain.dto.WorkRecordDTO;
import com.ruoyi.ibs.task.domain.entity.Alter;
import com.ruoyi.ibs.task.domain.entity.AlterConfig;
@@ -95,12 +98,37 @@ public class WorkRecordController extends BaseController {
@GetMapping("/alter/allList")
@Log(title = "工作台-查询预警信息")
@ApiOperation("查询所有预警信息")
public TableDataPageInfo<AlterVO> allAlterList(String status, String alterType) {
public TableDataPageInfo<AlterVO> allAlterList(String status, String alterType, String forwardFlag) {
Page<Object> page = startPage();
List<AlterVO> list = workRecordService.getAllAlterList(status, alterType);
List<AlterVO> list = workRecordService.getAllAlterList(status, alterType, forwardFlag);
return getDataTable(list, page);
}
@GetMapping("/alter/forward/meta")
@Log(title = "工作台-查询预警转发元数据")
@ApiOperation("查询预警转发元数据")
public AjaxResult getAlterForwardMeta(@RequestParam String ids) {
List<Long> idList = Arrays.stream(ids.split(","))
.filter(org.apache.commons.lang3.StringUtils::isNotBlank)
.map(Long::valueOf)
.collect(Collectors.toList());
return AjaxResult.success(workRecordService.getAlterForwardMeta(idList));
}
@PostMapping("/alter/forward")
@Log(title = "工作台-转发预警信息")
@ApiOperation("批量转发预警信息")
public AjaxResult forwardAlter(@Validated @RequestBody AlterForwardRequest request) {
AlterForwardResultVO result = workRecordService.forwardAlter(request);
if (result.getSuccessCount() > 0 && result.getFailCount() > 0) {
return AjaxResult.success("成功转发" + result.getSuccessCount() + "条,失败" + result.getFailCount() + "", result);
}
if (result.getSuccessCount() > 0) {
return AjaxResult.success("成功转发" + result.getSuccessCount() + "", result);
}
return AjaxResult.error("未能成功转发,失败" + result.getFailCount() + "");
}
@GetMapping("/alter/count")
@Log(title = "工作台-查询预警推送次数")
@ApiOperation("查询预警推送次数")

View File

@@ -0,0 +1,23 @@
package com.ruoyi.ibs.task.domain.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
@Data
public class AlterForwardRequest {
@NotEmpty(message = "请选择需要转发的预警")
private List<Long> ids;
@NotBlank(message = "请选择转发目标类型")
private String targetType;
private Long deptId;
private String userName;
private Boolean useHistory;
}

View File

@@ -0,0 +1,19 @@
package com.ruoyi.ibs.task.domain.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class ForwardTarget {
private String targetType;
private Long deptId;
private String userName;
private String nickName;
private String targetName;
}

View File

@@ -0,0 +1,53 @@
package com.ruoyi.ibs.task.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("alter_assign_history")
public class AlterAssignHistory implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
@ApiModelProperty("预警类型")
private String alterType;
@ApiModelProperty("客户号")
private String custId;
@ApiModelProperty("客户姓名")
private String custName;
@ApiModelProperty("所属支行/当前操作机构ID")
private Long deptId;
@ApiModelProperty("最近一次转发目标类型dept/user")
private String lastAssignTargetType;
@ApiModelProperty("最近一次转发目标部门ID")
private Long lastAssignTargetDeptId;
@ApiModelProperty("最近一次转发目标用户账号")
private String lastAssignTargetUser;
@ApiModelProperty("最近一次转发目标名称")
private String lastAssignTargetName;
@ApiModelProperty("最近一次转发操作人账号")
private String lastAssignByUser;
@ApiModelProperty("最近一次转发操作人角色")
private String lastAssignByRole;
@ApiModelProperty("更新时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}

View File

@@ -94,4 +94,8 @@ public class WorkRecord implements Serializable {
@ApiModelProperty(value = "是否逾期", notes = "")
private Integer isOverdue;
/** 当前承接部门ID仅转发到网点时使用 */
@ApiModelProperty(value = "当前承接部门ID", notes = "")
private Long deptId;
}

View File

@@ -0,0 +1,14 @@
package com.ruoyi.ibs.task.domain.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class AlterAssignTargetVO {
@ApiModelProperty("目标编码")
private String targetCode;
@ApiModelProperty("目标名称")
private String targetName;
}

View File

@@ -0,0 +1,32 @@
package com.ruoyi.ibs.task.domain.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class AlterForwardMetaVO {
@ApiModelProperty("可选网点列表")
private List<AlterAssignTargetVO> deptOptions = new ArrayList<>();
@ApiModelProperty("可选客户经理列表")
private List<AlterAssignTargetVO> userOptions = new ArrayList<>();
@ApiModelProperty("历史推荐目标类型dept/user")
private String recommendedTargetType;
@ApiModelProperty("历史推荐目标编码")
private String recommendedTargetCode;
@ApiModelProperty("历史推荐目标名称")
private String recommendedTargetName;
@ApiModelProperty("是否仅允许按历史推荐转发")
private Boolean historyOnly = false;
@ApiModelProperty("是否存在历史推荐")
private Boolean hasHistoryRecommend = false;
}

View File

@@ -0,0 +1,14 @@
package com.ruoyi.ibs.task.domain.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class AlterForwardResultVO {
@ApiModelProperty("成功数量")
private int successCount;
@ApiModelProperty("失败数量")
private int failCount;
}

View File

@@ -47,6 +47,14 @@ public class AlterVO {
@ApiModelProperty(value = "客户内码", notes = "")
private String custIsn;
/** 当前承接部门ID */
@ApiModelProperty(value = "当前承接部门ID", notes = "")
private Long deptId;
/** 当前承接网点名称 */
@ApiModelProperty(value = "当前承接网点名称", notes = "")
private String deptName;
/** 状态 */
@ApiModelProperty(value = "状态", notes = "")
private String status;
@@ -62,4 +70,12 @@ public class AlterVO {
/** 是否需要反馈 */
@ApiModelProperty(value = "是否需要反馈", notes = "")
private String isFeedback;
/** 转发标识1需要转发0无需转发 */
@ApiModelProperty(value = "转发标识", notes = "")
private String forwardFlag;
/** 是否可转发 */
@ApiModelProperty(value = "是否可转发", notes = "")
private Boolean canForward;
}

View File

@@ -0,0 +1,9 @@
package com.ruoyi.ibs.task.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.ibs.task.domain.entity.AlterAssignHistory;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AlterAssignHistoryMapper extends BaseMapper<AlterAssignHistory> {
}

View File

@@ -6,9 +6,9 @@ import java.util.Date;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.ibs.task.domain.entity.WorkRecord;
import com.ruoyi.ibs.task.domain.dto.WorkRecordDTO;
import com.ruoyi.ibs.task.domain.entity.AlterConfig;
import com.ruoyi.ibs.task.domain.entity.WorkRecord;
import com.ruoyi.ibs.task.domain.vo.*;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -86,10 +86,26 @@ public interface WorkRecordMapper extends BaseMapper<WorkRecord> {
* @return 预警信息
*/
List<AlterVO> selectAllAlterList(@Param("deptId") String deptId, @Param("role") String role,
@Param("status") String status, @Param("alterType") String alterType, @Param("username") String username);
@Param("status") String status, @Param("alterType") String alterType,
@Param("username") String username, @Param("forwardFlag") String forwardFlag);
AlterCountVO selectAlterCount(@Param("reportTime") Date reportTime, @Param("role") String role, @Param("deptId") String deptId);
List<AlterAssignTargetVO> selectForwardDeptTargets(@Param("branchDeptId") Long branchDeptId);
List<AlterAssignTargetVO> selectForwardUserTargets(@Param("deptId") Long deptId, @Param("role") String role);
int updateAlterForwardToDept(@Param("id") Long id, @Param("sourceUserName") String sourceUserName,
@Param("targetDeptId") Long targetDeptId, @Param("updateBy") String updateBy);
int updateAlterForwardToUserByBranch(@Param("id") Long id, @Param("sourceUserName") String sourceUserName,
@Param("targetUserName") String targetUserName, @Param("targetNickName") String targetNickName,
@Param("updateBy") String updateBy);
int updateAlterForwardToUserByOutlet(@Param("id") Long id, @Param("sourceDeptId") Long sourceDeptId,
@Param("targetUserName") String targetUserName, @Param("targetNickName") String targetNickName,
@Param("updateBy") String updateBy);
/**
* 设置工作清单为过期
*

View File

@@ -5,6 +5,7 @@ import java.util.List;
import com.ruoyi.common.core.page.TableDataPageInfo;
import com.ruoyi.ibs.task.domain.dto.WorkRecordDTO;
import com.ruoyi.ibs.task.domain.dto.AlterForwardRequest;
import com.ruoyi.ibs.task.domain.entity.AlterConfig;
import com.ruoyi.ibs.task.domain.entity.WorkRecord;
import com.ruoyi.ibs.task.domain.vo.*;
@@ -61,7 +62,23 @@ public interface WorkRecordService{
* @param alterType
* @return
*/
List<AlterVO> getAllAlterList(String status, String alterType);
List<AlterVO> getAllAlterList(String status, String alterType, String forwardFlag);
/**
* 获取预警转发元数据
*
* @param id 预警ID
* @return 转发元数据
*/
AlterForwardMetaVO getAlterForwardMeta(List<Long> ids);
/**
* 批量转发预警
*
* @param request 转发请求
* @return 结果
*/
AlterForwardResultVO forwardAlter(AlterForwardRequest request);
/**
* 定时任务生成工作清单
*

View File

@@ -11,20 +11,29 @@ import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.Page;
import com.ruoyi.common.core.page.TableDataPageInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.ibs.task.domain.dto.AlterForwardRequest;
import com.ruoyi.ibs.task.domain.dto.ForwardTarget;
import com.ruoyi.ibs.task.domain.dto.WorkRecordDTO;
import com.ruoyi.ibs.task.domain.entity.AlterAssignHistory;
import com.ruoyi.ibs.task.domain.entity.AlterConfig;
import com.ruoyi.ibs.task.domain.entity.WorkRecord;
import com.ruoyi.ibs.task.domain.vo.*;
import com.ruoyi.ibs.task.mapper.AlterAssignHistoryMapper;
import com.ruoyi.ibs.task.mapper.WorkRecordMapper;
import com.ruoyi.ibs.task.service.WorkRecordService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -41,16 +50,31 @@ import org.springframework.transaction.annotation.Transactional;
public class WorkRecordServiceImpl implements WorkRecordService {
private final static String alterTypesRedisKey = "work:record:alter:types";
private static final String ROLE_MANAGER = "manager";
private static final String ROLE_BRANCH = "branch";
private static final String ROLE_OUTLET = "outlet";
private static final String TARGET_TYPE_DEPT = "dept";
private static final String TARGET_TYPE_USER = "user";
private static final Set<String> FORWARD_ALTER_TYPES = new HashSet<>(Arrays.asList(
"个人资产客户定期存款",
"个人资产客户封闭式理财"
));
@Autowired
private WorkRecordMapper workRecordMapper;
@Autowired
private AlterAssignHistoryMapper alterAssignHistoryMapper;
@Autowired
private ISysPostService sysPostService;
@Autowired
private ISysDeptService sysDeptService;
@Autowired
private ISysUserService sysUserService;
@Autowired
private RedisCache redisCache;
@@ -143,7 +167,9 @@ public class WorkRecordServiceImpl implements WorkRecordService {
@Transactional(rollbackFor = Exception.class)
public List<AlterVO> getAlterList(String status, String alterType) {
String username = SecurityUtils.getUsername();
return workRecordMapper.selectAlterList(username, status, alterType);
List<AlterVO> alterVOS = workRecordMapper.selectAlterList(username, status, alterType);
fillAlterExtFields(alterVOS);
return alterVOS;
}
/**
@@ -156,27 +182,98 @@ public class WorkRecordServiceImpl implements WorkRecordService {
* @return 预警信息
*/
@Override
public List<AlterVO> getAllAlterList(String status, String alterType) {
List<AlterVO> alterVOS = workRecordMapper.selectAllAlterList(String.valueOf(SecurityUtils.getDeptId()), SecurityUtils.userRole(), status, alterType, SecurityUtils.getUsername());
// 将 userName 和 nickName 以 "userName-nickName" 的方式拼接后设置到 custInfo 字段
if (alterVOS != null && !alterVOS.isEmpty()) {
alterVOS.forEach(alterVO -> {
String userName = alterVO.getUserName();
String nickName = alterVO.getNickName();
if (userName != null && nickName != null) {
alterVO.setUserInfo(nickName + "-" + userName);
} else if (userName != null) {
alterVO.setUserInfo(userName);
} else if (nickName != null) {
alterVO.setUserInfo(nickName);
} else {
alterVO.setUserInfo("");
}
});
}
public List<AlterVO> getAllAlterList(String status, String alterType, String forwardFlag) {
List<AlterVO> alterVOS = workRecordMapper.selectAllAlterList(
String.valueOf(SecurityUtils.getDeptId()),
SecurityUtils.userRole(),
status,
alterType,
SecurityUtils.getUsername(),
forwardFlag
);
fillAlterExtFields(alterVOS);
return alterVOS;
}
/**
* 查询转发弹窗所需元数据。
* 单选时返回手动选项并附带历史推荐;多选时根据是否存在历史记录决定走手动分配还是历史推荐模式。
*/
@Override
public AlterForwardMetaVO getAlterForwardMeta(List<Long> ids) {
if (ids == null || ids.isEmpty()) {
throw new ServiceException("请选择需要转发的预警");
}
AlterForwardMetaVO metaVO = new AlterForwardMetaVO();
String role = requireForwardRole();
Long currentDeptId = SecurityUtils.getDeptId();
String currentUser = SecurityUtils.getUsername();
List<WorkRecord> workRecords = workRecordMapper.selectBatchIds(ids);
if (workRecords == null || workRecords.size() != ids.size()) {
throw new ServiceException("存在预警记录已不存在,请刷新后重试");
}
workRecords.forEach(item -> validateRecordBeforeForward(item, role, currentUser, currentDeptId));
if (ids.size() > 1) {
boolean hasAnyHistory = workRecords.stream()
.map(item -> getHistoryRecommend(item.getCustId(), currentDeptId, role))
.anyMatch(Objects::nonNull);
metaVO.setHasHistoryRecommend(hasAnyHistory);
metaVO.setHistoryOnly(hasAnyHistory);
if (!hasAnyHistory) {
fillManualOptions(metaVO, role, currentDeptId);
}
return metaVO;
}
WorkRecord workRecord = workRecords.get(0);
fillManualOptions(metaVO, role, currentDeptId);
fillHistoryRecommend(metaVO, workRecord.getCustId(), currentDeptId, role);
return metaVO;
}
/**
* 执行预警转发。
* 支持手动分配和按历史推荐分配两种模式,并分别统计成功和失败数量。
*/
@Override
@Transactional(rollbackFor = Exception.class)
public AlterForwardResultVO forwardAlter(AlterForwardRequest request) {
String role = requireForwardRole();
String currentUser = SecurityUtils.getUsername();
Long currentDeptId = SecurityUtils.getDeptId();
AlterForwardResultVO result = new AlterForwardResultVO();
boolean useHistory = Boolean.TRUE.equals(request.getUseHistory());
ForwardTarget manualTarget = useHistory ? null : resolveManualTarget(request, role, currentDeptId);
List<WorkRecord> workRecords = workRecordMapper.selectBatchIds(request.getIds());
if (workRecords == null || workRecords.size() != request.getIds().size()) {
throw new ServiceException("存在预警记录已不存在,请刷新后重试");
}
for (WorkRecord workRecord : workRecords) {
validateRecordBeforeForward(workRecord, role, currentUser, currentDeptId);
AlterAssignHistory history = useHistory ? getHistoryRecommend(workRecord.getCustId(), currentDeptId, role) : null;
ForwardTarget target = useHistory ? resolveHistoryTarget(history, role, currentDeptId) : manualTarget;
if (target == null) {
result.setFailCount(result.getFailCount() + 1);
continue;
}
int row = doForward(workRecord.getId(), currentUser, currentDeptId, role, target);
if (row <= 0) {
result.setFailCount(result.getFailCount() + 1);
continue;
}
result.setSuccessCount(result.getSuccessCount() + row);
if (useHistory) {
if (history != null) {
saveAssignHistoryByHistory(workRecord, history, role, currentDeptId);
}
} else {
saveAssignHistory(workRecord, manualTarget, role, currentDeptId);
}
}
return result;
}
/**
* 定时任务生成工作清单
*
@@ -351,4 +448,306 @@ public class WorkRecordServiceImpl implements WorkRecordService {
return java.sql.Timestamp.valueOf(endTime);
}
private void fillAlterExtFields(List<AlterVO> alterVOS) {
if (alterVOS == null || alterVOS.isEmpty()) {
return;
}
String role = SecurityUtils.userRole();
Long currentDeptId = SecurityUtils.getDeptId();
String currentUser = SecurityUtils.getUsername();
alterVOS.forEach(alterVO -> {
alterVO.setForwardFlag(parseForwardFlag(alterVO.getAlterDetail()));
alterVO.setAlterDetail(stripForwardPrefix(alterVO.getAlterDetail()));
alterVO.setUserInfo(buildUserInfo(alterVO.getUserName(), alterVO.getNickName()));
alterVO.setCanForward(canForward(alterVO, role, currentDeptId, currentUser));
});
}
private String buildUserInfo(String userName, String nickName) {
if (StringUtils.isNotEmpty(userName) && StringUtils.isNotEmpty(nickName)) {
return nickName + "-" + userName;
}
if (StringUtils.isNotEmpty(userName)) {
return userName;
}
if (StringUtils.isNotEmpty(nickName)) {
return nickName;
}
return "";
}
private String parseForwardFlag(String alterDetail) {
if (StringUtils.isEmpty(alterDetail)) {
return "";
}
if (alterDetail.startsWith("[FORWARD=1]")) {
return "1";
}
if (alterDetail.startsWith("[FORWARD=0]")) {
return "0";
}
return "";
}
private String stripForwardPrefix(String alterDetail) {
if (StringUtils.isEmpty(alterDetail)) {
return alterDetail;
}
if (alterDetail.startsWith("[FORWARD=1] ")) {
return alterDetail.substring(12);
}
if (alterDetail.startsWith("[FORWARD=0] ")) {
return alterDetail.substring(12);
}
if (alterDetail.startsWith("[FORWARD=1]") || alterDetail.startsWith("[FORWARD=0]")) {
return alterDetail.substring(11);
}
return alterDetail;
}
private Boolean canForward(AlterVO alterVO, String role, Long currentDeptId, String currentUser) {
if (!FORWARD_ALTER_TYPES.contains(alterVO.getAlterType())) {
return false;
}
if (!"1".equals(alterVO.getForwardFlag())) {
return false;
}
if ("2".equals(alterVO.getStatus())) {
return false;
}
if (ROLE_BRANCH.equals(role)) {
return StringUtils.equals(currentUser, alterVO.getUserName()) && alterVO.getDeptId() == null;
}
if (ROLE_OUTLET.equals(role)) {
return alterVO.getDeptId() != null && alterVO.getDeptId().equals(currentDeptId) && StringUtils.isEmpty(alterVO.getUserName());
}
return false;
}
/**
* 校验当前登录角色是否具备预警转发能力,并返回角色标识。
*/
private String requireForwardRole() {
String role = SecurityUtils.userRole();
if (!ROLE_BRANCH.equals(role) && !ROLE_OUTLET.equals(role)) {
throw new ServiceException("当前角色不支持转发预警");
}
return role;
}
/**
* 校验预警记录当前是否仍处于登录人可转发范围内,防止页面停留期间数据状态已变化。
*/
private void validateRecordBeforeForward(WorkRecord workRecord, String role, String currentUser, Long currentDeptId) {
if (workRecord == null || workRecord.getId() == null) {
throw new ServiceException("预警记录不存在");
}
if (!Integer.valueOf(1).equals(workRecord.getIsAlter())) {
throw new ServiceException("当前记录不是预警信息");
}
if (!FORWARD_ALTER_TYPES.contains(workRecord.getAlterType())) {
throw new ServiceException("当前预警类型不支持转发");
}
if (!"1".equals(parseForwardFlag(workRecord.getAlterDetail()))) {
throw new ServiceException("当前预警已有管户,无需转发");
}
if ("2".equals(workRecord.getStatus())) {
throw new ServiceException("当前预警已完成,不能转发");
}
if (ROLE_BRANCH.equals(role)) {
if (!StringUtils.equals(currentUser, workRecord.getUserName()) || workRecord.getDeptId() != null) {
throw new ServiceException("当前预警已不在您的待转发范围内");
}
return;
}
if (ROLE_OUTLET.equals(role)) {
if (workRecord.getDeptId() == null || !workRecord.getDeptId().equals(currentDeptId) || StringUtils.isNotEmpty(workRecord.getUserName())) {
throw new ServiceException("当前预警已不在本网点待转发范围内");
}
return;
}
throw new ServiceException("当前角色不支持转发预警");
}
/**
* 解析手动转发目标,并顺带完成目标权限范围校验。
*/
private ForwardTarget resolveManualTarget(AlterForwardRequest request, String role, Long currentDeptId) {
if (TARGET_TYPE_DEPT.equals(request.getTargetType())) {
if (request.getDeptId() == null) {
throw new ServiceException("请选择转发网点");
}
if (!ROLE_BRANCH.equals(role)) {
throw new ServiceException("网点管理员只能转发给客户经理");
}
String deptName = getAllowedDeptName(request.getDeptId(), currentDeptId);
return new ForwardTarget(TARGET_TYPE_DEPT, request.getDeptId(), null, null, deptName);
}
if (!TARGET_TYPE_USER.equals(request.getTargetType()) || StringUtils.isEmpty(request.getUserName())) {
throw new ServiceException("请选择转发客户经理");
}
SysUser user = getAllowedTargetUser(request.getUserName(), role, currentDeptId);
String targetName = StringUtils.isNotEmpty(user.getNickName()) ? user.getNickName() : user.getUserName();
return new ForwardTarget(TARGET_TYPE_USER, null, user.getUserName(), user.getNickName(), targetName);
}
/**
* 将历史分配记录转换成可执行的转发目标;若历史目标已失效,则返回空。
*/
private ForwardTarget resolveHistoryTarget(AlterAssignHistory history, String role, Long currentDeptId) {
if (history == null) {
return null;
}
if (TARGET_TYPE_DEPT.equals(history.getLastAssignTargetType())) {
if (history.getLastAssignTargetDeptId() == null) {
return null;
}
String deptName = getAllowedDeptName(history.getLastAssignTargetDeptId(), currentDeptId);
return new ForwardTarget(TARGET_TYPE_DEPT, history.getLastAssignTargetDeptId(), null, null, deptName);
}
if (!TARGET_TYPE_USER.equals(history.getLastAssignTargetType()) || StringUtils.isEmpty(history.getLastAssignTargetUser())) {
return null;
}
try {
SysUser user = getAllowedTargetUser(history.getLastAssignTargetUser(), role, currentDeptId);
String targetName = StringUtils.isNotEmpty(user.getNickName()) ? user.getNickName() : user.getUserName();
return new ForwardTarget(TARGET_TYPE_USER, null, user.getUserName(), user.getNickName(), targetName);
} catch (ServiceException ex) {
return null;
}
}
/**
* 按目标类型执行真正的转发落库更新。
*/
private int doForward(Long workRecordId, String currentUser, Long currentDeptId, String role, ForwardTarget target) {
if (TARGET_TYPE_DEPT.equals(target.getTargetType())) {
return workRecordMapper.updateAlterForwardToDept(workRecordId, currentUser, target.getDeptId(), currentUser);
}
if (ROLE_BRANCH.equals(role)) {
return workRecordMapper.updateAlterForwardToUserByBranch(
workRecordId, currentUser, target.getUserName(), target.getNickName(), currentUser
);
}
return workRecordMapper.updateAlterForwardToUserByOutlet(
workRecordId, currentDeptId, target.getUserName(), target.getNickName(), currentUser
);
}
/**
* 校验目标网点是否在当前支行管理员的可转发范围内,并返回网点名称。
*/
private String getAllowedDeptName(Long targetDeptId, Long currentDeptId) {
List<AlterAssignTargetVO> deptOptions = workRecordMapper.selectForwardDeptTargets(currentDeptId);
return deptOptions.stream()
.filter(item -> String.valueOf(targetDeptId).equals(item.getTargetCode()))
.map(AlterAssignTargetVO::getTargetName)
.findFirst()
.orElseThrow(() -> new ServiceException("所选网点不在当前支行可转发范围内"));
}
/**
* 校验目标客户经理是否在当前管理员可转发范围内,并返回用户信息。
*/
private SysUser getAllowedTargetUser(String targetUserName, String role, Long currentDeptId) {
List<AlterAssignTargetVO> userOptions = workRecordMapper.selectForwardUserTargets(currentDeptId, ROLE_MANAGER);
boolean matched = userOptions.stream().anyMatch(item -> StringUtils.equals(targetUserName, item.getTargetCode()));
if (!matched) {
if (ROLE_BRANCH.equals(role)) {
throw new ServiceException("所选客户经理不在当前支行可转发范围内");
}
throw new ServiceException("所选客户经理不在当前网点可转发范围内");
}
SysUser user = sysUserService.selectUserByUserName(targetUserName);
if (user == null || StringUtils.isEmpty(user.getUserName())) {
throw new ServiceException("转发目标客户经理不存在");
}
return user;
}
/**
* 填充手动分配弹窗可选项;支行管理员可选网点和客户经理,网点管理员仅可选客户经理。
*/
private void fillManualOptions(AlterForwardMetaVO metaVO, String role, Long currentDeptId) {
if (ROLE_BRANCH.equals(role)) {
metaVO.setDeptOptions(workRecordMapper.selectForwardDeptTargets(currentDeptId));
metaVO.setUserOptions(workRecordMapper.selectForwardUserTargets(currentDeptId, ROLE_MANAGER));
return;
}
if (ROLE_OUTLET.equals(role)) {
metaVO.setUserOptions(workRecordMapper.selectForwardUserTargets(currentDeptId, ROLE_MANAGER));
return;
}
throw new ServiceException("当前角色不支持转发预警");
}
/**
* 按客户、当前部门和当前角色查询历史推荐,并回填到前端元数据中。
*/
private void fillHistoryRecommend(AlterForwardMetaVO metaVO, String custId, Long deptId, String role) {
AlterAssignHistory history = getHistoryRecommend(custId, deptId, role);
if (history == null) {
return;
}
metaVO.setHasHistoryRecommend(true);
metaVO.setRecommendedTargetType(history.getLastAssignTargetType());
if (TARGET_TYPE_DEPT.equals(history.getLastAssignTargetType())) {
metaVO.setRecommendedTargetCode(history.getLastAssignTargetDeptId() == null ? "" : String.valueOf(history.getLastAssignTargetDeptId()));
} else {
metaVO.setRecommendedTargetCode(history.getLastAssignTargetUser());
}
metaVO.setRecommendedTargetName(history.getLastAssignTargetName());
}
/**
* 保存本次手动分配结果;同一客户在同部门、同角色下只维护一条最新历史。
*/
private void saveAssignHistory(WorkRecord workRecord, ForwardTarget target, String role, Long currentDeptId) {
AlterAssignHistory history = getHistoryRecommend(workRecord.getCustId(), currentDeptId, role);
if (history == null) {
history = new AlterAssignHistory();
history.setCustId(workRecord.getCustId());
}
history.setAlterType(workRecord.getAlterType());
history.setCustName(workRecord.getCustName());
history.setDeptId(currentDeptId);
history.setLastAssignTargetType(target.getTargetType());
history.setLastAssignTargetDeptId(target.getDeptId());
history.setLastAssignTargetUser(target.getUserName());
history.setLastAssignTargetName(target.getTargetName());
history.setLastAssignByUser(SecurityUtils.getUsername());
history.setLastAssignByRole(role);
history.setUpdateTime(new Date());
if (history.getId() == null) {
alterAssignHistoryMapper.insert(history);
} else {
alterAssignHistoryMapper.updateById(history);
}
}
/**
* 按历史推荐成功转发后,刷新该客户最新一次分配历史的更新时间和目标信息。
*/
private void saveAssignHistoryByHistory(WorkRecord workRecord, AlterAssignHistory sourceHistory, String role, Long currentDeptId) {
ForwardTarget target = new ForwardTarget(
sourceHistory.getLastAssignTargetType(),
sourceHistory.getLastAssignTargetDeptId(),
sourceHistory.getLastAssignTargetUser(),
null,
sourceHistory.getLastAssignTargetName()
);
saveAssignHistory(workRecord, target, role, currentDeptId);
}
/**
* 获取当前角色在当前部门下,对指定客户的最近一次分配历史。
*/
private AlterAssignHistory getHistoryRecommend(String custId, Long deptId, String role) {
return alterAssignHistoryMapper.selectOne(new LambdaQueryWrapper<AlterAssignHistory>()
.eq(AlterAssignHistory::getCustId, custId)
.eq(AlterAssignHistory::getDeptId, deptId)
.eq(AlterAssignHistory::getLastAssignByRole, role)
.last("limit 1"));
}
}

View File

@@ -184,19 +184,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</insert>
<select id="selectAlterList" resultType="AlterVO">
select id, user_name, nick_name, alter_type, alter_detail, cust_id, cust_name, read_time, status, remark, is_feedback, cust_isn
from work_record
select wr.id, wr.user_name, wr.nick_name, wr.alter_type, wr.alter_detail, wr.cust_id, wr.cust_name,
wr.read_time, wr.status, wr.remark, wr.is_feedback, wr.cust_isn, wr.dept_id, sd.dept_name
from work_record wr
left join sys_dept sd on wr.dept_id = sd.dept_id
<where>
is_alter = 1
and user_name= #{username}
wr.is_alter = 1
and wr.user_name= #{username}
<if test="status != null and status != ''">
and status = #{status}
and wr.status = #{status}
</if>
<if test="alterType != null and alterType != ''">
and alter_type = #{alterType}
and wr.alter_type = #{alterType}
</if>
</where>
order by create_time desc, status asc
order by wr.create_time desc, wr.status asc
</select>
<select id="selectAlterCount" resultType="AlterCountVO">
@@ -209,24 +211,27 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
from work_record wr
left join sys_user su on su.user_name = wr.user_name
left join sys_dept d on su.dept_id = d.dept_id
left join sys_dept wd on wr.dept_id = wd.dept_id
where wr.is_alter = 1
and wr.create_time &lt;= #{reportTime}
and (
<choose>
<when test="role != null and role == 'outlet'"> su.dept_id = #{deptId} </when>
<when test="role != null and role == 'branch'"> (su.dept_id = #{deptId} or find_in_set(#{deptId},d.ancestors)) </when>
<when test="role != null and role == 'private'"> (left(su.dept_id,3) = left(#{deptId},3) and wr.cust_type in ('0', '1')) </when>
<when test="role != null and role == 'public'"> (left(su.dept_id,3) = left(#{deptId},3) and wr.cust_type = '2') </when>
<when test="role != null and role == 'ops'"> left(su.dept_id,3) = left(#{deptId},3) </when>
<when test="role != null and role == 'head'"> left(su.dept_id,3) = left(#{deptId},3) </when>
<when test="role != null and role == 'outlet'"> (su.dept_id = #{deptId} or wr.dept_id = #{deptId}) </when>
<when test="role != null and role == 'branch'"> ((su.dept_id = #{deptId} or find_in_set(#{deptId},d.ancestors)) or (wr.dept_id = #{deptId} or find_in_set(#{deptId},wd.ancestors))) </when>
<when test="role != null and role == 'private'"> ((left(su.dept_id,3) = left(#{deptId},3) or left(wr.dept_id,3) = left(#{deptId},3)) and wr.cust_type in ('0', '1')) </when>
<when test="role != null and role == 'public'"> ((left(su.dept_id,3) = left(#{deptId},3) or left(wr.dept_id,3) = left(#{deptId},3)) and wr.cust_type = '2') </when>
<when test="role != null and role == 'ops'"> (left(su.dept_id,3) = left(#{deptId},3) or left(wr.dept_id,3) = left(#{deptId},3)) </when>
<when test="role != null and role == 'head'"> (left(su.dept_id,3) = left(#{deptId},3) or left(wr.dept_id,3) = left(#{deptId},3)) </when>
</choose>)
</select>
<select id="selectAllAlterList" resultType="AlterVO">
select wr.id, wr.user_name, wr.nick_name, wr.alter_type, wr.alter_detail, wr.cust_id, wr.cust_name, wr.read_time, wr.status, wr.remark, wr.cust_type, wr.is_feedback, wr.cust_isn
select wr.id, wr.user_name, wr.nick_name, wr.alter_type, wr.alter_detail, wr.cust_id, wr.cust_name, wr.read_time,
wr.status, wr.remark, wr.cust_type, wr.is_feedback, wr.cust_isn, wr.dept_id, wd.dept_name
from work_record wr
left join sys_user su on su.user_name = wr.user_name
left join sys_dept d on su.dept_id = d.dept_id
left join sys_dept wd on wr.dept_id = wd.dept_id
where wr.is_alter = 1
<if test="status != null and status != ''">
and wr.status = #{status}
@@ -234,20 +239,120 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="alterType != null and alterType != ''">
and wr.alter_type = #{alterType}
</if>
<if test="forwardFlag != null and forwardFlag != ''">
<choose>
<when test='forwardFlag == "1"'>
and wr.alter_type in ('个人资产客户定期存款', '个人资产客户封闭式理财')
and wr.alter_detail like '[FORWARD=1]%'
</when>
<when test='forwardFlag == "0"'>
and (
(wr.alter_type in ('个人资产客户定期存款', '个人资产客户封闭式理财')
and wr.alter_detail like '[FORWARD=0]%')
or wr.alter_type not in ('个人资产客户定期存款', '个人资产客户封闭式理财')
)
</when>
</choose>
</if>
<!-- "走访异常提醒"类型直接通过用户名匹配,其他类型按角色权限处理 -->
and ((wr.alter_type = '走访异常提醒' and wr.user_name = #{username}) or
(wr.alter_type != '走访异常提醒' and (
<choose>
<when test="role != null and role == 'outlet'"> su.dept_id = #{deptId} </when>
<when test="role != null and role == 'branch'"> (su.dept_id = #{deptId} or find_in_set(#{deptId},d.ancestors)) </when>
<when test="role != null and role == 'private'"> (left(su.dept_id,3) = left(#{deptId},3) and wr.cust_type in ('0', '1')) </when>
<when test="role != null and role == 'public'"> (left(su.dept_id,3) = left(#{deptId},3) and wr.cust_type = '2') </when>
<when test="role != null and role == 'ops'"> left(su.dept_id,3) = left(#{deptId},3) </when>
<when test="role != null and role == 'head'"> left(su.dept_id,3) = left(#{deptId},3) </when>
<when test="role != null and role == 'outlet'"> (su.dept_id = #{deptId} or wr.dept_id = #{deptId}) </when>
<when test="role != null and role == 'branch'"> ((su.dept_id = #{deptId} or find_in_set(#{deptId},d.ancestors)) or (wr.dept_id = #{deptId} or find_in_set(#{deptId},wd.ancestors))) </when>
<when test="role != null and role == 'private'"> ((left(su.dept_id,3) = left(#{deptId},3) or left(wr.dept_id,3) = left(#{deptId},3)) and wr.cust_type in ('0', '1')) </when>
<when test="role != null and role == 'public'"> ((left(su.dept_id,3) = left(#{deptId},3) or left(wr.dept_id,3) = left(#{deptId},3)) and wr.cust_type = '2') </when>
<when test="role != null and role == 'ops'"> (left(su.dept_id,3) = left(#{deptId},3) or left(wr.dept_id,3) = left(#{deptId},3)) </when>
<when test="role != null and role == 'head'"> (left(su.dept_id,3) = left(#{deptId},3) or left(wr.dept_id,3) = left(#{deptId},3)) </when>
</choose> )))
order by wr.create_time desc, wr.status asc, wr.user_name desc
</select>
<select id="selectForwardDeptTargets" resultType="AlterAssignTargetVO">
select cast(sd.dept_id as char) as targetCode, sd.dept_name as targetName
from sys_dept sd
where sd.del_flag = '0'
and sd.status = '0'
and sd.dept_type = 'outlet'
and sd.parent_id = #{branchDeptId}
order by sd.order_num, sd.dept_id
</select>
<select id="selectForwardUserTargets" resultType="AlterAssignTargetVO">
select su.user_name as targetCode, concat(su.nick_name, '-', su.user_name) as targetName
from sys_user su
where su.del_flag = '0'
and su.status = '0'
and su.dept_id = #{deptId}
<choose>
<when test="role == 'manager'">
and su.role_id = 102
</when>
<when test="role == 'branch'">
and su.role_id = 101
</when>
<when test="role == 'outlet'">
and su.role_id = 116
</when>
<otherwise>
and 1 = 2
</otherwise>
</choose>
order by su.nick_name, su.user_name
</select>
<update id="updateAlterForwardToDept">
update work_record
set user_name = null,
nick_name = null,
dept_id = #{targetDeptId},
read_time = null,
update_time = sysdate(),
update_by = #{updateBy}
where id = #{id}
and user_name = #{sourceUserName}
and dept_id is null
and is_alter = 1
</update>
<update id="updateAlterForwardToUserByBranch">
update work_record
set user_name = #{targetUserName},
nick_name = #{targetNickName},
alter_detail = case
when alter_detail like '[FORWARD=1] %' then concat('[FORWARD=0] ', substring(alter_detail, 13))
when alter_detail like '[FORWARD=1]%' then concat('[FORWARD=0]', substring(alter_detail, 12))
else alter_detail
end,
dept_id = null,
read_time = null,
update_time = sysdate(),
update_by = #{updateBy}
where id = #{id}
and user_name = #{sourceUserName}
and dept_id is null
and is_alter = 1
</update>
<update id="updateAlterForwardToUserByOutlet">
update work_record
set user_name = #{targetUserName},
nick_name = #{targetNickName},
alter_detail = case
when alter_detail like '[FORWARD=1] %' then concat('[FORWARD=0] ', substring(alter_detail, 13))
when alter_detail like '[FORWARD=1]%' then concat('[FORWARD=0]', substring(alter_detail, 12))
else alter_detail
end,
dept_id = null,
read_time = null,
update_time = sysdate(),
update_by = #{updateBy}
where id = #{id}
and dept_id = #{sourceDeptId}
and user_name is null
and is_alter = 1
</update>
<select id="selectAlterConfigList" resultType="AlterConfigVO">
select id, alter_type, prod_type, warn_role, warn_threshold, update_time, update_by, type
from alter_config
@@ -278,4 +383,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by alter_type
</select>
</mapper>
</mapper>

View File

@@ -167,6 +167,36 @@
</where>
</select>
<select id="getCustManagerListByPage" resultType="DwbRetailCustLevelManagerDetailVO">
select id, outlet_id, outlet_name, branch_id, branch_name, cust_name, cust_idc, cust_isn, cust_age, cust_sex, cust_phone, cust_address, cust_aum_bal,
aum_bal_comp_lm, cust_aum_month_avg, cust_level, cust_level_comp_lm, manager_name, manager_id
from dwb_retail_cust_level_manager_detail_${headId}
<where>
<if test="dto.managerId != null and dto.managerId !='' ">and manager_id = #{dto.managerId}</if>
<if test="dto.outletId != null and dto.outletId !='' ">and outlet_id = #{dto.outletId}</if>
<if test="dto.branchId != null and dto.branchId !='' ">and branch_id = #{dto.branchId}</if>
<if test="dto.statusType != null and dto.statusType !=''">
<choose>
<when test="dto.statusType == 'current'">
and cust_level = #{dto.custLevel}
</when>
<when test="dto.statusType == 'last'">
and cust_level_lm = #{dto.custLevel}
</when>
<when test="dto.statusType == 'rise'">
and cust_level = #{dto.custLevel}
and cust_level_comp_lm like '上升%'
</when>
<when test="dto.statusType == 'fall'">
and cust_level_lm = #{dto.custLevel}
and cust_level_comp_lm like '下降%'
</when>
</choose>
</if>
</where>
limit #{offset}, #{pageSize}
</select>
<select id="getCustLevelCount" resultType="Integer">
select count(1)
from dwb_retail_cust_level_manager_detail
@@ -521,4 +551,4 @@
</foreach>
</select>
</mapper>
</mapper>