diff --git a/blade-service-api/blade-system-api/src/main/java/org/springblade/system/pojo/entity/Dept.java b/blade-service-api/blade-system-api/src/main/java/org/springblade/system/pojo/entity/Dept.java
index 15a3e94a..e5958c76 100644
--- a/blade-service-api/blade-system-api/src/main/java/org/springblade/system/pojo/entity/Dept.java
+++ b/blade-service-api/blade-system-api/src/main/java/org/springblade/system/pojo/entity/Dept.java
@@ -150,6 +150,13 @@ public class Dept extends TenantEntity {
@Schema(description = "合同编码前缀")
private String contractCodePrefix;
+ /**
+ * 合同初始流水号(该部门当年首个合同时从此号起编,范围1-999)
+ */
+ @Schema(description = "合同初始流水号")
+ @TableField(updateStrategy = FieldStrategy.ALWAYS)
+ private Integer contractInitialSerial;
+
/**
* 组织简称
*/
diff --git a/blade-service/blade-system/src/main/java/org/springblade/system/mapper/DeptMapper.xml b/blade-service/blade-system/src/main/java/org/springblade/system/mapper/DeptMapper.xml
index f45626dd..bfbaf61f 100644
--- a/blade-service/blade-system/src/main/java/org/springblade/system/mapper/DeptMapper.xml
+++ b/blade-service/blade-system/src/main/java/org/springblade/system/mapper/DeptMapper.xml
@@ -14,6 +14,7 @@
+
@@ -36,6 +37,7 @@
+
diff --git a/blade-service/blade-system/src/main/java/org/springblade/system/service/impl/DeptServiceImpl.java b/blade-service/blade-system/src/main/java/org/springblade/system/service/impl/DeptServiceImpl.java
index 3dda7348..dd24564f 100644
--- a/blade-service/blade-system/src/main/java/org/springblade/system/service/impl/DeptServiceImpl.java
+++ b/blade-service/blade-system/src/main/java/org/springblade/system/service/impl/DeptServiceImpl.java
@@ -687,6 +687,7 @@ public class DeptServiceImpl extends ServiceImpl implements ID
}
validateDeptCategory(dept);
validateDeptCode(dept, parent);
+ validateContractInitialSerial(dept);
return saveOrUpdate(dept);
}
@@ -874,6 +875,16 @@ public class DeptServiceImpl extends ServiceImpl implements ID
}
}
+ private void validateContractInitialSerial(Dept dept) {
+ Integer serial = dept.getContractInitialSerial();
+ if (serial == null) {
+ return;
+ }
+ if (serial < 1 || serial > 999) {
+ throw new ServiceException("合同初始流水号范围为1到999");
+ }
+ }
+
private void validateDeptCode(Dept dept, Dept parent) {
String deptCode = dept.getDeptCode();
// 组织编码非必填,为空时存 null,避免唯一索引冲突
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ContractManageServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ContractManageServiceImpl.java
index 1ec56fd9..9d36d811 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ContractManageServiceImpl.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ContractManageServiceImpl.java
@@ -298,6 +298,7 @@ public class ContractManageServiceImpl extends BaseServiceImpl beforeData = buildContractChangeSnapshot(source);
+ applyContractNo(source, request.getContractNo(), false);
source.setContractName(request.getContractName()); source.setPartyB(request.getPartyB());
source.setStartDate(request.getStartDate()); source.setEndDate(request.getEndDate()); source.setContractFormat(request.getContractFormat());
source.setSettlementMode(request.getSettlementMode()); source.setLegalSealFlag(request.getLegalSealFlag()); source.setCopyCount(request.getCopyCount());
@@ -507,8 +508,7 @@ public class ContractManageServiceImpl extends BaseServiceImpllambdaQuery()
+ .eq(ContractManage::getIsDeleted, 0)
+ .eq(ContractManage::getContractNo, normalizedContractNo)
+ .ne(Func.isNotEmpty(contractManage.getId()), ContractManage::getId, contractManage.getId()));
+ if (duplicatedCount != null && duplicatedCount > 0) {
+ throw new ServiceException("合同编号已存在");
+ }
+ contractManage.setContractNo(normalizedContractNo);
+ }
+
@Override
public synchronized String nextContractNo(Long organizationId) {
if (Func.isEmpty(organizationId)) {
@@ -558,7 +580,8 @@ public class ContractManageServiceImpl extends BaseServiceImpl 999) {
+ throw new ServiceException("组织机构中配置的合同初始流水号不能超过999");
+ }
+ return serial;
+ }
+
private void refreshArchiveStatusOnApprove(ContractManage contractManage) {
if (hasSealArchiveFile(contractManage.getContractFileJson())) {
contractManage.setArchiveStatus(ARCHIVE_STATUS_ARCHIVED);
@@ -1015,6 +1049,7 @@ public class ContractManageServiceImpl extends BaseServiceImpl buildContractChangeSnapshot(ContractManage contractManage) {
Map data = new LinkedHashMap<>();
+ data.put("contractNo", contractManage.getContractNo());
data.put("contractName", contractManage.getContractName());
data.put("partyB", contractManage.getPartyB());
data.put("startDate", contractManage.getStartDate());
diff --git a/doc/sql/bladex/bladex.mysql.all.create.sql b/doc/sql/bladex/bladex.mysql.all.create.sql
index 7a6e69cc..fed3b1b5 100644
--- a/doc/sql/bladex/bladex.mysql.all.create.sql
+++ b/doc/sql/bladex/bladex.mysql.all.create.sql
@@ -305,6 +305,7 @@ CREATE TABLE `blade_dept` (
`dept_code` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组织编码',
`kingdee_dept_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '金蝶部门代码',
`contract_code_prefix` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '合同编码前缀',
+ `contract_initial_serial` int NULL DEFAULT NULL COMMENT '合同初始流水号',
`short_name` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组织简称',
`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 '助记码',
diff --git a/doc/sql/transport/blade_dept_contract_initial_serial_20261020.sql b/doc/sql/transport/blade_dept_contract_initial_serial_20261020.sql
new file mode 100644
index 00000000..7b4ac000
--- /dev/null
+++ b/doc/sql/transport/blade_dept_contract_initial_serial_20261020.sql
@@ -0,0 +1,3 @@
+-- 组织机构新增合同初始流水号:该部门当年首个合同从此流水号起编,后续递增
+ALTER TABLE `blade_dept`
+ ADD COLUMN `contract_initial_serial` int(11) DEFAULT NULL COMMENT '合同初始流水号' AFTER `contract_code_prefix`;