调整 合同、运力、客商、项目

This commit is contained in:
2026-09-15 11:59:42 +08:00
parent 087d89b31a
commit 0d1f14f703
19 changed files with 285 additions and 49 deletions
@@ -179,4 +179,10 @@ public class Dept extends TenantEntity {
@Schema(description = "是否是oa的部门")
private Integer isOa;
/**
* 是否平台公司:0否,1是
*/
@Schema(description = "是否平台公司:0否,1是")
private Integer isPlatformCompany;
}
@@ -30,6 +30,7 @@ import org.springblade.transport.pojo.entity.CustomerArchive;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serial;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@@ -85,4 +86,20 @@ public class CustomerArchiveVO extends CustomerArchive {
@Schema(description = "客商类型:external外部客商,internal内部组织")
private String customerKind;
@TableField(exist = false)
@Schema(description = "资金使用风险等级:high、medium、none")
private String fundUseRisk;
@TableField(exist = false)
@Schema(description = "资金使用风险名称")
private String fundUseRiskName;
@TableField(exist = false)
@Schema(description = "资金使用率(百分比)")
private BigDecimal fundUseRate;
@TableField(exist = false)
@Schema(description = "已付金额合计(元)")
private BigDecimal usedFundLimit;
}
@@ -50,6 +50,9 @@ public class VehicleDispatchVO extends VehicleDispatch {
@Schema(description = "审批状态名称")
private String approvalStatusName;
@TableField(exist = false)
@Schema(description = "车辆类型")
private String vehicleType;
@TableField(exist = false)
@Schema(description = "创建人姓名")
private String createUserName;
@TableField(exist = false)
@@ -189,12 +189,23 @@ public class DeptController extends BladeController {
return R.data(deptService.selectDept(deptId));
}
/**
* 平台公司下拉(是否平台公司=是)
*/
@PreAuth(AuthConstant.PERMIT_ALL)
@GetMapping("/platform-company-select")
@ApiOperationSupport(order = 9)
@Operation(summary = "平台公司下拉", description = "返回是否平台公司=是的部门列表")
public R<List<Dept>> platformCompanySelect() {
return R.data(deptService.listPlatformCompany());
}
/**
* 获取部门的主管信息
*/
@IsAdmin
@GetMapping("/dept-leader-info")
@ApiOperationSupport(order = 9)
@ApiOperationSupport(order = 10)
@Operation(summary = "获取部门的主管信息", description = "传入deptId")
public R<List<UserVO>> deptLeaderInfo(@Parameter(description = "部门id", required = true) @RequestParam Long deptId) {
List<UserVO> list = deptService.deptLeaderInfo(deptId);
@@ -16,6 +16,7 @@
<result column="pinyin_mnemonic" property="pinyinMnemonic"/>
<result column="mnemonic_code" property="mnemonicCode"/>
<result column="carrier_customer_id" property="carrierCustomerId"/>
<result column="is_platform_company" property="isPlatformCompany"/>
<result column="sort" property="sort"/>
<result column="remark" property="remark"/>
<result column="status" property="status"/>
@@ -35,6 +36,7 @@
<result column="pinyin_mnemonic" property="pinyinMnemonic"/>
<result column="mnemonic_code" property="mnemonicCode"/>
<result column="carrier_customer_id" property="carrierCustomerId"/>
<result column="is_platform_company" property="isPlatformCompany"/>
<result column="sort" property="sort"/>
<result column="remark" property="remark"/>
<result column="status" property="status"/>
@@ -97,6 +97,13 @@ public interface IDeptService extends IService<Dept> {
*/
List<Dept> selectDept(String deptId);
/**
* 平台公司下拉(是否平台公司=是)
*
* @return 平台公司部门列表
*/
List<Dept> listPlatformCompany();
/**
* 根据部门名称精确匹配获取部门ID集合
*
@@ -151,6 +151,18 @@ public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements ID
return baseMapper.selectList(queryWrapper);
}
@Override
public List<Dept> listPlatformCompany() {
LambdaQueryWrapper<Dept> queryWrapper = Wrappers.<Dept>lambdaQuery()
.eq(Dept::getIsPlatformCompany, 1)
.orderByAsc(Dept::getSort)
.orderByAsc(Dept::getId);
if (!AuthUtil.isAdministrator()) {
queryWrapper.eq(Dept::getTenantId, AuthUtil.getTenantId());
}
return list(queryWrapper);
}
@Override
public String getDeptIds(String tenantId, String deptNames) {
List<Dept> deptList = baseMapper.selectList(Wrappers.<Dept>query().lambda().eq(Dept::getTenantId, tenantId).in(Dept::getDeptName, Func.toStrList(deptNames)));
@@ -232,6 +244,9 @@ public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements ID
dept.setAncestors(parent.getAncestors() + StringPool.COMMA + dept.getParentId());
}
dept.setIsDeleted(BladeConstant.DB_NOT_DELETED);
if (dept.getIsPlatformCompany() == null) {
dept.setIsPlatformCompany(0);
}
if (Func.isEmpty(dept.getTenantId())) {
throw new ServiceException("租户ID不能为空");
}
@@ -264,8 +279,10 @@ public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements ID
private void validateDeptCode(Dept dept, Dept parent) {
String deptCode = dept.getDeptCode();
// 组织编码非必填,为空时存 null,避免唯一索引冲突
if (StringUtil.isBlank(deptCode)) {
throw new ServiceException("组织编码不能为空");
dept.setDeptCode(null);
return;
}
deptCode = deptCode.trim();
if (deptCode.length() > 30) {
@@ -132,7 +132,7 @@ public class ContractManageController extends BladeController {
@Operation(summary = "发起变更", description = "传入id、changeContent和changeReason")
public R startChange(@Parameter(description = "主键", required = true) @RequestParam Long id,
@RequestParam(required = false) String changeContent,
@RequestParam String changeReason) {
@RequestParam(required = false) String changeReason) {
return R.status(contractManageService.startChange(id, changeContent, changeReason));
}
@@ -54,36 +54,24 @@ public class CustomerArchiveExcel implements Serializable {
@ExcelProperty("客商简称")
private String shortName;
@ExcelProperty("*客商名称")
@ExcelProperty("客商名称")
private String fullName;
@ExcelProperty("*客商类型")
@ExcelProperty("客商类型")
private String customerType;
@ExcelProperty("*客商性质")
@ExcelProperty("客商性质")
private String customerNature;
@ExcelProperty("*统一信用代码")
@ExcelProperty("统一信用代码")
private String unifiedCreditCode;
@ExcelProperty("*所属组织")
@ExcelProperty("所属组织")
private String deptName;
@ExcelProperty("准入类型")
private String accessTypeName;
@ExcelProperty("审批状态")
private String approvalStatusName;
@ExcelProperty("当前节点")
private String currentNode;
@ExcelProperty("当前处理人")
private String currentProcessor;
@ExcelProperty("审核通过时间")
private LocalDateTime approvedTime;
@ExcelProperty("状态")
private String statusName;
@@ -96,13 +84,25 @@ public class CustomerArchiveExcel implements Serializable {
@ExcelProperty("申请总资金使用额度(万元)")
private BigDecimal applyCreditLimit;
@ExcelProperty("*联系电话")
@ExcelProperty("联系电话")
private String contactPhone;
@ExcelProperty("*法人/负责人")
@ExcelProperty("法人/负责人")
private String legalPerson;
@ExcelProperty("创建时间")
private Date createTime;
@ExcelProperty("审批状态")
private String approvalStatusName;
@ExcelProperty("当前节点")
private String currentNode;
@ExcelProperty("当前处理人")
private String currentProcessor;
@ExcelProperty("审核通过时间")
private LocalDateTime approvedTime;
}
@@ -60,7 +60,7 @@ public class ProjectApplyExcel implements Serializable {
private String projectType;
@ExcelProperty("业务部门")
private String businessDeptName;
@ExcelProperty("承办部门")
@ExcelProperty("平台公司")
private String undertakeDeptName;
@ExcelProperty("项目由来")
private String projectSource;
@@ -30,6 +30,7 @@ public class VehicleDispatchExcel implements Serializable {
@ExcelProperty("车牌号") private String plateNo;
@ExcelProperty("所属组织") private String organizationName;
@ExcelProperty("使用部门") private String useDepartment;
@ExcelProperty("车辆类型") private String vehicleType;
@ExcelProperty("审批状态") private String approvalStatusName;
@ExcelProperty("当前节点") private String currentNode;
@ExcelProperty("当前处理人") private String currentProcessor;
@@ -42,6 +43,7 @@ public class VehicleDispatchExcel implements Serializable {
target.plateNo = source.getPlateNo();
target.organizationName = source.getOrganizationName();
target.useDepartment = source.getUseDepartment();
target.vehicleType = source.getVehicleType();
target.approvalStatusName = source.getApprovalStatusName();
target.currentNode = source.getCurrentNode();
target.currentProcessor = source.getCurrentProcessor();
@@ -8,6 +8,7 @@
<result column="plate_no" property="plateNo"/>
<result column="organization_name" property="organizationName"/>
<result column="use_department" property="useDepartment"/>
<result column="vehicle_type" property="vehicleType"/>
<result column="approval_status" property="approvalStatus"/>
<result column="current_node" property="currentNode"/>
<result column="current_processor" property="currentProcessor"/>
@@ -21,26 +22,31 @@
<result column="attachments" property="attachments"/>
</resultMap>
<select id="selectVehicleDispatchPage" resultMap="vehicleDispatchResultMap">
SELECT id, tenant_id, application_no, plate_no, organization_name, use_department,
approval_status, current_node, current_processor, remark, attachments, create_user,
create_time, update_user, update_time, status, is_deleted
FROM blade_transport_vehicle_dispatch
WHERE is_deleted = 0
SELECT d.id, d.tenant_id, d.application_no, d.plate_no, d.organization_name, d.use_department,
v.vehicle_type, d.approval_status, d.current_node, d.current_processor, d.remark,
d.attachments, d.create_user, d.create_time, d.update_user, d.update_time, d.status,
d.is_deleted
FROM blade_transport_vehicle_dispatch d
LEFT JOIN blade_transport_vehicle v
ON v.plate_no = d.plate_no
AND v.tenant_id = d.tenant_id
AND v.is_deleted = 0
WHERE d.is_deleted = 0
<if test="dispatch.applicationNo != null and dispatch.applicationNo != ''">
AND application_no LIKE CONCAT('%', #{dispatch.applicationNo}, '%')
AND d.application_no LIKE CONCAT('%', #{dispatch.applicationNo}, '%')
</if>
<if test="dispatch.plateNo != null and dispatch.plateNo != ''">
AND plate_no LIKE CONCAT('%', #{dispatch.plateNo}, '%')
AND d.plate_no LIKE CONCAT('%', #{dispatch.plateNo}, '%')
</if>
<if test="dispatch.organizationName != null and dispatch.organizationName != ''">
AND organization_name LIKE CONCAT('%', #{dispatch.organizationName}, '%')
AND d.organization_name LIKE CONCAT('%', #{dispatch.organizationName}, '%')
</if>
<if test="dispatch.useDepartment != null and dispatch.useDepartment != ''">
AND use_department LIKE CONCAT('%', #{dispatch.useDepartment}, '%')
AND d.use_department LIKE CONCAT('%', #{dispatch.useDepartment}, '%')
</if>
<if test="dispatch.approvalStatus != null and dispatch.approvalStatus != ''">
AND approval_status = #{dispatch.approvalStatus}
AND d.approval_status = #{dispatch.approvalStatus}
</if>
ORDER BY create_time DESC
ORDER BY d.create_time DESC
</select>
</mapper>
@@ -251,7 +251,6 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
throw new ServiceException("仅正式合同允许发起变更");
}
String normalizedReason = TransportBusinessSupport.trimToNull(changeReason);
TransportBusinessSupport.validateRequired(normalizedReason, "请输入变更原因");
TransportBusinessSupport.validateLength(normalizedReason, 500, "变更原因不能超过500字");
contractManage.setApprovalStatus(STATUS_CHANGE_REVIEWING);
contractManage.setChangeContent(TransportBusinessSupport.trimToNull(changeContent));
@@ -275,7 +274,6 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
if (Func.isEmpty(changeReason) && Objects.equals(source.getApprovalStatus(), STATUS_CHANGE_REJECTED)) {
changeReason = resolveResubmitChangeReason(source);
}
TransportBusinessSupport.validateRequired(changeReason, "请输入变更原因");
TransportBusinessSupport.validateLength(changeReason, 500, "变更原因不能超过500字");
ContractManage candidate = new ContractManage();
BeanUtil.copyProperties(source, candidate);
@@ -49,6 +49,7 @@ import org.springblade.transport.mapper.CustomerCreditScoreMapper;
import org.springblade.transport.mapper.CustomerInvoiceContactMapper;
import org.springblade.transport.mapper.CustomerInvoiceInfoMapper;
import org.springblade.transport.mapper.CustomerReceiptAccountMapper;
import org.springblade.transport.mapper.PaymentApplicationMapper;
import org.springblade.transport.mapper.UserCustomerScopeMapper;
import org.springblade.transport.pojo.entity.CreditRatingStandard;
import org.springblade.transport.pojo.entity.CreditScoreCategory;
@@ -63,6 +64,7 @@ import org.springblade.transport.pojo.entity.CustomerCreditScoreDetail;
import org.springblade.transport.pojo.entity.CustomerInvoiceContact;
import org.springblade.transport.pojo.entity.CustomerInvoiceInfo;
import org.springblade.transport.pojo.entity.CustomerReceiptAccount;
import org.springblade.transport.pojo.entity.PaymentApplication;
import org.springblade.transport.pojo.vo.CustomerArchiveVO;
import org.springblade.transport.pojo.vo.CustomerChangeRecordVO;
import org.springblade.transport.pojo.vo.CustomerContactVO;
@@ -78,15 +80,19 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
/**
@@ -107,6 +113,15 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
private static final String APPROVAL_APPROVED = "approved";
private static final String APPROVAL_REJECTED = "rejected";
private static final String CUSTOMER_CODE_PREFIX = "KS";
/**
* 变更快照忽略字段:明细每次保存会重建主键/审计字段,不能作为“是否有修改”的依据
*/
private static final Set<String> CHANGE_SNAPSHOT_IGNORE_FIELDS = Set.of(
"id", "customerId", "invoiceId", "scoreId", "tenantId",
"createUser", "createDept", "createTime", "updateUser", "updateTime",
"isDeleted", "status", "regionPath", "deptIdList", "registeredRegionPath",
"fundUseAmount", "fundUseRate", "fundUseRisk", "standards", "attachments"
);
private final CustomerContactMapper contactMapper;
private final CustomerReceiptAccountMapper receiptAccountMapper;
@@ -121,10 +136,13 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
private final CreditScoreItemOptionMapper optionMapper;
private final CreditRatingStandardMapper standardMapper;
private final UserCustomerScopeMapper userCustomerScopeMapper;
private final PaymentApplicationMapper paymentApplicationMapper;
@Override
public IPage<CustomerArchiveVO> selectCustomerArchivePage(IPage<CustomerArchiveVO> page, CustomerArchiveVO customer) {
return page.setRecords(baseMapper.selectCustomerArchivePage(page, customer, AuthUtil.getUserId()));
List<CustomerArchiveVO> records = baseMapper.selectCustomerArchivePage(page, customer, AuthUtil.getUserId());
fillFundUseRisk(records);
return page.setRecords(records);
}
@Override
@@ -156,6 +174,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
detail.setReceiptAccounts(loadReceiptAccounts(id));
detail.setInvoices(loadInvoices(id));
detail.setScores(loadScores(id));
fillFundUseRisk(List.of(detail));
return detail;
}
@@ -177,9 +196,12 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
if (created && result) {
grantNewCustomerToIncludedUsers(entity);
}
// 仅「提交」写入变更记录;「保存」不落变更记录
// 仅「提交」写入变更记录;「保存」不落变更记录
// 保存后重新读取落库结果再对比,避免前端冗余字段造成误判;无实质变更则不记。
if (result && !created && Boolean.TRUE.equals(customer.getRecordChange())) {
addChangeRecord(entity.getId(), "修改客商档案", before, entity, beforeDetail, customer);
CustomerArchiveVO afterDetail = detail(entity.getId());
CustomerArchive afterEntity = Objects.requireNonNull(BeanUtil.copyProperties(afterDetail, CustomerArchive.class));
addChangeRecord(entity.getId(), "修改客商档案", before, afterEntity, beforeDetail, afterDetail);
}
return result;
}
@@ -1011,7 +1033,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
}
Object beforeValue = beforeSnapshot.get(field);
Object afterValue = afterSnapshot.get(field);
if (!Objects.equals(beforeValue, afterValue)) {
if (!isSameSnapshotValue(beforeValue, afterValue)) {
changedFields.add(field);
beforeData.put(field, beforeValue);
afterData.put(field, afterValue);
@@ -1033,14 +1055,93 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
changeRecordMapper.insert(record);
}
private boolean isSameSnapshotValue(Object beforeValue, Object afterValue) {
return Objects.equals(normalizeComparableValue(beforeValue), normalizeComparableValue(afterValue));
}
private Object normalizeComparableValue(Object value) {
if (value == null) {
return "";
}
if (value instanceof BigDecimal decimal) {
return decimal.stripTrailingZeros().toPlainString();
}
if (value instanceof Number number) {
return new BigDecimal(number.toString()).stripTrailingZeros().toPlainString();
}
if (value instanceof LocalDate || value instanceof LocalDateTime) {
return String.valueOf(value);
}
String text = String.valueOf(value).trim();
if (Func.isEmpty(text) || "null".equalsIgnoreCase(text)) {
return "";
}
return text;
}
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()));
snapshot.put("联系人信息", toBusinessSnapshotJson(detail.getContacts()));
snapshot.put("收款信息", toBusinessSnapshotJson(detail.getReceiptAccounts()));
snapshot.put("发票信息", toBusinessSnapshotJson(detail.getInvoices()));
snapshot.put("评分信息", toBusinessSnapshotJson(detail.getScores()));
}
/**
* 明细快照只保留业务字段,并忽略主键/审计字段,避免“无修改提交”因重建 ID 误记变更。
*/
private String toBusinessSnapshotJson(Object value) {
Object parsed = JsonUtil.parse(JsonUtil.toJson(value == null ? List.of() : value), Object.class);
return JsonUtil.toJson(normalizeSnapshotNode(parsed));
}
@SuppressWarnings("unchecked")
private Object normalizeSnapshotNode(Object node) {
if (node == null) {
return null;
}
if (node instanceof Map<?, ?> map) {
Map<String, Object> result = new TreeMap<>();
map.forEach((key, value) -> {
String field = String.valueOf(key);
if (CHANGE_SNAPSHOT_IGNORE_FIELDS.contains(field)) {
return;
}
Object normalized = normalizeSnapshotNode(value);
if (normalized == null || "".equals(normalized)) {
return;
}
if (normalized instanceof Map<?, ?> nestedMap && nestedMap.isEmpty()) {
return;
}
if (normalized instanceof List<?> nestedList && nestedList.isEmpty()) {
return;
}
result.put(field, normalized);
});
return result;
}
if (node instanceof List<?> list) {
List<Object> result = list.stream()
.map(this::normalizeSnapshotNode)
.filter(Objects::nonNull)
.collect(Collectors.toCollection(ArrayList::new));
result.sort(Comparator.comparing(JsonUtil::toJson));
return result;
}
if (node instanceof BigDecimal decimal) {
return decimal.stripTrailingZeros().toPlainString();
}
if (node instanceof Number number) {
return new BigDecimal(number.toString()).stripTrailingZeros().toPlainString();
}
if (node instanceof Boolean || node instanceof LocalDate || node instanceof LocalDateTime) {
return node;
}
String text = String.valueOf(node).trim();
return Func.isEmpty(text) || "null".equalsIgnoreCase(text) ? null : text;
}
private Map<String, Object> customerSnapshot(CustomerArchive customer) {
@@ -1085,6 +1186,65 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
return snapshot;
}
/**
* 资金使用情况 = 付款申请中「付款方=当前客商」且审核通过的已付金额合计;
* 资金使用额度风险 = 合计已付金额 / 客商最大资金使用额度。
*/
private void fillFundUseRisk(List<CustomerArchiveVO> records) {
if (records == null || records.isEmpty()) {
return;
}
Set<String> payerNames = new HashSet<>();
records.forEach(customer -> {
if (Func.isNotEmpty(customer.getFullName())) {
payerNames.add(customer.getFullName().trim());
}
if (Func.isNotEmpty(customer.getShortName())) {
payerNames.add(customer.getShortName().trim());
}
});
Map<String, BigDecimal> paidAmountByPayer = new HashMap<>();
if (!payerNames.isEmpty()) {
paymentApplicationMapper.selectList(Wrappers.<PaymentApplication>lambdaQuery()
.in(PaymentApplication::getPayerName, payerNames)
.eq(PaymentApplication::getApprovalStatus, APPROVAL_APPROVED)
.eq(PaymentApplication::getIsDeleted, 0))
.forEach(item -> {
String payerName = Func.toStr(item.getPayerName()).trim();
if (Func.isEmpty(payerName)) {
return;
}
paidAmountByPayer.merge(payerName, nonNegative(item.getPaidAmount()), BigDecimal::add);
});
}
records.forEach(customer -> {
BigDecimal usedFundLimit = BigDecimal.ZERO;
if (Func.isNotEmpty(customer.getFullName())) {
usedFundLimit = usedFundLimit.add(paidAmountByPayer.getOrDefault(customer.getFullName().trim(), BigDecimal.ZERO));
}
if (Func.isNotEmpty(customer.getShortName())) {
String shortName = customer.getShortName().trim();
if (!shortName.equals(Func.toStr(customer.getFullName()).trim())) {
usedFundLimit = usedFundLimit.add(paidAmountByPayer.getOrDefault(shortName, BigDecimal.ZERO));
}
}
BigDecimal maxCreditLimitYuan = nonNegative(customer.getMaxCreditLimit()).multiply(BigDecimal.valueOf(10000));
BigDecimal fundUseRate = maxCreditLimitYuan.signum() == 0
? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
: usedFundLimit.multiply(BigDecimal.valueOf(100)).divide(maxCreditLimitYuan, 2, RoundingMode.HALF_UP);
String risk = fundUseRate.compareTo(new BigDecimal("90")) >= 0 ? "high"
: fundUseRate.compareTo(new BigDecimal("80")) >= 0 ? "medium" : "none";
customer.setUsedFundLimit(usedFundLimit);
customer.setFundUseRate(fundUseRate);
customer.setFundUseRisk(risk);
customer.setFundUseRiskName("high".equals(risk) ? "高风险" : "medium".equals(risk) ? "中风险" : "无风险");
});
}
private BigDecimal nonNegative(BigDecimal value) {
return value == null || value.signum() < 0 ? BigDecimal.ZERO : value;
}
private CustomerArchiveExcel buildExcel(CustomerArchive customer) {
CustomerArchiveExcel excel = new CustomerArchiveExcel();
excel.setCustomerCode(customer.getCustomerCode());
@@ -683,7 +683,7 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
Map<String, String> labels = Map.ofEntries(
Map.entry("projectType", "项目类型"), Map.entry("projectName", "项目名称"),
Map.entry("projectShortName", "项目简称"), Map.entry("businessDeptName", "业务部门"),
Map.entry("undertakeDeptName", "承办部门"), Map.entry("projectSource", "项目由来"),
Map.entry("undertakeDeptName", "平台公司"), Map.entry("projectSource", "项目由来"),
Map.entry("sourceRemark", "项目由来说明"), Map.entry("fundLimit", "项目资金使用额度"),
Map.entry("receivableLimit", "项目应收账款额度"), Map.entry("receivableDays", "应收账款回款期限"),
Map.entry("paymentDays", "回款账期"), Map.entry("cargoType", "货物类型"),
@@ -717,7 +717,7 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
validateDraft(projectApply);
TransportBusinessSupport.validateRequired(projectApply.getProjectShortName(), "请输入项目简称");
TransportBusinessSupport.validateRequired(projectApply.getBusinessDeptName(), "请选择业务部门");
TransportBusinessSupport.validateRequired(projectApply.getUndertakeDeptName(), "请选择承办部门");
TransportBusinessSupport.validateRequired(projectApply.getUndertakeDeptName(), "请选择平台公司");
TransportBusinessSupport.validateRequired(projectApply.getBusinessMode(), "请选择业务模式");
TransportBusinessSupport.validateRequired(projectApply.getCustomerNames(), "请选择客户");
TransportBusinessSupport.validateRequired(projectApply.getCarrierNames(), "请选择下游承运商");
@@ -242,9 +242,6 @@ public class TemporaryCreditLimitServiceImpl extends BaseServiceImpl<TemporaryCr
TransportBusinessSupport.validateRequired(temporaryCreditLimit.getProjectCode(), "项目编号不能为空");
TransportBusinessSupport.validateRequired(temporaryCreditLimit.getUndertakeDeptName(), "承办部门不能为空");
TransportBusinessSupport.validateRequired(temporaryCreditLimit.getValidUntil() == null ? null : temporaryCreditLimit.getValidUntil().toString(), "请选择申请有效期至");
if (temporaryCreditLimit.getValidUntil() != null && !temporaryCreditLimit.getValidUntil().isAfter(LocalDate.now())) {
throw new ServiceException("申请有效期至必须晚于当前日期");
}
if (temporaryCreditLimit.getProjectFundLimit() == null || temporaryCreditLimit.getUsedFundLimit() == null || temporaryCreditLimit.getRemainingFundLimit() == null) {
throw new ServiceException("项目额度数据异常,请重新选择项目");
}
@@ -29,7 +29,12 @@ public class VehicleDispatchWrapper extends BaseEntityWrapper<VehicleDispatch, V
@Override
public VehicleDispatchVO entityVO(VehicleDispatch entity) {
if (entity == null) return null;
String vehicleType = null;
if (entity instanceof VehicleDispatchVO vehicleDispatchVO) {
vehicleType = vehicleDispatchVO.getVehicleType();
}
VehicleDispatchVO vo = Objects.requireNonNull(BeanUtil.copyProperties(entity, VehicleDispatchVO.class));
vo.setVehicleType(vehicleType);
vo.setCreateUserName(org.springblade.system.cache.UserCache.getUserRealName(entity.getCreateUser()));
vo.setUpdateUserName(org.springblade.system.cache.UserCache.getUserRealName(entity.getUpdateUser()));
vo.setApprovalStatusName(statusName(entity.getApprovalStatus()));
@@ -307,6 +307,7 @@ CREATE TABLE `blade_dept` (
`pinyin_mnemonic` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '拼音助记码',
`mnemonic_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '助记码',
`carrier_customer_id` bigint NULL DEFAULT NULL COMMENT '承运商客商档案主键',
`is_platform_company` tinyint NOT NULL DEFAULT 0 COMMENT '是否平台公司:0否,1是',
`sort` int NULL DEFAULT NULL COMMENT '排序',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注',
`status` int NULL DEFAULT 1 COMMENT '状态',
@@ -0,0 +1,4 @@
-- 机构表:新增「是否平台公司」字段,默认否
ALTER TABLE `blade_dept`
ADD COLUMN `is_platform_company` tinyint NOT NULL DEFAULT 0 COMMENT '是否平台公司:0否,1是' AFTER `carrier_customer_id`;