+2
@@ -30,6 +30,8 @@ public class FormalSettlementSaveRequest implements Serializable {
|
|||||||
private String businessModel;
|
private String businessModel;
|
||||||
/** 运输方式(业务字典 transport_type) */
|
/** 运输方式(业务字典 transport_type) */
|
||||||
private String transportType;
|
private String transportType;
|
||||||
|
/** 用印类型(多选,顿号拼接:公章、业务章) */
|
||||||
|
private String sealTypes;
|
||||||
private LocalDate exchangeRateDate;
|
private LocalDate exchangeRateDate;
|
||||||
private BigDecimal exchangeRate;
|
private BigDecimal exchangeRate;
|
||||||
private String attachmentsJson;
|
private String attachmentsJson;
|
||||||
|
|||||||
+3
@@ -61,6 +61,9 @@ public class PreSettlementSaveRequest implements Serializable {
|
|||||||
@Schema(description = "运输方式(业务字典 transport_type)")
|
@Schema(description = "运输方式(业务字典 transport_type)")
|
||||||
private String transportType;
|
private String transportType;
|
||||||
|
|
||||||
|
@Schema(description = "用印类型(多选,顿号拼接:公章、业务章)")
|
||||||
|
private String sealTypes;
|
||||||
|
|
||||||
@Schema(description = "汇率日期")
|
@Schema(description = "汇率日期")
|
||||||
private LocalDate exchangeRateDate;
|
private LocalDate exchangeRateDate;
|
||||||
|
|
||||||
|
|||||||
+4
@@ -96,6 +96,10 @@ public class FormalSettlement extends TenantEntity {
|
|||||||
* 运输方式(业务字典 transport_type)
|
* 运输方式(业务字典 transport_type)
|
||||||
*/
|
*/
|
||||||
private String transportType;
|
private String transportType;
|
||||||
|
/**
|
||||||
|
* 用印类型(多选,顿号拼接:公章、业务章)
|
||||||
|
*/
|
||||||
|
private String sealTypes;
|
||||||
/**
|
/**
|
||||||
* 本位币,默认 RMB
|
* 本位币,默认 RMB
|
||||||
*/
|
*/
|
||||||
|
|||||||
+3
@@ -98,6 +98,9 @@ public class PreSettlement extends TenantEntity {
|
|||||||
@Schema(description = "运输方式(业务字典 transport_type)")
|
@Schema(description = "运输方式(业务字典 transport_type)")
|
||||||
private String transportType;
|
private String transportType;
|
||||||
|
|
||||||
|
@Schema(description = "用印类型(多选,顿号拼接:公章、业务章)")
|
||||||
|
private String sealTypes;
|
||||||
|
|
||||||
@Schema(description = "本位币")
|
@Schema(description = "本位币")
|
||||||
private String localCurrency;
|
private String localCurrency;
|
||||||
|
|
||||||
|
|||||||
+3
@@ -188,6 +188,9 @@ public class ProjectChange extends TenantEntity {
|
|||||||
@Schema(description = "项目附件JSON")
|
@Schema(description = "项目附件JSON")
|
||||||
private String attachmentsJson;
|
private String attachmentsJson;
|
||||||
|
|
||||||
|
@Schema(description = "调整材料JSON(含原附件快照与调整原因)")
|
||||||
|
private String adjustAttachmentsJson;
|
||||||
|
|
||||||
@Schema(description = "审批状态")
|
@Schema(description = "审批状态")
|
||||||
private String approvalStatus;
|
private String approvalStatus;
|
||||||
|
|
||||||
|
|||||||
+1
@@ -101,6 +101,7 @@ public class FormalSettlementController extends BladeController {
|
|||||||
excel.setSettlementAmount(formatMoney(vo.getSettlementAmount(), vo.getCurrency()));
|
excel.setSettlementAmount(formatMoney(vo.getSettlementAmount(), vo.getCurrency()));
|
||||||
excel.setBusinessModelName(vo.getBusinessModelName());
|
excel.setBusinessModelName(vo.getBusinessModelName());
|
||||||
excel.setTransportTypeName(vo.getTransportTypeName());
|
excel.setTransportTypeName(vo.getTransportTypeName());
|
||||||
|
excel.setSealTypes(vo.getSealTypes());
|
||||||
excel.setLocalSettlementAmount(formatMoney(vo.getLocalSettlementAmount(), vo.getLocalCurrency()));
|
excel.setLocalSettlementAmount(formatMoney(vo.getLocalSettlementAmount(), vo.getLocalCurrency()));
|
||||||
excel.setExchangeRate(vo.getExchangeRate() == null ? "" : vo.getExchangeRate().stripTrailingZeros().toPlainString());
|
excel.setExchangeRate(vo.getExchangeRate() == null ? "" : vo.getExchangeRate().stripTrailingZeros().toPlainString());
|
||||||
excel.setInvoiceStatusName(invoiceStatusName(vo.getInvoiceStatus(), vo.getSettlementType()));
|
excel.setInvoiceStatusName(invoiceStatusName(vo.getInvoiceStatus(), vo.getSettlementType()));
|
||||||
|
|||||||
+1
@@ -252,6 +252,7 @@ public class PreSettlementController extends BladeController {
|
|||||||
excel.setSettlementAmount(formatMoney(vo.getSettlementAmount(), vo.getCurrency()));
|
excel.setSettlementAmount(formatMoney(vo.getSettlementAmount(), vo.getCurrency()));
|
||||||
excel.setBusinessModelName(vo.getBusinessModelName());
|
excel.setBusinessModelName(vo.getBusinessModelName());
|
||||||
excel.setTransportTypeName(vo.getTransportTypeName());
|
excel.setTransportTypeName(vo.getTransportTypeName());
|
||||||
|
excel.setSealTypes(vo.getSealTypes());
|
||||||
excel.setLocalSettlementAmount(formatMoney(vo.getLocalSettlementAmount(), vo.getLocalCurrency()));
|
excel.setLocalSettlementAmount(formatMoney(vo.getLocalSettlementAmount(), vo.getLocalCurrency()));
|
||||||
excel.setExchangeRate(vo.getExchangeRate() == null ? "" : vo.getExchangeRate().stripTrailingZeros().toPlainString());
|
excel.setExchangeRate(vo.getExchangeRate() == null ? "" : vo.getExchangeRate().stripTrailingZeros().toPlainString());
|
||||||
excel.setAdvanceAppliedAmount(formatMoney(vo.getAdvanceAppliedAmount(), vo.getCurrency()));
|
excel.setAdvanceAppliedAmount(formatMoney(vo.getAdvanceAppliedAmount(), vo.getCurrency()));
|
||||||
|
|||||||
+2
@@ -43,6 +43,8 @@ public class FormalSettlementExcel implements Serializable {
|
|||||||
private String businessModelName;
|
private String businessModelName;
|
||||||
@ExcelProperty("运输方式")
|
@ExcelProperty("运输方式")
|
||||||
private String transportTypeName;
|
private String transportTypeName;
|
||||||
|
@ExcelProperty("用印类型")
|
||||||
|
private String sealTypes;
|
||||||
@ExcelProperty("本位币结算金额")
|
@ExcelProperty("本位币结算金额")
|
||||||
private String localSettlementAmount;
|
private String localSettlementAmount;
|
||||||
@ExcelProperty("结算汇率")
|
@ExcelProperty("结算汇率")
|
||||||
|
|||||||
+2
@@ -54,6 +54,8 @@ public class PreSettlementExcel implements Serializable {
|
|||||||
private String businessModelName;
|
private String businessModelName;
|
||||||
@ExcelProperty("运输方式")
|
@ExcelProperty("运输方式")
|
||||||
private String transportTypeName;
|
private String transportTypeName;
|
||||||
|
@ExcelProperty("用印类型")
|
||||||
|
private String sealTypes;
|
||||||
@ExcelProperty("本位币结算金额")
|
@ExcelProperty("本位币结算金额")
|
||||||
private String localSettlementAmount;
|
private String localSettlementAmount;
|
||||||
@ExcelProperty("结算汇率")
|
@ExcelProperty("结算汇率")
|
||||||
|
|||||||
+1
@@ -651,6 +651,7 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
|
|||||||
if (first == null) copyHeader(contract, settlementType, directDetails.get(0), settlement); else copyHeader(first, settlement);
|
if (first == null) copyHeader(contract, settlementType, directDetails.get(0), settlement); else copyHeader(first, settlement);
|
||||||
settlement.setBusinessModel(limit(request.getBusinessModel(), 64));
|
settlement.setBusinessModel(limit(request.getBusinessModel(), 64));
|
||||||
settlement.setTransportType(limit(request.getTransportType(), 64));
|
settlement.setTransportType(limit(request.getTransportType(), 64));
|
||||||
|
settlement.setSealTypes(TransportBusinessSupport.normalizeSettlementSealTypes(request.getSealTypes()));
|
||||||
settlement.setExchangeRateDate(request.getExchangeRateDate());
|
settlement.setExchangeRateDate(request.getExchangeRateDate());
|
||||||
settlement.setExchangeRate(request.getExchangeRate() == null ? BigDecimal.ONE : positive(request.getExchangeRate(), "结算汇率"));
|
settlement.setExchangeRate(request.getExchangeRate() == null ? BigDecimal.ONE : positive(request.getExchangeRate(), "结算汇率"));
|
||||||
BigDecimal sourceAmount = sources.stream().map(PreSettlement::getSettlementAmount).map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add);
|
BigDecimal sourceAmount = sources.stream().map(PreSettlement::getSettlementAmount).map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
|
|||||||
+1
@@ -417,6 +417,7 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
|
|||||||
fillContract(settlement, contract);
|
fillContract(settlement, contract);
|
||||||
settlement.setBusinessModel(limitText(request.getBusinessModel(), 64, "业务模式"));
|
settlement.setBusinessModel(limitText(request.getBusinessModel(), 64, "业务模式"));
|
||||||
settlement.setTransportType(limitText(request.getTransportType(), 64, "运输方式"));
|
settlement.setTransportType(limitText(request.getTransportType(), 64, "运输方式"));
|
||||||
|
settlement.setSealTypes(TransportBusinessSupport.normalizeSettlementSealTypes(request.getSealTypes()));
|
||||||
settlement.setExchangeRateDate(request.getExchangeRateDate());
|
settlement.setExchangeRateDate(request.getExchangeRateDate());
|
||||||
settlement.setExchangeRate(request.getExchangeRate());
|
settlement.setExchangeRate(request.getExchangeRate());
|
||||||
settlement.setAttachmentsJson(request.getAttachmentsJson());
|
settlement.setAttachmentsJson(request.getAttachmentsJson());
|
||||||
|
|||||||
+124
-1
@@ -63,10 +63,12 @@ import java.time.format.DateTimeFormatter;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -345,6 +347,7 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 将变更单可回写字段映射为临时 ProjectApply,供 copyChangeFields 复用。
|
* 将变更单可回写字段映射为临时 ProjectApply,供 copyChangeFields 复用。
|
||||||
|
* 项目材料:以变更单原材料为基础,按调整材料替换/追加后回写原项目档案。
|
||||||
*/
|
*/
|
||||||
private ProjectApply toProjectApplySnapshot(ProjectChange change) {
|
private ProjectApply toProjectApplySnapshot(ProjectChange change) {
|
||||||
ProjectApply snapshot = new ProjectApply();
|
ProjectApply snapshot = new ProjectApply();
|
||||||
@@ -378,12 +381,132 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
|||||||
snapshot.setCustomerJson(change.getCustomerJson());
|
snapshot.setCustomerJson(change.getCustomerJson());
|
||||||
snapshot.setCarrierJson(change.getCarrierJson());
|
snapshot.setCarrierJson(change.getCarrierJson());
|
||||||
snapshot.setSituationRemark(change.getSituationRemark());
|
snapshot.setSituationRemark(change.getSituationRemark());
|
||||||
snapshot.setAttachmentsJson(change.getAttachmentsJson());
|
snapshot.setAttachmentsJson(applyAdjustAttachments(change.getAttachmentsJson(), change.getAdjustAttachmentsJson()));
|
||||||
snapshot.setChangeContent(change.getChangeContent());
|
snapshot.setChangeContent(change.getChangeContent());
|
||||||
snapshot.setChangeReason(change.getChangeReason());
|
snapshot.setChangeReason(change.getChangeReason());
|
||||||
return snapshot;
|
return snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批通过后应用调整材料:有原附件则替换,无原附件则追加;新材料同步到项目档案【项目材料】。
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private String applyAdjustAttachments(String attachmentsJson, String adjustAttachmentsJson) {
|
||||||
|
List<Map<String, Object>> materials = parseAttachmentMapList(attachmentsJson);
|
||||||
|
List<Map<String, Object>> adjustRows = parseAttachmentMapList(adjustAttachmentsJson);
|
||||||
|
if (adjustRows.isEmpty()) {
|
||||||
|
return TransportBusinessSupport.trimToNull(attachmentsJson);
|
||||||
|
}
|
||||||
|
Set<Integer> replacedIndexes = new HashSet<>();
|
||||||
|
for (Map<String, Object> adjustRow : adjustRows) {
|
||||||
|
if (adjustRow == null || adjustRow.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Map<String, Object> nextMaterial = toProjectMaterialRow(adjustRow);
|
||||||
|
if (nextMaterial.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int originIndex = findOriginAttachmentIndex(materials, adjustRow, replacedIndexes);
|
||||||
|
if (originIndex >= 0) {
|
||||||
|
materials.set(originIndex, nextMaterial);
|
||||||
|
replacedIndexes.add(originIndex);
|
||||||
|
} else {
|
||||||
|
materials.add(nextMaterial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return materials.isEmpty() ? null : JsonUtil.toJson(materials);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Map<String, Object>> parseAttachmentMapList(String value) {
|
||||||
|
if (Func.isEmpty(value)) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Object parsed = JsonUtil.parse(value, List.class);
|
||||||
|
if (!(parsed instanceof List<?> list)) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
List<Map<String, Object>> rows = new ArrayList<>();
|
||||||
|
for (Object item : list) {
|
||||||
|
if (item instanceof Map<?, ?> map) {
|
||||||
|
Map<String, Object> row = new LinkedHashMap<>();
|
||||||
|
map.forEach((key, val) -> row.put(String.valueOf(key), val));
|
||||||
|
rows.add(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> toProjectMaterialRow(Map<String, Object> adjustRow) {
|
||||||
|
Map<String, Object> material = new LinkedHashMap<>(adjustRow);
|
||||||
|
material.remove("adjustReason");
|
||||||
|
material.remove("originAttachment");
|
||||||
|
material.remove("originKey");
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private int findOriginAttachmentIndex(List<Map<String, Object>> materials, Map<String, Object> adjustRow,
|
||||||
|
Set<Integer> replacedIndexes) {
|
||||||
|
Object originObj = adjustRow.get("originAttachment");
|
||||||
|
Map<String, Object> origin = null;
|
||||||
|
if (originObj instanceof Map<?, ?> map) {
|
||||||
|
origin = new LinkedHashMap<>();
|
||||||
|
Map<String, Object> finalOrigin = origin;
|
||||||
|
map.forEach((key, val) -> finalOrigin.put(String.valueOf(key), val));
|
||||||
|
}
|
||||||
|
String originKey = String.valueOf(adjustRow.getOrDefault("originKey", "")).trim();
|
||||||
|
for (int index = 0; index < materials.size(); index++) {
|
||||||
|
if (replacedIndexes.contains(index)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Map<String, Object> current = materials.get(index);
|
||||||
|
if (Func.isNotEmpty(originKey) && originKey.equals(attachmentIdentity(current))) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
if (origin != null && attachmentIdentity(current).equals(attachmentIdentity(origin))) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String attachmentIdentity(Map<String, Object> row) {
|
||||||
|
if (row == null || row.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String uid = String.valueOf(row.getOrDefault("uid", "")).trim();
|
||||||
|
if (Func.isNotEmpty(uid) && !"null".equals(uid)) {
|
||||||
|
return "uid:" + uid;
|
||||||
|
}
|
||||||
|
for (String field : List.of("url", "link", "fileUrl", "downloadUrl", "src", "domain")) {
|
||||||
|
String value = String.valueOf(row.getOrDefault(field, "")).trim();
|
||||||
|
if (Func.isNotEmpty(value) && !"null".equals(value)) {
|
||||||
|
return "url:" + value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String fileType = String.valueOf(row.getOrDefault("fileType", "")).trim();
|
||||||
|
String name = firstAttachmentName(row);
|
||||||
|
if (Func.isNotEmpty(fileType) || Func.isNotEmpty(name)) {
|
||||||
|
return "name:" + fileType + "|" + name;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String firstAttachmentName(Map<String, Object> row) {
|
||||||
|
for (String field : List.of("originalName", "name", "fileName")) {
|
||||||
|
String value = String.valueOf(row.getOrDefault(field, "")).trim();
|
||||||
|
if (Func.isNotEmpty(value) && !"null".equals(value)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean removeDraft(String ids) {
|
public boolean removeDraft(String ids) {
|
||||||
|
|||||||
+2
@@ -126,6 +126,7 @@ public class ProjectChangeServiceImpl extends BaseServiceImpl<ProjectChangeMappe
|
|||||||
projectChange.setChangeDate(LocalDate.now());
|
projectChange.setChangeDate(LocalDate.now());
|
||||||
projectChange.setChangeContent(null);
|
projectChange.setChangeContent(null);
|
||||||
projectChange.setChangeReason(null);
|
projectChange.setChangeReason(null);
|
||||||
|
projectChange.setAdjustAttachmentsJson(null);
|
||||||
projectChange.setBeforeDataJson(JsonUtil.toJson(buildSnapshot(projectApply)));
|
projectChange.setBeforeDataJson(JsonUtil.toJson(buildSnapshot(projectApply)));
|
||||||
projectChange.setApprovalStatus(STATUS_DRAFT);
|
projectChange.setApprovalStatus(STATUS_DRAFT);
|
||||||
projectChange.setCurrentNode("草稿");
|
projectChange.setCurrentNode("草稿");
|
||||||
@@ -350,6 +351,7 @@ public class ProjectChangeServiceImpl extends BaseServiceImpl<ProjectChangeMappe
|
|||||||
target.setCarrierJson(source.getCarrierJson());
|
target.setCarrierJson(source.getCarrierJson());
|
||||||
target.setSituationRemark(source.getSituationRemark());
|
target.setSituationRemark(source.getSituationRemark());
|
||||||
target.setAttachmentsJson(source.getAttachmentsJson());
|
target.setAttachmentsJson(source.getAttachmentsJson());
|
||||||
|
target.setAdjustAttachmentsJson(source.getAdjustAttachmentsJson());
|
||||||
if (source.getReceivableDays() != null && source.getReceivableDays() == -1) {
|
if (source.getReceivableDays() != null && source.getReceivableDays() == -1) {
|
||||||
target.setReceivableDays(null);
|
target.setReceivableDays(null);
|
||||||
}
|
}
|
||||||
|
|||||||
+56
-4
@@ -34,6 +34,7 @@ import org.springblade.system.cache.RoleDataScopeCache;
|
|||||||
import org.springblade.system.cache.SysCache;
|
import org.springblade.system.cache.SysCache;
|
||||||
import org.springblade.system.cache.UserCache;
|
import org.springblade.system.cache.UserCache;
|
||||||
import org.springblade.system.pojo.entity.Dept;
|
import org.springblade.system.pojo.entity.Dept;
|
||||||
|
import org.springblade.system.pojo.enums.RoleDataScopeType;
|
||||||
import org.springblade.system.pojo.vo.RoleDataScopeVO;
|
import org.springblade.system.pojo.vo.RoleDataScopeVO;
|
||||||
import org.springblade.transport.mapper.ProjectApplyMapper;
|
import org.springblade.transport.mapper.ProjectApplyMapper;
|
||||||
import org.springblade.transport.pojo.entity.ProjectApply;
|
import org.springblade.transport.pojo.entity.ProjectApply;
|
||||||
@@ -61,6 +62,8 @@ public final class TransportBusinessSupport {
|
|||||||
public static final String DATA_SOURCE_MANUAL = "手工创建";
|
public static final String DATA_SOURCE_MANUAL = "手工创建";
|
||||||
public static final String DATA_SOURCE_PLAN_DISPATCH = "计划调度";
|
public static final String DATA_SOURCE_PLAN_DISPATCH = "计划调度";
|
||||||
public static final String DATA_SOURCE_EXTERNAL = "外部系统";
|
public static final String DATA_SOURCE_EXTERNAL = "外部系统";
|
||||||
|
/** 结算单用印类型固定选项(展示顺序固定) */
|
||||||
|
public static final List<String> SETTLEMENT_SEAL_TYPE_OPTIONS = List.of("公章", "业务章");
|
||||||
/** 站点名(省+市+区县)列宽:blade_waybill.departure_name / arrival_name 为 varchar(100) */
|
/** 站点名(省+市+区县)列宽:blade_waybill.departure_name / arrival_name 为 varchar(100) */
|
||||||
public static final int REGION_NAME_MAX_LENGTH = 100;
|
public static final int REGION_NAME_MAX_LENGTH = 100;
|
||||||
|
|
||||||
@@ -134,7 +137,8 @@ public final class TransportBusinessSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析指定菜单下的角色数据权限(超管视为全部组织),并与用户「数据管理权限」组织取并集。
|
* 解析指定菜单下的角色数据权限(超管视为全部组织)。
|
||||||
|
* 全部组织、本人创建以角色权限为准;所在部门及下级按用户数据权限组织。
|
||||||
*/
|
*/
|
||||||
public static RoleDataScopeVO resolveRoleDataScope(String menuCode) {
|
public static RoleDataScopeVO resolveRoleDataScope(String menuCode) {
|
||||||
if (isAdministrator()) {
|
if (isAdministrator()) {
|
||||||
@@ -166,7 +170,8 @@ public final class TransportBusinessSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析最宽角色数据权限,并与用户「数据管理权限」组织取并集。
|
* 解析最宽角色数据权限。
|
||||||
|
* 全部组织、本人创建以角色权限为准;所在部门及下级按用户数据权限组织。
|
||||||
*/
|
*/
|
||||||
public static RoleDataScopeVO resolveWidestDataScope() {
|
public static RoleDataScopeVO resolveWidestDataScope() {
|
||||||
if (isAdministrator()) {
|
if (isAdministrator()) {
|
||||||
@@ -177,9 +182,12 @@ public final class TransportBusinessSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色组织权限与用户数据管理组织取并集。
|
* 按角色数据权限类型决定是否采用用户数据权限组织。
|
||||||
* <p>
|
* <p>
|
||||||
* 全部组织 / 本人创建 不因用户管理组织改变;其余类型将用户管理组织(含下级)并入 deptIds。
|
* 全部组织、本人创建以角色权限为准,不按用户数据权限收窄。
|
||||||
|
* 所在部门及下级改为用户「数据管理权限」组织(含下级);同时存在自定义组织时取并集。
|
||||||
|
* 自定义组织仍与用户数据权限组织取并集。
|
||||||
|
* 所在部门及下级且用户未配置数据权限组织时,返回不可命中的组织,避免回落到所属组织或全部数据。
|
||||||
*/
|
*/
|
||||||
private static RoleDataScopeVO mergeUserManageDepts(RoleDataScopeVO scope) {
|
private static RoleDataScopeVO mergeUserManageDepts(RoleDataScopeVO scope) {
|
||||||
if (scope == null || scope.isAllDept() || scope.isOwnCreate()) {
|
if (scope == null || scope.isAllDept() || scope.isOwnCreate()) {
|
||||||
@@ -187,6 +195,19 @@ public final class TransportBusinessSupport {
|
|||||||
}
|
}
|
||||||
Long userId = AuthUtil.getUserId();
|
Long userId = AuthUtil.getUserId();
|
||||||
List<Long> manageDeptIds = UserCache.getManageDeptIds(userId);
|
List<Long> manageDeptIds = UserCache.getManageDeptIds(userId);
|
||||||
|
if (RoleDataScopeType.DEPT_AND_CHILD.matches(scope.getScopeType())) {
|
||||||
|
LinkedHashSet<Long> deptIds = new LinkedHashSet<>();
|
||||||
|
if (Func.isNotEmpty(scope.getDeptIds())) {
|
||||||
|
deptIds.addAll(scope.getDeptIds());
|
||||||
|
}
|
||||||
|
if (Func.isNotEmpty(manageDeptIds)) {
|
||||||
|
deptIds.addAll(manageDeptIds);
|
||||||
|
}
|
||||||
|
if (deptIds.isEmpty()) {
|
||||||
|
return RoleDataScopeVO.ofDepts(RoleDataScopeType.DEPT_AND_CHILD.getCode(), List.of(-1L));
|
||||||
|
}
|
||||||
|
return RoleDataScopeVO.ofDepts(RoleDataScopeType.DEPT_AND_CHILD.getCode(), List.copyOf(deptIds));
|
||||||
|
}
|
||||||
if (Func.isEmpty(manageDeptIds)) {
|
if (Func.isEmpty(manageDeptIds)) {
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
@@ -495,6 +516,37 @@ public final class TransportBusinessSupport {
|
|||||||
return trimValue.isEmpty() ? null : trimValue;
|
return trimValue.isEmpty() ? null : trimValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 归一化结算单用印类型:仅允许「公章」「业务章」,多选用顿号拼接,并按固定顺序去重。
|
||||||
|
*
|
||||||
|
* @param value 原始用印类型(支持顿号、逗号、空白分隔)
|
||||||
|
* @return 归一化后的用印类型,未选择时返回 null
|
||||||
|
*/
|
||||||
|
public static String normalizeSettlementSealTypes(String value) {
|
||||||
|
String source = trimToNull(value);
|
||||||
|
if (Func.isEmpty(source)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String[] parts = source.split("[、,,\\s]+");
|
||||||
|
LinkedHashSet<String> selected = new LinkedHashSet<>();
|
||||||
|
for (String part : parts) {
|
||||||
|
String item = trimToNull(part);
|
||||||
|
if (Func.isEmpty(item)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!SETTLEMENT_SEAL_TYPE_OPTIONS.contains(item)) {
|
||||||
|
throw new ServiceException("用印类型仅支持:公章、业务章");
|
||||||
|
}
|
||||||
|
selected.add(item);
|
||||||
|
}
|
||||||
|
if (selected.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return SETTLEMENT_SEAL_TYPE_OPTIONS.stream()
|
||||||
|
.filter(selected::contains)
|
||||||
|
.collect(Collectors.joining("、"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 归一化运输计划数据来源,保证列表只出现约定的三种来源。
|
* 归一化运输计划数据来源,保证列表只出现约定的三种来源。
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- 项目变更:调整材料(记录原附件,审批通过后替换并同步到原项目档案项目材料)
|
||||||
|
ALTER TABLE `blade_project_change`
|
||||||
|
ADD COLUMN `adjust_attachments_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '调整材料JSON(含原附件快照与调整原因)' AFTER `attachments_json`;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- 预付结算单、正式结算单(付款/收款):用印类型(多选,顿号拼接存储:公章、业务章)
|
||||||
|
ALTER TABLE `blade_pre_settlement`
|
||||||
|
ADD COLUMN `seal_types` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用印类型(多选,顿号拼接:公章、业务章)' AFTER `transport_type`;
|
||||||
|
|
||||||
|
ALTER TABLE `blade_formal_settlement`
|
||||||
|
ADD COLUMN `seal_types` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用印类型(多选,顿号拼接:公章、业务章)' AFTER `transport_type`;
|
||||||
Reference in New Issue
Block a user