Jelajahi Sumber

Merge remote-tracking branch 'origin/master'

sbtjtserver/zhaoxh 7 bulan lalu
induk
melakukan
54a4fb8333
35 mengubah file dengan 6277 tambahan dan 365 penghapusan
  1. 86 0
      src/main/java/fi/ar/opplugin/FinarbillPushOpPlugin.java
  2. 95 0
      src/main/java/fi/ar/task/FinarbillPushTask.java
  3. 79 0
      src/main/java/fi/cas/formplugin/ArBadDebtLossListPlugin.java
  4. 157 29
      src/main/java/fi/cas/opplugin/PayBillToolUtil.java
  5. 17 2
      src/main/java/fi/cas/opplugin/PayToZFQZOP.java
  6. 140 0
      src/main/java/fi/cas/task/MatchBadDebtsTask.java
  7. 73 0
      src/main/java/fi/cas/task/PayQueryStatusTast.java
  8. 28 0
      src/main/java/fi/cas/task/PayUpadteStatusTask.java
  9. 3 0
      src/main/java/fi/em/formPlugin/AgentpaybillFormPlugin.java
  10. 2 0
      src/main/java/fi/em/formPlugin/BusinessProcessingEditPlugin.java
  11. 57 0
      src/main/java/fi/em/formPlugin/BusinessProcessingListPlugin.java
  12. 3 0
      src/main/java/fi/em/formPlugin/BusinessProcessingPlugin.java
  13. 3 4
      src/main/java/fi/em/formPlugin/SalaryFileUploadEditPlugin.java
  14. 297 0
      src/main/java/fi/em/formPlugin/SubAndAudFormPlugin.java
  15. 3 0
      src/main/java/fi/em/opplugin/AgentpayPushOpPlugin.java
  16. 98 40
      src/main/java/fi/er/opplugin/FinapbillBeforeF7SelectSample.java
  17. 1012 0
      src/main/java/fi/fa/formPlugin/FaInventoryTaskListNew.java
  18. 140 80
      src/main/java/fi/fa/opplugin/AssetMidBillOpPlugin.java
  19. 43 0
      src/main/java/fi/fa/opplugin/BusProcessBillOpPlugin.java
  20. 132 114
      src/main/java/fi/fa/opplugin/FaChangeMidOpPlugin.java
  21. 106 60
      src/main/java/fi/fa/opplugin/FaDisCardMidOpPlugin.java
  22. 47 1
      src/main/java/fi/fa/opplugin/RealCardBillOpPlugin.java
  23. 29 1
      src/main/java/fi/fa/opplugin/RealCardF7OpPlugin.java
  24. 0 1
      src/main/java/kd/bos/login/utils/DemoSMSSender.java
  25. 1135 0
      src/main/java/kd/bos/newdevportal/table/DBTableProviderNew.java
  26. 58 33
      src/main/java/kd/bos/newdevportal/table/TableListPlugin.java
  27. 314 0
      src/main/java/sys/sc/formplugin/ABillServiceHelper.java
  28. 146 0
      src/main/java/sys/sc/formplugin/ApiHttpUtils.java
  29. 37 0
      src/main/java/sys/sc/formplugin/Filetest.java
  30. 886 0
      src/main/java/sys/sc/formplugin/TestPlugin.java
  31. 77 0
      src/main/java/sys/sc/opplugin/utils/ReflectUtils.java
  32. 74 0
      src/main/java/sys/sc/opplugin/utils/SftpClient.java
  33. 210 0
      src/main/java/sys/sc/task/UpdateBankDailyTask.java
  34. 490 0
      src/main/java/sys/sc/task/UpdateDataDailyTask.java
  35. 200 0
      src/main/java/sys/sc/task/UpdateImpairmentDailyTask.java

+ 86 - 0
src/main/java/fi/ar/opplugin/FinarbillPushOpPlugin.java

@@ -0,0 +1,86 @@
+package fi.ar.opplugin;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.botp.runtime.ConvertOperationResult;
+import kd.bos.entity.botp.runtime.PushArgs;
+import kd.bos.entity.datamodel.ListSelectedRow;
+import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
+import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.botp.ConvertServiceHelper;
+import kd.bos.metadata.botp.ConvertRuleReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author cjz
+ * @date 2024/9/10 15:21
+ * @description:应收挂账当下推坏账计提
+ */
+public class FinarbillPushOpPlugin extends AbstractOperationServicePlugIn {
+
+    private static String ar_finarbill="ar_finarbill";//应收挂账单标识源单
+    private static String ar_baddebtlossbill="ar_baddebtlossbill";//坏账损失单标识目标单
+
+    @Override
+    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
+        super.beginOperationTransaction(e);
+        if ("sdpush".equals(e.getOperationKey())){
+            //是否诉讼类费用为是
+            QFilter filter=new QFilter("nckd_checkboxfield1", QCP.equals,true);
+            //未结算金额不为0
+            filter.and("unsettleamount", QCP.not_equals,0);
+            DynamicObject[] dynamicObjects=BusinessDataServiceHelper.load(ar_finarbill,"id",new QFilter[]{filter});
+            //获取转换规则id
+            ConvertRuleReader read=new ConvertRuleReader();
+            List<String> loadRuleIds = read.loadRuleIds(ar_finarbill, ar_baddebtlossbill, false);
+            for (int i=0;i< dynamicObjects.length;i++)
+            {
+                //获取应收挂帐单
+                DynamicObject info= BusinessDataServiceHelper
+                        .loadSingle(dynamicObjects[i].getPkValue(),dynamicObjects[i].getDynamicObjectType().getName());
+                //源单id
+                Long pkid=info.getLong("id");
+                // 下推参数,设置所选数据项
+                List<ListSelectedRow> selectedRows=new ArrayList<>();
+                ListSelectedRow selectedRow=new ListSelectedRow(pkid);
+                //设置需要下推的单据名
+//                selectedRow.setEntryEntityKey("nckd_salarydistribute");
+                // 设置需要下推的单据体行内码:按分录下推时必须设置
+                selectedRow.setEntryPrimaryKeyValue(pkid);
+                selectedRows.add(selectedRow);
+                // 创建下推参数
+                PushArgs pushArgs = new PushArgs();
+                // 源单标识
+                pushArgs.setSourceEntityNumber(ar_finarbill);
+                // 目标单据标识
+                pushArgs.setTargetEntityNumber(ar_baddebtlossbill);
+                // 生成转换结果报告
+                pushArgs.setBuildConvReport(true);
+                //传入下推使用的转换规则id,不填则使用默认规则
+                pushArgs.setRuleId(loadRuleIds.get(0));
+                //下推默认保存
+                pushArgs.setAutoSave(true);
+                // 设置源单选中的数据包
+                pushArgs.setSelectedRows(selectedRows);
+                // 执行下推操作
+                ConvertOperationResult result = ConvertServiceHelper.push(pushArgs);
+                //获取下推目标单id
+                Set<Object> targetBillIds = result.getTargetBillIds();
+                if(!targetBillIds.isEmpty()) {
+                    this.operationResult.setShowMessage(true);
+                    this.operationResult.setSuccess(true);
+                    this.operationResult.setMessage("下推坏账处理单成功");
+                }else {
+                    this.operationResult.setShowMessage(true);
+                    this.operationResult.setSuccess(false);
+                    this.operationResult.setMessage("下推坏账处理单失败");
+                }
+            }
+        }
+    }
+
+}

+ 95 - 0
src/main/java/fi/ar/task/FinarbillPushTask.java

@@ -0,0 +1,95 @@
+package fi.ar.task;
+
+import com.alibaba.druid.support.logging.Log;
+import com.alibaba.druid.support.logging.LogFactory;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.botp.runtime.ConvertOperationResult;
+import kd.bos.entity.botp.runtime.PushArgs;
+import kd.bos.entity.datamodel.ListSelectedRow;
+import kd.bos.exception.KDException;
+import kd.bos.metadata.botp.ConvertRuleReader;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.schedule.api.MessageHandler;
+import kd.bos.schedule.executor.AbstractTask;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.botp.ConvertServiceHelper;
+import sys.sc.task.UpdateImpairmentDailyTask;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author cjz
+ * @date 2024/9/10 16:42
+ * @description:应收单下推坏账处理单调度计划,每月
+ */
+public class FinarbillPushTask extends AbstractTask {
+    private static final Log log = LogFactory.getLog(FinarbillPushTask.class);
+    private static String ar_finarbill="ar_finarbill";//应收挂账单标识源单
+    private static String ar_baddebtlossbill="ar_baddebtlossbill";//坏账损失单标识目标单
+
+    @Override
+    public MessageHandler getMessageHandle() {
+        return super.getMessageHandle();
+    }
+
+    @Override
+    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
+        //是否诉讼类费用为是
+        QFilter filter=new QFilter("nckd_checkboxfield1", QCP.equals,true);
+        //未结算金额不为0
+        filter.and("unsettleamount", QCP.not_equals,0);
+        DynamicObject[] dynamicObjects= BusinessDataServiceHelper.load(ar_finarbill,"id",new QFilter[]{filter});
+        //获取转换规则id
+        ConvertRuleReader read=new ConvertRuleReader();
+        List<String> loadRuleIds = read.loadRuleIds(ar_finarbill, ar_baddebtlossbill, false);
+        for (DynamicObject dynamicObject : dynamicObjects) {
+            //获取应收挂帐单
+            DynamicObject info = BusinessDataServiceHelper
+                    .loadSingle(dynamicObject.getPkValue(), dynamicObject.getDynamicObjectType().getName());
+            //源单id
+            Long pkid = info.getLong("id");
+            // 下推参数,设置所选数据项
+            List<ListSelectedRow> selectedRows = new ArrayList<>();
+            ListSelectedRow selectedRow = new ListSelectedRow(pkid);
+            //设置需要下推的单据名
+//                selectedRow.setEntryEntityKey("nckd_salarydistribute");
+            // 设置需要下推的单据体行内码:按分录下推时必须设置
+            selectedRow.setEntryPrimaryKeyValue(pkid);
+            selectedRows.add(selectedRow);
+            // 创建下推参数
+            PushArgs pushArgs = new PushArgs();
+            // 源单标识
+            pushArgs.setSourceEntityNumber(ar_finarbill);
+            // 目标单据标识
+            pushArgs.setTargetEntityNumber(ar_baddebtlossbill);
+            // 生成转换结果报告
+            pushArgs.setBuildConvReport(true);
+            //传入下推使用的转换规则id,不填则使用默认规则
+            pushArgs.setRuleId(loadRuleIds.get(0));
+            //下推默认保存
+            pushArgs.setAutoSave(true);
+            // 设置源单选中的数据包
+            pushArgs.setSelectedRows(selectedRows);
+            // 执行下推操作
+            ConvertOperationResult result = ConvertServiceHelper.push(pushArgs);
+            //获取下推目标单id
+            Set<Object> targetBillIds = result.getTargetBillIds();
+            if (!targetBillIds.isEmpty()) {
+                log.info("----------------------------下推坏账处理单成功----------------------");
+            } else {
+                log.info("----------------------------下推坏账处理单失败----------------------");
+            }
+        }
+
+    }
+
+    @Override
+    public boolean isSupportReSchedule() {
+        return super.isSupportReSchedule();
+    }
+}

+ 79 - 0
src/main/java/fi/cas/formplugin/ArBadDebtLossListPlugin.java

@@ -0,0 +1,79 @@
+package fi.cas.formplugin;
+
+import fi.cas.task.MatchBadDebtsTask;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.datamodel.ListSelectedRowCollection;
+import kd.bos.form.control.events.ItemClickEvent;
+import kd.bos.list.BillList;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EventObject;
+import java.util.List;
+
+//坏账单计算计提金额
+public class ArBadDebtLossListPlugin extends AbstractListPlugin {
+
+    public void registerListener(EventObject e) {
+        super.registerListener(e);
+        this.addItemClickListeners(new String[]{"toolbarap"});
+    }
+
+    @Override
+    public void itemClick(ItemClickEvent evt) {
+        String itemKey = evt.getItemKey();
+        if ("nckd_match".equals(itemKey)) {
+            List<DynamicObject> jz = new ArrayList<>();
+            List<DynamicObject> ar_baddebtlossbill = new ArrayList<>();//坏账单列表
+            List<String> dubilList = new ArrayList<>();//坏账单列表
+            List<String> custList = new ArrayList<>();//坏账单列表
+            List<DynamicObject> infoList = new ArrayList<>();//计算成功的坏帐单列表
+            List<DynamicObject> ar_baddebtlossbill_customer = new ArrayList<>();//根据客户坏账单列表
+            List<DynamicObject> ar_baddebtlossbill_five_level = new ArrayList<>();//根据五级分类坏账单列表
+
+            BillList billList = (BillList)this.getControl("billlistap");
+            ListSelectedRowCollection list =  billList.getSelectedRows();
+            Object[] primaryKeyValues = list.getPrimaryKeyValues();
+            if (primaryKeyValues.length > 0) {
+                for (Object pk : primaryKeyValues) {
+                    DynamicObject info = BusinessDataServiceHelper.loadSingle(pk, "ar_baddebtlossbill");
+                    ar_baddebtlossbill.add(info);
+                    dubilList.add(info.getString("nckd_textfield"));
+                    custList.add(info.getDynamicObject("asstact").getString("number"));
+                }
+
+                //查询减值准备数据(最新一批)
+                QFilter filter = new QFilter("nckd_dubil_id", QCP.in, dubilList);
+                filter.or("nckd_cust_id", QCP.in, custList);
+                DynamicObject[] jzdynamicObjects = BusinessDataServiceHelper.load("nckd_impairment","nckd_dubil_id,nckd_cust_id,nckd_ecl_ratio", new QFilter[]{filter});
+                jz =  new ArrayList<>(Arrays.asList(jzdynamicObjects));
+
+                MatchBadDebtsTask matchBadDebtsTask = new MatchBadDebtsTask();
+
+                //下推坏账-根据借据号匹配
+                matchBadDebtsTask.MatchByDubilId(ar_baddebtlossbill, jz, infoList, ar_baddebtlossbill_customer);
+
+                //下推坏账-根据客户匹配
+                matchBadDebtsTask.MatchByCustom(ar_baddebtlossbill_customer, jz, infoList, ar_baddebtlossbill_five_level);
+
+                //下推坏账-根据五级分类匹配
+                matchBadDebtsTask.MatchByFiveLevel(ar_baddebtlossbill_five_level, infoList);
+
+                //保存
+                DynamicObject[] array = infoList.toArray(new DynamicObject[0]);
+                SaveServiceHelper.save(array);
+
+                // 显示最终的成功和失败消息
+                String message = String.format("执行完成:成功 %d 条,失败 %d 条", array.length, list.size() - array.length);
+                this.getView().showMessage(message);
+            }else {
+                this.getView().showMessage("请至少选择一条数据");
+            }
+        }
+    }
+}

+ 157 - 29
src/main/java/fi/cas/opplugin/PayBillToolUtil.java

@@ -33,6 +33,44 @@ public class PayBillToolUtil {
     public static final String ENTITY_NAME = "cas_paybill";
     protected static final Log log = LogFactory.getLog(PayBillToolUtil.class);
 
+    public static String queryPaymentRequest(DynamicObject payBillEntity) {
+        try {
+            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+            Document doc = dBuilder.newDocument();
+
+            Element rootElement = doc.createElement("Message");
+            doc.appendChild(rootElement);
+
+            Element body = doc.createElement("Body");
+            rootElement.appendChild(body);
+
+
+            createElement(doc, body, "transcode", "BTSQO001");
+            createElement(doc, body, "ochannelcode", "JF");//发起渠道
+            createElement(doc, body, "ochanneldate", payBillEntity.getString("nckd_fqqdrq"));//发起渠道日期
+
+            String channelserno = payBillEntity.get("billno")+"-"+payBillEntity.getInt("nckd_bbh");
+            createElement(doc, body, "ochannelserno", channelserno);//发起渠道流水
+            TransformerFactory transformerFactory = TransformerFactory.newInstance();
+            Transformer transformer = transformerFactory.newTransformer();
+
+            // 指定编码格式为GBK
+            transformer.setOutputProperty(OutputKeys.ENCODING, "GBK");
+            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+
+
+            DOMSource source = new DOMSource(doc);
+            StringWriter writer = new StringWriter();
+            StreamResult result = new StreamResult(writer);
+            transformer.transform(source, result);
+
+            return writer.toString();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
     public static String createSinglePaymentRequest(DynamicObject payBillEntity) {
         try {
             DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
@@ -47,10 +85,13 @@ public class PayBillToolUtil {
 
 
             createElement(doc, body, "transcode", "BTSCO001");
-            createElement(doc, body, "trxcode", "jfgx");//渠道交易代码
-            createElement(doc, body, "channelcode", "经费共享");//发起渠道
+            createElement(doc, body, "trxcode", "JF01");//渠道交易代码
+            createElement(doc, body, "channelcode", "JF");//发起渠道
             Calendar currentdate = Calendar.getInstance();
             createElement(doc, body, "channeldate", TypeUtils.date2String(currentdate.getTime(),"yyyyMMdd"));//发起渠道日期
+
+            payBillEntity.set("nckd_fqqdrq",TypeUtils.date2String(currentdate.getTime(),"yyyyMMdd"));
+
             String channelserno = payBillEntity.get("billno")+"-"+payBillEntity.getInt("nckd_bbh");
             createElement(doc, body, "channelserno", channelserno);//发起渠道流水
             createElement(doc, body, "channeltime", currentdate.get(Calendar.HOUR)+""+currentdate.get(Calendar.MINUTE)+""+currentdate.get(Calendar.SECOND));
@@ -63,7 +104,7 @@ public class PayBillToolUtil {
             //付款账号
             DynamicObject payeracctbankEntity = BusinessDataServiceHelper.loadSingle(payBillEntity.getDynamicObject("payeracctbank").getPkValue(), "am_accountbank");
             String payeracc = payeracctbankEntity.getString("bankaccountnumber");
-            String payername = payeracctbankEntity.getString("name");
+            String payername = payeracctbankEntity.getString("acctname");
             createElement(doc, body, "payeracc", payeracc);//付款账户
             createElement(doc, body, "payername", payername);//付款人名称
             createElement(doc, body, "realpayeracc", payeracc);//实际付款人账户
@@ -149,7 +190,7 @@ public class PayBillToolUtil {
                 isZFQZ = false;
             }
             if(bbh>=1 && bbh!=fkcs){
-                errMsg.append("单据号:").append(billNum).append(",付款单版本号有误,请检查数据,或联系管理员~\r\n");
+                errMsg.append("单据号:").append(billNum).append(",付款单未调整,请调整数据,或点击重付~\r\n");
                 isZFQZ = false;
             }
             if(payBillEntity.getDynamicObject("payeracctbank")==null) {
@@ -182,36 +223,54 @@ public class PayBillToolUtil {
             if(cbsReturnJson==null){
                 isSuccess = false;
                 errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,");
-                errMsg.append("错误号:").append("XXXXXX");
+                errMsg.append("错误号:").append("XXXXXXX");
                 errMsg.append(",错误原因:").append("接口无法连通,未获取到返回结果");
                 errMsg.append("\r\n");
+            }else if(cbsReturnJson.get("Message")==null){
+                isSuccess = false;
+                errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,");
+                errMsg.append("错误号:").append("DDDDDD1");
+                errMsg.append(",错误原因:").append("接口已连通,但未获取到返回结果");
+                errMsg.append("\r\n");
             }else{
-                String errcode =cbsReturnJson.getString("errorcode");
-
-                if ("FIN0000".equals(errcode)) {//已受理,不代表支付成功
-                    isSuccess = true;
-                    errMsg.append("单据号:").append(billNum).append(",推送支付前置成功!");
-                    payBillEntity.set("nckd_fkcs", fkcs+1);//付款次数+1
-                    payBillEntity.set("nckd_sbyy",cbsReturnJson.getString("errormsg"));//错误信息
-                    String zfstatus = cbsReturnJson.getString("status");
-                    if("S".equals(zfstatus)){//成功
-                        payBillEntity.set("nckd_paystatus",3);
-                    }else if("U".equals(zfstatus)){//在途
-                        payBillEntity.set("nckd_paystatus",2);//支付中
-                    }else if("F".equals(zfstatus)){//失败
-                        payBillEntity.set("nckd_paystatus",4);//支付失败
-                    }
-
-                } else {
+                JSONObject bodyinfo = cbsReturnJson.getJSONObject("Message").getJSONObject("Body");
+                if(bodyinfo==null){
                     isSuccess = false;
                     errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,");
-                    errMsg.append("错误号:").append(errcode);
-                    errMsg.append(",错误原因:").append(cbsReturnJson.getString("errormsg"));
+                    errMsg.append("错误号:").append("DDDDDDD2");
+                    errMsg.append(",错误原因:").append("接口已连通,但无法解析返回结果"+cbsReturnJson.toString());
                     errMsg.append("\r\n");
+                }else{
+                    String errcode =bodyinfo.getString("errorcode");
+
+                    if ("FIN0000".equals(errcode)) {//已受理,不代表支付成功
+                        isSuccess = true;
+                        errMsg.append("单据号:").append(billNum).append(",推送支付前置成功!");
+                        payBillEntity.set("nckd_fkcs", fkcs+1);//付款次数+1
+                        payBillEntity.set("nckd_sbyy",bodyinfo.getString("errormsg"));//错误信息
+                        String zfstatus = bodyinfo.getString("status");
+                        if("S".equals(zfstatus)){//成功
+                            payBillEntity.set("nckd_paystatus",3);
+                        }else if("U".equals(zfstatus)){//在途
+                            payBillEntity.set("nckd_paystatus",2);//支付中
+                        }else if("F".equals(zfstatus)){//失败
+                            payBillEntity.set("nckd_paystatus",4);//支付失败
+                        }
+
+                    } else {//拿到返回结果支付次数就必须加一
+                        isSuccess = false;
+                        errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,");
+                        errMsg.append("错误号:").append(errcode);
+                        errMsg.append(",错误原因:").append(bodyinfo.getString("errormsg"));
+                        errMsg.append("\r\n");
+                        payBillEntity.set("nckd_fkcs", fkcs+1);//付款次数+1
+                        payBillEntity.set("nckd_paystatus",4);//支付失败
+                        payBillEntity.set("nckd_sbyy",bodyinfo.getString("errormsg"));//错误信息
+                        SaveServiceHelper.update(new DynamicObject[]{payBillEntity});
+                    }
+
                 }
             }
-            ////返回日志处理
-            System.out.println("调用支付前置接口返回值:" + cbsReturnJson.toString());
 
             if (isSuccess) {
                 SaveServiceHelper.update(new DynamicObject[]{payBillEntity});
@@ -227,10 +286,15 @@ public class PayBillToolUtil {
             logInfo.set("number",channelserno);
             logInfo.set("name",payBillEntity.get("billno")+"付款日志");
             logInfo.set("status","A");
+            logInfo.set("enable","1");
+            Calendar currentdate = Calendar.getInstance();
+            logInfo.set("nckd_redate",currentdate.getTime());
             logInfo.set("nckd_billno",payBillEntity.get("billno"));
             logInfo.set("nckd_payid",payBillEntity.getPkValue()+"");
-            logInfo.set("nckd_qqbw",qqbw);
-            logInfo.set("nckd_fhbw",fhbw);
+            logInfo.set("nckd_qqbw_tag",qqbw);
+            logInfo.set("nckd_fhbw_tag",fhbw);
+            logInfo.set("nckd_redate",new Date());
+
             logInfo.set("nckd_djlx","1");
             OperationServiceHelper.executeOperate("save","nckd_zfjkdyrz",new DynamicObject[]{logInfo});
 
@@ -240,13 +304,77 @@ public class PayBillToolUtil {
         }
 
 
+    }
+
+
+    public static void saveupdatelog(DynamicObject payBillEntity,String qqbw,String fhbw){
+        try {
+            DynamicObject logInfo = new DynamicObject( EntityMetadataCache.getDataEntityType("nckd_zfcxjkrz"));
+            String channelserno = payBillEntity.get("billno")+"-"+payBillEntity.getInt("nckd_bbh");
+            logInfo.set("number",channelserno);
+            logInfo.set("name",payBillEntity.get("billno")+"查询状态日志");
+            logInfo.set("status","A");
+            logInfo.set("enable","1");
+            Calendar currentdate = Calendar.getInstance();
+            logInfo.set("nckd_redate",currentdate.getTime());
+            logInfo.set("nckd_billno",payBillEntity.get("billno"));
+            logInfo.set("nckd_payid",payBillEntity.getPkValue()+"");
+            logInfo.set("nckd_qqbw_tag",qqbw);
+            logInfo.set("nckd_fhbw_tag",fhbw);
+            logInfo.set("nckd_redate",new Date());
+
+            logInfo.set("nckd_djlx","1");
+            OperationServiceHelper.executeOperate("save","nckd_zfcxjkrz",new DynamicObject[]{logInfo});
+
+        }catch (Exception e){
+            log.info("保存日志报错"+e.getMessage());
+
+        }
+
+
     }
 
     public static JSONObject socketService(String serverName,String port,String xmlData){
         try {
             Socket client = new Socket(serverName,TypeUtils.nullToInt(port));
             int messageLength = xmlData.getBytes("GBK").length;
-            String header = String.format("%08dXMLBTSCO001%%%%%%%%%%%%%%%%%%%%%%%%", messageLength);
+            String header = String.format("%08dXMLBTSCO001%%%%%%%%%%%%%%%%%%%%%%%%%%", messageLength);
+            String fullMessage = header + xmlData;
+            OutputStream outToServer = client.getOutputStream();
+
+            PrintWriter out = new PrintWriter(new OutputStreamWriter(outToServer, "GBK"), true);
+            out.println(fullMessage);
+
+            InputStream inFromServer = client.getInputStream();
+            BufferedReader in = new BufferedReader(new InputStreamReader(inFromServer, "GBK"));
+            StringBuilder responseBuilder = new StringBuilder();
+            String line;
+            while ((line = in.readLine()) != null) {
+                responseBuilder.append(line);
+            }
+            String responseJson = responseBuilder.toString();
+            if(responseJson.indexOf("<?xml")>0){
+                int index = responseJson.indexOf("<?xml");
+                responseJson = responseJson.substring(index);
+            }
+
+            JSONObject jsonObject = XML.toJSONObject(responseJson);
+            client.close();
+            return  jsonObject;
+        } catch (IOException e) {
+            e.printStackTrace();
+            log.info(e.getMessage());
+        }
+        return null;
+    }
+
+
+
+    public static JSONObject socketServiceQuery(String serverName,String port,String xmlData,String transcode){
+        try {
+            Socket client = new Socket(serverName,TypeUtils.nullToInt(port));
+            int messageLength = xmlData.getBytes("GBK").length;
+            String header = String.format("%08dXML"+transcode+"%%%%%%%%%%%%%%%%%%%%%%%%%%", messageLength);
             String fullMessage = header + xmlData;
             OutputStream outToServer = client.getOutputStream();
 

+ 17 - 2
src/main/java/fi/cas/opplugin/PayToZFQZOP.java

@@ -6,6 +6,8 @@ import kd.bos.entity.plugin.AddValidatorsEventArgs;
 import kd.bos.entity.plugin.args.AfterOperationArgs;
 import kd.bos.entity.plugin.args.BeforeOperationArgs;
 import com.alibaba.druid.util.StringUtils;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
 
 
 public class PayToZFQZOP  extends AbstractOperationServicePlugIn {
@@ -25,10 +27,23 @@ public class PayToZFQZOP  extends AbstractOperationServicePlugIn {
 
         //获取选中行
         DynamicObject[] billEntities = e.getDataEntities();
-
-        //获取操作按钮操作编码
         String operationKey = e.getOperationKey();
+        //获取操作按钮操作编码
         if (StringUtils.equals( "paytoqianzhi",operationKey)){
+            for (DynamicObject dataEntity : billEntities) {
+                DynamicObject payBillEntity = BusinessDataServiceHelper.loadSingle(dataEntity.getPkValue(), ENTITY_NAME);
+
+                String paystatus = payBillEntity.getString("nckd_paystatus");
+                int bbh = payBillEntity.getInt("nckd_bbh");
+                int fkcs = payBillEntity.getInt("nckd_fkcs");
+                String billstatusString = payBillEntity.getString("billstatus");
+                if ("C".equals(billstatusString)&&"4".equals(paystatus)&&bbh>=1 && bbh!=fkcs-1) {
+                    //状态为已审批,支付状态为失败,版本号>1,版本号=付款次数-1。符合付款条件,修改状态和版本号先
+                    payBillEntity.set("nckd_paystatus", "1");//支付状态改回未支付
+                    payBillEntity.set("nckd_bbh",bbh+1);
+                    SaveServiceHelper.update(payBillEntity);
+                }
+            }
             errMsg =  PayBillToolUtil.payBillForCBSSync(billEntities);
         }
         if(!errMsg.isEmpty()) {

+ 140 - 0
src/main/java/fi/cas/task/MatchBadDebtsTask.java

@@ -0,0 +1,140 @@
+package fi.cas.task;
+
+import com.alibaba.druid.util.StringUtils;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.exception.KDException;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.schedule.executor.AbstractTask;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+//计算财务应付单到坏账计提单的减值数据
+public class MatchBadDebtsTask extends AbstractTask {
+    @Override
+    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
+
+        List<DynamicObject> jz = new ArrayList<>();//减值数据
+        List<DynamicObject> ar_baddebtlossbill = new ArrayList<>();//坏账单列表
+        List<String> dubilList = new ArrayList<>();//坏账单列表
+        List<String> custList = new ArrayList<>();//坏账单列表
+        List<DynamicObject> infoList = new ArrayList<>();//计算成功的坏帐单列表
+        List<DynamicObject> ar_baddebtlossbill_customer = new ArrayList<>();//根据客户坏账单列表
+        List<DynamicObject> ar_baddebtlossbill_five_level = new ArrayList<>();//根据五级分类坏账单列表
+
+
+        //获取当前日期和时间
+        Date currentDate = new Date();
+        // 使用Calendar来获取前七天的日期
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(currentDate);
+        calendar.add(Calendar.DAY_OF_MONTH, -7);
+        Date sevenDaysAgo = calendar.getTime();
+
+        //查询“是否诉讼类费用”且业务日期再当前日期到啊七天前之间的坏账单
+        QFilter filter = new QFilter("nckd_checkboxfield", QCP.equals, "1");
+        filter.and("bizdate", QCP.large_than, sevenDaysAgo);
+        filter.and("bizdate", QCP.less_than, currentDate);
+        filter.and("baddebtamt", QCP.large_than, 0);
+        filter.and("nckd_match_amt", QCP.equals, "0");
+        DynamicObject[] dynamicObjects = BusinessDataServiceHelper.load("ar_baddebtlossbill","id", new QFilter[] {filter});
+        for (int i = 0; i < dynamicObjects.length; i++) {
+            DynamicObject info = BusinessDataServiceHelper.loadSingle(dynamicObjects[i].getPkValue(), dynamicObjects[i].getDynamicObjectType().getName());
+            ar_baddebtlossbill.add(info);
+            dubilList.add(info.getString("nckd_textfield"));
+            custList.add(info.getDynamicObject("asstact").getString("number"));
+        }
+
+        //查询减值准备数据(最新一批)
+        QFilter jzfilter = new QFilter("nckd_dubil_id", QCP.in, dubilList);
+        jzfilter.or("nckd_cust_id", QCP.in, custList);
+        DynamicObject[] jzdynamicObjects = BusinessDataServiceHelper.load("nckd_impairment","nckd_dubil_id,nckd_cust_id,nckd_ecl_ratio", new QFilter[]{jzfilter});
+        jz =  new ArrayList<>(Arrays.asList(jzdynamicObjects));
+
+        //下推坏账-根据借据号匹配
+        MatchByDubilId(ar_baddebtlossbill, jz, infoList, ar_baddebtlossbill_customer);
+
+        //下推坏账-根据客户匹配
+        MatchByCustom(ar_baddebtlossbill_customer, jz, infoList, ar_baddebtlossbill_five_level);
+
+        //下推坏账-根据五级分类匹配
+        MatchByFiveLevel(ar_baddebtlossbill_five_level, infoList);
+
+        //保存
+        DynamicObject[] array = infoList.toArray(new DynamicObject[0]);
+        SaveServiceHelper.save(array);
+    }
+
+    public void MatchByDubilId(List<DynamicObject> ar_baddebtlossbill, List<DynamicObject> jz, List<DynamicObject> infoList, List<DynamicObject> ar_baddebtlossbill_customer) {
+        for (DynamicObject dynamicObject : ar_baddebtlossbill) {
+            String dubil_id = dynamicObject.getString("nckd_textfield");//借据号
+            BigDecimal unsettleamount = dynamicObject.getBigDecimal("baddebtamt");//未结算金额
+            BigDecimal nckd_amountfield1 = dynamicObject.getBigDecimal("nckd_amountfield1");//上月计提金额
+            //查询借据号匹配的减值数据
+            List<DynamicObject> jzInfo = jz.stream().filter(item -> StringUtils.equals(item.getString("nckd_dubil_id"), dubil_id)).collect(Collectors.toList());
+            if (jzInfo.size() > 0) {
+                //更新坏账单
+                BigDecimal ecl_ratio = jzInfo.get(0).getBigDecimal("nckd_ecl_ratio");
+                BigDecimal ecl_amount = unsettleamount.multiply(ecl_ratio);
+                dynamicObject.set("nckd_textfield1", String.valueOf(ecl_ratio));//计提比例
+                dynamicObject.set("nckd_amountfield", ecl_amount);//计提金额
+                dynamicObject.set("nckd_match_amt", true);//是否计算计提金额
+                dynamicObject.set("nckd_amountfield2", ecl_amount.subtract(nckd_amountfield1 != null ? nckd_amountfield1 : BigDecimal.ZERO));//扎差金额
+                infoList.add(dynamicObject);
+            }else {
+                //根据客户匹配
+                ar_baddebtlossbill_customer.add(dynamicObject);
+            }
+        }
+    }
+
+    public void MatchByCustom(List<DynamicObject> ar_baddebtlossbill_customer, List<DynamicObject> jz, List<DynamicObject> infoList, List<DynamicObject> ar_baddebtlossbill_five_level) {
+        for (DynamicObject dynamicObject : ar_baddebtlossbill_customer) {
+            BigDecimal unsettleamount = dynamicObject.getBigDecimal("baddebtamt");//未结算金额
+            String customer = dynamicObject.getDynamicObject("asstact").getString("number");//供应商编码
+            BigDecimal nckd_amountfield1 = dynamicObject.getBigDecimal("nckd_amountfield1");//上月计提金额
+            //查询客户匹配的减值数据
+            List<DynamicObject> jzInfo = jz.stream().filter(item -> StringUtils.equals(item.getString("nckd_cust_id"), customer)).collect(Collectors.toList());
+            if (jzInfo.size() > 0) {
+                //更新坏账单
+                BigDecimal ecl_ratio = jzInfo.stream()
+                        .map(s -> {
+                            BigDecimal value = s.getBigDecimal("nckd_ecl_ratio");
+                            return value != null ? value : BigDecimal.ZERO; // 处理 null
+                        })
+                        .reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(jzInfo.size()));
+                BigDecimal ecl_amount = unsettleamount.multiply(ecl_ratio);
+                dynamicObject.set("nckd_textfield1", String.valueOf(ecl_ratio));//计提比例
+                dynamicObject.set("nckd_amountfield", ecl_amount);//计提金额
+                dynamicObject.set("nckd_match_amt", true);//是否计算计提金额
+                dynamicObject.set("nckd_amountfield2", ecl_amount.subtract(nckd_amountfield1 != null ? nckd_amountfield1 : BigDecimal.ZERO));//扎差金额
+                infoList.add(dynamicObject);
+            }else {
+                //根据五级分类匹配
+                ar_baddebtlossbill_five_level.add(dynamicObject);
+            }
+        }
+    }
+
+    public void MatchByFiveLevel(List<DynamicObject> ar_baddebtlossbill_five_level, List<DynamicObject> infoList) {
+        for (DynamicObject dynamicObject : ar_baddebtlossbill_five_level) {
+            BigDecimal unsettleamount = dynamicObject.getBigDecimal("baddebtamt");//未结算金额
+            DynamicObject fiveLevel = dynamicObject.getDynamicObject("nckd_basedatafield");//五级分类
+            BigDecimal nckd_amountfield1 = dynamicObject.getBigDecimal("nckd_amountfield1");//上月计提金额
+            if (fiveLevel != null) {
+                //更新坏账单
+                BigDecimal ecl_ratio = fiveLevel.getBigDecimal("nckd_ecl_ratio");
+                BigDecimal ecl_amount = unsettleamount.multiply(ecl_ratio);
+                dynamicObject.set("nckd_textfield1", String.valueOf(ecl_ratio));//计提比例
+                dynamicObject.set("nckd_amountfield", ecl_amount);//计提金额
+                dynamicObject.set("nckd_match_amt", true);//是否计算计提金额
+                dynamicObject.set("nckd_amountfield2", ecl_amount.subtract(nckd_amountfield1 != null ? nckd_amountfield1 : BigDecimal.ZERO));//扎差金额
+                infoList.add(dynamicObject);
+            }
+        }
+    }
+}

+ 73 - 0
src/main/java/fi/cas/task/PayQueryStatusTast.java

@@ -0,0 +1,73 @@
+package fi.cas.task;
+
+import com.alibaba.druid.support.logging.Log;
+import com.alibaba.druid.support.logging.LogFactory;
+import fi.cas.opplugin.PayBillToolUtil;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.exception.KDException;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.schedule.executor.AbstractTask;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import org.json.JSONObject;
+
+import java.util.Map;
+
+public class PayQueryStatusTast extends AbstractTask {
+    private static final Log log = LogFactory.getLog(PayQueryStatusTast.class);
+    @Override
+    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
+        //获取要查询的数据。状态为已审批,支付状态为支付中。
+        QFilter filter = new QFilter("billstatus", QCP.equals, "C");
+        filter.and("nckd_paystatus", QCP.equals, "2");
+        filter.and("nckd_fkcs", QCP.large_than, 0);
+        DynamicObject[] payinfos = BusinessDataServiceHelper.load("cas_paybill","billno,billstatus,nckd_paystatus,nckd_sbyy,nckd_fqqdrq,nckd_fkcs,nckd_bbh", new QFilter[] {filter});
+        DynamicObject jkpzxx = BusinessDataServiceHelper.loadSingle("nckd_jkpzxx",new QFilter[]{new QFilter("number","=","paytozfqz")});
+        String servername =  jkpzxx.getString("nckd_servername");
+        String port =  jkpzxx.getString("nckd_port");
+
+        for (DynamicObject dataEntity : payinfos) {
+            //调用接口查询付款状态
+            String bodyxml = PayBillToolUtil.queryPaymentRequest(dataEntity);
+            String billNum = dataEntity.getString("billno");
+            log.info("单据号:"+billNum+"传入参数"+bodyxml);
+            JSONObject cbsReturnJson =PayBillToolUtil.socketServiceQuery(servername,port,bodyxml,"BTSQO001");
+            log.info("单据号:"+billNum+"返回参数"+cbsReturnJson.toString());
+            if(cbsReturnJson==null||cbsReturnJson.get("Message")==null){
+            }else{
+                JSONObject bodyinfo = cbsReturnJson.getJSONObject("Message").getJSONObject("Body");
+                if(bodyinfo!=null){
+                    String errcode =bodyinfo.getString("errorcode");
+                    boolean isupdate = false;
+                    if ("FIN0000".equals(errcode)) {//已查询到,不代表支付成功
+                        String zfstatus = bodyinfo.getString("status");
+                        String errormsg =bodyinfo.getString("remark3");
+                        if("U".equals(zfstatus)){//在途
+                            //判断原因是否有变化
+                           String sbyy =  dataEntity.getString("nckd_sbyy");
+                           if(errormsg!=null&&errormsg.equals(sbyy)){//相等
+                           }else{
+                               dataEntity.set("nckd_sbyy",errormsg);//错误信息更新
+                               isupdate = true;
+                           }
+                        }else if("S".equals(zfstatus)){//成功
+                            dataEntity.set("nckd_paystatus",3);
+                            dataEntity.set("nckd_sbyy","支付成功");//错误信息更新
+                            isupdate = true;
+                        }else if("F".equals(zfstatus)){//失败
+                            dataEntity.set("nckd_paystatus",4);//支付失败
+                            dataEntity.set("nckd_sbyy",errormsg);//错误信息更新
+                            isupdate = true;
+                        }
+                        if(isupdate){
+                            SaveServiceHelper.update(new DynamicObject[]{dataEntity});
+                            PayBillToolUtil.saveupdatelog(dataEntity,bodyxml,cbsReturnJson.toString());
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

+ 28 - 0
src/main/java/fi/cas/task/PayUpadteStatusTask.java

@@ -0,0 +1,28 @@
+package fi.cas.task;
+
+import com.alibaba.druid.support.logging.Log;
+import com.alibaba.druid.support.logging.LogFactory;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.OperateOption;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.exception.KDException;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.schedule.executor.AbstractTask;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.OperationServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+
+import java.util.Map;
+
+public class PayUpadteStatusTask  extends AbstractTask {
+    private static final Log log = LogFactory.getLog(PayUpadteStatusTask.class);
+    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
+        //获取要查询的数据。状态为已审批,支付状态为支付成功。
+        QFilter filter = new QFilter("billstatus", QCP.equals, "C");
+        filter.and("nckd_paystatus", QCP.equals, 3);
+        filter.and("nckd_fkcs", QCP.large_than, 0);
+        DynamicObject[] payinfos = BusinessDataServiceHelper.load("cas_paybill","billno,billstatus,nckd_paystatus,nckd_sbyy,nckd_fqqdrq,nckd_fkcs,nckd_bbh", new QFilter[] {filter});
+        OperationServiceHelper.executeOperate("pay","cas_paybill",payinfos, OperateOption.create());
+    }
+}

+ 3 - 0
src/main/java/fi/em/formPlugin/AgentpaybillFormPlugin.java

@@ -115,6 +115,9 @@ public class AgentpaybillFormPlugin extends AbstractListPlugin implements Plugin
             //反写后保存
             SaveServiceHelper.save(new DynamicObject[] {agentpaybill});
         }
+
+
+
     }
 
     public void propertyChanged(PropertyChangedArgs e)

+ 2 - 0
src/main/java/fi/em/formPlugin/BusinessProcessingEditPlugin.java

@@ -228,6 +228,7 @@ public class BusinessProcessingEditPlugin extends AbstractListPlugin implements
                         String nckdCyffyxm = reJo.getString("nckd_cyffyxm");
                         String settleorg = reJo.getString("settleorg");
                         String duedate = reJo.getString("duedate");
+                        Long id = reJo.getLong("id");
                         QFilter nckd_cysfyxmFilter = new QFilter("number", QCP.equals, nckdCyffyxm);
                         DynamicObject nckd_cyffyxm = BusinessDataServiceHelper.loadSingle("er_expenseitemedit", "id", new QFilter[]{nckd_cysfyxmFilter});
                         BigDecimal settleamount = reJo.getBigDecimal("nckd_cyfgzbalance");
@@ -243,6 +244,7 @@ public class BusinessProcessingEditPlugin extends AbstractListPlugin implements
                         DynamicObject dynamicObjects = (DynamicObject) value;
                         this.getModel().setValue("nckd_cyfwldw", dynamicObjects, rowIndex);
                         this.getModel().setValue("nckd_cyfdata", bizdate, rowIndex);
+                        this.getModel().setValue("nckd_bigintfield", id, rowIndex);
                         this.getModel().setValue("nckd_datefield1", duedate, rowIndex);
                         this.getModel().setValue("nckd_cyfgzbalance", settleamount, rowIndex);
                         this.getModel().setValue("nckd_cyfcxbalance", settleamount, rowIndex);

+ 57 - 0
src/main/java/fi/em/formPlugin/BusinessProcessingListPlugin.java

@@ -0,0 +1,57 @@
+package fi.em.formPlugin;
+
+import com.alibaba.druid.util.StringUtils;
+import kd.bos.bill.BillShowParameter;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.datamodel.ListSelectedRowCollection;
+import kd.bos.form.ShowType;
+import kd.bos.form.control.events.ItemClickEvent;
+import kd.bos.list.BillList;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+
+import java.util.EventObject;
+
+public class BusinessProcessingListPlugin extends AbstractListPlugin {
+    public void registerListener(EventObject e) {
+        super.registerListener(e);
+        this.addItemClickListeners(new String[]{"toolbarap"});
+    }
+
+    @Override
+    public void itemClick(ItemClickEvent evt) {
+        String itemKey = evt.getItemKey();
+        if ("nckd_trackup".equals(itemKey)) {
+            BillList billList = (BillList) this.getControl("billlistap");
+            ListSelectedRowCollection list = billList.getSelectedRows();
+            if (list.size() == 0) {
+                this.getView().showMessage("请选择一条数据");
+                return;
+            } else if (list.size() > 1) {
+                this.getView().showMessage("只能选择一条数据");
+                return;
+            }
+            Object[] primaryKeyValues = list.getPrimaryKeyValues();
+            long id = 0;
+            String type = null;
+            for (Object pk : primaryKeyValues) {
+                DynamicObject info = BusinessDataServiceHelper.loadSingle(pk, "nckd_ywcld");
+                id = info.getLong("nckd_mid_assert");
+                type = info.getString("nckd_source_type");
+                if (id == 0 || StringUtils.isEmpty(type)) {
+                    this.getView().showMessage("该数据不是由中间表生成,无法上查到中间表");
+                    return;
+                }
+            }
+            BillShowParameter showParameter = new BillShowParameter();
+
+            showParameter.setFormId(type);
+
+            showParameter.getOpenStyle().setShowType(ShowType.Modal);//打开方式
+
+            showParameter.setPkId(id);
+
+            this.getView().showForm(showParameter);
+        }
+    }
+}

+ 3 - 0
src/main/java/fi/em/formPlugin/BusinessProcessingPlugin.java

@@ -205,6 +205,7 @@ public class BusinessProcessingPlugin extends AbstractFormPlugin implements Plug
                 Date bizdate = dynamicObject.getDate("bizdate");
                 Date duedate = dynamicObject.getDate("duedate");
                 DynamicObject org = dynamicObject.getDynamicObject("org");
+                long id = dynamicObject.getLong("id");
                 //应收挂账金额/冲销金额
                 BigDecimal settleamount = dynamicObject.getBigDecimal("unsettleamount");
                 for (DynamicObject entryentity : dynamicObject.getDynamicObjectCollection("detailentry")) {
@@ -224,6 +225,7 @@ public class BusinessProcessingPlugin extends AbstractFormPlugin implements Plug
                     this.getModel().setValue("nckd_cyforg", org, rowIndex);
                     this.getModel().setValue("nckd_cyfgzbalance", settleamount, rowIndex);
                     this.getModel().setValue("nckd_cyfcxbalance", settleamount, rowIndex);
+                    this.getModel().setValue("nckd_billid", id, rowIndex);
                     QFilter nckd_cysfyxmFilter = new QFilter("number", QCP.equals,payeenamev);
                     DynamicObject nckd_cyffyxm = BusinessDataServiceHelper.loadSingle("bd_supplier","id",new QFilter[] {nckd_cysfyxmFilter});
                     this.getModel().setValue("nckd_basedatafield", nckd_cyffyxm, rowIndex);
@@ -250,6 +252,7 @@ public class BusinessProcessingPlugin extends AbstractFormPlugin implements Plug
                     obj.put("nckd_cyfwldw", "");
                     obj.put("nckd_cyfdata", bizdate);
                     obj.put("duedate", duedate);
+                    obj.put("id", id);
                     obj.put("nckd_cyfgzbalance", settleamount);
                     obj.put("settleorg", org.getString("number"));
                     if (expenseitem != null) {

+ 3 - 4
src/main/java/fi/em/formPlugin/SalaryFileUploadEditPlugin.java

@@ -71,7 +71,7 @@ public class SalaryFileUploadEditPlugin extends AbstractBillPlugIn implements Up
             readExcelByRowOrCell(4,78,inputStream,billtype);
         } else if ("E".equals(nckd_entrytype)) {
             billtype="nckd_salaryentryre";
-            readExcelByRowOrCell(4,34,inputStream,billtype);
+            readExcelByRowOrCell(4,41,inputStream,billtype);
         } else if (null==nckd_entrytype) {
             throw new KDBizException("请选择分录类型");
         }
@@ -176,7 +176,8 @@ public class SalaryFileUploadEditPlugin extends AbstractBillPlugIn implements Up
                 ,"nckd_see_per_bhopins","nckd_see_per_hosins","nckd_see_per_cmymey","nckd_see_unionmey","nckd_see_tax"
                 ,"nckd_see_desalary","nckd_see_netsalary","nckd_see_otherreduce","nckd_see_cpy_endins","nckd_see_cpy_bhopins"
                 ,"nckd_see_cpy_ljins","nckd_see_cpy_birthins","nckd_see_cpy_dmgins","nckd_see_cpy_cmymey","nckd_see_cpy_hosins"
-                ,"nckd_see_taxt","nckd_see_alltaxt","nckd_see_charge","nckd_see_finallsys");
+                ,"nckd_see_taxt","nckd_see_alltaxt","nckd_see_charge","nckd_see_finallsys","nckd_see_cpy_oldins","nckd_see_cpy_hop"
+                ,"nckd_see_cpy_bhop","nckd_see_cpy_bir","nckd_see_cpy_ljob","nckd_see_cpy_dwork","nckd_see_cpy_hos","nckd_see_cpy_cmy");
 
 
         //将excel数据存入薪酬明细(一般员工)分录
@@ -316,7 +317,6 @@ public class SalaryFileUploadEditPlugin extends AbstractBillPlugIn implements Up
                 }
             }
         }
-
         //薪酬明细(退休)分录
         if(nckd_entry.equals("nckd_retireentry")) {
             this.getModel().deleteEntryData("nckd_retireentry");
@@ -446,7 +446,6 @@ public class SalaryFileUploadEditPlugin extends AbstractBillPlugIn implements Up
             }
 
         }
-
         //人力薪酬内退分录
         if (nckd_entry.equals("nckd_salaryentryre")){
             this.getModel().deleteEntryData("nckd_salaryentryre");

+ 297 - 0
src/main/java/fi/em/formPlugin/SubAndAudFormPlugin.java

@@ -0,0 +1,297 @@
+package fi.em.formPlugin;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.form.events.BeforeDoOperationEventArgs;
+import kd.bos.form.operate.FormOperate;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.sdk.plugin.Plugin;
+
+import java.math.BigDecimal;
+import java.util.*;
+
+/**
+ * @author cjz
+ * @date 2024/9/12 11:12
+ * @description:薪酬计提提交后自动审核,保存前计算汇总分录
+ */
+public class SubAndAudFormPlugin extends AbstractListPlugin implements Plugin {
+
+    private static String nckd_staffentry="nckd_staffentry";//通用薪酬一般员工
+    private static String nckd_earlyretiredentry="nckd_earlyretiredentry";//通用薪酬内退
+    private static String nckd_retireentry="nckd_retireentry";//通用薪酬退休
+    private static String nckd_salaryentry="nckd_salaryentry";//人力薪酬
+    private static String nckd_salaryentryre="nckd_salaryentryre";//人力薪酬内退
+    private static String nckd_allentry="nckd_allentry";//汇总分录
+
+    public void afterDoOperation(AfterDoOperationEventArgs arg){
+        //提交并审核
+        if ("submit".equals(arg.getOperateKey())) {
+            //调用审核
+            this.getView().invokeOperation("audit");
+        }
+    }
+
+
+    //根据输入的list名,返回对应list
+    public List<String> entryList(String nckdentry)
+    {
+        //薪酬明细(一般员工)分录字段标识,金额字段
+        List<String> nckd_generalemployees = Arrays.asList("nckd_se_allbasicsry"
+                ,"nckd_se_basicsry","nckd_se_acmsry","nckd_se_reacmsry","nckd_se_bsnrwd","nckd_se_otreward","nckd_se_cmcsbd"
+                ,"nckd_se_otherpysry","nckd_se_clearrwd","nckd_se_awareward","nckd_se_otherdevreward","nckd_se_coldsbad"
+                ,"nckd_se_warmsbad","nckd_se_nursabd","nckd_se_otherallowance","nckd_se_salarypayable","nckd_se_per_endins"
+                ,"nckd_se_per_hopins","nckd_se_per_bhopins","nckd_se_per_ljins","nckd_se_per_hosins","nckd_se_per_cmymey"
+                ,"nckd_se_unionmey","nckd_se_tax","nckd_se_otherreduce","nckd_se_desalary","nckd_se_netsalary","nckd_se_cpy_endins"
+                ,"nckd_se_cpy_hopins","nckd_se_cpy_bhopins","nckd_se_cpy_ljins","nckd_se_cpy_birthins","nckd_se_cpy_dmgins","nckd_se_cpy_hosins"
+                ,"nckd_se_cpy_cmymey");
+        //薪酬明细(一般员工)汇总分录字段标识
+        List<String> nckd_allemployees=Arrays.asList("nckd_all_allbsry","nckd_all_basicsry","nckd_all_acmsry","nckd_all_reacmsry"
+                ,"nckd_all_bsnrwd","nckd_all_otreward","nckd_all_cmcsbd","nckd_all_otherpysry","nckd_all_clearrwd","nckd_all_awareward"
+                ,"nckd_all_odevreward","nckd_all_coldsbad","nckd_all_warmsbad","nckd_all_nursabd","nckd_all_oallowance","nckd_all_salarypaya"
+                ,"nckd_all_per_endins","nckd_all_per_hopins","nckd_all_per_bhopins","nckd_all_per_ljins","nckd_all_per_hosins","nckd_all_per_cmymey"
+                ,"nckd_all_unionmey","nckd_all_tax","nckd_all_otherreduce","nckd_all_desalary","nckd_all_netsalary","nckd_all_cpy_endins"
+                ,"nckd_all_cpy_hopins","nckd_all_cpy_bhopins","nckd_all_cpy_ljins","nckd_all_cpy_birthins","nckd_all_cpy_dmgins","nckd_all_cpy_hosins"
+                ,"nckd_all_cpy_cmymey");
+
+
+        //薪酬明细(内退)分录字段标识,金额字段
+        List<String> nckd_earlyretired=Arrays.asList("nckd_ee_allbasicsry","nckd_ee_allowance","nckd_ee_otherallowance","nckd_ee_per_endins"
+                ,"nckd_ee_per_ljins","nckd_ee_per_hopins","nckd_ee_per_bhopins","nckd_ee_per_hosins","nckd_ee_per_cmymey","nckd_ee_unionmey"
+                ,"nckd_ee_tax","nckd_ee_desalary","nckd_ee_netsalary","nckd_ee_otherreduce","nckd_ee_cpy_endins","nckd_ee_cpy_bhopins"
+                ,"nckd_ee_cpy_ljins","nckd_ee_cpy_birthins","nckd_ee_cpy_dmgins","nckd_ee_cpy_cmymey","nckd_ee_cpy_hosins","nckd_ee_taxt"
+                ,"nckd_ee_alltaxt","nckd_ee_charge","nckd_ee_finallsys");
+        //薪酬明细(内退)汇总分录字段标识
+        List<String> nckd_allearlytired=Arrays.asList("nckd_all_allbasicsry","nckd_all_allowqance","nckd_all_owance","nckd_all_reduceitem"
+                ,"nckd_all_sumsry","nckd_all_laryreduce","nckd_all_pushreduce","nckd_all_lrulereduce","nckd_all_badreduce","nckd_all_oreduce","nckd_all_reducesry"
+                ,"nckd_all_salarypaya","nckd_all_nesalary","nckd_all_per_endins","nckd_all_per_hopins","nckd_all_per_bhopins","nckd_all_per_ljins"
+                ,"nckd_all_per_hosins","nckd_all_per_cmymey","nckd_all_sumins","nckd_all_workamount","nckd_all_tax","nckd_all_alltaxt"
+                ,"nckd_all_charge","nckd_all_netsalary");
+
+
+        //薪酬明细(退休)分录字段标识,金额字段
+        List<String> nckd_retired=Arrays.asList("nckd_re_livallowance","nckd_re_otherallowance","nckd_re_reward"
+                ,"nckd_re_salarypayable","nckd_re_desalary","nckd_re_netsalary");
+        //薪酬明细(退休)汇总分录字段标识
+        List<String> nckd_allretired=Arrays.asList("nckd_all_livallowance","nckd_all_otherwance","nckd_all_reward","nckd_all_salarypaya"
+                ,"nckd_all_desalary","nckd_all_netsalary");
+
+
+        //人力薪酬分录标识金额字段,金额字段
+        List<String> nckd_pay=Arrays.asList("nckd_sae_levelsry","nckd_sae_dutiessry","nckd_sae_updutiessry","nckd_sae_workyearsry"
+                ,"nckd_sae_depyear","nckd_sae_eduasry","nckd_sae_transry","nckd_sae_jobsry","nckd_sae_basicsry","nckd_sae_allbasicsry","nckd_sae_acmsry"
+                ,"nckd_sae_mountsry","nckd_sae_reacmsry","nckd_sae_balyearsry","nckd_sae_blastyearsry","nckd_sae_allsry","nckd_sae_bsnrwd","nckd_sae_cpmrwd"
+                ,"nckd_sae_psrwd","nckd_sae_comrwd","nckd_sae_cardrwd","nckd_sae_intwrd","nckd_sae_clearrwd","nckd_sae_allrwd","nckd_sae_retainsry"
+                ,"nckd_sae_reward","nckd_sae_otreward","nckd_sae_cmcsbd","nckd_sae_trfsbd","nckd_sae_housesbd","nckd_sae_warmsbd","nckd_sae_edusbd"
+                ,"nckd_sae_trafficsbd","nckd_sae_othersbd","nckd_sae_reduce","nckd_sae_othersry","nckd_sae_sickreduce","nckd_sae_sickhopreduce"
+                ,"nckd_sae_eventreduce","nckd_sae_afwreduce","nckd_sae_latereduce","nckd_sae_cwasry","nckd_sae_cwareduce","nckd_sae_dgreduce"
+                ,"nckd_sae_dcpreduce","nckd_sae_badreduce","nckd_sae_otherreduce","nckd_sae_allreduce","nckd_sae_lastsry","nckd_sae_allpay"
+                ,"nckd_sae_per_endins","nckd_sae_per_ljins","nckd_sae_per_hopins","nckd_sae_per_bhopins","nckd_sae_per_hosins","nckd_sae_per_cmymey"
+                ,"nckd_sae_per_ins","nckd_sae_unionmey","nckd_sae_tax","nckd_sae_allamount","nckd_sae_cash","nckd_sae_wages","nckd_sae_cpy_endins"
+                ,"nckd_sae_cpy_hopins","nckd_sae_cpy_bhopins","nckd_sae_cpy_birthins","nckd_sae_cpy_ljins","nckd_sae_cpy_dmgins","nckd_sae_cpy_hosins"
+                ,"nckd_sae_cpy_cmymey");
+        //人力薪酬汇总分录字段标识
+        List<String> nckd_allpay=Arrays.asList("nckd_all_levelsry","nckd_all_dutiessry","nckd_all_updutiessry","nckd_all_workyearsry"
+                ,"nckd_all_depyear","nckd_all_eduasry","nckd_all_transry","nckd_all_jobsry","nckd_all_rebasicsry","nckd_all_allbacsry"
+                ,"nckd_all_allcmsry","nckd_all_mountsry","nckd_all_reacmamount","nckd_all_balyearsry","nckd_all_blastyearsry","nckd_all_allsry"
+                ,"nckd_all_bsnreda","nckd_all_cpmrwd","nckd_all_psrwd","nckd_all_comrwd","nckd_all_cardrwd","nckd_all_intwrd","nckd_all_clearwd"
+                ,"nckd_all_allrwd","nckd_all_retainsry","nckd_all_owance","nckd_all_otrewardam","nckd_all_rlcmcsbd","nckd_all_trfsbd"
+                ,"nckd_all_housesbd","nckd_all_warmsbd","nckd_all_edusbd","nckd_all_trafficsbd","nckd_all_othersbd","nckd_all_reduce"
+                ,"nckd_all_othersry","nckd_all_sickreduce","nckd_all_sickhopreduce","nckd_all_eventreduce","nckd_all_afwreduce","nckd_all_latereduce"
+                ,"nckd_all_cwasry","nckd_all_cwareduce","nckd_all_dgreduce","nckd_all_dcpreduce","nckd_all_badredu","nckd_all_othereduce"
+                ,"nckd_all_allreduce","nckd_all_salarypaya","nckd_all_nesalary","nckd_all_per_endins","nckd_all_per_hopins","nckd_all_per_bhopins"
+                ,"nckd_all_per_ljins","nckd_all_per_hosins","nckd_all_per_cmymey","nckd_all_sumins","nckd_all_workamount","nckd_all_tax"
+                ,"nckd_all_alltaxt","nckd_all_charge","nckd_all_netsalary","nckd_all_cpy_endins","nckd_all_cpy_hopins","nckd_all_cpy_bhopins"
+                ,"nckd_all_cpy_birthins","nckd_all_cpy_ljins","nckd_all_cpy_dmgins","nckd_all_cpy_hosins","nckd_all_cpy_cmymey");
+
+
+        //人力薪酬内退分录标识,金额字段
+        List<String> nckd_payretird=Arrays.asList("nckd_see_allbasicsry"
+                ,"nckd_see_allowance","nckd_see_otherallowanc","nckd_see_per_endins","nckd_see_per_ljins","nckd_see_per_hopins"
+                ,"nckd_see_per_bhopins","nckd_see_per_hosins","nckd_see_per_cmymey","nckd_see_unionmey","nckd_see_tax"
+                ,"nckd_see_desalary","nckd_see_netsalary","nckd_see_otherreduce","nckd_see_cpy_endins","nckd_see_cpy_bhopins"
+                ,"nckd_see_cpy_ljins","nckd_see_cpy_birthins","nckd_see_cpy_dmgins","nckd_see_cpy_cmymey","nckd_see_cpy_hosins"
+                ,"nckd_see_taxt","nckd_see_alltaxt","nckd_see_charge","nckd_see_finallsys","nckd_see_cpy_oldins","nckd_see_cpy_hop"
+                ,"nckd_see_cpy_bhop","nckd_see_cpy_bir","nckd_see_cpy_ljob","nckd_see_cpy_dwork","nckd_see_cpy_hos","nckd_see_cpy_cmy");
+
+        //人力薪酬内退分录汇总字段
+        List<String> nckd_allpayretird=Arrays.asList("nckd_all_allbasicsry","nckd_all_allowqance","nckd_all_owance","nckd_all_reduceitem"
+                ,"nckd_all_sumsry","nckd_all_laryreduce","nckd_all_pushreduce","nckd_all_lrulereduce","nckd_all_badreduce","nckd_all_oreduce"
+                ,"nckd_all_reducesry","nckd_all_salarypaya","nckd_all_nesalary","nckd_all_per_endins","nckd_all_per_hopins","nckd_all_per_ljins"
+                ,"nckd_all_per_bhopins","nckd_all_per_hosins","nckd_all_per_cmymey","nckd_all_sumins","nckd_all_workamount","nckd_all_tax"
+                ,"nckd_all_alltaxt","nckd_all_charge","nckd_all_netsalary","nckd_all_cpy_endins","nckd_all_cpy_hopins","nckd_all_cpy_bhopins"
+                ,"nckd_all_cpy_birthins","nckd_all_cpy_ljins","nckd_all_cpy_dmgins","nckd_all_cpy_hosins","nckd_all_cpy_cmymey");
+
+        Map<String,List<String>> mapList=new HashMap<>();
+        mapList.put("nckd_generalemployees",nckd_generalemployees);
+        mapList.put("nckd_allemployees",nckd_allemployees);
+        mapList.put("nckd_earlyretired",nckd_earlyretired);
+        mapList.put("nckd_retired",nckd_retired);
+        mapList.put("nckd_pay",nckd_pay);
+        mapList.put("nckd_payretird",nckd_payretird);
+        mapList.put("nckd_allearlytired",nckd_allearlytired);
+        mapList.put("nckd_allretired",nckd_allretired);
+        mapList.put("nckd_allpay",nckd_allpay);
+        mapList.put("nckd_allpayretird",nckd_allpayretird);
+
+
+        //list名
+        List<String> list=new ArrayList<>();
+        list.add("nckd_generalemployees");
+        list.add("nckd_allemployees");
+        list.add("nckd_earlyretired");
+        list.add("nckd_retired");
+        list.add("nckd_pay");
+        list.add("nckd_payretird");
+        list.add("nckd_allearlytired");
+        list.add("nckd_allretired");
+        list.add("nckd_allpay");
+        list.add("nckd_allpayretird");
+        for (String item:list) {
+            if (nckdentry.equals(item))
+            {
+                return mapList.get(nckdentry);
+            }
+        }
+        return null;
+    }
+
+    //保存前计算汇总分录
+    public void beforeDoOperation(BeforeDoOperationEventArgs arg) {
+        super.beforeDoOperation(arg);
+        FormOperate source = (FormOperate) arg.getSource();
+        //获取当前操作单据
+        DynamicObject dynamicObject=this.getModel().getDataEntity(true);
+        //当前单据分录类型
+        String nckd_entrytype=dynamicObject.getString("nckd_entrytype");
+
+        //保存前,计算汇总分录
+        if ("save".equals(source.getOperateKey())||"countall".equals(source.getOperateKey())){
+            //先清空汇总分录分录
+            this.getModel().deleteEntryData("nckd_allentry");
+            //分录类型为通用薪酬一般员工
+            if ("A".equals(nckd_entrytype)) {
+                //字段标识
+                String entrylist="nckd_generalemployees";
+                //对应分录标识
+                String propername="nckd_staffentry";
+                //对应部门标识
+                String dep="nckd_se_department";
+                //对应汇总分录字段标识
+                String allentrtlist="nckd_allemployees";
+                countEntry(dynamicObject,entrylist,propername,dep,allentrtlist);
+            }
+            //分录类型为通用薪酬内退
+            if ("B".equals(nckd_entrytype)) {
+                //字段标识
+                String entrylist="nckd_earlyretired";
+                //对应分录标识
+                String propername="nckd_earlyretiredentry";
+                //对应部门标识
+                String dep="nckd_ee_department";
+                //对应汇总分录字段标识
+                String allentrtlist="nckd_allearlytired";
+                countEntry(dynamicObject,entrylist,propername,dep,allentrtlist);
+            }
+            //分录类型为通用薪酬退休
+            if ("C".equals(nckd_entrytype)) {
+                //字段标识
+                String entrylist="nckd_retired";
+                //对应分录标识
+                String propername="nckd_retireentry";
+                //对应部门标识
+                String dep="nckd_re_department";
+                //对应汇总分录字段标识
+                String allentrtlist="nckd_allretired";
+                countEntry(dynamicObject,entrylist,propername,dep,allentrtlist);
+            }
+            //分录类型为人力薪酬(一般员工)
+            if ("D".equals(nckd_entrytype)) {
+                //字段标识
+                String entrylist="nckd_pay";
+                //对应分录标识
+                String propername="nckd_salaryentry";
+                //对应部门标识
+                String dep="nckd_sae_department";
+                //对应汇总分录字段标识
+                String allentrtlist="nckd_allpay";
+                countEntry(dynamicObject,entrylist,propername,dep,allentrtlist);
+            }
+            //分录类型为人力薪酬(内退)
+            if ("E".equals(nckd_entrytype)) {
+                //字段标识
+                String entrylist="nckd_payretird";
+                //对应分录标识
+                String propername="nckd_salaryentryre";
+                //对应部门标识
+                String dep="nckd_see_department";
+                //对应汇总分录字段标识
+                String allentrtlist="nckd_allpayretird";
+                countEntry(dynamicObject,entrylist,propername,dep,allentrtlist);
+            }
+        }
+
+    }
+
+    /**
+     * @dynamicObject 当前单据信息
+     * @entrylist 字段标识列表
+     * @propername 分录标识
+     * @dep 对应分录部门标识
+     * @allentrtlist 写入的汇总分录字段
+     * @description:根据分录类型不同计算汇总分录
+     */
+    public void countEntry(DynamicObject dynamicObject,String entrylist,String propername,String dep,String allentrtlist)
+    {
+        //字段标识
+        List<String> nckd_generalemployees = entryList(entrylist);
+        //获取一般员工分录
+        DynamicObjectCollection staffentry=dynamicObject.getDynamicObjectCollection(propername);
+        //分录部门list
+        List<DynamicObject> depList=new ArrayList<>();
+        //初始化值为第一行部门
+        depList.add(staffentry.get(0).getDynamicObject(dep));
+        for (DynamicObject item:staffentry) {
+            //将不同的值加入到部门的list中
+            if (!depList.contains(item.getDynamicObject(dep))) {
+                depList.add(item.getDynamicObject(dep));
+            }
+        }
+
+        //几个不同部门则循环几次
+        for (DynamicObject bumen : depList) {
+            //某部门总数据
+            List<BigDecimal> sumNum = new ArrayList<>();
+            //汇总表部门list初始化
+            for (int b = 0; b < nckd_generalemployees.size(); b++) {
+                sumNum.add(new BigDecimal("0.0"));
+            }
+            //计算一个部门汇总
+            for (DynamicObject object : staffentry) {
+                //获取所在部门
+                DynamicObject department = object.getDynamicObject(dep);
+                //相同部门则累加金额数据
+                if (department.equals(bumen)) {
+                    for (int a = 0; a < nckd_generalemployees.size(); a++) {
+                        BigDecimal cell = sumNum.get(a);
+                        //字段标识
+                        String entry = nckd_generalemployees.get(a);
+                        //i行的a列数据
+                        BigDecimal num = object.getBigDecimal(entry);
+                        cell = cell.add(num);
+                        sumNum.set(a, cell);
+                    }
+                }
+            }
+            //创建新的分录行
+            int rowIndex = this.getModel().createNewEntryRow(nckd_allentry);
+            //设置部门
+            this.getModel().setValue("nckd_all_department", bumen, rowIndex);
+            for (int c = 0; c < sumNum.size(); c++) {
+                this.getModel().setValue(entryList(allentrtlist).get(c), sumNum.get(c), rowIndex);
+            }
+        }
+    }
+
+}

+ 3 - 0
src/main/java/fi/em/opplugin/AgentpayPushOpPlugin.java

@@ -58,6 +58,9 @@ public class AgentpayPushOpPlugin extends AbstractOperationServicePlugIn {
                 // 设置需要下推的单据体行内码:按分录下推时必须设置
                 selectedRow.setEntryPrimaryKeyValue(pkid);
                 selectedRows.add(selectedRow);
+                //获取转换规则id
+                ConvertRuleReader read=new ConvertRuleReader();
+                List<String> loadRuleIds = read.loadRuleIds(nckd_salarydistribute, cas_agentpaybill, false);
                 // 创建下推参数
                 PushArgs pushArgs = new PushArgs();
                 // 源单标识

+ 98 - 40
src/main/java/fi/er/opplugin/FinapbillBeforeF7SelectSample.java

@@ -5,6 +5,7 @@ import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.entity.datamodel.events.ChangeData;
 import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.form.field.MulBasedataEdit;
 import kd.bos.form.field.RefBillEdit;
 import kd.bos.form.field.events.BeforeF7SelectEvent;
 import kd.bos.form.field.events.BeforeF7SelectListener;
@@ -28,6 +29,8 @@ public class FinapbillBeforeF7SelectSample extends AbstractFormPlugin implements
         //监听单据字段
         super.registerListener(e);
         RefBillEdit bill = this.getView().getControl(nckd_apfinapbill);
+        MulBasedataEdit mEdit = this.getView().getControl("nckd_real_card");
+        mEdit.addBeforeF7SelectListener(this);
         bill.addBeforeF7SelectListener(this);
     }
     @Override
@@ -57,6 +60,12 @@ public class FinapbillBeforeF7SelectSample extends AbstractFormPlugin implements
                 ListShowParameter showParameter = (ListShowParameter)arg0.getFormShowParameter();
                 showParameter.getListFilterParameter().setFilter(qFilter);
             }
+        } else if (StringUtils.equals(fieldKey, "nckd_real_card")) {
+            DynamicObject assetorg = (DynamicObject) this.getModel().getValue("assetorg");//资产组织
+            QFilter qFilter = new QFilter("nckd_orgfield.id", QCP.equals, assetorg.getLong("id"));
+            // 表过滤条件
+            ListShowParameter showParameter = (ListShowParameter)arg0.getFormShowParameter();
+            showParameter.getListFilterParameter().setFilter(qFilter);
         }
     }
 
@@ -117,20 +126,39 @@ public class FinapbillBeforeF7SelectSample extends AbstractFormPlugin implements
                 DynamicObject receivingsupplierid = gzInfo.getDynamicObject("receivingsupplierid");//供应商
                 Date bookdate = gzInfo.getDate("bookdate");
                 String remark = gzInfo.getString("remark");
-                BigDecimal pricetaxtotal = gzInfo.getBigDecimal("pricetaxtotal");
+                BigDecimal pricetaxtotal = gzInfo.getBigDecimal("pricetaxtotal");//应付金额
+                BigDecimal e_amount = BigDecimal.ZERO;//不含税应付金额
                 BigDecimal expenseamount = BigDecimal.ZERO;//报销金额
+                BigDecimal orientryamount = BigDecimal.ZERO;//不含税金额
 
+                //应付挂账单明细分录
+                DynamicObjectCollection detailentry1 = gzInfo.getDynamicObjectCollection("detailentry");
+                for (DynamicObject object : detailentry1) {
+                    e_amount = e_amount.add(object.getBigDecimal("e_amount"));
+                }
 
                 //费用明细分录
                 DynamicObjectCollection expenseentryentity = this.getModel().getEntryEntity("expenseentryentity");
                 for (DynamicObject object : expenseentryentity) {
                     expenseamount = expenseamount.add(object.getBigDecimal("expenseamount"));
+                    orientryamount = orientryamount.add(object.getBigDecimal("orientryamount"));
                 }
 
                 //冲销金额
                 BigDecimal nckd_accloanamount = expenseamount;
+
+                //不含税借款余额
+                BigDecimal nckd_e_amount = e_amount;
+
+                //不含税冲销金额
+                BigDecimal nckd_amountfield6 = orientryamount;
+
                 //差额
                 BigDecimal nckd_sub_amount = pricetaxtotal.subtract(nckd_accloanamount);
+
+                //不含税差额
+                BigDecimal nckd_amountfield8 = nckd_e_amount.subtract(nckd_amountfield6);
+
                 //给冲预付借款赋值
                 this.getModel().deleteEntryData("nckd_ap_finapbill_detail");
                 int rowIndex = this.getModel().createNewEntryRow("nckd_ap_finapbill_detail");
@@ -146,45 +174,22 @@ public class FinapbillBeforeF7SelectSample extends AbstractFormPlugin implements
                 this.getModel().setValue("nckd_currloanamount",pricetaxtotal,rowIndex);
                 this.getModel().setValue("nckd_accloanamount",nckd_accloanamount,rowIndex);
                 this.getModel().setValue("nckd_curraccloanamount",nckd_accloanamount,rowIndex);
-                this.getModel().setValue("nckd_sub_amount",nckd_sub_amount,rowIndex);
+                this.getModel().setValue("nckd_amountfield7",nckd_sub_amount,rowIndex);
+                this.getModel().setValue("nckd_e_amount",nckd_e_amount,rowIndex);
+                this.getModel().setValue("nckd_amountfield6",nckd_amountfield6,rowIndex);
+                this.getModel().setValue("nckd_amountfield8",nckd_amountfield8,rowIndex);
+
+                DynamicObjectCollection assetentry = this.getModel().getEntryEntity("assetentry");
+                if(assetentry.size() > 0) {
+                    this.getModel().setValue("nckd_amountfield9",nckd_sub_amount,0);
+                    this.getModel().setValue("nckd_amountfield10",nckd_amountfield8,0);
+                }
+
                 //刷新冲预付借款分录
                 this.getView().updateView("nckd_ap_finapbill_detail");
+                this.getView().updateView("assetentry");
             }
-        }//资产组织变更
-        else if (StringUtils.equals("assetorg", fieldKey)) {
-            ChangeData changeData = e.getChangeSet()[0];
-            DynamicObject dynamicObject = (DynamicObject) changeData.getNewValue();
-            Long id = dynamicObject.getLong("id");
-            //查询组织
-            QFilter filter = new QFilter("id", QCP.equals,id);
-            DynamicObject[] orgDynamicObjects = BusinessDataServiceHelper.load("bos_org","id",new QFilter[] {filter});
-            DynamicObject orgInfo = BusinessDataServiceHelper.loadSingle(orgDynamicObjects[0].getPkValue(), orgDynamicObjects[0].getDynamicObjectType().getName());
-            //获取资产信息分录
-            DynamicObjectCollection assetentry = this.getModel().getEntryEntity("assetentry");
-            for (int i = 0; i < assetentry.size(); i++) {
-                //给分录核算组织,使用部门赋值
-                this.getModel().setValue("nckd_orgfield1", orgInfo, i);
-                this.getModel().setValue("asset_costdept", orgInfo, i);
-            }
-            //刷新资产信息分录
-            this.getView().updateView("assetentry");
-        } //资产信息分录-核算组织变更
-        else if (StringUtils.equals("nckd_orgfield1", fieldKey)) {
-            ChangeData changeData = e.getChangeSet()[0];
-            DynamicObject dynamicObject = (DynamicObject) changeData.getNewValue();
-            Long id = dynamicObject.getLong("id");
-            //查询组织
-            QFilter filter = new QFilter("id", QCP.equals,id);
-            DynamicObject[] orgDynamicObjects = BusinessDataServiceHelper.load("bos_org","id",new QFilter[] {filter});
-            DynamicObject orgInfo = BusinessDataServiceHelper.loadSingle(orgDynamicObjects[0].getPkValue(), orgDynamicObjects[0].getDynamicObjectType().getName());
-            //获取资产信息分录
-            DynamicObjectCollection assetentry = this.getModel().getEntryEntity("assetentry");
-            //给分录核算组织,使用部门赋值
-            this.getModel().setValue("nckd_orgfield1", orgInfo, e.getChangeSet()[0].getRowIndex());
-            this.getModel().setValue("asset_costdept", orgInfo, e.getChangeSet()[0].getRowIndex());
-            //刷新资产信息分录
-            this.getView().updateView("assetentry");
-        } else if (StringUtils.equals("expenseamount", fieldKey) || StringUtils.equals("nckd_amountfield3", fieldKey)) {
+        }else if (StringUtils.equals("expenseamount", fieldKey) || StringUtils.equals("nckd_amountfield3", fieldKey)) {
             String reimbursetype = (String) this.getModel().getValue("reimbursetype");
             if("asset".equals(reimbursetype)) {
                 if (this.getModel().getEntryEntity("assetentry").size() == 0) {
@@ -218,26 +223,45 @@ public class FinapbillBeforeF7SelectSample extends AbstractFormPlugin implements
             DynamicObjectCollection nckd_ap_finapbill_detail = this.getModel().getEntryEntity("nckd_ap_finapbill_detail");
             if (nckd_ap_finapbill_detail.size() > 0) {
                 BigDecimal expenseamount = BigDecimal.ZERO;//核定金额
+                BigDecimal orientryamount = BigDecimal.ZERO;//不含税核定金额
                 //费用明细分录
                 DynamicObjectCollection expenseentryentity = this.getModel().getEntryEntity("expenseentryentity");
                 for (DynamicObject object : expenseentryentity) {
                     expenseamount = expenseamount.add(object.getBigDecimal("expenseamount"));
+                    orientryamount = orientryamount.add(object.getBigDecimal("orientryamount"));
                 }
 
                 //冲销金额
                 BigDecimal nckd_accloanamount = expenseamount;
+                //不含税冲销金额
+                BigDecimal nckd_amountfield6 = orientryamount;
                 //借款余额
                 BigDecimal nckd_loanamount = nckd_ap_finapbill_detail.get(0).getBigDecimal("nckd_loanamount");
+                //不含税借款余额
+                BigDecimal nckd_e_amount = nckd_ap_finapbill_detail.get(0).getBigDecimal("nckd_e_amount");
                 //差额
                 BigDecimal nckd_sub_amount = nckd_loanamount.subtract(nckd_accloanamount);
+                //不含税差额
+                BigDecimal nckd_amountfield8 = nckd_e_amount.subtract(nckd_amountfield6);
 
                 this.getModel().setValue("nckd_loanamount",nckd_loanamount,0);
                 this.getModel().setValue("nckd_currloanamount",nckd_loanamount,0);
                 this.getModel().setValue("nckd_accloanamount",nckd_accloanamount,0);
                 this.getModel().setValue("nckd_curraccloanamount",nckd_accloanamount,0);
-                this.getModel().setValue("nckd_sub_amount",nckd_sub_amount,0);
+                this.getModel().setValue("nckd_amountfield7",nckd_sub_amount,0);
+                this.getModel().setValue("nckd_e_amount",nckd_e_amount,0);
+                this.getModel().setValue("nckd_amountfield6",nckd_amountfield6,0);
+                this.getModel().setValue("nckd_amountfield8",nckd_amountfield8,0);
+
+                DynamicObjectCollection assetentry = this.getModel().getEntryEntity("assetentry");
+                if(assetentry.size() > 0) {
+                    this.getModel().setValue("nckd_amountfield9",nckd_sub_amount,0);
+                    this.getModel().setValue("nckd_amountfield10",nckd_amountfield8,0);
+                }
+
                 //刷新冲预付借款分录
                 this.getView().updateView("nckd_ap_finapbill_detail");
+                this.getView().updateView("assetentry");
             }
         } else if (StringUtils.equals("taxrate", fieldKey) || StringUtils.equals("assettaxrate", fieldKey)) {
             String reimbursetype = (String) this.getModel().getValue("reimbursetype");
@@ -269,6 +293,36 @@ public class FinapbillBeforeF7SelectSample extends AbstractFormPlugin implements
                 BigDecimal assettaxamount = assetexpenseamount.subtract(assetorientryamount);
                 this.getModel().setValue("assettaxamount", assettaxamount, 0);
             }
+
+            DynamicObjectCollection nckd_ap_finapbill_detail = this.getModel().getEntryEntity("nckd_ap_finapbill_detail");
+            if (nckd_ap_finapbill_detail.size() > 0) {
+                BigDecimal orientryamount = BigDecimal.ZERO;//不含税核定金额
+                //费用明细分录
+                DynamicObjectCollection expenseentryentity = this.getModel().getEntryEntity("expenseentryentity");
+                for (DynamicObject object : expenseentryentity) {
+                    orientryamount = orientryamount.add(object.getBigDecimal("orientryamount"));
+                }
+
+                //不含税冲销金额
+                BigDecimal nckd_amountfield6 = orientryamount;
+                //不含税借款余额
+                BigDecimal nckd_e_amount = nckd_ap_finapbill_detail.get(0).getBigDecimal("nckd_e_amount");
+                //不含税差额
+                BigDecimal nckd_amountfield8 = nckd_e_amount.subtract(nckd_amountfield6);
+
+                this.getModel().setValue("nckd_e_amount",nckd_e_amount,0);
+                this.getModel().setValue("nckd_amountfield6",nckd_amountfield6,0);
+                this.getModel().setValue("nckd_amountfield8",nckd_amountfield8,0);
+
+                DynamicObjectCollection assetentry = this.getModel().getEntryEntity("assetentry");
+                if(assetentry.size() > 0) {
+                    this.getModel().setValue("nckd_amountfield10",nckd_amountfield8,0);
+                }
+
+                //刷新冲预付借款分录
+                this.getView().updateView("nckd_ap_finapbill_detail");
+                this.getView().updateView("assetentry");
+            }
         }
     }
 
@@ -278,13 +332,17 @@ public class FinapbillBeforeF7SelectSample extends AbstractFormPlugin implements
         String reimbursetype = (String) this.getModel().getValue("reimbursetype");
         int rowIndex = this.getModel().createNewEntryRow("assetentry");
         if("asset".equals(reimbursetype)){
-            //获取费用明细分录
-            DynamicObjectCollection assetentry = this.getModel().getEntryEntity("expenseentryentity");
             //查询费用明细
             QFilter filter = new QFilter("name", QCP.equals,"资产报账");
             DynamicObject[] dynamicObjects = BusinessDataServiceHelper.load("er_expenseitemedit","id",new QFilter[] {filter});
             DynamicObject info = BusinessDataServiceHelper.loadSingle(dynamicObjects[0].getPkValue(), dynamicObjects[0].getDynamicObjectType().getName());
             this.getModel().setValue("expenseitem", info, 0);
+
+            //给资产信息分录,核算组织,使用部门赋值
+            DynamicObject assetorg = (DynamicObject) this.getModel().getValue("assetorg");//资产组织
+            DynamicObject costdept = (DynamicObject) this.getModel().getValue("costdept");//费用承担部门
+            this.getModel().setValue("nckd_orgfield1", assetorg.getLong("id"), 0);//核算组织
+            this.getModel().setValue("asset_costdept", costdept.getLong("id"), 0);//使用部门
         }
     }
 

+ 1012 - 0
src/main/java/fi/fa/formPlugin/FaInventoryTaskListNew.java

@@ -0,0 +1,1012 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package fi.fa.formPlugin;
+
+import com.alibaba.fastjson.JSON;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.EventObject;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import fi.fa.opplugin.utils.ChangeDataUtils;
+import kd.bos.algo.DataSet;
+import kd.bos.algo.Row;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.entity.CloneUtils;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.entity.LocaleString;
+import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
+import kd.bos.dataentity.resource.ResManager;
+import kd.bos.dataentity.serialization.SerializationUtils;
+import kd.bos.db.tx.TX;
+import kd.bos.db.tx.TXHandle;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.MainEntityType;
+import kd.bos.entity.cache.AppCache;
+import kd.bos.entity.cache.IAppCache;
+import kd.bos.entity.datamodel.ListSelectedRow;
+import kd.bos.entity.datamodel.ListSelectedRowCollection;
+import kd.bos.entity.datamodel.events.PackageDataEvent;
+import kd.bos.entity.list.column.ColumnDesc;
+import kd.bos.entity.property.MulBasedataProp;
+import kd.bos.entity.validate.BillStatus;
+import kd.bos.exception.KDBizException;
+import kd.bos.filter.CommonFilterColumn;
+import kd.bos.filter.FilterColumn;
+import kd.bos.form.CloseCallBack;
+import kd.bos.form.ConfirmCallBackListener;
+import kd.bos.form.ConfirmTypes;
+import kd.bos.form.FormShowParameter;
+import kd.bos.form.MessageBoxOptions;
+import kd.bos.form.MessageBoxResult;
+import kd.bos.form.ShowFormHelper;
+import kd.bos.form.ShowType;
+import kd.bos.form.control.Control;
+import kd.bos.form.control.events.ItemClickEvent;
+import kd.bos.form.events.BeforeCreateListColumnsArgs;
+import kd.bos.form.events.BeforeCreateListDataProviderArgs;
+import kd.bos.form.events.ClosedCallBackEvent;
+import kd.bos.form.events.FilterContainerInitArgs;
+import kd.bos.form.events.HyperLinkClickArgs;
+import kd.bos.form.events.HyperLinkClickEvent;
+import kd.bos.form.events.MessageBoxClosedEvent;
+import kd.bos.form.events.PreOpenFormEventArgs;
+import kd.bos.form.events.SetFilterEvent;
+import kd.bos.form.field.ComboItem;
+import kd.bos.fs.util.StringUtils;
+import kd.bos.license.api.LicenseCheckResult;
+import kd.bos.list.BillList;
+import kd.bos.list.IListColumn;
+import kd.bos.list.IListView;
+import kd.bos.list.ListShowParameter;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.mvc.list.ListDataProvider;
+import kd.bos.orm.datamanager.DataManagerUtils;
+import kd.bos.orm.query.QFilter;
+import kd.bos.orm.util.CollectionUtils;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.bos.servicehelper.license.LicenseServiceHelper;
+import kd.bos.servicehelper.operation.DeleteServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.bos.servicehelper.workflow.MessageCenterServiceHelper;
+import kd.bos.url.UrlService;
+import kd.bos.util.JSONUtils;
+import kd.bos.workflow.engine.msg.info.MessageInfo;
+import kd.fi.fa.business.BizStatusEnum;
+import kd.fi.fa.business.utils.FaOperateLogUtil;
+import kd.fi.fa.business.utils.FaUtils;
+import kd.fi.fa.common.util.ContextUtil;
+import kd.fi.fa.common.util.Fa;
+import kd.fi.fa.utils.FaAssetTypeUtils;
+import kd.fi.fa.utils.FaInventoryUtils;
+
+public class FaInventoryTaskListNew extends AbstractListPlugin {
+    private static final Log log = LogFactory.getLog(FaInventoryTaskListNew.class);
+    public static final String ALGOKEY = "kd.fi.fa.formplugin.FaInventoryTaskListNew";
+    private static final int DATA_SIZE = DataManagerUtils.getBatchSize();
+    private static final String ASSIGNINVENTORY = "assigninventory";
+    private Map<Long, Map<String, Set<Long>>> idAndBaseDataMap = new HashMap(16);
+    private Map<String, Map<Long, String>> resultMap = new HashMap(16);
+    private Map<String, Map<String, Object>> baseEntityIdMap = FaInventoryUtils.getBaseEntityIdMap();
+    private Map<String, String> baseNameMap;
+    private Set<String> columnNames;
+    private Map<Long, Map<String, Integer>> map;
+    private Set<String> splitFields;
+
+    public FaInventoryTaskListNew() {
+        this.baseNameMap = new HashMap(this.baseEntityIdMap.size(), 1.0F);
+        this.columnNames = new HashSet(16);
+        this.map = null;
+        this.splitFields = null;
+    }
+
+    public void preOpenForm(PreOpenFormEventArgs e) {
+        LicenseCheckResult result = LicenseServiceHelper.checkByAppAndBizObj("83bfebc800001aac", "fa_inventscheme_new", Long.valueOf(RequestContext.get().getUserId()));
+        if (!result.getHasLicense()) {
+            boolean isConstellation = LicenseServiceHelper.getModeType() == 3;
+            String version = LicenseServiceHelper.getProductVersion();
+            String msg = ResManager.loadKDString("没有财务+供应链+制造分组固定资产许可,请联系管理员。", "FaInventoryTaskList_0", "fi-fa-formplugin", new Object[0]);
+            if (isConstellation) {
+                switch (version) {
+                    case "1.0":
+                    case "2.0":
+                    case "3.0":
+                        msg = ResManager.loadKDString("没有财务会计专业分组许可,请联系管理员。", "FaInventoryTaskList_1", "fi-fa-formplugin", new Object[0]);
+                    case "4.0":
+                }
+            }
+
+            e.setCancel(true);
+            e.setCancelMessage(msg);
+        } else {
+            super.preOpenForm(e);
+        }
+
+    }
+
+    public void filterContainerInit(FilterContainerInitArgs args) {
+        super.filterContainerInit(args);
+        this.setDefaultQuerySelect(args);
+    }
+
+    public void setFilter(SetFilterEvent e) {
+        Map<String, Object> customParams = this.getView().getFormShowParameter().getCustomParams();
+        Object schemeId = customParams.get("schemeId");
+        e.getQFilters().add(new QFilter("status", "!=", "Z"));
+        if (schemeId == null) {
+            e.getQFilters().add(new QFilter("status", "!=", "A"));
+            Long userId = ContextUtil.getUserId();
+            QFilter qfInventory = new QFilter("inventperson", "=", userId);
+            qfInventory.or(new QFilter("inventorychecker.fbasedataid", "=", userId));
+            e.getQFilters().add(qfInventory);
+            this.getView().setVisible(false, new String[]{"inventoryassign"});
+            this.getView().setVisible(false, new String[]{"inventorywithdrawal"});
+            LicenseCheckResult result = LicenseServiceHelper.checkByAppAndBizObj("/OSOW2CPH91+", "fap_apphome", userId);
+            if (result != null && !result.getHasLicense()) {
+                this.getView().setVisible(false, new String[]{"inventorynotice"});
+            }
+        } else {
+            e.getQFilters().add(new QFilter("inventsscopeid.inventschemeentry", "=", schemeId));
+            this.getView().setVisible(false, new String[]{"inventorycreaterecord"});
+            this.getView().setVisible(false, new String[]{"inventorynotice"});
+            this.getView().setVisible(false, new String[]{"inventorydelete"});
+        }
+
+        ArrayList<QFilter> filters = new ArrayList(e.getQFilters());
+        String selectFields = Fa.comma(new String[]{"id", "inventschemeid", "splitfieldvalue", Fa.dot(new String[]{"inventsscopeid", "assetunit", "id"}), "status"});
+        DynamicObjectCollection inventoryTasks = QueryServiceHelper.query("fa_inventory_task", selectFields, (QFilter[])filters.toArray(filters.toArray(new QFilter[0])));
+        this.map = FaInventoryUtils.updateProgress(inventoryTasks);
+        this.splitFields = FaInventoryUtils.getSplitFields(inventoryTasks);
+        this.initbaseNameMap(this.splitFields);
+        this.setColumnVisible(this.splitFields);
+        this.setColumnName();
+    }
+
+    public void click(EventObject evt) {
+        Control c = (Control)evt.getSource();
+        String key = c.getKey();
+        if ("name".equalsIgnoreCase(key)) {
+            Object rowPk = ((IListView)this.getView()).getCurrentSelectedRowInfo().getPrimaryKeyValue();
+            this.viewInventoryRecord(rowPk);
+        }
+
+        super.click(evt);
+    }
+
+    public void billListHyperLinkClick(HyperLinkClickArgs args) {
+        if (!FaUtils.isF7(this.getView())) {
+            BillList billList = (BillList)this.getControl("BillListAp");
+            HyperLinkClickEvent hyperClick = args.getHyperLinkClickEvent();
+            if ("inventsscopeid_assetunit_name".equals(hyperClick.getFieldName())) {
+                Object rowPk = billList.getCurrentSelectedRowInfo().getPrimaryKeyValue();
+                args.setCancel(true);
+                this.viewInventoryRecord(rowPk);
+            }
+        }
+
+    }
+
+    private void viewInventoryRecord(Object rowPk) {
+        String selectFields = "inventschemeid, inventsscopeid.assetunit";
+        QFilter[] filters = new QFilter[]{new QFilter("id", "=", rowPk)};
+        DynamicObject inventTask = QueryServiceHelper.queryOne("fa_inventory_task", selectFields, filters);
+        ListShowParameter parameter = new ListShowParameter();
+        parameter.setFormId("bos_list");
+        parameter.setCaption(ResManager.loadKDString("盘点记录", "FaInventoryTaskList_2", "fi-fa-formplugin", new Object[0]));
+        parameter.setCustomParam("inventorytaskid", rowPk);
+        parameter.setCustomParam("inventschemaid", String.valueOf(inventTask.getLong("inventschemeid")));
+        parameter.setCustomParam("inventassetunitid", String.valueOf(inventTask.getLong("inventsscopeid.assetunit")));
+        Object schemeId = this.getView().getFormShowParameter().getCustomParam("schemeId");
+        parameter.setCustomParam("showAuditBar", schemeId == null);
+        parameter.setBillFormId("fa_inventory_record");
+        parameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
+        this.getView().showForm(parameter);
+    }
+
+    public void beforeCreateListDataProvider(BeforeCreateListDataProviderArgs args) {
+        super.beforeCreateListDataProvider(args);
+        args.setListDataProvider(new FaInventoryTaskListProvide());
+    }
+
+    public void packageData(PackageDataEvent e) {
+        if (e.getSource() instanceof ColumnDesc) {
+            ColumnDesc columnDesc = (ColumnDesc)e.getSource();
+            String columnName = columnDesc.getKey();
+            long rowId = e.getRowData().getLong("id");
+            if (this.baseNameMap.containsKey(columnName)) {
+                Map<String, Set<Long>> baseDataMap = (Map)this.idAndBaseDataMap.get(rowId);
+                if (baseDataMap.size() == 0 || null == baseDataMap.get(this.baseNameMap.get(columnName)) || ((Set)baseDataMap.get(this.baseNameMap.get(columnName))).size() == 0) {
+                    return;
+                }
+
+                Set<Long> ids = (Set)baseDataMap.get(this.baseNameMap.get(columnName));
+                List<String> names = new ArrayList(ids.size());
+                Map<Long, String> idAndNamesMap = (Map)this.resultMap.get(this.baseNameMap.get(columnName));
+                Iterator var10 = ids.iterator();
+
+                while(var10.hasNext()) {
+                    Long id = (Long)var10.next();
+                    names.add(idAndNamesMap.get(id));
+                }
+
+                e.setFormatValue(FaInventoryUtils.getAllNamesString(names));
+            }
+
+            if ("inventprogress".equals(columnName) && !this.map.isEmpty() && this.map.get(rowId) != null) {
+                e.setFormatValue(((Map)this.map.get(rowId)).get("inventRate"));
+            }
+
+            if ("auditprogress".equals(columnName) && !this.map.isEmpty() && this.map.get(rowId) != null) {
+                e.setFormatValue(((Map)this.map.get(rowId)).get("auditRate"));
+            }
+        }
+
+        super.packageData(e);
+    }
+
+    public void itemClick(ItemClickEvent evt) {
+        super.itemClick(evt);
+        String key = evt.getItemKey();
+        IListView view = (IListView)this.getView();
+        String opMsg = ResManager.loadKDString("成功", "FaInventoryTaskList_3", "fi-fa-formplugin", new Object[0]);
+        ListSelectedRowCollection selectedRows = view.getSelectedRows();
+        if (selectedRows.size() < 1 && !key.equals("tblrefresh") && !key.equals("tblclose")) {
+            this.getView().showTipNotification(ResManager.loadKDString("请选择一行操作。", "FaInventoryTaskList_4", "fi-fa-formplugin", new Object[0]));
+        } else {
+            int rowNum;
+            Iterator var8;
+            ListSelectedRow selectedRow;
+            DynamicObject inventoryTask;
+            String assetUnitName;
+            if ("inventorynotice".equals(key)) {
+                rowNum = this.isSchemeClose(selectedRows);
+                if (rowNum != -1) {
+                    this.getView().showTipNotification(String.format(ResManager.loadKDString("任务第%s行:盘点方案已关闭,不能进行盘点通知。", "FaInventoryTaskList_5", "fi-fa-formplugin", new Object[0]), rowNum));
+                } else {
+                    List<Long> inventoryTaskPks = new ArrayList();
+                    var8 = selectedRows.iterator();
+
+                    while(var8.hasNext()) {
+                        selectedRow = (ListSelectedRow)var8.next();
+                        inventoryTask = BusinessDataServiceHelper.loadSingle(String.valueOf(selectedRow), "fa_inventory_task");
+                        assetUnitName = (String)inventoryTask.get("status");
+                        if (!BillStatus.C.toString().equals(assetUnitName)) {
+                            throw new KDBizException(ResManager.loadKDString("请先生成盘点记录。", "FaInventoryTaskList_6", "fi-fa-formplugin", new Object[0]));
+                        }
+
+                        inventoryTaskPks.add((Long)selectedRow.getPrimaryKeyValue());
+                    }
+
+                    try {
+                        this.getPageCache().put("inventoryTaskPks", JSONUtils.toString(inventoryTaskPks));
+                    } catch (IOException var31) {
+                        throw new KDBizException(ResManager.loadKDString("盘点通知有误", "FaInventoryTaskList_7", "fi-fa-formplugin", new Object[0]));
+                    }
+
+                    FormShowParameter para = new FormShowParameter();
+                    para.setFormId("fa_countingreport_message");
+                    para.getOpenStyle().setShowType(ShowType.Modal);
+                    para.setCloseCallBack(new CloseCallBack(this, "getmessage"));
+                    this.getView().showForm(para);
+                }
+            } else {
+                StringBuilder notRightStatus;
+                String unitName;
+                long assetUnitId;
+                if ("inventoryassign".equals(key)) {
+                    rowNum = this.isSchemeClose(selectedRows);
+                    if (rowNum != -1) {
+                        this.getView().showTipNotification(String.format(ResManager.loadKDString("任务第%s行:盘点方案已关闭,不能下达任务。", "FaInventoryTaskList_8", "fi-fa-formplugin", new Object[0]), rowNum));
+                    } else {
+                        notRightStatus = new StringBuilder();
+                        var8 = selectedRows.iterator();
+
+                        while(var8.hasNext()) {
+                            selectedRow = (ListSelectedRow)var8.next();
+                            inventoryTask = BusinessDataServiceHelper.loadSingle(String.valueOf(selectedRow), "fa_inventory_task");
+                            assetUnitName = inventoryTask.getDynamicObject("inventsscopeid").getDynamicObject("assetunit").getString("name");
+                            assetUnitId = inventoryTask.getDynamicObject("inventsscopeid").getDynamicObject("assetunit").getLong("id");
+                            unitName = inventoryTask.getString("status");
+                            if (!BillStatus.A.toString().equals(unitName)) {
+                                notRightStatus.append(assetUnitName).append(' ');
+                                FaOperateLogUtil.addLog("fa_inventory_task", assetUnitId, ResManager.loadKDString("下达任务", "FaInventoryTaskList_9", "fi-fa-formplugin", new Object[0]), String.format(ResManager.loadKDString("%s下达失败,任务状态不是未下达。", "FaInventoryTaskList_10", "fi-fa-formplugin", new Object[0]), assetUnitName));
+                            } else {
+                                inventoryTask.set("status", BillStatus.B.toString());
+                                SaveServiceHelper.save(inventoryTask.getDataEntityType(), new DynamicObject[]{inventoryTask});
+                                FaOperateLogUtil.addLog("fa_inventory_task", assetUnitId, ResManager.loadKDString("下达任务", "FaInventoryTaskList_9", "fi-fa-formplugin", new Object[0]), String.format(ResManager.loadKDString("%s下达任务成功。", "FaInventoryTaskList_11", "fi-fa-formplugin", new Object[0]), assetUnitName));
+                            }
+                        }
+
+                        if (notRightStatus.length() > 0) {
+                            opMsg = String.format(ResManager.loadKDString("%s下达失败,任务状态不是未下达。", "FaInventoryTaskList_10", "fi-fa-formplugin", new Object[0]), notRightStatus);
+                            this.getView().showTipNotification(opMsg);
+                        } else {
+                            opMsg = ResManager.loadKDString("任务下达成功。", "FaInventoryTaskList_12", "fi-fa-formplugin", new Object[0]);
+                            this.getView().showSuccessNotification(opMsg);
+                        }
+
+                        this.getView().invokeOperation("refresh");
+                    }
+                } else if ("inventorywithdrawal".equals(key)) {
+                    rowNum = this.isSchemeClose(selectedRows);
+                    if (rowNum != -1) {
+                        this.getView().showTipNotification(String.format(ResManager.loadKDString("任务第%s行:盘点方案已关闭,不能撤销任务。", "FaInventoryTaskList_13", "fi-fa-formplugin", new Object[0]), rowNum));
+                    } else {
+                        notRightStatus = new StringBuilder();
+                        var8 = selectedRows.iterator();
+
+                        while(var8.hasNext()) {
+                            selectedRow = (ListSelectedRow)var8.next();
+                            inventoryTask = BusinessDataServiceHelper.loadSingle(String.valueOf(selectedRow), "fa_inventory_task");
+                            assetUnitName = inventoryTask.getDynamicObject("inventsscopeid").getDynamicObject("assetunit").getString("name");
+                            assetUnitId = inventoryTask.getDynamicObject("inventsscopeid").getDynamicObject("assetunit").getLong("id");
+                            unitName = inventoryTask.getString("status");
+                            if (!BillStatus.B.toString().equals(unitName)) {
+                                notRightStatus.append(assetUnitName).append(' ');
+                                FaOperateLogUtil.addLog("fa_inventory_task", assetUnitId, ResManager.loadKDString("撤销任务", "FaInventoryTaskList_14", "fi-fa-formplugin", new Object[0]), String.format(ResManager.loadKDString("%s撤销失败,任务状态不是已下达。", "FaInventoryTaskList_15", "fi-fa-formplugin", new Object[0]), assetUnitName));
+                            } else {
+                                inventoryTask.set("status", "A");
+                                inventoryTask.set("inventorychecker", (Object)null);
+                                SaveServiceHelper.save(inventoryTask.getDataEntityType(), new DynamicObject[]{inventoryTask});
+                                FaOperateLogUtil.addLog("fa_inventory_task", assetUnitId, ResManager.loadKDString("撤销任务", "FaInventoryTaskList_14", "fi-fa-formplugin", new Object[0]), String.format(ResManager.loadKDString("%s撤销任务成功。", "FaInventoryTaskList_16", "fi-fa-formplugin", new Object[0]), assetUnitName));
+                            }
+                        }
+
+                        if (notRightStatus.length() > 0) {
+                            opMsg = String.format(ResManager.loadKDString("%s撤销失败,任务状态不是已下达。", "FaInventoryTaskList_15", "fi-fa-formplugin", new Object[0]), notRightStatus);
+                            this.getView().showTipNotification(opMsg);
+                        } else {
+                            opMsg = ResManager.loadKDString("任务撤销成功。", "FaInventoryTaskList_17", "fi-fa-formplugin", new Object[0]);
+                            this.getView().showSuccessNotification(opMsg);
+                        }
+
+                        this.getView().invokeOperation("refresh");
+                    }
+                } else if (!"inventorycreaterecord".equals(key)) {
+                    if ("inventorydelete".equals(key)) {
+                        rowNum = this.isSchemeClose(selectedRows);
+                        if (rowNum != -1) {
+                            this.getView().showTipNotification(String.format(ResManager.loadKDString("任务第%s行:盘点方案已关闭,不能清除盘点记录。", "FaInventoryTaskList_25", "fi-fa-formplugin", new Object[0]), rowNum));
+                        } else {
+                            this.getView().showConfirm(ResManager.loadKDString("此操作将清除任务下所有的盘点记录,是否继续。", "FaInventoryTaskList_26", "fi-fa-formplugin", new Object[0]), "", MessageBoxOptions.YesNo, ConfirmTypes.Delete, new ConfirmCallBackListener("inventorydelete", this));
+                        }
+                    } else {
+                        if ("assigninventory".equals(key)) {
+                            rowNum = this.isSchemeClose(selectedRows);
+                            if (rowNum != -1) {
+                                this.getView().showTipNotification(String.format(ResManager.loadKDString("任务第%s行:盘点方案已关闭,不能指定盘点人。", "FaInventoryTaskList_27", "fi-fa-formplugin", new Object[0]), rowNum));
+                                return;
+                            }
+
+                            this.assignInventory();
+                        }
+
+                    }
+                } else {
+                    rowNum = this.isSchemeClose(selectedRows);
+                    if (rowNum != -1) {
+                        this.getView().showTipNotification(String.format(ResManager.loadKDString("任务第%s行:盘点方案已关闭,不能生成盘点记录。", "FaInventoryTaskList_18", "fi-fa-formplugin", new Object[0]), rowNum));
+                    } else {
+                        notRightStatus = new StringBuilder();
+                        var8 = selectedRows.iterator();
+
+                        while(true) {
+                            while(var8.hasNext()) {
+                                selectedRow = (ListSelectedRow)var8.next();
+                                inventoryTask = BusinessDataServiceHelper.loadSingle(selectedRow.getPrimaryKeyValue(), "fa_inventory_task");
+                                DynamicObject inventorySope = inventoryTask.getDynamicObject("inventsscopeid");
+                                if (inventorySope == null) {
+                                    return;
+                                }
+
+                                String status = inventoryTask.getString("status");
+                                assetUnitId = (long) inventorySope.get("assetunit_id");
+                                unitName = inventoryTask.getDynamicObject("inventsscopeid").getDynamicObject("assetunit").getString("name");
+                                if (!BillStatus.B.toString().equals(status)) {
+                                    notRightStatus.append(unitName).append(' ');
+                                    FaOperateLogUtil.addLog("fa_inventory_task", (Long)assetUnitId, ResManager.loadKDString("生成盘点记录", "FaInventoryTaskList_19", "fi-fa-formplugin", new Object[0]), String.format(ResManager.loadKDString("%s生成失败,任务状态不是已下达。", "FaInventoryTaskList_20", "fi-fa-formplugin", new Object[0]), unitName));
+                                } else {
+                                    MainEntityType inventoryRecordType = EntityMetadataCache.getDataEntityType("fa_inventory_record");
+                                    Date finaccountdate = inventorySope.getDate("finaccountdate");
+                                    QFilter timeLimitCond = new QFilter("realaccountdate", "<=", finaccountdate);
+                                    QFilter billstatusCond = new QFilter("billstatus", "=", BillStatus.C.toString());
+                                    QFilter assetunitCond = new QFilter("assetunit_id", "=", assetUnitId);
+                                    QFilter bizstatusDeleteCond = new QFilter("bizstatus", "!=", BizStatusEnum.DELETE);
+                                    QFilter notIsBackAndOther = new QFilter("isbak", "=", false);
+                                    String splitfieldvalue = inventoryTask.getString("splitfieldvalue");
+                                    if (!StringUtils.isBlank(splitfieldvalue)) {
+                                        Map<String, Object> maps = (Map)JSON.parse(splitfieldvalue);
+                                        Iterator<Map.Entry<String, Object>> it = maps.entrySet().iterator();
+
+                                        while(it.hasNext()) {
+                                            Map.Entry<String, Object> entry = (Map.Entry)it.next();
+                                            String keySet = (String)entry.getKey();
+                                            Object valueSet = entry.getValue();
+                                            if (valueSet != null) {
+                                                List<Long> idList = null;
+                                                String assetcatIds = (String)valueSet;
+                                                if (!StringUtils.isBlank(assetcatIds)) {
+                                                    Set<Long> idSet = (Set)Arrays.asList(assetcatIds.split(",")).stream().map((s) -> {
+                                                        return Long.parseLong(StringUtils.isBlank(s) ? "0" : s.trim());
+                                                    }).collect(Collectors.toSet());
+                                                    idList = new ArrayList(idSet);
+                                                    if (idList.size() == 1 && ((Long)idList.get(0)).equals(0L)) {
+                                                        idList = null;
+                                                    }
+                                                }
+
+                                                QFilter assetIds = null;
+                                                if (idList != null) {
+                                                    if ("assetcat".equals(keySet)) {
+                                                        assetIds = new QFilter("assetcat_id", "in", FaAssetTypeUtils.getAllSubAssetTypes(idList));
+                                                    } else {
+                                                        assetIds = new QFilter(keySet + "_id", "in", idList);
+                                                    }
+                                                }
+
+                                                if (assetIds != null) {
+                                                    notIsBackAndOther.and(assetIds);
+                                                }
+                                            }
+                                        }
+                                    }
+
+                                    String sicOnlyId = Fa.join(",", new String[]{"id"});
+                                    String sic = Fa.join(",", new String[]{"id,number,barcode,assetname,model,assetamount,unit,headuseperson,nckd_storeplace"});
+                                    DynamicObjectCollection realCards = QueryServiceHelper.query("fa_card_real", sicOnlyId, new QFilter[]{assetunitCond, timeLimitCond, billstatusCond, bizstatusDeleteCond, notIsBackAndOther});
+                                    Set<Long> cardIds = new HashSet();
+                                    Iterator var43 = realCards.iterator();
+
+                                    while(var43.hasNext()) {
+                                        DynamicObject realCard = (DynamicObject)var43.next();
+                                        cardIds.add(realCard.getLong("id"));
+                                    }
+
+                                    int i = 0;
+                                    Set<Long> cardId = new HashSet();
+
+                                    try {
+                                        Iterator<Long> ite = cardIds.iterator();
+
+                                        while(ite.hasNext()) {
+                                            if (i == DATA_SIZE) {
+                                                this.createInventoryRedords(inventoryRecordType, inventoryTask, sic, cardId);
+                                                cardId = new HashSet();
+                                                i = 0;
+                                            } else {
+                                                cardId.add(ite.next());
+                                                ++i;
+                                            }
+                                        }
+
+                                        if (!cardId.isEmpty()) {
+                                            this.createInventoryRedords(inventoryRecordType, inventoryTask, sic, cardId);
+                                        }
+
+                                        inventoryTask.set("status", "C");
+                                        SaveServiceHelper.save(inventoryTask.getDataEntityType(), new DynamicObject[]{inventoryTask});
+                                        FaOperateLogUtil.addLog("fa_inventory_task", (Long)assetUnitId, ResManager.loadKDString("生成盘点记录", "FaInventoryTaskList_19", "fi-fa-formplugin", new Object[0]), String.format(ResManager.loadKDString("%s生成盘点记录成功。", "FaInventoryTaskList_21", "fi-fa-formplugin", new Object[0]), unitName));
+                                    } catch (Exception var32) {
+                                        FaOperateLogUtil.addLog("fa_inventory_task", (Long)assetUnitId, ResManager.loadKDString("生成盘点记录", "FaInventoryTaskList_19", "fi-fa-formplugin", new Object[0]), String.format(ResManager.loadKDString("%1$s生成盘点记录事务失败,联系管理员查看日志:%2$s。", "FaInventoryTaskList_22", "fi-fa-formplugin", new Object[0]), unitName, var32.getMessage()));
+                                        throw new KDBizException(String.format(ResManager.loadKDString("%1$s生成盘点记录事务失败,联系管理员查看日志:%2$s。", "FaInventoryTaskList_22", "fi-fa-formplugin", new Object[0]), unitName, var32.getMessage()));
+                                    }
+                                }
+                            }
+
+                            if (notRightStatus.length() > 0) {
+                                int unSuccess = notRightStatus.toString().split(" ").length;
+                                int success = selectedRows.size() - unSuccess;
+                                this.getView().showTipNotification(String.format(ResManager.loadKDString("成功%1$d条,失败%2$d条,其中[%3$s]生成失败,任务状态不是已下达。", "FaInventoryTaskList_23", "fi-fa-formplugin", new Object[0]), success, unSuccess, notRightStatus));
+                            } else {
+                                this.getView().showSuccessNotification(ResManager.loadKDString("生成盘点记录成功。", "FaInventoryTaskList_24", "fi-fa-formplugin", new Object[0]));
+                            }
+
+                            this.getView().invokeOperation("refresh");
+                            return;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private int isSchemeClose(ListSelectedRowCollection selectedRows) {
+        DynamicObject[] selectDynamicObject = this.getSelectDynamicObjcet();
+        DynamicObject[] var3 = selectDynamicObject;
+        int var4 = selectDynamicObject.length;
+
+        for(int var5 = 0; var5 < var4; ++var5) {
+            DynamicObject selectDO = var3[var5];
+            if ("C".equals(selectDO.getString("inventschemeid.billstate"))) {
+                Iterator var7 = selectedRows.iterator();
+
+                while(var7.hasNext()) {
+                    ListSelectedRow selectRow = (ListSelectedRow)var7.next();
+                    if (selectDO.getLong("id") == (Long)selectRow.getPrimaryKeyValue()) {
+                        return selectRow.getRowKey() + 1;
+                    }
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    private void assignInventory() {
+        DynamicObject[] selectDys = this.getSelectDynamicObjcet();
+        if (selectDys != null) {
+            long userId = ContextUtil.getUserId();
+            DynamicObject[] var4 = selectDys;
+            int var5 = selectDys.length;
+
+            for(int var6 = 0; var6 < var5; ++var6) {
+                DynamicObject dy = var4[var6];
+                if (userId != dy.getLong("inventperson_id") && userId != dy.getDynamicObject("inventschemeid").getDynamicObject("creator").getLong("id")) {
+                    this.getView().showTipNotification(ResManager.loadKDString("只允许盘点负责人和方案创建人指定盘点人。", "FaInventoryTaskList_28", "fi-fa-formplugin", new Object[0]));
+                    return;
+                }
+            }
+
+            this.showUserForm();
+        }
+    }
+
+    private void showUserForm() {
+        ListShowParameter param = ShowFormHelper.createShowListForm("bos_user", true);
+        param.setCloseCallBack(new CloseCallBack(this, "assigninventory"));
+        param.setCustomParam("skipCheckSelectRows", true);
+        DynamicObject[] selectDys = this.getSelectDynamicObjcet();
+        List<Long> selectids = new ArrayList(10);
+        Arrays.asList(selectDys).stream().forEach((v) -> {
+            List<Long> collect = (List)v.getDynamicObjectCollection("inventorychecker").stream().map((t) -> {
+                return t.getLong("fbasedataid_id");
+            }).collect(Collectors.toList());
+            selectids.addAll(collect);
+        });
+        param.setSelectedRows(selectids.toArray());
+        this.getView().showForm(param);
+    }
+
+    private void createInventoryRedords(MainEntityType inventoryRecordType, DynamicObject inventoryTask, String sic, Set<Long> cardId) {
+        TXHandle h = TX.requiresNew();
+        Throwable var6 = null;
+
+        try {
+            try {
+                DynamicObjectCollection realCards = QueryServiceHelper.query("fa_card_real", sic, new QFilter[]{new QFilter("id", "in", cardId)});
+                DynamicObject inventoryRecordEntity = (DynamicObject)inventoryRecordType.createInstance();
+                List<DynamicObject> inventoryRecordList = new ArrayList();
+                Iterator var10 = realCards.iterator();
+
+                while(var10.hasNext()) {
+                    DynamicObject realCard = (DynamicObject)var10.next();
+                    DynamicObject fin = ChangeDataUtils.queryFinCard(realCard.getLong("id"));
+                    DynamicObject inventoryRecordInstance = (DynamicObject)(new CloneUtils(false, true)).clone(inventoryRecordType, inventoryRecordEntity);
+                    inventoryRecordInstance.set("realCard_id", realCard.get("id"));
+                    inventoryRecordInstance.set("number", realCard.getString("number"));
+                    inventoryRecordInstance.set("barcode", realCard.getString("barcode"));
+                    inventoryRecordInstance.set("name", realCard.getString("assetname"));
+                    inventoryRecordInstance.set("model", realCard.getString("model"));
+                    inventoryRecordInstance.set("bookquantity", realCard.getBigDecimal("assetamount"));
+                    inventoryRecordInstance.set("unit_id", realCard.get("unit"));
+                    inventoryRecordInstance.set("inventoryquantity", BigDecimal.ZERO);
+                    inventoryRecordInstance.set("difference", BigDecimal.ZERO);
+                    inventoryRecordInstance.set("inventorystate", BillStatus.B.toString());
+                    inventoryRecordInstance.set("reason", "1 ");
+                    inventoryRecordInstance.set("inventorytask_id", inventoryTask.getPkValue());
+                    inventoryRecordInstance.set("inventschemeentry_id", inventoryTask.getDynamicObject("inventsscopeid").getDynamicObject("inventschemeentry").getPkValue());
+                    inventoryRecordInstance.set("billstatus", "C");
+                    inventoryRecordInstance.set("billstate", "A");
+                    inventoryRecordInstance.set("nckd_storeplace", realCard.getString("nckd_storeplace"));
+                    inventoryRecordInstance.set("nckd_fincard_id", fin != null ? fin.getLong("id") : null);
+                    inventoryRecordList.add(inventoryRecordInstance);
+                }
+
+                if (inventoryRecordList.size() > 0) {
+                    SaveServiceHelper.save(inventoryRecordType, inventoryRecordList.toArray(new DynamicObject[0]));
+                }
+            } catch (Throwable var21) {
+                h.markRollback();
+                throw var21;
+            }
+        } catch (Throwable var22) {
+            var6 = var22;
+            throw var22;
+        } finally {
+            if (h != null) {
+                if (var6 != null) {
+                    try {
+                        h.close();
+                    } catch (Throwable var20) {
+                        var6.addSuppressed(var20);
+                    }
+                } else {
+                    h.close();
+                }
+            }
+
+        }
+
+    }
+
+    public void confirmCallBack(MessageBoxClosedEvent messageBoxClosedEvent) {
+        super.confirmCallBack(messageBoxClosedEvent);
+        IListView view = (IListView)this.getView();
+        ListSelectedRowCollection selectedRows = view.getSelectedRows();
+        String callBackId = messageBoxClosedEvent.getCallBackId();
+        if ("inventorydelete".equals(callBackId) && MessageBoxResult.Yes.equals(messageBoxClosedEvent.getResult())) {
+            StringBuilder notRightStatus = new StringBuilder();
+            StringBuilder notBillStatus = new StringBuilder();
+            Iterator var7 = selectedRows.iterator();
+
+            while(var7.hasNext()) {
+                ListSelectedRow selectedRow = (ListSelectedRow)var7.next();
+                DynamicObject inventoryTask = BusinessDataServiceHelper.loadSingle(String.valueOf(selectedRow), "fa_inventory_task");
+                DynamicObject inventorySope = inventoryTask.getDynamicObject("inventsscopeid");
+                if (inventorySope == null) {
+                    return;
+                }
+
+                Object assetunitId = inventorySope.get("assetunit_id");
+                String assetUnitName = inventorySope.getDynamicObject("assetunit").getString("name");
+                String status = inventoryTask.getString("status");
+                if (!BillStatus.C.toString().equals(status)) {
+                    notRightStatus.append(assetUnitName).append(' ');
+                    FaOperateLogUtil.addLog("fa_inventory_task", (Long)assetunitId, ResManager.loadKDString("清除盘点记录", "FaInventoryTaskList_29", "fi-fa-formplugin", new Object[0]), String.format(ResManager.loadKDString("%s删除盘点记录失败,任务状态不是已生成。", "FaInventoryTaskList_30", "fi-fa-formplugin", new Object[0]), assetUnitName));
+                } else {
+                    QFilter qfBillStatus = new QFilter("billstate", "=", "C");
+                    QFilter qfInventoryTask = new QFilter("inventorytask", "=", inventoryTask.getPkValue());
+                    boolean exists = QueryServiceHelper.exists("fa_inventory_record", new QFilter[]{qfInventoryTask, qfBillStatus});
+                    if (exists) {
+                        notBillStatus.append(assetUnitName).append(' ');
+                        FaOperateLogUtil.addLog("fa_inventory_task", (Long)assetunitId, ResManager.loadKDString("清除盘点记录", "FaInventoryTaskList_29", "fi-fa-formplugin", new Object[0]), String.format(ResManager.loadKDString("%s删除盘点记录失败,存在已审核的盘点记录。", "FaInventoryTaskList_31", "fi-fa-formplugin", new Object[0]), assetUnitName));
+                    } else {
+                        Object inventoryTaskPk = selectedRow.getPrimaryKeyValue();
+                        QFilter inventoryTaskPkCond = new QFilter("inventorytask_id", "=", inventoryTaskPk);
+                        DeleteServiceHelper.delete("fa_inventory_record", new QFilter[]{inventoryTaskPkCond});
+                        QFilter qInventoryTaskPk = new QFilter("inventorytask_id", "=", inventoryTaskPk);
+                        DeleteServiceHelper.delete("fa_inventory_entrust", new QFilter[]{qInventoryTaskPk});
+                        inventoryTask.set("status", BillStatus.B.toString());
+                        SaveServiceHelper.save(inventoryTask.getDataEntityType(), new DynamicObject[]{inventoryTask});
+                        FaOperateLogUtil.addLog("fa_inventory_task", (Long)assetunitId, ResManager.loadKDString("清除盘点记录", "FaInventoryTaskList_29", "fi-fa-formplugin", new Object[0]), String.format(ResManager.loadKDString("%s删除盘点记录成功。", "FaInventoryTaskList_32", "fi-fa-formplugin", new Object[0]), assetUnitName));
+                    }
+                }
+            }
+
+            if (notBillStatus.length() > 0) {
+                this.getView().showTipNotification(String.format(ResManager.loadKDString("%s删除盘点记录失败,存在已审核的盘点记录。", "FaInventoryTaskList_31", "fi-fa-formplugin", new Object[0]), notRightStatus));
+            } else if (notRightStatus.length() > 0) {
+                this.getView().showTipNotification(String.format(ResManager.loadKDString("%s删除盘点记录失败,任务状态不是已生成。", "FaInventoryTaskList_33", "fi-fa-formplugin", new Object[0]), notRightStatus));
+            } else {
+                this.getView().showSuccessNotification(String.format(ResManager.loadKDString("%s删除盘点记录成功。", "FaInventoryTaskList_32", "fi-fa-formplugin", new Object[0]), ""));
+            }
+
+            this.getView().invokeOperation("refresh");
+        }
+
+    }
+
+    public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
+        super.closedCallBack(closedCallBackEvent);
+        Object returnData = closedCallBackEvent.getReturnData();
+        if (returnData != null) {
+            if (!"assigninventory".equals(closedCallBackEvent.getActionId())) {
+                if ("getmessage".equals(closedCallBackEvent.getActionId())) {
+                    IAppCache cacheDepreCheck = AppCache.get("fa");
+                    String title = (String)cacheDepreCheck.get("countingreport_message_title", String.class);
+                    this.sendMessage(returnData.toString(), title);
+                }
+
+            } else {
+                DynamicObjectCollection proto = this.buildMulBasedata((ListSelectedRowCollection)returnData);
+                DynamicObject[] selectDys = this.getSelectDynamicObjcet();
+                CloneUtils c = new CloneUtils(true, true);
+                DynamicObject[] var7 = selectDys;
+                int var8 = selectDys.length;
+
+                for(int var9 = 0; var9 < var8; ++var9) {
+                    DynamicObject dy = var7[var9];
+                    List<DynamicObject> collection = new ArrayList(10);
+                    Iterator var11 = proto.iterator();
+
+                    while(var11.hasNext()) {
+                        DynamicObject protoDy = (DynamicObject)var11.next();
+                        collection.add((DynamicObject)c.clone(((DynamicObject)proto.get(0)).getDataEntityType(), protoDy));
+                    }
+
+                    dy.set("inventorychecker", collection);
+                }
+
+                SaveServiceHelper.save(selectDys);
+                this.getView().updateView();
+            }
+        }
+    }
+
+    private DynamicObjectCollection buildMulBasedata(ListSelectedRowCollection selectedRows) {
+        DynamicObjectCollection collection = new DynamicObjectCollection();
+        MainEntityType mainInventory = EntityMetadataCache.getDataEntityType("fa_inventory_task");
+        MulBasedataProp mulBasedataProp = (MulBasedataProp)mainInventory.findProperty("inventorychecker");
+        DynamicObjectType dynamicCollectionItemPropertyType = mulBasedataProp.getDynamicCollectionItemPropertyType();
+        Iterator var6 = selectedRows.iterator();
+
+        while(var6.hasNext()) {
+            ListSelectedRow row = (ListSelectedRow)var6.next();
+            DynamicObject dy = new DynamicObject(dynamicCollectionItemPropertyType);
+            dy.set("fbasedataid", row.getPrimaryKeyValue());
+            dy.set("fbasedataid_id", row.getPrimaryKeyValue());
+            collection.add(dy);
+        }
+
+        return collection;
+    }
+
+    public static void inventoryAssign(Object[] pkArray) {
+        QFilter filtersPk = new QFilter("id", "in", pkArray);
+        DynamicObject[] inventoryTasks = BusinessDataServiceHelper.load("fa_inventory_task", "status", new QFilter[]{filtersPk});
+        List<DynamicObject> inventoryTasksNeedChange = new ArrayList(inventoryTasks.length);
+        DynamicObject[] var4 = inventoryTasks;
+        int var5 = inventoryTasks.length;
+
+        for(int var6 = 0; var6 < var5; ++var6) {
+            DynamicObject inventoryTask = var4[var6];
+            inventoryTask.set("status", BillStatus.B.toString());
+            inventoryTasksNeedChange.add(inventoryTask);
+        }
+
+        if (inventoryTasksNeedChange.size() > 0) {
+            SaveServiceHelper.save(((DynamicObject)inventoryTasksNeedChange.get(0)).getDataEntityType(), inventoryTasksNeedChange.toArray());
+        }
+
+    }
+
+    private void sendMessage(String content, String title) {
+        MessageInfo message = new MessageInfo();
+        message.setType("message");
+        if (StringUtils.isNotEmpty(title)) {
+            message.setTitle(title);
+        } else {
+            message.setTitle(ResManager.loadKDString("人人资产-盘点", "FaInventoryTaskList_34", "fi-fa-formplugin", new Object[0]));
+        }
+
+        List<Long> inventoryTaskPks = (List)SerializationUtils.fromJsonString(String.valueOf(this.getPageCache().get("inventoryTaskPks")), List.class);
+        Iterator var5 = inventoryTaskPks.iterator();
+
+        while(var5.hasNext()) {
+            Long inventoryTaskPk = (Long)var5.next();
+            List<Long> assetInventors = this.getAssetInventors(inventoryTaskPk);
+            message.setUserIds(assetInventors);
+            message.setSenderId(ContextUtil.getUserId());
+            message.setSendTime(new Date(System.currentTimeMillis()));
+            message.setEntityNumber("fa_inventory_task");
+            message.setBizDataId(inventoryTaskPk);
+            message.setTag(ResManager.loadKDString("人人资产", "FaInventoryTaskList_35", "fi-fa-formplugin", new Object[0]));
+            String clientUrl = UrlService.getDomainContextUrl();
+            StringBuilder urlWithEncodedParams = new StringBuilder(clientUrl);
+            if (!clientUrl.trim().endsWith("/")) {
+                urlWithEncodedParams.append("/");
+            }
+
+            String strMobContentUrl = "%sintegration/yzjShareOpen.do?mb_formId=fa_mobile_inventpage&pkId=%s&device=mob&accountId=%s";
+            message.setMobContentUrl(String.format(strMobContentUrl, urlWithEncodedParams.toString(), inventoryTaskPk, RequestContext.get().getAccountId()));
+            log.info("FaInventoryTaskList-message-MobContentUrl-is " + message.getMobContentUrl());
+            String strContentUrl = "%sindex.html?formId=fa_inventory_task&pkId=%s";
+            message.setContentUrl(String.format(strContentUrl, urlWithEncodedParams.toString(), inventoryTaskPk));
+            log.info("FaInventoryTaskList-message-ContentUrl-is " + message.getContentUrl());
+            message.setContent(content);
+            log.info("FaInventoryTaskList-message-Content-is " + message.getContent());
+            message.setPubaccNumber("systempubacc");
+            MessageCenterServiceHelper.sendMessage(message);
+            this.getView().showMessage(ResManager.loadKDString("发送普通消息给“系统级消息助手”成功。", "FaInventoryTaskList_36", "fi-fa-formplugin", new Object[0]));
+        }
+
+    }
+
+    private List<Long> getAssetInventors(Long inventoryTaskPk) {
+        Set<Long> assetInventors = new HashSet();
+        String sic = Fa.join(",", new String[]{"realcard.headuseperson.id"});
+        QFilter filters1 = new QFilter("inventorytask", "=", inventoryTaskPk);
+        filters1.and("inventorystate", "=", BillStatus.B);
+        DataSet dataSet = QueryServiceHelper.queryDataSet(FaInventoryTaskListNew.class.getName(), "fa_inventory_record", sic, new QFilter[]{filters1}, (String)null);
+        Iterator var6 = dataSet.iterator();
+
+        while(var6.hasNext()) {
+            Row row = (Row)var6.next();
+            assetInventors.add(row.getLong("realcard.headuseperson.id"));
+        }
+
+        return new ArrayList(assetInventors);
+    }
+
+    public void beforeBindData(EventObject e) {
+        super.beforeBindData(e);
+    }
+
+    private void setDefaultQuerySelect(FilterContainerInitArgs filtercontainerinitargs) {
+        List<FilterColumn> listFilterColumns = filtercontainerinitargs.getFilterContainerInitEvent().getCommonFilterColumns();
+        Map<String, Object> customParams = this.getView().getFormShowParameter().getCustomParams();
+        Object schemeId = customParams.get("schemeId");
+        Long userId = ContextUtil.getUserId();
+        List<ComboItem> comboItemsStatus = new ArrayList();
+        ComboItem a = new ComboItem(new LocaleString(ResManager.loadKDString("未下达", "FaInventoryTaskList_37", "fi-fa-formplugin", new Object[0])), BillStatus.A.toString());
+        ComboItem b = new ComboItem(new LocaleString(ResManager.loadKDString("已下达", "FaInventoryTaskList_38", "fi-fa-formplugin", new Object[0])), BillStatus.B.toString());
+        ComboItem c = new ComboItem(new LocaleString(ResManager.loadKDString("已生成", "FaInventoryTaskList_39", "fi-fa-formplugin", new Object[0])), "C");
+        if (schemeId != null) {
+            this.getPageCache().put("schemeIds", SerializationUtils.serializeToBase64(schemeId));
+            ListIterator<FilterColumn> deleteListFilterColumns = listFilterColumns.listIterator();
+
+            while(deleteListFilterColumns.hasNext()) {
+                String fieldName = ((FilterColumn)deleteListFilterColumns.next()).getFieldName();
+                if ("inventsscopeid.inventschemeentry.name".equals(fieldName)) {
+                    deleteListFilterColumns.remove();
+                }
+            }
+
+        } else {
+            Iterator var29 = listFilterColumns.iterator();
+
+            while(true) {
+                while(var29.hasNext()) {
+                    FilterColumn listFilter = (FilterColumn)var29.next();
+                    CommonFilterColumn commFilter = (CommonFilterColumn)listFilter;
+                    String fieldName = commFilter.getFieldName();
+                    if ("inventsscopeid.inventschemeentry.name".equals(fieldName)) {
+                        Set<ComboItem> comboItemsTrys = new HashSet();
+                        QFilter filtersUserid = new QFilter("inventperson", "=", userId);
+                        filtersUserid.or(new QFilter("inventorychecker.fbasedataid", "=", userId));
+                        QFilter filterStatus = new QFilter("status", "!=", "A");
+                        QFilter filterStatusZ = new QFilter("status", "!=", "Z");
+                        DynamicObjectCollection invenTasks = QueryServiceHelper.query("fa_inventory_task", "inventsscopeid", new QFilter[]{filtersUserid, filterStatus, filterStatusZ});
+                        Set<Long> scopeIds = (Set)invenTasks.stream().map((s) -> {
+                            return s.getLong("inventsscopeid");
+                        }).collect(Collectors.toSet());
+                        QFilter scopeIdsQ = new QFilter("id", "in", scopeIds);
+                        DynamicObjectCollection invenschemeetry = QueryServiceHelper.query("fa_inventory_sope", "inventschemeentry", new QFilter[]{scopeIdsQ}, "createtime desc");
+                        Set<Long> schemeIds = (Set)invenschemeetry.stream().map((s) -> {
+                            return s.getLong("inventschemeentry");
+                        }).collect(Collectors.toSet());
+                        this.getPageCache().put("schemeIds", SerializationUtils.serializeToBase64(schemeIds));
+                        QFilter schemeIdsQ = new QFilter("id", "in", schemeIds);
+                        DynamicObjectCollection inventschemes = QueryServiceHelper.query("fa_inventscheme_new", "id,name,entryentity.splitfieldentity.splitfield splitfield", new QFilter[]{schemeIdsQ}, "createtime desc");
+                        Iterator var25 = inventschemes.iterator();
+
+                        while(var25.hasNext()) {
+                            DynamicObject inventscheme = (DynamicObject)var25.next();
+                            ComboItem item = new ComboItem(new LocaleString(inventscheme.getString("name")), inventscheme.getString("id"));
+                            comboItemsTrys.add(item);
+                        }
+
+                        if (!CollectionUtils.isEmpty(inventschemes)) {
+                            commFilter.setDefaultValue(((DynamicObject)inventschemes.get(0)).getString("id"));
+                        }
+
+                        List<ComboItem> allInventoryName = new ArrayList(comboItemsTrys);
+                        commFilter.setComboItems(allInventoryName);
+                        commFilter.setMustInput(true);
+                    } else if ("status".equals(fieldName)) {
+                        comboItemsStatus.add(a);
+                        comboItemsStatus.add(b);
+                        comboItemsStatus.add(c);
+                        commFilter.setComboItems(comboItemsStatus);
+                    }
+                }
+
+                return;
+            }
+        }
+    }
+
+    private DynamicObject[] getSelectDynamicObjcet() {
+        QFilter qfIds = new QFilter("id", "in", this.getSelectedRows().getPrimaryKeyValues());
+        return BusinessDataServiceHelper.load("fa_inventory_task", "inventorychecker,inventperson,inventschemeid", new QFilter[]{qfIds});
+    }
+
+    private void initbaseNameMap(Set<String> splitfields) {
+        int k = 0;
+        Iterator var3 = splitfields.iterator();
+
+        while(var3.hasNext()) {
+            String splitfield = (String)var3.next();
+            String columnName = "entrytext" + k++;
+            this.baseNameMap.put(columnName, splitfield);
+        }
+
+    }
+
+    private void setColumnVisible(Set<String> splitfields) {
+        Iterator var2 = splitfields.iterator();
+
+        while(var2.hasNext()) {
+            String splitfield = (String)var2.next();
+            Iterator var4 = this.baseNameMap.entrySet().iterator();
+
+            while(var4.hasNext()) {
+                Map.Entry<String, String> entry = (Map.Entry)var4.next();
+                if (splitfield.equals(entry.getValue())) {
+                    this.columnNames.add(entry.getKey());
+                }
+            }
+        }
+
+        BillList list = (BillList)this.getControl("billlistap");
+        FaInventoryUtils.setColumnVisible(list.getView(), this.columnNames);
+    }
+
+    private void setColumnName() {
+        BillList billList = (BillList)this.getView().getControl("billlistap");
+        BeforeCreateListColumnsArgs args = billList.getBeforeCreateListColumnsArgs();
+        if (null != args) {
+            Iterator var3 = this.columnNames.iterator();
+
+            while(var3.hasNext()) {
+                String columnName = (String)var3.next();
+                String entityId = (String)this.baseNameMap.get(columnName);
+                Map<String, Object> map = (Map)this.baseEntityIdMap.get(entityId);
+                IListColumn listColumn = billList.getBeforeCreateListColumnsArgs().getListColumn(columnName);
+                if (null != listColumn && null != map.get("displayName")) {
+                    listColumn.setCaption((LocaleString)map.get("displayName"));
+                }
+            }
+
+        }
+    }
+
+    private class FaInventoryTaskListProvide extends ListDataProvider {
+        private FaInventoryTaskListProvide() {
+        }
+
+        public DynamicObjectCollection getData(int start, int limit) {
+            DynamicObjectCollection rows = super.getData(start, limit);
+            Map<String, Set<Long>> queryMap = new HashMap(FaInventoryTaskListNew.this.baseEntityIdMap.size(), 1.0F);
+            Iterator var5 = FaInventoryTaskListNew.this.baseEntityIdMap.keySet().iterator();
+
+            while(var5.hasNext()) {
+                String s = (String)var5.next();
+                queryMap.put(s, new HashSet());
+            }
+
+            var5 = rows.iterator();
+
+            while(var5.hasNext()) {
+                DynamicObject row = (DynamicObject)var5.next();
+                Map<String, Set<Long>> baseDataMap = new HashMap(16);
+                String splitFieldObj = row.getString("splitfieldvalue");
+                if (StringUtils.isNotEmpty(splitFieldObj)) {
+                    baseDataMap = FaInventoryUtils.transferSplitFieldValue(splitFieldObj);
+                }
+
+                Iterator var9 = ((Map)baseDataMap).entrySet().iterator();
+
+                while(var9.hasNext()) {
+                    Map.Entry<String, Set<Long>> entry = (Map.Entry)var9.next();
+                    Set<Long> ids = (Set)queryMap.get(entry.getKey());
+                    ids.addAll((Collection)entry.getValue());
+                    queryMap.put(entry.getKey(), ids);
+                }
+
+                FaInventoryTaskListNew.this.idAndBaseDataMap.put(row.getLong("id"), baseDataMap);
+            }
+
+            FaInventoryUtils.setResultMapValue(queryMap, FaInventoryTaskListNew.this.baseEntityIdMap, FaInventoryTaskListNew.this.resultMap);
+            return rows;
+        }
+    }
+}

+ 140 - 80
src/main/java/fi/fa/opplugin/AssetMidBillOpPlugin.java

@@ -2,106 +2,166 @@ package fi.fa.opplugin;
 
 import com.alibaba.druid.util.StringUtils;
 import fi.fa.opplugin.utils.ChangeDataUtils;
+import kd.bos.bill.BillShowParameter;
 import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.entity.datamodel.ListSelectedRowCollection;
 import kd.bos.entity.operate.result.OperationResult;
-import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
-import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
-import kd.bos.exception.KDBizException;
+import kd.bos.form.FormShowParameter;
+import kd.bos.form.ShowType;
+import kd.bos.form.control.events.ItemClickEvent;
+import kd.bos.list.BillList;
+import kd.bos.list.plugin.AbstractListPlugin;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.operation.OperationServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
+import java.math.BigDecimal;
+import java.util.EventObject;
 import java.util.List;
 
 //资产调出单中间表下推资产调出单
-public class AssetMidBillOpPlugin extends AbstractOperationServicePlugIn {
+public class AssetMidBillOpPlugin extends AbstractListPlugin {
+
+    public void registerListener(EventObject e) {
+        super.registerListener(e);
+        this.addItemClickListeners(new String[]{"toolbarap"});
+    }
+
     @Override
-    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
-        super.beginOperationTransaction(e);
-        DynamicObject[] dynamicObjects = e.getDataEntities();
-        for (int i = 0; i < dynamicObjects.length; i++) {
-            if (StringUtils.equals(e.getOperationKey(), "push")) {
-                DynamicObject info = BusinessDataServiceHelper.loadSingle(dynamicObjects[i].getPkValue(), dynamicObjects[i].getDynamicObjectType().getName());
-                String nckd_flag = info.getString("nckd_flag");
-                if ("1".equals(nckd_flag)) {
-                    throw new KDBizException("单据" + info.getString("number") + "已经下推生成了资产调拨单,不允许重复下推!");
-                }else {
-                    String dispatchType = info.getString("nckd_dispatch_type");
+    public void itemClick(ItemClickEvent evt) {
+        String itemKey = evt.getItemKey();
+        if ("nckd_push".equals(itemKey)) {
+            StringBuilder errMsg = new StringBuilder();
+            BillList billList = (BillList) this.getControl("billlistap");
+            ListSelectedRowCollection list = billList.getSelectedRows();
+            Object[] primaryKeyValues = list.getPrimaryKeyValues();
+            if (primaryKeyValues.length > 0) {
+                for (Object pk : primaryKeyValues) {
+                    DynamicObject info = BusinessDataServiceHelper.loadSingle(pk, "nckd_e_dispatch_mid");
+                    String nckd_flag = info.getString("nckd_flag");
                     String direction = info.getString("nckd_direction");
+                    if ("1".equals(nckd_flag)) {
+                        errMsg.append("单据号: ").append(info.getString("number")).append("已经下推生成了业务处理单,不允许重复下推!");
+                        errMsg.append("\r\n");
+                        continue;
+                    }
                     String error = ChangeDataUtils.check(info);
                     if (!StringUtils.isEmpty(error)) {
-                        this.operationResult.setShowMessage(true);
-                        this.operationResult.setSuccess(false);
-                        this.operationResult.setMessage(error);
-                    }else {
-                        List<String> codeList = ChangeDataUtils.getCardNumber(info);
-                        if ("0".equals(dispatchType)) {
-                            QFilter filter = new QFilter("number", QCP.in,codeList);
-                            filter.and("isbak",  QCP.equals, "0");
-                            DynamicObject[] card = BusinessDataServiceHelper.load("fa_card_real","id",new QFilter[] {filter});
-                            DynamicObject dispatch = BusinessDataServiceHelper.newDynamicObject("fa_dispatch");
-                            //单据头
-                            dispatch.set("dispatchdate", info.getDate("nckd_date_out"));//调出日期
-                            dispatch.set("assetunit", ChangeDataUtils.getOrg(info.getString("nckd_org_out")));//调出组织
-                            dispatch.set("inassetunit", ChangeDataUtils.getOrg(info.getString("nckd_org_in")));//调入组织
-                            dispatch.set("org", ChangeDataUtils.getOrg(info.getString("nckd_org_out")));//调出核算组织
-                            dispatch.set("inorg", ChangeDataUtils.getOrg(info.getString("nckd_org_in")));//调入核算组织
-                            dispatch.set("reason", info.getString("nckd_reason"));//调出原因
-                            dispatch.set("dispatchtype", "A");//调拨类型 A="平价调拨",B="非平价调拨"
-                            dispatch.set("changemode", 14);//减少方式默认"调出"
-                            dispatch.set("currency", 1);//币种
-                            dispatch.set("currencyrate", 1);//结算汇率
-                            //制单信息
-                            dispatch.set("billstatus", "A");//暂存
-                            //调出方向
-                            if("0".equals(direction)){
-                                dispatch.set("outuser", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//调出申请人
-                                dispatch.set("inuser", ChangeDataUtils.getUser(info.getString("nckd_user_in")));//调入负责人
-                                dispatch.set("creator", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//创建人
-                                dispatch.set("modifier", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//修改人
-                                dispatch.set("auditor", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//审核人
-                                dispatch.set("appliant", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//调拨申请人
-                            }//调入方向
-                            else if ("1".equals(direction)) {
-                                dispatch.set("outuser", ChangeDataUtils.getUser(info.getString("nckd_user_in")));//调出申请人
-                                dispatch.set("inuser", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//调入负责人
-                                dispatch.set("creator", ChangeDataUtils.getUser(info.getString("nckd_user_in")));//创建人
-                                dispatch.set("modifier", ChangeDataUtils.getUser(info.getString("nckd_user_in")));//修改人
-                                dispatch.set("auditor", ChangeDataUtils.getUser(info.getString("nckd_user_in")));//审核人
-                                dispatch.set("appliant", ChangeDataUtils.getUser(info.getString("nckd_user_in")));//调拨申请人
-                            }
-                            for (int c = 0; c < card.length; c++) {
-                                DynamicObject cardInfo = BusinessDataServiceHelper.loadSingle(card[c].getPkValue(), card[c].getDynamicObjectType().getName());
-                                //创建调出单分录
-                                DynamicObjectCollection entryEntity = dispatch.getDynamicObjectCollection("dispatchentry");
-                                DynamicObject entry1 = entryEntity.addNew();
-                                entry1.set("realcard", cardInfo);//资产编码
-                                entry1.set("measurement", cardInfo.getDynamicObject("unit").getLong("id"));//计量单位
-                                entry1.set("dispatchqty", cardInfo.getInt("assetamount"));//数量
-                                entry1.set("inusedept", ChangeDataUtils.getOrg(info.getString("nckd_dept_in")));//调入使用部门
-                            }
-                            //执行保存-提交-审核
-                            OperationResult saveResult = SaveServiceHelper.saveOperate("fa_dispatch", new DynamicObject[]{dispatch}, OperateOption.create());
-                            if (saveResult.isSuccess()){
-                                info.set("nckd_flag", "1");
-                                SaveServiceHelper.save(new DynamicObject[]{info});
-                                this.operationResult.setSuccess(true);
-                                this.operationResult.setMessage("下推资产调出单成功");
-                                this.operationResult.setShowMessage(true);
-                                OperationResult submitResult = OperationServiceHelper.executeOperate("submit", "fa_dispatch",saveResult.getSuccessPkIds().toArray(),OperateOption.create());
-                                OperationResult auditResult = OperationServiceHelper.executeOperate("audit", "fa_dispatch",submitResult.getSuccessPkIds().toArray(),OperateOption.create());
-                            }else {
-                                this.operationResult.setShowMessage(true);
-                                this.operationResult.setSuccess(false);
-                                this.operationResult.setMessage("下推资产调出单单失败");
-                            }
+                        errMsg.append(error);
+                        errMsg.append("\r\n");
+                        continue;
+                    }
+                    DynamicObject busProcess = BusinessDataServiceHelper.newDynamicObject("nckd_ywcld");
+                    busProcess.set("nckd_bizdate", info.getDate("nckd_date_out"));//业务日期
+                    busProcess.set("nckd_costcompany", ChangeDataUtils.getOrg(info.getString("nckd_org_in")));//资产组织
+                    busProcess.set("nckd_orgfield1", ChangeDataUtils.getOrg(info.getString("nckd_org_out")));//调出组织
+                    busProcess.set("nckd_orgfield2", ChangeDataUtils.getOrg(info.getString("nckd_org_in")));//调入组织
+                    busProcess.set("nckd_orgfield3", ChangeDataUtils.getOrg(info.getString("nckd_dept_in")));//调入使用部门
+                    busProcess.set("nckd_textfield1", info.getString("nckd_reason"));//调拨原因
+                    busProcess.set("nckd_userfield", ChangeDataUtils.getUser(info.getString("nckd_used_user")));//调入使用人
+                    busProcess.set("nckd_textfield7", info.getString("nckd_storeplace"));//调入存放地点
+
+                    busProcess.set("billstatus", "A");//暂存
+                    busProcess.set("nckd_detailtype", "E");//业务类型(E:资产调拨)
+                    busProcess.set("nckd_combofield2", "1");//调拨类型(1:跨组织)
+                    busProcess.set("nckd_mid_assert", pk);//中间表id
+                    busProcess.set("nckd_source_type", "nckd_e_dispatch_mid");//源单类型
+                    //调出方向
+                    if ("0".equals(direction)) {
+                        busProcess.set("nckd_applierv", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//调出申请人
+                        busProcess.set("nckd_basedatafield4", ChangeDataUtils.getUser(info.getString("nckd_user_in")));//调入负责人
+                        busProcess.set("creator", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//创建人
+                    }//调入方向
+                    else if ("1".equals(direction)) {
+                        busProcess.set("nckd_applierv", ChangeDataUtils.getUser(info.getString("nckd_user_in")));//调出申请人
+                        busProcess.set("nckd_basedatafield4", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//调入负责人
+                        busProcess.set("creator", ChangeDataUtils.getUser(info.getString("nckd_user_in")));//创建人
+                    }
+
+                    List<String> codeList = ChangeDataUtils.getCardNumber(info);
+                    QFilter filter = new QFilter("number", QCP.in, codeList);
+                    filter.and("isbak", QCP.equals, "0");
+                    DynamicObject[] card = BusinessDataServiceHelper.load("fa_card_real", "id", new QFilter[]{filter});
+                    for (int c = 0; c < card.length; c++) {
+                        DynamicObject cardInfo = BusinessDataServiceHelper.loadSingle(card[c].getPkValue(), card[c].getDynamicObjectType().getName());
+                        DynamicObject fin = ChangeDataUtils.queryFinCard(cardInfo.getLong("id"));
+                        BigDecimal originalval = BigDecimal.ZERO;
+                        BigDecimal accumdepre = BigDecimal.ZERO;
+                        BigDecimal decval = BigDecimal.ZERO;
+                        BigDecimal preresidualval = BigDecimal.ZERO;
+                        BigDecimal nckd_amountfield23 = BigDecimal.ZERO;
+                        BigDecimal nckd_amountfield24 = BigDecimal.ZERO;
+                        if (fin != null) {
+                            originalval = fin.getBigDecimal("originalval");//资产原值(nckd_amountfield19)
+                            accumdepre = fin.getBigDecimal("accumdepre");//累计折旧(nckd_amountfield20)
+                            decval = fin.getBigDecimal("decval");//减值准备(nckd_amountfield21)
+                            preresidualval = fin.getBigDecimal("preresidualval");//预计净残值(nckd_amountfield22)
+                            nckd_amountfield23 = originalval.subtract(accumdepre);//预计清理净值(nckd_amountfield23 = nckd_amountfield19 - nckd_amountfield20)
+                            nckd_amountfield24 = nckd_amountfield23.subtract(decval);//预计净残值(nckd_amountfield24 = nckd_amountfield19 - nckd_amountfield20 - nckd_amountfield21)
                         }
+                        //创建资产调拨分录
+                        DynamicObjectCollection entryEntity = busProcess.getDynamicObjectCollection("nckd_entryentity216");
+                        DynamicObject entry1 = entryEntity.addNew();
+                        entry1.set("nckd_basedatafield5", cardInfo);//资产编码
+                        entry1.set("nckd_amountfield19", originalval);//预计清理原值
+                        entry1.set("nckd_amountfield20", accumdepre);//预计清理累计折旧
+                        entry1.set("nckd_amountfield21", decval);//预计清理减值准备
+                        entry1.set("nckd_amountfield22", preresidualval);//预计清理残值
+                        entry1.set("nckd_amountfield23", nckd_amountfield23);//预计清理净值
+                        entry1.set("nckd_amountfield24", nckd_amountfield24);//预计清理净额
                     }
+
+                    //执行保存-提交-审核
+                    OperationResult saveResult = SaveServiceHelper.saveOperate("nckd_ywcld", new DynamicObject[]{busProcess}, OperateOption.create());
+                    if (saveResult.isSuccess()){
+                        info.set("nckd_flag", "1");
+                        info.set("nckd_ywcl", saveResult.getSuccessPkIds().get(0));
+                        SaveServiceHelper.save(new DynamicObject[]{info});
+                        errMsg.append("单据号: ").append(info.getString("number")).append("下推生成业务处理单成功!");
+                        errMsg.append("\r\n");
+                        OperationResult submitResult = OperationServiceHelper.executeOperate("submit", "nckd_ywcld",saveResult.getSuccessPkIds().toArray(),OperateOption.create());
+                        OperationResult auditResult = OperationServiceHelper.executeOperate("audit", "nckd_ywcld",submitResult.getSuccessPkIds().toArray(),OperateOption.create());
+                    }else {
+                        errMsg.append(saveResult.getMessage());
+                        errMsg.append("\r\n");
+                    }
+                }
+            } else {
+                this.getView().showMessage("请至少选择一条数据");
+            }
+            this.getView().showMessage(errMsg.toString());
+        } else if ("nckd_trackdown".equals(itemKey)) {
+            BillList billList = (BillList) this.getControl("billlistap");
+            ListSelectedRowCollection list = billList.getSelectedRows();
+            if (list.size() == 0) {
+                this.getView().showMessage("请选择一条数据");
+                return;
+            } else if (list.size() > 1) {
+                this.getView().showMessage("只能选择一条数据");
+                return;
+            }
+            Object[] primaryKeyValues = list.getPrimaryKeyValues();
+            long id = 0;
+            for (Object pk : primaryKeyValues) {
+                DynamicObject info = BusinessDataServiceHelper.loadSingle(pk, "nckd_e_dispatch_mid");
+                id = info.getLong("nckd_ywcl");
+                if (id == 0) {
+                    this.getView().showMessage("该单据还未下推生成业务处理单");
+                    return;
                 }
             }
+            BillShowParameter showParameter = new BillShowParameter();
+
+            showParameter.setFormId("nckd_ywcld");
+
+            showParameter.getOpenStyle().setShowType(ShowType.Modal);//打开方式
+
+            showParameter.setPkId(id);
+
+            this.getView().showForm(showParameter);
         }
     }
 }

+ 43 - 0
src/main/java/fi/fa/opplugin/BusProcessBillOpPlugin.java

@@ -2,6 +2,7 @@ package fi.fa.opplugin;
 
 import com.alibaba.druid.util.StringUtils;
 import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
 import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
 import kd.bos.orm.query.QCP;
@@ -34,6 +35,28 @@ public class BusProcessBillOpPlugin extends AbstractOperationServicePlugIn {
 
                     }
                 }
+
+                //获取租赁合同分录
+                DynamicObjectCollection nckd_entryentity3 = info.getDynamicObjectCollection("nckd_entryentity3");
+                for (DynamicObject object : nckd_entryentity3) {
+                    long org = object.getDynamicObject("nckd_pzhtorg").getLong("id");
+                    String nckd_pzhthth = object.getString("nckd_pzhthth");
+                    String nckd_combofield = object.getString("nckd_combofield");
+
+                    //查询租赁合同反写
+                    QFilter htfilter = new QFilter("number", QCP.equals,nckd_pzhthth);
+                    htfilter.and("org.id", QCP.equals,org);
+                    DynamicObject[] contract = BusinessDataServiceHelper.load("fa_lease_contract","id",new QFilter[] {htfilter});
+                    for (int j = 0; j < contract.length; j++) {
+                        DynamicObject contractInfo = BusinessDataServiceHelper.loadSingle(contract[j].getPkValue(), contract[j].getDynamicObjectType().getName());
+                        //收款/付款计划明细分录
+                        DynamicObjectCollection payplanentryentity = contractInfo.getDynamicObjectCollection("payplanentryentity");
+                        for (DynamicObject detail : payplanentryentity) {
+                            detail.set("nckd_combofield1", nckd_combofield);
+                        }
+                        SaveServiceHelper.save(new DynamicObject[]{contractInfo});
+                    }
+                }
             }
             else if (StringUtils.equals(e.getOperationKey(),"unaudit")) {
                 DynamicObject info = BusinessDataServiceHelper.loadSingle(dynamicObjects[i].getPkValue(), dynamicObjects[i].getDynamicObjectType().getName());
@@ -54,6 +77,26 @@ public class BusProcessBillOpPlugin extends AbstractOperationServicePlugIn {
 
                     }
                 }
+
+                //获取租赁合同分录
+                DynamicObjectCollection nckd_entryentity3 = info.getDynamicObjectCollection("nckd_entryentity3");
+                for (DynamicObject object : nckd_entryentity3) {
+                    long org = object.getDynamicObject("nckd_pzhtorg").getLong("id");
+                    String nckd_pzhthth = object.getString("nckd_pzhthth");
+                    //查询租赁合同反写
+                    QFilter htfilter = new QFilter("number", QCP.equals,nckd_pzhthth);
+                    htfilter.and("org.id", QCP.equals,org);
+                    DynamicObject[] contract = BusinessDataServiceHelper.load("fa_lease_contract","id",new QFilter[] {htfilter});
+                    for (int j = 0; j < contract.length; j++) {
+                        DynamicObject contractInfo = BusinessDataServiceHelper.loadSingle(contract[j].getPkValue(), contract[j].getDynamicObjectType().getName());
+                        //收款/付款计划明细分录
+                        DynamicObjectCollection payplanentryentity = contractInfo.getDynamicObjectCollection("payplanentryentity");
+                        for (DynamicObject detail : payplanentryentity) {
+                            detail.set("nckd_combofield1", null);
+                        }
+                        SaveServiceHelper.save(new DynamicObject[]{contractInfo});
+                    }
+                }
             }
         }
     }

+ 132 - 114
src/main/java/fi/fa/opplugin/FaChangeMidOpPlugin.java

@@ -2,142 +2,160 @@ package fi.fa.opplugin;
 
 import com.alibaba.druid.util.StringUtils;
 import fi.fa.opplugin.utils.ChangeDataUtils;
+import kd.bos.bill.BillShowParameter;
 import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.entity.datamodel.ListSelectedRowCollection;
 import kd.bos.entity.operate.result.OperationResult;
-import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
-import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
-import kd.bos.exception.KDBizException;
+import kd.bos.form.ShowType;
+import kd.bos.form.control.events.ItemClickEvent;
+import kd.bos.list.BillList;
+import kd.bos.list.plugin.AbstractListPlugin;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.operation.OperationServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
+import java.math.BigDecimal;
+import java.util.EventObject;
 import java.util.List;
 
 //资产变更单中间表下推资产变更单
-public class FaChangeMidOpPlugin extends AbstractOperationServicePlugIn {
+public class FaChangeMidOpPlugin extends AbstractListPlugin {
+
+    public void registerListener(EventObject e) {
+        super.registerListener(e);
+        this.addItemClickListeners(new String[]{"toolbarap"});
+    }
+
     @Override
-    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
-        super.beginOperationTransaction(e);
-        DynamicObject[] dynamicObjects = e.getDataEntities();
-        for (int i = 0; i < dynamicObjects.length; i++) {
-            if (StringUtils.equals(e.getOperationKey(), "push")) {
-                DynamicObject info = BusinessDataServiceHelper.loadSingle(dynamicObjects[i].getPkValue(), dynamicObjects[i].getDynamicObjectType().getName());
-                String nckd_flag = info.getString("nckd_flag");
-                if ("1".equals(nckd_flag)) {
-                    throw new KDBizException("单据" + info.getString("number") + "已经下推生成了资产调拨单,不允许重复下推!");
-                }else {
-                    String dispatchType = info.getString("nckd_dispatch_type");
+    public void itemClick(ItemClickEvent evt) {
+        String itemKey = evt.getItemKey();
+        if ("nckd_push".equals(itemKey)) {
+            StringBuilder errMsg = new StringBuilder();
+            BillList billList = (BillList)this.getControl("billlistap");
+            ListSelectedRowCollection list =  billList.getSelectedRows();
+            Object[] primaryKeyValues = list.getPrimaryKeyValues();
+            if (primaryKeyValues.length > 0) {
+                for (Object pk : primaryKeyValues) {
+                    DynamicObject info = BusinessDataServiceHelper.loadSingle(pk, "nckd_e_change_mid");
+                    String nckd_flag = info.getString("nckd_flag");
                     String direction = info.getString("nckd_direction");
+                    if ("1".equals(nckd_flag)) {
+                        errMsg.append("单据号: ").append(info.getString("number")).append("已经下推生成了业务处理单,不允许重复下推!");
+                        errMsg.append("\r\n");
+                        continue;
+                    }
                     String error = ChangeDataUtils.check(info);
                     if (!StringUtils.isEmpty(error)) {
-                        this.operationResult.setShowMessage(true);
-                        this.operationResult.setSuccess(false);
-                        this.operationResult.setMessage(error);
-                    }else {
-
-                        if ("1".equals(dispatchType)) {
-                            DynamicObject changeDept = BusinessDataServiceHelper.newDynamicObject("fa_change_dept");
-                            //单据头
-                            DynamicObject orgInfo = ChangeDataUtils.queryOrg(ChangeDataUtils.getOrg(info.getString("nckd_org_in")));
-                            changeDept.set("org", orgInfo);//核算组织
-                            changeDept.set("changedate", info.getDate("nckd_date_out"));//记账日期
-                            changeDept.set("appliantid", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//变更申请人
-                            changeDept.set("remark", info.getString("nckd_reason"));//调出原因
-                            changeDept.set("sourcetype", 2);//来源方式(5:API生成)
-                            changeDept.set("changetype", ChangeDataUtils.queryChangeType(Long.parseLong("733953285719123968")));//变更类型,默认部门变更
-                            changeDept.set("chtypedetail", "1");//变更类型明细默认实物变更1
-                            changeDept.set("voucherflag", "A");//记账标识默认无需记账A
-                            changeDept.set("billstatus", "A");//暂存
-                            //调出方向
-                            if("0".equals(direction)){
-                                changeDept.set("creator", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//创建人
-                                changeDept.set("appliantid", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//调拨申请人
-                            }//调入方向
-                            else if ("1".equals(direction)) {
-                                changeDept.set("creator", ChangeDataUtils.getUser(info.getString("nckd_user_in")));//创建人
-                                changeDept.set("appliantid", ChangeDataUtils.getUser(info.getString("nckd_user_in")));//调拨申请人
-                            }
-                            List<String> codeList =ChangeDataUtils.getCardNumber(info);
-                            QFilter filter = new QFilter("number", QCP.in,codeList);
-                            filter.and("isbak",  QCP.equals, "0");
-                            DynamicObject[] card = BusinessDataServiceHelper.load("fa_card_real","id",new QFilter[] {filter});
-                            for (int c = 0; c < card.length; c++) {
-                                DynamicObject cardInfo = BusinessDataServiceHelper.loadSingle(card[c].getPkValue(), card[c].getDynamicObjectType().getName());
-                                //查询财务卡片
-                                DynamicObject fin = ChangeDataUtils.queryFinCard(cardInfo.getLong("id"));//财务卡片id
-                                //创建变更字段分录
-                                DynamicObjectCollection fieldentry = changeDept.getDynamicObjectCollection("fieldentry");
+                        errMsg.append(error);
+                        errMsg.append("\r\n");
+                        continue;
+                    }
+                    DynamicObject busProcess = BusinessDataServiceHelper.newDynamicObject("nckd_ywcld");
+                    busProcess.set("nckd_bizdate", info.getDate("nckd_date_out"));//业务日期
+                    busProcess.set("nckd_costcompany", ChangeDataUtils.getOrg(info.getString("nckd_org_in")));//资产组织
+                    busProcess.set("nckd_orgfield3", ChangeDataUtils.getOrg(info.getString("nckd_dept_in")));//调入使用部门
+                    busProcess.set("nckd_userfield", ChangeDataUtils.getUser(info.getString("nckd_used_user")));//调入使用人
+                    busProcess.set("nckd_textfield7", info.getString("nckd_storeplace"));//调入存放地点
+                    busProcess.set("nckd_textfield1", info.getString("nckd_reason"));//调拨原因
+                    busProcess.set("billstatus", "A");//暂存
+                    busProcess.set("nckd_detailtype", "E");//业务类型(E:资产调拨)
+                    busProcess.set("nckd_combofield2", "2");//调拨类型(2:组织内)
+                    busProcess.set("nckd_mid_assert", pk);//中间表id
+                    busProcess.set("nckd_source_type", "nckd_e_change_mid");//源单类型
+                    //调出方向
+                    if("0".equals(direction)){
+                        busProcess.set("creator", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//创建人
+                        busProcess.set("nckd_applierv", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//调拨申请人
+                    }//调入方向
+                    else if ("1".equals(direction)) {
+                        busProcess.set("creator", ChangeDataUtils.getUser(info.getString("nckd_user_in")));//创建人
+                        busProcess.set("nckd_applierv", ChangeDataUtils.getUser(info.getString("nckd_user_in")));//调拨申请人
+                    }
 
-                                String deptAftervalue = ChangeDataUtils.getOrg(info.getString("nckd_dept_in")) == null ? null : ChangeDataUtils.getOrg(info.getString("nckd_dept_in")).toString();
-                                String deptBeforevalue =  cardInfo.getDynamicObject("headusedept") == null ? null : String.valueOf(cardInfo.getDynamicObject("headusedept").getLong("id"));
-                                if (!StringUtils.equals(deptBeforevalue, deptAftervalue)) {
-                                    DynamicObject entry1 = fieldentry.addNew();
-                                    entry1.set("realcard1", cardInfo);//资产编码
-                                    entry1.set("depreuse1", ChangeDataUtils.queryDepreuse(Long.parseLong("418714318096331776")));//折旧用途默认
-                                    entry1.set("currency1", 1);//币别
-                                    entry1.set("basecurrency1", 1);//本币位
-                                    entry1.set("assetnumber",cardInfo.getString("number"));//资产编码
-                                    entry1.set("bizdate1", info.getDate("nckd_date_out"));//业务日期
-                                    entry1.set("field", "fa_card_real.headusedept");//变更字段-部门
-                                    entry1.set("beforevalue", deptBeforevalue);//变更前值
-                                    entry1.set("aftervalue", deptAftervalue);//变更后值
-                                    entry1.set("realcardmasterid", cardInfo);//实物卡片id
-                                    entry1.set("fincard1", fin);//财务卡片
-                                }
+                    List<String> codeList =ChangeDataUtils.getCardNumber(info);
+                    QFilter filter = new QFilter("number", QCP.in,codeList);
+                    filter.and("isbak",  QCP.equals, "0");
+                    DynamicObject[] card = BusinessDataServiceHelper.load("fa_card_real","id",new QFilter[] {filter});
+                    for (int c = 0; c < card.length; c++) {
+                        DynamicObject cardInfo = BusinessDataServiceHelper.loadSingle(card[c].getPkValue(), card[c].getDynamicObjectType().getName());
+                        DynamicObject fin = ChangeDataUtils.queryFinCard(cardInfo.getLong("id"));
+                        BigDecimal originalval = BigDecimal.ZERO;
+                        BigDecimal accumdepre = BigDecimal.ZERO;
+                        BigDecimal decval = BigDecimal.ZERO;
+                        BigDecimal preresidualval = BigDecimal.ZERO;
+                        BigDecimal nckd_amountfield23 = BigDecimal.ZERO;
+                        BigDecimal nckd_amountfield24 = BigDecimal.ZERO;
+                        if (fin != null) {
+                            originalval = fin.getBigDecimal("originalval");//资产原值(nckd_amountfield19)
+                            accumdepre = fin.getBigDecimal("accumdepre");//累计折旧(nckd_amountfield20)
+                            decval = fin.getBigDecimal("decval");//减值准备(nckd_amountfield21)
+                            preresidualval = fin.getBigDecimal("preresidualval");//预计净残值(nckd_amountfield22)
+                            nckd_amountfield23 = originalval.subtract(accumdepre);//预计清理净值(nckd_amountfield23 = nckd_amountfield19 - nckd_amountfield20)
+                            nckd_amountfield24 = nckd_amountfield23.subtract(decval);//预计净残值(nckd_amountfield24 = nckd_amountfield19 - nckd_amountfield20 - nckd_amountfield21)
+                        }
+                        //创建资产调拨分录
+                        DynamicObjectCollection entryEntity = busProcess.getDynamicObjectCollection("nckd_entryentity216");
+                        DynamicObject entry1 = entryEntity.addNew();
+                        entry1.set("nckd_basedatafield5", cardInfo);//资产编码
+                        entry1.set("nckd_amountfield19", originalval);//预计清理原值
+                        entry1.set("nckd_amountfield20", accumdepre);//预计清理累计折旧
+                        entry1.set("nckd_amountfield21", decval);//预计清理减值准备
+                        entry1.set("nckd_amountfield22", preresidualval);//预计清理残值
+                        entry1.set("nckd_amountfield23", nckd_amountfield23);//预计清理净值
+                        entry1.set("nckd_amountfield24", nckd_amountfield24);//预计清理净额
+                    }
 
-                                String userAftervalue = info.getString("nckd_used_user") == null ? null : String.valueOf(ChangeDataUtils.getUser(info.getString("nckd_used_user")).getLong("id"));
-                                String userBeforevalue  = cardInfo.getDynamicObject("headuseperson") == null ? null : String.valueOf(ChangeDataUtils.getUser(info.getString("nckd_used_user")).getLong("id"));
-                                if (!StringUtils.equals(userBeforevalue, userAftervalue)) {
-                                    DynamicObject entry2 = fieldentry.addNew();
-                                    entry2.set("realcard1", cardInfo);//资产编码
-                                    entry2.set("depreuse1", ChangeDataUtils.queryDepreuse(Long.parseLong("418714318096331776")));//折旧用途默认
-                                    entry2.set("currency1", 1);//币别
-                                    entry2.set("basecurrency1", 1);//本币位
-                                    entry2.set("assetnumber",cardInfo.getString("number"));//资产编码
-                                    entry2.set("bizdate1", info.getDate("nckd_date_out"));//业务日期
-                                    entry2.set("field", "fa_card_real.headuseperson");//变更字段-使用人
-                                    entry2.set("beforevalue", userBeforevalue);//变更前值
-                                    entry2.set("aftervalue", userAftervalue);//变更后值
-                                    entry2.set("realcardmasterid", cardInfo);//实物卡片id
-                                    entry2.set("fincard1", fin);//财务卡片
-                                }
+                    //执行保存-提交-审核
+                    OperationResult saveResult = SaveServiceHelper.saveOperate("nckd_ywcld", new DynamicObject[]{busProcess}, OperateOption.create());
+                    if (saveResult.isSuccess()){
+                        info.set("nckd_flag", "1");
+                        info.set("nckd_ywcl", saveResult.getSuccessPkIds().get(0));
+                        SaveServiceHelper.save(new DynamicObject[]{info});
+                        errMsg.append("单据号: ").append(info.getString("number")).append("下推生成业务处理单成功!");
+                        errMsg.append("\r\n");
+                        OperationResult submitResult = OperationServiceHelper.executeOperate("submit", "nckd_ywcld",saveResult.getSuccessPkIds().toArray(),OperateOption.create());
+                        OperationResult auditResult = OperationServiceHelper.executeOperate("audit", "nckd_ywcld",submitResult.getSuccessPkIds().toArray(),OperateOption.create());
+                    }else {
+                        errMsg.append(saveResult.getMessage());
+                        errMsg.append("\r\n");
+                    }
+                }
+            }else {
+                this.getView().showMessage("请至少选择一条数据");
+            }
+            this.getView().showMessage(errMsg.toString());
+        } else if ("nckd_trackdown".equals(itemKey)) {
+            BillList billList = (BillList) this.getControl("billlistap");
+            ListSelectedRowCollection list = billList.getSelectedRows();
+            if (list.size() == 0) {
+                this.getView().showMessage("请选择一条数据");
+                return;
+            } else if (list.size() > 1) {
+                this.getView().showMessage("只能选择一条数据");
+                return;
+            }
+            Object[] primaryKeyValues = list.getPrimaryKeyValues();
+            long id = 0;
+            for (Object pk : primaryKeyValues) {
+                DynamicObject info = BusinessDataServiceHelper.loadSingle(pk, "nckd_e_change_mid");
+                id = info.getLong("nckd_ywcl");
+                if (id == 0) {
+                    this.getView().showMessage("该单据还未下推生成业务处理单");
+                    return;
+                }
+            }
+            BillShowParameter showParameter = new BillShowParameter();
 
+            showParameter.setFormId("nckd_ywcld");
 
-                                //创建实物变更分录
-                                DynamicObjectCollection realentry = changeDept.getDynamicObjectCollection("realentry");
-                                DynamicObject realentry1 = realentry.addNew();
-                                realentry1.set("realcard", cardInfo.getLong("id"));//资产编码
+            showParameter.getOpenStyle().setShowType(ShowType.Modal);//打开方式
 
-                                //创建财务变更分录
-                                DynamicObjectCollection finentry = realentry1.getDynamicObjectCollection("finentry");
-                                DynamicObject finentry1 = finentry.addNew();
-                                finentry1.set("depreuse", ChangeDataUtils.queryDepreuse(Long.parseLong("418714318096331776")));//折旧用途默认
-                                finentry1.set("fincard", fin);
-                                finentry1.set("bizdate", info.getDate("nckd_date_out"));
+            showParameter.setPkId(id);
 
-                            }
-                            //执行保存-提交-审核
-                            OperationResult saveResult = SaveServiceHelper.saveOperate("fa_change_dept", new DynamicObject[]{changeDept}, OperateOption.create());
-                            if (saveResult.isSuccess()) {
-                                info.set("nckd_flag", "1");
-                                SaveServiceHelper.save(new DynamicObject[]{info});
-                                this.operationResult.setShowMessage(true);
-                                this.operationResult.setSuccess(true);
-                                this.operationResult.setMessage("下推资产变更单成功");
-                                OperationResult submitResult = OperationServiceHelper.executeOperate("submit", "fa_change_dept",saveResult.getSuccessPkIds().toArray(),OperateOption.create());
-                                OperationResult auditResult = OperationServiceHelper.executeOperate("audit", "fa_change_dept",submitResult.getSuccessPkIds().toArray(),OperateOption.create());
-                            }else {
-                                this.operationResult.setShowMessage(true);
-                                this.operationResult.setSuccess(false);
-                                this.operationResult.setMessage("下推资产变更单失败");
-                            }
-                        }
-                    }
-                }
-            }
+            this.getView().showForm(showParameter);
         }
     }
 }

+ 106 - 60
src/main/java/fi/fa/opplugin/FaDisCardMidOpPlugin.java

@@ -2,85 +2,131 @@ package fi.fa.opplugin;
 
 import com.alibaba.druid.util.StringUtils;
 import fi.fa.opplugin.utils.ChangeDataUtils;
+import kd.bos.bill.BillShowParameter;
 import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.entity.datamodel.ListSelectedRowCollection;
 import kd.bos.entity.operate.result.OperationResult;
-import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
-import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
-import kd.bos.exception.KDBizException;
+import kd.bos.form.ShowType;
+import kd.bos.form.control.events.ItemClickEvent;
+import kd.bos.list.BillList;
+import kd.bos.list.plugin.AbstractListPlugin;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.operation.OperationServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
+import java.util.EventObject;
 import java.util.List;
 
 //资产报废单中间表下推业务处理单
-public class FaDisCardMidOpPlugin extends AbstractOperationServicePlugIn {
+public class FaDisCardMidOpPlugin extends AbstractListPlugin {
+
+    public void registerListener(EventObject e) {
+        super.registerListener(e);
+        this.addItemClickListeners(new String[]{"toolbarap"});
+    }
+
     @Override
-    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
-        super.beginOperationTransaction(e);
-        DynamicObject[] dynamicObjects = e.getDataEntities();
-        for (int i = 0; i < dynamicObjects.length; i++) {
-            if (StringUtils.equals(e.getOperationKey(), "push")) {
-                DynamicObject info = BusinessDataServiceHelper.loadSingle(dynamicObjects[i].getPkValue(), dynamicObjects[i].getDynamicObjectType().getName());
-                String nckd_flag = info.getString("nckd_flag");
-                if ("1".equals(nckd_flag)) {
-                    throw new KDBizException("单据" + info.getString("number") + "已经下推生成了资产调拨单,不允许重复下推!");
-                }else {
-                    String dispatchType = info.getString("nckd_dispatch_type");
+    public void itemClick(ItemClickEvent evt) {
+        String itemKey = evt.getItemKey();
+        if ("nckd_push".equals(itemKey)) {
+            StringBuilder errMsg = new StringBuilder();
+            BillList billList = (BillList)this.getControl("billlistap");
+            ListSelectedRowCollection list =  billList.getSelectedRows();
+            Object[] primaryKeyValues = list.getPrimaryKeyValues();
+            if (primaryKeyValues.length > 0) {
+                for (Object pk : primaryKeyValues) {
+                    DynamicObject info = BusinessDataServiceHelper.loadSingle(pk, "nckd_e_discard_mid");
+                    String nckd_flag = info.getString("nckd_flag");
+                    if ("1".equals(nckd_flag)) {
+                        errMsg.append("单据号: ").append(info.getString("number")).append("已经下推生成了业务处理单,不允许重复下推!");
+                        errMsg.append("\r\n");
+                        continue;
+                    }
                     String error = ChangeDataUtils.check(info);
                     if (!StringUtils.isEmpty(error)) {
-                        this.operationResult.setShowMessage(true);
-                        this.operationResult.setSuccess(false);
-                        this.operationResult.setMessage(error);
-                    }else {
-                        List<String> codeList = ChangeDataUtils.getCardNumber(info);
-                        if ("2".equals(dispatchType)) {
-                            DynamicObject busProcess = BusinessDataServiceHelper.newDynamicObject("nckd_ywcld");
-                            busProcess.set("nckd_bizdate", info.getDate("nckd_date_out"));//业务日期
-                            busProcess.set("nckd_detailtype", "D");//业务类型 D:报废
-                            busProcess.set("nckd_costcompany", ChangeDataUtils.getOrg(info.getString("nckd_org_in")));//资产组织
-                            busProcess.set("nckd_textfield1", info.getString("nckd_reason"));//摘要事由
-                            busProcess.set("nckd_applierv", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//制单人
+                        errMsg.append(error);
+                        errMsg.append("\r\n");
+                        continue;
+                    }
 
-                            //制单信息
-                            busProcess.set("creator", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//创建人
-                            busProcess.set("createtime", info.getDate("nckd_date_out"));//创建时间
-                            busProcess.set("billstatus", "A");//状态
-                            QFilter filter = new QFilter("number", QCP.in,codeList);
-                            filter.and("isbak",  QCP.equals, "0");
-                            DynamicObject[] card = BusinessDataServiceHelper.load("fa_card_real","id",new QFilter[] {filter});
-                            for (int c = 0; c < card.length; c++) {
-                                DynamicObject cardInfo = BusinessDataServiceHelper.loadSingle(card[c].getPkValue(), card[c].getDynamicObjectType().getName());
-                                //创建报废明细分录
-                                DynamicObjectCollection entryEntity = busProcess.getDynamicObjectCollection("nckd_entryentity6");
-                                DynamicObject entry1 = entryEntity.addNew();
-                                entry1.set("nckd_basedatafield", cardInfo);//资产编码
-                                String nckd_count = info.getString("nckd_count").isEmpty() ? "1" : info.getString("nckd_count");
-                                Integer count = Integer.valueOf(nckd_count);
-                                entry1.set("nckd_integerfield", count);//报废数量
-                            }
-                            //执行保存-提交-审核
-                            OperationResult saveResult = SaveServiceHelper.saveOperate("nckd_ywcld", new DynamicObject[]{busProcess}, OperateOption.create());
-                            if (saveResult.isSuccess()){
-                                info.set("nckd_flag", "1");
-                                SaveServiceHelper.save(new DynamicObject[]{info});
-                                this.operationResult.setShowMessage(true);
-                                this.operationResult.setSuccess(true);
-                                this.operationResult.setMessage("下推业务处理单成功");
-                                OperationResult submitResult = OperationServiceHelper.executeOperate("submit", "nckd_ywcld",saveResult.getSuccessPkIds().toArray(),OperateOption.create());
-                                OperationResult auditResult = OperationServiceHelper.executeOperate("audit", "nckd_ywcld",submitResult.getSuccessPkIds().toArray(),OperateOption.create());
-                            }else {
-                                this.operationResult.setShowMessage(true);
-                                this.operationResult.setSuccess(false);
-                                this.operationResult.setMessage("下推业务处理单失败");
-                            }
-                        }
+                    List<String> codeList = ChangeDataUtils.getCardNumber(info);
+                    DynamicObject busProcess = BusinessDataServiceHelper.newDynamicObject("nckd_ywcld");
+                    busProcess.set("nckd_bizdate", info.getDate("nckd_date_out"));//业务日期
+                    busProcess.set("nckd_detailtype", "D");//业务类型 D:报废
+                    busProcess.set("nckd_costcompany", ChangeDataUtils.getOrg(info.getString("nckd_org_in")));//资产组织
+                    busProcess.set("nckd_textfield1", info.getString("nckd_reason"));//摘要事由
+                    busProcess.set("nckd_applierv", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//制单人
+
+                    //制单信息
+                    busProcess.set("creator", ChangeDataUtils.getUser(info.getString("nckd_user_out")));//创建人
+                    busProcess.set("createtime", info.getDate("nckd_date_out"));//创建时间
+                    busProcess.set("billstatus", "A");//状态
+                    busProcess.set("nckd_mid_assert", pk);//中间表id
+                    busProcess.set("nckd_source_type", "nckd_e_discard_mid");//源单类型
+                    QFilter filter = new QFilter("number", QCP.in,codeList);
+                    filter.and("isbak",  QCP.equals, "0");
+                    DynamicObject[] card = BusinessDataServiceHelper.load("fa_card_real","id",new QFilter[] {filter});
+                    for (int c = 0; c < card.length; c++) {
+                        DynamicObject cardInfo = BusinessDataServiceHelper.loadSingle(card[c].getPkValue(), card[c].getDynamicObjectType().getName());
+                        //创建报废明细分录
+                        DynamicObjectCollection entryEntity = busProcess.getDynamicObjectCollection("nckd_entryentity6");
+                        DynamicObject entry1 = entryEntity.addNew();
+                        entry1.set("nckd_basedatafield", cardInfo);//资产编码
+                        String nckd_count = info.getString("nckd_count").isEmpty() ? "1" : info.getString("nckd_count");
+                        Integer count = Integer.valueOf(nckd_count);
+                        entry1.set("nckd_integerfield", count);//报废数量
+                    }
+                    //执行保存-提交-审核
+                    OperationResult saveResult = SaveServiceHelper.saveOperate("nckd_ywcld", new DynamicObject[]{busProcess}, OperateOption.create());
+                    if (saveResult.isSuccess()){
+                        info.set("nckd_flag", "1");
+                        info.set("nckd_ywcl", saveResult.getSuccessPkIds().get(0));
+                        SaveServiceHelper.save(new DynamicObject[]{info});
+                        errMsg.append("单据号: ").append(info.getString("number")).append("下推生成业务处理单成功!");
+                        errMsg.append("\r\n");
+                        OperationResult submitResult = OperationServiceHelper.executeOperate("submit", "nckd_ywcld",saveResult.getSuccessPkIds().toArray(),OperateOption.create());
+                        OperationResult auditResult = OperationServiceHelper.executeOperate("audit", "nckd_ywcld",submitResult.getSuccessPkIds().toArray(),OperateOption.create());
+                    }else {
+                        errMsg.append(saveResult.getMessage());
+                        errMsg.append("\r\n");
                     }
                 }
+            }else {
+                this.getView().showMessage("请至少选择一条数据");
+            }
+            this.getView().showMessage(errMsg.toString());
+        } else if ("nckd_trackdown".equals(itemKey)) {
+            BillList billList = (BillList) this.getControl("billlistap");
+            ListSelectedRowCollection list = billList.getSelectedRows();
+            if (list.size() == 0) {
+                this.getView().showMessage("请选择一条数据");
+                return;
+            } else if (list.size() > 1) {
+                this.getView().showMessage("只能选择一条数据");
+                return;
+            }
+            Object[] primaryKeyValues = list.getPrimaryKeyValues();
+            long id = 0;
+            for (Object pk : primaryKeyValues) {
+                DynamicObject info = BusinessDataServiceHelper.loadSingle(pk, "nckd_e_discard_mid");
+                id = info.getLong("nckd_ywcl");
+                if (id == 0) {
+                    this.getView().showMessage("该单据还未下推生成业务处理单");
+                    return;
+                }
             }
+            BillShowParameter showParameter = new BillShowParameter();
+
+            showParameter.setFormId("nckd_ywcld");
+
+            showParameter.getOpenStyle().setShowType(ShowType.Modal);//打开方式
+
+            showParameter.setPkId(id);
+
+            this.getView().showForm(showParameter);
         }
     }
 }

+ 47 - 1
src/main/java/fi/fa/opplugin/RealCardBillOpPlugin.java

@@ -22,7 +22,7 @@ public class RealCardBillOpPlugin extends AbstractOperationServicePlugIn {
                 //审批通过后,如果是报销单下推的单据,则回写e卡片清单
                 DynamicObject info = BusinessDataServiceHelper.loadSingle(dynamicObjects[i].getPkValue(), dynamicObjects[i].getDynamicObjectType().getName());
                 String srcbillentityname = info.getString("srcbillentityname");
-                Long bxId = info.getLong("nckd_bz_id");
+                long bxId = info.getLong("nckd_bz_id");
                 String number = info.getString("number");//资产编码
                 String name = info.getString("assetname");//资产名称
                 DynamicObject org = info.getDynamicObject("assetunit");//资产组织
@@ -40,9 +40,32 @@ public class RealCardBillOpPlugin extends AbstractOperationServicePlugIn {
                             SaveServiceHelper.save(new DynamicObject[]{cardInfo});
                         }
                     }
+
+                    //反写合同台账单
+                    if (bxId != 0) {
+                        //查询报销单
+                        QFilter bxFilter = new QFilter("id", QCP.equals,bxId);
+                        DynamicObject[] bxDynamicObjects = BusinessDataServiceHelper.load("er_publicreimbursebill","id",new QFilter[] {bxFilter});
+                        for (int j = 0; j < bxDynamicObjects.length; j++) {
+                            DynamicObject bxInfo = BusinessDataServiceHelper.loadSingle(bxDynamicObjects[i].getPkValue(), bxDynamicObjects[i].getDynamicObjectType().getName());
+                            String nckd_sourcebillid = bxInfo.getString("nckd_sourcebillid");
+                            if (!StringUtils.isEmpty(nckd_sourcebillid)) {
+                                Long contractbillId = Long.parseLong(nckd_sourcebillid);
+                                //查询合同台账单
+                                QFilter htFilter = new QFilter("id", QCP.equals,contractbillId);
+                                DynamicObject[] htDynamicObjects = BusinessDataServiceHelper.load("er_contractbill","id",new QFilter[] {htFilter});
+                                for (int k = 0; k < htDynamicObjects.length; k++) {
+                                    DynamicObject htInfo = BusinessDataServiceHelper.loadSingle(htDynamicObjects[i].getPkValue(), htDynamicObjects[i].getDynamicObjectType().getName());
+                                    htInfo.set("nckd_real_card", info.getString("billno"));
+                                    SaveServiceHelper.save(new DynamicObject[]{htInfo});
+                                }
+                            }
+                        }
+                    }
                 }
             }else if(StringUtils.equals(e.getOperationKey(),"unaudit")) {
                 DynamicObject info = BusinessDataServiceHelper.loadSingle(dynamicObjects[i].getPkValue(), dynamicObjects[i].getDynamicObjectType().getName());
+                long bxId = info.getLong("nckd_bz_id");
                 String srcbillentityname = info.getString("srcbillentityname");
                 if (!"fa_assetsplitbill".equals(srcbillentityname)) {
                     //反审核,e管家实物卡片清单三个字段置为空
@@ -59,6 +82,29 @@ public class RealCardBillOpPlugin extends AbstractOperationServicePlugIn {
                         cardInfo.set("nckd_card_real_name", null);
                         SaveServiceHelper.save(new DynamicObject[]{cardInfo});
                     }
+
+                    //反写合同台账
+                    if (bxId != 0) {
+                        //查询报销单
+                        QFilter bxFilter = new QFilter("id", QCP.equals,bxId);
+                        DynamicObject[] bxDynamicObjects = BusinessDataServiceHelper.load("er_publicreimbursebill","id",new QFilter[] {bxFilter});
+                        for (int j = 0; j < bxDynamicObjects.length; j++) {
+                            DynamicObject bxInfo = BusinessDataServiceHelper.loadSingle(bxDynamicObjects[i].getPkValue(), bxDynamicObjects[i].getDynamicObjectType().getName());
+                            String nckd_sourcebillid = bxInfo.getString("nckd_sourcebillid");
+                            if (!StringUtils.isEmpty(nckd_sourcebillid)) {
+                                Long contractbillId = Long.parseLong(nckd_sourcebillid);
+                                //查询合同台账单
+                                QFilter htFilter = new QFilter("id", QCP.equals,contractbillId);
+                                DynamicObject[] htDynamicObjects = BusinessDataServiceHelper.load("er_contractbill","id",new QFilter[] {htFilter});
+                                for (int k = 0; k < htDynamicObjects.length; k++) {
+                                    DynamicObject htInfo = BusinessDataServiceHelper.loadSingle(htDynamicObjects[i].getPkValue(), htDynamicObjects[i].getDynamicObjectType().getName());
+                                    htInfo.set("nckd_real_card", null);
+                                    SaveServiceHelper.save(new DynamicObject[]{htInfo});
+                                }
+                            }
+
+                        }
+                    }
                 }
             }
         }

+ 29 - 1
src/main/java/fi/fa/opplugin/RealCardF7OpPlugin.java

@@ -5,11 +5,20 @@ import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.entity.datamodel.events.ChangeData;
 import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.form.field.MulBasedataEdit;
+import kd.bos.form.field.RefBillEdit;
+import kd.bos.form.field.events.BeforeF7SelectEvent;
+import kd.bos.form.field.events.BeforeF7SelectListener;
 import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.list.ListShowParameter;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
 
+import java.util.EventObject;
+
 //实物卡片关联e管家实物卡片清单插件
-public class RealCardF7OpPlugin extends AbstractFormPlugin {
+public class RealCardF7OpPlugin extends AbstractFormPlugin implements BeforeF7SelectListener {
     @Override
     public void propertyChanged(PropertyChangedArgs e) {
         String fieldKey = e.getProperty().getName();
@@ -25,4 +34,23 @@ public class RealCardF7OpPlugin extends AbstractFormPlugin {
             this.getView().updateView("nckd_realcard_list");
         }
     }
+
+    @Override
+    public void registerListener(EventObject e) {
+        //监听单据字段
+        super.registerListener(e);
+        MulBasedataEdit mEdit = this.getView().getControl("nckd_real_card");
+        mEdit.addBeforeF7SelectListener(this);
+    }
+    @Override
+    public void beforeF7Select(BeforeF7SelectEvent arg0) {
+        String fieldKey = arg0.getProperty().getName();
+        if (StringUtils.equals(fieldKey, "nckd_real_card")) {
+            DynamicObject assetunit = (DynamicObject) this.getModel().getValue("assetunit");//资产组织
+            QFilter qFilter = new QFilter("nckd_orgfield.id", QCP.equals, assetunit.getLong("id"));
+            // 表过滤条件
+            ListShowParameter showParameter = (ListShowParameter)arg0.getFormShowParameter();
+            showParameter.getListFilterParameter().setFilter(qFilter);
+        }
+    }
 }

+ 0 - 1
src/main/java/kd/bos/login/utils/DemoSMSSender.java

@@ -213,7 +213,6 @@ public class DemoSMSSender implements SMSSender {
                 int index = responseJson.indexOf("<?xml");
                 responseJson = responseJson.substring(index);
             }
-
             JSONObject jsonObject = XML.toJSONObject(responseJson);
             client.close();
             return jsonObject;

+ 1135 - 0
src/main/java/kd/bos/newdevportal/table/DBTableProviderNew.java

@@ -0,0 +1,1135 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package kd.bos.newdevportal.table;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import kd.bos.algo.DataSet;
+import kd.bos.algo.Row;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.entity.ILocaleString;
+import kd.bos.dataentity.entity.LocaleString;
+import kd.bos.dataentity.utils.StringUtils;
+import kd.bos.db.DB;
+import kd.bos.db.DBRoute;
+import kd.bos.db.DBType;
+import kd.bos.db.FieldInfo;
+import kd.bos.db.IndexInfo;
+import kd.bos.db.SqlBuilder;
+import kd.bos.db.SqlParameter;
+import kd.bos.db.tx.TX;
+import kd.bos.exception.ErrorCode;
+import kd.bos.exception.KDException;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.QueryServiceHelper;
+import org.apache.commons.collections.map.CaseInsensitiveMap;
+
+class DBTableProviderNew extends TableInfoProvider {
+    private static Log log = LogFactory.getLog(DBTableProviderNew.class);
+    private static boolean distinct = Boolean.parseBoolean(System.getProperty("bos.dev.tableprovider.distinct", "true"));
+    protected IGetTableHandler handler;
+
+    DBTableProviderNew() {
+    }
+
+    public Map<String,DesignerTable> getTableInfo_youhua(List<String> tableNames,List<String> entityNumList) {
+        Map<String, List<DesignerColumn>> column_map = this.handler.batchLoadColumns(this.route,tableNames);
+        Map<String,DesignerTable> returnmap = new HashMap<>();
+        for (int i = 0; i < tableNames.size(); i++) {
+            DesignerTable table = this.buildTableInfo_youhua(column_map.get(tableNames.get(i)), tableNames.get(i),entityNumList.get(i));
+            returnmap.put(tableNames.get(i), table);
+        }
+        return returnmap;
+    }
+
+    public DesignerTable getTableInfo(String tableName, String entityNum) {
+        String lowerTableName = tableName.toLowerCase();
+        List<DesignerColumn> cols = this.handler.getColumns(this.route, lowerTableName);
+        List<DesignerIndex> idxs = this.handler.getIndexs(this.route, lowerTableName);
+        List<DesignerConstaint> constraints = this.handler.getConstraints(this.route, lowerTableName);
+        return this.buildTableInfo(cols, constraints, idxs, lowerTableName, entityNum, false);
+    }
+
+    private DesignerTable buildTableInfo_youhua(List<DesignerColumn> cols, String tableName,String entityNum) {
+        DesignerTable tableInfo = new DesignerTable();
+        tableInfo.setId(this.getRoute() + "#" + tableName);
+        tableInfo.setComment(new LocaleString(""));
+        tableInfo.setCode(tableName);
+        tableInfo.setName(tableName);
+        Iterator var8;
+        if (cols != null) {
+            var8 = cols.iterator();
+
+            while(var8.hasNext()) {
+                DesignerColumn column = (DesignerColumn)var8.next();
+                tableInfo.getCols().add(DesignerColumn.copy(column));
+            }
+        }
+
+        tableInfo.bindEntityMeta(entityNum, true);
+        return tableInfo;
+    }
+
+
+    private DesignerTable buildTableInfo(List<DesignerColumn> cols, List<DesignerConstaint> constraints, List<DesignerIndex> idxs, String tableName, String entityNum, boolean fastMode) {
+        DesignerTable tableInfo = new DesignerTable();
+        tableInfo.setId(this.getRoute() + "#" + tableName);
+        tableInfo.setComment(new LocaleString(""));
+        tableInfo.setCode(tableName);
+        tableInfo.setName(tableName);
+        Iterator var8;
+        if (cols != null) {
+            var8 = cols.iterator();
+
+            while(var8.hasNext()) {
+                DesignerColumn column = (DesignerColumn)var8.next();
+                tableInfo.getCols().add(DesignerColumn.copy(column));
+            }
+        }
+
+        if (constraints != null) {
+            var8 = constraints.iterator();
+
+            while(var8.hasNext()) {
+                DesignerConstaint constaint = (DesignerConstaint)var8.next();
+                tableInfo.getConstaints().add(DesignerConstaint.copy(constaint));
+            }
+        }
+
+        if (idxs != null) {
+            var8 = idxs.iterator();
+
+            while(var8.hasNext()) {
+                DesignerIndex index = (DesignerIndex)var8.next();
+                tableInfo.getIdxs().add(DesignerIndex.copy(index));
+            }
+        }
+
+        if (distinct) {
+            List<DesignerColumn> distinctCons = new ArrayList();
+            if (!tableInfo.getCols().isEmpty()) {
+                distinctCons = new ArrayList();
+                List<DesignerColumn> colList = tableInfo.getCols();
+                for (DesignerColumn col:colList) {
+                    if (!distinctCons.contains(col)) {
+                        distinctCons.add(col);
+                    }
+                }
+                tableInfo.setCols(distinctCons);
+            }
+
+            if (!tableInfo.getIdxs().isEmpty()) {
+                ArrayList distinctCons_index = new ArrayList();
+                List<DesignerIndex> colList = tableInfo.getIdxs();
+                for (DesignerIndex col:colList) {
+                    if (!distinctCons_index.contains(col)) {
+                        distinctCons_index.add(col);
+                    }
+                }
+                tableInfo.setIdxs(distinctCons_index);
+            }
+
+            if (!tableInfo.getConstaints().isEmpty()) {
+                ArrayList  distinctCons_Constaint = new ArrayList();
+                List<DesignerConstaint> colList = tableInfo.getConstaints();
+                for (DesignerConstaint col:colList) {
+                    if (!distinctCons_Constaint.contains(col)) {
+                        distinctCons_Constaint.add(col);
+                    }
+                }
+                tableInfo.setConstaints(distinctCons_Constaint);
+            }
+        }
+
+        tableInfo.bindEntityMeta(entityNum, fastMode);
+        return tableInfo;
+    }
+
+    public List<DesignerTable> getTableInfoByAppId(List<String> appIds) {
+        QFilter[] filter = new QFilter[]{new QFilter("entryentity.mainentity.bizapp.id", "in", appIds.toArray())};
+        Map<String, Map<String, Set<String>>> routeTables = new CaseInsensitiveMap(appIds.size());
+        Map<String, Map<String, EntityTableUtil.TableInfo>> entityTableMapping = new HashMap(appIds.size());
+        String entityId;
+        Iterator var38;
+        Map.Entry it;
+        if (Boolean.getBoolean("entitytable.export.fastmode")) {
+            DynamicObjectCollection cols = QueryServiceHelper.query("bos_devp_tablediction", "entity.bizapp.dbroute,entity.bizapp.number,tablename,entity.number", filter);
+            Iterator var6 = cols.iterator();
+
+            while(var6.hasNext()) {
+                DynamicObject row = (DynamicObject)var6.next();
+                String dbroute = row.getString("entity.bizapp.dbroute");
+                String tableName = row.getString("tablename");
+                entityId = row.getString("entity.number");
+                routeTables.putIfAbsent(dbroute, new HashMap());
+                ((Map)routeTables.get(dbroute)).putIfAbsent(tableName, new HashSet());
+                ((Set)((Map)routeTables.get(dbroute)).get(tableName)).add(entityId);
+            }
+        } else {
+            SqlBuilder builder = new SqlBuilder();
+            Map<String, Map<String, String>> entityRouteMap = new HashMap(16);
+            builder.append("select t1.fid as entityid,t1.fnumber as entitynum,t2.fdbroute as route from t_meta_formdesign t1 inner join t_meta_bizapp t2 on t1.fbizappid = t2.fid where t1.ftype != '2'  and ", new Object[0]).appendIn("t2.fid", appIds.toArray());
+            DataSet dataSet = DB.queryDataSet("entitytable", DBRoute.meta, builder);
+            Throwable var39 = null;
+
+            try {
+                while(dataSet.hasNext()) {
+                    Row row = dataSet.next();
+                    entityId = row.getString("entityid");
+                    String dbroute = row.getString("route");
+                    String num = row.getString("entitynum");
+                    if (!StringUtils.isBlank(entityId) && !StringUtils.isBlank(dbroute) && !StringUtils.isBlank(num)) {
+                        Map<String, String> entityIds = (Map)entityRouteMap.getOrDefault(dbroute, new HashMap(30));
+                        entityIds.put(entityId, num);
+                        entityRouteMap.put(dbroute, entityIds);
+                    }
+                }
+            } catch (Throwable var31) {
+                var39 = var31;
+                throw var31;
+            } finally {
+                if (dataSet != null) {
+                    if (var39 != null) {
+                        try {
+                            dataSet.close();
+                        } catch (Throwable var28) {
+                            var39.addSuppressed(var28);
+                        }
+                    } else {
+                        dataSet.close();
+                    }
+                }
+
+            }
+
+            var38 = entityRouteMap.entrySet().iterator();
+
+            while(var38.hasNext()) {
+                it = (Map.Entry)var38.next();
+                routeTables.put((String)it.getKey(), new HashMap(50));
+                Iterator var42 = ((Map)it.getValue()).entrySet().iterator();
+
+                while(var42.hasNext()) {
+                    Map.Entry<String, String> idNumEntry = (Map.Entry)var42.next();
+
+                    try {
+                        Map<String, EntityTableUtil.TableInfo> tableRef = EntityTableUtil.getTableRef((String)idNumEntry.getKey());
+                        entityTableMapping.put(idNumEntry.getValue(), tableRef);
+                        Iterator var48 = tableRef.entrySet().iterator();
+
+                        while(var48.hasNext()) {
+                            Map.Entry<String, EntityTableUtil.TableInfo> tables = (Map.Entry)var48.next();
+                            ((Map)routeTables.get(it.getKey())).putIfAbsent(tables.getKey(), new HashSet());
+                            ((Set)((Map)routeTables.get(it.getKey())).get(tables.getKey())).add(idNumEntry.getValue());
+                        }
+                    } catch (Exception var30) {
+                        log.error("导出数据表解析元数据报错:" + var30.getMessage(), var30);
+                    }
+                }
+            }
+        }
+
+        int batchSize = Integer.getInteger("devp.tableprovider.batchsize", 1000);
+        List<DesignerTable> result = new ArrayList(10);
+        var38 = routeTables.entrySet().iterator();
+
+        while(var38.hasNext()) {
+            it = (Map.Entry)var38.next();
+            DBRoute route = DBRoute.of((String)it.getKey());
+
+            try {
+                DB.getDBType(route);
+            } catch (Exception var29) {
+                this.getLog().error(var29);
+                continue;
+            }
+
+            List<String> tables = new ArrayList(((Map)it.getValue()).keySet());
+            int max = tables.size();
+            int i = 0;
+            Map<String, List<DesignerColumn>> colMap = new CaseInsensitiveMap();
+            Map<String, List<DesignerIndex>> indexMap = new CaseInsensitiveMap();
+
+            CaseInsensitiveMap constraintMap;
+            for(constraintMap = new CaseInsensitiveMap(); i <= max; i += batchSize) {
+                int off = i + batchSize > max ? max : i + batchSize;
+                colMap.putAll(this.handler.batchLoadColumns(route, tables.subList(i, off)));
+                indexMap.putAll(this.handler.batchLoadIndexs(route, tables.subList(i, off)));
+                constraintMap.putAll(this.handler.batchLoadConstraints(route, tables.subList(i, off)));
+            }
+
+            Iterator var52 = ((Map)it.getValue()).entrySet().iterator();
+
+            while(var52.hasNext()) {
+                Map.Entry<String, Set<String>> items = (Map.Entry)var52.next();
+
+                DesignerTable designerTable;
+                for(Iterator var18 = ((Set)items.getValue()).iterator(); var18.hasNext(); result.add(designerTable)) {
+                    String entityNum = (String)var18.next();
+                    designerTable = this.buildTableInfo((List)colMap.get(items.getKey()), (List)constraintMap.get(items.getKey()), (List)indexMap.get(items.getKey()), (String)items.getKey(), entityNum, true);
+                    Object extCaption = ((EntityTableUtil.TableInfo)((Map)entityTableMapping.getOrDefault(entityNum, new HashMap(0))).getOrDefault(items.getKey(), new EntityTableUtil.TableInfo())).getExtInfo().get("caption");
+                    if (extCaption instanceof ILocaleString) {
+                        designerTable.setName(extCaption.toString());
+                    }
+                }
+            }
+        }
+
+        return result;
+    }
+
+    protected void setRoute(DBRoute route) {
+        super.setRoute(route);
+        this.initHandler(route);
+    }
+
+    protected void initHandler(DBRoute route) {
+        this.handler = new DefaultTableHandler();
+    }
+
+    interface IGetTableHandler {
+        default List<DesignerColumn> getColumns(DBRoute route, String tablename) {
+            List<String> list = new ArrayList(1);
+            list.add(tablename);
+            return (List)this.batchLoadColumns(route, list).get(tablename);
+        }
+
+
+
+        default List<DesignerIndex> getIndexs(DBRoute route, String tablename) {
+            List<String> list = new ArrayList(1);
+            list.add(tablename);
+            return (List)this.batchLoadIndexs(route, list).get(tablename);
+        }
+
+        default List<DesignerConstaint> getConstraints(DBRoute route, String tablename) {
+            List<String> list = new ArrayList(1);
+            list.add(tablename);
+            return (List)this.batchLoadConstraints(route, list).get(tablename);
+        }
+
+        default Map<String, Object> getTableExtInfo(DBRoute route, String tablename) {
+            return Collections.emptyMap();
+        }
+
+        Map<String, List<DesignerColumn>> batchLoadColumns(DBRoute var1, List<String> var2);
+
+        Map<String, List<DesignerIndex>> batchLoadIndexs(DBRoute var1, List<String> var2);
+
+        Map<String, List<DesignerConstaint>> batchLoadConstraints(DBRoute var1, List<String> var2);
+
+        default Map<String, Map<String, Object>> batchLoadTableExtInfo(DBRoute route, List<String> tableNames) {
+            return Collections.emptyMap();
+        }
+
+        default Map<String, List<String>> getPrimaryKeys(DBType dbType, DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                SqlBuilder builder = new SqlBuilder();
+                List<String> lowerCaseTables = (List)tableNames.stream().map(String::toLowerCase).collect(Collectors.toList());
+                List<String> upCaseTables = (List)tableNames.stream().map(String::toUpperCase).collect(Collectors.toList());
+                if (DBType.Oracle != dbType && DBType.DM != dbType) {
+                    if (DBType.MySQL == dbType) {
+                        builder.append("/*dialect*/select column_name,table_name from information_schema.key_column_usage where TABLE_SCHEMA = schema() and constraint_name= 'PRIMARY' ", new Object[0]).append(" and ", new Object[0]).appendIn("table_name", tableNames.toArray());
+                    } else if (DBType.PostgreSQL == dbType) {
+                        builder.append("/*dialect*/select kcu.column_name,kcu.table_name as key_column from information_schema.table_constraints tco join information_schema.key_column_usage kcu on kcu.constraint_name = tco.constraint_name and kcu.constraint_schema = tco.constraint_schema and kcu.constraint_name = tco.constraint_name where tco.constraint_type = 'PRIMARY KEY' ", new Object[0]).append(" and ", new Object[0]).appendIn("kcu.table_name", lowerCaseTables.toArray()).append(" order by kcu.ordinal_position", new Object[0]);
+                    } else {
+                        if (DBType.SQLServer != dbType) {
+                            throw new RuntimeException("dbType " + dbType.name() + " not supported yet!");
+                        }
+
+                        builder.append("/*dialect*/select c.name,o.name from sysindexes i join sysindexkeys k on i.id = k.id and i.indid = k.indid join sysobjects o on i.id = o.id join syscolumns c on i.id=c.id and k.colid = c.colid where o.xtype = 'U' and exists(select 1 from sysobjects where xtype = 'PK' and name = i.name) ", new Object[0]).append(" and ", new Object[0]).appendIn("o.name", upCaseTables.toArray());
+                    }
+                } else {
+                    builder.append("/*dialect*/select col.column_name,col.table_name from user_constraints con, user_cons_columns col where con.constraint_name = col.constraint_name and con.constraint_type='P'", new Object[0]).append(" and ", new Object[0]).appendIn("col.table_name", upCaseTables.toArray()).append(" order by position", new Object[0]);
+                }
+
+                return (Map)DB.query(route, builder, (rs) -> {
+                    Map<String, List<String>> cols = new HashMap(16);
+
+                    while(rs.next()) {
+                        String table = rs.getString(2);
+                        cols.put(table, new ArrayList());
+                        List<String> list = (List)cols.get(table);
+                        list.add(rs.getString(1));
+                    }
+
+                    return cols;
+                });
+            }
+        }
+    }
+
+    static class DefaultTableHandler implements IGetTableHandler {
+        DefaultTableHandler() {
+        }
+
+        public Map<String, List<DesignerColumn>> batchLoadColumns(DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                List<String> lowerCaseTables = (List)tableNames.stream().map(String::toLowerCase).collect(Collectors.toList());
+                Map<String, Map<String, DesignerColumn>> res = new HashMap(tableNames.size());
+                Iterator var5 = lowerCaseTables.iterator();
+
+                while(var5.hasNext()) {
+                    String lowerTable = (String)var5.next();
+                    res.putIfAbsent(lowerTable, new HashMap());
+                    List<FieldInfo> fields = DB.getFieldInfo(route, lowerTable);
+                    Iterator var8 = fields.iterator();
+
+                    while(var8.hasNext()) {
+                        FieldInfo field = (FieldInfo)var8.next();
+                        DesignerColumn col = new DesignerColumn();
+                        String name = field.getFieldName();
+                        col.setCode(String.valueOf(name));
+                        col.setName(name);
+                        col.setType(field.getDataType());
+                        col.setFullType(field.getDataType());
+                        String desc = "";
+                        col.setComment(new LocaleString(desc));
+                        Object defaultValue = field.getDataDefault();
+                        col.setDefValue(defaultValue == null ? null : String.valueOf(defaultValue));
+                        long fieldLenth = field.getDataLength();
+                        if (fieldLenth == 0L) {
+                            fieldLenth = (long)field.getDataPrecision();
+                        }
+
+                        col.setLength(fieldLenth);
+                        col.setPrecision((long)field.getDataPrecision());
+                        col.setScale(field.getDataScale());
+                        col.setNotnull(!field.isNullable());
+                        ((Map)res.get(lowerTable)).put(name, col);
+                    }
+                }
+
+                Map<String, List<DesignerColumn>> resultData = new HashMap(16);
+                Iterator var17 = res.entrySet().iterator();
+
+                while(var17.hasNext()) {
+                    Map.Entry<String, Map<String, DesignerColumn>> item = (Map.Entry)var17.next();
+                    resultData.put(item.getKey(), new ArrayList(((Map)item.getValue()).values()));
+                }
+
+                return resultData;
+            }
+        }
+
+        public Map<String, List<DesignerIndex>> batchLoadIndexs(DBRoute route, List<String> tableNames) {
+            Map<String, List<DesignerIndex>> datas = new HashMap(tableNames.size());
+            if (tableNames.isEmpty()) {
+                return datas;
+            } else {
+                try {
+                    List<String> lowerCaseTables = (List)tableNames.stream().map(String::toLowerCase).collect(Collectors.toList());
+                    Map<String, List<DesignerIndex>> res = new HashMap(tableNames.size());
+                    Iterator var6 = lowerCaseTables.iterator();
+
+                    while(var6.hasNext()) {
+                        String lowTable = (String)var6.next();
+                        res.putIfAbsent(lowTable, new ArrayList());
+                        List<IndexInfo> indexInfos = DB.getIndexInfo(route, lowTable);
+                        Iterator var9 = indexInfos.iterator();
+
+                        while(var9.hasNext()) {
+                            IndexInfo indexInfo = (IndexInfo)var9.next();
+                            List<DesignerIndex> idxs = (List)res.get(lowTable);
+                            DesignerIndex idx = new DesignerIndex();
+                            String indexName = indexInfo.getIndexName();
+                            idx.setName(indexName);
+                            idx.setCode(indexName);
+                            idx.setIndexdef(IndexType.Common.typeValue);
+                            idx.setIndexType(IndexType.Common);
+                            List<IndexInfo.IndexFieldInfo> indexfieldInfos = indexInfo.getIndexFieldInfo();
+                            List<String> fieldNames = new ArrayList(10);
+                            Iterator var16 = indexfieldInfos.iterator();
+
+                            while(var16.hasNext()) {
+                                IndexInfo.IndexFieldInfo indexfieldInfo = (IndexInfo.IndexFieldInfo)var16.next();
+                                fieldNames.add(indexfieldInfo.getFieldName());
+                            }
+
+                            idx.setRefCols(fieldNames);
+                            idxs.add(idx);
+                        }
+                    }
+
+                    datas.putAll(res);
+                } catch (Exception var18) {
+                    DBTableProviderNew.log.error("数据表查询索引失败:" + var18.getMessage(), var18);
+                }
+
+                return datas;
+            }
+        }
+
+        public Map<String, List<DesignerConstaint>> batchLoadConstraints(DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                List<String> lowerCaseTables = (List)tableNames.stream().map(String::toLowerCase).collect(Collectors.toList());
+                Map<String, List<DesignerConstaint>> res = new HashMap(10);
+                Iterator var5 = lowerCaseTables.iterator();
+
+                while(var5.hasNext()) {
+                    String lowerTable = (String)var5.next();
+                    res.putIfAbsent(lowerTable, new ArrayList());
+                    List<DesignerConstaint> constaints = (List)res.get(lowerTable);
+                    List<String> primaryKeys = DB.getPrimaryKeys(route, lowerTable);
+                    Iterator var9 = primaryKeys.iterator();
+
+                    while(var9.hasNext()) {
+                        String primaryKey = (String)var9.next();
+                        DesignerConstaint constaint = new DesignerConstaint();
+                        constaints.add(constaint);
+                        constaint.setName(primaryKey);
+                        constaint.setCode(primaryKey);
+                        constaint.setRefCols(primaryKeys);
+                        constaint.setConstaintType(ConstaintType.Primary);
+                    }
+                }
+
+                return res;
+            }
+        }
+    }
+
+    static class KSQLTableHandler implements IGetTableHandler {
+        KSQLTableHandler() {
+        }
+
+        public Map<String, List<DesignerColumn>> batchLoadColumns(DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                List<String> lowerCaseTables = (List)tableNames.stream().map(String::toLowerCase).collect(Collectors.toList());
+                SqlBuilder builder = new SqlBuilder();
+                builder.append("SELECT TABLE_NAME,COLUMN_DEFAULT,IS_NULLABLE", new Object[0]).append(",NUMERIC_SCALE,COLUMN_NAME,CHARACTER_MAXIMUM_LENGTH ", new Object[0]).append(",DATA_TYPE  ", new Object[0]).append(",NUMERIC_PRECISION  ", new Object[0]).append("  ", new Object[0]).append(" FROM KSQL_USERCOLUMNS WHERE ", new Object[0]).appendIn("KSQL_TABNAME", lowerCaseTables.toArray());
+                Map<String, Map<String, DesignerColumn>> data = (Map)DB.query(route, builder, (rs) -> {
+                    Map<String, Map<String, DesignerColumn>> result = new HashMap(tableNames.size());
+
+                    while(rs.next()) {
+                        String tableName = rs.getString("TABLE_NAME");
+                        String name = rs.getString("COLUMN_NAME");
+                        result.putIfAbsent(tableName, new HashMap());
+                        DesignerColumn col = new DesignerColumn();
+                        Object defvalue = rs.getObject("COLUMN_DEFAULT");
+                        Object nullable = rs.getObject("IS_NULLABLE");
+                        String type = rs.getString("DATA_TYPE");
+                        Object length = rs.getObject("CHARACTER_MAXIMUM_LENGTH");
+                        Object precision = rs.getObject("NUMERIC_PRECISION");
+                        Object scale = rs.getObject("NUMERIC_SCALE");
+                        String desc = "";
+                        col.setCode(name);
+                        col.setName(name);
+                        col.setType(type);
+                        col.setFullType(type);
+                        col.setComment(new LocaleString(desc));
+                        String defstr = defvalue == null ? null : String.valueOf(defvalue);
+                        col.setDefValue(defstr == null ? null : defstr.split("::")[0]);
+                        col.setLength(length == null ? (long)Integer.parseInt(String.valueOf(precision == null ? "-1" : precision)) : (long)Integer.parseInt(String.valueOf(length)));
+                        col.setScale(scale == null ? 0 : Integer.parseInt(String.valueOf(scale)));
+                        col.setNotnull("NO".equalsIgnoreCase(String.valueOf(nullable)));
+                        ((Map)result.get(tableName)).put(name, col);
+                    }
+
+                    return result;
+                });
+                SqlBuilder typeBuild = new SqlBuilder();
+                typeBuild.append("/*dialect*/", new Object[0]).append(" select c.relname as ftablename,  a.attname   as fname, format_type(a.atttypid, a.atttypmod)  as ffulltype, t.typname  as  ftype   from pg_class c  inner join  pg_attribute a  on a.attrelid = c.oid\n             inner join pg_type t on a.atttypid = t.oid  where a.attnum > 0 and", new Object[0]).appendIn("c.relname", lowerCaseTables.toArray());
+                DB.query(route, typeBuild, (rs) -> {
+                    while(rs.next()) {
+                        String table = rs.getString(1);
+                        String column = rs.getString(2);
+                        if (table != null && column != null) {
+                            String fullType = rs.getString(3);
+                            String type = rs.getString(4);
+                            Map<String, DesignerColumn> items = (Map)data.get(table);
+                            if (items != null) {
+                                DesignerColumn item = (DesignerColumn)items.get(column);
+                                if (item != null) {
+                                    item.setType(type);
+                                }
+                            }
+                        }
+                    }
+
+                    return null;
+                });
+                Map<String, List<DesignerColumn>> resultData = new HashMap(16);
+                Iterator var8 = data.entrySet().iterator();
+
+                while(var8.hasNext()) {
+                    Map.Entry<String, Map<String, DesignerColumn>> item = (Map.Entry)var8.next();
+                    resultData.put(item.getKey(), new ArrayList(((Map)item.getValue()).values()));
+                }
+
+                return resultData;
+            }
+        }
+
+        public Map<String, List<DesignerIndex>> batchLoadIndexs(DBRoute route, List<String> tableNames) {
+            Map<String, List<DesignerIndex>> datas = new HashMap(tableNames.size());
+            if (tableNames.isEmpty()) {
+                return datas;
+            } else {
+                try {
+                    List<String> lowerCaseTables = (List)tableNames.stream().map(String::toLowerCase).collect(Collectors.toList());
+                    SqlBuilder builder = new SqlBuilder();
+                    builder.append(" SELECT ", new Object[0]).append(" INDEXNAME,INDEXDEF,TABLENAME ", new Object[0]).append(" FROM KSQL_INDEXES ", new Object[0]).append(" ", new Object[0]).append(" WHERE ", new Object[0]).appendIn("KSQL_TABNAME", lowerCaseTables.toArray());
+                    datas.putAll((Map)DB.query(route, builder, (rs) -> {
+                        Map<String, List<DesignerIndex>> result = new HashMap(tableNames.size());
+
+                        while(rs.next()) {
+                            String tableName = rs.getString("TABLENAME");
+                            result.putIfAbsent(tableName, new ArrayList());
+                            List<DesignerIndex> idxs = (List)result.get(tableName);
+                            DesignerIndex idx = new DesignerIndex();
+                            String name = rs.getString("INDEXNAME");
+                            String indexof = rs.getString("INDEXDEF");
+                            idx.setName(name);
+                            idx.setCode(name);
+                            idx.setIndexdef(indexof);
+                            idx.setIndexType(IndexType.of(this.exprIndexType(indexof, name)));
+                            idx.setRefCols(this.exprIndexRef(indexof));
+                            idxs.add(idx);
+                        }
+
+                        return result;
+                    }));
+                } catch (Exception var10) {
+                    DBType type = DB.getDBType(route);
+                    if (DBType.MySQL == type) {
+                        Iterator var6 = tableNames.iterator();
+
+                        while(var6.hasNext()) {
+                            String tablename = (String)var6.next();
+                            StringBuilder sbuilder = new StringBuilder();
+                            sbuilder.append("/*dialect*/").append(" show index from ").append(tablename);
+                            datas.putIfAbsent(tablename, new ArrayList());
+                            Map<String, DesignerIndex> tableIndexs = (Map)DB.query(route, sbuilder.toString(), (rs) -> {
+                                Map<String, DesignerIndex> indexMap = new HashMap(5);
+
+                                while(rs.next()) {
+                                    String indexName = rs.getString("Key_name");
+                                    String column = rs.getString("Column_name");
+                                    indexMap.putIfAbsent(indexName, new DesignerIndex());
+                                    DesignerIndex index = (DesignerIndex)indexMap.get(indexName);
+                                    index.setCode(indexName);
+                                    index.setName(indexName);
+                                    index.setComment(new LocaleString(indexName));
+                                    index.getRefCols().add(column);
+                                    index.setTablename(tablename);
+                                }
+
+                                return indexMap;
+                            });
+                            ((List)datas.get(tablename)).addAll(tableIndexs.values());
+                        }
+                    } else {
+                        DBTableProviderNew.log.error("数据表查询索引失败:" + var10.getMessage(), var10);
+                    }
+                }
+
+                return datas;
+            }
+        }
+
+        private List<String> exprIndexRef(String createStr) {
+            int start = createStr.indexOf(40) + 1;
+            int end = createStr.indexOf(41);
+            String data = createStr.substring(start, end);
+            return Arrays.asList(data.split(","));
+        }
+
+        private String exprIndexType(String createStr, String idxNum) {
+            String[] parts = createStr.split(idxNum);
+            int index = parts[0].indexOf(" ") + 1;
+            return parts[0].substring(index);
+        }
+
+        public Map<String, List<DesignerConstaint>> batchLoadConstraints(DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                List<String> lowerCaseTables = (List)tableNames.stream().map(String::toLowerCase).collect(Collectors.toList());
+                SqlBuilder builder = new SqlBuilder();
+                builder.append("SELECT * FROM KSQL_CONSTRAINTS ", new Object[0]).append(" WHERE ", new Object[0]).appendIn("TABLE_NAME", lowerCaseTables.toArray()).append(" and CONSTRAINT_TYPE = 'PRIMARY KEY'", new Object[0]);
+                Map<String, List<String>> pkInfos = this.getPrimaryKeys(DB.getDBType(route), route, lowerCaseTables);
+                return (Map)DB.query(route, builder, (rs) -> {
+                    Map<String, List<DesignerConstaint>> result = new HashMap(10);
+
+                    while(rs.next()) {
+                        String tableName = rs.getString("TABLE_NAME");
+                        List<String> cols = (List)pkInfos.get(tableName);
+                        if (cols != null && !cols.isEmpty()) {
+                            result.putIfAbsent(tableName, new ArrayList());
+                            List<DesignerConstaint> constaints = (List)result.get(tableName);
+                            String name = rs.getString("CONSTRAINT_NAME");
+                            DesignerConstaint constaint = new DesignerConstaint();
+                            constaints.add(constaint);
+                            constaint.setName(name);
+                            constaint.setCode(name);
+                            constaint.getRefCols().addAll(cols);
+                            constaint.setConstaintType(ConstaintType.of(rs.getString("CONSTRAINT_TYPE")));
+                        }
+                    }
+
+                    return result;
+                });
+            }
+        }
+    }
+
+    static class PostgreSQLHandler implements IGetTableHandler {
+        PostgreSQLHandler() {
+        }
+
+        private boolean isNumricType(String type) {
+            return "numeric".equalsIgnoreCase(type);
+        }
+
+        private List<String> exprIndexRef(String createStr) {
+            int start = createStr.indexOf(40) + 1;
+            int end = createStr.indexOf(41);
+            String data = createStr.substring(start, end);
+            return Arrays.asList(data.split(","));
+        }
+
+        private String exprIndexType(String createStr, String idxNum) {
+            String[] parts = createStr.split(idxNum);
+            int index = parts[0].indexOf(" ") + 1;
+            return parts[0].substring(index);
+        }
+
+        public Map<String, List<DesignerColumn>> batchLoadColumns(DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                List<String> lowerCaseTables = (List)tableNames.stream().map(String::toLowerCase).collect(Collectors.toList());
+                SqlBuilder builder = new SqlBuilder();
+                builder.append("/*dialect*/ select distinct  c.relname as ftablename,\n", new Object[0]).append("a.attname   as fname,\n", new Object[0]).append("format_type(a.atttypid, a.atttypmod)  as ffulltype,\n", new Object[0]).append("(case when a.attlen > 0 then a.attlen else a.atttypmod - 4 end) as flength,\n", new Object[0]).append(" a.attnotnull      as fnullable,\n", new Object[0]).append(" pg_get_expr(d.adbin,d.adrelid)          as fdefvalue,\n", new Object[0]).append(" col_description(a.attrelid, a.attnum)                           as fdesc,\n", new Object[0]).append(" a.attlen   as   fattlen,    a.atttypmod   as    fatttypmod     ,t.typname  as  ftype", new Object[0]).append(" from pg_class c,\n", new Object[0]).append(" pg_attribute a\n", new Object[0]).append(" inner join (select  distinct a.attname, ad.adbin,ad.adrelid\n", new Object[0]).append(" from pg_class c,\n", new Object[0]).append(" pg_attribute a,\n", new Object[0]).append(" pg_attrdef ad,\n", new Object[0]).append(" pg_type t", new Object[0]).append(" where ", new Object[0]).appendIn("relname", lowerCaseTables.toArray()).append(" and ad.adrelid = c.oid\n", new Object[0]).append(" and adnum = a.attnum\n", new Object[0]).append(" and attrelid = c.oid) as d on a.attname = d.attname\n", new Object[0]).append("  , pg_type t ", new Object[0]).append("where ", new Object[0]).appendIn("c.relname", lowerCaseTables.toArray()).append("  and a.attrelid = c.oid\n", new Object[0]).append("  and a.attnum > 0 and a.atttypid = t.oid;", new Object[0]);
+                return (Map)DB.query(route, builder, (rs) -> {
+                    HashMap result;
+                    List cols;
+                    DesignerColumn col;
+                    for(result = new HashMap(16); rs.next(); cols.add(col)) {
+                        String tableName = rs.getString("ftablename");
+                        result.putIfAbsent(tableName, new ArrayList());
+                        cols = (List)result.get(tableName);
+                        col = new DesignerColumn();
+                        String name = rs.getString("fname");
+                        String type = rs.getString("ftype");
+                        int lenght = rs.getInt("flength");
+                        boolean nullable = rs.getBoolean("fnullable");
+                        Object defvalue = rs.getObject("fdefvalue");
+                        String desc = rs.getString("fdesc");
+                        col.setCode(name);
+                        col.setName(name);
+                        col.setType(type);
+                        col.setFullType(rs.getString("ffulltype"));
+                        Integer atttypmod = rs.getInt("fatttypmod");
+                        col.setLength((long)lenght);
+                        if (this.isNumricType(type)) {
+                            int precision = atttypmod - 4 >> 16 & '\uffff';
+                            int scale = atttypmod - 4 & '\uffff';
+                            col.setLength((long)precision);
+                            col.setPrecision((long)precision);
+                            col.setScale(scale);
+                        }
+
+                        col.setNotnull(!nullable);
+                        String defstr = defvalue == null ? null : String.valueOf(defvalue);
+                        col.setDefValue(defstr == null ? null : defstr.split("::")[0]);
+                        if (StringUtils.isNotBlank(desc)) {
+                            col.setComment(new LocaleString(desc));
+                        } else {
+                            col.setComment(new LocaleString(name));
+                        }
+                    }
+
+                    return result;
+                });
+            }
+        }
+
+        public Map<String, List<DesignerIndex>> batchLoadIndexs(DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                List<String> lowerCaseTables = (List)tableNames.stream().map(String::toLowerCase).collect(Collectors.toList());
+                SqlBuilder builder = new SqlBuilder();
+                builder.append("/*dialect*/", new Object[0]).append(" SELECT TABLENAME,INDEXNAME,INDEXDEF ", new Object[0]).append(" FROM PG_INDEXES ", new Object[0]).append(" WHERE ", new Object[0]).appendIn("TABLENAME", lowerCaseTables.toArray());
+                return (Map)DB.query(route, builder, (rs) -> {
+                    Map<String, List<DesignerIndex>> result = new HashMap(tableNames.size());
+
+                    while(rs.next()) {
+                        String tableName = rs.getString(1);
+                        result.putIfAbsent(tableName, new ArrayList());
+                        List<DesignerIndex> idxs = (List)result.get(tableName);
+                        DesignerIndex idx = new DesignerIndex();
+                        String name = rs.getString(2);
+                        String indexof = rs.getString(3);
+                        idx.setName(name);
+                        idx.setCode(name);
+                        idx.setIndexdef(indexof);
+                        idx.setIndexType(IndexType.of(this.exprIndexType(indexof, name)));
+                        idx.setRefCols(this.exprIndexRef(indexof));
+                        idxs.add(idx);
+                    }
+
+                    return result;
+                });
+            }
+        }
+
+        public Map<String, List<DesignerConstaint>> batchLoadConstraints(DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                List<String> lowerCaseTables = (List)tableNames.stream().map(String::toLowerCase).collect(Collectors.toList());
+                SqlBuilder builder = new SqlBuilder();
+                builder.append("/*dialect*/", new Object[0]).append(" SELECT TC.TABLE_NAME,TC.CONSTRAINT_NAME, KCU.COLUMN_NAME,", new Object[0]).append(" TC.CONSTRAINT_TYPE ", new Object[0]).append(" FROM ", new Object[0]).append(" INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC \n", new Object[0]).append(" JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU ON TC.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME ", new Object[0]).append(" JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS CCU ON CCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME ", new Object[0]).append(" WHERE  ", new Object[0]).appendIn("TC.TABLE_NAME", lowerCaseTables.toArray());
+                return (Map)DB.query(route, builder, (rs) -> {
+                    Map<String, List<DesignerConstaint>> result = new HashMap(10);
+
+                    while(rs.next()) {
+                        String tableName = rs.getString(1);
+                        result.putIfAbsent(tableName, new ArrayList());
+                        List<DesignerConstaint> constaints = (List)result.get(tableName);
+                        String name = rs.getString(2);
+                        DesignerConstaint constaint = new DesignerConstaint();
+                        constaints.add(constaint);
+                        constaint.setName(name);
+                        constaint.setCode(name);
+                        constaint.setComment(new LocaleString(""));
+                        constaint.getRefCols().add(rs.getString(3));
+                        constaint.setConstaintType(ConstaintType.of(rs.getString(4)));
+                    }
+
+                    return result;
+                });
+            }
+        }
+    }
+
+    static class OracleHandler implements IGetTableHandler {
+        OracleHandler() {
+        }
+
+        public Map<String, List<DesignerColumn>> batchLoadColumns(DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                List<String> upperTables = (List)tableNames.stream().map(String::toUpperCase).collect(Collectors.toList());
+                SqlBuilder builder = new SqlBuilder();
+                builder.append("/*dialect*/", new Object[0]).append("select ", new Object[0]).append("T.TABLE_NAME AS TABLENAME,T.COLUMN_NAME AS COLUMNNAME, T.DATA_TYPE AS COLTYPE, T.DATA_LENGTH LENGTH,T.DATA_PRECISION AS COLPRECISION,T.DATA_SCALE AS COLSCALE,T.NULLABLE AS NULLABLE,C.COMMENTS  AS COMMENTS ,T.DATA_DEFAULT AS COLDEFAULT ", new Object[0]).append(" FROM USER_TAB_COLUMNS T, USER_COL_COMMENTS C WHERE T.TABLE_NAME = C.TABLE_NAME AND T.COLUMN_NAME = C.COLUMN_NAME AND ", new Object[0]).appendIn("T.TABLE_NAME", upperTables.toArray());
+                return (Map)DB.query(route, builder, (rs) -> {
+                    Map<String, List<DesignerColumn>> result = new CaseInsensitiveMap(tableNames.size());
+
+                    while(rs.next()) {
+                        String tableName = rs.getString("TABLENAME");
+                        result.putIfAbsent(tableName, new ArrayList());
+                        List<DesignerColumn> dbcols = (List)result.get(tableName);
+                        DesignerColumn col = new DesignerColumn();
+                        String name = rs.getString("COLUMNNAME");
+                        Object nullable = rs.getObject("NULLABLE");
+                        String type = rs.getString("COLTYPE");
+                        Object length = rs.getObject("LENGTH");
+                        Object precision = rs.getObject("COLPRECISION");
+                        Object scale = rs.getObject("COLSCALE");
+                        Object comment = rs.getObject("COMMENTS");
+                        Object defvalue = rs.getObject("COLDEFAULT");
+                        String desc = comment == null ? "" : comment.toString();
+                        col.setCode(name);
+                        col.setName(name);
+                        col.setType(type);
+                        col.setFullType(type);
+                        col.setComment(new LocaleString(desc));
+                        col.setDefValue(defvalue == null ? null : String.valueOf(defvalue));
+
+                        try {
+                            col.setLength(precision == null ? (long)Integer.parseInt(String.valueOf(length)) : (long)Integer.parseInt(String.valueOf(precision)));
+                        } catch (Exception var16) {
+                            col.setLength(-1L);
+                        }
+
+                        col.setScale(scale == null ? 0 : Integer.parseInt(String.valueOf(scale)));
+                        col.setNotnull("N".equalsIgnoreCase(String.valueOf(nullable)));
+                        dbcols.add(col);
+                    }
+
+                    return result;
+                });
+            }
+        }
+
+        public Map<String, List<DesignerIndex>> batchLoadIndexs(DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                List<String> upperTables = (List)tableNames.stream().map(String::toUpperCase).collect(Collectors.toList());
+                SqlBuilder builder = new SqlBuilder();
+                builder.append("/*dialect*/", new Object[0]).append("SELECT T1.INDEX_NAME , T1.INDEX_TYPE, T1.UNIQUENESS,T1.TABLE_NAME, T2.COLUMN_NAME FROM USER_INDEXES T1 ", new Object[0]).append("INNER JOIN  USER_IND_COLUMNS T2  ON T1.INDEX_NAME = T2.INDEX_NAME  WHERE ", new Object[0]).appendIn("T1.TABLE_NAME", upperTables.toArray());
+                Map<String, Map<String, DesignerIndex>> queryResult = (Map)DB.query(route, builder, (rs) -> {
+                    Map<String, Map<String, DesignerIndex>> result = new CaseInsensitiveMap(tableNames.size());
+
+                    while(rs.next()) {
+                        String tableName = rs.getString("TABLE_NAME");
+                        result.putIfAbsent(tableName, new CaseInsensitiveMap());
+                        Map<String, DesignerIndex> idxs = (Map)result.get(tableName);
+                        String name = rs.getString("INDEX_NAME");
+                        Object unique = rs.getObject("UNIQUENESS");
+                        DesignerIndex idx = (DesignerIndex)idxs.getOrDefault(name, new DesignerIndex());
+                        idxs.put(name, idx);
+                        idx.setName(name);
+                        idx.setTablename(tableName);
+                        idx.setCode(name);
+                        idx.getRefCols().add(rs.getString("COLUMN_NAME"));
+                        if ("unique".equalsIgnoreCase(String.valueOf(unique))) {
+                            idx.setIndexType(IndexType.Unique);
+                        } else {
+                            String type = rs.getString("INDEX_TYPE");
+                            idx.setIndexType(IndexType.of(type));
+                        }
+                    }
+
+                    return result;
+                });
+                Map<String, List<DesignerIndex>> resultData = new CaseInsensitiveMap(16);
+                Iterator var7 = queryResult.entrySet().iterator();
+
+                while(var7.hasNext()) {
+                    Map.Entry<String, Map<String, DesignerIndex>> item = (Map.Entry)var7.next();
+                    resultData.put(item.getKey(), new ArrayList(((Map)item.getValue()).values()));
+                }
+
+                return resultData;
+            }
+        }
+
+        public Map<String, List<DesignerConstaint>> batchLoadConstraints(DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                List<String> upperTables = (List)tableNames.stream().map(String::toUpperCase).collect(Collectors.toList());
+                SqlBuilder builder = new SqlBuilder();
+                builder.append("/*dialect*/", new Object[0]).append("SELECT ", new Object[0]).append("  USER_CONS_COLUMNS.CONSTRAINT_NAME AS CONNAME , USER_CONS_COLUMNS.TABLE_NAME AS TABLENAME ,USER_CONS_COLUMNS.COLUMN_NAME AS COLNAME ", new Object[0]).append(" FROM USER_CONSTRAINTS JOIN USER_CONS_COLUMNS ON (USER_CONSTRAINTS.CONSTRAINT_NAME = USER_CONS_COLUMNS.CONSTRAINT_NAME) WHERE ", new Object[0]).append(" CONSTRAINT_TYPE = 'P' AND", new Object[0]).appendIn("USER_CONS_COLUMNS.TABLE_NAME", upperTables.toArray());
+                Map<String, Map<String, DesignerConstaint>> data = (Map)DB.query(route, builder, (rs) -> {
+                    Map<String, Map<String, DesignerConstaint>> result = new CaseInsensitiveMap();
+
+                    while(rs.next()) {
+                        String tableName = rs.getString("TABLENAME");
+                        String name = rs.getString("CONNAME");
+                        result.putIfAbsent(tableName, new HashMap());
+                        ((Map)result.get(tableName)).putIfAbsent(name, new DesignerConstaint());
+                        DesignerConstaint constaint = (DesignerConstaint)((Map)result.get(tableName)).get(name);
+                        constaint.setName(name);
+                        constaint.setCode(name);
+                        constaint.setComment(new LocaleString(""));
+                        constaint.getRefCols().add(rs.getString(3));
+                        constaint.setConstaintType(ConstaintType.Primary);
+                    }
+
+                    return result;
+                });
+                Map<String, List<DesignerConstaint>> resultData = new CaseInsensitiveMap(16);
+                Iterator var7 = data.entrySet().iterator();
+
+                while(var7.hasNext()) {
+                    Map.Entry<String, Map<String, DesignerConstaint>> item = (Map.Entry)var7.next();
+                    resultData.put(item.getKey(), new ArrayList(((Map)item.getValue()).values()));
+                }
+
+                return resultData;
+            }
+        }
+    }
+
+    static class MySQLHandler implements IGetTableHandler {
+        MySQLHandler() {
+        }
+
+        public Map<String, List<DesignerColumn>> batchLoadColumns(DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                List<String> lowerCaseTables = (List)tableNames.stream().map(String::toLowerCase).collect(Collectors.toList());
+                String schema = this.getTableScheme(route);
+                SqlBuilder builder = new SqlBuilder();
+                builder.append("/*dialect*/", new Object[0]).append(" SELECT TABLE_NAME,COLUMN_NAME ,COLUMN_DEFAULT ,IS_NULLABLE ,DATA_TYPE ,CHARACTER_MAXIMUM_LENGTH ,NUMERIC_PRECISION ,NUMERIC_SCALE,COLLATION_NAME ,COLUMN_KEY ,COLUMN_COMMENT,COLUMN_TYPE  ", new Object[0]).append(" FROM information_schema.COLUMNS ", new Object[0]).append(" WHERE ", new Object[0]);
+                if (StringUtils.isNotBlank(schema)) {
+                    builder.append(" TABLE_SCHEMA = ? ", new Object[]{new SqlParameter(":TABLE_SCHEMA", 12, schema)}).append(" AND ", new Object[0]);
+                }
+
+                builder.appendIn(" TABLE_NAME ", lowerCaseTables.toArray());
+                Map<String, List<DesignerColumn>> data = (Map)DB.query(route, builder, (rs) -> {
+                    Map<String, List<DesignerColumn>> result = new HashMap(tableNames.size());
+
+                    while(rs.next()) {
+                        String tableName = rs.getString("TABLE_NAME");
+                        result.putIfAbsent(tableName, new ArrayList());
+                        List<DesignerColumn> dbcols = (List)result.get(tableName);
+                        DesignerColumn col = new DesignerColumn();
+                        String name = rs.getString("COLUMN_NAME");
+                        Object defvalue = rs.getObject("COLUMN_DEFAULT");
+                        Object nullable = rs.getObject("IS_NULLABLE");
+                        String type = rs.getString("DATA_TYPE");
+                        Object length = rs.getObject("CHARACTER_MAXIMUM_LENGTH");
+                        Object precision = rs.getObject("NUMERIC_PRECISION");
+                        Object scale = rs.getObject("NUMERIC_SCALE");
+                        Object comment = rs.getObject("COLUMN_COMMENT");
+                        String desc = comment == null ? "" : comment.toString();
+                        col.setCode(name);
+                        col.setName(name);
+                        col.setType(type);
+                        col.setFullType(rs.getString("COLUMN_TYPE"));
+                        col.setComment(new LocaleString(desc));
+                        col.setDefValue(defvalue == null ? null : String.valueOf(defvalue));
+
+                        try {
+                            col.setScale(scale == null ? 0 : Integer.parseInt(String.valueOf(scale)));
+                            col.setLength(length == null ? (precision == null ? -1L : Long.parseLong(String.valueOf(precision))) : Long.parseLong(String.valueOf(length)));
+                            col.setPrecision(col.getLength());
+                        } catch (Exception var16) {
+                            col.setLength(-1L);
+                            col.setScale(0);
+                        }
+
+                        col.setNotnull("NO".equalsIgnoreCase(String.valueOf(nullable)));
+                        dbcols.add(col);
+                    }
+
+                    return result;
+                });
+                return data;
+            }
+        }
+
+        private String getTableScheme(DBRoute route) {
+            String schema = null;
+
+            try {
+                schema = TX.__getConnection(route.getRouteKey(), true).getSchema();
+                return schema;
+            } catch (SQLException var4) {
+                throw new KDException(new ErrorCode("env.tablequery.err", "query databasename err"), new Object[]{var4});
+            }
+        }
+
+        public Map<String, List<DesignerIndex>> batchLoadIndexs(DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                List<String> lowerCaseTables = (List)tableNames.stream().map(String::toLowerCase).collect(Collectors.toList());
+                Map<String, List<DesignerIndex>> result = new HashMap(16);
+                Iterator var5 = lowerCaseTables.iterator();
+
+                while(var5.hasNext()) {
+                    String tablename = (String)var5.next();
+                    result.putIfAbsent(tablename, new ArrayList());
+
+                    try {
+                        StringBuilder sbuilder = new StringBuilder();
+                        sbuilder.append("/*dialect*/").append(" show index from ").append(tablename);
+                        Map<String, DesignerIndex> tableIndexs = (Map)DB.query(route, sbuilder.toString(), (Object[])null, (rs) -> {
+                            Map<String, DesignerIndex> indexMap = new HashMap(5);
+
+                            while(rs.next()) {
+                                String indexName = rs.getString("Key_name");
+                                String column = rs.getString("Column_name");
+                                indexMap.putIfAbsent(indexName, new DesignerIndex());
+                                DesignerIndex index = (DesignerIndex)indexMap.get(indexName);
+                                index.setCode(indexName);
+                                index.setName(indexName);
+                                String uniqueStr = rs.getString("Non_unique");
+                                if ("0".equals(uniqueStr)) {
+                                    index.setIndexType(IndexType.Unique);
+                                } else {
+                                    index.setIndexType(IndexType.Common);
+                                }
+
+                                index.setIndexdef("");
+                                index.setComment(new LocaleString(indexName));
+                                index.getRefCols().add(column);
+                                index.setTablename(tablename);
+                            }
+
+                            return indexMap;
+                        });
+                        ((List)result.get(tablename)).addAll(tableIndexs.values());
+                    } catch (Exception var9) {
+                        DBTableProviderNew.log.error("devp.DBTableProviderNew.err", var9);
+                    }
+                }
+
+                return result;
+            }
+        }
+
+        public Map<String, List<DesignerConstaint>> batchLoadConstraints(DBRoute route, List<String> tableNames) {
+            if (tableNames.isEmpty()) {
+                return new HashMap();
+            } else {
+                List<String> lowerCaseTables = (List)tableNames.stream().map(String::toLowerCase).collect(Collectors.toList());
+                String schema = this.getTableScheme(route);
+                SqlBuilder builder = new SqlBuilder();
+                builder.append("/*dialect*/", new Object[0]).append("select  CONSTRAINT_NAME ,CONSTRAINT_TYPE,TABLE_NAME   FROM information_schema.TABLE_CONSTRAINTS ", new Object[0]).append(" WHERE ", new Object[0]);
+                if (StringUtils.isNotBlank(schema)) {
+                    builder.append("  CONSTRAINT_SCHEMA = ? ", new Object[]{new SqlParameter(":CONSTRAINT_SCHEMA", 12, schema)}).append(" AND ", new Object[0]);
+                }
+
+                builder.appendIn("TABLE_NAME", lowerCaseTables.toArray());
+                Map<String, List<String>> pkInfos = this.getPrimaryKeys(DB.getDBType(route), route, lowerCaseTables);
+                Map<String, Map<String, DesignerConstaint>> data = (Map)DB.query(route, builder, (rs) -> {
+                    Map<String, Map<String, DesignerConstaint>> result = new HashMap(16);
+
+                    while(rs.next()) {
+                        String tableName = rs.getString("TABLE_NAME");
+                        result.putIfAbsent(tableName, new HashMap());
+                        List<String> cols = (List)pkInfos.get(tableName);
+                        if (cols != null && !cols.isEmpty()) {
+                            Map<String, DesignerConstaint> constaints = (Map)result.get(tableName);
+                            String name = rs.getString("CONSTRAINT_NAME");
+                            DesignerConstaint constaint = (DesignerConstaint)constaints.getOrDefault(name, new DesignerConstaint());
+                            constaints.put(name, constaint);
+                            constaint.setName(name);
+                            constaint.setCode(name);
+                            constaint.setComment(new LocaleString(""));
+                            if (constaint.getRefCols().isEmpty()) {
+                                constaint.getRefCols().add(cols.get(0));
+                            } else {
+                                constaint.getRefCols().set(0, cols.get(0));
+                            }
+
+                            constaint.setConstaintType(ConstaintType.of(rs.getString("CONSTRAINT_TYPE")));
+                        }
+                    }
+
+                    return result;
+                });
+                Map<String, List<DesignerConstaint>> returnData = new HashMap(data.size());
+                data.forEach((k, v) -> {
+                    returnData.put(k, new ArrayList(v.values()));
+                });
+                return returnData;
+            }
+        }
+    }
+}

+ 58 - 33
src/main/java/kd/bos/newdevportal/table/TableListPlugin.java

@@ -6,12 +6,11 @@ import kd.bos.db.DBRoute;
 import kd.bos.entity.EntityMetadataCache;
 import kd.bos.entity.datamodel.ListSelectedRow;
 import kd.bos.entity.datamodel.ListSelectedRowCollection;
-import kd.bos.exception.KDException;
 import kd.bos.form.control.events.ItemClickEvent;
 import kd.bos.list.BillList;
 import kd.bos.metadata.dao.MetadataDao;
-import java.util.EventObject;
-import java.util.Iterator;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * TableListPlugin 添加表注释和表字段注释
@@ -33,10 +32,10 @@ public class TableListPlugin extends TableManagerListPlugin {
         if ("nckd_remark".equals(itemKey)) {
             BillList billList = (BillList)this.getControl("billlistap");
             ListSelectedRowCollection list =  billList.getSelectedRows();
+            Map<String, List<String >> entityIdGroups = new HashMap<>();
             // 统计成功和失败的次数
             int successCount = 0;
             int failureCount = 0;
-
             for (ListSelectedRow detail : list) {
                 Object pk = detail.getPrimaryKeyValue();
                 String pkStr = String.valueOf(pk);
@@ -45,43 +44,69 @@ public class TableListPlugin extends TableManagerListPlugin {
                     failureCount++; // 如果数据不正确,增加失败计数
                     continue; // 跳过此条记录,继续处理下一条
                 }
-
                 //获取数据字典明细
                 String tablename = info[0];//表名称
                 String entityId = info[1];//id
                 String dbroute = EntityMetadataCache.getDataEntityType(MetadataDao.getEntityNumberById(info[1])).getDBRouteKey();
-                TableInfoProvider provider = TableInfoProvider.create(DBRoute.of(dbroute == null ? "sys" : dbroute));
-                String refEntityNum =  StringUtils.isNotBlank(entityId) ? MetadataDao.getNumberById(entityId) : null;
-                DesignerTable table =  provider.getTableInfo(tablename == null ? "t_bd_attachment" : tablename, refEntityNum);
+                // 根据 dbroute 将数据分组
+                entityIdGroups.computeIfAbsent(dbroute, k -> new ArrayList<>()).add(pkStr);
+            }
+            // 打印每个分组的 tablename
+            for (Map.Entry<String, List<String >> entry : entityIdGroups.entrySet()) {
+                String dbroute = entry.getKey();
+                List<String> pks = entry.getValue();
+                // 使用 Stream 提取 tableNames 和 entityIds
+                List<String> tableNames = pks.stream()
+                        .map(pkStr -> pkStr.split("@@")) // 分割字符串
+                        .filter(info -> info.length >= 2) // 过滤出有效数据
+                        .map(info -> info[0]) // 提取表名称
+                        .collect(Collectors.toList()); // 收集为 List
 
-                //表注释
-                String comment = table.getName();
-                StringBuilder sql = new StringBuilder();
-                if (table != null) {
-                    sql.append("/*dialect*/ COMMENT ON TABLE " + tablename + " IS '" + comment + "';");
-                    //获取表字段
-                    Iterator fields = table.getCols().iterator();
-                    while(fields.hasNext()) {
-                        DesignerColumn col = (DesignerColumn)fields.next();
-                        String f_fieldkey = col.getCode();//字段标识
-                        String f_fieldname = col.getName();//字段名称
-                        sql.append("/*dialect*/ COMMENT ON COLUMN " + tablename + "." +f_fieldkey + " IS '" + f_fieldname + "';");
-                    }
-                    // 获取SQL字符串
-                    String sqlContent = sql.toString();
+                List<String> entityIds = pks.stream()
+                        .map(pkStr -> pkStr.split("@@")) // 分割字符串
+                        .filter(info -> info.length >= 2) // 过滤出有效数据
+                        .map(info -> info[1]) // 提取表名称
+                        .collect(Collectors.toList()); // 收集为 List
+
+                // 根据 entityId 列表生成 refEntityNum 列表
+                List<String> refEntityNums = entityIds.stream()
+                        .map(entityId -> StringUtils.isNotBlank(entityId) ? MetadataDao.getNumberById(entityId) : null)
+                        .collect(Collectors.toList());
+
+                DBTableProviderNew provider =new DBTableProviderNew();
+                provider.setRoute(DBRoute.of(dbroute == null ? "sys" : dbroute));
+                Map<String,DesignerTable> tableMap =  provider.getTableInfo_youhua(tableNames,refEntityNums);
+                for (Map.Entry<String, DesignerTable> table : tableMap.entrySet()) {
+                    String tablename = table.getKey();
+                    DesignerTable designerTable = table.getValue();
+                    String comment = designerTable.getName();
+                    StringBuilder sql = new StringBuilder();
+                    if (table != null) {
+                        sql.append("/*dialect*/ COMMENT ON TABLE " + tablename + " IS '" + comment + "';");
+                        //获取表字段
+                        Iterator fields = designerTable.getCols().iterator();
+                        while(fields.hasNext()) {
+                            DesignerColumn col = (DesignerColumn)fields.next();
+                            String f_fieldkey = col.getCode();//字段标识
+                            String f_fieldname = col.getName();//字段名称
+                            sql.append("/*dialect*/ COMMENT ON COLUMN " + tablename + "." +f_fieldkey + " IS '" + f_fieldname + "';");
+                        }
+                        // 获取SQL字符串
+                        String sqlContent = sql.toString();
 
-                    try {
-                        //执行
-                        DBRoute route = DBRoute.of(dbroute);
-                        DB.execute(route, sqlContent);
-                        successCount++; // 增加成功计数
-                    } catch (Exception e) {
-                        // 处理执行过程中可能出现的异常
-                        e.printStackTrace(); // 可以替换为日志记录
+                        try {
+                            //执行
+                            DBRoute route = DBRoute.of(dbroute);
+                            DB.execute(route, sqlContent);
+                            successCount++; // 增加成功计数
+                        } catch (Exception e) {
+                            // 处理执行过程中可能出现的异常
+                            e.printStackTrace(); // 可以替换为日志记录
+                            failureCount++; // 增加失败计数
+                        }
+                    }else {
                         failureCount++; // 增加失败计数
                     }
-                }else {
-                    failureCount++; // 增加失败计数
                 }
             }
             // 显示最终的成功和失败消息

+ 314 - 0
src/main/java/sys/sc/formplugin/ABillServiceHelper.java

@@ -0,0 +1,314 @@
+package sys.sc.formplugin;
+
+import kd.bos.base.BaseShowParameter;
+import kd.bos.bill.BillShowParameter;
+import kd.bos.bill.OperationStatus;
+import kd.bos.dataentity.OperateOption;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.db.tx.TX;
+import kd.bos.db.tx.TXHandle;
+import kd.bos.dlock.DLock;
+import kd.bos.entity.BasedataEntityType;
+import kd.bos.entity.BillEntityType;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.MainEntityType;
+import kd.bos.entity.operate.result.OperationResult;
+import kd.bos.form.CloseCallBack;
+import kd.bos.form.FormShowParameter;
+import kd.bos.form.IFormView;
+import kd.bos.form.ShowType;
+import kd.bos.mvc.SessionManager;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.bos.servicehelper.operation.OperationServiceHelper;
+import sys.sc.opplugin.utils.ReflectUtils;
+
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * @Des 单据帮助类
+ * @Author jiang
+ */
+
+public class ABillServiceHelper {
+
+    /**
+     * 执行单据操作
+     *
+     * @param operationKey 单据上操作代码
+     * @param formId       单据实体编码
+     * @param dataEntities 单据数据包
+     * @param option       option
+     * @return 操作结果
+     */
+    public static OperationResult executeOperate(String operationKey, String formId, DynamicObject[] dataEntities, OperateOption option) {
+        return OperationServiceHelper.executeOperate(operationKey, formId, dataEntities, option);
+    }
+
+    /**
+     * 执行单据操作
+     *
+     * @param operationKey 单据上操作代码
+     * @param formId       单据实体编码
+     * @param ids          单据id集合
+     * @param option       option
+     * @return 操作结果
+     */
+    public static OperationResult executeOperate(String operationKey, String formId, Object[] ids, OperateOption option) {
+        return OperationServiceHelper.executeOperate(operationKey, formId, ids, option);
+    }
+
+    /**
+     * 创建新增界面模型
+     *
+     * @param formId 单据实体编码
+     * @return 界面模型
+     */
+    public static IFormView createAddView(String formId) {
+        FormShowParameter parameter = getShowParameter(formId);
+        return createViewByShowParameter(parameter);
+    }
+
+    /**
+     * 通过打开参数创建view
+     *
+     * @param parameter 打开参数
+     * @return 界面模型
+     */
+    public static IFormView createViewByShowParameter(FormShowParameter parameter) {
+        invokeFormServiceMethod(parameter);
+        return SessionManager.getCurrent().getView(parameter.getPageId());
+    }
+
+    /**
+     * 创建修改界面模型
+     *
+     * @param formId 单据实体编码
+     * @param id     id
+     * @return 界面模型
+     */
+    public static IFormView createModifyView(String formId, String id) {
+        FormShowParameter parameter = getModifyParameter(formId, id);
+        return createViewByShowParameter(parameter);
+    }
+
+    /**
+     * 修改单据并创建修改锁
+     *
+     * @param formId 单据实体编码
+     * @param id     id
+     * @param view   view回调
+     * @param action 操作回调
+     * @return 操作结果
+     */
+    public static OperationResult modifyFormWithLock(String formId, String id, Consumer<IFormView> view,
+                                                     Function<IFormView, OperationResult> action) {
+        DLock lock = DLock.create(formId + id, "createModifyView" + formId + id);
+        lock.lock();
+        OperationResult result;
+        try {
+            IFormView modifyView = createModifyView(formId, id);
+            view.accept(modifyView);
+            result = action.apply(modifyView);
+            exitView(modifyView);
+        } finally {
+            lock.unlock();
+        }
+        return result;
+    }
+
+    /**
+     * 执行保存操作并不受到外围事务的影响
+     *
+     * @param view 单据视图
+     * @return 操作结果
+     */
+    public static OperationResult saveOperateWithNoTx(IFormView view) {
+        try (TXHandle ignored = TX.notSupported()) {
+            return saveOperate(view);
+        }
+    }
+
+    /**
+     * 执行保存操作并不受到外围事务的影响
+     *
+     * @param view      单据视图
+     * @param autoAudit 是否自动提交审核
+     * @return 操作结果
+     */
+    public static OperationResult saveOperateWithNoTx(IFormView view, boolean autoAudit) {
+        try (TXHandle ignored = TX.notSupported()) {
+            return saveOperate(view, autoAudit);
+        }
+    }
+
+    /**
+     * 执行保存操作并且受外围事务的影响
+     *
+     * @param view 单据视图
+     * @return 操作结果
+     */
+    public static OperationResult saveOperate(IFormView view) {
+        OperationResult result;
+        try {
+            result = view.invokeOperation("save");
+        } finally {
+            exitView(view);
+        }
+        return result;
+    }
+
+    /**
+     * 执行保存操作并且受外围事务的影响
+     *
+     * @param view      单据视图
+     * @param autoAudit 是否自动提交审核
+     * @return 操作结果
+     */
+    public static OperationResult saveOperate(IFormView view, boolean autoAudit) {
+        OperationResult result = saveOperate(view);
+        if (autoAudit) {
+            if (result.isSuccess()) {
+                IFormView modifyView = createModifyView(view.getEntityId(), result.getSuccessPkIds().get(0).toString());
+                try {
+                    result = modifyView.invokeOperation("submit");
+                    if (result.isSuccess()) {
+                        result = modifyView.invokeOperation("audit");
+                    }
+                } finally {
+                    exitView(modifyView);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 获取单据打开参数
+     *
+     * @param formId 单据实体编码
+     * @return 打开参数
+     */
+    public static FormShowParameter getShowParameter(String formId) {
+        FormShowParameter parameter;
+        MainEntityType mainEntityType = EntityMetadataCache.getDataEntityType(formId);
+        if (mainEntityType.getClass().equals(BasedataEntityType.class)) {
+
+            parameter = new BaseShowParameter();
+        } else if (mainEntityType.getClass().equals(BillEntityType.class)) {
+            BillShowParameter s = new BillShowParameter();
+            Map<String, Object> maps = new HashMap<String, Object>();
+            maps.put("SELECT_ORG_ID", "1002947892337442816");
+            s.setCustomParams(maps);
+            parameter = s ;
+
+        } else {
+            parameter = new FormShowParameter();
+        }
+
+        parameter.setStatus(OperationStatus.ADDNEW);
+        parameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
+        parameter.getOpenStyle().setTargetKey("tabap");
+        parameter.setFormId(formId);
+        return parameter;
+    }
+
+    /**
+     * 获取单据修改打开参数
+     *
+     * @param formId 单据实体编码
+     * @param id     id
+     * @return 打开参数
+     */
+    public static FormShowParameter getModifyParameter(String formId, String id) {
+        FormShowParameter parameter = getShowParameter(formId);
+        if (parameter.getClass().equals(BaseShowParameter.class)) {
+            BaseShowParameter baseShowParameter = (BaseShowParameter) parameter;
+            try {
+                MainEntityType mainEntityType = EntityMetadataCache.getDataEntityType(formId);
+                String org = mainEntityType.getMainOrg();
+                String pkName = mainEntityType.getPrimaryKey().getName();
+                DynamicObject object = QueryServiceHelper.queryOne(formId, org, new QFilter[]{new QFilter(pkName, QCP.equals, id)});
+                String orgId = object.getString(org);
+                baseShowParameter.setCustomParam("useorgId", orgId);
+                baseShowParameter.setUseOrgId(object.getLong(org));
+            } catch (Exception ignored) {
+            }
+            baseShowParameter.setPkId(id);
+            baseShowParameter.setStatus(OperationStatus.EDIT);
+
+        } else {
+            BillShowParameter billShowParameter = (BillShowParameter) parameter;
+            billShowParameter.setPkId(id);
+            billShowParameter.setStatus(OperationStatus.EDIT);
+        }
+        return parameter;
+    }
+    /**
+     * 获取客户单据修改打开参数
+     *
+     * @param formId 单据实体编码
+     * @param id     id
+     * @return 打开参数
+     */
+    public static FormShowParameter kHgetModifyParameter(String formId, String id,String appyId) {
+        FormShowParameter parameter = getShowParameter(formId);
+        if (parameter.getClass().equals(BaseShowParameter.class)) {
+            BaseShowParameter baseShowParameter = (BaseShowParameter) parameter;
+            try {
+                MainEntityType mainEntityType = EntityMetadataCache.getDataEntityType(formId);
+                String org = mainEntityType.getMainOrg();
+                String pkName = mainEntityType.getPrimaryKey().getName();
+                DynamicObject object = QueryServiceHelper.queryOne(formId, org, new QFilter[]{new QFilter(pkName, QCP.equals, id)});
+                String orgId = object.getString(org);
+                baseShowParameter.setCustomParam("useorgId", orgId);
+                baseShowParameter.setUseOrgId(object.getLong(org));
+                //添加维护个性化参数
+                baseShowParameter.setCustomParam("isPersonalizeData", Boolean.TRUE);
+                baseShowParameter.setCustomParam("isPersonalizedModify", Boolean.TRUE);
+                baseShowParameter.setCustomParam("useOrgID",appyId);
+                baseShowParameter.setCustomParam("useorgId",appyId);
+               // CloseCallBack callBack = new CloseCallBack(this, "personalizeData");
+            } catch (Exception ignored) {
+            }
+            baseShowParameter.setPkId(id);
+            //添加维护个性化参数
+            baseShowParameter.setCustomParam("isPersonalizeData", Boolean.TRUE);
+            baseShowParameter.setCustomParam("isPersonalizedModify", Boolean.TRUE);
+            baseShowParameter.setCustomParam("useOrgID",appyId);
+            baseShowParameter.setCustomParam("useorgId",appyId);
+            baseShowParameter.setStatus(OperationStatus.EDIT);
+
+        } else {
+            BillShowParameter billShowParameter = (BillShowParameter) parameter;
+            billShowParameter.setPkId(id);
+            billShowParameter.setStatus(OperationStatus.EDIT);
+            //添加维护个性化参数
+            billShowParameter.setCustomParam("isPersonalizeData", Boolean.TRUE);
+            billShowParameter.setCustomParam("isPersonalizedModify", Boolean.TRUE);
+            billShowParameter.setCustomParam("useOrgID",appyId);
+            billShowParameter.setCustomParam("useorgId",appyId);
+        }
+        return parameter;
+    }
+
+    /**
+     * 反射执行内部方法
+     *
+//     * @param parameter 打开参数
+     */
+    private static void invokeFormServiceMethod(FormShowParameter parameter) {
+        ReflectUtils.invokeCosmicMethod("kd.bos.service.ServiceFactory", "FormService", "createConfig", parameter);
+        ReflectUtils.invokeCosmicMethod("kd.bos.service.ServiceFactory", "FormService", "batchInvokeAction", parameter.getPageId(), "[{\"key\":\"\",\"methodName\":\"loadData\",\"args\":[],\"postData\":[]}]");
+    }
+
+    public static void exitView(IFormView view) {
+        view.getModel().setDataChanged(false);
+        view.close();
+    }
+}

+ 146 - 0
src/main/java/sys/sc/formplugin/ApiHttpUtils.java

@@ -0,0 +1,146 @@
+package sys.sc.formplugin;
+
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import kd.bos.script.annotations.KSObject;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+@KSObject
+public class ApiHttpUtils {
+
+    public static String Posthttp(String url, String Params) throws Exception {
+        // 获得Http客户端
+        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+        // 创建Post请求
+        //设置请求路径
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.setHeader("Content-type", "application/json;charset=utf-8");
+        httpPost.setHeader("mesgtype", "bills_crop_base64");
+        httpPost.setHeader("channelcode", "JSX");
+        Date date = new Date();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        String formatDate = dateFormat.format(date);
+        httpPost.setHeader("channeldate", formatDate);
+        long time = new Date().getTime();
+        String channeltime = Long.toString(time);
+        httpPost.setHeader("channeltime",channeltime);
+        long l = System.currentTimeMillis();
+        String channelserno = Long.toString(l);
+        httpPost.setHeader("channelserno", channelserno);
+        httpPost.setHeader("brno", "");
+        httpPost.setHeader("tellerno", "*DMY");
+        httpPost.setHeader("terminalno", "");
+        httpPost.setHeader("APP_", "");
+        httpPost.setHeader("reserve", "");
+        httpPost.setHeader("dealcode", "");
+        httpPost.setHeader("dealmsg", "");
+        httpPost.setHeader("App_key", "XYK_DPJ_KEY");
+        httpPost.setHeader("App_secret", "XYK_DPJ_SECRET");
+        JSONObject object = new JSONObject();
+        object.put("file_base64",Params);
+        StringEntity entity = new StringEntity(object.toString(), ContentType.APPLICATION_JSON);
+        // post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
+        // 设置编码格式
+//        entity.setContentEncoding("UTF-8");
+        // 发送Json格式的数据请求
+//        entity.setContentType("application/json");
+        httpPost.setEntity(entity);
+        // 响应模型(发送post请求)
+        CloseableHttpResponse response = httpClient.execute(httpPost);
+        // 从响应模型中获取响应实体
+        HttpEntity responseEntity = response.getEntity();
+        JSONObject jsonObject = new JSONObject();
+        if (responseEntity != null) {
+            jsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity()));
+            return jsonObject.toJSONString();
+        }
+        // 释放资源
+        if (httpClient != null) {
+            httpClient.close();
+        }
+        if (response != null) {
+            response.close();
+        }
+        return "";
+    }
+    public static String toJsonString(String Params) throws Exception {
+        JSONObject json = new JSONObject();//返回最外层json
+        json.put("errcode","");
+        json.put("traceId","");
+        json.put("description","");
+        JSONObject data = new JSONObject();//数据层json
+        json.put("batchNo","");
+        JSONArray recoginitionData = new JSONArray();//数据层数组
+        JSONObject fileObj = new JSONObject();//实际数据json
+        fileObj.put("canBeDeduction","");
+        fileObj.put("salerName","");
+        fileObj.put("invoiceMoney","");
+        fileObj.put("signStatus","");
+        fileObj.put("downloadUrl","");
+        fileObj.put("fileHash","");
+        fileObj.put("invoiceAmount","");
+        fileObj.put("localUrl","");
+        fileObj.put("deductionStatus","");
+        fileObj.put("salerTaxNo","");
+        fileObj.put("invoiceType","");
+        fileObj.put("invoiceNo","");
+        fileObj.put("isRepeat","");
+        fileObj.put("pixel","");
+        fileObj.put("oriImageSize","");
+        fileObj.put("pdfToImgSnapshotUrl","");
+        fileObj.put("orientation","");
+        fileObj.put("batchNo","");
+        fileObj.put("clientId","");
+        fileObj.put("buyerTaxNo","");
+        fileObj.put("warningCode","");
+        fileObj.put("originalState","");
+        fileObj.put("companySeal","");
+        fileObj.put("originalUrl","");
+        fileObj.put("invoiceDate","");
+        fileObj.put("buyerName","");
+        fileObj.put("invoiceCode","");
+        fileObj.put("serialNo","");
+        fileObj.put("totalAmount","");
+        fileObj.put("taxRate","");
+        fileObj.put("oriOrientation","");
+        fileObj.put("oriRegion","");
+        fileObj.put("rotationAngle","");
+        fileObj.put("snapshotUrl","");
+        fileObj.put("imageSerialNo","");
+        fileObj.put("recognitionSerialNo","");
+        fileObj.put("totalTaxAmount","");
+        fileObj.put("taxAmount","");
+        fileObj.put("region","");
+        fileObj.put("isExpend","");
+        fileObj.put("expendStatus","");
+        fileObj.put("fileType","");
+        JSONArray items = new JSONArray();//数据明细层数组
+        JSONObject mxFileObj = new JSONObject();//明细数据json
+        mxFileObj.put("unitPrice","");
+        mxFileObj.put("taxRate","");
+        mxFileObj.put("unit","");
+        mxFileObj.put("num","");
+        mxFileObj.put("detailAmount","");
+        mxFileObj.put("taxAmount","");
+        mxFileObj.put("goodsName","");
+        //值拼接完成后开始set数据结构
+        items.add(mxFileObj);
+        fileObj.put("items",items);
+        recoginitionData.add(fileObj);
+        data.put("recoginitionData",recoginitionData);
+        json.put("data",data);
+        return json.toJSONString();
+    }
+}

+ 37 - 0
src/main/java/sys/sc/formplugin/Filetest.java

@@ -0,0 +1,37 @@
+package sys.sc.formplugin;
+
+import kd.bos.script.annotations.KSMethod;
+import kd.bos.script.annotations.KSObject;
+
+import java.io.File;
+
+/**
+ * @author cjz
+ * @date 2024/9/9 14:12
+ * @description:
+ */
+@KSObject
+public class Filetest {
+
+
+    @KSMethod
+    public File getFile(String url){
+        return new File(url);
+    }
+
+    @KSMethod
+    public void createNewFile(File file) throws Exception{
+        file.createNewFile();
+    }
+
+    @KSMethod
+    public boolean exists(File file){
+
+        return file.exists();
+    }
+    @KSMethod
+    public boolean mkdirs(File file){
+
+        return file.mkdirs();
+    }
+}

+ 886 - 0
src/main/java/sys/sc/formplugin/TestPlugin.java

@@ -0,0 +1,886 @@
+package sys.sc.formplugin;
+
+import com.jcraft.jsch.*;
+import com.tongtech.jms.ra.core.Options;
+import kd.bos.base.utils.msg.BaseMessage;
+import kd.bos.base.utils.msg.OrgMessage;
+import kd.bos.dataentity.entity.CloneUtils;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.operate.result.OperationResult;
+import kd.bos.form.IFormView;
+import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.form.events.BeforeDoOperationEventArgs;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.bos.org.utils.OrgUtils;
+import kd.bos.orm.ORM;
+import kd.bos.orm.impl.ORMImpl;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.sec.user.utils.UserOperationUtils;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.DeleteServiceHelper;
+import kd.bos.servicehelper.operation.OperationServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.epm.eb.common.model.DynamicInfoCollection;
+import kd.imc.bdm.common.constant.BotpCallBackLogConstant;
+import sys.sc.opplugin.utils.SftpClient;
+
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+import java.util.Date;
+import java.util.*;
+
+public class TestPlugin  extends AbstractListPlugin {
+
+    public static String host="192.168.10.69";//服务器ip地址
+    public static String username="root";//用户名
+    public static int port = 22;//端口号
+    public static String password="Kd@86262007";//用户密码
+
+    //根据接口配置信息获取组织人员,拼接服务器文件路径url,参数为urlcode接口配置信息编码
+    public String getFileUrl(String urlcode) throws IOException {
+        //组织人员接口配置信息获取
+        DynamicObject nckd_jkpzxx= BusinessDataServiceHelper
+                .loadSingle("nckd_jkpzxx", new QFilter[]{new QFilter("number", "=", urlcode)});
+        //取文件名
+        String nckd_filename=nckd_jkpzxx.getString("nckd_filename");
+        //获取文件路径
+        String nckd_url=nckd_jkpzxx.getString("nckd_url");
+        //当前日期
+        Date currentDate=new Date();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(currentDate);
+        calendar.add(Calendar.DATE, -1); // 将日期减少一天
+        //日期减少一天
+        Date newDate = calendar.getTime();
+        //转换日期格式
+        SimpleDateFormat sf=new SimpleDateFormat("yyyyMMdd");
+        String datestr=sf.format(newDate);
+        //真实路径
+        if (nckd_url.equals("/var/appstatic/")) {
+            nckd_url="/home/kingdee/cosmic/nginx-appstatic/store/appstatic/";
+        }
+        //文件完整路径
+        String realPath = nckd_url+datestr+File.separator+nckd_filename;
+        return realPath;
+    }
+
+    //从文件读取数据更新到基础资料中
+    public void generateDataFile(String filePath) {
+        try {
+
+            DynamicObjectType dynamicObjectType = EntityMetadataCache.getDataEntityType("nckd_basicdata");
+            List<String> selector = Arrays.asList(
+                    "nckd_employeeid", "nckd_name", "nckd_gender", "nckd_nl", "nckd_zzmm",
+                    "nckd_zgxl", "nckd_szdwname", "nckd_szdwcode", "nckd_orgidname", "nckd_orgidcode",
+                    "nckd_yjbmname", "nckd_yjbmcode", "nckd_posidname", "nckd_posidcode", "nckd_yggxlb",
+                    "nckd_status", "nckd_sjh"
+            );
+            List<DynamicObject> createdataList = new ArrayList<>();
+            List<DynamicObject> updatedataList = new ArrayList<>();
+            //查出所有现有的数据
+            DynamicObject[] existingData = BusinessDataServiceHelper
+                    .load(dynamicObjectType.getName(), String.join(",", selector) + ",nckd_updatedate,nckd_isdelete", null);
+            Map<String, DynamicObject> existingDataMap = new HashMap<>();
+            for (DynamicObject obj : existingData) {
+                existingDataMap.put(obj.getString("nckd_employeeid"), obj);
+            }
+            Set<String> processedGonghaoSet = new HashSet<>();
+            try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    //去掉换行符|$|
+                    line = line.replace("|$|", "");
+                    //空格符号,根据这个符号分割
+                    String[] fields = line.split("\u0001");
+                    //如果获取的数据行不等于预设字段的行,则跳过这行数据
+                    if (fields.length != selector.size()) {
+                        continue;
+                    }
+                    //获取工号
+                    String gonghao = fields[0];
+                    boolean isUpdated = false;
+                    DynamicObject data;
+                    processedGonghaoSet.add(gonghao);
+                    if (existingDataMap.containsKey(gonghao)) {
+                        //获取对应工号的数据
+                        data = existingDataMap.get(gonghao);
+                        for (int i = 0; i < selector.size(); i++) {
+                            String fieldName = selector.get(i);
+                            String newValue = fields[i];
+                            String existingValue = data.getString(fieldName);
+                            //判断数据是否与之前的数据相同,不相同则更新
+                            if (!Objects.equals(existingValue, newValue)) {
+                                data.set(fieldName, newValue);
+                                isUpdated = true;
+                            }
+                        }
+                        //更新了数据则设置数据更新的时间
+                        if (isUpdated) {
+                            data.set("nckd_updatedate", new Date());
+                            updatedataList.add(data);
+                        }
+                    } else {
+                        //不存在这条数据则新增一条到data中
+                        data = new DynamicObject(dynamicObjectType);
+                        for (int i = 0; i < selector.size(); i++) {
+                            data.set(selector.get(i), fields[i]);
+                        }
+                        Date now = new Date();
+                        data.set("nckd_createdate", now);
+                        data.set("nckd_updatedate", now);
+                        createdataList.add(data);
+                    }
+                }
+            }
+            for (Map.Entry<String, DynamicObject> entry : existingDataMap.entrySet()) {
+                String gonghao = entry.getKey();
+                DynamicObject data = entry.getValue();
+
+                if (!processedGonghaoSet.contains(gonghao)) {
+                    data.set("nckd_isdelete", true);
+                    updatedataList.add(data);
+                }
+            }
+
+            //新增数据不为空则更新到数据库中
+            if (!createdataList.isEmpty()) {
+                SaveServiceHelper.save(dynamicObjectType, createdataList.toArray(new DynamicObject[0]));
+            }
+            //更新的数据不为空,则更新到数据库中
+            if (!updatedataList.isEmpty()) {
+                SaveServiceHelper.save(updatedataList.get(0).getDynamicObjectType(), updatedataList.toArray(new DynamicObject[0]));
+            }
+            this.getView().showMessage("数据已成功保存!");
+        } catch (IOException ex) {
+            ex.printStackTrace();
+            this.getView().showMessage("读取文件时发生错误:" + ex.getMessage());
+        }
+    }
+
+    @Override
+    public void afterBindData(EventObject e) {
+        super.afterBindData(e);
+    }
+
+    //根据基础资料数据生成dat文件,nckdentry基础资料标识,selector字段标识,filePath文件路径
+    public void creatDatFile(String nckdentry,List<String> selector,String filePath) {
+        try {
+            //基础资料数据
+            DynamicObjectType dynamicObjectType = EntityMetadataCache.getDataEntityType(nckdentry);
+            DynamicObject[] dataList = BusinessDataServiceHelper.load(dynamicObjectType.getName(), String.join(",", selector), null);
+            File file = new File(filePath);
+            //文件路径不存在则创建文件
+            if (!file.exists()) {
+                File parentDir = file.getParentFile();
+                if (parentDir != null && !parentDir.exists()) {
+                    parentDir.mkdirs();
+                }
+                file.createNewFile();
+            }
+            try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath), "GBK"))) {
+                for (DynamicObject data : dataList) {
+                    StringBuilder line = new StringBuilder();
+                    for (String field : selector) {
+                        line.append(data.get(field) != null ? data.get(field).toString() : "").append("\u0001");
+                    }
+                    line.setLength(line.length() - 1);
+                    line.append("|$|");
+                    writer.write(line.toString());
+                    writer.newLine();
+                }
+                this.getView().showMessage("数据文件已成功生成!");
+            }
+        } catch (IOException ex) {
+            ex.printStackTrace();
+            this.getView().showMessage("生成数据文件时发生错误!");
+        }
+    }
+
+    @Override
+    public void afterDoOperation(AfterDoOperationEventArgs e) {
+        super.afterDoOperation(e);
+        String filePath = "D:/test.dat";
+        //生成data文件
+        if ("scdatwj".equals(e.getOperateKey())) {//生成data文件
+            try {
+                DynamicObjectType dynamicObjectType = EntityMetadataCache.getDataEntityType("nckd_basicdata");
+                // 定义选择的字段
+                List<String> selector = new ArrayList<>();
+                selector.add("nckd_employeeid");
+                selector.add("nckd_name");
+                selector.add("nckd_gender");
+                selector.add("nckd_nl");
+                selector.add("nckd_zzmm");
+                selector.add("nckd_zgxl");
+                selector.add("nckd_szdwname");
+                selector.add("nckd_szdwcode");
+                selector.add("nckd_orgidname");
+                selector.add("nckd_orgidcode");
+                selector.add("nckd_yjbmname");
+                selector.add("nckd_yjbmcode");
+                selector.add("nckd_posidname");
+                selector.add("nckd_posidcode");
+                selector.add("nckd_yggxlb");
+                selector.add("nckd_status");
+                selector.add("nckd_sjh");
+                DynamicObject[] dataList = BusinessDataServiceHelper.load(dynamicObjectType.getName(), String.join(",", selector), null);
+                File file = new File(filePath);
+                //文件路径不存在则创建文件
+                if (!file.exists()) {
+                    File parentDir = file.getParentFile();
+                    if (parentDir != null && !parentDir.exists()) {
+                        parentDir.mkdirs();
+                    }
+                    file.createNewFile();
+                }
+                try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath), "GBK"))) {
+                    for (DynamicObject data : dataList) {
+                        StringBuilder line = new StringBuilder();
+                        for (String field : selector) {
+                            line.append(data.get(field) != null ? data.get(field).toString() : "").append("\u0001");
+                        }
+                        line.setLength(line.length() - 1);
+                        line.append("|$|");
+                        writer.write(line.toString());
+                        writer.newLine();
+                    }
+                    this.getView().showMessage("数据文件已成功生成!");
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                this.getView().showMessage("生成数据文件时发生错误!");
+            }
+        }
+        //更新人员
+        else if ("gxry".equals(e.getOperateKey())) {
+            //更新人员
+            // 从 nckd_basicdata 表中获取所有人员数据,假设通过某个条件查找
+            DynamicObject[] personDataArray = BusinessDataServiceHelper.load(
+                    "nckd_basicdata",
+                    "id,nckd_employeeid,nckd_name,nckd_gender,nckd_nl,nckd_zzmm,nckd_zgxl,nckd_orgidname,nckd_orgidcode,nckd_posidname,nckd_posidcode,nckd_yggxlb,nckd_status,nckd_sjh",
+                    null
+            );
+            if (personDataArray == null || personDataArray.length == 0) {
+                this.getView().showMessage("未从 nckd_basicdata 表中获取到任何人员数据!");
+                return;
+            }
+            String msg="";
+            for (DynamicObject personData : personDataArray) {
+                //获取id
+                String id=personData.getString("id");
+                // 获取工号
+                String gonghao = personData.getString("nckd_employeeid");
+                if (gonghao == null || gonghao.isEmpty()) {
+                    continue;
+                }
+                // 查询用户是否已存在
+                DynamicObject existingUser = BusinessDataServiceHelper.loadSingle(
+                        "bos_user", new QFilter[]{new QFilter("number", "=", gonghao)}
+                );
+                // 用户已存在,进行数据更新
+                if (existingUser != null) {
+                    //初始化
+                    boolean isUpdated = false;
+                    // 比较并更新性别
+                    Object newGender = personData.get("nckd_gender");
+                    if (!newGender.equals(existingUser.get("gender"))) {
+                        existingUser.set("gender", newGender);
+                        isUpdated = true;
+                    }
+                    // 比较并更新手机号
+                    Object newPhone = personData.get("nckd_sjh");
+                    if (!newPhone.equals(existingUser.get("phone"))) {
+                        existingUser.set("phone", newPhone);
+                        isUpdated = true;
+                    }
+                    //更新部门和岗位
+                    DynamicObjectCollection existingDeptEntries = existingUser.getDynamicObjectCollection("entryentity");
+                    //人员部门分录
+                    DynamicObject existingDeptEntry = existingDeptEntries.isEmpty() ? null : existingDeptEntries.get(0);
+                    // 获取新的部门信息
+                    String deptCode = personData.getString("nckd_orgidcode");
+                    DynamicObject newOrgInfo = BusinessDataServiceHelper.loadSingle(
+                            "bos_adminorg", new QFilter[]{new QFilter("number", "=", deptCode)}
+                    );
+                    boolean deptUpdated = false;
+                    if (newOrgInfo != null) {
+                        if (existingDeptEntry == null) {
+                            // 如果没有现有部门分录,则添加新的部门分录
+                            existingDeptEntry = existingDeptEntries.addNew();
+                            deptUpdated = true;
+                        }
+                        // 比较并更新部门信息
+                        if (!deptCode.equals(existingDeptEntry.get("dpt.number"))) {
+                            existingDeptEntry.set("dpt", newOrgInfo);
+                            deptUpdated = true;
+                        }
+                        // 更新组织结构
+                        DynamicObjectCollection structureInfoCollection = newOrgInfo.getDynamicObjectCollection("structure");
+                        if (structureInfoCollection != null && !structureInfoCollection.isEmpty()) {
+                            DynamicObject structureInfo = structureInfoCollection.get(0);
+                            if(existingDeptEntry.getDynamicObject("orgstructure")!=null){
+                                if (!structureInfo.getPkValue().equals(existingDeptEntry.getDynamicObject("orgstructure").getPkValue())) {
+                                    existingDeptEntry.set("orgstructure", structureInfo.getPkValue());
+                                    deptUpdated = true;
+                                }
+                            }else{
+                                existingDeptEntry.set("orgstructure", structureInfo.getPkValue());
+                                deptUpdated = true;
+                            }
+                        }
+                        // 标记是否需要保存
+                        if (deptUpdated) {
+                            isUpdated = true;
+                        }
+                    } else {
+                        this.getView().showMessage("未找到部门编码为 " + deptCode + " 的部门信息!");
+                    }
+                    // 获取新的岗位信息
+                    String postName = personData.getString("nckd_posidname");
+                    if (!postName.equals(existingDeptEntry.getString("position"))) {
+                        existingDeptEntry.set("position", postName);
+                        isUpdated = true;
+                    }
+                    // 如果有更新则保存
+                    if (isUpdated) {
+                        SaveServiceHelper.save(new DynamicObject[]{existingUser});
+                        msg+="工号为 " + gonghao + " 的用户信息已更新!";
+                    }
+
+                } else {
+                    // 用户不存在,创建新用户
+                    DynamicObjectType userType = EntityMetadataCache.getDataEntityType("bos_user");
+                    DynamicObject userinfo = new DynamicObject(userType);
+                    ORM impl = ORM.create();
+                    userinfo.set("id", impl.genLongId("bos_user"));
+                    userinfo.set("number", gonghao);
+                    // 设置其他字段
+                    userinfo.set("gender", personData.get("nckd_gender"));
+//                    userinfo.set("nckd_nl", personData.get("nckd_nl"));
+//                    userinfo.set("nckd_zzmm", personData.get("nckd_zzmm"));
+//                    userinfo.set("nckd_zgxl", personData.get("nckd_zgxl"));
+//                    userinfo.set("nckd_yggxlb", personData.get("nckd_yggxlb"));
+//                    userinfo.set("nckd_status", personData.get("nckd_status"));
+                    //人员手机号
+                    userinfo.set("phone", personData.get("nckd_sjh"));
+                    // 设置其他固定字段
+                    userinfo.set("startdate", new Date());
+                    Calendar c = Calendar.getInstance();
+                    c.set(Calendar.YEAR, 2999);
+                    userinfo.set("enddate", c.getTime());
+                    userinfo.set("masterid", userinfo.get("id"));
+                    userinfo.set("enable", 1);
+                    userinfo.set("status", "C");
+                    userinfo.set("password", "8HrquJnZfyOkmmHkpGLXfg==");
+                    userinfo.set("isregisted", "1");
+                    userinfo.set("isactived", "1");
+                    userinfo.set("pswstrategy", "338333884850648064");
+                    userinfo.set("psweffectivedate", new Date());
+                    userinfo.set("useenddate", c.getTime());
+                    // 设置姓名和拼音
+                    String name = personData.getString("nckd_name");
+                    userinfo.set("name", name);
+                    String fullPinyin = UserOperationUtils.getFullSpellByName(name);
+                    String simplePinyin = UserOperationUtils.getFirstSpellByName(name);
+                    userinfo.set("fullpinyin", fullPinyin);
+                    userinfo.set("simplepinyin", simplePinyin);
+                    // 设置用户名
+                    String username = UserOperationUtils.getUserNameByFormatedFullPinyin(
+                            (long) userinfo.getPkValue(), fullPinyin, null
+                    );
+                    userinfo.set("username", username);
+                    // 创建部门分录
+                    DynamicObjectCollection bmflList = userinfo.getDynamicObjectCollection("entryentity");
+                    DynamicObject bumeninfo = bmflList.addNew();
+                    // 获取部门编码并在 bos_adminorg 表中查找部门信息
+                    String deptCode = personData.getString("nckd_orgidcode");
+                    DynamicObject orginfo = BusinessDataServiceHelper.loadSingle(
+                            "bos_adminorg", new QFilter[]{new QFilter("number", "=", deptCode)}
+                    );
+                    if (orginfo != null) {
+                        bumeninfo.set("dpt", orginfo);
+                        // 获取组织的分录集合 structure 的第一条数据
+                        DynamicObjectCollection structureInfoCollection = orginfo.getDynamicObjectCollection("structure");
+                        if (structureInfoCollection != null && !structureInfoCollection.isEmpty()) {
+                            DynamicObject structureInfo = structureInfoCollection.get(0); // 获取第一条结构信息
+                            bumeninfo.set("orgstructure", structureInfo.getPkValue());
+                        } else {
+                            this.getView().showMessage("部门编码为 " + deptCode + " 的部门缺少组织结构信息,跳过该记录。");
+                        }
+                    }
+                    String postName = personData.getString("nckd_posidname");;
+                    bumeninfo.set("position", postName);
+                    //所在岗位名称
+                    String positionnumber = personData.getString("nckd_posidname");;
+                    bumeninfo.set("post", positionnumber);
+                    // 保存新用户信息
+                    SaveServiceHelper.save(new DynamicObject[]{userinfo});
+                    msg+="工号为 " + gonghao + " 的用户已创建!";
+                }
+            }
+            if("".equals(msg)){
+                this.getView().showMessage("没有需要更新或新增的人员");
+            }else{
+                this.getView().showMessage(msg);
+            }
+        }
+        //更新组织
+        else if ("gxzz".equals(e.getOperateKey())){
+            // 获取形态信息 编码为 Orgform06 的 bos_org_pattern(部门组织)
+            DynamicObject xingtaiinfo = BusinessDataServiceHelper.loadSingle(
+                    "bos_org_pattern", new QFilter[]{new QFilter("number", "=", "Orgform06")}
+            );
+            //获取形态信息,编码为 Orgform02 的bos_org_pattern(公司组织)
+            DynamicObject cpyinfo = BusinessDataServiceHelper.loadSingle(
+                    "bos_org_pattern", new QFilter[]{new QFilter("number", "=", "Orgform02")}
+            );
+            // 查询 nckd_basicdata 表中需要更新的数据
+            DynamicObject[] nckdData = BusinessDataServiceHelper.load(
+                    "nckd_basicdata",
+                    "id,nckd_szdwcode,nckd_szdwname,nckd_yjbmcode,nckd_yjbmname,nckd_orgidcode,nckd_orgidname",
+                    null
+            );
+            //行政组织
+            DynamicObject rootOrg = BusinessDataServiceHelper.loadSingle(
+                    "bos_adminorg", new QFilter[]{new QFilter("number", "=", "jxyh")}
+            );
+            if (rootOrg == null) {
+                this.getView().showMessage("指定的上级组织 'jxyh' 未找到!");
+                return;
+            }
+
+//            DynamicObjectType adminOrgType = EntityMetadataCache.getDataEntityType("bos_adminorg");
+            IFormView orgview = ABillServiceHelper.createAddView("bos_adminorg");
+            for (DynamicObject record : nckdData) {
+                // 判断并创建或更新所在单位
+                //所在单位编码
+                String szdwbm = record.getString("nckd_szdwcode");
+                //所在单位名称
+                String szdwmc = record.getString("nckd_szdwname");
+                DynamicObject org = BusinessDataServiceHelper.loadSingle(
+                        "bos_adminorg", new QFilter[]{new QFilter("number", "=", szdwbm)}
+                );
+                //没有单位则创建
+                if (org == null) {
+//                    org = new DynamicObject(adminOrgType);
+//                    IFormView orgview = ABillServiceHelper.createAddView("bos_adminorg");
+                    //组织编码
+                    orgview.getModel().setValue("number", szdwbm);
+                    //组织名称
+                    orgview.getModel().setValue("name", szdwmc);
+                    //上级组织
+                    orgview.getModel().setValue("parent", rootOrg);
+                    //形态,设置形态为公司
+                    orgview.getModel().setValue("orgpattern", cpyinfo);
+                    //数据状态设置为已审核
+                    orgview.getModel().setValue("status", "C");
+                    //使用状态设置为可用
+                    orgview.getModel().setValue("enable", "1");
+                    OperationResult operationResult = ABillServiceHelper.saveOperate(orgview);
+                    //保存不成功
+                    if (!operationResult.isSuccess()) {
+
+                    }
+                    org = orgview.getModel().getDataEntity();
+                    //如果存在单位则检查单位名是否一致,不一致则更新
+                }else if (!org.getString("name").equals(szdwmc))
+                {
+                    //设置单位名称
+                    org.set("name",szdwmc);
+                    // 更新组织结构
+                    DynamicObjectCollection structureInfoCollection = org.getDynamicObjectCollection("structure");
+                    DynamicObject structureInfo = structureInfoCollection.get(0);
+                    //设置长名称
+                    structureInfo.set("fullname",rootOrg.getString("name")+"_"+szdwmc);
+                    SaveServiceHelper.update(org);
+                }
+                // 判断一级机构编码 在行政组织中是否存在,不存在则新增
+                String yjjgbm = record.getString("nckd_yjbmcode");
+                String yjjgmc = record.getString("nckd_yjbmname");
+                //一级机构
+                DynamicObject yjjg = BusinessDataServiceHelper.loadSingle("bos_adminorg", new QFilter[]{new QFilter("number", "=", yjjgbm)});
+                if (yjjg == null) {
+//                    yjjg = new DynamicObject(adminOrgType);
+//                    IFormView yjjgView = ABillServiceHelper.createAddView("bos_adminorg");
+                    IFormView yjjgView = orgview;
+                    yjjgView.getModel().setValue("number", yjjgbm);
+                    yjjgView.getModel().setValue("name", yjjgmc);
+                    yjjgView.getModel().setValue("parent", org); // 父级组织为 org
+                    yjjgView.getModel().setValue("orgpattern", xingtaiinfo);
+                    yjjgView.getModel().setValue("status", "C");
+                    yjjgView.getModel().setValue("enable", "1");
+                    OperationResult yjjgOperationResult = ABillServiceHelper.saveOperate(yjjgView);
+                    if (!yjjgOperationResult.isSuccess()) {
+                        // Handle the failure case here
+                    }
+                    yjjg = yjjgView.getModel().getDataEntity();
+                } else if (!yjjg.getString("name").equals(yjjgmc)) {
+                    yjjg.set("name",yjjgmc);
+                    DynamicObjectCollection structureInfoCollection = yjjg.getDynamicObjectCollection("structure");
+                    DynamicObject structureInfo = structureInfoCollection.get(0);
+                    //设置长名称
+                    structureInfo.set("fullname",rootOrg.getString("name")+"_"+szdwmc+"_"+yjjgmc);
+                    SaveServiceHelper.update(yjjg);
+                }
+                // 判断所在部门编码 在行政组织中是否存在,不存在则新增
+                String szbmbm = record.getString("nckd_orgidcode");
+                String szbmmc = record.getString("nckd_orgidname");
+                //所在部门
+                DynamicObject szbm = BusinessDataServiceHelper.loadSingle("bos_adminorg", new QFilter[]{new QFilter("number", "=", szbmbm)});
+                if (szbm == null) {
+//                    szbm = new DynamicObject(adminOrgType);
+//                    IFormView szbmView = ABillServiceHelper.createAddView("bos_adminorg");
+                    IFormView szbmView=orgview;
+                    szbmView.getModel().setValue("number", szbmbm);
+                    szbmView.getModel().setValue("name", szbmmc);
+                    szbmView.getModel().setValue("parent", yjjg); // 设置父级为 yjjg
+                    szbmView.getModel().setValue("orgpattern", xingtaiinfo);
+                    szbmView.getModel().setValue("status", "C"); // 设置状态
+                    szbmView.getModel().setValue("enable", "1"); // 设置为启用状态
+                    // 保存操作
+                    OperationResult szbmOperationResult = ABillServiceHelper.saveOperate(szbmView);
+                    if (!szbmOperationResult.isSuccess()) {
+                        // 如果保存失败,可以在这里处理错误
+                        this.getView().showMessage("保存部门失败!");
+                        return;
+                    }
+                    if (szbmView.getModel() != null) {
+                        szbm = szbmView.getModel().getDataEntity();
+                    } else {
+                        this.getView().showMessage("保存后未能获取到部门数据!");
+                        return;
+                    }
+                    this.getView().showMessage("行政组织数据已成功更新!");
+                } else if (!szbm.getString("name").equals(szbmmc)) {
+                    szbm.set("name",szbmmc);
+                    DynamicObjectCollection structureInfoCollection = szbm.getDynamicObjectCollection("structure");
+                    DynamicObject structureInfo = structureInfoCollection.get(0);
+                    //设置长名称
+                    structureInfo.set("fullname",rootOrg.getString("name")+"_"+szdwmc+"_"+yjjgmc+"_"+szbmmc);
+                    SaveServiceHelper.update(szbm);
+                }
+            }
+        }
+        //生成数据
+        else if ("scsj".equals(e.getOperateKey())) {//从文件读取数据插入基础资料
+            try {
+                generateDataFile(getFileUrl("organduserurl"));
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+        //减值数据,导入数据先删除旧的数据
+        if ("jzsj".equals(e.getOperateKey()))
+        {
+            try {
+                //文件路径
+                String filelocation="D:/jzdata.dat";
+                //减值数据基础资料
+                DynamicObjectType dynamicObjectType = EntityMetadataCache.getDataEntityType("nckd_impairment");
+                //减值表字段
+                List<String> selector = Arrays.asList(
+                        "nckd_dubil_id", "nckd_cust_id", "nckd_cur_cd", "nckd_dubil_amt", "nckd_asset_bal",
+                        "nckd_stage_rslt", "nckd_ecl_ratio","nckd_cust_name"
+                );
+                List<DynamicObject> createdataList = new ArrayList<>();
+                QFilter filter=new QFilter("nckd_isdelete",QCP.equals,false);
+                //查询已经存在的数据
+                DynamicObject[] existingData = BusinessDataServiceHelper
+                        .load(dynamicObjectType.getName(), String.join(",", selector) + ",nckd_isdelete", new QFilter[]{filter});
+
+                Set<String> processeddubilidSet = new HashSet<>();
+                try (BufferedReader reader = new BufferedReader(new FileReader(filelocation))) {
+                    String line;
+                    while ((line = reader.readLine()) != null) {
+                        //去掉换行符|$|
+                        line = line.replace("|$|", "");
+                        //空格符号,根据这个符号分割
+                        String[] fields = line.split("\u0001");
+                        //如果获取的数据行不等于预设字段的行,则跳过这行数据
+                        if (fields.length != selector.size()) {
+                            continue;
+                        }
+                        //获取单据号
+                        String dubil_id = fields[0];
+                        DynamicObject data;
+                        processeddubilidSet.add(dubil_id);
+                        //新增数据
+                        data = new DynamicObject(dynamicObjectType);
+                        for (int i = 0; i < selector.size(); i++) {
+                            data.set(selector.get(i), fields[i]);
+                        }
+                        //设置创建时间
+                        data.set("nckd_creatd",new Date());
+                        data.set("nckd_isdelete",false);
+                        createdataList.add(data);
+                    }
+                }
+                //读取的文件数据转化成DynamicObject
+                DynamicObject[] dynamicObjectlist=createdataList.toArray(new DynamicObject[0]);
+                //新增数据不为空则更新到数据库中
+                if (!createdataList.isEmpty()) {
+                    //转换list为DynamicObject类型
+                    SaveServiceHelper.save(dynamicObjectType,dynamicObjectlist);
+                }
+                //删除所有的数据,再新增
+                for (DynamicObject existingDatum : existingData) {
+                    existingDatum.set("nckd_isdelete", true);
+                }
+                SaveServiceHelper.save(existingData);
+                QFilter qFilter=new QFilter("nckd_isdelete",QCP.equals,true);
+                DeleteServiceHelper.delete(dynamicObjectType.getName(),new QFilter[]{qFilter});
+
+                //保存客户基础资料
+                custSave(dynamicObjectlist);
+                this.getView().showMessage("数据已成功保存!");
+
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                this.getView().showMessage("读取文件时发生错误:" + ex.getMessage());
+            }
+        }
+        //获取接口配置表中组织人员的数据,返回服务器中文件路径
+        if ("jkpz".equals(e.getOperateKey())) {
+            try {
+                getFileUrl("organduserurl");
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+
+        //读取行名行号,存入对应基础资料中
+        if("hmhh".equals(e.getOperateKey())) {
+            //行名行号表字段
+            List<String> selector = Arrays.asList(
+                    "number", "name"
+            );
+            //行名行号表标识
+            String bd_bebank="bd_bebank";
+            try {
+                //文件路径
+                String fileurl = getFileUrl("hmhhurl");
+                //获取服务器连接
+                SftpClient sftpClient=new SftpClient(host,username,password,port);
+                sftpClient.connect();
+                //基础资料
+                DynamicObjectType dynamicObjectType = EntityMetadataCache.getDataEntityType(bd_bebank);
+                //国家基础资料(中国)
+                DynamicObject country=BusinessDataServiceHelper
+                        .loadSingle("bd_country","number", new QFilter[]{new QFilter("number", QCP.equals, "001")});
+                List<DynamicObject> createdataList = new ArrayList<>();
+                List<DynamicObject> updatedataList = new ArrayList<>();
+                //查出所有现有的数据
+                DynamicObject[] existingData = BusinessDataServiceHelper
+                        .load(dynamicObjectType.getName(), String.join(",", selector)+",enable,nckd_datasource", null);
+                //查找文件更新的数据
+                Map<String, DynamicObject> existingDataMap = new HashMap<>();
+                for (DynamicObject obj : existingData) {
+                    //单据号
+                    existingDataMap.put(obj.getString(selector.get(0)), obj);
+                }
+                Set<String> processeddubilidSet = new HashSet<>();
+                //读取服务器文件并写入
+                try (BufferedReader reader = new BufferedReader(new InputStreamReader(sftpClient.fileInputStream(fileurl)))) {
+                    String line;
+                    while ((line = reader.readLine()) != null) {
+                        //去掉换行符|$|
+                        line = line.replace("|$|", "");
+                        //空格符号,根据这个符号分割
+                        String[] fields = line.split("\u0001");
+                        //如果获取的数据行不等于预设字段的行,则跳过这行数据
+//                        if (fields.length != selector.size()) {
+//                            continue;
+//                        }
+                        //获取单据号
+                        String dubil_id = fields[0];
+                        boolean isUpdated = false;
+                        DynamicObject data;
+                        processeddubilidSet.add(dubil_id);
+                        if (existingDataMap.containsKey(dubil_id)) {
+                            //获取对应单据号的数据
+                            data = existingDataMap.get(dubil_id);
+                            for (int i = 0; i < selector.size(); i++) {
+                                String fieldName = selector.get(i);
+                                String newValue = fields[i];
+                                String existingValue = data.getString(fieldName);
+                                //判断数据是否与之前的数据相同,不相同则更新
+                                if (!Objects.equals(existingValue, newValue)) {
+                                    data.set(fieldName, newValue);
+                                    isUpdated = true;
+                                }
+                            }
+                            //更新了数据则设置数据更新的时间
+                            if (isUpdated) {
+                                updatedataList.add(data);
+                            }
+                        } else {
+                            //不存在这条数据则新增一条到data中
+                            data = new DynamicObject(dynamicObjectType);
+                            for (int i = 0; i < selector.size(); i++) {
+                                data.set(selector.get(i), fields[i]);
+                            }
+                            //国家
+                            data.set("country",country);
+                            //省
+                            data.set("provincetxt","江西");
+                            //市
+                            data.set("citytxt","南昌");
+                            //联行号等于行号
+                            data.set("union_number",fields[0]);
+                            //设置可用状态
+                            data.set("enable","1");
+                            //设置数据来源,0为手动更新,1为文件自动更新
+                            data.set("nckd_datasource","1");
+                            createdataList.add(data);
+                        }
+                    }
+                }
+                //关闭连接
+                sftpClient.disconnect();
+                //获取自动添加的数据
+                DynamicObject[] autoData = BusinessDataServiceHelper
+                        .load(dynamicObjectType.getName()
+                                , String.join(",", selector)+",enable,nckd_datasource",
+                                new QFilter[]{new QFilter("nckd_datasource", QCP.equals, "1")});
+                for (int i=0;i< autoData.length;i++)
+                {
+                    //如果导入的数据在系统中没有则禁用
+                    if (!processeddubilidSet.contains(autoData[i].getString("number"))) {
+                        //设置禁用
+                        autoData[i].set("enable","0");
+                    }
+
+                }
+                SaveServiceHelper.save(autoData);
+                //查找更新数据
+                for (Map.Entry<String, DynamicObject> entry : existingDataMap.entrySet()) {
+                    String dubil_id = entry.getKey();
+                    DynamicObject data = entry.getValue();
+                    if (!processeddubilidSet.contains(dubil_id)) {
+//                        data.set("nckd_isdelete", true);
+                        updatedataList.add(data);
+                    }
+                }
+                //新增数据不为空则更新到数据库中
+                if (!createdataList.isEmpty()) {
+                    SaveServiceHelper.save(dynamicObjectType, createdataList.toArray(new DynamicObject[0]));
+                }
+                //更新的数据不为空,则更新到数据库中
+                if (!updatedataList.isEmpty()) {
+                    SaveServiceHelper.save(updatedataList.get(0).getDynamicObjectType(), updatedataList.toArray(new DynamicObject[0]));
+                }
+                this.getView().showMessage("数据已成功保存!");
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                this.getView().showMessage("读取文件时发生错误:" + ex.getMessage());
+            } catch (Exception ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+
+
+        //获取linux服务器连接
+        if ("connect".equals(e.getOperateKey()))
+        {
+            try {
+                FileCreat();
+            } catch (JSchException ex) {
+                throw new RuntimeException(ex);
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            } catch (Exception ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+
+    }
+
+
+    //连接服务器操作文件类
+    public void FileCreat() throws Exception {
+        SftpClient sftpClient=new SftpClient(host,username,password,port);
+        //连接服务器
+        sftpClient.connect();
+        String remoteFilePath = "/home/kingdee/cosmic/nginx-appstatic/store/appstatic/20240908/zzry.dat";  // 上传到远程服务器的路径
+        BufferedReader reader = new BufferedReader(new InputStreamReader(sftpClient.fileInputStream(remoteFilePath)));
+        reader.readLine();
+        // 5. 上传文件到远程服务器
+        File file=new File(remoteFilePath);
+        FileInputStream fis = new FileInputStream(file);
+        if (!file.exists())
+        {
+            File parentDir = file.getParentFile();
+            ///没有路径就创建文件夹
+            if (parentDir != null && !parentDir.exists()) {
+                parentDir.mkdirs();
+            }
+            //创建文件
+            file.createNewFile();
+            //上传到linux服务器
+            sftpClient.getSftpChannel().put(fis,remoteFilePath);
+            this.getView().showMessage("成功生成文件");
+        }else {
+            this.getView().showMessage("已存在文件");
+        }
+        // 6. 关闭流和连接
+        fis.close();
+        sftpClient.disconnect();
+    }
+
+    //根据减值数据存储客户名客户号数据
+    public void custSave(DynamicObject[] dynamicObjectlist)
+    {
+        //客户基础资料
+        DynamicObjectType dynamicObjectType = EntityMetadataCache.getDataEntityType("nckd_customers");
+        //客户表字段
+        List<String> selector = Arrays.asList(
+                "number", "name"
+        );
+        //查询已经存在的客户数据
+        DynamicObject[] existingData = BusinessDataServiceHelper
+                .load(dynamicObjectType.getName(), String.join(",", selector),null);
+        List<DynamicObject> dataListAdd = new ArrayList<>();
+        //存在数据的客户号
+        Map<String, DynamicObject> existingDataMap = new HashMap<>();
+        for (DynamicObject obj : existingData) {
+            existingDataMap.put(obj.getString("number"), obj);
+        }
+
+        for(DynamicObject dataList:dynamicObjectlist)
+        {
+            //获取这条数据的编码
+            String nckd_cust_id=dataList.getString("nckd_cust_id");
+            //客户号不存在则保存
+            if (!existingDataMap.containsKey(nckd_cust_id))
+            {
+                DynamicObject data = new DynamicObject(dynamicObjectType);
+                //客户号
+                data.set("number",dataList.getString("nckd_cust_id"));
+                //客户名
+                data.set("name",dataList.getString("nckd_cust_id"));
+                //设置状态为可用
+                data.set("enable","1");
+                //设置状态为已审核
+                data.set("status","C");
+                dataListAdd.add(data);
+            }
+        }
+        //保存
+        SaveServiceHelper.save(dynamicObjectType,dataListAdd.toArray(new DynamicObject[0]));
+
+    }
+}
+
+

+ 77 - 0
src/main/java/sys/sc/opplugin/utils/ReflectUtils.java

@@ -0,0 +1,77 @@
+package sys.sc.opplugin.utils;
+
+import kd.bos.audit.Audit;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.TypesContainer;
+import kd.bos.dataentity.resource.ResManager;
+import kd.bos.exception.ErrorCode;
+import kd.bos.exception.KDException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class ReflectUtils {
+            private static final ConcurrentHashMap<String, Object> serviceObjectMap = new ConcurrentHashMap<>();
+            private static final ConcurrentHashMap<String, Method> serviceMethodMap = new ConcurrentHashMap<>();
+            public static Object invokeCosmicMethod(String appServiceFacory, String serviceName, String methodName, Object... paras) {
+                Class<?> factory = TypesContainer.getOrRegister(appServiceFacory);
+                Object result = null;
+                Object serviceObject = serviceObjectMap.get(serviceName);
+                if (serviceObject == null) {
+                    synchronized (serviceObjectMap) {
+                        serviceObject = serviceObjectMap.get(serviceName);
+                        if (serviceObject == null) {
+                            try {
+                                serviceObject = factory.getMethod("getService", String.class).invoke(null, serviceName);
+                            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+                                e.printStackTrace();
+                            }
+                            if (serviceObject != null) {
+                                serviceObjectMap.put(serviceName, serviceObject);
+                            }
+                        }
+                    }
+                }
+
+                if (serviceObject != null) {
+                    Method serviceMethod = findServiceMethod(serviceObject.getClass(), methodName, paras == null ? 0 : paras.length);
+                    Audit audit = RequestContext.get().getAudit();
+                    if (audit.getServiceName() == null) {
+                        audit.setServiceName(serviceName + '.' + methodName);
+                    }
+
+                    try {
+                        result = serviceMethod.invoke(serviceObject, paras);
+                    } catch (IllegalAccessException | InvocationTargetException e) {
+                        e.printStackTrace();
+                    }
+                }
+
+                return result;
+            }
+
+            private static Method findServiceMethod(Class<?> clazz, String method, int paramterLength) {
+                String key = clazz.getName() + '#' + method + '#' + paramterLength;
+                Method serviceMethod = serviceMethodMap.get(key);
+                if (serviceMethod == null) {
+                    synchronized (serviceMethodMap) {
+                        serviceMethod = serviceMethodMap.get(key);
+                        if (serviceMethod == null) {
+                            Method[] methods = clazz.getMethods();
+                            for (Method m : methods) {
+                                if (m.getName().equalsIgnoreCase(method) && m.getParameterCount() == paramterLength) {
+                                    serviceMethod = m;
+                                    serviceMethodMap.put(key, m);
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    if (serviceMethod == null) {
+                        throw new KDException(new ErrorCode("###", ResManager.loadKDString("未发现类%s的方法%s", "DispatchServiceImpl_1", "bos-mservice-form")), clazz.getName(), method);
+                    }
+                }
+                return serviceMethod;
+            }
+        }

+ 74 - 0
src/main/java/sys/sc/opplugin/utils/SftpClient.java

@@ -0,0 +1,74 @@
+package sys.sc.opplugin.utils;
+
+/**
+ * @author cjz
+ * @date 2024/9/9 17:05
+ * @description:连接服务器获取sftp,工具类
+ */
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.SftpException;
+
+import java.io.FileOutputStream;
+import java.io.InputStream;
+
+public class SftpClient {
+    private String host;
+    private String usernmae;
+    private String password;
+    private int port;
+    private Session session;
+    private ChannelSftp sftpChannel;
+
+    public SftpClient(String host, String user, String password,int port) {
+        this.host = host;
+        this.usernmae = user;
+        this.password = password;
+        this.port=port;
+    }
+
+    // 连接到 SFTP 服务器
+    public void connect() throws Exception {
+        JSch jsch = new JSch();
+        session = jsch.getSession(usernmae, host, port);
+        session.setPassword(password);
+        session.setConfig("StrictHostKeyChecking", "no");
+        session.connect();
+        sftpChannel = (ChannelSftp) session.openChannel("sftp");
+        sftpChannel.connect();
+    }
+    //根据服务器路径读取文件,返回文件流
+    public InputStream fileInputStream(String remoteFilePath) throws SftpException {
+        InputStream inputStream = sftpChannel.get(remoteFilePath);
+        return inputStream;
+    }
+
+    // 下载文件
+//    public void downloadFile(String remoteFilePath, String localFilePath) throws Exception {
+//        try (InputStream inputStream = sftpChannel.get(remoteFilePath);
+//             FileOutputStream outputStream = new FileOutputStream(localFilePath)) {
+//
+//            byte[] buffer = new byte[1024];
+//            int bytesRead;
+//            while ((bytesRead = inputStream.read(buffer)) != -1) {
+//                outputStream.write(buffer, 0, bytesRead);
+//            }
+//        }
+//    }
+
+    // 断开连接
+    public void disconnect() {
+        if (sftpChannel != null && sftpChannel.isConnected()) {
+            sftpChannel.disconnect();
+        }
+        if (session != null && session.isConnected()) {
+            session.disconnect();
+        }
+    }
+
+
+    public ChannelSftp getSftpChannel() {
+        return sftpChannel;
+    }
+}

+ 210 - 0
src/main/java/sys/sc/task/UpdateBankDailyTask.java

@@ -0,0 +1,210 @@
+package sys.sc.task;
+
+import com.alibaba.druid.support.logging.Log;
+import com.alibaba.druid.support.logging.LogFactory;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.exception.KDException;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.schedule.api.MessageHandler;
+import kd.bos.schedule.executor.AbstractTask;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import sys.sc.opplugin.utils.SftpClient;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * @author cjz
+ * @date 2024/9/10 9:00
+ * @description:日常更新行名行号调度计划
+ */
+public class UpdateBankDailyTask extends AbstractTask {
+    private static final Log log = LogFactory.getLog(UpdateBankDailyTask.class);
+    public static String host="192.168.10.69";//服务器ip地址
+    public static String username="root";//用户名
+    public static int port = 22;//端口号
+    public static String password="Kd@86262007";//用户密码
+
+
+    @Override
+    public MessageHandler getMessageHandle() {
+        return super.getMessageHandle();
+    }
+
+    @Override
+    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
+        log.info("----------------------获取服务器连接------------------------");
+        //获取服务器连接
+        SftpClient sftpClient=new SftpClient(host,username,password,port);
+        try {
+            sftpClient.connect();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        String mes="-----------------正在执行任务,读取行名行号---------------------";
+        log.info(mes+requestContext);
+        //行名行号表字段
+        List<String> selector = Arrays.asList(
+                "number", "name"
+        );
+        //行名行号表标识
+        String bd_bebank="bd_bebank";
+        try {
+            List<DynamicObject> createdataList = new ArrayList<>();
+            List<DynamicObject> updatedataList = new ArrayList<>();
+            //文件路径
+            String fileurl = getFileUrl("hmhhurl");
+            //基础资料
+            DynamicObjectType dynamicObjectType = EntityMetadataCache.getDataEntityType(bd_bebank);
+            //国家基础资料(中国)
+            DynamicObject country= BusinessDataServiceHelper
+                    .loadSingle("bd_country","number", new QFilter[]{new QFilter("number", QCP.equals, "001")});
+            //查出所有现有的数据
+            DynamicObject[] existingData = BusinessDataServiceHelper
+                    .load(dynamicObjectType.getName(), String.join(",", selector)+",enable,nckd_datasource", null);
+            //查找文件更新的数据
+            Map<String, DynamicObject> existingDataMap = new HashMap<>();
+            for (DynamicObject obj : existingData) {
+                //单据号
+                existingDataMap.put(obj.getString(selector.get(0)), obj);
+            }
+            Set<String> processeddubilidSet = new HashSet<>();
+            //读取服务器文件并写入
+            try (BufferedReader reader = new BufferedReader(new InputStreamReader(sftpClient.fileInputStream(fileurl)))) {
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    //去掉换行符|$|
+                    line = line.replace("|$|", "");
+                    //空格符号,根据这个符号分割
+                    String[] fields = line.split("\u0001");
+                    //如果获取的数据行不等于预设字段的行,则跳过这行数据
+//                        if (fields.length != selector.size()) {
+//                            continue;
+//                        }
+                    //获取单据号
+                    String dubil_id = fields[0];
+                    boolean isUpdated = false;
+                    DynamicObject data;
+                    processeddubilidSet.add(dubil_id);
+                    if (existingDataMap.containsKey(dubil_id)) {
+                        //获取对应单据号的数据
+                        data = existingDataMap.get(dubil_id);
+                        for (int i = 0; i < selector.size(); i++) {
+                            String fieldName = selector.get(i);
+                            String newValue = fields[i];
+                            String existingValue = data.getString(fieldName);
+                            //判断数据是否与之前的数据相同,不相同则更新
+                            if (!Objects.equals(existingValue, newValue)) {
+                                data.set(fieldName, newValue);
+                                isUpdated = true;
+                            }
+                        }
+                        //更新了数据则设置数据更新的时间
+                        if (isUpdated) {
+                            updatedataList.add(data);
+                        }
+                    } else {
+                        //不存在这条数据则新增一条到data中
+                        data = new DynamicObject(dynamicObjectType);
+                        for (int i = 0; i < selector.size(); i++) {
+                            data.set(selector.get(i), fields[i]);
+                        }
+                        //国家
+                        data.set("country",country);
+                        //省
+                        data.set("provincetxt","江西");
+                        //市
+                        data.set("citytxt","南昌");
+                        //联行号等于行号
+                        data.set("union_number",fields[0]);
+                        //设置可用状态
+                        data.set("enable","1");
+                        //设置数据来源,0为手动更新,1为文件自动更新
+                        data.set("nckd_datasource","1");
+                        createdataList.add(data);
+                    }
+                }
+            }
+            //关闭连接
+            sftpClient.disconnect();
+            //获取自动添加的数据,与手动添加的数据做区分,nckd_datasource:1为读取数据添加,0为手动添加
+            DynamicObject[] autoData = BusinessDataServiceHelper
+                    .load(dynamicObjectType.getName()
+                            , String.join(",", selector)+",enable,nckd_datasource",
+                            new QFilter[]{new QFilter("nckd_datasource", QCP.equals, "1")});
+            for (DynamicObject autoDatum : autoData) {
+                //如果导入的数据在系统中没有则禁用
+                if (!processeddubilidSet.contains(autoDatum.getString("number"))) {
+                    //设置禁用
+                    autoDatum.set("enable", "0");
+                }
+            }
+            SaveServiceHelper.save(autoData);
+            //查找更新数据
+            for (Map.Entry<String, DynamicObject> entry : existingDataMap.entrySet()) {
+                String dubil_id = entry.getKey();
+                DynamicObject data = entry.getValue();
+                if (!processeddubilidSet.contains(dubil_id)) {
+//                        data.set("nckd_isdelete", true);
+                    updatedataList.add(data);
+                }
+            }
+            //新增数据不为空则更新到数据库中
+            if (!createdataList.isEmpty()) {
+                SaveServiceHelper.save(dynamicObjectType, createdataList.toArray(new DynamicObject[0]));
+            }
+            //更新的数据不为空,则更新到数据库中
+            if (!updatedataList.isEmpty()) {
+                SaveServiceHelper.save(updatedataList.get(0).getDynamicObjectType(), updatedataList.toArray(new DynamicObject[0]));
+            }
+            log.info("------------------数据已成功保存------------------");
+        } catch (IOException ex) {
+            ex.printStackTrace();
+            log.info("----------------------读取文件时发生错误-----------------");
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @Override
+    public boolean isSupportReSchedule() {
+        return super.isSupportReSchedule();
+    }
+
+    //根据接口配置信息获取组织人员,拼接服务器文件路径url,参数为urlcode接口配置信息编码
+    public String getFileUrl(String urlcode)
+    {
+        //组织人员接口配置信息获取
+        DynamicObject nckd_jkpzxx= BusinessDataServiceHelper
+                .loadSingle("nckd_jkpzxx", new QFilter[]{new QFilter("number", "=", urlcode)});
+        //取文件名
+        String nckd_filename=nckd_jkpzxx.getString("nckd_filename");
+        //获取文件路径
+        String nckd_url=nckd_jkpzxx.getString("nckd_url");
+        //当前日期
+        Date currentDate=new Date();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(currentDate);
+        calendar.add(Calendar.DATE, -1); // 将日期减少一天
+        //日期减少一天
+        Date newDate = calendar.getTime();
+        //转换日期格式
+        SimpleDateFormat sf=new SimpleDateFormat("yyyyMMdd");
+        String datestr=sf.format(newDate);
+        //文件路径拼接
+        //真实路径
+        if (nckd_url.equals("/var/appstatic/")) {
+            nckd_url="/home/kingdee/cosmic/nginx-appstatic/store/appstatic/";
+        }
+        String realPath = nckd_url+datestr+"/"+nckd_filename;
+        return realPath;
+    }
+}

+ 490 - 0
src/main/java/sys/sc/task/UpdateDataDailyTask.java

@@ -0,0 +1,490 @@
+package sys.sc.task;
+
+import com.alibaba.druid.support.logging.Log;
+import com.alibaba.druid.support.logging.LogFactory;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.operate.result.OperationResult;
+import kd.bos.exception.KDException;
+import kd.bos.form.IFormView;
+import kd.bos.orm.ORM;
+import kd.bos.orm.query.QFilter;
+import kd.bos.schedule.api.MessageHandler;
+import kd.bos.schedule.executor.AbstractTask;
+import kd.bos.sec.user.utils.UserOperationUtils;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import sys.sc.formplugin.ABillServiceHelper;
+import sys.sc.opplugin.utils.SftpClient;
+
+import java.io.*;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * @author cjz
+ * @date 2024/9/3 15:13
+ * @description:获取日常数据更新组织和人员调度计划
+ */
+public class UpdateDataDailyTask extends AbstractTask {
+
+    private static final Log log = LogFactory.getLog(UpdateDataDailyTask.class);
+    public static String host="192.168.10.69";//服务器ip地址
+    public static String username="root";//用户名
+    public static int port = 22;//端口号
+    public static String password="Kd@86262007";//用户密码
+
+
+    @Override
+    public MessageHandler getMessageHandle() {
+        return super.getMessageHandle();
+    }
+
+    @Override
+    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
+        String mes="---------------正在执行任务,读取文件数据更新组织和人员------------------";
+        log.info(mes+requestContext);
+        //文件路径
+        String path=getFileUrl("organduserurl");
+        //获取连接对象
+        SftpClient sftpClient=new SftpClient(host,username,password,port);
+        try {
+            sftpClient.connect();
+            //读取文件更新基础资料
+            updatebasicdata(sftpClient.fileInputStream(path));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        //关闭连接
+        sftpClient.disconnect();
+        //更新组织
+        log.info("----------------更新组织中---------------------");
+        updateorg();
+        //更新人员
+        log.info("----------------更新人员中-------------------");
+        updateperson();
+    }
+    //读取文件更新基础资料
+    public void updatebasicdata(InputStream inputStream)
+    {
+        //读取文件写入基础资料中
+        try {
+            DynamicObjectType dynamicObjectType = EntityMetadataCache.getDataEntityType("nckd_basicdata");
+            List<String> selector = Arrays.asList(
+                    "nckd_employeeid", "nckd_name", "nckd_gender", "nckd_nl", "nckd_zzmm",
+                    "nckd_zgxl", "nckd_szdwname", "nckd_szdwcode", "nckd_orgidname", "nckd_orgidcode",
+                    "nckd_yjbmname", "nckd_yjbmcode", "nckd_posidname", "nckd_posidcode", "nckd_yggxlb",
+                    "nckd_status", "nckd_sjh"
+            );
+            List<DynamicObject> createdataList = new ArrayList<>();
+            List<DynamicObject> updatedataList = new ArrayList<>();
+            //查出所有现有的数据
+            DynamicObject[] existingData = BusinessDataServiceHelper
+                    .load(dynamicObjectType.getName(), String.join(",", selector) + ",nckd_updatedate,nckd_isdelete", null);
+            Map<String, DynamicObject> existingDataMap = new HashMap<>();
+            for (DynamicObject obj : existingData) {
+                existingDataMap.put(obj.getString("nckd_employeeid"), obj);
+            }
+            Set<String> processedGonghaoSet = new HashSet<>();
+            try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    //去掉换行符|$|
+                    line = line.replace("|$|", "");
+                    //空格符号,根据这个符号分割
+                    String[] fields = line.split("\u0001");
+                    //如果获取的数据行不等于预设字段的行,则跳过这行数据
+                    if (fields.length != selector.size()) {
+                        continue;
+                    }
+                    //获取工号
+                    String gonghao = fields[0];
+                    boolean isUpdated = false;
+                    DynamicObject data;
+                    processedGonghaoSet.add(gonghao);
+                    if (existingDataMap.containsKey(gonghao)) {
+                        //获取对应工号的数据
+                        data = existingDataMap.get(gonghao);
+                        for (int i = 0; i < selector.size(); i++) {
+                            String fieldName = selector.get(i);
+                            String newValue = fields[i];
+                            String existingValue = data.getString(fieldName);
+                            //判断数据是否与之前的数据相同,不相同则更新
+                            if (!Objects.equals(existingValue, newValue)) {
+                                data.set(fieldName, newValue);
+                                isUpdated = true;
+                            }
+                        }
+                        //更新了数据则设置数据更新的时间
+                        if (isUpdated) {
+                            data.set("nckd_updatedate", new Date());
+                            updatedataList.add(data);
+                        }
+                    } else {
+                        //不存在这条数据则新增一条到data中
+                        data = new DynamicObject(dynamicObjectType);
+                        for (int i = 0; i < selector.size(); i++) {
+                            data.set(selector.get(i), fields[i]);
+                        }
+                        Date now = new Date();
+                        data.set("nckd_createdate", now);
+                        data.set("nckd_updatedate", now);
+                        createdataList.add(data);
+                    }
+                }
+            }
+            for (Map.Entry<String, DynamicObject> entry : existingDataMap.entrySet()) {
+                String gonghao = entry.getKey();
+                DynamicObject data = entry.getValue();
+
+                if (!processedGonghaoSet.contains(gonghao)) {
+                    data.set("nckd_isdelete", true);
+                    updatedataList.add(data);
+                }
+            }
+            //新增数据不为空则更新到数据库中
+            if (!createdataList.isEmpty()) {
+                SaveServiceHelper.save(dynamicObjectType, createdataList.toArray(new DynamicObject[0]));
+            }
+            //更新的数据不为空,则更新到数据库中
+            if (!updatedataList.isEmpty()) {
+                SaveServiceHelper.save(updatedataList.get(0).getDynamicObjectType(), updatedataList.toArray(new DynamicObject[0]));
+            }
+            log.info("数据已成功保存!");
+        } catch (IOException ex) {
+            ex.printStackTrace();
+            log.info("读取文件时发生错误:" + ex.getMessage());
+        }
+    }
+    //根据基础资料更新组织
+    public void updateorg()
+    {
+        // 获取形态信息 编码为 Orgform06 的 bos_org_pattern(部门组织)
+        DynamicObject xingtaiinfo = BusinessDataServiceHelper.loadSingle(
+                "bos_org_pattern", new QFilter[]{new QFilter("number", "=", "Orgform06")}
+        );
+        //获取形态信息,编码为 Orgform02 的bos_org_pattern(公司组织)
+        DynamicObject cpyinfo = BusinessDataServiceHelper.loadSingle(
+                "bos_org_pattern", new QFilter[]{new QFilter("number", "=", "Orgform02")}
+        );
+        // 查询 nckd_basicdata 表中需要更新的数据
+        DynamicObject[] nckdData = BusinessDataServiceHelper.load(
+                "nckd_basicdata",
+                "id,nckd_szdwcode,nckd_szdwname,nckd_yjbmcode,nckd_yjbmname,nckd_orgidcode,nckd_orgidname",
+                null
+        );
+        //行政组织
+        DynamicObject rootOrg = BusinessDataServiceHelper.loadSingle(
+                "bos_adminorg", new QFilter[]{new QFilter("number", "=", "jxyh")}
+        );
+        if (rootOrg == null) {
+            log.info("指定的上级组织 'jxyh' 未找到!");
+            return;
+        }
+        IFormView orgview = ABillServiceHelper.createAddView("bos_adminorg");
+        for (DynamicObject record : nckdData) {
+            // 判断并创建或更新所在单位
+            //所在单位编码
+            String szdwbm = record.getString("nckd_szdwcode");
+            //所在单位名称
+            String szdwmc = record.getString("nckd_szdwname");
+            DynamicObject org = BusinessDataServiceHelper.loadSingle(
+                    "bos_adminorg", new QFilter[]{new QFilter("number", "=", szdwbm)}
+            );
+            //没有单位则创建
+            if (org == null) {
+                //组织编码
+                orgview.getModel().setValue("number", szdwbm);
+                //组织名称
+                orgview.getModel().setValue("name", szdwmc);
+                //上级组织
+                orgview.getModel().setValue("parent", rootOrg);
+                //形态,设置形态为公司
+                orgview.getModel().setValue("orgpattern", cpyinfo);
+                //数据状态设置为已审核
+                orgview.getModel().setValue("status", "C");
+                //使用状态设置为可用
+                orgview.getModel().setValue("enable", "1");
+                OperationResult operationResult = ABillServiceHelper.saveOperate(orgview);
+                //保存不成功
+                if (!operationResult.isSuccess()) {
+
+                }
+                org = orgview.getModel().getDataEntity();
+                //如果存在单位则检查单位名是否一致,不一致则更新
+            }else if (!org.getString("name").equals(szdwmc))
+            {
+                //设置单位名称
+                org.set("name",szdwmc);
+                // 更新组织结构
+                DynamicObjectCollection structureInfoCollection = org.getDynamicObjectCollection("structure");
+                DynamicObject structureInfo = structureInfoCollection.get(0);
+                //设置长名称
+                structureInfo.set("fullname",rootOrg.getString("name")+"_"+szdwmc);
+                SaveServiceHelper.update(org);
+            }
+            // 判断一级机构编码 在行政组织中是否存在,不存在则新增
+            String yjjgbm = record.getString("nckd_yjbmcode");
+            String yjjgmc = record.getString("nckd_yjbmname");
+            //一级机构
+            DynamicObject yjjg = BusinessDataServiceHelper.loadSingle("bos_adminorg", new QFilter[]{new QFilter("number", "=", yjjgbm)});
+            if (yjjg == null) {
+                IFormView yjjgView=orgview;
+                yjjgView.getModel().setValue("number", yjjgbm);
+                yjjgView.getModel().setValue("name", yjjgmc);
+                yjjgView.getModel().setValue("parent", org); // 父级组织为 org
+                yjjgView.getModel().setValue("orgpattern", xingtaiinfo);
+                yjjgView.getModel().setValue("status", "C");
+                yjjgView.getModel().setValue("enable", "1");
+                OperationResult yjjgOperationResult = ABillServiceHelper.saveOperate(yjjgView);
+                if (!yjjgOperationResult.isSuccess()) {
+                    // Handle the failure case here
+                }
+                yjjg = yjjgView.getModel().getDataEntity();
+            } else if (!yjjg.getString("name").equals(yjjgmc)) {
+                yjjg.set("name",yjjgmc);
+                DynamicObjectCollection structureInfoCollection = yjjg.getDynamicObjectCollection("structure");
+                DynamicObject structureInfo = structureInfoCollection.get(0);
+                //设置长名称
+                structureInfo.set("fullname",rootOrg.getString("name")+"_"+szdwmc+"_"+yjjgmc);
+                SaveServiceHelper.update(yjjg);
+            }
+            // 判断所在部门编码 在行政组织中是否存在,不存在则新增
+            String szbmbm = record.getString("nckd_orgidcode");
+            String szbmmc = record.getString("nckd_orgidname");
+            //所在部门
+            DynamicObject szbm = BusinessDataServiceHelper.loadSingle("bos_adminorg", new QFilter[]{new QFilter("number", "=", szbmbm)});
+            if (szbm == null) {
+                IFormView szbmView=orgview;
+                szbmView.getModel().setValue("number", szbmbm);
+                szbmView.getModel().setValue("name", szbmmc);
+                szbmView.getModel().setValue("parent", yjjg); // 设置父级为 yjjg
+                szbmView.getModel().setValue("orgpattern", xingtaiinfo);
+                szbmView.getModel().setValue("status", "C"); // 设置状态
+                szbmView.getModel().setValue("enable", "1"); // 设置为启用状态
+                // 保存操作
+                OperationResult szbmOperationResult = ABillServiceHelper.saveOperate(szbmView);
+                if (!szbmOperationResult.isSuccess()) {
+                    // 如果保存失败,可以在这里处理错误
+                    log.info("保存部门失败!");
+                    return;
+                }
+                if (szbmView.getModel() != null) {
+                    szbm = szbmView.getModel().getDataEntity();
+                } else {
+                    log.info("保存后未能获取到部门数据!");
+                    return;
+                }
+                log.info("行政组织数据已成功更新!");
+            } else if (!szbm.getString("name").equals(szbmmc)) {
+                szbm.set("name",szbmmc);
+                DynamicObjectCollection structureInfoCollection = szbm.getDynamicObjectCollection("structure");
+                DynamicObject structureInfo = structureInfoCollection.get(0);
+                //设置长名称
+                structureInfo.set("fullname",rootOrg.getString("name")+"_"+szdwmc+"_"+yjjgmc+"_"+szbmmc);
+                SaveServiceHelper.update(szbm);
+            }
+        }
+    }
+    //根据基础资料更新人员
+    public void updateperson()
+    {
+        // 从 nckd_basicdata 表中获取所有人员数据,假设通过某个条件查找
+        DynamicObject[] personDataArray = BusinessDataServiceHelper.load(
+                "nckd_basicdata",
+                "id,nckd_employeeid,nckd_name,nckd_gender,nckd_nl,nckd_zzmm,nckd_zgxl,nckd_orgidname,nckd_orgidcode,nckd_posidname,nckd_posidcode,nckd_yggxlb,nckd_status,nckd_sjh",
+                null
+        );
+        if (personDataArray == null || personDataArray.length == 0) {
+            log.info("未从 nckd_basicdata 表中获取到任何人员数据!");
+            return;
+        }
+        String msg="";
+        for (DynamicObject personData : personDataArray) {
+            log.info("-------------更新人员------------");
+            // 获取工号
+            String gonghao = personData.getString("nckd_employeeid");
+            if (gonghao == null || gonghao.isEmpty()) {
+                continue;
+            }
+            // 查询用户是否已存在
+            DynamicObject existingUser = BusinessDataServiceHelper.loadSingle(
+                    "bos_user", new QFilter[]{new QFilter("number", "=", gonghao)}
+            );
+            // 用户已存在,进行数据更新
+            if (existingUser != null) {
+                //初始化
+                boolean isUpdated = false;
+                // 比较并更新性别
+                Object newGender = personData.get("nckd_gender");
+                if (!newGender.equals(existingUser.get("gender"))) {
+                    existingUser.set("gender", newGender);
+                    isUpdated = true;
+                }
+                // 比较并更新手机号
+                Object newPhone = personData.get("nckd_sjh");
+                if (!newPhone.equals(existingUser.get("phone"))) {
+                    existingUser.set("phone", newPhone);
+                    isUpdated = true;
+                }
+                //更新部门和岗位
+                DynamicObjectCollection existingDeptEntries = existingUser.getDynamicObjectCollection("entryentity");
+                //人员部门分录
+                DynamicObject existingDeptEntry = existingDeptEntries.isEmpty() ? null : existingDeptEntries.get(0);
+                // 获取新的部门信息
+                String deptCode = personData.getString("nckd_orgidcode");
+                DynamicObject newOrgInfo = BusinessDataServiceHelper.loadSingle(
+                        "bos_adminorg", new QFilter[]{new QFilter("number", "=", deptCode)}
+                );
+                boolean deptUpdated = false;
+                if (newOrgInfo != null) {
+                    if (existingDeptEntry == null) {
+                        // 如果没有现有部门分录,则添加新的部门分录
+                        existingDeptEntry = existingDeptEntries.addNew();
+                        deptUpdated = true;
+                    }
+                    // 比较并更新部门信息
+                    if (!deptCode.equals(existingDeptEntry.get("dpt.number"))) {
+                        existingDeptEntry.set("dpt", newOrgInfo);
+                        deptUpdated = true;
+                    }
+                    // 更新组织结构
+                    DynamicObjectCollection structureInfoCollection = newOrgInfo.getDynamicObjectCollection("structure");
+                    if (structureInfoCollection != null && !structureInfoCollection.isEmpty()) {
+                        DynamicObject structureInfo = structureInfoCollection.get(0);
+                        if(existingDeptEntry.getDynamicObject("orgstructure")!=null){
+                            if (!structureInfo.getPkValue().equals(existingDeptEntry.getDynamicObject("orgstructure").getPkValue())) {
+                                existingDeptEntry.set("orgstructure", structureInfo.getPkValue());
+                                deptUpdated = true;
+                            }
+                        }else{
+                            existingDeptEntry.set("orgstructure", structureInfo.getPkValue());
+                            deptUpdated = true;
+                        }
+                    }
+                    // 标记是否需要保存
+                    if (deptUpdated) {
+                        isUpdated = true;
+                    }
+                } else {
+                    log.info("未找到部门编码为 " + deptCode + " 的部门信息!");
+                }
+                // 获取新的岗位信息
+                String postName = personData.getString("nckd_posidname");
+                if (!postName.equals(existingDeptEntry.getString("position"))) {
+                    existingDeptEntry.set("position", postName);
+                    isUpdated = true;
+                }
+                // 如果有更新则保存
+                if (isUpdated) {
+                    SaveServiceHelper.save(new DynamicObject[]{existingUser});
+                    msg+="工号为 " + gonghao + " 的用户信息已更新!";
+                }
+            } else {
+                // 用户不存在,创建新用户
+                DynamicObjectType userType = EntityMetadataCache.getDataEntityType("bos_user");
+                DynamicObject userinfo = new DynamicObject(userType);
+                ORM impl = ORM.create();
+                userinfo.set("id", impl.genLongId("bos_user"));
+                userinfo.set("number", gonghao);
+                // 设置其他字段
+                userinfo.set("gender", personData.get("nckd_gender"));
+                //人员手机号
+                userinfo.set("phone", personData.get("nckd_sjh"));
+                // 设置其他固定字段
+                userinfo.set("startdate", new Date());
+                Calendar c = Calendar.getInstance();
+                c.set(Calendar.YEAR, 2999);
+                userinfo.set("enddate", c.getTime());
+                userinfo.set("masterid", userinfo.get("id"));
+                userinfo.set("enable", 1);
+                userinfo.set("status", "C");
+                userinfo.set("password", "8HrquJnZfyOkmmHkpGLXfg==");
+                userinfo.set("isregisted", "1");
+                userinfo.set("isactived", "1");
+                userinfo.set("pswstrategy", "338333884850648064");
+                userinfo.set("psweffectivedate", new Date());
+                userinfo.set("useenddate", c.getTime());
+                // 设置姓名和拼音
+                String name = personData.getString("nckd_name");
+                userinfo.set("name", name);
+                String fullPinyin = UserOperationUtils.getFullSpellByName(name);
+                String simplePinyin = UserOperationUtils.getFirstSpellByName(name);
+                userinfo.set("fullpinyin", fullPinyin);
+                userinfo.set("simplepinyin", simplePinyin);
+                // 设置用户名
+                String username = UserOperationUtils.getUserNameByFormatedFullPinyin(
+                        (long) userinfo.getPkValue(), fullPinyin, null
+                );
+                userinfo.set("username", username);
+                // 创建部门分录
+                DynamicObjectCollection bmflList = userinfo.getDynamicObjectCollection("entryentity");
+                DynamicObject bumeninfo = bmflList.addNew();
+                // 获取部门编码并在 bos_adminorg 表中查找部门信息
+                String deptCode = personData.getString("nckd_orgidcode");
+                DynamicObject orginfo = BusinessDataServiceHelper.loadSingle(
+                        "bos_adminorg", new QFilter[]{new QFilter("number", "=", deptCode)}
+                );
+                if (orginfo != null) {
+                    bumeninfo.set("dpt", orginfo);
+                    // 获取组织的分录集合 structure 的第一条数据
+                    DynamicObjectCollection structureInfoCollection = orginfo.getDynamicObjectCollection("structure");
+                    if (structureInfoCollection != null && !structureInfoCollection.isEmpty()) {
+                        DynamicObject structureInfo = structureInfoCollection.get(0); // 获取第一条结构信息
+                        bumeninfo.set("orgstructure", structureInfo.getPkValue());
+                    } else {
+                        log.info("部门编码为 " + deptCode + " 的部门缺少组织结构信息,跳过该记录。");
+                    }
+                }
+                String postName = personData.getString("nckd_posidname");;
+                bumeninfo.set("position", postName);
+                //所在岗位名称
+                String positionnumber = personData.getString("nckd_posidname");;
+                bumeninfo.set("post", positionnumber);
+                // 保存新用户信息
+                SaveServiceHelper.save(new DynamicObject[]{userinfo});
+                msg+="工号为 " + gonghao + " 的用户已创建!";
+            }
+        }
+        if("".equals(msg)){
+            log.info("没有需要更新或新增的人员");
+        }else{
+            log.info(msg);
+        }
+    }
+    //根据接口配置信息获取组织人员,拼接服务器文件路径url,参数为urlcode接口配置信息编码
+    public String getFileUrl(String urlcode)
+    {
+        //组织人员接口配置信息获取
+        DynamicObject nckd_jkpzxx= BusinessDataServiceHelper
+                .loadSingle("nckd_jkpzxx", new QFilter[]{new QFilter("number", "=", urlcode)});
+        //取文件名
+        String nckd_filename=nckd_jkpzxx.getString("nckd_filename");
+        //获取文件路径
+        String nckd_url=nckd_jkpzxx.getString("nckd_url");
+        //当前日期
+        Date currentDate=new Date();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(currentDate);
+        calendar.add(Calendar.DATE, -1); // 将日期减少一天
+        //日期减少一天
+        Date newDate = calendar.getTime();
+        //转换日期格式
+        SimpleDateFormat sf=new SimpleDateFormat("yyyyMMdd");
+        String datestr=sf.format(newDate);
+        //文件路径拼接
+        //真实路径
+        if (nckd_url.equals("/var/appstatic/")) {
+            nckd_url="/home/kingdee/cosmic/nginx-appstatic/store/appstatic/";
+        }
+        String realPath = nckd_url+datestr+"/"+nckd_filename;
+        return realPath;
+    }
+    @Override
+    public boolean isSupportReSchedule() {
+        return super.isSupportReSchedule();
+    }
+}

+ 200 - 0
src/main/java/sys/sc/task/UpdateImpairmentDailyTask.java

@@ -0,0 +1,200 @@
+package sys.sc.task;
+
+import com.alibaba.druid.support.logging.Log;
+import com.alibaba.druid.support.logging.LogFactory;
+import com.jcraft.jsch.SftpException;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.exception.KDException;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.schedule.api.MessageHandler;
+import kd.bos.schedule.executor.AbstractTask;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.DeleteServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import sys.sc.opplugin.utils.SftpClient;
+
+import java.io.*;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * @author cjz
+ * @date 2024/9/10 11:06
+ * @description:减值数据自动更新,并更新客户基础资料
+ */
+public class UpdateImpairmentDailyTask extends AbstractTask {
+    private static final Log log = LogFactory.getLog(UpdateImpairmentDailyTask.class);
+    public static String host="192.168.10.69";//服务器ip地址
+    public static String username="root";//用户名
+    public static int port = 22;//端口号
+    public static String password="Kd@86262007";//用户密码
+
+
+    @Override
+    public MessageHandler getMessageHandle() {
+        return super.getMessageHandle();
+    }
+
+    @Override
+    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
+        log.info("---------------------获取服务器连接--------------------");
+        //获取服务器连接
+        SftpClient sftpClient=new SftpClient(host,username,password,port);
+        try {
+            sftpClient.connect();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        String mes="-------------------------正在执行任务,读取减值数据----------------------";
+        log.info(mes+requestContext);
+        try {
+            //文件路径
+            String filelocation=getFileUrl("jzsjurl");
+            //减值数据基础资料
+            DynamicObjectType dynamicObjectType = EntityMetadataCache.getDataEntityType("nckd_impairment");
+            //减值表字段
+            List<String> selector = Arrays.asList(
+                    "nckd_dubil_id", "nckd_cust_id", "nckd_cur_cd", "nckd_dubil_amt", "nckd_asset_bal",
+                    "nckd_stage_rslt", "nckd_ecl_ratio","nckd_cust_name"
+            );
+            List<DynamicObject> createdataList = new ArrayList<>();
+            QFilter filter=new QFilter("nckd_isdelete", QCP.equals,false);
+            //查询已经存在的数据
+            DynamicObject[] existingData = BusinessDataServiceHelper
+                    .load(dynamicObjectType.getName(), String.join(",", selector) + ",nckd_isdelete", new QFilter[]{filter});
+            Set<String> processeddubilidSet = new HashSet<>();
+            try (BufferedReader reader = new BufferedReader(new InputStreamReader(sftpClient.fileInputStream(filelocation)))) {
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    //去掉换行符|$|
+                    line = line.replace("|$|", "");
+                    //空格符号,根据这个符号分割
+                    String[] fields = line.split("\u0001");
+                    //如果获取的数据行不等于预设字段的行,则跳过这行数据
+                    if (fields.length != selector.size()) {
+                        continue;
+                    }
+                    //获取单据号
+                    String dubil_id = fields[0];
+                    DynamicObject data;
+                    processeddubilidSet.add(dubil_id);
+                    //新增数据
+                    data = new DynamicObject(dynamicObjectType);
+                    for (int i = 0; i < selector.size(); i++) {
+                        data.set(selector.get(i), fields[i]);
+                    }
+                    //设置创建时间
+                    data.set("nckd_creatd",new Date());
+                    data.set("nckd_isdelete",false);
+                    createdataList.add(data);
+                }
+            }
+            sftpClient.disconnect();
+            //读取的文件数据转化成DynamicObject
+            DynamicObject[] dynamicObjectlist=createdataList.toArray(new DynamicObject[0]);
+            //新增数据不为空则更新到数据库中
+            if (!createdataList.isEmpty()) {
+                //转换list为DynamicObject类型
+                SaveServiceHelper.save(dynamicObjectType,dynamicObjectlist);
+            }
+            //删除所有的数据,再新增
+            for (DynamicObject existingDatum : existingData) {
+                existingDatum.set("nckd_isdelete", true);
+            }
+            SaveServiceHelper.save(existingData);
+            QFilter qFilter=new QFilter("nckd_isdelete",QCP.equals,true);
+            DeleteServiceHelper.delete(dynamicObjectType.getName(),new QFilter[]{qFilter});
+            log.info("-----------------------减值数据已成功保存---------------------");
+            custSave(dynamicObjectlist);
+            log.info("------------------------客户数据已成功保存----------------------");
+        } catch (IOException ex) {
+            ex.printStackTrace();
+            log.error("----------------------------读取文件发生错误"+ex.getMessage()+"--------------------------");
+        } catch (SftpException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public boolean isSupportReSchedule() {
+        return super.isSupportReSchedule();
+    }
+
+    //根据接口配置信息获取组织人员,拼接服务器文件路径url,参数为urlcode接口配置信息编码
+    public String getFileUrl(String urlcode) throws IOException {
+        //组织人员接口配置信息获取
+        DynamicObject nckd_jkpzxx= BusinessDataServiceHelper
+                .loadSingle("nckd_jkpzxx", new QFilter[]{new QFilter("number", "=", urlcode)});
+        //取文件名
+        String nckd_filename=nckd_jkpzxx.getString("nckd_filename");
+        //获取文件路径
+        String nckd_url=nckd_jkpzxx.getString("nckd_url");
+        //当前日期
+        Date currentDate=new Date();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(currentDate);
+        calendar.add(Calendar.DATE, -1); // 将日期减少一天
+        //日期减少一天
+        Date newDate = calendar.getTime();
+        //转换日期格式
+        SimpleDateFormat sf=new SimpleDateFormat("yyyyMMdd");
+        String datestr=sf.format(newDate);
+        //真实路径
+        if (nckd_url.equals("/var/appstatic/")) {
+            nckd_url="/home/kingdee/cosmic/nginx-appstatic/store/appstatic/";
+        }
+        //文件完整路径
+        String realPath = nckd_url+datestr+ File.separator+nckd_filename;
+        return realPath;
+    }
+
+
+    //根据减值数据存储客户名客户号数据
+    public void custSave(DynamicObject[] dynamicObjectlist)
+    {
+        //客户基础资料
+        DynamicObjectType dynamicObjectType = EntityMetadataCache.getDataEntityType("nckd_customers");
+        //客户表字段
+        List<String> selector = Arrays.asList(
+                "number", "name"
+        );
+        //查询已经存在的客户数据
+        DynamicObject[] existingData = BusinessDataServiceHelper
+                .load(dynamicObjectType.getName(), String.join(",", selector),null);
+
+
+        List<DynamicObject> dataListAdd = new ArrayList<>();
+        //存在数据的客户号
+        Map<String, DynamicObject> existingDataMap = new HashMap<>();
+        for (DynamicObject obj : existingData) {
+            existingDataMap.put(obj.getString("number"), obj);
+        }
+
+        for(DynamicObject dataList:dynamicObjectlist)
+        {
+            //获取这条数据的id
+            String nckd_cust_id=dataList.getString("nckd_cust_id");
+            //客户号不存在则保存
+            if (!existingDataMap.containsKey(nckd_cust_id))
+            {
+                DynamicObject data = new DynamicObject(dynamicObjectType);
+                //客户号
+                data.set("number",dataList.getString("nckd_cust_id"));
+                //客户名
+                data.set("name",dataList.getString("nckd_cust_name"));
+                //设置状态为可用
+                data.set("enable","1");
+                //设置状态为已审核
+                data.set("status","C");
+                dataListAdd.add(data);
+            }
+        }
+        //保存
+        SaveServiceHelper.save(dynamicObjectType,dataListAdd.toArray(new DynamicObject[0]));
+
+    }
+}