浏览代码

Merge remote-tracking branch 'origin/master'

徐昊 7 月之前
父节点
当前提交
7bd392c478

+ 40 - 26
src/main/java/fi/cas/opplugin/PayBillToolUtil.java

@@ -51,6 +51,9 @@ public class PayBillToolUtil {
             createElement(doc, body, "channelcode", "经费共享");//发起渠道
             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 +66,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);//实际付款人账户
@@ -182,36 +185,44 @@ 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{
-                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("DDDDDDD");
+                    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");
+                    }
+
                 }
             }
-            ////返回日志处理
-            System.out.println("调用支付前置接口返回值:" + cbsReturnJson.toString());
 
             if (isSuccess) {
                 SaveServiceHelper.update(new DynamicObject[]{payBillEntity});
@@ -227,10 +238,13 @@ 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_djlx","1");
             OperationServiceHelper.executeOperate("save","nckd_zfjkdyrz",new DynamicObject[]{logInfo});
 
@@ -246,7 +260,7 @@ public class PayBillToolUtil {
         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();
 

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

@@ -0,0 +1,187 @@
+package kd.bos.login.utils;
+
+import fi.cas.opplugin.TypeUtils;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.login.utils.sms.SMSSender;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import org.json.JSONObject;
+import org.json.XML;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.*;
+import java.net.Socket;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * 通用插件
+ * 2024-09-02 wangj
+ * 主要功能:短信发送扩展调用第三方接口
+ */
+public class DemoSMSSender implements SMSSender {
+    protected static final Log log = LogFactory.getLog(DemoSMSSender.class);
+
+    @Override
+    public boolean sendMessage(String phone, String message, String signature) {
+        Boolean flag = false;
+        //1.获取接口链接等信息
+        DynamicObject jkpzxx = BusinessDataServiceHelper.loadSingle("nckd_jkpzxx",new QFilter[]{new QFilter("number","=","dxyz")});
+        String servername =  jkpzxx.getString("nckd_servername");
+        String port =  jkpzxx.getString("nckd_port");
+        //2.获取xml对象
+        String bodyxml = createSingleMessageRequest(phone,message);
+        //3.调用接口
+        JSONObject cbsReturnJson =socketService(servername,port,bodyxml);
+        if(cbsReturnJson!=null) {
+            JSONObject reMessage = cbsReturnJson.getJSONObject("Message");
+            JSONObject reBodyInfo = reMessage.getJSONObject("BodyInfo");
+            if ("success".equals(reBodyInfo.getString("Fs_retMsg"))) {//相应成功
+                if ("000".equals(reBodyInfo.getString("Fs_retCode"))) {
+                    flag = true;
+                    log.info("短信前置机响应成功,前置机接口发送成功");
+                } else {
+                    log.info("短信前置机响应成功,前置机接口发送失败");
+                }
+            } else {
+                log.info("短信发送前置机响应失败");
+            }
+        }
+
+        return flag;
+    }
+
+    @Override
+    public boolean sendMessage(String phone, String message) {
+        Boolean flag = false;
+//        //1.获取接口链接等信息
+//        DynamicObject jkpzxx = BusinessDataServiceHelper.loadSingle("nckd_jkpzxx",new QFilter[]{new QFilter("number","=","dxyz")});
+//        String servername =  jkpzxx.getString("nckd_servername");
+//        String port =  jkpzxx.getString("nckd_port");
+//        //2.获取xml对象
+//        String bodyxml = createSingleMessageRequest(phone,message);
+//        //3.调用接口
+//        JSONObject cbsReturnJson =socketService(servername,port,bodyxml);
+//        if(cbsReturnJson!=null) {
+//            JSONObject reMessage = cbsReturnJson.getJSONObject("Message");
+//            JSONObject reBodyInfo = reMessage.getJSONObject("BodyInfo");
+//            if ("success".equals(reBodyInfo.getString("Fs_retMsg"))) {//相应成功
+//                if ("000".equals(reBodyInfo.getString("Fs_retCode"))) {
+//                    flag = true;
+//                    log.info("短信前置机响应成功,前置机接口发送成功");
+//                } else {
+//                    log.info("短信前置机响应成功,前置机接口发送失败");
+//                }
+//            } else {
+//                log.info("短信发送前置机响应失败");
+//            }
+//        }
+
+        return flag;
+    }
+
+    private String createSingleMessageRequest(String phone, String message) {
+        try {
+            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+            Document doc = dBuilder.newDocument();
+            //创建Message节点
+            Element rootElement = doc.createElement("Message");
+            doc.appendChild(rootElement);
+            //创建BodyInfo节点
+            Element body = doc.createElement("BodyInfo");
+            rootElement.appendChild(body);
+            //拼接报文
+            createElement(doc, body, "Fs_channelcode", "JSX"); //渠道号
+            createElement(doc, body, "Fs_transcode", "SingleMsg");  //交易码
+            createElement(doc, body, "Fs_rpid", "12345");        //流水号(待提供)
+            createElement(doc, body, "Fs_phone", phone);        //手机号
+            createElement(doc, body, "Fs_ParamCount", "2");//模板数量
+            createElement(doc, body, "ParamName1", "SmsVerifyCode");//模板名称1
+            String ParamValue1 = message.substring(4,10);
+            createElement(doc, body, "ParamValue1", ParamValue1);//模板值1
+            createElement(doc, body, "ParamName2", "SceneName");//模板名称2
+            createElement(doc, body, "ParamValue2", "wj");//模板值2
+
+            createElement(doc, body, "Fs_regOrg", "");//发送机构(待提供)
+            createElement(doc, body, "Fs_bizId", "00007");//业务类型id
+            createElement(doc, body, "Fs_templateld", "2409029227");//模板id
+
+            Date now = new Date();
+            SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd HHmmss");
+            String nowStr = formatter.format(now);
+            String Fs_reqDate = nowStr.substring(0,8);
+            createElement(doc, body, "Fs_reqDate", Fs_reqDate);
+            String Fs_regTime = nowStr.substring(9,15);
+            createElement(doc, body, "Fs_regTime", Fs_regTime);
+
+            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;
+        }
+    }
+
+    private String tranTime(int hour, int minute, int second) {
+        String Fs_regTime = String.valueOf(hour)+String.valueOf(minute)+String.valueOf(second);
+
+        return Fs_regTime;
+    }
+
+    public static JSONObject socketService(String serverName,String port,String xmlData){
+        try {
+            Socket client = new Socket(serverName, TypeUtils.nullToInt(port));
+            OutputStream outToServer = client.getOutputStream();
+            PrintWriter out = new PrintWriter(new OutputStreamWriter(outToServer, "GBK"), true);
+            out.println(xmlData);
+
+            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;
+    }
+
+    private static void createElement(Document doc, Element parent, String name, String value) {
+        Element element = doc.createElement(name);
+        element.appendChild(doc.createTextNode(value));
+        parent.appendChild(element);
+    }
+}

+ 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;
+            }
+        }
+    }
+}

+ 117 - 0
src/main/java/kd/bos/newdevportal/table/TableListPlugin.java

@@ -0,0 +1,117 @@
+package kd.bos.newdevportal.table;
+
+import kd.bos.dataentity.utils.StringUtils;
+import kd.bos.db.DB;
+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.form.control.events.ItemClickEvent;
+import kd.bos.list.BillList;
+import kd.bos.metadata.dao.MetadataDao;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * TableListPlugin 添加表注释和表字段注释
+ * <p>
+ * 添加表注释和表字段注释
+ * </p>
+ *
+ * @author ww
+ * @version 1.0
+ */
+public class TableListPlugin extends TableManagerListPlugin {
+    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_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);
+                String[] info = pkStr.split("@@");
+                if (info.length < 2) {
+                    failureCount++; // 如果数据不正确,增加失败计数
+                    continue; // 跳过此条记录,继续处理下一条
+                }
+                //获取数据字典明细
+                String tablename = info[0];//表名称
+                String entityId = info[1];//id
+                String dbroute = EntityMetadataCache.getDataEntityType(MetadataDao.getEntityNumberById(info[1])).getDBRouteKey();
+                // 根据 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
+
+                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(); // 可以替换为日志记录
+                            failureCount++; // 增加失败计数
+                        }
+                    }else {
+                        failureCount++; // 增加失败计数
+                    }
+                }
+            }
+            // 显示最终的成功和失败消息
+            String message = String.format("执行完成:成功 %d 条,失败 %d 条", successCount, failureCount);
+            this.getView().showMessage(message);
+        }
+    }
+}

+ 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();
+    }
+}

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

@@ -0,0 +1,736 @@
+package sys.sc.formplugin;
+
+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.OperationServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.imc.bdm.common.constant.BotpCallBackLogConstant;
+
+
+import java.io.*;
+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 {
+
+    //根据接口配置信息获取组织人员,拼接服务器文件路径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);
+        //文件路径拼接
+        String url=nckd_url+datestr+"/"+nckd_filename;
+        return url;
+    }
+
+    //从文件读取数据更新到基础资料中
+    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);
+    }
+
+    @Override
+    public void afterDoOperation(AfterDoOperationEventArgs e) {
+        super.afterDoOperation(e);
+        String filePath = "D:/test.dat";
+        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())) {//从文件读取数据插入基础资料
+            generateDataFile(getFileUrl("organduserurl"));
+        }
+        //减值数据
+        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"
+                );
+                List<DynamicObject> createdataList = new ArrayList<>();
+                List<DynamicObject> updatedataList = new ArrayList<>();
+                //查出所有现有的数据
+                DynamicObject[] existingData = BusinessDataServiceHelper
+                        .load(dynamicObjectType.getName(), String.join(",", selector) + ",nckd_isdelete", null);
+                Map<String, DynamicObject> existingDataMap = new HashMap<>();
+                for (DynamicObject obj : existingData) {
+                    //单据号
+                    existingDataMap.put(obj.getString("nckd_dubil_id"), obj);
+                }
+                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];
+                        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) {
+//                                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 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());
+            }
+        }
+
+        //获取接口配置表中组织人员的数据,返回服务器中文件路径
+        if ("jkpz".equals(e.getOperateKey())) {
+            getFileUrl("organduserurl");
+        }
+
+        //读取行名行号,存入对应基础资料中
+        if("hmhh".equals(e.getOperateKey())) {
+            String fileurl=getFileUrl("hmhhurl");
+            //行名行号表字段
+            List<String> selector = Arrays.asList(
+                    "number", "name"
+            );
+            //文件路径
+//            String fileurl="D:/hmhh.dat";
+            //行名行号表标识
+            String bd_bebank="bd_bebank";
+            try {
+                //基础资料
+                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), 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 FileReader(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]);
+                            createdataList.add(data);
+                        }
+                    }
+                }
+                //查找更新数据
+                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());
+            }
+        }
+
+    }
+}
+
+

+ 473 - 0
src/main/java/sys/sc/formplugin/UpdateDataDailyTask.java

@@ -0,0 +1,473 @@
+package sys.sc.formplugin;
+
+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 java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+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);
+
+    @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");
+        //读取文件更新基础资料
+        updatebasicdata(path);
+        //更新组织
+        log.info("----------------更新组织中---------------------");
+        updateorg();
+        //更新人员
+        log.info("----------------更新人员中-------------------");
+        updateperson();
+    }
+    //读取文件更新基础资料
+    public void updatebasicdata(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]));
+            }
+            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);
+        //文件路径拼接
+        String url=nckd_url+datestr+"/"+nckd_filename;
+        return url;
+    }
+    @Override
+    public boolean isSupportReSchedule() {
+        return super.isSupportReSchedule();
+    }
+}

+ 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;
+            }
+        }