diff --git a/common/common-association/src/main/java/apelet/association/plugin/UnitNameChangeFormPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/UnitNameChangeFormPlugin.java index 64d166c..51e4dac 100644 --- a/common/common-association/src/main/java/apelet/association/plugin/UnitNameChangeFormPlugin.java +++ b/common/common-association/src/main/java/apelet/association/plugin/UnitNameChangeFormPlugin.java @@ -20,6 +20,6 @@ public class UnitNameChangeFormPlugin extends ExecutePluginParent { public void formCreated(String str, ObjectValue objectValue) { super.formCreated(str, objectValue); //objectValue.setString("billStatus", "A"); - this.setWidgetAttribute("billStatus", AttributeEnum.VALUE_CHANGE, "A"); + //this.setWidgetAttribute("billstatus", AttributeEnum.VALUE_CHANGE, "A"); } } \ No newline at end of file diff --git a/common/common-association/src/main/java/apelet/association/plugin/UnitNameChangeOperationPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/UnitNameChangeOperationPlugin.java new file mode 100644 index 0000000..a3566cc --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/plugin/UnitNameChangeOperationPlugin.java @@ -0,0 +1,295 @@ +package apelet.association.plugin; + +import apelet.common.core.object.ObjectCollection; +import apelet.common.core.object.ObjectValue; +import apelet.common.generator.utils.OrmGenDataSourceUtil; +import apelet.common.online.plugin.BeginOperationTransactionArgs; +import apelet.common.online.plugin.OperationResult; +import apelet.common.online.plugin.OperationServicePlugIn; +import apelet.common.orm.impl.Filter; +import apelet.common.orm.impl.FilterItem; + +import java.util.Iterator; +import java.util.Map; + +/** + * @ClassName: UnitNameChangeOperationPlugin + * @Author: huangdehua + * @Date: 2026/4/30 11:02 + * @Description: 入会申请与审核 变更单位名称 + */ +public class UnitNameChangeOperationPlugin extends OperationServicePlugIn { + + // 主表与子表数据源变量名,需与在线表单配置保持一致。 + private static final String TABLE_NAME = "membership_apply"; + private static final String CHILD_TABLE_NAME = "membership_apply_entry"; + private static final String FIELD_ID = "id"; + private static final String FIELD_NUMBER = "number"; + private static final String FIELD_UNIT_NAME = "unit_name"; + private static final String FIELD_BILL_STATUS = "billstatus"; + private static final String FIELD_IS_HISTORY = "is_history"; + private static final String FIELD_VERSION_NUMBER = "version_number"; + private static final String STATUS_ACTIVE = "A"; + private static final String STATUS_CHANGED = "C"; + private static final Integer IS_HISTORY_YES = 1; + private static final Integer IS_HISTORY_NO = 0; + + @Override + public void beginOperationTransaction(BeginOperationTransactionArgs args) { + try { + ObjectValue model = args.getModel(); + if (model == null) { + setFailResult("获取表单数据失败"); + return; + } + + String pkId = model.getString(FIELD_ID); + if (pkId == null || pkId.isEmpty()) { + setFailResult("新增单据不允许执行变更操作"); + return; + } + + String newUnitName = model.getString(FIELD_UNIT_NAME); + if (newUnitName == null || newUnitName.isEmpty()) { + setFailResult("单位名称不能为空"); + return; + } + + OrmGenDataSourceUtil ormUtil = ormGenDataSourceUtil(); + if (ormUtil == null) { + setFailResult("获取数据库连接失败"); + return; + } + + Filter pkFilter = new Filter(); + pkFilter.add(new FilterItem(FIELD_ID, "=", pkId)); + ObjectCollection oldCollection = ormUtil.query(TABLE_NAME, pkFilter, null); + if (oldCollection == null || oldCollection.isEmpty()) { + setFailResult("未找到当前单据数据"); + return; + } + + ObjectValue oldBill = oldCollection.getObject(0); + String oldUnitName = oldBill.getString(FIELD_UNIT_NAME); + if (oldUnitName == null || oldUnitName.equals(newUnitName)) { + setFailResult("单位名称未发生变化,无需变更"); + return; + } + + String billNumber = oldBill.getString(FIELD_NUMBER); + if (billNumber == null || billNumber.isEmpty()) { + setFailResult("单据编号不能为空"); + return; + } + + // 通过单据编号 + 排除当前ID,查找同一业务单据之前变更产生的记录 + ObjectValue previousChangedBill = findBillByNumberAndStatus(ormUtil, billNumber, pkId, STATUS_CHANGED); + ObjectValue previousActiveBill = findBillByNumberAndStatus(ormUtil, billNumber, pkId, STATUS_ACTIVE); + + if (previousActiveBill != null) { + // 二次变更:同一单据编号下已存在 A 记录(上次变更产生的),直接更新其 unit_name,无需新增 + // 获取当前历史单据的最大版本号 + int currentMaxVersion = getMaxVersionNumber(ormUtil, billNumber, pkId); + if (previousChangedBill != null) { + // 已有历史 C 记录,用当前旧单据数据覆盖它,并更新版本号 + overwriteBill(ormUtil, previousChangedBill, oldBill, currentMaxVersion + 1); + } else { + // 无历史 C 记录,将当前旧单据标记为 C,并设置版本号 + oldBill.put(FIELD_BILL_STATUS, STATUS_CHANGED); + oldBill.put(FIELD_IS_HISTORY, IS_HISTORY_YES); + oldBill.put(FIELD_VERSION_NUMBER, currentMaxVersion + 1); + ormUtil.update(TABLE_NAME, oldBill, null); + } + // 直接更新 A 记录的 unit_name + previousActiveBill.put(FIELD_UNIT_NAME, newUnitName); + ormUtil.update(TABLE_NAME, previousActiveBill, null); + } else { + // 首次变更:同一单据编号下没有 A 记录,走新增逻辑 + oldBill.put(FIELD_BILL_STATUS, STATUS_CHANGED); + oldBill.put(FIELD_IS_HISTORY, IS_HISTORY_YES); + oldBill.put(FIELD_VERSION_NUMBER, 1); + ormUtil.update(TABLE_NAME, oldBill, null); + + ObjectValue newBill = new ObjectValue(TABLE_NAME); + copyValuesWithoutId(oldBill, newBill, FIELD_BILL_STATUS, FIELD_IS_HISTORY, FIELD_VERSION_NUMBER); + newBill.put(FIELD_UNIT_NAME, newUnitName); + newBill.put(FIELD_IS_HISTORY, IS_HISTORY_NO); + newBill.put(FIELD_VERSION_NUMBER, 1); + + ObjectCollection copiedChildren = copyChildCollection(model.getValues().get(CHILD_TABLE_NAME)); + if (copiedChildren != null && !copiedChildren.isEmpty()) { + newBill.put(CHILD_TABLE_NAME, copiedChildren); + } + + ormUtil.addNew(TABLE_NAME, newBill); + updateNewBillStatus(ormUtil, pkId, newUnitName); + } + setSuccessResult(); + } catch (Exception e) { + e.printStackTrace(); + setFailResult("单位名称变更处理失败:" + e.getMessage()); + } + } + + private void copyValuesWithoutId(ObjectValue source, ObjectValue target, String... excludedFields) { + Map values = source.getValues(); + Iterator it = values.keySet().iterator(); + while (it.hasNext()) { + String key = it.next(); + if (FIELD_ID.equals(key) || isExcludedField(key, excludedFields)) { + continue; + } + // 排除 history 和 versionNumber 字段,由业务逻辑单独设置 + if (FIELD_IS_HISTORY.equals(key) || FIELD_VERSION_NUMBER.equals(key)) { + continue; + } + target.put(key, values.get(key)); + } + } + + private boolean isExcludedField(String fieldName, String... excludedFields) { + if (excludedFields == null) { + return false; + } + for (String excludedField : excludedFields) { + if (fieldName.equals(excludedField)) { + return true; + } + } + return false; + } + + private ObjectCollection copyChildCollection(Object childValue) { + if (!(childValue instanceof ObjectCollection)) { + return null; + } + + // 子表行只去掉主键,其他字段原样复制,避免丢失联系人等历史明细。 + ObjectCollection oldChildren = (ObjectCollection) childValue; + if (oldChildren.isEmpty()) { + return null; + } + + ObjectCollection newChildren = new ObjectCollection(); + for (int i = 0; i < oldChildren.size(); i++) { + ObjectValue oldChild = oldChildren.getObject(i); + if (oldChild == null) { + continue; + } + + ObjectValue newChild = new ObjectValue(null); + copyValuesWithoutId(oldChild, newChild); + newChildren.addObject(newChild); + } + return newChildren; + } + + /** + * 通过单据编号查找同一业务单据的变更记录。 + * 查询条件:number = billNumber AND id != excludePkId AND billstatus = status + * + * @param ormUtil ORM 工具 + * @param billNumber 单据编号(关联同一业务单据) + * @param excludePkId 排除的单据主键(当前操作的记录) + * @param status 单据状态 + * @return 匹配的单据,无则返回 null + */ + private ObjectValue findBillByNumberAndStatus(OrmGenDataSourceUtil ormUtil, String billNumber, String excludePkId, String status) throws Exception { + Filter filter = new Filter(); + filter.add(new FilterItem(FIELD_NUMBER, "=", billNumber)); + filter.add(new FilterItem(FIELD_ID, "<>", excludePkId)); + //filter.add(new FilterItem(FIELD_BILL_STATUS, "=", status)); + ObjectCollection collection = ormUtil.query(TABLE_NAME, filter, null); + if (collection == null || collection.isEmpty()) { + return null; + } + return collection.getObject(0); + } + + /** + * 用源单据数据覆盖目标单据(保留目标单据的 ID,其他字段用源数据替换)。 + * + * @param ormUtil ORM 工具 + * @param targetBill 被覆盖的历史单据(保留其 ID) + * @param sourceBill 用于覆盖的数据源 + * @param versionNumber 版本号 + */ + private void overwriteBill(OrmGenDataSourceUtil ormUtil, ObjectValue targetBill, ObjectValue sourceBill, int versionNumber) throws Exception { + ObjectValue overwrittenBill = new ObjectValue(TABLE_NAME); + overwrittenBill.put(FIELD_ID, targetBill.getString(FIELD_ID)); + copyValuesWithoutId(sourceBill, overwrittenBill, FIELD_BILL_STATUS, FIELD_IS_HISTORY, FIELD_VERSION_NUMBER); + overwrittenBill.put(FIELD_BILL_STATUS, STATUS_CHANGED); + overwrittenBill.put(FIELD_IS_HISTORY, IS_HISTORY_YES); + overwrittenBill.put(FIELD_VERSION_NUMBER, versionNumber); + ormUtil.update(TABLE_NAME, overwrittenBill, null); + } + + private void updateNewBillStatus(OrmGenDataSourceUtil ormUtil, String oldPkId, String newUnitName) throws Exception { + Filter filter = new Filter(); + filter.add(new FilterItem(FIELD_ID, "<>", oldPkId)); + filter.add(new FilterItem(FIELD_UNIT_NAME, "=", newUnitName)); + ObjectCollection collection = ormUtil.query(TABLE_NAME, filter, null); + if (collection == null || collection.isEmpty()) { + return; + } + + ObjectValue newBill = collection.getObject(0); + if (newBill == null) { + return; + } + + newBill.put(FIELD_BILL_STATUS, STATUS_ACTIVE); + newBill.put(FIELD_IS_HISTORY, IS_HISTORY_NO); + newBill.put(FIELD_VERSION_NUMBER, 1); + ormUtil.update(TABLE_NAME, newBill, null); + } + + private void setSuccessResult() { + OperationResult result = new OperationResult(); + result.setSuccess(true); + setOperationResult(result); + } + + private void setFailResult(String message) { + OperationResult result = new OperationResult(); + result.setSuccess(false); + result.setMessage(message); + result.setShowMessage(true); + setOperationResult(result); + } + + /** + * 获取同一单据编号下的最大版本号(排除当前操作的记录)。 + * + * @param ormUtil ORM 工具 + * @param billNumber 单据编号 + * @param excludePkId 排除的单据主键 + * @return 最大版本号,未找到则返回 0 + */ + private int getMaxVersionNumber(OrmGenDataSourceUtil ormUtil, String billNumber, String excludePkId) throws Exception { + Filter filter = new Filter(); + filter.add(new FilterItem(FIELD_NUMBER, "=", billNumber)); + filter.add(new FilterItem(FIELD_ID, "<>", excludePkId)); + ObjectCollection collection = ormUtil.query(TABLE_NAME, filter, null); + if (collection == null || collection.isEmpty()) { + return 0; + } + int maxVersion = 0; + for (int i = 0; i < collection.size(); i++) { + ObjectValue bill = collection.getObject(i); + Object versionObj = bill.getValues().get(FIELD_VERSION_NUMBER); + if (versionObj != null) { + int version; + if (versionObj instanceof Integer) { + version = (Integer) versionObj; + } else { + version = Integer.parseInt(versionObj.toString()); + } + if (version > maxVersion) { + maxVersion = version; + } + } + } + return maxVersion; + } +}