fix bug
This commit is contained in:
+9
@@ -57,6 +57,15 @@ public class CustomerChangeRecord extends TenantEntity {
|
|||||||
@Schema(description = "变更内容")
|
@Schema(description = "变更内容")
|
||||||
private String changeContent;
|
private String changeContent;
|
||||||
|
|
||||||
|
@Schema(description = "变更字段,多个字段以逗号分隔")
|
||||||
|
private String changedFields;
|
||||||
|
|
||||||
|
@Schema(description = "变更前数据JSON")
|
||||||
|
private String beforeData;
|
||||||
|
|
||||||
|
@Schema(description = "变更后数据JSON")
|
||||||
|
private String afterData;
|
||||||
|
|
||||||
@Schema(description = "变更账号")
|
@Schema(description = "变更账号")
|
||||||
private String changeUserName;
|
private String changeUserName;
|
||||||
|
|
||||||
|
|||||||
+12
@@ -43,6 +43,7 @@ import org.springblade.core.tool.utils.Func;
|
|||||||
import org.springblade.transport.excel.CustomerArchiveExcel;
|
import org.springblade.transport.excel.CustomerArchiveExcel;
|
||||||
import org.springblade.transport.pojo.entity.CustomerArchive;
|
import org.springblade.transport.pojo.entity.CustomerArchive;
|
||||||
import org.springblade.transport.pojo.vo.CustomerArchiveVO;
|
import org.springblade.transport.pojo.vo.CustomerArchiveVO;
|
||||||
|
import org.springblade.transport.pojo.vo.CustomerChangeRecordVO;
|
||||||
import org.springblade.transport.pojo.vo.CustomerCreditScoreVO;
|
import org.springblade.transport.pojo.vo.CustomerCreditScoreVO;
|
||||||
import org.springblade.transport.service.ICustomerArchiveService;
|
import org.springblade.transport.service.ICustomerArchiveService;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@@ -89,6 +90,17 @@ public class CustomerArchiveController extends BladeController {
|
|||||||
return R.data(pages);
|
return R.data(pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变更记录分页
|
||||||
|
*/
|
||||||
|
@GetMapping("/change-record/list")
|
||||||
|
@ApiOperationSupport(order = 3)
|
||||||
|
@Operation(summary = "客商变更记录分页", description = "传入客商ID")
|
||||||
|
public R<IPage<CustomerChangeRecordVO>> changeRecordList(
|
||||||
|
@Parameter(description = "客商ID", required = true) @RequestParam Long customerId, Query query) {
|
||||||
|
return R.data(customerArchiveService.selectChangeRecordPage(Condition.getPage(query), customerId));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增或修改
|
* 新增或修改
|
||||||
*/
|
*/
|
||||||
|
|||||||
+2
-2
@@ -144,8 +144,8 @@ public class ProjectApplyController extends BladeController {
|
|||||||
@ApiOperationSupport(order = 12)
|
@ApiOperationSupport(order = 12)
|
||||||
@Operation(summary = "发起变更", description = "传入id、changeContent和changeReason")
|
@Operation(summary = "发起变更", description = "传入id、changeContent和changeReason")
|
||||||
public R startChange(@Parameter(description = "主键", required = true) @RequestParam Long id,
|
public R startChange(@Parameter(description = "主键", required = true) @RequestParam Long id,
|
||||||
@RequestParam String changeContent,
|
@RequestParam(required = false) String changeContent,
|
||||||
@RequestParam String changeReason) {
|
@RequestParam(required = false) String changeReason) {
|
||||||
return R.status(projectApplyService.startChange(id, changeContent, changeReason));
|
return R.status(projectApplyService.startChange(id, changeContent, changeReason));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
@@ -28,6 +28,7 @@ import org.springblade.core.mp.base.BaseService;
|
|||||||
import org.springblade.transport.excel.CustomerArchiveExcel;
|
import org.springblade.transport.excel.CustomerArchiveExcel;
|
||||||
import org.springblade.transport.pojo.entity.CustomerArchive;
|
import org.springblade.transport.pojo.entity.CustomerArchive;
|
||||||
import org.springblade.transport.pojo.vo.CustomerArchiveVO;
|
import org.springblade.transport.pojo.vo.CustomerArchiveVO;
|
||||||
|
import org.springblade.transport.pojo.vo.CustomerChangeRecordVO;
|
||||||
import org.springblade.transport.pojo.vo.CustomerCreditScoreVO;
|
import org.springblade.transport.pojo.vo.CustomerCreditScoreVO;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -48,6 +49,15 @@ public interface ICustomerArchiveService extends BaseService<CustomerArchive> {
|
|||||||
*/
|
*/
|
||||||
IPage<CustomerArchiveVO> selectCustomerArchivePage(IPage<CustomerArchiveVO> page, CustomerArchiveVO customer);
|
IPage<CustomerArchiveVO> selectCustomerArchivePage(IPage<CustomerArchiveVO> page, CustomerArchiveVO customer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客商变更记录分页
|
||||||
|
*
|
||||||
|
* @param page 分页参数
|
||||||
|
* @param customerId 客商ID
|
||||||
|
* @return 变更记录分页
|
||||||
|
*/
|
||||||
|
IPage<CustomerChangeRecordVO> selectChangeRecordPage(IPage<CustomerChangeRecordVO> page, Long customerId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 聚合详情
|
* 聚合详情
|
||||||
*
|
*
|
||||||
|
|||||||
+173
-61
@@ -27,6 +27,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springblade.core.log.exception.ServiceException;
|
import org.springblade.core.log.exception.ServiceException;
|
||||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||||
@@ -122,33 +123,46 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
return page.setRecords(baseMapper.selectCustomerArchivePage(page, customer, AuthUtil.getUserId()));
|
return page.setRecords(baseMapper.selectCustomerArchivePage(page, customer, AuthUtil.getUserId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPage<CustomerChangeRecordVO> selectChangeRecordPage(IPage<CustomerChangeRecordVO> page, Long customerId) {
|
||||||
|
if (Func.isEmpty(customerId)) {
|
||||||
|
throw new ServiceException("客商ID不能为空");
|
||||||
|
}
|
||||||
|
ensureCustomerAccessible(customerId);
|
||||||
|
IPage<CustomerChangeRecord> recordPage = changeRecordMapper.selectPage(
|
||||||
|
new Page<>(page.getCurrent(), page.getSize()),
|
||||||
|
Wrappers.<CustomerChangeRecord>lambdaQuery()
|
||||||
|
.eq(CustomerChangeRecord::getCustomerId, customerId)
|
||||||
|
.eq(CustomerChangeRecord::getIsDeleted, 0)
|
||||||
|
.orderByDesc(CustomerChangeRecord::getChangeTime));
|
||||||
|
page.setTotal(recordPage.getTotal());
|
||||||
|
return page.setRecords(recordPage.getRecords().stream()
|
||||||
|
.map(record -> Objects.requireNonNull(BeanUtil.copyProperties(record, CustomerChangeRecordVO.class)))
|
||||||
|
.toList());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CustomerArchiveVO detail(Long id) {
|
public CustomerArchiveVO detail(Long id) {
|
||||||
if (Func.isEmpty(id)) {
|
if (Func.isEmpty(id)) {
|
||||||
throw new ServiceException("主键不能为空");
|
throw new ServiceException("主键不能为空");
|
||||||
}
|
}
|
||||||
CustomerArchive customer = getById(id);
|
CustomerArchive customer = ensureCustomerAccessible(id);
|
||||||
if (Func.isEmpty(customer) || Objects.equals(customer.getIsDeleted(), 1)) {
|
|
||||||
throw new ServiceException("客商档案不存在");
|
|
||||||
}
|
|
||||||
if (baseMapper.selectCustomerPermissionCount(id, AuthUtil.getUserId()) == 0) {
|
|
||||||
throw new ServiceException("无权访问该客商档案");
|
|
||||||
}
|
|
||||||
CustomerArchiveVO detail = Objects.requireNonNull(BeanUtil.copyProperties(customer, CustomerArchiveVO.class));
|
CustomerArchiveVO detail = Objects.requireNonNull(BeanUtil.copyProperties(customer, CustomerArchiveVO.class));
|
||||||
detail.setContacts(loadContacts(id));
|
detail.setContacts(loadContacts(id));
|
||||||
detail.setReceiptAccounts(loadReceiptAccounts(id));
|
detail.setReceiptAccounts(loadReceiptAccounts(id));
|
||||||
detail.setInvoices(loadInvoices(id));
|
detail.setInvoices(loadInvoices(id));
|
||||||
detail.setScores(loadScores(id));
|
detail.setScores(loadScores(id));
|
||||||
detail.setChangeRecords(loadChangeRecords(id));
|
|
||||||
return detail;
|
return detail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean submit(CustomerArchiveVO customer) {
|
public boolean submit(CustomerArchiveVO customer) {
|
||||||
|
CustomerArchiveVO beforeDetail = Func.isEmpty(customer.getId()) ? null : detail(customer.getId());
|
||||||
prepare(customer);
|
prepare(customer);
|
||||||
validateBase(customer);
|
validateBase(customer);
|
||||||
boolean created = Func.isEmpty(customer.getId());
|
boolean created = Func.isEmpty(customer.getId());
|
||||||
|
CustomerArchive before = created ? null : ensureCustomerAccessible(customer.getId());
|
||||||
if (created) {
|
if (created) {
|
||||||
customer.setCustomerCode(nextCustomerCode());
|
customer.setCustomerCode(nextCustomerCode());
|
||||||
}
|
}
|
||||||
@@ -159,7 +173,9 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
if (created && result) {
|
if (created && result) {
|
||||||
grantNewCustomerToIncludedUsers(entity);
|
grantNewCustomerToIncludedUsers(entity);
|
||||||
}
|
}
|
||||||
addChangeRecord(entity.getId(), created ? "新增客商档案" : "修改客商档案");
|
if (result) {
|
||||||
|
addChangeRecord(entity.getId(), created ? "新增客商档案" : "修改客商档案", before, entity, beforeDetail, customer);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,32 +186,28 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
prepare(detail);
|
prepare(detail);
|
||||||
validateBase(detail);
|
validateBase(detail);
|
||||||
validateApproval(detail);
|
validateApproval(detail);
|
||||||
CustomerArchive update = new CustomerArchive();
|
CustomerArchive before = Objects.requireNonNull(BeanUtil.copyProperties(detail, CustomerArchive.class));
|
||||||
update.setId(id);
|
CustomerArchive after = copyCustomer(before);
|
||||||
update.setApprovalStatus(APPROVAL_REVIEWING);
|
after.setApprovalStatus(APPROVAL_REVIEWING);
|
||||||
update.setCurrentNode("客商准入审批");
|
after.setCurrentNode("客商准入审批");
|
||||||
update.setCurrentProcessor("待处理");
|
after.setCurrentProcessor("待处理");
|
||||||
addChangeRecord(id, "提交客商准入审批");
|
addChangeRecord(id, "提交客商准入审批", before, after);
|
||||||
return updateById(update);
|
return updateById(after);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean withdrawApproval(Long id) {
|
public boolean withdrawApproval(Long id) {
|
||||||
CustomerArchive customer = getById(id);
|
CustomerArchive customer = ensureCustomerAccessible(id);
|
||||||
if (Func.isEmpty(customer) || Objects.equals(customer.getIsDeleted(), 1)) {
|
|
||||||
throw new ServiceException("客商档案不存在");
|
|
||||||
}
|
|
||||||
if (!List.of(APPROVAL_DRAFT, APPROVAL_REVIEWING).contains(customer.getApprovalStatus())) {
|
if (!List.of(APPROVAL_DRAFT, APPROVAL_REVIEWING).contains(customer.getApprovalStatus())) {
|
||||||
throw new ServiceException("仅未审核或审核中状态客商可撤回");
|
throw new ServiceException("仅未审核或审核中状态客商可撤回");
|
||||||
}
|
}
|
||||||
CustomerArchive update = new CustomerArchive();
|
CustomerArchive after = copyCustomer(customer);
|
||||||
update.setId(id);
|
after.setApprovalStatus(APPROVAL_DRAFT);
|
||||||
update.setApprovalStatus(APPROVAL_DRAFT);
|
after.setCurrentNode("草稿");
|
||||||
update.setCurrentNode("草稿");
|
after.setCurrentProcessor(AuthUtil.getUserName());
|
||||||
update.setCurrentProcessor(AuthUtil.getUserName());
|
addChangeRecord(id, "撤回客商准入审批", customer, after);
|
||||||
addChangeRecord(id, "撤回客商准入审批");
|
return updateById(after);
|
||||||
return updateById(update);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -205,27 +217,27 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
prepare(detail);
|
prepare(detail);
|
||||||
validateBase(detail);
|
validateBase(detail);
|
||||||
validateApproval(detail);
|
validateApproval(detail);
|
||||||
CustomerArchive update = new CustomerArchive();
|
CustomerArchive before = Objects.requireNonNull(BeanUtil.copyProperties(detail, CustomerArchive.class));
|
||||||
update.setId(id);
|
CustomerArchive after = copyCustomer(before);
|
||||||
update.setAccessType(ACCESS_FORMAL);
|
after.setAccessType(ACCESS_FORMAL);
|
||||||
update.setApprovalStatus(APPROVAL_APPROVED);
|
after.setApprovalStatus(APPROVAL_APPROVED);
|
||||||
update.setCurrentNode("审核通过");
|
after.setCurrentNode("审核通过");
|
||||||
update.setCurrentProcessor(AuthUtil.getUserName());
|
after.setCurrentProcessor(AuthUtil.getUserName());
|
||||||
update.setApprovedTime(LocalDateTime.now());
|
after.setApprovedTime(LocalDateTime.now());
|
||||||
addChangeRecord(id, "客商准入审核通过");
|
addChangeRecord(id, "客商准入审核通过", before, after);
|
||||||
return updateById(update);
|
return updateById(after);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean reject(Long id) {
|
public boolean reject(Long id) {
|
||||||
CustomerArchive update = new CustomerArchive();
|
CustomerArchive before = ensureCustomerAccessible(id);
|
||||||
update.setId(id);
|
CustomerArchive after = copyCustomer(before);
|
||||||
update.setApprovalStatus(APPROVAL_REJECTED);
|
after.setApprovalStatus(APPROVAL_REJECTED);
|
||||||
update.setCurrentNode("审核不通过");
|
after.setCurrentNode("审核不通过");
|
||||||
update.setCurrentProcessor(AuthUtil.getUserName());
|
after.setCurrentProcessor(AuthUtil.getUserName());
|
||||||
addChangeRecord(id, "客商准入审核不通过");
|
addChangeRecord(id, "客商准入审核不通过", before, after);
|
||||||
return updateById(update);
|
return updateById(after);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -234,15 +246,11 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
if (!Objects.equals(status, STATUS_ENABLED) && !Objects.equals(status, STATUS_DISABLED)) {
|
if (!Objects.equals(status, STATUS_ENABLED) && !Objects.equals(status, STATUS_DISABLED)) {
|
||||||
throw new ServiceException("启停状态不正确");
|
throw new ServiceException("启停状态不正确");
|
||||||
}
|
}
|
||||||
CustomerArchive customer = getById(id);
|
CustomerArchive customer = ensureCustomerAccessible(id);
|
||||||
if (Func.isEmpty(customer) || Objects.equals(customer.getIsDeleted(), 1)) {
|
CustomerArchive after = copyCustomer(customer);
|
||||||
throw new ServiceException("客商档案不存在");
|
after.setStatus(status);
|
||||||
}
|
addChangeRecord(id, Objects.equals(status, STATUS_ENABLED) ? "启用客商档案" : "停用客商档案", customer, after);
|
||||||
CustomerArchive update = new CustomerArchive();
|
return updateById(after);
|
||||||
update.setId(id);
|
|
||||||
update.setStatus(status);
|
|
||||||
addChangeRecord(id, Objects.equals(status, STATUS_ENABLED) ? "启用客商档案" : "停用客商档案");
|
|
||||||
return updateById(update);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -477,6 +485,9 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
score.setIsDeleted(0);
|
score.setIsDeleted(0);
|
||||||
creditScoreMapper.insert(score);
|
creditScoreMapper.insert(score);
|
||||||
List<CustomerCreditScoreDetailVO> details = scoreVO.getDetails() == null ? new ArrayList<>() : scoreVO.getDetails();
|
List<CustomerCreditScoreDetailVO> details = scoreVO.getDetails() == null ? new ArrayList<>() : scoreVO.getDetails();
|
||||||
|
if (Func.isEmpty(details)) {
|
||||||
|
throw new ServiceException("评分明细不能为空,请重新读取评分量化表后再保存");
|
||||||
|
}
|
||||||
for (int detailIndex = 0; detailIndex < details.size(); detailIndex++) {
|
for (int detailIndex = 0; detailIndex < details.size(); detailIndex++) {
|
||||||
CustomerCreditScoreDetailVO detailVO = details.get(detailIndex);
|
CustomerCreditScoreDetailVO detailVO = details.get(detailIndex);
|
||||||
if (Func.isEmpty(detailVO.getScore())) {
|
if (Func.isEmpty(detailVO.getScore())) {
|
||||||
@@ -484,6 +495,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
}
|
}
|
||||||
CustomerCreditScoreDetail detail = Objects.requireNonNull(BeanUtil.copyProperties(detailVO, CustomerCreditScoreDetail.class));
|
CustomerCreditScoreDetail detail = Objects.requireNonNull(BeanUtil.copyProperties(detailVO, CustomerCreditScoreDetail.class));
|
||||||
detail.setId(IdWorker.getId());
|
detail.setId(IdWorker.getId());
|
||||||
|
detail.setTenantId(score.getTenantId());
|
||||||
detail.setScoreId(scoreId);
|
detail.setScoreId(scoreId);
|
||||||
detail.setQuantificationId(score.getQuantificationId());
|
detail.setQuantificationId(score.getQuantificationId());
|
||||||
detail.setSort(detailIndex + 1);
|
detail.setSort(detailIndex + 1);
|
||||||
@@ -604,14 +616,6 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<CustomerChangeRecordVO> loadChangeRecords(Long customerId) {
|
|
||||||
return changeRecordMapper.selectList(Wrappers.<CustomerChangeRecord>lambdaQuery()
|
|
||||||
.eq(CustomerChangeRecord::getCustomerId, customerId)
|
|
||||||
.eq(CustomerChangeRecord::getIsDeleted, 0)
|
|
||||||
.orderByDesc(CustomerChangeRecord::getChangeTime))
|
|
||||||
.stream().map(record -> Objects.requireNonNull(BeanUtil.copyProperties(record, CustomerChangeRecordVO.class))).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private CreditScoreQuantification resolveQuantification(Long quantificationId) {
|
private CreditScoreQuantification resolveQuantification(Long quantificationId) {
|
||||||
CreditScoreQuantification quantification;
|
CreditScoreQuantification quantification;
|
||||||
if (Func.isNotEmpty(quantificationId)) {
|
if (Func.isNotEmpty(quantificationId)) {
|
||||||
@@ -763,17 +767,125 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
return CUSTOMER_CODE_PREFIX + String.format("%06d", nextNumber);
|
return CUSTOMER_CODE_PREFIX + String.format("%06d", nextNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addChangeRecord(Long customerId, String content) {
|
private CustomerArchive ensureCustomerAccessible(Long id) {
|
||||||
|
CustomerArchive customer = getById(id);
|
||||||
|
if (Func.isEmpty(customer) || Objects.equals(customer.getIsDeleted(), 1)) {
|
||||||
|
throw new ServiceException("客商档案不存在");
|
||||||
|
}
|
||||||
|
if (baseMapper.selectCustomerPermissionCount(id, AuthUtil.getUserId()) == 0) {
|
||||||
|
throw new ServiceException("无权访问该客商档案");
|
||||||
|
}
|
||||||
|
return customer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CustomerArchive copyCustomer(CustomerArchive customer) {
|
||||||
|
return Objects.requireNonNull(BeanUtil.copyProperties(customer, CustomerArchive.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addChangeRecord(Long customerId, String content, CustomerArchive before, CustomerArchive after) {
|
||||||
|
Map<String, Object> beforeSnapshot = customerSnapshot(before);
|
||||||
|
Map<String, Object> afterSnapshot = customerSnapshot(after);
|
||||||
|
addDetailSnapshot(beforeSnapshot, null);
|
||||||
|
addDetailSnapshot(afterSnapshot, null);
|
||||||
|
writeChangeRecord(customerId, content, beforeSnapshot, afterSnapshot);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addChangeRecord(Long customerId, String content, CustomerArchive before, CustomerArchive after,
|
||||||
|
CustomerArchiveVO beforeDetail, CustomerArchiveVO afterDetail) {
|
||||||
|
Map<String, Object> beforeSnapshot = customerSnapshot(before);
|
||||||
|
Map<String, Object> afterSnapshot = customerSnapshot(after);
|
||||||
|
addDetailSnapshot(beforeSnapshot, beforeDetail);
|
||||||
|
addDetailSnapshot(afterSnapshot, afterDetail);
|
||||||
|
writeChangeRecord(customerId, content, beforeSnapshot, afterSnapshot);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeChangeRecord(Long customerId, String content, Map<String, Object> beforeSnapshot,
|
||||||
|
Map<String, Object> afterSnapshot) {
|
||||||
|
for (String field : afterSnapshot.keySet()) {
|
||||||
|
beforeSnapshot.putIfAbsent(field, null);
|
||||||
|
}
|
||||||
|
Map<String, Object> beforeData = new LinkedHashMap<>();
|
||||||
|
Map<String, Object> afterData = new LinkedHashMap<>();
|
||||||
|
List<String> changedFields = new ArrayList<>();
|
||||||
|
for (String field : beforeSnapshot.keySet()) {
|
||||||
|
if (!afterSnapshot.containsKey(field)) {
|
||||||
|
afterSnapshot.put(field, null);
|
||||||
|
}
|
||||||
|
Object beforeValue = beforeSnapshot.get(field);
|
||||||
|
Object afterValue = afterSnapshot.get(field);
|
||||||
|
if (!Objects.equals(beforeValue, afterValue)) {
|
||||||
|
changedFields.add(field);
|
||||||
|
beforeData.put(field, beforeValue);
|
||||||
|
afterData.put(field, afterValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changedFields.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
CustomerChangeRecord record = new CustomerChangeRecord();
|
CustomerChangeRecord record = new CustomerChangeRecord();
|
||||||
record.setId(IdWorker.getId());
|
record.setId(IdWorker.getId());
|
||||||
record.setCustomerId(customerId);
|
record.setCustomerId(customerId);
|
||||||
record.setChangeTime(LocalDateTime.now());
|
record.setChangeTime(LocalDateTime.now());
|
||||||
record.setChangeContent(content);
|
record.setChangeContent(content);
|
||||||
|
record.setChangedFields(String.join("、", changedFields));
|
||||||
|
record.setBeforeData(JsonUtil.toJson(beforeData));
|
||||||
|
record.setAfterData(JsonUtil.toJson(afterData));
|
||||||
record.setChangeUserName(AuthUtil.getUserName());
|
record.setChangeUserName(AuthUtil.getUserName());
|
||||||
record.setStatus(STATUS_ENABLED);
|
record.setStatus(STATUS_ENABLED);
|
||||||
changeRecordMapper.insert(record);
|
changeRecordMapper.insert(record);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addDetailSnapshot(Map<String, Object> snapshot, CustomerArchiveVO detail) {
|
||||||
|
if (detail == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
snapshot.put("联系人信息", JsonUtil.toJson(detail.getContacts()));
|
||||||
|
snapshot.put("收款信息", JsonUtil.toJson(detail.getReceiptAccounts()));
|
||||||
|
snapshot.put("发票信息", JsonUtil.toJson(detail.getInvoices()));
|
||||||
|
snapshot.put("评分信息", JsonUtil.toJson(detail.getScores()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> customerSnapshot(CustomerArchive customer) {
|
||||||
|
Map<String, Object> snapshot = new LinkedHashMap<>();
|
||||||
|
if (customer == null) {
|
||||||
|
return snapshot;
|
||||||
|
}
|
||||||
|
snapshot.put("客商编号", customer.getCustomerCode());
|
||||||
|
snapshot.put("客商简称", customer.getShortName());
|
||||||
|
snapshot.put("客商全称", customer.getFullName());
|
||||||
|
snapshot.put("客商性质", customer.getCustomerNature());
|
||||||
|
snapshot.put("统一社会信用代码", customer.getUnifiedCreditCode());
|
||||||
|
snapshot.put("客商类型", customer.getCustomerType());
|
||||||
|
snapshot.put("所属项目", customer.getProjectName());
|
||||||
|
snapshot.put("注册/实际经营地址", customer.getRegisteredAddress());
|
||||||
|
snapshot.put("注册地址行政区划", customer.getRegisteredRegionName());
|
||||||
|
snapshot.put("注册地址详细地址", customer.getRegisteredDetailAddress());
|
||||||
|
snapshot.put("法人/负责人", customer.getLegalPerson());
|
||||||
|
snapshot.put("联系电话", customer.getContactPhone());
|
||||||
|
snapshot.put("所属组织ID", customer.getDeptId());
|
||||||
|
snapshot.put("所属组织ID集合", customer.getDeptIds());
|
||||||
|
snapshot.put("所属组织", customer.getDeptName());
|
||||||
|
snapshot.put("开票税点", customer.getInvoiceTaxRate());
|
||||||
|
snapshot.put("经营范围", customer.getBusinessScope());
|
||||||
|
snapshot.put("营业期限类型", customer.getBusinessTermType());
|
||||||
|
snapshot.put("营业期限截止日", customer.getBusinessEndDate());
|
||||||
|
snapshot.put("注册资金(万元)", customer.getRegisteredCapital());
|
||||||
|
snapshot.put("客商负责人", customer.getPrincipal());
|
||||||
|
snapshot.put("助记码", customer.getMnemonicCode());
|
||||||
|
snapshot.put("客户等级", customer.getCustomerLevel());
|
||||||
|
snapshot.put("最大资金使用额度(万元)", customer.getMaxCreditLimit());
|
||||||
|
snapshot.put("申请总资金使用额度(万元)", customer.getApplyCreditLimit());
|
||||||
|
snapshot.put("备注", customer.getRemark());
|
||||||
|
snapshot.put("客商材料", customer.getQualificationAttachments());
|
||||||
|
snapshot.put("准入类型", customer.getAccessType());
|
||||||
|
snapshot.put("审批状态", customer.getApprovalStatus());
|
||||||
|
snapshot.put("当前节点", customer.getCurrentNode());
|
||||||
|
snapshot.put("当前处理人", customer.getCurrentProcessor());
|
||||||
|
snapshot.put("审核通过时间", customer.getApprovedTime());
|
||||||
|
snapshot.put("状态", customer.getStatus());
|
||||||
|
return snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
private CustomerArchiveExcel buildExcel(CustomerArchive customer) {
|
private CustomerArchiveExcel buildExcel(CustomerArchive customer) {
|
||||||
CustomerArchiveExcel excel = new CustomerArchiveExcel();
|
CustomerArchiveExcel excel = new CustomerArchiveExcel();
|
||||||
excel.setCustomerCode(customer.getCustomerCode());
|
excel.setCustomerCode(customer.getCustomerCode());
|
||||||
|
|||||||
-4
@@ -214,8 +214,6 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
|||||||
if (!canCurrentUserOperate(projectApply)) {
|
if (!canCurrentUserOperate(projectApply)) {
|
||||||
throw new ServiceException("无权操作其他组织项目立项");
|
throw new ServiceException("无权操作其他组织项目立项");
|
||||||
}
|
}
|
||||||
TransportBusinessSupport.validateRequired(changeContent, "请输入变更内容");
|
|
||||||
TransportBusinessSupport.validateRequired(changeReason, "请输入变更原因");
|
|
||||||
projectApply.setApprovalStatus(STATUS_CHANGE_REVIEWING);
|
projectApply.setApprovalStatus(STATUS_CHANGE_REVIEWING);
|
||||||
projectApply.setChangeContent(TransportBusinessSupport.trimToNull(changeContent));
|
projectApply.setChangeContent(TransportBusinessSupport.trimToNull(changeContent));
|
||||||
projectApply.setChangeReason(TransportBusinessSupport.trimToNull(changeReason));
|
projectApply.setChangeReason(TransportBusinessSupport.trimToNull(changeReason));
|
||||||
@@ -439,8 +437,6 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
|||||||
if (!List.of(CHANGE_TYPE_PROJECT, CHANGE_TYPE_RECORD).contains(changeType)) {
|
if (!List.of(CHANGE_TYPE_PROJECT, CHANGE_TYPE_RECORD).contains(changeType)) {
|
||||||
throw new ServiceException("请选择变更类型");
|
throw new ServiceException("请选择变更类型");
|
||||||
}
|
}
|
||||||
TransportBusinessSupport.validateRequired(projectApply.getChangeContent(), "请输入变更内容");
|
|
||||||
TransportBusinessSupport.validateRequired(projectApply.getChangeReason(), "请输入变更原因");
|
|
||||||
validateChangeLength(projectApply);
|
validateChangeLength(projectApply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+34
-5
@@ -45,6 +45,7 @@ import org.springblade.transport.wrapper.WaybillWrapper;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -427,11 +428,13 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
|
|||||||
} else {
|
} else {
|
||||||
TransportBusinessSupport.validateRequired(waybill.getDriverName(), "司机不能为空");
|
TransportBusinessSupport.validateRequired(waybill.getDriverName(), "司机不能为空");
|
||||||
TransportBusinessSupport.validateRequired(waybill.getDriverPhone(), "司机手机号不能为空");
|
TransportBusinessSupport.validateRequired(waybill.getDriverPhone(), "司机手机号不能为空");
|
||||||
TransportBusinessSupport.validateRequired(waybill.getTrailerVehicleNo(), "挂车车牌号不能为空");
|
if (!isRoadTransport(waybill.getTransportType())) {
|
||||||
TransportBusinessSupport.validateRequired(waybill.getEscortName(), "押运人不能为空");
|
TransportBusinessSupport.validateRequired(waybill.getTrailerVehicleNo(), "挂车车牌号不能为空");
|
||||||
TransportBusinessSupport.validateRequired(waybill.getEscortPhone(), "押运人手机号不能为空");
|
TransportBusinessSupport.validateRequired(waybill.getEscortName(), "押运人不能为空");
|
||||||
if (Func.isEmpty(waybill.getMileage())) {
|
TransportBusinessSupport.validateRequired(waybill.getEscortPhone(), "押运人手机号不能为空");
|
||||||
throw new ServiceException("里程不能为空");
|
if (Func.isEmpty(waybill.getMileage())) {
|
||||||
|
throw new ServiceException("里程不能为空");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TransportBusinessSupport.validateRequired(waybill.getCarrierJson(), "承运信息不能为空");
|
TransportBusinessSupport.validateRequired(waybill.getCarrierJson(), "承运信息不能为空");
|
||||||
@@ -492,6 +495,7 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
|
|||||||
TransportBusinessSupport.validateNonNegative(waybill.getMileage(), "里程");
|
TransportBusinessSupport.validateNonNegative(waybill.getMileage(), "里程");
|
||||||
TransportBusinessSupport.validateNonNegative(waybill.getUnitPrice(), "单价");
|
TransportBusinessSupport.validateNonNegative(waybill.getUnitPrice(), "单价");
|
||||||
TransportBusinessSupport.validateNonNegative(waybill.getOtherFeeTotal(), "其他费用合计");
|
TransportBusinessSupport.validateNonNegative(waybill.getOtherFeeTotal(), "其他费用合计");
|
||||||
|
validateRoadTaskInfo(waybill);
|
||||||
TransportBusinessSupport.validateDateRange(waybill.getStartDate(), waybill.getEndDate(), "开始日期不能晚于结束日期");
|
TransportBusinessSupport.validateDateRange(waybill.getStartDate(), waybill.getEndDate(), "开始日期不能晚于结束日期");
|
||||||
if (waybill.getEstimatedStartTime() != null
|
if (waybill.getEstimatedStartTime() != null
|
||||||
&& waybill.getEstimatedEndTime() != null
|
&& waybill.getEstimatedEndTime() != null
|
||||||
@@ -518,6 +522,31 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateRoadTaskInfo(Waybill waybill) {
|
||||||
|
if (!isRoadTransport(waybill.getTransportType())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TransportBusinessSupport.validateLength(waybill.getDriverName(), 20, "司机姓名不能超过20字");
|
||||||
|
TransportBusinessSupport.validateLength(waybill.getDriverPhone(), 20, "司机手机号不能超过20字");
|
||||||
|
TransportBusinessSupport.validateLength(waybill.getVehicleNo(), 30, "车牌号不能超过30字");
|
||||||
|
TransportBusinessSupport.validateLength(waybill.getTrailerVehicleNo(), 30, "挂车车牌号不能超过30字");
|
||||||
|
TransportBusinessSupport.validateLength(waybill.getEscortName(), 20, "押运人不能超过20字");
|
||||||
|
TransportBusinessSupport.validateLength(waybill.getEscortPhone(), 20, "押运人手机号不能超过20字");
|
||||||
|
BigDecimal mileage = waybill.getMileage();
|
||||||
|
if (mileage == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BigDecimal normalizedMileage = mileage.stripTrailingZeros();
|
||||||
|
if (normalizedMileage.signum() <= 0 || normalizedMileage.scale() > 0 || normalizedMileage.precision() > 10) {
|
||||||
|
throw new ServiceException("里程必须为不超过10位的正整数");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRoadTransport(String transportType) {
|
||||||
|
String value = transportType == null ? "" : transportType.toLowerCase();
|
||||||
|
return value.contains("公路") || value.contains("道路") || value.contains("road") || "gl".equals(value);
|
||||||
|
}
|
||||||
|
|
||||||
private void fillJsonFromFlatFields(Waybill waybill) {
|
private void fillJsonFromFlatFields(Waybill waybill) {
|
||||||
if (Func.isEmpty(waybill.getTaskEntryMode())) {
|
if (Func.isEmpty(waybill.getTaskEntryMode())) {
|
||||||
waybill.setTaskEntryMode("simple");
|
waybill.setTaskEntryMode("simple");
|
||||||
|
|||||||
@@ -221,6 +221,9 @@ CREATE TABLE `blade_customer_change_record` (
|
|||||||
`customer_id` bigint NOT NULL COMMENT '客商ID',
|
`customer_id` bigint NOT NULL COMMENT '客商ID',
|
||||||
`change_time` datetime NULL DEFAULT NULL COMMENT '变更日期',
|
`change_time` datetime NULL DEFAULT NULL COMMENT '变更日期',
|
||||||
`change_content` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '变更内容',
|
`change_content` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '变更内容',
|
||||||
|
`changed_fields` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '变更字段',
|
||||||
|
`before_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '变更前数据JSON',
|
||||||
|
`after_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '变更后数据JSON',
|
||||||
`change_user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '变更账号',
|
`change_user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '变更账号',
|
||||||
`create_user` bigint NULL DEFAULT NULL COMMENT '创建人',
|
`create_user` bigint NULL DEFAULT NULL COMMENT '创建人',
|
||||||
`create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门',
|
`create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门',
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- 客商变更记录:增加字段变更审计明细
|
||||||
|
|
||||||
|
ALTER TABLE `blade_customer_change_record`
|
||||||
|
ADD COLUMN `changed_fields` varchar(1000) DEFAULT NULL COMMENT '变更字段' AFTER `change_content`,
|
||||||
|
ADD COLUMN `before_data` text COMMENT '变更前数据JSON' AFTER `changed_fields`,
|
||||||
|
ADD COLUMN `after_data` text COMMENT '变更后数据JSON' AFTER `before_data`;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
-- 修复评分明细未写入 tenant_id 导致被多租户拦截器过滤的问题。
|
||||||
|
-- 明细租户与所属评分主记录保持一致;仅更新 tenant_id 为空的历史数据。
|
||||||
|
|
||||||
|
UPDATE `blade_customer_credit_score_detail` detail
|
||||||
|
INNER JOIN `blade_customer_credit_score` score ON score.`id` = detail.`score_id`
|
||||||
|
SET detail.`tenant_id` = score.`tenant_id`
|
||||||
|
WHERE (detail.`tenant_id` IS NULL OR TRIM(detail.`tenant_id`) = '')
|
||||||
|
AND score.`tenant_id` IS NOT NULL
|
||||||
|
AND TRIM(score.`tenant_id`) <> '';
|
||||||
Reference in New Issue
Block a user