diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/ProjectInfo.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/ProjectInfo.java index 51490739..cd47b4ce 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/ProjectInfo.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/ProjectInfo.java @@ -66,8 +66,10 @@ public class ProjectInfo extends BaseEntity private String operateInstitution; /** 代理商code */ - @Excel(name = "代理商code") + private String partnerCode; + @Excel(name = "代理商") + private String partnerName; /** 联系方式 */ @Excel(name = "联系方式") diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/ProjectInfoMapper.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/ProjectInfoMapper.java index 2acc4f24..f24438c3 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/ProjectInfoMapper.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/ProjectInfoMapper.java @@ -1,6 +1,8 @@ package com.ruoyi.sip.mapper; import java.util.List; + +import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.sip.domain.ProjectInfo; /** @@ -60,4 +62,6 @@ public interface ProjectInfoMapper public int deleteProjectInfoByIds(String[] ids); String selectMaxProjectCode(ProjectInfo projectInfo); + + List selectUserById(List list); } diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/ProjectInfoServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/ProjectInfoServiceImpl.java index 2f493b84..8a40cdff 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/ProjectInfoServiceImpl.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/ProjectInfoServiceImpl.java @@ -1,12 +1,14 @@ package com.ruoyi.sip.service.impl; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.math.BigDecimal; +import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; import cn.hutool.core.collection.CollUtil; +import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.sip.domain.*; import com.ruoyi.sip.service.IProjectOperateLogService; @@ -35,9 +37,15 @@ public class ProjectInfoServiceImpl implements IProjectInfoService { private IProjectWorkProgressService workProgressService; @Autowired private IProjectOperateLogService operateLogService; + private static final String PROJECT_CODE_PREFIX = "V"; private static final Integer PROJECT_CODE_LENGTH = 5; + + public static final String INDUSTRY_TYPE_DICT_TYPE = "industry_type"; + public static final String PROJECT_STAGE_DICT_TYPE = "project_stage"; + public static final String OPERATE_INSTITUTION_DICT_TYPE = "operate_institution"; + /** * 查询项目管理 * @@ -91,29 +99,40 @@ public class ProjectInfoServiceImpl implements IProjectInfoService { projectInfo.setCreateTime(DateUtils.getNowDate()); projectInfo.setCreateBy(ShiroUtils.getUserId().toString()); int i = projectInfoMapper.insertProjectInfo(projectInfo); + saveOtherInfo(projectInfo); + return i; + } + + private void saveOtherInfo(ProjectInfo projectInfo1) { //插入产品信息 - List hardwareProjectProductInfoList = projectInfo.getHardwareProjectProductInfoList(); - List softwareProjectProductInfoList = projectInfo.getSoftwareProjectProductInfoList(); - List addList=new ArrayList<>(); - addList.addAll(hardwareProjectProductInfoList); - addList.addAll(softwareProjectProductInfoList); - if (CollUtil.isNotEmpty(addList)){ + List hardwareProjectProductInfoList = projectInfo1.getHardwareProjectProductInfoList(); + List softwareProjectProductInfoList = projectInfo1.getSoftwareProjectProductInfoList(); + List addList = new ArrayList<>(); + if (CollUtil.isNotEmpty(hardwareProjectProductInfoList)) { + addList.addAll(hardwareProjectProductInfoList); + } + if (CollUtil.isNotEmpty(softwareProjectProductInfoList)) { + addList.addAll(softwareProjectProductInfoList); + } + if (CollUtil.isNotEmpty(addList)) { for (ProjectProductInfo projectProductInfo : addList) { - projectProductInfo.setProjectId(projectInfo.getId()); + projectProductInfo.setProjectId(projectInfo1.getId()); } productInfoService.saveBatch(addList); } //插入变更记录信息 - List projectWorkProgressList = projectInfo.getProjectWorkProgressList(); + List projectWorkProgressList = projectInfo1.getProjectWorkProgressList(); if (CollUtil.isNotEmpty(projectWorkProgressList)) { for (ProjectWorkProgress workProgress : projectWorkProgressList) { - workProgress.setProjectId(projectInfo.getId()); + workProgress.setProjectId(projectInfo1.getId()); + workProgress.setWorkUser(ShiroUtils.getUserId().toString()); + workProgress.setWorkTime(DateUtils.getNowDate()); } workProgressService.insertIgnoreBatch(projectWorkProgressList); } - return i; } + /** * 修改项目管理 * @@ -124,35 +143,60 @@ public class ProjectInfoServiceImpl implements IProjectInfoService { public int updateProjectInfo(ProjectInfo projectInfo) { // 获取更新前的项目信息 ProjectInfo oldProjectInfo = projectInfoMapper.selectProjectInfoById(projectInfo.getId()); - // 更新项目信息 projectInfo.setUpdateTime(DateUtils.getNowDate()); int result = projectInfoMapper.updateProjectInfo(projectInfo); - + //变更其它信息 + saveOtherInfo(projectInfo); // 记录操作日志 + recordOperationLogs(projectInfo, oldProjectInfo); + return result; + } + + private void recordOperationLogs(ProjectInfo projectInfo, ProjectInfo oldProjectInfo) { StringBuilder logContent = new StringBuilder(); int logIndex = 1; + // 比较项目信息字段差异 + logIndex = compareField(logContent, logIndex, "项目名称", oldProjectInfo.getProjectName(), projectInfo.getProjectName()); + logIndex = compareField(logContent, logIndex, "客户名称", oldProjectInfo.getCustomerName(), projectInfo.getCustomerName()); + + logIndex = compareField(logContent, logIndex, "行业", DictUtils.getDictLabel(INDUSTRY_TYPE_DICT_TYPE, oldProjectInfo.getIndustryType()) + , DictUtils.getDictLabel(INDUSTRY_TYPE_DICT_TYPE, projectInfo.getIndustryType())); + logIndex = compareField(logContent, logIndex, "属地", oldProjectInfo.getProvince(), projectInfo.getProvince()); + logIndex = compareField(logContent, logIndex, "项目阶段", DictUtils.getDictLabel(PROJECT_STAGE_DICT_TYPE, oldProjectInfo.getProjectStage()) + , DictUtils.getDictLabel(PROJECT_STAGE_DICT_TYPE, projectInfo.getProjectStage())); + logIndex = compareField(logContent, logIndex, "项目把握度", oldProjectInfo.getProjectGraspDegree(), projectInfo.getProjectGraspDegree()); + if (oldProjectInfo.getHzSupportUser() != null || projectInfo.getHzSupportUser() != null) { + List sysUsers = projectInfoMapper.selectUserById(Stream.of(oldProjectInfo.getHzSupportUser(), projectInfo.getHzSupportUser()).filter(Objects::nonNull).collect(Collectors.toList())); + Map userMap = sysUsers.stream().collect(Collectors.toMap(item -> item.getUserId().toString(), SysUser::getUserName)); + logIndex = compareField(logContent, logIndex, "汇智支撑人员", userMap.get(oldProjectInfo.getHzSupportUser()), userMap.get(projectInfo.getHzSupportUser())); + } + + logIndex = compareField(logContent, logIndex, "运作机构", DictUtils.getDictLabel(OPERATE_INSTITUTION_DICT_TYPE, oldProjectInfo.getOperateInstitution()), + DictUtils.getDictLabel(OPERATE_INSTITUTION_DICT_TYPE, projectInfo.getOperateInstitution())); + //替换代理商名称 + logIndex = compareField(logContent, logIndex, "代理商", oldProjectInfo.getPartnerName(), projectInfo.getPartnerName()); + logIndex = compareField(logContent, logIndex, "联系方式", oldProjectInfo.getContactWay(), projectInfo.getContactWay()); + logIndex = compareBigDecimalField(logContent, logIndex, "预计金额", oldProjectInfo.getEstimatedAmount(), projectInfo.getEstimatedAmount()); + logIndex = compareField(logContent, logIndex, "预计下单时间", oldProjectInfo.getEstimatedOrderTime(), projectInfo.getEstimatedOrderTime()); + logIndex = compareField(logContent, logIndex, "预计发货时间", oldProjectInfo.getEstimatedDeliverTime(), projectInfo.getEstimatedDeliverTime()); + logIndex = compareField(logContent, logIndex, "竞争对手", oldProjectInfo.getCompetitor(), projectInfo.getCompetitor()); + logIndex = compareField(logContent, logIndex, "关键技术问题", oldProjectInfo.getKeyProblem(), projectInfo.getKeyProblem()); + logIndex = compareField(logContent, logIndex, "项目简述", oldProjectInfo.getProjectDesc(), projectInfo.getProjectDesc()); + + // 配置信息变更 + List oldHardwareList = oldProjectInfo.getHardwareProjectProductInfoList(); + List oldSoftwareList = oldProjectInfo.getSoftwareProjectProductInfoList(); + List newHardwareList = projectInfo.getHardwareProjectProductInfoList(); + List newSoftwareList = projectInfo.getSoftwareProjectProductInfoList(); + + // 比较硬件产品信息 + logIndex = compareProductInfoList(logContent, logIndex, "硬件产品", oldHardwareList, newHardwareList); + + + // 比较软件产品信息 + logIndex = compareProductInfoList(logContent, logIndex, "软件产品", oldSoftwareList, newSoftwareList); - // 比较字段差异 - compareField(logContent, logIndex++, "项目名称", oldProjectInfo.getProjectName(), projectInfo.getProjectName()); - compareField(logContent, logIndex++, "客户名称", oldProjectInfo.getCustomerName(), projectInfo.getCustomerName()); - compareField(logContent, logIndex++, "行业", oldProjectInfo.getIndustryType(), projectInfo.getIndustryType()); - compareField(logContent, logIndex++, "属地", oldProjectInfo.getProvince(), projectInfo.getProvince()); - compareField(logContent, logIndex++, "项目阶段", oldProjectInfo.getProjectStage(), projectInfo.getProjectStage()); - compareField(logContent, logIndex++, "项目把握度", oldProjectInfo.getProjectGraspDegree(), projectInfo.getProjectGraspDegree()); - compareField(logContent, logIndex++, "汇智支撑人员", oldProjectInfo.getHzSupportUser(), projectInfo.getHzSupportUser()); - compareField(logContent, logIndex++, "运作机构", oldProjectInfo.getOperateInstitution(), projectInfo.getOperateInstitution()); - compareField(logContent, logIndex++, "代理商", oldProjectInfo.getOperateInstitution(), projectInfo.getOperateInstitution()); - compareField(logContent, logIndex++, "竞争对手", oldProjectInfo.getCompetitor(), projectInfo.getCompetitor()); -// compareField(logContent, logIndex++, "项目类型", oldProjectInfo.getProjectType(), projectInfo.getProjectType()); -// compareField(logContent, logIndex++, "项目状态", oldProjectInfo.getProjectStatus(), projectInfo.getProjectStatus()); -// compareField(logContent, logIndex++, "项目经理", oldProjectInfo.getProjectManager(), projectInfo.getProjectManager()); -// compareField(logContent, logIndex++, "预期收益", oldProjectInfo.getExpectedRevenue(), projectInfo.getExpectedRevenue()); -// compareField(logContent, logIndex++, "实际收益", oldProjectInfo.getActualRevenue(), projectInfo.getActualRevenue()); -// compareField(logContent, logIndex++, "开始日期", oldProjectInfo.getStartDate(), projectInfo.getStartDate()); -// compareField(logContent, logIndex++, "结束日期", oldProjectInfo.getEndDate(), projectInfo.getEndDate()); -// compareField(logContent, logIndex++, "风险等级", oldProjectInfo.getRiskLevel(), projectInfo.getRiskLevel()); -// compareField(logContent, logIndex++, "备注", oldProjectInfo.getRemarks(), projectInfo.getRemarks()); // 插入操作日志 if (logContent.length() > 0) { @@ -163,21 +207,81 @@ public class ProjectInfoServiceImpl implements IProjectInfoService { operateLog.setOperateUser(ShiroUtils.getUserId().toString()); operateLogService.insertProjectOperateLog(operateLog); } - - return result; } /** - * 比较字段并生成日志内容 + * 比较产品信息列表并生成日志内容 * * @param logContent 日志内容构建器 * @param index 日志索引 - * @param fieldName 字段名称 - * @param oldValue 旧值 - * @param newValue 新值 + * @param type 产品类型(硬件或软件) + * @param oldList 旧的产品信息列表 + * @param newList 新的产品信息列表 */ - private void compareField(StringBuilder logContent, int index, String fieldName, Object oldValue, Object newValue) { - if (!oldValue.equals(newValue)) { + private int compareProductInfoList(StringBuilder logContent, int index, String type, List oldList, List newList) { + // 将旧列表和新列表转换为以 id 为键的 Map,便于快速查找 + Map oldMap = CollUtil.isEmpty(oldList) ? new HashMap<>() : oldList.stream() + .collect(Collectors.toMap(ProjectProductInfo::getId, product -> product)); + Map newMap = CollUtil.isEmpty(newList) ? new HashMap<>() : newList.stream() + .collect(Collectors.toMap(ProjectProductInfo::getId, product -> product)); + + // 获取所有 id 的并集 + Set allIds = new HashSet<>(oldMap.keySet()); + allIds.addAll(newMap.keySet()); + + for (Long id : allIds) { + ProjectProductInfo oldProduct = oldMap.get(id); + ProjectProductInfo newProduct = newMap.get(id); + + if (oldProduct == null && newProduct != null) { + // 新增产品 + logContent.append(index).append(".").append(type).append("新增:").append(newProduct.getProductCode()).append("\n"); + index++; + } else if (oldProduct != null && newProduct == null) { + // 删除产品 + logContent.append(index).append(".").append(type).append("删除:").append(oldProduct.getProductCode()).append("\n"); + index++; + } else if (oldProduct != null) { + // 变更产品 + + if (!oldProduct.getProductCode().equals(newProduct.getProductCode())) { + logContent.append(index).append(".").append(type).append("变更:").append(oldProduct.getProductCode()).append(" -> ").append(newProduct.getProductCode()).append("\n"); + index++; + } + if (!Objects.equals(oldProduct.getModel(), newProduct.getModel())) { + logContent.append(index).append(".").append("型号").append("由‘").append(oldProduct.getModel()).append("’变更为‘").append(newProduct.getModel()).append("’\n"); + index++; + } + if (!Objects.equals(oldProduct.getQuantity(), newProduct.getQuantity())) { + logContent.append(index).append(".").append("数量").append("由‘").append(oldProduct.getQuantity()).append("’变更为‘").append(newProduct.getQuantity()).append("’\n"); + index++; + } + if (!Objects.equals(oldProduct.getRemark(), newProduct.getRemark())) { + logContent.append(index).append(".").append("备注").append("由‘").append(oldProduct.getRemark()).append("’变更为‘").append(newProduct.getRemark()).append("’\n"); + index++; + } + + } + } + return index; + } + + private int compareField(StringBuilder logContent, int index, String fieldName, Object oldValue, Object newValue) { + if (!Objects.equals(oldValue, newValue)) { + logContent.append(index).append(".") + .append(fieldName) + .append("由‘") + .append(oldValue == null ? "" : oldValue) + .append("’变更为‘") + .append(newValue == null ? "" : oldValue) + .append("’\n"); + index++; + } + return index; + } + + private int compareBigDecimalField(StringBuilder logContent, int index, String fieldName, BigDecimal oldValue, BigDecimal newValue) { + if (oldValue != null && newValue != null && oldValue.compareTo(newValue) != 0) { logContent.append(index).append(".") .append(fieldName) .append("由‘") @@ -185,7 +289,9 @@ public class ProjectInfoServiceImpl implements IProjectInfoService { .append("’变更为‘") .append(newValue) .append("’\n"); + index++; } + return index; } /** diff --git a/ruoyi-sip/src/main/resources/mapper/sip/ProjectInfoMapper.xml b/ruoyi-sip/src/main/resources/mapper/sip/ProjectInfoMapper.xml index 674e5c08..7103415a 100644 --- a/ruoyi-sip/src/main/resources/mapper/sip/ProjectInfoMapper.xml +++ b/ruoyi-sip/src/main/resources/mapper/sip/ProjectInfoMapper.xml @@ -34,7 +34,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select id, project_code, project_name, customer_code, customer_name, industry_type, province, project_stage, project_grasp_degree, hz_support_user, operate_institution, partner_code, contact_way, estimated_amount, currency_type, estimated_order_time, estimated_deliver_time, competitor, country_product, server_configuration, key_problem, project_desc, create_by, create_time, update_by, update_time from project_info + select id, project_code, project_name, customer_code, customer_name, industry_type, province, project_stage, project_grasp_degree, hz_support_user, operate_institution + , partner_code, partner_name, contact_way, estimated_amount, currency_type, estimated_order_time, estimated_deliver_time, competitor, country_product, server_configuration + , key_problem, project_desc, create_by, create_time, update_by, update_time from project_info + insert into project_info @@ -88,6 +97,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" hz_support_user, operate_institution, partner_code, + partner_name, contact_way, estimated_amount, currency_type, @@ -115,6 +125,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{hzSupportUser}, #{operateInstitution}, #{partnerCode}, + #{partnerName}, #{contactWay}, #{estimatedAmount}, #{currencyType}, @@ -145,7 +156,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" project_grasp_degree = #{projectGraspDegree}, hz_support_user = #{hzSupportUser}, operate_institution = #{operateInstitution}, - partner_code = #{partnerCode}, + partner_code = #{partnerCode}, + partner_name = #{partnerName}, contact_way = #{contactWay}, estimated_amount = #{estimatedAmount}, currency_type = #{currencyType},