Commit 53450aaf244536e42619abf546937fe58c180eec

Authored by 房远帅
1 parent 6e7cbbf8

楚江ERP:客户资信变更详情

  1 +package com.lframework.xingyun.sc;
  2 +
  3 +import java.lang.annotation.ElementType;
  4 +import java.lang.annotation.Retention;
  5 +import java.lang.annotation.RetentionPolicy;
  6 +import java.lang.annotation.Target;
  7 +
  8 +@Retention(RetentionPolicy.RUNTIME) // 必须是 RUNTIME,才能在运行时通过反射读取
  9 +@Target(ElementType.FIELD) // 用于字段
  10 +public @interface Label {
  11 + String value();
  12 +}
  1 +package com.lframework.xingyun.sc.bo.customer.credit;
  2 +
  3 +
  4 +import java.util.List;
  5 +
  6 +/**
  7 + * 变更数据
  8 + */
  9 +public class ChangeData {
  10 + private List<ChangeItem> otherChangeList;
  11 +
  12 + public List<ChangeItem> getOtherChangeList() {
  13 + return otherChangeList;
  14 + }
  15 +
  16 + public void setOtherChangeList(List<ChangeItem> otherChangeList) {
  17 + this.otherChangeList = otherChangeList;
  18 + }
  19 +}
  1 +package com.lframework.xingyun.sc.bo.customer.credit;
  2 +
  3 +
  4 +/**
  5 + * 字段变更项实体,用于审计、日志、审批展示
  6 + */
  7 +public class ChangeItem {
  8 + /**
  9 + * 序号(从1开始)
  10 + */
  11 + private Integer serialNumber;
  12 +
  13 + /**
  14 + * 变更前的值
  15 + */
  16 + private String beforeChange;
  17 +
  18 + /**
  19 + * 变更后的值
  20 + */
  21 + private String afterChange;
  22 +
  23 + // 构造函数(可选)
  24 + public ChangeItem() {
  25 + }
  26 +
  27 + public ChangeItem(Integer serialNumber, String beforeChange, String afterChange) {
  28 + this.serialNumber = serialNumber;
  29 + this.beforeChange = beforeChange;
  30 + this.afterChange = afterChange;
  31 + }
  32 +
  33 + // Getter 和 Setter
  34 + public Integer getSerialNumber() {
  35 + return serialNumber;
  36 + }
  37 +
  38 + public void setSerialNumber(Integer serialNumber) {
  39 + this.serialNumber = serialNumber;
  40 + }
  41 +
  42 + public String getBeforeChange() {
  43 + return beforeChange;
  44 + }
  45 +
  46 + public void setBeforeChange(String beforeChange) {
  47 + this.beforeChange = beforeChange;
  48 + }
  49 +
  50 + public String getAfterChange() {
  51 + return afterChange;
  52 + }
  53 +
  54 + public void setAfterChange(String afterChange) {
  55 + this.afterChange = afterChange;
  56 + }
  57 +
  58 + @Override
  59 + public String toString() {
  60 + return "ChangeItem{" +
  61 + "serialNumber=" + serialNumber +
  62 + ", beforeChange='" + beforeChange + '\'' +
  63 + ", afterChange='" + afterChange + '\'' +
  64 + '}';
  65 + }
  66 +}
@@ -83,6 +83,12 @@ public class GetCustomerCreditHistoryBo extends BaseBo<CustomerCreditHistory> { @@ -83,6 +83,12 @@ public class GetCustomerCreditHistoryBo extends BaseBo<CustomerCreditHistory> {
83 private String companyId; 83 private String companyId;
84 84
85 /** 85 /**
  86 + * 单位名称(非持久化字段)
  87 + */
  88 + @ApiModelProperty("单位名称")
  89 + private String companyName;
  90 +
  91 + /**
86 * 企业性质 92 * 企业性质
87 */ 93 */
88 @ApiModelProperty("企业性质") 94 @ApiModelProperty("企业性质")
1 package com.lframework.xingyun.sc.controller.customer; 1 package com.lframework.xingyun.sc.controller.customer;
2 2
  3 +import com.lframework.starter.common.utils.StringUtil;
3 import com.lframework.starter.web.core.annotations.security.HasPermission; 4 import com.lframework.starter.web.core.annotations.security.HasPermission;
4 import com.lframework.starter.web.core.controller.DefaultBaseController; 5 import com.lframework.starter.web.core.controller.DefaultBaseController;
  6 +import com.lframework.starter.web.core.utils.IdUtil;
5 import com.lframework.starter.web.core.utils.PageResultUtil; 7 import com.lframework.starter.web.core.utils.PageResultUtil;
6 import com.lframework.starter.web.core.components.resp.PageResult; 8 import com.lframework.starter.web.core.components.resp.PageResult;
7 import com.lframework.starter.web.core.components.resp.InvokeResult; 9 import com.lframework.starter.web.core.components.resp.InvokeResult;
  10 +
  11 +import javax.annotation.Resource;
8 import javax.validation.constraints.NotBlank; 12 import javax.validation.constraints.NotBlank;
  13 +
  14 +import com.lframework.xingyun.sc.bo.customer.credit.ChangeData;
  15 +import com.lframework.xingyun.sc.bo.customer.credit.ChangeItem;
9 import com.lframework.xingyun.sc.bo.customer.credit.GetCustomerCreditHistoryBo; 16 import com.lframework.xingyun.sc.bo.customer.credit.GetCustomerCreditHistoryBo;
  17 +import com.lframework.xingyun.sc.entity.CustomerCredit;
10 import com.lframework.xingyun.sc.entity.CustomerCreditHistory; 18 import com.lframework.xingyun.sc.entity.CustomerCreditHistory;
11 import com.lframework.xingyun.sc.service.customer.CustomerCreditHistoryService; 19 import com.lframework.xingyun.sc.service.customer.CustomerCreditHistoryService;
  20 +import com.lframework.xingyun.sc.service.customer.CustomerCreditService;
12 import com.lframework.xingyun.sc.vo.customer.credit.CreateCustomerCreditHistoryVo; 21 import com.lframework.xingyun.sc.vo.customer.credit.CreateCustomerCreditHistoryVo;
13 import com.lframework.xingyun.sc.vo.customer.credit.QueryCustomerCreditHistoryVo; 22 import com.lframework.xingyun.sc.vo.customer.credit.QueryCustomerCreditHistoryVo;
14 import io.swagger.annotations.ApiImplicitParam; 23 import io.swagger.annotations.ApiImplicitParam;
@@ -18,14 +27,13 @@ import io.swagger.annotations.ApiOperation; @@ -18,14 +27,13 @@ import io.swagger.annotations.ApiOperation;
18 import com.lframework.starter.common.utils.CollectionUtil; 27 import com.lframework.starter.common.utils.CollectionUtil;
19 import io.swagger.annotations.Api; 28 import io.swagger.annotations.Api;
20 import org.springframework.web.bind.annotation.DeleteMapping; 29 import org.springframework.web.bind.annotation.DeleteMapping;
21 -import org.springframework.beans.factory.annotation.Autowired;  
22 import org.springframework.validation.annotation.Validated; 30 import org.springframework.validation.annotation.Validated;
23 import org.springframework.web.bind.annotation.*; 31 import org.springframework.web.bind.annotation.*;
24 32
25 import javax.validation.Valid; 33 import javax.validation.Valid;
26 import java.time.LocalDateTime; 34 import java.time.LocalDateTime;
27 import java.time.format.DateTimeFormatter; 35 import java.time.format.DateTimeFormatter;
28 -import java.util.List; 36 +import java.util.*;
29 import java.util.stream.Collectors; 37 import java.util.stream.Collectors;
30 38
31 /** 39 /**
@@ -38,8 +46,10 @@ import java.util.stream.Collectors; @@ -38,8 +46,10 @@ import java.util.stream.Collectors;
38 @RequestMapping("/customerCreditHistory") 46 @RequestMapping("/customerCreditHistory")
39 public class CustomerCreditHistoryController extends DefaultBaseController { 47 public class CustomerCreditHistoryController extends DefaultBaseController {
40 48
41 - @Autowired 49 + @Resource
42 private CustomerCreditHistoryService customerCreditHistoryService; 50 private CustomerCreditHistoryService customerCreditHistoryService;
  51 + @Resource
  52 + private CustomerCreditService customerCreditService;
43 53
44 /** 54 /**
45 * 查询列表 55 * 查询列表
@@ -91,20 +101,195 @@ public class CustomerCreditHistoryController extends DefaultBaseController { @@ -91,20 +101,195 @@ public class CustomerCreditHistoryController extends DefaultBaseController {
91 } 101 }
92 102
93 /** 103 /**
94 - * 根据ID查询 104 + * 根据ID查询变更记录
95 */ 105 */
96 - @ApiOperation("根据ID查询") 106 + @ApiOperation("根据ID查询变更记录")
97 @ApiImplicitParam(value = "id", name = "id", paramType = "query", required = true) 107 @ApiImplicitParam(value = "id", name = "id", paramType = "query", required = true)
98 @HasPermission({"customerCreditHistory:customercredithistory:query"}) 108 @HasPermission({"customerCreditHistory:customercredithistory:query"})
99 - @GetMapping  
100 - public InvokeResult<GetCustomerCreditHistoryBo> get(@NotBlank(message = "id不能为空!") String id) { 109 + @GetMapping("/getById")
  110 + public InvokeResult<ChangeData> get(@NotBlank(message = "id不能为空!") String id) {
101 111
102 CustomerCreditHistory data = customerCreditHistoryService.findById(id); 112 CustomerCreditHistory data = customerCreditHistoryService.findById(id);
103 if (data == null) { 113 if (data == null) {
104 throw new DefaultClientException("客户资信历史记录表不存在!"); 114 throw new DefaultClientException("客户资信历史记录表不存在!");
105 } 115 }
  116 + //客户资信ID
  117 + String creditId = data.getCreditId();
  118 + QueryCustomerCreditHistoryVo vo = new QueryCustomerCreditHistoryVo();
  119 + vo.setCreditId(creditId);
  120 + List<CustomerCreditHistory> query = customerCreditHistoryService.query(vo);
  121 + Map<String, CustomerCreditHistory> map = query.stream()
  122 + .filter(item -> item.getSort() != null)
  123 + .collect(Collectors.toMap(
  124 + CustomerCreditHistory::getSort,
  125 + item -> item,
  126 + (a, b) -> a // 保留第一个,去重
  127 + ));
  128 + //第几次变更
  129 + int sort = Integer.parseInt(data.getSort());
  130 + //变更次数
  131 + int size = query.size();
  132 + List<ChangeItem> differencesWithIndex = new ArrayList<>();
  133 + if (sort + 1 <= size) {
  134 + //data与customerCreditHistory的比较,其中data与为变更前,customerCreditHistory为变更后
  135 + CustomerCreditHistory customerCreditHistory = map.get(String.valueOf(sort + 1));
  136 + differencesWithIndex = customerCreditHistoryService.getDifferencesWithIndex(data, customerCreditHistory);
  137 +
  138 + } else {
  139 + //现在的数据与这data相对比,其中data为变更前,customerCredit为变更后
  140 + CustomerCredit customerCredit = customerCreditService.findById(creditId);
  141 + CustomerCreditHistory customerCreditHistory = new CustomerCreditHistory();
  142 + if (!StringUtil.isBlank(customerCredit.getSerialNumber())) {
  143 + customerCreditHistory.setSerialNumber(customerCredit.getSerialNumber());
  144 + }
  145 + if (!StringUtil.isBlank(customerCredit.getRegion())) {
  146 + customerCreditHistory.setRegion(customerCredit.getRegion());
  147 + }
  148 + if (customerCredit.getRegisterDate() != null) {
  149 + customerCreditHistory.setRegisterDate(customerCredit.getRegisterDate());
  150 + }
  151 + if (!StringUtil.isBlank(customerCredit.getCustomerShortName())) {
  152 + customerCreditHistory.setCustomerShortName(customerCredit.getCustomerShortName());
  153 + }
  154 + customerCreditHistory.setEnterpriseType(customerCredit.getEnterpriseType());
  155 + customerCreditHistory.setCompanyId(customerCredit.getCompanyId());
  156 + if (!StringUtil.isBlank(customerCredit.getCompanyNature())) {
  157 + customerCreditHistory.setCompanyNature(customerCredit.getCompanyNature());
  158 + }
  159 + if (!StringUtil.isBlank(customerCredit.getCompanyAddress())) {
  160 + customerCreditHistory.setCompanyAddress(customerCredit.getCompanyAddress());
  161 + }
  162 + if (customerCredit.getRegisteredCapital() != null) {
  163 + customerCreditHistory.setRegisteredCapital(customerCredit.getRegisteredCapital());
  164 + }
  165 + if (!StringUtil.isBlank(customerCredit.getBankAccount())) {
  166 + customerCreditHistory.setBankAccount(customerCredit.getBankAccount());
  167 + }
  168 + if (!StringUtil.isBlank(customerCredit.getBankName())) {
  169 + customerCreditHistory.setBankName(customerCredit.getBankName());
  170 + }
  171 + if (!StringUtil.isBlank(customerCredit.getTaxNumber())) {
  172 + customerCreditHistory.setTaxNumber(customerCredit.getTaxNumber());
  173 + }
  174 + if (customerCredit.getRegistrationTime() != null) {
  175 + customerCreditHistory.setRegistrationTime(customerCredit.getRegistrationTime());
  176 + }
  177 + if (!StringUtil.isBlank(customerCredit.getBusinessYears())) {
  178 + customerCreditHistory.setBusinessYears(customerCredit.getBusinessYears());
  179 + }
  180 + if (!StringUtil.isBlank(customerCredit.getBusinessScope())) {
  181 + customerCreditHistory.setBusinessScope(customerCredit.getBusinessScope());
  182 + }
  183 + if (!StringUtil.isBlank(customerCredit.getBusinessProperty())) {
  184 + customerCreditHistory.setBusinessProperty(customerCredit.getBusinessProperty());
  185 + }
  186 + if (customerCredit.getLandArea() != null) {
  187 + customerCreditHistory.setLandArea(customerCredit.getLandArea());
  188 + }
  189 + if (!StringUtil.isBlank(customerCredit.getStorageConditions())) {
  190 + customerCreditHistory.setStorageConditions(customerCredit.getStorageConditions());
  191 + }
  192 + if (customerCredit.getEmployeeCount() != null) {
  193 + customerCreditHistory.setEmployeeCount(customerCredit.getEmployeeCount());
  194 + }
  195 + if (!StringUtil.isBlank(customerCredit.getEquipmentAttributes())) {
  196 + customerCreditHistory.setEquipmentAttributes(customerCredit.getEquipmentAttributes());
  197 + }
  198 + if (!StringUtil.isBlank(customerCredit.getAssetEvaluation())) {
  199 + customerCreditHistory.setAssetEvaluation(customerCredit.getAssetEvaluation());
  200 + }
  201 + if (!StringUtil.isBlank(customerCredit.getLastYearSales())) {
  202 + customerCreditHistory.setLastYearSales(customerCredit.getLastYearSales());
  203 + }
  204 + if (!StringUtil.isBlank(customerCredit.getMonthlyAvgSales())) {
  205 + customerCreditHistory.setMonthlyAvgSales(customerCredit.getMonthlyAvgSales());
  206 + }
  207 + if (!StringUtil.isBlank(customerCredit.getInvoiceItemUnit())) {
  208 + customerCreditHistory.setInvoiceItemUnit(customerCredit.getInvoiceItemUnit());
  209 + }
  210 + if (!StringUtil.isBlank(customerCredit.getCertificationCertificate())) {
  211 + customerCreditHistory.setCertificationCertificate(customerCredit.getCertificationCertificate());
  212 + }
  213 + if (!StringUtil.isBlank(customerCredit.getProductMatch())) {
  214 + customerCreditHistory.setProductMatch(customerCredit.getProductMatch());
  215 + }
  216 + if (!StringUtil.isBlank(customerCredit.getMajorCustomers())) {
  217 + customerCreditHistory.setMajorCustomers(customerCredit.getMajorCustomers());
  218 + }
  219 + if (!StringUtil.isBlank(customerCredit.getMainProjects())) {
  220 + customerCreditHistory.setMainProjects(customerCredit.getMainProjects());
  221 + }
  222 + if (!StringUtil.isBlank(customerCredit.getIndustryInvolved())) {
  223 + customerCreditHistory.setIndustryInvolved(customerCredit.getIndustryInvolved());
  224 + }
  225 + if (!StringUtil.isBlank(customerCredit.getIndustryExperience())) {
  226 + customerCreditHistory.setIndustryExperience(customerCredit.getIndustryExperience());
  227 + }
  228 + if (!StringUtil.isBlank(customerCredit.getHasDispute())) {
  229 + customerCreditHistory.setHasDispute(customerCredit.getHasDispute());
  230 + }
  231 + if (!StringUtil.isBlank(customerCredit.getCooperationStartDate())) {
  232 + customerCreditHistory.setCooperationStartDate(customerCredit.getCooperationStartDate());
  233 + }
  234 + if (!StringUtil.isBlank(customerCredit.getMonthlyAvgVolume())) {
  235 + customerCreditHistory.setMonthlyAvgVolume(customerCredit.getMonthlyAvgVolume());
  236 + }
  237 + if (!StringUtil.isBlank(customerCredit.getIsVerbalAgreement())) {
  238 + customerCreditHistory.setIsVerbalAgreement(customerCredit.getIsVerbalAgreement());
  239 + }
  240 + if (!StringUtil.isBlank(customerCredit.getOtherAgreements())) {
  241 + customerCreditHistory.setOtherAgreements(customerCredit.getOtherAgreements());
  242 + }
  243 + if (!StringUtil.isBlank(customerCredit.getHasLongTermContract())) {
  244 + customerCreditHistory.setHasLongTermContract(customerCredit.getHasLongTermContract());
  245 + }
  246 + if (!StringUtil.isBlank(customerCredit.getContractType())) {
  247 + customerCreditHistory.setContractType(customerCredit.getContractType());
  248 + }
  249 + if (!StringUtil.isBlank(customerCredit.getHasInterruption())) {
  250 + customerCreditHistory.setHasInterruption(customerCredit.getHasInterruption());
  251 + }
  252 + if (!StringUtil.isBlank(customerCredit.getSettlementPeriod())) {
  253 + customerCreditHistory.setSettlementPeriod(customerCredit.getSettlementPeriod());
  254 + }
  255 + if (!StringUtil.isBlank(customerCredit.getMaterialSupplyPlan())) {
  256 + customerCreditHistory.setMaterialSupplyPlan(customerCredit.getMaterialSupplyPlan());
  257 + }
  258 + customerCreditHistory.setSuggestedCategory(customerCredit.getSuggestedCategory());
  259 + if (!StringUtil.isBlank(customerCredit.getCreditLimit())) {
  260 + customerCreditHistory.setCreditLimit(customerCredit.getCreditLimit());
  261 + }
  262 + if (!StringUtil.isBlank(customerCredit.getInvestigator())) {
  263 + customerCreditHistory.setInvestigator(customerCredit.getInvestigator());
  264 + }
  265 + if (!StringUtil.isBlank(customerCredit.getSupervisorReview())) {
  266 + customerCreditHistory.setSupervisorReview(customerCredit.getSupervisorReview());
  267 + }
  268 + if (!StringUtil.isBlank(customerCredit.getAnnualTotalSales())) {
  269 + customerCreditHistory.setAnnualTotalSales(customerCredit.getAnnualTotalSales());
  270 + }
  271 + if (!StringUtil.isBlank(customerCredit.getMainIndustry())) {
  272 + customerCreditHistory.setMainIndustry(customerCredit.getMainIndustry());
  273 + }
  274 + if (!StringUtil.isBlank(customerCredit.getAnnualMaterialOverview())) {
  275 + customerCreditHistory.setAnnualMaterialOverview(customerCredit.getAnnualMaterialOverview());
  276 + }
  277 + if (!StringUtil.isBlank(customerCredit.getCompanySettlementPeriod())) {
  278 + customerCreditHistory.setCompanySettlementPeriod(customerCredit.getCompanySettlementPeriod());
  279 + }
  280 + if (!StringUtil.isBlank(customerCredit.getCompanyCreditLimit())) {
  281 + customerCreditHistory.setCompanyCreditLimit(customerCredit.getCompanyCreditLimit());
  282 + }
  283 + if (!StringUtil.isBlank(customerCredit.getCompanyMaterialSupplyPlan())) {
  284 + customerCreditHistory.setCompanyMaterialSupplyPlan(customerCredit.getCompanyMaterialSupplyPlan());
  285 + }
  286 + customerCreditHistory.setCompanySuggestedCategory(customerCredit.getCompanySuggestedCategory());
  287 + customerCreditHistory.setStatus(customerCredit.getStatus());
  288 + differencesWithIndex = customerCreditHistoryService.getDifferencesWithIndex(data, customerCreditHistory);
  289 + }
106 290
107 - GetCustomerCreditHistoryBo result = new GetCustomerCreditHistoryBo(data); 291 + ChangeData result = new ChangeData();
  292 + result.setOtherChangeList(differencesWithIndex);
108 293
109 return InvokeResultBuilder.success(result); 294 return InvokeResultBuilder.success(result);
110 } 295 }
@@ -8,6 +8,7 @@ import java.time.LocalDateTime; @@ -8,6 +8,7 @@ import java.time.LocalDateTime;
8 import com.baomidou.mybatisplus.annotation.FieldFill; 8 import com.baomidou.mybatisplus.annotation.FieldFill;
9 import com.lframework.starter.web.core.entity.BaseEntity; 9 import com.lframework.starter.web.core.entity.BaseEntity;
10 import com.baomidou.mybatisplus.annotation.TableField; 10 import com.baomidou.mybatisplus.annotation.TableField;
  11 +import com.lframework.xingyun.sc.Label;
11 import lombok.Data; 12 import lombok.Data;
12 13
13 /** 14 /**
@@ -42,251 +43,307 @@ public class CustomerCreditHistory extends BaseEntity implements BaseDto { @@ -42,251 +43,307 @@ public class CustomerCreditHistory extends BaseEntity implements BaseDto {
42 /** 43 /**
43 * 编号 44 * 编号
44 */ 45 */
  46 + @Label("编号")
45 private String serialNumber; 47 private String serialNumber;
46 48
47 /** 49 /**
48 * 区域 50 * 区域
49 */ 51 */
  52 + @Label("区域")
50 private String region; 53 private String region;
51 54
52 /** 55 /**
53 * 登记日期 56 * 登记日期
54 */ 57 */
  58 + @Label("登记日期")
55 private LocalDate registerDate; 59 private LocalDate registerDate;
56 60
57 /** 61 /**
58 * 客户简称 62 * 客户简称
59 */ 63 */
  64 + @Label("客户简称")
60 private String customerShortName; 65 private String customerShortName;
61 66
62 /** 67 /**
63 * 企业类型:经销商(distributor)、终端(terminal) 68 * 企业类型:经销商(distributor)、终端(terminal)
64 */ 69 */
  70 + @Label("企业类型")
65 private String enterpriseType; 71 private String enterpriseType;
66 72
67 /** 73 /**
68 * 单位名称 74 * 单位名称
69 */ 75 */
  76 + @Label("单位名称")
70 private String companyId; 77 private String companyId;
71 78
72 /** 79 /**
73 * 企业性质 80 * 企业性质
74 */ 81 */
  82 + @Label("企业性质")
75 private String companyNature; 83 private String companyNature;
76 84
77 /** 85 /**
78 * 单位地址 86 * 单位地址
79 */ 87 */
  88 + @Label("单位地址")
80 private String companyAddress; 89 private String companyAddress;
81 90
82 /** 91 /**
83 * 注册资本(单位:万元) 92 * 注册资本(单位:万元)
84 */ 93 */
  94 + @Label("注册资本")
85 private BigDecimal registeredCapital; 95 private BigDecimal registeredCapital;
86 96
87 /** 97 /**
88 * 账号 98 * 账号
89 */ 99 */
  100 + @Label("账号")
90 private String bankAccount; 101 private String bankAccount;
91 102
92 /** 103 /**
93 * 开户行 104 * 开户行
94 */ 105 */
  106 + @Label("开户行")
95 private String bankName; 107 private String bankName;
96 108
97 /** 109 /**
98 * 税号 110 * 税号
99 */ 111 */
  112 + @Label("税号")
100 private String taxNumber; 113 private String taxNumber;
101 114
102 /** 115 /**
103 * 注册时间 116 * 注册时间
104 */ 117 */
  118 + @Label("注册时间")
105 private LocalDate registrationTime; 119 private LocalDate registrationTime;
106 120
107 /** 121 /**
108 * 经营年限(年) 122 * 经营年限(年)
109 */ 123 */
  124 + @Label("经营年限")
110 private String businessYears; 125 private String businessYears;
111 126
112 /** 127 /**
113 * 经营范围 128 * 经营范围
114 */ 129 */
  130 + @Label("经营范围")
115 private String businessScope; 131 private String businessScope;
116 132
117 /** 133 /**
118 * 经营场地属性 134 * 经营场地属性
119 */ 135 */
  136 + @Label("经营场地属性")
120 private String businessProperty; 137 private String businessProperty;
121 138
122 /** 139 /**
123 * 占地面积(平方米) 140 * 占地面积(平方米)
124 */ 141 */
  142 + @Label("占地面积")
125 private String landArea; 143 private String landArea;
126 144
127 /** 145 /**
128 * 仓储条件 146 * 仓储条件
129 */ 147 */
  148 + @Label("仓储条件")
130 private String storageConditions; 149 private String storageConditions;
131 150
132 /** 151 /**
133 * 员工人数 152 * 员工人数
134 */ 153 */
  154 + @Label("员工人数")
135 private Integer employeeCount; 155 private Integer employeeCount;
136 156
137 /** 157 /**
138 * 设备属性 158 * 设备属性
139 */ 159 */
  160 + @Label("设备属性")
140 private String equipmentAttributes; 161 private String equipmentAttributes;
141 162
142 /** 163 /**
143 * 资产评估 164 * 资产评估
144 */ 165 */
  166 + @Label("资产评估")
145 private String assetEvaluation; 167 private String assetEvaluation;
146 168
147 /** 169 /**
148 * 上年度销售额(万元) 170 * 上年度销售额(万元)
149 */ 171 */
  172 + @Label("上年度销售额")
150 private String lastYearSales; 173 private String lastYearSales;
151 174
152 /** 175 /**
153 * 月均销量(万元) 176 * 月均销量(万元)
154 */ 177 */
  178 + @Label("月均销量")
155 private String monthlyAvgSales; 179 private String monthlyAvgSales;
156 180
157 /** 181 /**
158 * 销项发票所开品名与计量单位 182 * 销项发票所开品名与计量单位
159 */ 183 */
  184 + @Label("销项发票所开品名与计量单位")
160 private String invoiceItemUnit; 185 private String invoiceItemUnit;
161 186
162 /** 187 /**
163 - * 认证证书我司售于产品与经营范围是否匹配 188 + * 认证证书
  189 + */
  190 + @Label("认证证书")
  191 + private String certificationCertificate;
  192 +
  193 + /**
  194 + * 我司售于产品与经营范围是否匹配
164 */ 195 */
  196 + @Label("我司售于产品与经营范围是否匹配")
165 private String productMatch; 197 private String productMatch;
166 198
167 /** 199 /**
168 * 主要客户 200 * 主要客户
169 */ 201 */
  202 + @Label("主要客户")
170 private String majorCustomers; 203 private String majorCustomers;
171 204
172 /** 205 /**
173 * 主营项目 206 * 主营项目
174 */ 207 */
  208 + @Label("主营项目")
175 private String mainProjects; 209 private String mainProjects;
176 210
177 /** 211 /**
178 * 从事行业 212 * 从事行业
179 */ 213 */
  214 + @Label("从事行业")
180 private String industryInvolved; 215 private String industryInvolved;
181 216
182 /** 217 /**
183 * 在该行业中的经验 218 * 在该行业中的经验
184 */ 219 */
  220 + @Label("在该行业中的经验")
185 private String industryExperience; 221 private String industryExperience;
186 222
187 /** 223 /**
188 * 是否与其他企业有经济纠纷 违规信息 拖欠员工薪资等 224 * 是否与其他企业有经济纠纷 违规信息 拖欠员工薪资等
189 */ 225 */
  226 + @Label("是否与其他企业有经济纠纷 违规信息 拖欠员工薪资等")
190 private String hasDispute; 227 private String hasDispute;
191 228
192 /** 229 /**
193 * 与我司合作时间 230 * 与我司合作时间
194 */ 231 */
  232 + @Label("与我司合作时间")
195 private String cooperationStartDate; 233 private String cooperationStartDate;
196 234
197 /** 235 /**
198 * 月均操作量 236 * 月均操作量
199 */ 237 */
  238 + @Label("月均操作量")
200 private String monthlyAvgVolume; 239 private String monthlyAvgVolume;
201 240
202 /** 241 /**
203 * 是否口头协议操作 242 * 是否口头协议操作
204 */ 243 */
  244 + @Label("是否口头协议操作")
205 private String isVerbalAgreement; 245 private String isVerbalAgreement;
206 246
207 /** 247 /**
208 * 是否签订其他协议(列举) 248 * 是否签订其他协议(列举)
209 */ 249 */
  250 + @Label("是否签订其他协议(列举)")
210 private String otherAgreements; 251 private String otherAgreements;
211 252
212 /** 253 /**
213 * 与我司操作是否签订长年合同 254 * 与我司操作是否签订长年合同
214 */ 255 */
  256 + @Label("与我司操作是否签订长年合同")
215 private String hasLongTermContract; 257 private String hasLongTermContract;
216 258
217 /** 259 /**
218 * 合同类型 260 * 合同类型
219 */ 261 */
  262 + @Label("合同类型")
220 private String contractType; 263 private String contractType;
221 264
222 /** 265 /**
223 * 是否有过中断及中断原因 266 * 是否有过中断及中断原因
224 */ 267 */
  268 + @Label("是否有过中断及中断原因")
225 private String hasInterruption; 269 private String hasInterruption;
226 270
227 /** 271 /**
228 - * 结算期限 272 + * 结算期限(办事处)
229 */ 273 */
  274 + @Label("结算期限(办事处)")
230 private String settlementPeriod; 275 private String settlementPeriod;
231 276
232 /** 277 /**
233 - * 加工料提供时间 278 + * 加工操作方案(办事处)
234 */ 279 */
  280 + @Label("加工操作方案(办事处)")
235 private String materialSupplyPlan; 281 private String materialSupplyPlan;
236 282
237 /** 283 /**
238 * 建议客户分类:AAA、AA、A、BBB、BB、B、C、D 284 * 建议客户分类:AAA、AA、A、BBB、BB、B、C、D
239 */ 285 */
  286 + @Label("建议客户分类")
240 private String suggestedCategory; 287 private String suggestedCategory;
241 288
242 /** 289 /**
243 * 授信额度(万元) 290 * 授信额度(万元)
244 */ 291 */
  292 + @Label("授信额度")
245 private String creditLimit; 293 private String creditLimit;
246 294
247 /** 295 /**
248 * 调查人 296 * 调查人
249 */ 297 */
  298 + @Label("调查人")
250 private String investigator; 299 private String investigator;
251 300
252 /** 301 /**
253 * 主管审核 302 * 主管审核
254 */ 303 */
  304 + @Label("主管审核")
255 private String supervisorReview; 305 private String supervisorReview;
256 306
257 /** 307 /**
258 * 年度总销量(万元) 308 * 年度总销量(万元)
259 */ 309 */
  310 + @Label("年度总销量")
260 private String annualTotalSales; 311 private String annualTotalSales;
261 312
262 /** 313 /**
263 * 主要行业 314 * 主要行业
264 */ 315 */
  316 + @Label("主要行业")
265 private String mainIndustry; 317 private String mainIndustry;
266 318
267 /** 319 /**
268 * 年度款料概况 320 * 年度款料概况
269 */ 321 */
  322 + @Label("年度款料概况")
270 private String annualMaterialOverview; 323 private String annualMaterialOverview;
271 324
272 /** 325 /**
273 - * 结算期限 326 + * 结算期限(公司评审)
274 */ 327 */
  328 + @Label("结算期限(公司评审)")
275 private String companySettlementPeriod; 329 private String companySettlementPeriod;
276 330
277 /** 331 /**
278 * 授信额度(万元) 332 * 授信额度(万元)
279 */ 333 */
  334 + @Label("授信额度")
280 private String companyCreditLimit; 335 private String companyCreditLimit;
281 336
282 /** 337 /**
283 - * 加工料提供时间 338 + * 加工操作方案(公司评审)
284 */ 339 */
  340 + @Label("加工操作方案(公司评审)")
285 private String companyMaterialSupplyPlan; 341 private String companyMaterialSupplyPlan;
286 342
287 /** 343 /**
288 - * 建议客户分类:AAA、AA、A、BBB、BB、B、C、D 344 + * 客户分类:AAA、AA、A、BBB、BB、B、C、D
289 */ 345 */
  346 + @Label("客户分类")
290 private String companySuggestedCategory; 347 private String companySuggestedCategory;
291 348
292 /** 349 /**
@@ -330,9 +387,4 @@ public class CustomerCreditHistory extends BaseEntity implements BaseDto { @@ -330,9 +387,4 @@ public class CustomerCreditHistory extends BaseEntity implements BaseDto {
330 */ 387 */
331 private String status; 388 private String status;
332 389
333 - /**  
334 - * 认证证书  
335 - */  
336 - private String certificationCertificate;  
337 -  
338 } 390 }
@@ -12,6 +12,10 @@ import com.lframework.starter.web.core.components.resp.PageResult; @@ -12,6 +12,10 @@ import com.lframework.starter.web.core.components.resp.PageResult;
12 import com.lframework.starter.common.utils.StringUtil; 12 import com.lframework.starter.common.utils.StringUtil;
13 import java.io.Serializable; 13 import java.io.Serializable;
14 import com.lframework.starter.common.utils.Assert; 14 import com.lframework.starter.common.utils.Assert;
  15 +import com.lframework.xingyun.basedata.entity.Customer;
  16 +import com.lframework.xingyun.basedata.service.customer.CustomerService;
  17 +import com.lframework.xingyun.sc.Label;
  18 +import com.lframework.xingyun.sc.bo.customer.credit.ChangeItem;
15 import com.lframework.xingyun.sc.entity.CustomerCreditHistory; 19 import com.lframework.xingyun.sc.entity.CustomerCreditHistory;
16 import com.lframework.xingyun.sc.mappers.CustomerCreditHistoryMapper; 20 import com.lframework.xingyun.sc.mappers.CustomerCreditHistoryMapper;
17 import com.lframework.xingyun.sc.service.customer.CustomerCreditHistoryService; 21 import com.lframework.xingyun.sc.service.customer.CustomerCreditHistoryService;
@@ -22,11 +26,27 @@ import org.springframework.cache.annotation.CacheEvict; @@ -22,11 +26,27 @@ import org.springframework.cache.annotation.CacheEvict;
22 import org.springframework.cache.annotation.Cacheable; 26 import org.springframework.cache.annotation.Cacheable;
23 import org.springframework.stereotype.Service; 27 import org.springframework.stereotype.Service;
24 28
25 -import java.util.List; 29 +import javax.annotation.Resource;
  30 +import java.lang.reflect.Field;
  31 +import java.math.BigDecimal;
  32 +import java.time.LocalDate;
  33 +import java.time.format.DateTimeFormatter;
  34 +import java.util.*;
26 35
27 @Service 36 @Service
28 public class CustomerCreditHistoryServiceImpl extends BaseMpServiceImpl<CustomerCreditHistoryMapper, CustomerCreditHistory> implements CustomerCreditHistoryService { 37 public class CustomerCreditHistoryServiceImpl extends BaseMpServiceImpl<CustomerCreditHistoryMapper, CustomerCreditHistory> implements CustomerCreditHistoryService {
29 38
  39 + @Resource
  40 + private CustomerService customerService;
  41 + // 定义不需要比较的字段
  42 + private static final Set<String> EXCLUDED_FIELDS = new HashSet<>(Arrays.asList(
  43 + "id", "sort", "createById", "createBy", "updateById",
  44 + "updateBy", "createTime", "updateTime", "status"
  45 + ));
  46 +
  47 + // LocalDate 格式化器
  48 + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  49 +
30 @Override 50 @Override
31 public PageResult<CustomerCreditHistory> query(Integer pageIndex, Integer pageSize, QueryCustomerCreditHistoryVo vo) { 51 public PageResult<CustomerCreditHistory> query(Integer pageIndex, Integer pageSize, QueryCustomerCreditHistoryVo vo) {
32 52
@@ -232,6 +252,133 @@ public class CustomerCreditHistoryServiceImpl extends BaseMpServiceImpl<Customer @@ -232,6 +252,133 @@ public class CustomerCreditHistoryServiceImpl extends BaseMpServiceImpl<Customer
232 getBaseMapper().deleteById(id); 252 getBaseMapper().deleteById(id);
233 } 253 }
234 254
  255 + /**
  256 + * 比较两个对象,返回 List<ChangeItem>
  257 + * 内层 map:
  258 + * 1 -> 整体序号(从 1 开始)
  259 + * 2 -> 变更前值
  260 + * 3 -> 变更后值
  261 + */
  262 + public List<ChangeItem> getDifferencesWithIndex(
  263 + CustomerCreditHistory data,
  264 + CustomerCreditHistory customerCreditHistory) {
  265 +
  266 + Map<String, Map<Integer, String>> result = new LinkedHashMap<>();
  267 + Class<?> clazz = CustomerCreditHistory.class;
  268 +
  269 + if (data == null || customerCreditHistory == null) {
  270 + return null;
  271 + }
  272 +
  273 + int index = 1; // 变更序号
  274 +
  275 + try {
  276 + for (Field field : clazz.getDeclaredFields()) {
  277 + String fieldName = field.getName();
  278 +
  279 + if (EXCLUDED_FIELDS.contains(fieldName)) {
  280 + continue;
  281 + }
  282 +
  283 + field.setAccessible(true);
  284 +
  285 + Object value1 = field.get(data);
  286 + Object value2 = field.get(customerCreditHistory);
  287 +
  288 + if (!Objects.equals(value1, value2)) {
  289 + // 获取中文标签,优先使用 @Label,否则用字段名
  290 + String label = getLabel(field);
  291 +
  292 + Map<Integer, String> changeMap = new LinkedHashMap<>();
  293 + changeMap.put(1, String.valueOf(index));
  294 + changeMap.put(2, formatValue(value1));
  295 + changeMap.put(3, formatValue(value2));
  296 +
  297 + result.put(label, changeMap);
  298 + index++;
  299 + }
  300 + }
  301 + } catch (IllegalAccessException e) {
  302 + throw new RuntimeException("字段访问异常", e);
  303 + }
  304 +
  305 + List<ChangeItem> changeItems = toChangeItemList(result);
  306 +
  307 + return changeItems;
  308 +
  309 + }
  310 +
  311 + /**
  312 + * 获取字段的中文标签
  313 + */
  314 + private String getLabel(Field field) {
  315 + Label label = field.getAnnotation(Label.class);
  316 + return label != null ? label.value() : field.getName(); // 没有注解则返回字段名
  317 + }
  318 +
  319 + /**
  320 + * 格式化各种类型的值为可读字符串
  321 + */
  322 + private static String formatValue(Object value) {
  323 + if (value == null) {
  324 + return "null";
  325 + }
  326 +
  327 + if (value instanceof Boolean) {
  328 + return (Boolean) value ? "是" : "否";
  329 + }
  330 +
  331 + if (value instanceof LocalDate) {
  332 + return ((LocalDate) value).format(DATE_FORMATTER);
  333 + }
  334 +
  335 + if (value instanceof BigDecimal) {
  336 + return ((BigDecimal) value).stripTrailingZeros().toPlainString();
  337 + }
  338 +
  339 + if (value instanceof String) {
  340 + return (String) value;
  341 + }
  342 +
  343 + if (value instanceof Integer) {
  344 + return value.toString();
  345 + }
  346 +
  347 + return value.toString();
  348 + }
  349 +
  350 + /**
  351 + * 将嵌套 Map 转换为 List<ChangeItem>
  352 + *
  353 + * @param differencesMap key: 中文字段名, value: {1:序号, 2:变更前, 3:变更后}
  354 + * @return List<ChangeItem>
  355 + */
  356 + public List<ChangeItem> toChangeItemList(Map<String, Map<Integer, String>> differencesMap) {
  357 + List<ChangeItem> list = new ArrayList<>();
  358 +
  359 + for (Map.Entry<String, Map<Integer, String>> entry : differencesMap.entrySet()) {
  360 + String fieldName = entry.getKey(); // 中文字段名,如“区域”
  361 + Map<Integer, String> changeData = entry.getValue();
  362 +
  363 + ChangeItem item = new ChangeItem();
  364 + item.setSerialNumber(Integer.valueOf(changeData.get(1))); // 序号
  365 + String beforeChange = changeData.get(2);
  366 + if (changeData.get(2) == null) {
  367 + beforeChange = "";
  368 + }
  369 + String afterChange = changeData.get(3);
  370 + if (changeData.get(3) == null) {
  371 + afterChange = "";
  372 + }
  373 + item.setBeforeChange(fieldName + ":" + beforeChange); // 变更前
  374 + item.setAfterChange(fieldName + ":" + afterChange); // 变更后
  375 +
  376 + list.add(item);
  377 + }
  378 +
  379 + return list;
  380 + }
  381 +
235 @CacheEvict(value = CustomerCreditHistory.CACHE_NAME, key = "@cacheVariables.tenantId() + #key") 382 @CacheEvict(value = CustomerCreditHistory.CACHE_NAME, key = "@cacheVariables.tenantId() + #key")
236 @Override 383 @Override
237 public void cleanCacheByKey(Serializable key) { 384 public void cleanCacheByKey(Serializable key) {
@@ -2,10 +2,12 @@ package com.lframework.xingyun.sc.service.customer; @@ -2,10 +2,12 @@ package com.lframework.xingyun.sc.service.customer;
2 2
3 import com.lframework.starter.web.core.service.BaseMpService; 3 import com.lframework.starter.web.core.service.BaseMpService;
4 import com.lframework.starter.web.core.components.resp.PageResult; 4 import com.lframework.starter.web.core.components.resp.PageResult;
  5 +import com.lframework.xingyun.sc.bo.customer.credit.ChangeItem;
5 import com.lframework.xingyun.sc.entity.CustomerCreditHistory; 6 import com.lframework.xingyun.sc.entity.CustomerCreditHistory;
6 import com.lframework.xingyun.sc.vo.customer.credit.CreateCustomerCreditHistoryVo; 7 import com.lframework.xingyun.sc.vo.customer.credit.CreateCustomerCreditHistoryVo;
7 import com.lframework.xingyun.sc.vo.customer.credit.QueryCustomerCreditHistoryVo; 8 import com.lframework.xingyun.sc.vo.customer.credit.QueryCustomerCreditHistoryVo;
8 import java.util.List; 9 import java.util.List;
  10 +import java.util.Map;
9 11
10 /** 12 /**
11 * 客户资信历史记录表 Service 13 * 客户资信历史记录表 Service
@@ -46,4 +48,9 @@ public interface CustomerCreditHistoryService extends BaseMpService<CustomerCred @@ -46,4 +48,9 @@ public interface CustomerCreditHistoryService extends BaseMpService<CustomerCred
46 * @return 48 * @return
47 */ 49 */
48 void deleteById(String id); 50 void deleteById(String id);
  51 +
  52 + /**
  53 + * 比较两个 CustomerCreditHistory 对象,返回字段变更描述
  54 + */
  55 + List<ChangeItem> getDifferencesWithIndex(CustomerCreditHistory data, CustomerCreditHistory customerCreditHistory);
49 } 56 }