Browse Source

Merge branch 'master' of http://111.75.220.136:10030/turborao/jyyy

tanya 3 weeks ago
parent
commit
b916147bff
22 changed files with 1780 additions and 213 deletions
  1. 42 2
      code/base/nckd-jimin-base-helper/src/main/java/nckd/base/helper/CusFileServiceExt.java
  2. 224 94
      code/base/nckd-jimin-base-helper/src/main/java/nckd/base/helper/FileSECUtils.java
  3. 1 1
      code/jyyy/nckd-jimin-jyyy-bd/src/main/java/nckd/jimin/jyyy/bd/common/oauth/FanWeiUtils.java
  4. 55 31
      code/jyyy/nckd-jimin-jyyy-bd/src/main/java/nckd/jimin/jyyy/bd/task/impl/SynSapServiceImpl.java
  5. 17 3
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/fi/cas/opplugin/PayBillToolUtil.java
  6. 36 6
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/fi/cas/task/AgentpaybillQueryStatusTast.java
  7. 40 8
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/fi/cas/task/PayQueryStatusTast.java
  8. 67 0
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/business/DtgTripCusPlugin.java
  9. 7 4
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/mservice/SyncSapFIUtils.java
  10. 5 4
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/mservice/impl/SynSapFIServiceImpl.java
  11. 45 0
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/form/PayApplyBillSRMEditPlugin.java
  12. 3 1
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/form/PayBigCategoryFormPlugin.java
  13. 11 0
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/form/PublicReimburseBillFormPlugin.java
  14. 124 0
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/operate/PrepayBillReturnOpPlugin.java
  15. 10 0
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/operate/SRMHelperUtils.java
  16. 16 4
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/task/WriteBackPayResult2SRMTask.java
  17. 13 24
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/webapi/AttachmentFileUtil.java
  18. 152 27
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/webapi/SRMSynPayApiPlugin.java
  19. 3 2
      code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/webapi/TransDetailApiPlugin.java
  20. 3 2
      code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/hrmp/hbpm/task/SyncUtil.java
  21. 42 0
      code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/plugin/workflow/GetJobLevelWorkflowPlugin.java
  22. 864 0
      code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/wtc/wtss/formplugin/web/pc/WtssPersonHomePCPluginEx.java

+ 42 - 2
code/base/nckd-jimin-base-helper/src/main/java/nckd/base/helper/CusFileServiceExt.java

@@ -1,25 +1,65 @@
 package nckd.base.helper;
 
+import kd.bos.fileservice.FileServiceFactory;
 import kd.bos.fileservice.extension.FileServiceExt;
 import kd.bos.logging.Log;
 import kd.bos.logging.LogFactory;
 import kd.bos.service.attachment.FilePathService;
 
+import java.io.File;
 import java.io.InputStream;
 
+/**
+ * 自定义附件服务
+ * 处理附件加密解密
+ *
+ * @author turborao
+ * @date 2025/05/26 14:07
+ */
 public class CusFileServiceExt extends FilePathService implements FileServiceExt {
 
     private static final Log logger = LogFactory.getLog(CusFileServiceExt.class);
 
     @Override
     public InputStream encode(String originalPath, InputStream in) {
-        logger.info("--------------附件加密----------------");
+        logger.info("--------------SEC 附件加密 "+originalPath+"----------------");
+
+//        InputStream inForSEC = null;
+//        int isEncryption = FileSECUtils.checkFileIsEncryptionRest(in);
+//        if(isEncryption != 1){
+//
+//            long filesize = FileSECUtils.getFileSizeByPath(originalPath);
+//            inForSEC = FileSECUtils.decodeFileForSEC(filesize,in);
+//            if(inForSEC != null){
+//                return inForSEC;
+//            }
+//        }else{
+//            logger.info("--------------SEC 附件已加密 "+originalPath+"----------------");
+//        }
         return in;
     }
 
+
+    /**
+     * 附件解密
+     * 先解决附件解密,后面再解决附件加密问题
+     * @param originalPath
+     * @param in
+     * @return
+     */
     @Override
     public InputStream decode(String originalPath, InputStream in) {
-        logger.info("--------------附件解密----------------");
+        logger.info("--------------SEC 附件解密 "+originalPath+"----------------");
+
+        InputStream inForSEC = null;
+        int isEncryption = FileSECUtils.checkFileIsEncryptionRest(in);
+        if(isEncryption == 1) {
+            long filesize = FileSECUtils.getFileSizeByPath(originalPath);
+            inForSEC = FileSECUtils.decodeFileForSEC(filesize, in);
+            if (inForSEC != null) {
+                return inForSEC;
+            }
+        }
         return in;
     }
 

+ 224 - 94
code/base/nckd-jimin-base-helper/src/main/java/nckd/base/helper/FileSECUtils.java

@@ -1,141 +1,271 @@
 package nckd.base.helper;
 
-import com.itrus.security.cert.X509Certificate;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.fileservice.FileServiceFactory;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
-import kd.bos.sdk.util.KHttpClientUtils;
 import kd.bos.servicehelper.AttachmentDto;
 import kd.bos.servicehelper.AttachmentServiceHelper;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
-import okhttp3.*;
-
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLContextBuilder;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.entity.AbstractHttpEntity;
+import org.apache.http.entity.InputStreamEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
 import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
+
 import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
 import java.security.cert.CertificateException;
-import java.util.HashMap;
+import java.text.DecimalFormat;
 import java.util.List;
 import java.util.Map;
 
+
 public class FileSECUtils {
+    private static final Log logger = LogFactory.getLog(FileSECUtils.class);
 
-    public static byte[] getFileTest() {
+    public static InputStream getFileTest() {
 
         String entryEntityName = "nckd_filetest";
 
-//        DynamicObject billByn = BusinessDataServiceHelper.loadSingle(entryEntityName,
-//                new QFilter[]{new QFilter("billno", QCP.equals, "test0001")});
-//
-//        List<Map<String, Object>> sourceFileList = AttachmentServiceHelper.getAttachments(entryEntityName,billByn.getPkValue(), "attachmentpanel");
-//        Map<String, InputStream> files = new HashMap<>();
-//
-//        if(sourceFileList != null && sourceFileList.size()>0)
-//        {
-//            for(Map<String,Object> fileMap : sourceFileList){
-//                //AttachmentDto attachmentDto = AttachmentServiceHelper.getAttachmentInfoByAttPk(fileMap.get("attPkId"));
-//                //String fileUrl= attachmentDto.getResourcePath();
-//                //String fileName = attachmentDto.getFilename();
-//
-//
-//
-//                System.out.println("fileUrl:" + fileUrl+ ",fileName:"+fileName);
-//                ByteArrayOutputStream out = new ByteArrayOutputStream();
-//                FileServiceFactory.getAttachmentFileService().download(fileUrl, out, null);
-//                System.out.println("file:" + out.toByteArray());
-//                return out.toByteArray();
-//                //InputStream in = new ByteArrayInputStream(out.toByteArray());
-//                //files.put(fileUrl,in);
-//            }
-//        }
-
-        String filePath = "C:\\Users\\Administrator\\Desktop\\test.txt";
-        try (InputStream inputStream = new FileInputStream(filePath)) {
-            byte[] buffer = new byte[1024];
-            int bytesRead;
+        DynamicObject billByn = BusinessDataServiceHelper.loadSingle(entryEntityName,
+                new QFilter[]{new QFilter("billno", QCP.equals, "test0001")});
+
+        List<Map<String, Object>> sourceFileList = AttachmentServiceHelper.getAttachments(entryEntityName,billByn.getPkValue(), "attachmentpanel");
 
-            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        if(sourceFileList != null && sourceFileList.size()>0)
+        {
+            for(Map<String,Object> fileMap : sourceFileList){
+                AttachmentDto attachmentDto = AttachmentServiceHelper.getAttachmentInfoByAttPk(fileMap.get("attPkId"));
+                String fileUrl= attachmentDto.getResourcePath();
+                String fileName = attachmentDto.getFilename();
 
-            while ((bytesRead = inputStream.read(buffer)) != -1) {
-                outputStream.write(buffer, 0, bytesRead);
+                System.out.println("fileUrl:" + fileUrl+ ",fileName:"+fileName);
+                ByteArrayOutputStream out = new ByteArrayOutputStream();
+                FileServiceFactory.getAttachmentFileService().download(fileUrl, out, null);
+                InputStream in = new ByteArrayInputStream(out.toByteArray());
+                return in;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * 检查文件是否加密的REST接口调用方法
+     * 该方法会从配置中获取检查URL,构造请求并发送文件流进行检测。
+     * 返回结果说明:
+     *   1: 文件是秘文(加密状态)
+     *   0: 文件是明文(未加密状态)
+     *  -1: 发生错误或未找到配置信息
+     */
+    public static int checkFileIsEncryptionRest(InputStream inputStream){
+
+        Map<String, String> mapentity = CommonHelperUtils.getCommonParams("SEC");
+        if(mapentity == null){
+            return -1;
+        }
+        String url = mapentity.get("url");
+
+        try {
+            CloseableHttpClient httpclient = null;
+            HttpPost post = new HttpPost(url);
+            post.addHeader("method~name", "checkFileIsEncryptionRest");//文件加密
+
+            //String filePath = "C:\\Users\\Administrator\\Desktop\\test.txt";
+            //InputStream inputStream = new FileInputStream(filePath);
+
+            AbstractHttpEntity entity = new InputStreamEntity(inputStream);
+            post.setEntity(entity);
+
+            httpclient = buildSSLCloseableHttpClient();
+            CloseableHttpResponse response = httpclient.execute(post);
+            String result = response.getFirstHeader("data~returnFlag").getValue();
+
+            // 获取响应状态码
+            if("1".equals(result)){//1表示秘文
+                System.out.println("是秘文");
+                return 1;
+            }else if("0".equals(result)){//0表示明文
+                System.out.println("是明文");
+                return 0;
+            }else{
+                System.out.println(result);
+                return -1;
             }
-            // 如果需要,可以在这里对 outputStream 进行额外操作
-            // 例如:outputStream.flush();
-            return outputStream.toByteArray();
 
         } catch (IOException e) {
             e.printStackTrace();
+            logger.info("SEC附件 ERR content1: " + e.getMessage());
+        } catch (Exception e1){
+            e1.printStackTrace();
+            logger.info("SEC附件 ERR content2: " + e1.getMessage());
         }
-        return null;
+        return -1;
     }
 
-    public static void postSECApi(){
-        String url = "https://ebis.jeyoupharma.com:8443";
-        Map<String, String> header = new HashMap<>();
-        header.put("method-name", "checkFileIsEncryptionRest");
+    public static InputStream encodeFileForSEC(long fileSize,InputStream inputStream){
 
-        TrustManager[] trustAllCerts = new TrustManager[]{
-                new X509TrustManager() {
+        Map<String, String> mapentity = CommonHelperUtils.getCommonParams("SEC");
+        if(mapentity == null){
+            return null;
+        }
+        String url = mapentity.get("url");
 
-                    @Override
-                    public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {
+        try {
 
-                    }
+            //String filePath = "C:\\Users\\turbo_i49t4d3\\Downloads\\副本经理人周会数据.xlsx";
+            //File file = new File(filePath);
+            //InputStream inputStream1 = new FileInputStream(filePath);
 
-                    @Override
-                    public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {
+            CloseableHttpClient httpclient = null;
+            HttpPost post = new HttpPost(url);
+            post.addHeader("method~name", "fileEncryptionRest"); //文件加密
+            post.addHeader("data~fileOffset", "0");
+            post.addHeader("data~counSize", String.valueOf(fileSize));
+            post.addHeader("data~secLevel", "10");
 
-                    }
+            AbstractHttpEntity entity = new InputStreamEntity(inputStream);
+            post.setEntity(entity);
 
-                    @Override
-                    public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
-                }
-        };
+            httpclient = buildSSLCloseableHttpClient();
+            CloseableHttpResponse response = httpclient.execute(post);
+            String result = response.getFirstHeader("data~returnFlag").getValue();
 
-        try {
-            // 配置 SSLContext 使用不安全的 TrustManager
-            SSLContext sslContext = SSLContext.getInstance("SSL");
-            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
-
-            //OkHttpClient client = new OkHttpClient();
-            // 创建安全的 OkHttpClient
-            // 创建 OkHttpClient 并禁用证书验证
-            OkHttpClient insecureClient = new OkHttpClient.Builder()
-                    .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0])
-                    .hostnameVerifier((hostname, session) -> true) // 绕过主机名验证
-                    .build();
-
-            // 创建 byte[] 类型的数据
-            byte[] data = getFileTest();
-
-            // 创建 RequestBody,设置媒体类型和 byte[] 数据
-            //RequestBody requestBody = RequestBody.create(MediaType.get("application/octet-stream"), data);
-            RequestBody requestBody = RequestBody.create(data, MediaType.get("application/octet-stream"));
-
-            // 创建 Request 对象,设置目标 URL 和请求体
-            Request request = new Request.Builder()
-                    .url(url)
-                    .post(requestBody)
-                    .build();
-
-            // 执行请求
-            Response response = insecureClient.newCall(request).execute() ;
             // 获取响应状态码
-            System.out.println("Status code: " + response.code());
+            if("0".equals(result)){//1表示秘文
+                InputStream ins = response.getEntity().getContent();
+                logger.info("SEC附件加密成功: " + result);
+                return ins;
+            }else{
+                logger.debug("SEC附件加密失败: " + result);
+                return null;
+            }
 
-            // 获取响应体并打印
-            if (response.body() != null) {
-                System.out.println("Response content: " + response.body().string());
+        } catch (IOException e) {
+            e.printStackTrace();
+            logger.info("SEC附件加密 ERR content1: " + e.getMessage());
+        } catch (Exception e1){
+            e1.printStackTrace();
+            logger.info("SEC附件加密 ERR content2: " + e1.getMessage());
+        }
+        return null;
+    }
+
+    public static InputStream decodeFileForSEC(long fileSize,InputStream inputStream){
+        Map<String, String> mapentity = CommonHelperUtils.getCommonParams("SEC");
+        if(mapentity == null){
+            return null;
+        }
+        String url = mapentity.get("url");
+
+        try {
+
+            //String filePath = "C:\\Users\\turbo_i49t4d3\\Downloads\\PMS项目预算编制维度-01.xlsx";
+           // File file = new File(filePath);
+            //InputStream inputStream1 = new FileInputStream(filePath);
+
+            CloseableHttpClient httpclient = null;
+            HttpPost post = new HttpPost(url);
+            post.addHeader("method~name", "fileDecryptionRest"); //文件解密
+            post.addHeader("data~fileOffset", "0");
+            post.addHeader("data~counSize", String.valueOf(fileSize));
+
+            AbstractHttpEntity entity = new InputStreamEntity(inputStream);
+            post.setEntity(entity);
+
+            httpclient = buildSSLCloseableHttpClient();
+            CloseableHttpResponse response = httpclient.execute(post);
+            String result = response.getFirstHeader("data~returnFlag").getValue();
+
+            // 获取响应状态码
+            if("0".equals(result)){//1表示秘文
+                InputStream ins = response.getEntity().getContent();
+                logger.info("SEC附件解密成功: " + result);
+                return ins;
+            }else{
+                logger.info("SEC附件解密失败: " + result);
+                return null;
             }
+
         } catch (IOException e) {
             e.printStackTrace();
-            System.out.println("ERR content1: " + e.getMessage());
+            logger.info("SEC附件解密 ERR content1: " + e.getMessage());
         } catch (Exception e1){
             e1.printStackTrace();
-            System.out.println("ERR content2: " + e1.getMessage());
+            logger.info("SEC附件解密 ERR content2: " + e1.getMessage());
+        }
+        return null;
+    }
+
+    private static CloseableHttpClient buildSSLCloseableHttpClient() throws Exception {
+        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
+            @Override
+            public boolean isTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {
+                return true;
+            }
+        }).build();
+        // ALLOW_ALL_HOSTNAME_VERIFIER:这个主机名验证器基本上是关闭主机名验证的,实现的是一个空操作,并且不会抛出javax.net.ssl.SSLException异常。
+        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1" }, null,
+                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+        return HttpClients.custom().setSSLSocketFactory(sslsf).build();
+    }
+
+
+    /**
+     * 根据地址获得数据的字节流并转换成大小
+     * @param originalPath 文件实际地址
+     * @return
+     */
+    public static long getFileSizeByPath(String originalPath){
+        InputStream inStream=null;
+        ByteArrayOutputStream outStream=null;
+        long size = 0;
+        try {
+            InputStream inputStream = FileServiceFactory.getAttachmentFileService().getInputStream(originalPath);
+
+            outStream = new ByteArrayOutputStream();
+            byte[] buffer = new byte[1024];
+            int len = 0;
+            while( (len = inStream.read(buffer)) != -1 ){
+                outStream.write(buffer, 0, len);
+            }
+            byte[] bt =  outStream.toByteArray();
+
+            if(null != bt && bt.length > 0){
+                DecimalFormat df = new DecimalFormat("#");
+                size = Integer.parseInt(df.format((double) bt.length));
+
+                logger.info("SEC附件 文件大小: " + size);
+            }else{
+                logger.info("SEC附件 没有从路径上获得内容");
+            }
+            inStream.close();
+            outStream.close();
+
+        } catch (Exception e) {
+            logger.info("SEC附件 文件大小ERR: " + e.getMessage());
+        }finally{
+            try{
+                if(inStream !=null){
+                    inStream.close();
+                }
+                if(outStream !=null){
+                    outStream.close();
+                }
+            } catch (IOException e) {
+                logger.info("SEC附件 文件大小ERR: " + e.getMessage());
+            }
         }
+        return size;
     }
 
 }

+ 1 - 1
code/jyyy/nckd-jimin-jyyy-bd/src/main/java/nckd/jimin/jyyy/bd/common/oauth/FanWeiUtils.java

@@ -132,7 +132,7 @@ public class FanWeiUtils {
 
         // 构建 requestData 数组
         JSONArray requestData = new JSONArray();
-        requestData.add(datajson);
+        requestData.add(datajsonParent);
 
         // 构建最终的根 JSON 对象
         JSONObject rootJson = new JSONObject();

+ 55 - 31
code/jyyy/nckd-jimin-jyyy-bd/src/main/java/nckd/jimin/jyyy/bd/task/impl/SynSapServiceImpl.java

@@ -435,6 +435,31 @@ public class SynSapServiceImpl implements SynSapService {
         return result;
     }
 
+    /**
+     * 同步OA主数据中的讲者信息
+     *
+     * <p>本方法负责从OA系统同步讲者相关的主数据,处理并保存到当前系统中。
+     * 它首先调用 FanWeiUtils.getFanWeiToken 获取泛微接口的访问令牌,并请求讲者数据,
+     * 然后解析这些数据,并与系统中已存在的讲者信息进行对比和更新。
+     * 如果讲者在系统中不存在,则会创建新的讲者记录;如果存在,则更新相关信息。</p>
+     *
+     * <p><b>关键流程如下:</b>
+     * <ul>
+     *     <li>调用 getFanWeiToken 方法获取访问 Token</li>
+     *     <li>请求并解析 OA 接口返回的讲者数据</li>
+     *     <li>遍历讲者数据,提取身份证号、姓名等核心字段</li>
+     *     <li>根据身份证号判断是否为新讲者,如是则新建 DynamicObject,否则更新已有记录</li>
+     *     <li>设置讲者的相关属性,包括医院、单位、领域、评定级别等扩展信息</li>
+     *     <li>批量保存讲者数据,并返回同步结果</li>
+     * </ul>
+     * </p>
+     *
+     * @return 返回一个包含同步结果的Map,其中:
+     *         <ul>
+     *             <li>"code": 状态码(200 表示成功,其他表示失败)</li>
+     *             <li>"msg": 同步结果描述信息</li>
+     *         </ul>
+     */
     @Override
     public Map<String, String> synSpeakerForOA() {
         Map<String, String> result = new HashMap<>();
@@ -472,7 +497,7 @@ public class SynSapServiceImpl implements SynSapService {
             speakerIdList.add(sfzh);
         }
         QFilter qFilter = new QFilter("number", QCP.in, speakerIdList);
-        DynamicObject[] speakerDyns = BusinessDataServiceHelper.load("nckd_speaker", "number", new QFilter[]{qFilter});
+        DynamicObject[] speakerDyns = BusinessDataServiceHelper.load("nckd_speaker", "id,number,name,status,creator,enable,nckd_pdjb,nckd_zlly,nckd_shdw,nckd_rzyy", new QFilter[]{qFilter});
         Map<String, DynamicObject> speakerMap =
                 Arrays.stream(speakerDyns)
                         .collect(Collectors.toMap(
@@ -517,40 +542,39 @@ public class SynSapServiceImpl implements SynSapService {
                 if(dyn==null){
                     dyn=BusinessDataServiceHelper.newDynamicObject("nckd_speaker");
                     dyn.set("number", sfzh);
-                    dyn.set("name",zjxm);
-                    dyn.set("nckd_rzyy",rzyy);
-                    dyn.set("nckd_shdw",shdw);
-                    dyn.set("nckd_zlly",zlly);
-                    if(EmptyUtils.isNotEmpty(zjpdjb)){
-                        switch (zjpdjb){
-                            case "0":
-                                dyn.set("nckd_pdjb","院士级");
-                                break;
-                            case "1":
-                                dyn.set("nckd_pdjb","国家级");
-                                break;
-                            case "2":
-                                dyn.set("nckd_pdjb","区域/省级");
-                                break;
-                            case "3":
-                                dyn.set("nckd_pdjb","城市级");
-                                break;
-                            case "4":
-                                dyn.set("nckd_pdjb","普通级");
-                                break;
-                            default:break;
-                        }
+                }
+                dyn.set("name",zjxm);
+                dyn.set("nckd_rzyy",rzyy);
+                dyn.set("nckd_shdw",shdw);
+                dyn.set("nckd_zlly",zlly);
+                if(EmptyUtils.isNotEmpty(zjpdjb)){
+                    switch (zjpdjb){
+                        case "0":
+                            dyn.set("nckd_pdjb","院士级");
+                            break;
+                        case "1":
+                            dyn.set("nckd_pdjb","国家级");
+                            break;
+                        case "2":
+                            dyn.set("nckd_pdjb","区域/省级");
+                            break;
+                        case "3":
+                            dyn.set("nckd_pdjb","城市级");
+                            break;
+                        case "4":
+                            dyn.set("nckd_pdjb","普通级");
+                            break;
+                        default:break;
                     }
-                    //数据状态
-                    dyn.set("status",data_status);
-                    //creator创建人
-                    dyn.set("creator",creator);
-                    //使用状态
-                    dyn.set("enable", "1");
                 }
+                //数据状态
+                dyn.set("status","C"); //接口值 没有用,直接给审核状态
+                //creator创建人
+                dyn.set("creator",creator);
+                //使用状态
+                dyn.set("enable", "1");
                 speakerDynList.add(dyn);
             }
-
         }
         if(speakerDynList.size()>0) {
             Object[] save = SaveServiceHelper.save(speakerDynList.toArray(new DynamicObject[0]));

+ 17 - 3
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/fi/cas/opplugin/PayBillToolUtil.java

@@ -160,7 +160,12 @@ public class PayBillToolUtil {
                 OP_ACNT_LIST.put(entrydata);
             }
             data.put("OP_ACNT_LIST", OP_ACNT_LIST);
-
+            //结算方式
+            if(info.getDynamicObject("settletype") != null) {
+                data.put("SETTLE_TYPE", info.getDynamicObject("settletype").getString("name"));
+            } else {
+                data.put("SETTLE_TYPE", "");
+            }
 
             //无用字段
             data.put("CLT_NO", JSONObject.NULL);
@@ -317,6 +322,14 @@ public class PayBillToolUtil {
         //币别
         data.put("CURRENCY", info.get("currency.number"));
 
+        //结算方式
+        //结算方式
+        if(info.getDynamicObject("settletype") != null) {
+            data.put("SETTLE_TYPE", info.getDynamicObject("settletype").getString("name"));
+        } else {
+            data.put("SETTLE_TYPE", "");
+        }
+
         //无用字段
         data.put("CLT_NO", JSONObject.NULL);
         data.put("PAY_ACNT_NAME", JSONObject.NULL);
@@ -461,7 +474,7 @@ public class PayBillToolUtil {
             } catch (IOException e) {
                 errMsg.append("单据号:").append(billNum).append(",推送资金系统失败,");
                 errMsg.append("错误号:").append("XXXXXXX");
-                errMsg.append(",错误原因:").append("接口无法连通,未获取到返回结果");
+                errMsg.append(",错误原因:").append("接口异常, " + e.getMessage());
                 errMsg.append("\r\n");
                 return errMsg.toString();
             }
@@ -616,6 +629,7 @@ public class PayBillToolUtil {
              */
             String JKNO = "";
             String settletype = payBillEntity.get("settletype.number") + "";
+
             if (settletype != null && !"".equals(settletype)) {
                 if (settletype.equals("BILL")) {//票据
                     JKNO = "JY-NSTC-T002";
@@ -676,7 +690,7 @@ public class PayBillToolUtil {
             } catch (IOException e) {
                 errMsg.append("单据号:").append(billNum).append(",推送资金系统失败,");
                 errMsg.append("错误号:").append("XXXXXXX");
-                errMsg.append(",错误原因:").append("接口无法连通,未获取到返回结果");
+                errMsg.append(",错误原因:").append("接口异常, " + e.getMessage());
                 errMsg.append("\r\n");
                 return errMsg.toString();
             }

+ 36 - 6
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/fi/cas/task/AgentpaybillQueryStatusTast.java

@@ -2,6 +2,8 @@ package fi.cas.task;
 
 import com.alibaba.druid.support.logging.Log;
 import com.alibaba.druid.support.logging.LogFactory;
+import com.kingdee.util.StringUtils;
+import fi.cas.opplugin.HttpUtils;
 import fi.cas.opplugin.PayBillToolUtil;
 import fi.cas.opplugin.TypeUtils;
 import fi.cas.opplugin.Utils;
@@ -17,10 +19,8 @@ import kd.bos.servicehelper.operation.SaveServiceHelper;
 import org.json.JSONArray;
 import org.json.JSONObject;
 
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.io.IOException;
+import java.util.*;
 
 public class AgentpaybillQueryStatusTast extends AbstractTask {
     private static final Log log = LogFactory.getLog(AgentpaybillQueryStatusTast.class);
@@ -36,7 +36,7 @@ public class AgentpaybillQueryStatusTast extends AbstractTask {
         Map<Object, DynamicObject> payinfos  = BusinessDataServiceHelper.loadFromCache("cas_agentpaybill", new QFilter[] {filter});
         DynamicObject jkpzxx = BusinessDataServiceHelper.loadSingle("nckd_jkpzxx",new QFilter[]{new QFilter("number","=","paytoJHX")});
         String url =  jkpzxx.getString("nckd_servername");
-
+        boolean isESBApi = jkpzxx.getBoolean("nckd_isesb");
 
         for (DynamicObject dataEntity : payinfos.values()) {
             //调用接口查询付款状态
@@ -52,7 +52,37 @@ public class AgentpaybillQueryStatusTast extends AbstractTask {
             String bodyjson=param.toString();
             String billNum = dataEntity.getString("billno");
             log.info("单据号:"+billNum+"传入参数"+param.toString());
-            JSONObject cbsReturnJson =PayBillToolUtil.JHXServiceQuery(url,bodyjson);//待补充,超时返回参数待修改,整体待重构
+
+
+//            JSONObject cbsReturnJson =PayBillToolUtil.JHXServiceQuery(url,bodyjson);//待补充,超时返回参数待修改,整体待重构
+
+            /***************************************add by wanghaiwu 20225/05/24*************************************************************/
+            //改成调用restful ebs api的方式
+            Map<String, String> header = new HashMap<>();
+            header.put("Content-Type", "application/json; charset=UTF-8");
+
+            //如果是esb接口,需要包一层参数
+            if(isESBApi) {
+                bodyjson = PayBillToolUtil.buildEsbApiBodyJSON(new JSONObject(bodyjson));
+            }
+
+            String apiResult = "";
+            try {
+                apiResult = HttpUtils.postjson(url, header, bodyjson);
+            } catch (IOException e) {
+                log.info("单据号:" + billNum + "查询失败:" + e.getMessage());
+                continue;
+            }
+
+            if(StringUtils.isEmpty(apiResult)){
+                log.info("单据号:" + billNum + "查询结果为空");
+                continue;
+            }
+
+            log.info("单据号:" + billNum + "返回参数" + apiResult);
+
+            JSONObject cbsReturnJson = new JSONObject(apiResult);
+            /************************************************************/
 
             log.info("单据号:"+billNum+"返回参数"+cbsReturnJson.toString());
             if(cbsReturnJson==null||cbsReturnJson.get("data")==null){

+ 40 - 8
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/fi/cas/task/PayQueryStatusTast.java

@@ -2,6 +2,7 @@ package fi.cas.task;
 
 import com.alibaba.druid.support.logging.Log;
 import com.alibaba.druid.support.logging.LogFactory;
+import com.kingdee.util.StringUtils;
 import fi.cas.opplugin.*;
 import kd.bos.context.RequestContext;
 import kd.bos.dataentity.entity.DynamicObject;
@@ -13,10 +14,8 @@ import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
 import org.json.JSONObject;
 
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.io.IOException;
+import java.util.*;
 
 public class PayQueryStatusTast extends AbstractTask {
     private static final Log log = LogFactory.getLog(PayQueryStatusTast.class);
@@ -32,7 +31,7 @@ public class PayQueryStatusTast extends AbstractTask {
         DynamicObject[] payinfos = BusinessDataServiceHelper.load("cas_paybill","billno,billstatus,nckd_paystatus,nckd_sbyy,nckd_fqqdrq,nckd_fkcs,nckd_bbh", new QFilter[] {filter});
         DynamicObject jkpzxx = BusinessDataServiceHelper.loadSingle("nckd_jkpzxx",new QFilter[]{new QFilter("number","=","paytoJHX")});
         String url =  jkpzxx.getString("nckd_servername");
-
+        boolean isESBApi = jkpzxx.getBoolean("nckd_isesb");
 
         for (DynamicObject dataEntity : payinfos) {
             //调用接口查询付款状态
@@ -43,12 +42,45 @@ public class PayQueryStatusTast extends AbstractTask {
             param.put("data",data);
             param.put("txDateTime",Utils.getData(new Date(), "yyyyMMddHHmmss"));
             param.put("batchNo",TypeUtils.nullToString(dataEntity.get("billno"))+"-"+TypeUtils.nullToString(dataEntity.get("nckd_bbh"))+"-"+Utils.getData(new Date(), "yyyyMMddHHmmss"));
-            param.put("code","NSTC-Q001");
+            param.put("code","JY-NSTC-Q001");
 
-            String bodyjson=param.toString();
+            String bodyjson = param.toString();
             String billNum = dataEntity.getString("billno");
+
             log.info("单据号:"+billNum+"传入参数"+param.toString());
-            JSONObject cbsReturnJson =PayBillToolUtil.JHXServiceQuery(url,bodyjson);//待补充,超时返回参数待修改,整体待重构
+
+
+//            JSONObject cbsReturnJson = PayBillToolUtil.JHXServiceQuery(url, bodyjson);//待补充,超时返回参数待修改,整体待重构
+
+            /***************************************add by wanghaiwu 20225/05/24*************************************************************/
+            //改成调用restful ebs api的方式
+            Map<String, String> header = new HashMap<>();
+            header.put("Content-Type", "application/json; charset=UTF-8");
+
+            //如果是esb接口,需要包一层参数
+            if(isESBApi) {
+                bodyjson = PayBillToolUtil.buildEsbApiBodyJSON(new JSONObject(bodyjson));
+            }
+
+            String apiResult = "";
+            try {
+                apiResult = HttpUtils.postjson(url, header, bodyjson);
+            } catch (IOException e) {
+                log.info("单据号:" + billNum + "查询失败:" + e.getMessage());
+                continue;
+            }
+
+            if(StringUtils.isEmpty(apiResult)){
+                log.info("单据号:" + billNum + "查询结果为空");
+                continue;
+            }
+
+            log.info("单据号:" + billNum + "返回参数" + apiResult);
+
+            JSONObject cbsReturnJson = new JSONObject(apiResult);
+            /************************************************************/
+
+
             log.info("单据号:"+billNum+"返回参数"+cbsReturnJson.toString());
             if(cbsReturnJson==null||cbsReturnJson.get("data")==null){
             }else{

+ 67 - 0
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/business/DtgTripCusPlugin.java

@@ -0,0 +1,67 @@
+package nckd.jimin.jyyy.fi.business;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.fi.er.business.trip.exception.TripSyncLogParam;
+import kd.hrmp.hrpi.business.infrastructure.utils.QFilterUtil;
+
+import java.util.Map;
+
+/**
+ * 商旅字段映射,同程人员同步
+ */
+public class DtgTripCusPlugin {
+    private static final Log logger = LogFactory.getLog(DtgTripCusPlugin.class);
+
+    public DtgTripCusPlugin() {
+    }
+    public Object getPositionLevelName(Map<String, Object> map, TripSyncLogParam tripSyncLogParam) {
+        Map<String, Object> context = (Map)map.get("context");
+        if (context == null) {
+            return "";
+        } else {
+            Object employeeNumber = context.get("param.outEmployeeId");
+            //人员基本信息hrpi_person
+            //职等基础hrpi_empjobrel
+            if (employeeNumber != null) {
+                QFilter statusFilter = QFilterUtil.getCurrentQf();
+                statusFilter.and(QFilterUtil.getDataStatusFilter());
+
+                QFilter qFilter = new QFilter("number", "=", employeeNumber);
+                qFilter.and(statusFilter);
+
+                DynamicObject hrPerson = BusinessDataServiceHelper.loadSingleFromCache("hrpi_person", "id", qFilter.toArray());
+                if (hrPerson == null) {
+                    logger.info("根据员工number未获取到HR人员基本信息{}", employeeNumber);
+                    return "";
+                }
+
+                qFilter = new QFilter("person.id", "=", hrPerson.getLong("id"));
+                qFilter.and(statusFilter);
+
+                DynamicObject hrJobrel = BusinessDataServiceHelper.loadSingleFromCache("hrpi_empjobrel", "id, joblevel", qFilter.toArray());
+                if (hrJobrel == null) {
+                    logger.info("根据员工number未获取到HR人员职等信息{}", employeeNumber);
+                    return "";
+                }
+
+                DynamicObject jobLevel = hrJobrel.getDynamicObject("joblevel");
+                if(jobLevel == null){
+                    logger.info("根据员工number未获取到HR人员职级{}", employeeNumber);
+                    return "";
+                }
+
+                String result = jobLevel.getString("name");
+
+                return result;
+            } else {
+                logger.info("未获取到员工{}", employeeNumber);
+                return "";
+            }
+        }
+    }
+}

+ 7 - 4
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/mservice/SyncSapFIUtils.java

@@ -73,7 +73,7 @@ public class SyncSapFIUtils {
     }
 
 
-    public static  JSONObject convertCosmicVoucherToSAPForEntry(DynamicObject voucher,String maincfitemNumber,Map<String, String> auxpropertiesMap) {
+    public static  JSONObject convertCosmicVoucherToSAPForEntry(DynamicObject voucher,String maincfitemNumber,String projectNumber,Map<String, String> auxpropertiesMap) {
 
         SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
 
@@ -127,14 +127,16 @@ public class SyncSapFIUtils {
         String VBUND = "";
         String ZFBDT = sdf.format(voucher.getDate(GlVoucherConstantInfo.BOOKEDDATE));  //到期日 取记账日期
 
-        String XREF1 = getXREF1(HKONT);  //凭证辅助项1
+        ///申请人
+        String XREF1 = StringUtils.isEmpty(voucher.getString("entries.nckd_applierv")) ? "" : voucher.getString("entries.nckd_applierv");  //凭证辅助项1  nckd_applierv
+        logger.info ("SAP凭证辅助项2:"+voucher.getString("entries.nckd_applierv"));
         String XREF2 = "";
         //交易流水号
         String XREF3 = StringUtils.isEmpty(voucher.getString("entries.nckd_detailseqid")) ? "" : voucher.getString("entries.nckd_detailseqid");
         logger.info ("SAP凭证辅助项1:"+voucher.getString("entries.nckd_detailseqid"));
         String ZZATTRI1 = "";
         String ZZATTRI2 = "";
-        String ZZATTRI3 = "";
+        String ZZATTRI3 = projectNumber;
 
         //现金流量项目    科目HKONT为1002*行项目需填写,现金流量表项
         if(StringUtils.isNotEmpty(HKONT)  && (HKONT.startsWith("1002"))) {
@@ -350,7 +352,8 @@ public class SyncSapFIUtils {
         sb.append("entries,"); //  凭证行
         sb.append("entries.id,"); //  凭证行ID
         sb.append("entries.seq,");
-        sb.append("entries.nckd_detailseqid,");
+        sb.append("entries.nckd_detailseqid,"); //流水号
+        sb.append("entries.nckd_applierv,");  //申请人工号
         sb.append("entries.").append(GlVoucherConstantInfo.CURRENCY).append(",");  //  凭证行币种
         sb.append("entries.").append(GlVoucherConstantInfo.CURRENCY).append(".number").append(",");  //  凭证行币种
         sb.append("entries.").append(GlVoucherConstantInfo.DEBITLOCAL).append(",");  //  凭证行借方金额

+ 5 - 4
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/mservice/impl/SynSapFIServiceImpl.java

@@ -53,6 +53,7 @@ public class SynSapFIServiceImpl implements SynSapService {
             JSONObject HEADERITEMINFO = new JSONObject();  //凭证表头
             //现金流量项目编码 不在现金科目行上,需要单独处理下
             String maincfitemNumber = "";
+            String projectNumber = "";
             String voucherInfo = "";
             //List<String> cashBillIDs =  new ArrayList<>();
             /**
@@ -65,11 +66,11 @@ public class SynSapFIServiceImpl implements SynSapService {
                 if (StringUtils.isNotEmpty(auxpropertiesMap.get("maincfitemNumber"))) {
                     maincfitemNumber = auxpropertiesMap.get("maincfitemNumber");
                 }
-                //String entriesId = voucherRow.getString("entries.id");
-                //cashBillIDs.add(entriesId);
+                if (StringUtils.isNotEmpty(auxpropertiesMap.get("bd_project"))) {
+                    projectNumber = auxpropertiesMap.get("bd_project");
+                }
             }
 
-
             //voucherDyns 凭证表头与分录平铺
             for (DynamicObject voucherRow : voucherDyns) {
                 String billid = voucherRow.getString("id");
@@ -80,7 +81,7 @@ public class SynSapFIServiceImpl implements SynSapService {
 
                 ////处理凭证表头
                 HEADERITEMINFO = SyncSapFIUtils.convertCosmicVoucherToSAPForHead(voucherRow);
-                JSONObject entry = SyncSapFIUtils.convertCosmicVoucherToSAPForEntry(voucherRow, maincfitemNumber, auxpropertiesMap);
+                JSONObject entry = SyncSapFIUtils.convertCosmicVoucherToSAPForEntry(voucherRow, maincfitemNumber,projectNumber, auxpropertiesMap);
                 ENTRY_ITEM.add(entry);
 
             }

+ 45 - 0
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/form/PayApplyBillSRMEditPlugin.java

@@ -2,10 +2,16 @@ package nckd.jimin.jyyy.fi.plugin.form;
 
 import com.alibaba.druid.util.StringUtils;
 import kd.bos.bill.AbstractBillPlugIn;
+import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.entity.operate.result.IOperateInfo;
 import kd.bos.entity.operate.result.OperationResult;
 import kd.bos.form.IClientViewProxy;
 import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+
+import java.util.EventObject;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -55,4 +61,43 @@ public class PayApplyBillSRMEditPlugin extends AbstractBillPlugIn {
             }
         }
     }
+
+
+    /**
+     * 在创建新数据后执行的操作,用于根据视图类型自动填充相关字段。
+     *
+     * 功能:
+     * - 从自定义参数中获取视图类型(viewType)。
+     * - 查询对应的视图类型数据(nckd_payviewtype)。
+     * - 如果视图类型编号为 "1004"(专项费用和培训申请),则进一步查询并自动填充费用类型(er_expenseitemedit)。
+     *
+     * @param e 事件对象,包含触发此操作的上下文信息。
+     */
+    @Override
+    public void afterCreateNewData(EventObject e) {
+        super.afterCreateNewData(e);
+        Map<String, Object> customParams = this.getView().getFormShowParameter().getCustomParams();
+        if(customParams.get("viewType") != null){
+            String[] typeStrings = customParams.get("viewType").toString().split(",");
+
+            QFilter qFilter = new QFilter("number", QCP.in, typeStrings);
+
+            DynamicObject[] viewTypeCols = BusinessDataServiceHelper.load("nckd_payviewtype", "id, masterid,number, name", qFilter.toArray());
+            if(viewTypeCols != null && viewTypeCols.length > 0){
+                //页面类型赋值
+                //  this.getModel().setValue("nckd_payviewtype", viewTypeCols[0]);
+                //根据页面类型找到费用类型,专项费用和培训申请时候自动填充费用类型
+                String viewtNumber=viewTypeCols[0].getString("number");
+                if(viewtNumber.equals("1004")){
+                    //根据页面类型查找费用类型
+                    QFilter expenseitemFilter = new QFilter("nckd_payviewtype", QCP.equals, viewTypeCols[0].getLong("id"));
+                    expenseitemFilter.and("isleaf",QCP.equals,true);
+                    DynamicObject[] expenseitemCols = BusinessDataServiceHelper.load("er_expenseitemedit", "id, number,name,fullname", expenseitemFilter.toArray());
+                    //费用项目赋值
+                    this.getModel().setValue("nckd_expenseitem", expenseitemCols[0]);
+                }
+
+            }
+        }
+    }
 }

+ 3 - 1
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/form/PayBigCategoryFormPlugin.java

@@ -71,10 +71,12 @@ public class PayBigCategoryFormPlugin extends AbstractFormPlugin {
                 parameter.setBillStatus(BillOperationStatus.ADDNEW);
                 parameter.setStatus(OperationStatus.ADDNEW);
 
+
                 if(mapFilter != null && mapFilter.containsKey(imageKey)) {
                     String viewType = mapFilter.get(imageKey);
                     parameter.setCustomParam("viewType", viewType);
-
+                    parameter.setCustomParam("imageKey", imageKey);
+                    parameter.setCustomParam("formId", formId);
                     QFilter viewTypeQFilter = getViewTypeQFilter(imageKey);
 
                     //费用大类过滤

+ 11 - 0
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/form/PublicReimburseBillFormPlugin.java

@@ -88,6 +88,17 @@ public class PublicReimburseBillFormPlugin extends AbstractBillPlugIn implements
                 //页面类型多选赋值
                 this.getModel().setValue("nckd_payviewtypemul", basedataIds);
 
+                //根据页面类型找到费用类型,专项费用和培训申请时候自动填充费用类型   刘志华增加
+                String viewtNumber=viewTypeCols[0].getString("number");
+                if(viewtNumber.equals("1004")||viewtNumber.equals("1005")){
+                    //根据页面类型查找费用类型
+                    QFilter expenseitemFilter = new QFilter("nckd_payviewtype", QCP.equals, viewTypeCols[0].getLong("id"));
+                    expenseitemFilter.and("isleaf",QCP.equals,true);
+                    DynamicObject[] expenseitemCols = BusinessDataServiceHelper.load("er_expenseitemedit", "id, number,name,fullname", expenseitemFilter.toArray());
+                    //费用项目赋值
+                    this.getModel().setValue("nckd_expenseitem", expenseitemCols[0]);
+                }
+
                 /***
                  * 当页面类型为 资金类时,往来类型为  内部公司
                  * turborao 2025/05/15

+ 124 - 0
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/operate/PrepayBillReturnOpPlugin.java

@@ -0,0 +1,124 @@
+package nckd.jimin.jyyy.fi.plugin.operate;
+
+import com.kingdee.util.StringUtils;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
+import kd.bos.entity.plugin.AddValidatorsEventArgs;
+import kd.bos.entity.plugin.PreparePropertysEventArgs;
+import kd.bos.entity.plugin.args.AfterOperationArgs;
+import kd.bos.entity.plugin.args.BeforeOperationArgs;
+import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
+import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 表单标识:预付单(nckd_er_prepaybill_ext)
+ * @author wanghaiwu_kd
+ * @date 2025/04/29
+ */
+public class PrepayBillReturnOpPlugin extends AbstractOperationServicePlugIn {
+    private static final Log logger = LogFactory.getLog(PrepayBillReturnOpPlugin.class);
+
+    public void onPreparePropertys(PreparePropertysEventArgs e) {
+        super.onPreparePropertys(e);
+
+        List<String> fieldKeys = e.getFieldKeys();
+
+        fieldKeys.add("billno");
+        fieldKeys.add("billstatus");
+        fieldKeys.add("nckd_srmbillno");
+        fieldKeys.add("nckd_srmurl");
+    }
+
+    public void onAddValidators(AddValidatorsEventArgs e) {
+        super.onAddValidators(e);
+    }
+
+    @Override
+    public void beforeExecuteOperationTransaction(BeforeOperationArgs e) {
+        super.beforeExecuteOperationTransaction(e);
+
+        StringBuffer errMessage = new StringBuffer();
+
+        DynamicObject[] billEntities = e.getDataEntities();
+        String operationKey = e.getOperationKey();
+
+        logger.info("开始执行操作:{},实体:{}", operationKey, billEntities);
+
+        if (StringUtils.equals( "nckd_returnsrm", operationKey)){//退回
+            for (DynamicObject billInfo : billEntities) {
+                String billno = billInfo.getString("billno");
+                String billstatus = billInfo.getString("billstatus");
+                String smrBillNo = billInfo.getString("nckd_srmbillno");
+
+                if(!"A".equals(billstatus) || StringUtils.isEmpty(smrBillNo)){
+                    if(errMessage.length() > 0){
+                        errMessage.append(",");
+                    }
+                    errMessage.append("单据(" + billno + ")不是暂存状态或不是由srm生成");
+
+                    continue;
+                }
+
+                Map<String, String> returnMap = SRMHelperUtils.writeBackSRMWfStatus(billInfo.getDataEntityType().getName(), billInfo.getLong("id"), operationKey);
+
+                if(returnMap != null){
+                    if("1".equals(returnMap.get("code"))){
+                        if(errMessage.length() > 0){
+                            errMessage.append(",");
+                        }
+                        errMessage.append("单据(" + billno + ")," + returnMap.get("msg"));
+                    } else {
+                        errMessage.append("获取单点地址:" + returnMap.get("msg"));
+                    }
+                }
+            }
+
+            if(errMessage.length() > 0) {
+                ////将错误信息返回到前端
+                String msg = errMessage.toString();
+                e.setCancelMessage(msg);
+                e.setCancel(true);
+
+                logger.info("PrepayBillReturnOpPlugin 退回失败:" + msg);
+            }
+        }
+    }
+
+    @Override
+    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
+        super.beginOperationTransaction(e);
+    }
+
+    @Override
+    public void endOperationTransaction(EndOperationTransactionArgs e) {
+        super.endOperationTransaction(e);
+    }
+
+    @Override
+    public void afterExecuteOperationTransaction(AfterOperationArgs args) {
+        super.afterExecuteOperationTransaction(args);
+
+        String operationKey = args.getOperationKey();
+        DynamicObject[] billEntities = args.getDataEntities();
+        logger.info("开始执行操作:{},实体:{}", operationKey, billEntities);
+
+        switch (operationKey) {
+            case "nckd_return"://退回,只有保存状态的单据可以退回
+                for (DynamicObject billInfo : billEntities) {
+                    if(!"A".equals(billInfo.getString("billstatus"))){
+                        String billno = billInfo.getString("billno");
+                    }
+
+                    billInfo.set("billstatus", "H");
+                }
+                break;
+            default:
+                break;
+        }
+    }
+}
+

+ 10 - 0
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/operate/SRMHelperUtils.java

@@ -238,6 +238,8 @@ public class SRMHelperUtils {
             returnMap.put("code", "1");
             returnMap.put("msg", tokenMap.get("msg"));
 
+            logger.info("SRMHelperUtils:获取token异常" + returnMap.toString());
+
             return returnMap;
         }
         String token = tokenMap.get("msg").toString();
@@ -264,6 +266,9 @@ public class SRMHelperUtils {
                 || StringUtils.isEmpty(applicationCode) || StringUtils.isEmpty(applicationGroupCode)){
             returnMap.put("code", "1");
             returnMap.put("msg", "请检查是否配置SRM参数:服务地址、付款结果回写接口、用户名、接口编码、外部系统、应用编码、应用组");
+
+            logger.info("SRMHelperUtils:同步失败" + returnMap);
+
             return returnMap;
         }
 
@@ -298,6 +303,9 @@ public class SRMHelperUtils {
         headerMap.put("User-Agent", "apifox/1.0.0 (https://www.apifox.cn)");
         headerMap.put("Authorization", "Bearer " + token);
 
+        logger.info("SRMHelperUtils:body " + body.toJSONString());
+        logger.info("SRMHelperUtils:header " + headerMap.toString());
+
         try {
             String response = KHttpClientUtils.postjson(url, headerMap, body.toJSONString());
 
@@ -313,6 +321,8 @@ public class SRMHelperUtils {
             if (resultJSON !=null && "SUCCESS".equals(resultJSON.get("responseStatus").toString())
                     &&"SUCCESS".equals(resultJSON.get("executeResult").toString())) {
                 returnMap.put("code","0");
+
+                returnMap.put("msg", "回写成功");
             } else{
                 returnMap.put("code","1");
                 returnMap.put("msg", "回写付款状态失败" + response);

+ 16 - 4
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/task/WriteBackPayResult2SRMTask.java

@@ -22,7 +22,7 @@ import java.util.*;
 
 
 /**
- * 付款状态回写srm调度任务类
+ * 付款状态回写srm调度任务类,同步付款状态至SRM的预付、付款申请
  * @author wanghaiwu_kd
  * @date 2025/05/15
  */
@@ -34,9 +34,6 @@ public class WriteBackPayResult2SRMTask extends AbstractTask implements StopTask
         writeBackPublicBill(requestContext, map);
         //预付单回写
         writeBackPrepayBill(requestContext, map);
-
-
-
     }
 
     private void writeBackPublicBill(RequestContext requestContext, Map<String, Object> map){
@@ -56,6 +53,9 @@ public class WriteBackPayResult2SRMTask extends AbstractTask implements StopTask
         DynamicObjectType type = EntityMetadataCache.getDataEntityType(entityName);
         //先找到批量的pkid
         List<Object> list = QueryServiceHelper.queryPrimaryKeys(entityName,  filter.toArray(), null, Integer.MAX_VALUE);
+
+        logger.info("查询到" + list.size() + "条符合条件的对公报销单:" + list.toString());
+
         //根据pkid找到完整的对象
         DynamicObject[] billEntities = BusinessDataServiceHelper.load(list.toArray(), type);
 
@@ -66,6 +66,8 @@ public class WriteBackPayResult2SRMTask extends AbstractTask implements StopTask
             String srmBillNo = payBillEntity.getString("nckd_srmbillno");
             String paymentDate = "";
 
+            logger.info("处理对公报销单:" + billno + ",srm单据号:" + srmBillNo);
+
             if(payBillEntity.getDate("head_paydate") != null){
                 paymentDate = CommonHelperUtils.getDateFormatString(payBillEntity.getDate("head_paydate"), pattern);
             }
@@ -82,6 +84,8 @@ public class WriteBackPayResult2SRMTask extends AbstractTask implements StopTask
             StringBuffer errMessage = new StringBuffer();
             Map<String, String> returnMap = SRMHelperUtils.writeBackPayResulst(srmBillNo, paymentDate, paymentAmount);
 
+            logger.info("付款单支付状态回写结果:" + returnMap.toString());
+
             if(returnMap != null){
                 if("1".equals(returnMap.get("code"))){
                     if(errMessage.length() > 0){
@@ -122,6 +126,9 @@ public class WriteBackPayResult2SRMTask extends AbstractTask implements StopTask
         DynamicObjectType type = EntityMetadataCache.getDataEntityType(entityName);
         //先找到批量的pkid
         List<Object> list = QueryServiceHelper.queryPrimaryKeys(entityName,  filter.toArray(), null, Integer.MAX_VALUE);
+
+        logger.info("查询到" + list.size() + "条符合条件的预付单:" + list.toString());
+
         //根据pkid找到完整的对象
         DynamicObject[] billEntities = BusinessDataServiceHelper.load(list.toArray(), type);
 
@@ -132,6 +139,8 @@ public class WriteBackPayResult2SRMTask extends AbstractTask implements StopTask
             String srmBillNo = payBillEntity.getString("nckd_srmbillno");
             String paymentDate = "";
 
+            logger.info("处理预付单:" + billno + ",srm单据号:" + srmBillNo);
+
             if(payBillEntity.getDate("head_paydate") != null){
                 paymentDate = CommonHelperUtils.getDateFormatString(payBillEntity.getDate("head_paydate"), pattern);
             }
@@ -148,12 +157,15 @@ public class WriteBackPayResult2SRMTask extends AbstractTask implements StopTask
             StringBuffer errMessage = new StringBuffer();
             Map<String, String> returnMap = SRMHelperUtils.writeBackPayResulst(srmBillNo, paymentDate, paymentAmount);
 
+            logger.info("预付单支付状态回写结果:" + returnMap.toString());
+
             if(returnMap != null){
                 if("1".equals(returnMap.get("code"))){
                     if(errMessage.length() > 0){
                         errMessage.append(",");
                     }
                     logger.info("预付单(" + billno + ", " + srmBillNo + ")回写失败," + returnMap.get("msg"));
+
                     payBillEntity.set("nckd_srmstatus", "4");
                 } else {
                     payBillEntity.set("nckd_srmstatus", "3");

+ 13 - 24
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/webapi/AttachmentFileUtil.java

@@ -88,25 +88,6 @@ public class AttachmentFileUtil {
             logger.info("FTP inputStream -- size:"+inputStream.available());
             System.out.println("inputStream:"+inputStream);
 
-            // outStream = new ByteArrayOutputStream();
-            // byte[] buffer = new byte[1024];
-            // int len = 0;
-            // while( (len = inputStream.read(buffer)) != -1 ){
-            //     outStream.write(buffer, 0, len);
-            // }
-            // byte[] bt =  outStream.toByteArray();
-
-            // if(null != bt && bt.length > 0){
-            //     DecimalFormat df = new DecimalFormat("#");
-            //     size = Integer.parseInt(df.format((double) bt.length));
-
-            //     System.out.println("文件大小=:" + size);
-            // }else{
-            //     System.out.println("没有从该连接获得内容");
-            // }
-
-            // attachItem.put("size",  size);
-//            苍穹自带
             TempFileCache cache = CacheFactory.getCommonCacheFactory().getTempFileCache();
             tempUrl = cache.saveAsFullUrl((String) attachItem.get("name"), inputStream, 1600);
             logger.info("FTP tempUrl -- inputStream -- size:" + CacheFactory.getCommonCacheFactory().getTempFileCache().getInputStream(tempUrl).available());
@@ -130,7 +111,7 @@ public class AttachmentFileUtil {
             } catch (Exception e) {
                 logger.info("附件上传失败,堆栈信息01:",e.getMessage());
                 result.put("isSuccess", "false");
-                result.put("msg", "文件流关闭异常:"+e.getMessage());
+                result.put("msg", ",文件流关闭异常:"+e.getMessage());
                 return result;
             }
         }
@@ -156,12 +137,19 @@ public class AttachmentFileUtil {
             FileItem fileItem = new FileItem(fileName, pathParam, in);
 
             //从临时上传至 文件服务器
-            String downUrl =service.upload(fileItem);
+            String downUrl = service.upload(fileItem);
             logger.info("FTP downUrl:"+downUrl);
             System.out.println("downUrl:"+downUrl);
 
+            /**
+             * 附件有2个地址
+             * 一个是 downloadID  示例:1ebecb8a91003c00
+             * 一个是 url  示例:http://192.168.1.1/1ebecb8a91003c00
+             */
+            attachItem.put("downUrl", downUrl);
             attachItem.put("url", actUrl);
             result.put("url", actUrl);
+            result.put("downUrl", downUrl);
             attachments.add(attachItem);
             //绑定单据
             AttachmentServiceHelper.upload(entity, pk, attachKey, attachments);
@@ -233,7 +221,8 @@ public class AttachmentFileUtil {
         attObj.set("name", attachment.get("name"));
         attObj.set("size", 0);
         attObj.set("uid", attachment.get("uid"));
-        attObj.set("url", attachment.get("uid"));
+        //attObj.set("url", attachment.get("url"));
+        attObj.set("url", attachment.get("downUrl"));
         String fileType = attachment.get("name").toString();
         if (fileType.contains(".")) {
             fileType = fileType.substring(fileType.lastIndexOf(".") + 1);
@@ -350,13 +339,13 @@ public class AttachmentFileUtil {
         return b.toString();
     }
 
-    public static StringBuilder getUid() {
+    public static String getUid() {
         StringBuilder uid = new StringBuilder("rc-upload-");
         uid.append((new Date()).getTime());
         uid.append("-");
         int index = (int) (1.0D + Math.random() * 10.0D);
         uid.append(index);
-        return uid;
+        return uid.toString();
     }
 
     public static void downloadFile(String fileUrl, String saveDir) throws IOException {

+ 152 - 27
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/webapi/SRMSynPayApiPlugin.java

@@ -26,10 +26,8 @@ import javax.validation.Valid;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * SRM系统调用,付款同步接口
@@ -55,7 +53,7 @@ public class SRMSynPayApiPlugin implements Serializable {
             @Valid @ApiParam(value = "付款申请") JSONArray bizAccountOutBills,
             @Valid @ApiParam(value = "预付款") JSONArray dailyLoanBills) {
         if(bizAccountOutBills == null && dailyLoanBills == null){
-            return returnResult("E", "失败,bizAccountOutBills、dailyLoanBills参数不能同时为空", null);
+            return returnResult("1", "失败,bizAccountOutBills、dailyLoanBills参数不能同时为空", null);
         }
         int bizAcctOutBillSize = 0;
         int dailyLoanBillSize = 0;
@@ -69,7 +67,7 @@ public class SRMSynPayApiPlugin implements Serializable {
         }
 
         if(bizAcctOutBillSize > 0 && dailyLoanBillSize > 0){
-            return returnResult("100", "失败,bizAccountOutBills、dailyLoanBills参数不能同时存在", null);
+            return returnResult("1", "失败,bizAccountOutBills、dailyLoanBills参数不能同时存在", null);
         }
 
         JSONArray responseData = new JSONArray();
@@ -79,7 +77,44 @@ public class SRMSynPayApiPlugin implements Serializable {
             responseData = synDailyLoanBill(dailyLoanBills);
         }
 
-        return returnResult("0", "成功", responseData);
+        String code = "1";
+        String msg = "";
+
+        int sucCount = 0;
+        int failCount = 0;
+        String billNo = "";
+
+        if(responseData == null){
+            code = "1";
+            msg = "失败";
+        } else if(responseData.size() > 0){
+            for(int i = 0; i < responseData.size(); i++){
+                JSONObject response  = responseData.getJSONObject(i);
+
+                String srmBillNo = response.getString("SRMBillNo");
+                String status = response.getString("status");
+                String message = response.getString("message");
+
+                if("0".equals(status)){
+                    sucCount++;
+                } else {
+                    failCount++;
+                }
+
+                billNo = srmBillNo;
+            }
+
+            if(sucCount == responseData.size()){
+                code = "0";
+                billNo = "成功SRMBillNo ," + billNo;
+            } else {
+                billNo = "失败SRMBillNo ," + billNo;
+            }
+
+            msg = String.format("成功%s条,失败%s条。%s", sucCount, failCount, billNo);
+        }
+
+        return returnResult(code, msg, responseData);
     }
 
     /**
@@ -142,17 +177,44 @@ public class SRMSynPayApiPlugin implements Serializable {
         String biller = inputData.getString("biller");//制单人工号
         String applier = inputData.getString("applier");//经办人工号
 
-        if(StringUtils.isEmpty(srmBillNo) || StringUtils.isEmpty(srmUrl) || StringUtils.isEmpty(cause)
-            || StringUtils.isEmpty(orgUnit) || StringUtils.isEmpty(position) || StringUtils.isEmpty(biller) || StringUtils.isEmpty(applier)){
-            returnMessage = "请检查以下参数 SRM单号、srmUrl、事由、申请部门、申请人职位、制单人、经办人 是否为空!";
-            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
-        } else if("XM".equals(billType)){
-            if(StringUtils.isEmpty(project) || StringUtils.isEmpty(contract)){
-                returnMessage = "项目类付款,请检查以下参数 项目编码、合同编码 是否为空!";
-                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
+        if(StringUtils.isEmpty(srmBillNo)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "SRM单号 不能为空";
+        }
+
+        if(StringUtils.isEmpty(srmUrl)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "srmUrl 不能为空";
+        }
+
+        if(StringUtils.isEmpty(cause)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "事由 不能为空";
+        }
+
+        if(StringUtils.isEmpty(orgUnit)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "申请部门 不能为空";
+        }
+
+        if(StringUtils.isEmpty(position)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "申请人职位 不能为空";
+        }
+
+        if(StringUtils.isEmpty(biller)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "制单人 不能为空";
+        }
+
+        if( StringUtils.isEmpty(applier)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "经办人 不能为空";
+        }
+
+        if("XM".equals(billType)){
+            if(StringUtils.isEmpty(project)){
+                returnMessage = ("".equals(returnMessage) ? "" : ",") + "项目类付款 项目编码 不能为空";
             }
         }
 
+        if(!StringUtils.isEmpty(returnMessage)){
+            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
+        }
+
         //根据srm单据编号,校验在星瀚中是否已存在单据
         String xhBillNO = queryBillInfoBySRMBillNo(ENTITY_PUBLICPAY, srmBillNo);
         if(!StringUtils.isEmpty(xhBillNO)){
@@ -246,6 +308,16 @@ public class SRMSynPayApiPlugin implements Serializable {
         bizAcctOutBill.set("nckd_srmstatus", "1");//srm状态,1:SRM已推送;2:已退回SRM;3:已反写SRM;4:反写SRM失败
         bizAcctOutBill.set("nckd_duigong", "01");//是否对公业务
 
+//        String[] typeStrings = new String[]{"1008", "1009"};
+//        QFilter qFilter111 = new QFilter("number", QCP.in, typeStrings);
+//        DynamicObject[] viewTypeCols = BusinessDataServiceHelper.load("nckd_payviewtype", "id, number, name", qFilter111.toArray());
+//        DynamicObjectCollection collection = new DynamicObjectCollection();
+//        for(DynamicObject col : viewTypeCols){
+//            collection.add(col);
+//        }
+//
+//        bizAcctOutBill.set("nckd_payviewtypemul", collection);//多选页面类型
+
         BigDecimal totalReimburseAmount = BigDecimal.ZERO;//报销金额合计
 
         //费用明细
@@ -286,9 +358,9 @@ public class SRMSynPayApiPlugin implements Serializable {
                     return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
                 }
 
-                DynamicObject projectInfo = CommonHelperUtils.queryBaseDynamicObject("bd_project", "number", project);
+                DynamicObject projectInfo = CommonHelperUtils.queryBaseDynamicObject("bd_project", "number", xsproject);
                 if(projectInfo == null){
-                    returnMessage = "项目(" + project + ")在星瀚系统中未匹配到数据!";
+                    returnMessage = "项目(" + xsproject + ")在星瀚系统中未匹配到数据!";
                     return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
                 }
 
@@ -697,9 +769,35 @@ public class SRMSynPayApiPlugin implements Serializable {
         String position = inputData.getString("position");//职位
         String biller = inputData.getString("biller");//制单人工号
 
-        if(StringUtils.isEmpty(srmBillNo) || StringUtils.isEmpty(srmUrl) || StringUtils.isEmpty(cause) || StringUtils.isEmpty(contract)
-                || StringUtils.isEmpty(orgUnit) || StringUtils.isEmpty(position) || StringUtils.isEmpty(biller) || StringUtils.isEmpty(applier)){
-            returnMessage = "请检查以下参数 SRM单号、srmUrl、合同编码、事由、申请部门、申请人职位、制单人、经办人 是否为空!";
+        if(StringUtils.isEmpty(srmBillNo)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "SRM单号 不能为空";
+        }
+
+        if(StringUtils.isEmpty(srmUrl)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "srmUrl 不能为空";
+        }
+
+        if(StringUtils.isEmpty(cause)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "事由 不能为空";
+        }
+
+        if(StringUtils.isEmpty(orgUnit)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "申请部门 不能为空";
+        }
+
+        if(StringUtils.isEmpty(position)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "申请人职位 不能为空";
+        }
+
+        if(StringUtils.isEmpty(biller)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "制单人 不能为空";
+        }
+
+        if( StringUtils.isEmpty(applier)){
+            returnMessage = ("".equals(returnMessage) ? "" : ",") + "经办人 不能为空";
+        }
+
+        if(!StringUtils.isEmpty(returnMessage)){
             return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
         }
 
@@ -755,8 +853,11 @@ public class SRMSynPayApiPlugin implements Serializable {
         }
 
         //合同台账
-        qFilter = new QFilter("contractcode", QCP.equals, contract);
-        DynamicObject contractInfo = BusinessDataServiceHelper.loadSingle("er_contractbill", qFilter.toArray());
+        DynamicObject contractInfo = null;
+        if(!StringUtils.isEmpty(contract)) {
+            qFilter = new QFilter("contractcode", QCP.equals, contract);
+            contractInfo = BusinessDataServiceHelper.loadSingle("er_contractbill", qFilter.toArray());
+        }
 
         //单据类型
         DynamicObject billTypeInfo = CommonHelperUtils.queryBaseDynamicObject("bos_billtype", "number", "er_prepaybill_BT_S");
@@ -794,6 +895,8 @@ public class SRMSynPayApiPlugin implements Serializable {
         dailyLoanBill.set("ispush", "false");//合同下推生成
         dailyLoanBill.set("nckd_srmstatus", "1");//srm状态,1:SRM已推送;2:已退回SRM;3:已反写SRM;4:反写SRM失败
 //        dailyLoanBill.set("repaymentdate", repaymentDate);//预计冲销日期
+        dailyLoanBill.set("nckd_duigong", "01");//是否对公业务
+//        dailyLoanBill.set("nckd_payviewtypemul", getDefaultMultViewType());//多选页面类型
 
         BigDecimal totalReimburseAmount = BigDecimal.ZERO;//报销金额合计
 
@@ -1064,14 +1167,15 @@ public class SRMSynPayApiPlugin implements Serializable {
      * @return   CustomApiResult  返回
      */
     public CustomApiResult<JSONObject> returnResult(String code, String message, JSONArray responseData){
-        JSONObject reslutData = new JSONObject();
+        JSONObject resultData = new JSONObject();
 
-        reslutData.put("message", message);
-        reslutData.put("code", code);
+        resultData.put("msg", message);
+        resultData.put("code", code);
+        resultData.put("successFlag", ("0".equals(code) ? true : false));
 
-        reslutData.put("data", responseData);
+        resultData.put("data", responseData);
 
-        return CustomApiResult.success(reslutData);
+        return CustomApiResult.success(resultData);
     }
 
     /**
@@ -1091,4 +1195,25 @@ public class SRMSynPayApiPlugin implements Serializable {
         }
         return billNO;
     }
+
+
+    /**
+     * 默认多选页面类型
+     * @return
+     */
+    private Object[] getDefaultMultViewType(){
+        String[] typeStrings = new String[]{"1008", "1009"};
+
+        QFilter qFilter = new QFilter("number", QCP.in, typeStrings);
+        DynamicObject[] viewTypeCols = BusinessDataServiceHelper.load("nckd_payviewtype", "id, number, name", qFilter.toArray());
+        if(viewTypeCols != null && viewTypeCols.length > 0){
+            List<Long> idList = Arrays.stream(viewTypeCols)
+                    .map(type ->  type.getLong("id"))
+                    .collect(Collectors.toList());
+            Object[] basedataIds = idList.toArray();
+            return basedataIds;
+        }
+
+        return null;
+    }
 }

+ 3 - 2
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/webapi/TransDetailApiPlugin.java

@@ -280,7 +280,7 @@ public class TransDetailApiPlugin implements Serializable {
 
         JSONObject bizTypeObj =  jsonObject.getJSONObject("bizType");
         if (EmptyUtils.isNotEmpty(bizTypeObj)) {
-            String bizType = jsonObject.getString("value");
+            String bizType = bizTypeObj.getString("value");
             switch (bizType) {
                 case "1":
                     transDetail.set(BeiTransdetailConstantInfo.BIZTYPE, "1");
@@ -439,7 +439,8 @@ public class TransDetailApiPlugin implements Serializable {
                 if(StringUtils.isNotEmpty(pathParam)){
                     elecreceiptDyn.set(BeiElecreceiptConstantInfo.FILEPATH, pathParam);
                 }
-                String url = reMap.get("url").toString();
+                //String url = reMap.get("url").toString();
+                String url = reMap.get("downUrl").toString();
                 if(StringUtils.isNotEmpty(url)){
                     elecreceiptDyn.set(BeiElecreceiptConstantInfo.UPLOADFILENAME, url);
                 }

+ 3 - 2
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/hrmp/hbpm/task/SyncUtil.java

@@ -384,8 +384,9 @@ public class SyncUtil {
         sb.append("             to_char(person.fmodifytime,'yyyy-MM-dd hh24:mi:ss') EMP_B_LAST_UPTIME, \n");
         // 邮箱,生日,办公地点
         sb.append("             e.fbusemail EMP_B_EMAIL,to_char(b.fbirthday,'yyyy-MM-dd') EMP_B_DATE_BIRTH,wp.fname EMP_B_WORKSPACE,\n");
-        // 身份证,用工关系状态,国籍
-        sb.append("             g.fnumber EMP_B_IDNUMBER, n.fk_nckd_mdmkey EMP_B_RELA_STATUS, nation.fk_nckd_mdmkey EMP_B_NATIONALITY, \n");
+        // 身份证,用工关系状态,国籍 2025-05-25 身份证不传
+        // sb.append("             g.fnumber EMP_B_IDNUMBER, n.fk_nckd_mdmkey EMP_B_RELA_STATUS, nation.fk_nckd_mdmkey EMP_B_NATIONALITY, \n");
+        sb.append("             ' ' EMP_B_IDNUMBER, n.fk_nckd_mdmkey EMP_B_RELA_STATUS, nation.fk_nckd_mdmkey EMP_B_NATIONALITY, \n");
         // 在职状态
         sb.append("             s.fk_nckd_mdmkey EMP_W_WORKSTATE, \n");
         // 退休日期

+ 42 - 0
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/plugin/workflow/GetJobLevelWorkflowPlugin.java

@@ -0,0 +1,42 @@
+package nckd.jimin.jyyy.hr.plugin.workflow;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.utils.ObjectUtils;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.bos.workflow.api.AgentExecution;
+import kd.bos.workflow.engine.extitf.IWorkflowPlugin;
+import kd.hrmp.hrpi.business.infrastructure.utils.QFilterUtil;
+import kd.sdk.plugin.Plugin;
+import nckd.jimin.jyyy.hr.hrmp.hbpm.task.SyncPositionTask;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * 通用工作流插件 Tyx 2025-05-26
+ * 获取人员职等
+ */
+public class GetJobLevelWorkflowPlugin implements IWorkflowPlugin {
+
+    private static final Log log = LogFactory.getLog(GetJobLevelWorkflowPlugin.class);
+
+    @Override
+    public void notify(AgentExecution execution) {
+        String personId = execution.getVariable("personId").toString();
+
+        QFilter filter = QFilterUtil.getCurrentQf();
+        filter.and(QFilterUtil.getDataStatusFilter());
+        filter.and("person.id", QCP.equals, Long.valueOf(personId));
+        DynamicObject bill = QueryServiceHelper.queryOne("hrpi_empjobrel", "jobgrade.number", new QFilter[]{filter});
+        if(!ObjectUtils.isEmpty(bill)) {
+            execution.setVariable("jobGradeNo", bill.getString("jobgrade.number"));
+        }
+        log.info("GetJobLevelWorkflowPlugin 职等编码 : {}", execution.getVariable("jobGradeNo"));
+    }
+}

+ 864 - 0
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/wtc/wtss/formplugin/web/pc/WtssPersonHomePCPluginEx.java

@@ -0,0 +1,864 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package nckd.jimin.jyyy.hr.wtc.wtss.formplugin.web.pc;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.EventObject;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import kd.bos.bill.BillShowParameter;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.resource.ResManager;
+import kd.bos.dataentity.serialization.SerializationUtils;
+import kd.bos.dataentity.utils.StringUtils;
+import kd.bos.entity.EntryType;
+import kd.bos.entity.datamodel.events.ChangeData;
+import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.exception.KDBizException;
+import kd.bos.ext.form.control.CustomControl;
+import kd.bos.extplugin.PluginFilter;
+import kd.bos.form.CloseCallBack;
+import kd.bos.form.FormShowParameter;
+import kd.bos.form.IFormView;
+import kd.bos.form.MobileFormShowParameter;
+import kd.bos.form.OpenStyle;
+import kd.bos.form.ShowType;
+import kd.bos.form.StyleCss;
+import kd.bos.form.cardentry.CardEntry;
+import kd.bos.form.container.Container;
+import kd.bos.form.container.Tab;
+import kd.bos.form.control.Control;
+import kd.bos.form.control.Label;
+import kd.bos.form.control.events.RowClickEvent;
+import kd.bos.form.control.events.RowClickEventListener;
+import kd.bos.form.control.events.TabSelectEvent;
+import kd.bos.form.control.events.TabSelectListener;
+import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.form.events.ClosedCallBackEvent;
+import kd.bos.form.events.CustomEventArgs;
+import kd.bos.form.events.HyperLinkClickEvent;
+import kd.bos.form.events.HyperLinkClickListener;
+import kd.bos.form.field.BasedataEdit;
+import kd.bos.form.field.events.BeforeF7SelectEvent;
+import kd.bos.form.field.events.BeforeF7SelectListener;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.list.ListFilterParameter;
+import kd.bos.list.ListShowParameter;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.orm.query.QFilter;
+import kd.hr.hbp.common.util.HRDateTimeUtils;
+import kd.hr.hbp.common.util.HRMapUtils;
+import kd.sdk.wtc.wtbs.business.custom.WTCCustomControlExtPlugin;
+import kd.sdk.wtc.wtbs.common.enums.WTCApplyType;
+import kd.sdk.wtc.wtbs.common.enums.WTCBillType;
+import kd.sdk.wtc.wtss.business.homepage.BeforeShowApplyPageEvent;
+import kd.sdk.wtc.wtss.business.homepage.BillReplaceExtPlugin;
+import kd.wtc.wtbs.business.bill.BillCommonService;
+import kd.wtc.wtbs.business.extplugin.WTCPluginProxy;
+import kd.wtc.wtbs.business.extplugin.WTCPluginProxyFactory;
+import kd.wtc.wtbs.business.mobile.MobileCommonServiceHelper;
+import kd.wtc.wtbs.business.web.attperiod.PerAttPeriodQueryServiceImpl;
+import kd.wtc.wtbs.common.model.mobile.AbnormalDealModel;
+import kd.wtc.wtbs.common.model.period.PerAttPeriod;
+import kd.wtc.wtbs.common.model.period.PerAttPeriodQueryParam;
+import kd.wtc.wtbs.common.util.Tuple;
+import kd.wtc.wtbs.common.util.WTCCollectionIndexUtil;
+import kd.wtc.wtbs.common.util.WTCCollections;
+import kd.wtc.wtbs.common.util.WTCDateUtils;
+import kd.wtc.wtbs.common.util.WTCInteDateUtil;
+import kd.wtc.wtbs.common.util.WTCMaps;
+import kd.wtc.wtbs.common.util.WTCSerializationUtils;
+import kd.wtc.wtbs.common.util.WTCStringUtils;
+import kd.wtc.wtbs.common.util.third.collect.Lists;
+import kd.wtc.wtbs.common.util.third.util.CollectionUtils;
+import kd.wtc.wtbs.common.util.third.util.NumberUtils;
+import kd.wtc.wtbs.formplugin.util.WTCFormUtils;
+import kd.wtc.wtp.business.attconfirm.impl.AttConfirmQueryServiceImpl;
+import kd.wtc.wtp.common.enums.attconfirm.AttConRecordStatusEnum;
+import kd.wtc.wtp.common.enums.attconfirm.AttConfirmDataStatusEnum;
+import kd.wtc.wtp.common.model.attconfirm.AttConfirmRecordModel;
+import kd.wtc.wtp.common.model.attconfirm.AttConfirmRecordQueryParam;
+import kd.wtc.wtss.business.attstatistics.AttConfirmServiceHelper;
+import kd.wtc.wtss.business.servicehelper.common.HomePageServiceHelper;
+import kd.wtc.wtss.business.servicehelper.common.QuotaStatisticIndexService;
+import kd.wtc.wtss.business.servicehelper.common.SchemaServiceHelper;
+import kd.wtc.wtss.business.servicehelper.mobile.MobileHomePageBusiness;
+import kd.wtc.wtss.business.servicehelper.mobile.MobileHomePageServiceHelper;
+import kd.wtc.wtss.business.servicehelper.pc.PersonHomePCBusiness;
+import kd.wtc.wtss.business.servicehelper.pc.PersonHomePCCountBusiness;
+import kd.wtc.wtss.business.servicehelper.pc.StaffPCAppConfigService;
+import kd.wtc.wtss.business.servicehelper.summaryconf.SummaryConfigDetailService;
+import kd.wtc.wtss.common.constants.PersonHomePCConstants;
+import kd.wtc.wtss.common.constants.StaffPCAppConfigConstants;
+import kd.wtc.wtss.common.dto.DailySource;
+import kd.wtc.wtss.common.dto.MobileHomeConf;
+import kd.wtc.wtss.common.dto.mobilehome.AttRecordModel;
+import kd.wtc.wtss.common.dto.mobilehome.CalendarGetDataModel;
+import kd.wtc.wtss.common.dto.mobilehome.CalendarInitModel;
+import kd.wtc.wtss.common.dto.mobilehome.DateDataModel;
+import kd.wtc.wtss.common.dto.mobilehome.DateStateModel;
+import kd.wtc.wtss.common.dto.summaryconf.SummaryConfDetail;
+import kd.wtc.wtss.common.enums.UnitDataEnum;
+import kd.wtc.wtss.common.utils.WTSSDateUtils;
+
+public class WtssPersonHomePCPluginEx extends AbstractFormPlugin implements RowClickEventListener, PersonHomePCConstants, TabSelectListener, BeforeF7SelectListener, HyperLinkClickListener {
+    private static final Log LOG = LogFactory.getLog(WtssPersonHomePCPluginEx.class);
+
+    public WtssPersonHomePCPluginEx() {
+    }
+
+    public void registerListener(EventObject eventObject) {
+        super.registerListener(eventObject);
+        this.addClickListeners(new String[]{"flexmore", "labelmore", "configap", "labelquestion1", "labelquestion2", "labelquestion3", "btn_attcon"});
+        CardEntry appContainer = (CardEntry)this.getView().getControl("fastappentryentity");
+        appContainer.addRowClickListener(this);
+        CardEntry qtEntryEntityCountContainer = (CardEntry)this.getView().getControl("qtentryentitycount");
+        qtEntryEntityCountContainer.addRowClickListener(this);
+        qtEntryEntityCountContainer.addHyperClickListener(this);
+        Tab tab = (Tab)this.getControl("tabap");
+        tab.addTabSelectListener(this);
+        Container container = (Container)this.getControl("attstavector");
+        container.addClickListener(this);
+        this.addBeforeF7SelectListener("attperiodentry");
+        this.addBeforeF7SelectListener("attperiod");
+    }
+
+    private void addBeforeF7SelectListener(String key) {
+        BasedataEdit personAddEdit = (BasedataEdit)this.getView().getControl(key);
+        personAddEdit.addBeforeF7SelectListener(this);
+    }
+
+    public void beforeBindData(EventObject eventObject) {
+        super.beforeBindData(eventObject);
+        LOG.info("pcpersonhome beforeBindData begin...");
+        this.initCalendar();
+        Long userId = MobileCommonServiceHelper.getInstance().getUserId();
+        Long employeeId = MobileCommonServiceHelper.getInstance().getEmployeeId();
+        this.getPageCache().put("cache_id_userid", String.valueOf(userId));
+        this.getPageCache().put("cache_id_employeeid", String.valueOf(employeeId));
+        String queryDate = WTCDateUtils.date2Str(new Date(), "yyyy-MM-dd");
+        Map<String, String> attFile = MobileHomePageServiceHelper.getAttFileWithEmployeeId(employeeId, queryDate);
+        if (HRMapUtils.isEmpty(attFile)) {
+            this.initControlWithoutValidValue();
+            this.getView().showErrorNotification(ResManager.loadKDString("您无有效的考勤档案,请联系管理员。", "PersonHomePCPlugin_0", "wtc-wtss-formplugin", new Object[0]));
+        } else {
+            long schemeId = MobileHomePageBusiness.getInstance().getSchemeIdWithWorkspace(attFile, "A");
+            if (schemeId == 0L) {
+                this.initControlWithoutValidValue();
+                this.getView().showErrorNotification(ResManager.loadKDString("您未关联假勤自助方案,请联系管理员。", "PersonHomePCPlugin_1", "wtc-wtss-formplugin", new Object[0]));
+            } else {
+                DynamicObject ruleByScheme = SchemaServiceHelper.getInstance().queryRuleByScheme(schemeId, "A");
+                long ruleId = ruleByScheme.getLong("id");
+                Long attfileBoid = Long.parseLong((String)attFile.get("boid"));
+                LOG.info("pcpersonhome archives schemeId:{} attfileBoid:{}", schemeId, attfileBoid);
+                this.getPageCache().put("cache_scheme_id", String.valueOf(schemeId));
+                this.getPageCache().put("cache_attfile_boid", String.valueOf(attfileBoid));
+                this.getPageCache().put("cache_rule_id", String.valueOf(ruleId));
+                long quotaConfigId = ruleByScheme.getLong("quotaconfig.id");
+                StaffPCAppConfigService.initFastApp(ruleId, this.getView());
+                this.initPersonCount(userId, schemeId, quotaConfigId, attfileBoid, employeeId);
+                this.initCommonProblem(schemeId);
+            }
+        }
+    }
+
+    public void propertyChanged(PropertyChangedArgs propertyChangedArgs) {
+        super.propertyChanged(propertyChangedArgs);
+        String fieldKey = propertyChangedArgs.getProperty().getName();
+        Object newValue = WTCCollectionIndexUtil.getEleFromArr(propertyChangedArgs.getChangeSet(), 0).isPresent() ? ((ChangeData)WTCCollectionIndexUtil.getEleFromArr(propertyChangedArgs.getChangeSet(), 0).get()).getNewValue() : null;
+        Object oldValue = WTCCollectionIndexUtil.getEleFromArr(propertyChangedArgs.getChangeSet(), 0).isPresent() ? ((ChangeData)WTCCollectionIndexUtil.getEleFromArr(propertyChangedArgs.getChangeSet(), 0).get()).getOldValue() : null;
+        long userId = Long.parseLong(this.getView().getPageCache().get("cache_id_userid"));
+        long employeeId = Long.parseLong(this.getView().getPageCache().get("cache_id_employeeid"));
+        LOG.info("pcteamhome.beforeBindData.userid:{}", userId);
+        long schemeId = Long.parseLong(this.getView().getPageCache().get("cache_scheme_id"));
+        Date date;
+        if (fieldKey.equals("daydate")) {
+            if (this.reSetOldVal(oldValue, newValue, "daydate")) {
+                return;
+            }
+
+            date = (Date)newValue;
+            String nowDateStr = WTCDateUtils.date2Str(date, "yyyy-MM-dd");
+            //PersonHomePCCountBusiness.getInstance().setDateDetail(userId, nowDateStr, schemeId, this.getView(), employeeId);
+            CalendarGetDataModel queryDateModel = new CalendarGetDataModel();
+            queryDateModel.setChooseDay(nowDateStr);
+            List<String> dateRange = (List)WTCDateUtils.getDateRange(WTCDateUtils.getBeginDayOfMonth(date), WTCDateUtils.getEndDayOfMonth(date)).stream().map((datex) -> {
+                return WTCDateUtils.date2Str(datex, "yyyy-MM-dd");
+            }).collect(Collectors.toList());
+            queryDateModel.setDateList(dateRange);
+            this.initCalendarState(queryDateModel, true);
+        } else if (fieldKey.equals("attperiodentry")) {
+            DynamicObject dynamicObject = this.getModel().getDataEntity().getDynamicObject("attperiodentry");
+            Long personAttPeriodId = dynamicObject.getLong("id");
+            PerAttPeriodQueryServiceImpl instance = PerAttPeriodQueryServiceImpl.getInstance();
+            PerAttPeriodQueryParam queryParam = new PerAttPeriodQueryParam();
+            queryParam.setExtendQFilter(new QFilter("id", "=", personAttPeriodId));
+            List<PerAttPeriod> perAttPeriod = instance.queryPerAttPeriodEntity(queryParam);
+            if (!CollectionUtils.isEmpty(perAttPeriod)) {
+                PerAttPeriod entry = (PerAttPeriod)perAttPeriod.get(0);
+                this.getView().getPageCache().put("PerAttId", String.valueOf(personAttPeriodId));
+                String personAttPeriodIdStr = entry.getId();
+                this.getView().getPageCache().put("PerAttIdStr", personAttPeriodIdStr);
+                long attFileBid = entry.getFileBoId();
+                this.getView().getPageCache().put("cache_attfile_boid", String.valueOf(attFileBid));
+                LOG.info("mobilehome initStatistic query begin...");
+                Map<String, Object> summaryConfig = SummaryConfigDetailService.getInstance().queryInfo(userId, "A", personAttPeriodIdStr, schemeId, 2, attFileBid);
+                LOG.info("mobilehome initStatistic query end...");
+                List<SummaryConfDetail> showSummary = (List)summaryConfig.get("show");
+                this.setDatePreDetail(showSummary);
+            }
+
+            AttConfirmServiceHelper.instance().updateBtnAttConfirmVisible(this.getView());
+        } else if ("qtdate".equals(fieldKey)) {
+            if (this.reSetOldVal(oldValue, newValue, "qtdate")) {
+                return;
+            }
+
+            date = this.getView().getModel().getDataEntity().getDate("qtdate");
+            if (date == null) {
+                date = new Date();
+                this.getView().getModel().getDataEntity().set("qtdate", date);
+            }
+
+            QuotaStatisticIndexService.getInstance().setQuotaDetail(schemeId, userId, date, this.getView(), "2", employeeId);
+        }
+
+    }
+
+    private boolean reSetOldVal(Object oldVal, Object newVal, String key) {
+        if (newVal == null) {
+            this.getModel().beginInit();
+            this.getModel().setValue(key, oldVal);
+            this.getModel().endInit();
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private void initPersonCount(long userId, long schemeId, long quotaConfigId, Long attfileBid, long employeeId) {
+        List<PerAttPeriod> userAllPeriods = MobileHomePageServiceHelper.getUserAllPeriodsSimpleWithEmployeeId(employeeId);
+        if (CollectionUtils.isEmpty(userAllPeriods)) {
+            this.getView().setVisible(Boolean.FALSE, new String[]{"nckd_flexpanelap", "dateflex", "perflex", "qtflex", "attstavector"});
+            this.getView().showErrorNotification(ResManager.loadKDString("您的档案未有人员考勤期间,导致首页数据无法查看,请联系管理员。", "PersonHomePCPlugin_2", "wtc-wtss-formplugin", new Object[0]));
+        } else {
+            this.getView().setVisible(Boolean.FALSE, new String[]{"attperiod", "flexattperoidconf", "perflex", "qtdate", "qtflex"});
+            Date nowDate = WTCDateUtils.addDays(new Date(), -1);
+            String nowDateStr = WTCDateUtils.date2Str(nowDate, "yyyy-MM-dd");
+            this.getPageCache().put("cache_date", nowDateStr);
+            this.getPageCache().put("current_statistic_mode", "mode_day");
+            this.getModel().setValue("daydate", nowDate);
+            List<Long> PerAttIds = new ArrayList(userAllPeriods.size());
+            long nowTime = nowDate.getTime();
+            String personAttPeriodId = ((PerAttPeriod)userAllPeriods.get(0)).getPrimaryId() + "";
+            String attPeriodId = ((PerAttPeriod)userAllPeriods.get(0)).getAttPeriodId() + "";
+            String personAttPeriodIdStr = ((PerAttPeriod)userAllPeriods.get(0)).getId();
+            Iterator var19 = userAllPeriods.iterator();
+
+            while(var19.hasNext()) {
+                PerAttPeriod periodReport = (PerAttPeriod)var19.next();
+                if (periodReport.getPerAttBeginDate().getTime() < nowDate.getTime()) {
+                    PerAttIds.add(periodReport.getPrimaryId());
+                }
+
+                HRDateTimeUtils.format(periodReport.getPerAttBeginDate(), "yyyy-MM-dd");
+                if (nowTime >= periodReport.getPerAttBeginDate().getTime() && nowTime <= periodReport.getPerAttEndDate().getTime()) {
+                    personAttPeriodId = periodReport.getPrimaryId() + "";
+                    attPeriodId = periodReport.getAttPeriodId() + "";
+                    personAttPeriodIdStr = periodReport.getId();
+                }
+            }
+
+            //this.getModel().setValue("attperiodentry", personAttPeriodId);
+            //this.getModel().setValue("attperiod", attPeriodId);
+            this.getPageCache().put("PerAttIds", SerializationUtils.toJsonString(PerAttIds));
+            this.getPageCache().put("PerAttId", personAttPeriodId);
+            this.getPageCache().put("PerAttIdStr", personAttPeriodIdStr);
+            LOG.info("mobilehome initStatistic query begin...");
+            Map<String, Object> summaryConfig = SummaryConfigDetailService.getInstance().queryInfo(userId, "A", personAttPeriodIdStr, schemeId, 2, attfileBid);
+            LOG.info("mobilehome initStatistic query end...");
+            List<SummaryConfDetail> showSummary = (List)summaryConfig.get("show");
+            this.setDatePreDetail(showSummary);
+            //PersonHomePCCountBusiness.getInstance().setDateDetail(userId, nowDateStr, schemeId, this.getView(), employeeId);
+            AttConfirmServiceHelper.instance().updateBtnAttConfirmVisible(this.getView());
+            if (quotaConfigId == 0L) {
+                this.getView().setVisible(Boolean.FALSE, new String[]{"qttabpage"});
+            } else {
+                this.getPageCache().put("quotaconfig.id", quotaConfigId + "");
+                Date date = this.getView().getModel().getDataEntity().getDate("qtdate");
+                QuotaStatisticIndexService.getInstance().setQuotaDetail(schemeId, userId, date, this.getView(), "2", employeeId);
+            }
+        }
+    }
+
+    private void setDatePreDetail(List<SummaryConfDetail> showSummary) {
+        DynamicObjectCollection dynamicObjects = this.getModel().getDataEntity(true).getDynamicObjectCollection("perentryentitycount");
+        EntryType entryType;
+        if (CollectionUtils.isNotEmpty(dynamicObjects) && WTCStringUtils.isEmpty(this.getPageCache().get("perentryentitycounttype"))) {
+            entryType = (EntryType)((DynamicObject)dynamicObjects.get(0)).getDynamicObjectType();
+            this.getPageCache().put("perentryentitycounttype", WTCSerializationUtils.serializeToBase64(entryType));
+        }
+
+        if (CollectionUtils.isEmpty(showSummary)) {
+            this.getModel().deleteEntryData("perentryentitycount");
+        } else {
+            entryType = this.getPerEntryEntityType(dynamicObjects);
+            this.getModel().deleteEntryData("perentryentitycount");
+            if (entryType != null) {
+                Iterator var5 = showSummary.iterator();
+
+                while(var5.hasNext()) {
+                    SummaryConfDetail summaryConfDetail = (SummaryConfDetail)var5.next();
+                    DynamicObject dynamicObject = new DynamicObject(entryType);
+                    dynamicObject.set("datasouvaluepre", summaryConfDetail.getAttItemValue());
+                    //dynamicObject.set("datasounamepre", summaryConfDetail.getName() + "(" + UnitDataEnum.getRetDesc(summaryConfDetail.getUnit()) + ")");
+                    dynamicObjects.add(dynamicObject);
+                }
+
+                this.getView().updateView("perentryentitycount");
+            }
+        }
+    }
+
+    public void click(EventObject evt) {
+        super.click(evt);
+        Control control = (Control)evt.getSource();
+        Long ruleId = Long.parseLong(this.getView().getPageCache().get("cache_rule_id"));
+        String key = control.getKey();
+        Tab tab = (Tab)this.getControl("tabap");
+        String staType = tab.getCurrentTab();
+        switch (key) {
+            case "flexmore":
+            case "labelmore":
+                ListShowParameter showParameter = new ListShowParameter();
+                showParameter.getOpenStyle().setShowType(ShowType.Modal);
+                showParameter.setFormId("wtss_problemlist");
+                this.getView().showForm(showParameter);
+                break;
+            case "configap":
+                FormShowParameter formShowParameter = new FormShowParameter();
+                formShowParameter.setFormId("wtss_appconfig");
+                OpenStyle openStyle = formShowParameter.getOpenStyle();
+                Optional.ofNullable(openStyle).ifPresent((style) -> {
+                    style.setShowType(ShowType.Modal);
+                });
+                formShowParameter.setCustomParam("ruleId", ruleId);
+                formShowParameter.setCloseCallBack(new CloseCallBack(this, "appConfig"));
+                this.getView().showForm(formShowParameter);
+                break;
+            case "labelquestion1":
+                PersonHomePCBusiness.getInstance().goToProblemDetail(this.getView(), 1);
+                break;
+            case "labelquestion2":
+                PersonHomePCBusiness.getInstance().goToProblemDetail(this.getView(), 2);
+                break;
+            case "labelquestion3":
+                PersonHomePCBusiness.getInstance().goToProblemDetail(this.getView(), 3);
+                break;
+            case "attstavector":
+                if ("daytabpage".equals(staType)) {
+                    this.showConfigPage(this.getView(), "A");
+                } else if ("pertabpage".equals(staType)) {
+                    this.showConfigPage(this.getView(), "B");
+                } else if ("qttabpage".equals(staType)) {
+                    this.showConfigPage(this.getView(), "C");
+                }
+        }
+
+    }
+
+    public void afterDoOperation(AfterDoOperationEventArgs evt) {
+        super.afterDoOperation(evt);
+        String opKey = evt.getOperateKey();
+        if ("attconf".equals(opKey) && evt.getOperationResult().isSuccess()) {
+            this.showAttConfirmPage();
+        }
+
+    }
+
+    private void showConfigPage(IFormView view, String configType) {
+        FormShowParameter showParameter = new FormShowParameter();
+        showParameter.getOpenStyle().setShowType(ShowType.Modal);
+        showParameter.setFormId("wtss_countcig");
+        Long ruleId = Long.parseLong(this.getView().getPageCache().get("cache_rule_id"));
+        long schemeId = Long.parseLong(this.getPageCache().get("cache_scheme_id"));
+        String nowDateStr = this.getView().getPageCache().get("cache_date");
+        String personAttPeriodIdStr = this.getPageCache().get("PerAttIdStr");
+        Map<String, Object> configParams = new HashMap(3);
+        configParams.put("cache_rule_id", ruleId);
+        configParams.put("cache_schemeId_id", schemeId);
+        configParams.put("perioddate", nowDateStr);
+        configParams.put("configtype", configType);
+        configParams.put("cache_attfile_boid", Long.parseLong(view.getPageCache().get("cache_attfile_boid")));
+        configParams.put("PerAttIdStr", personAttPeriodIdStr);
+        configParams.put("quotaconfig.id", this.getPageCache().get("quotaconfig.id"));
+        CloseCallBack callBack = new CloseCallBack(this, "saveconfig");
+        showParameter.setCloseCallBack(callBack);
+        showParameter.setCustomParams(configParams);
+        showParameter.setCaption(ResManager.loadKDString("考勤统计", "AttStaVectorName", "wtc-wtss-formplugin", new Object[0]));
+        view.showForm(showParameter);
+    }
+
+    public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
+        super.closedCallBack(closedCallBackEvent);
+        String actionId = closedCallBackEvent.getActionId();
+        Long ruleId = Long.parseLong(this.getView().getPageCache().get("cache_rule_id"));
+        switch (actionId) {
+            case "appConfig":
+                StaffPCAppConfigService.initFastApp(ruleId, this.getView());
+                break;
+            case "selectAttper":
+                Map<String, String> returnData = (Map)closedCallBackEvent.getReturnData();
+                if (returnData != null && returnData.size() > 0) {
+                    this.getModel().setValue("attperiodentry", returnData.get("pkvalue"));
+                    this.getModel().setValue("attperiod", returnData.get("attperiod"));
+                }
+                break;
+            case "saveconfig":
+                Long userId = Long.parseLong(this.getPageCache().get("cache_id_userid"));
+                Long employeeId = Long.parseLong(this.getPageCache().get("cache_id_employeeid"));
+                long schemeId = Long.parseLong(this.getPageCache().get("cache_scheme_id"));
+                Long attFileBid = Long.parseLong(this.getPageCache().get("cache_attfile_boid"));
+                Date queryDate = this.getModel().getDataEntity().getDate("daydate");
+                String nowDateStr = WTCDateUtils.date2Str(queryDate, "yyyy-MM-dd");
+                PersonHomePCCountBusiness.getInstance().setDateDetail(userId, nowDateStr, schemeId, this.getView(), employeeId);
+                LOG.info("pcpersonhome initStatistic query begin...");
+                String personAttPeriodIdStr = this.getView().getPageCache().get("PerAttIdStr");
+                Map<String, Object> summaryConfig = SummaryConfigDetailService.getInstance().queryInfo(userId, "A", personAttPeriodIdStr, schemeId, 2, attFileBid);
+                LOG.info("pcpersonhome initStatistic query end...");
+                List<SummaryConfDetail> showSummary = (List)summaryConfig.get("show");
+                this.setDatePreDetail(showSummary);
+                String cacheQuotaConfigId = this.getPageCache().get("quotaconfig.id");
+                long quotaConfigId = NumberUtils.isDigits(cacheQuotaConfigId) ? Long.parseLong(cacheQuotaConfigId) : 0L;
+                if (quotaConfigId != 0L) {
+                    Date date = this.getView().getModel().getDataEntity().getDate("qtdate");
+                    QuotaStatisticIndexService.getInstance().setQuotaDetail(schemeId, userId, date, this.getView(), "2", employeeId);
+                }
+                break;
+            case "attconf":
+                AttConfirmServiceHelper.instance().updateBtnAttConfirmVisible(this.getView());
+                String confirmDate = this.getPageCache().get("confirmDate");
+                if (WTCDateUtils.str2Date(confirmDate, "yyyy-MM-dd") != null) {
+                    this.setAttRecordData(confirmDate);
+                }
+        }
+
+    }
+
+    public void entryRowClick(RowClickEvent evt) {
+        RowClickEventListener.super.entryRowClick(evt);
+        CardEntry cardEntry = (CardEntry)evt.getSource();
+        String entryKey = cardEntry.getEntryKey();
+        if ("fastappentryentity".equals(entryKey)) {
+            int openIndex = this.getModel().getEntryCurrentRowIndex("fastappentryentity");
+            String openText = (String)this.getModel().getValue("fastname", openIndex);
+            String app = StaffPCAppConfigConstants.getBillNumber(openText);
+            if (WTCStringUtils.isEmpty(app)) {
+                return;
+            }
+
+            switch (app) {
+                case "A":
+                    this.showAddNewPage("wtabm_vaapplyself", true);
+                    break;
+                case "B":
+                    this.showAddNewPage("wtom_otbillself", true);
+                    break;
+                case "C":
+                    this.showAddNewPage("wts_swshiftselfbill", true);
+                    break;
+                case "D":
+                    this.showAddNewPage("wtam_busitripselfbill", true);
+                    break;
+                case "E":
+                    this.showAddNewPage("wtpm_supsignself", true);
+                    break;
+                case "M":
+                    this.showAddNewPage("wtam_attconfirmbill", false);
+            }
+        } else if ("qtentryentitycount".equals(entryKey)) {
+            this.showQTLineDetailList();
+        }
+
+    }
+
+    public void customEvent(CustomEventArgs cea) {
+        String key = cea.getKey();
+        String eventName = cea.getEventName();
+        LOG.info("pcpersonhome key:{} eventName:{} eventArgs:{} ", new Object[]{key, eventName, cea.getEventArgs()});
+        if (StringUtils.isEmpty(this.getPageCache().get("cache_normal_init"))) {
+            if ("customcalendar".equals(key) && "getDateData".equals(eventName)) {
+                CalendarGetDataModel getDate = (CalendarGetDataModel)SerializationUtils.fromJsonString(cea.getEventArgs(), CalendarGetDataModel.class);
+                this.initCalendarState(getDate, false);
+                this.getModel().setValue("daydate", getDate.getChooseDay());
+            } else if ("customcalendar".equals(key) && "getAttRecord".equals(eventName)) {
+                this.setAttRecordData(cea.getEventArgs());
+                this.getModel().setValue("daydate", cea.getEventArgs());
+            } else if ("customcalendar".equals(key) && "abnormalDeal".equals(eventName)) {
+                AbnormalDealModel abnormalDealModel = (AbnormalDealModel)SerializationUtils.fromJsonString(cea.getEventArgs(), AbnormalDealModel.class);
+                PersonHomePCBusiness.getInstance().showAddNewFormForAbnormal(this.getView(), abnormalDealModel);
+            } else if ("customcalendar".equals(key) && "attConfirm".equals(eventName)) {
+                JSONObject jsonEventArgs = JSONObject.parseObject(cea.getEventArgs());
+                Object jsonAttConfirmId = jsonEventArgs.get("attConfirmId");
+                if (jsonAttConfirmId != null) {
+                    this.getPageCache().put("attConfirmId", String.valueOf(jsonAttConfirmId));
+                    this.getPageCache().put("confirmDate", String.valueOf(jsonEventArgs.get("confirmDate")));
+                    this.getView().invokeOperation("attconf");
+                }
+            }
+
+        }
+    }
+
+    private void initCalendar() {
+        String chooseDay = WTSSDateUtils.getLastDateString();
+        LOG.info("pcpersonhome chooseDay : {}", chooseDay);
+        CustomControl customcontrol = (CustomControl)this.getView().getControl("customcalendar");
+        Map<String, Object> data = new HashMap(16);
+        CalendarInitModel calendarInitModel = new CalendarInitModel();
+        calendarInitModel.setEarliestMonth("2015-01");
+        calendarInitModel.setChooseDay(chooseDay);
+        data.put("event", "init");
+        data.put("args", calendarInitModel);
+        customcontrol.setData(data);
+    }
+
+    private void initCalendarState(CalendarGetDataModel getDate, Boolean isLocateDate) {
+        long userId = Long.parseLong(this.getView().getPageCache().get("cache_id_userid"));
+        long employeeId = Long.parseLong(this.getView().getPageCache().get("cache_id_employeeid"));
+        long schemeId = Long.parseLong(this.getView().getPageCache().get("cache_scheme_id"));
+        CustomControl customcontrol = (CustomControl)this.getView().getControl("customcalendar");
+        Map<String, Object> data = new HashMap(16);
+        Set<Long> abnormalConfig = SchemaServiceHelper.getInstance().getAbnormalConfig(schemeId, "A");
+        String yearMonth = StringUtils.substring(getDate.getChooseDay(), 0, 7);
+        Date beginDayOfMonth = WTCDateUtils.getBeginDayOfMonth(yearMonth);
+        Date lastDayOfMonth = WTCDateUtils.getLastDayOfMonth(yearMonth);
+        Map<Long, Tuple<Date, Date>> tupleMap = HomePageServiceHelper.getInstance().getAttFileMapWithEmployeeId(employeeId, beginDayOfMonth, lastDayOfMonth);
+        LOG.info("pcpersonhome initCalendarState queryScheduleInfoByAttFileBoId begin... abnormalConfig:{} tupleMap:{}", abnormalConfig, tupleMap);
+        Map<String, Map<String, Object>> scheduleInfo = HomePageServiceHelper.getInstance().queryScheduleInfoByMultiBo(userId, tupleMap, getDate.getChooseDay(), abnormalConfig);
+        Map<String, List<DailySource>> dailySourceData = SchemaServiceHelper.getInstance().getPeriodAttItems(schemeId, "A", userId, (String)getDate.getDateList().get(0), (String)getDate.getDateList().get(getDate.getDateList().size() - 1), tupleMap, 2);
+        if (scheduleInfo != null && LOG.isDebugEnabled()) {
+            LOG.debug("pcpersonhome initCalendarState scheduleInfo:{}", SerializationUtils.toJsonString(scheduleInfo));
+        }
+
+        List<DateStateModel> dateStateModels = HomePageServiceHelper.getInstance().getCalendarData(tupleMap, getDate, scheduleInfo, dailySourceData);
+        String dateStateStrings = "";
+        if (!CollectionUtils.isEmpty(dateStateModels)) {
+            dateStateStrings = SerializationUtils.serializeToBase64(dateStateModels);
+            this.getView().getPageCache().put("cache_id_date_state", dateStateStrings);
+        }
+
+        List<AttRecordModel> attRecordModel = HomePageServiceHelper.getInstance().getSignCardDetailWithEmployeeId(employeeId, schemeId, getDate.getChooseDay(), "0", dateStateStrings, false, (String)null);
+        DateDataModel dateDataModel = new DateDataModel();
+        dateDataModel.setDateList(dateStateModels);
+        dateDataModel.setAttRecord(attRecordModel);
+        data.put("event", "dateData");
+        data.put("isLocateDate", isLocateDate);
+        data.put("args", dateDataModel);
+        HomePageServiceHelper.getInstance().setAttConfirmByDate(data, employeeId, WTCDateUtils.str2Date(getDate.getChooseDay(), "yyyy-MM-dd"));
+        HomePageServiceHelper.getInstance().setData(data, attRecordModel, getDate.getChooseDay(), employeeId);
+        final WTCPluginProxy<WTCCustomControlExtPlugin> workCalendarExtPlugin = (WTCPluginProxy<WTCCustomControlExtPlugin>)WTCPluginProxyFactory.create((Object)null, (Class)WTCCustomControlExtPlugin.class, "kd.sdk.wtc.wtss.business.homepage.WorkCalendarCustomExt", (PluginFilter)null);
+        if (workCalendarExtPlugin.hasPlugin()) {
+            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(data));
+            Map<String, Object> request = WTCMaps.JsonToMap(jsonObject);
+            request.put("attPersonId", userId);
+            request.put("type", "pc");
+            workCalendarExtPlugin.invokeReplace((hrPlugin) -> {
+                hrPlugin.setCustomData(this.getView().getPageId(), "dateData", request);
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("WorkCalendarCustomExt.class:{},eventName:{}", hrPlugin.getClass().getName(), "dateData");
+                }
+
+            });
+            customcontrol.setData(request);
+        } else {
+            customcontrol.setData(data);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("pcpersonhome initCalendarState dateDataModel:{}", SerializationUtils.toJsonString(dateDataModel));
+        }
+
+    }
+
+    private void setAttRecordData(String date) {
+        CustomControl customcontrol = (CustomControl)this.getView().getControl("customcalendar");
+        Map<String, Object> data = new HashMap(16);
+        long employeeId = Long.parseLong(this.getView().getPageCache().get("cache_id_employeeid"));
+        long schemeId = Long.parseLong(this.getView().getPageCache().get("cache_scheme_id"));
+        String dateState = this.getView().getPageCache().get("cache_id_date_state");
+        List<AttRecordModel> attRecordModel = HomePageServiceHelper.getInstance().getSignCardDetailWithEmployeeId(employeeId, schemeId, date, "0", dateState, false, (String)null);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("pcpersonhome attRecord:{}", SerializationUtils.toJsonString(attRecordModel));
+        }
+
+        attRecordModel.sort(Comparator.comparing(AttRecordModel::getDate));
+        data.put("event", "attRecord");
+        data.put("attRecord", attRecordModel);
+        HomePageServiceHelper.getInstance().setAttConfirmByDate(data, employeeId, WTCDateUtils.str2Date(date, "yyyy-MM-dd"));
+        HomePageServiceHelper.getInstance().setData(data, attRecordModel, date, employeeId);
+        final WTCPluginProxy<WTCCustomControlExtPlugin> workCalendarExtPlugin = (WTCPluginProxy<WTCCustomControlExtPlugin>)WTCPluginProxyFactory.create((Object)null, (Class)WTCCustomControlExtPlugin.class, "kd.sdk.wtc.wtss.business.homepage.WorkCalendarCustomExt", (PluginFilter)null);
+        if (workCalendarExtPlugin.hasPlugin()) {
+            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(data));
+            Map<String, Object> request = WTCMaps.JsonToMap(jsonObject);
+            long userId = Long.parseLong(this.getView().getPageCache().get("cache_id_userid"));
+            request.put("attPersonId", userId);
+            request.put("type", "pc");
+            workCalendarExtPlugin.invokeReplace((hrPlugin) -> {
+                hrPlugin.setCustomData(this.getView().getPageId(), "attRecord", request);
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("WorkCalendarCustomExt.class:{},eventName:{}", hrPlugin.getClass().getName(), "attRecord");
+                }
+
+            });
+            customcontrol.setData(request);
+        } else {
+            customcontrol.setData(data);
+        }
+
+    }
+
+    private void initCommonProblem(Long schemeId) {
+        MobileHomeConf mobileHomeConf = SchemaServiceHelper.getInstance().getSchemeForHome(schemeId, "A");
+        if (mobileHomeConf != null && mobileHomeConf.isShowProblem()) {
+            if (CollectionUtils.isEmpty(mobileHomeConf.getProblems())) {
+                this.getView().setVisible(Boolean.FALSE, new String[]{"flexmore", "flexproblem1", "flexproblem2", "flexproblem3"});
+                this.getView().setVisible(Boolean.TRUE, new String[]{"comproblemdeftflex"});
+            } else {
+                this.getView().setVisible(Boolean.FALSE, new String[]{"comproblemdeftflex"});
+                String problemsString = SerializationUtils.serializeToBase64(mobileHomeConf.getProblems());
+                LOG.info("pcpersonhome initCommonProblem problemsString: {}", problemsString);
+                this.getView().getPageCache().put("cache_commproblem", problemsString);
+                List<MobileHomeConf.CommProblem> problems = mobileHomeConf.getProblems();
+                if (problems.size() >= 1) {
+                    if (problems.size() == 1) {
+                        this.getView().setVisible(Boolean.FALSE, new String[]{"flexproblem2"});
+                        this.getView().setVisible(Boolean.FALSE, new String[]{"flexproblem3"});
+                    } else if (problems.size() == 2) {
+                        this.getView().setVisible(Boolean.FALSE, new String[]{"flexproblem3"});
+                        ((Label)this.getControl("labelquestion2")).setText("2." + ((MobileHomeConf.CommProblem)problems.get(1)).getProblem());
+                        ((Label)this.getControl("labeltime2")).setText(WTCInteDateUtil.formatDateBySysTzAndUserFmt(((MobileHomeConf.CommProblem)problems.get(1)).getModifyTime()));
+                    } else {
+                        ((Label)this.getControl("labelquestion2")).setText("2." + ((MobileHomeConf.CommProblem)problems.get(1)).getProblem());
+                        ((Label)this.getControl("labeltime2")).setText(WTCInteDateUtil.formatDateBySysTzAndUserFmt(((MobileHomeConf.CommProblem)problems.get(1)).getModifyTime()));
+                        ((Label)this.getControl("labelquestion3")).setText("3." + ((MobileHomeConf.CommProblem)problems.get(2)).getProblem());
+                        ((Label)this.getControl("labeltime3")).setText(WTCInteDateUtil.formatDateBySysTzAndUserFmt(((MobileHomeConf.CommProblem)problems.get(2)).getModifyTime()));
+                    }
+
+                    ((Label)this.getControl("labelquestion1")).setText("1." + ((MobileHomeConf.CommProblem)problems.get(0)).getProblem());
+                    ((Label)this.getControl("labeltime1")).setText(WTCInteDateUtil.formatDateBySysTzAndUserFmt(((MobileHomeConf.CommProblem)problems.get(0)).getModifyTime()));
+                }
+            }
+        } else {
+            LOG.info("pcpersonhome initCommonProblem isShowProblem false");
+            this.getView().setVisible(Boolean.FALSE, new String[]{"flexcommproblem"});
+        }
+    }
+
+    public void tabSelected(TabSelectEvent tabSelectEvent) {
+        String tabKey = tabSelectEvent.getTabKey();
+        if (tabKey.equals("daytabpage")) {
+            this.getView().setVisible(Boolean.TRUE, new String[]{"daydate", "dateflex"});
+            this.getView().setVisible(Boolean.FALSE, new String[]{"attperiod", "flexattperoidconf", "perflex", "qtflex", "qtdate"});
+        } else if (tabKey.equals("pertabpage")) {
+            this.getView().setVisible(Boolean.TRUE, new String[]{"attperiod", "flexattperoidconf", "perflex"});
+            this.getView().setVisible(Boolean.FALSE, new String[]{"daydate", "dateflex", "qtdate", "qtflex"});
+        } else {
+            this.getView().setVisible(Boolean.TRUE, new String[]{"qtdate", "qtflex"});
+            this.getView().setVisible(Boolean.FALSE, new String[]{"daydate", "dateflex", "attperiod", "flexattperoidconf", "perflex"});
+        }
+
+    }
+
+    public void beforeF7Select(BeforeF7SelectEvent beforeF7SelectEvent) {
+        beforeF7SelectEvent.setCancel(true);
+        ListShowParameter listShowParameter = new ListShowParameter();
+        listShowParameter.getOpenStyle().setShowType(ShowType.Modal);
+        listShowParameter.setLookUp(true);
+        listShowParameter.setHasRight(true);
+        Object[] periodIds = new Object[1];
+        DynamicObject dynamicObject = this.getModel().getDataEntity().getDynamicObject("attperiodentry");
+        if (dynamicObject != null) {
+            periodIds[0] = dynamicObject.get("id");
+        }
+
+        listShowParameter.setSelectedRows(periodIds);
+        listShowParameter.setFormId("wtss_attperiod_f7list");
+        listShowParameter.setBillFormId("wtss_perattperiodquery");
+        listShowParameter.setCaption(ResManager.loadKDString("人员考勤期间", "PersonHomePCPlugin_5", "wtc-wtss-formplugin", new Object[0]));
+        StyleCss style = new StyleCss();
+        style.setWidth("1000");
+        style.setHeight("600");
+        listShowParameter.getOpenStyle().setInlineStyleCss(style);
+        CloseCallBack callBack = new CloseCallBack(this, "selectAttper");
+        listShowParameter.setCloseCallBack(callBack);
+        listShowParameter.setParentPageId(this.getView().getPageId());
+        listShowParameter.setMultiSelect(false);
+        listShowParameter.setCustomParam("multiType", Boolean.FALSE);
+        List<Long> PerAttIds = (List)SerializationUtils.fromJsonString(this.getView().getPageCache().get("PerAttIds"), List.class);
+        List<QFilter> qFilters = Lists.newArrayList();
+        qFilters.add(new QFilter("id", "in", PerAttIds));
+        ListFilterParameter filterList = new ListFilterParameter(qFilters, (String)null);
+        listShowParameter.setListFilterParameter(filterList);
+        this.getView().showForm(listShowParameter);
+    }
+
+    public void hyperLinkClick(HyperLinkClickEvent hyperLinkClickEvent) {
+        this.showQTLineDetailList();
+    }
+
+    private void initControlWithoutValidValue() {
+        this.getPageCache().put("cache_normal_init", "true");
+        this.getView().setVisible(Boolean.FALSE, new String[]{"flexmore", "flexproblem1", "flexproblem2", "flexproblem3"});
+        this.getView().setVisible(Boolean.FALSE, new String[]{"fastappentryentity", "configap"});
+        this.getView().setVisible(Boolean.FALSE, new String[]{"nckd_flexpanelap", "dateflex", "perflex", "qtflex", "attstavector"});
+    }
+
+    private void showAddNewPage(String formId, boolean isAddNew) {
+        WTCBillType billType = (WTCBillType)BillCommonService.getInstance().BILL_TYPE_MAP.get(formId);
+        BeforeShowApplyPageEvent beforeShowApplyPageEvent = new BeforeShowApplyPageEvent(billType, WTCApplyType.SELF, new BillShowParameter());
+        WTCPluginProxy<BillReplaceExtPlugin> proxy = WTCPluginProxyFactory.create(BillReplaceExtPlugin.class, "kd.sdk.wtc.wtss.business.homepage.BillReplaceExtPlugin");
+        proxy.invokeReplace((plugin) -> {
+            plugin.beforeShowApplyPage(beforeShowApplyPageEvent);
+        });
+        FormShowParameter formShowParameter = beforeShowApplyPageEvent.getFormShowParameter();
+        if (BillCommonService.getInstance().hasFormId(beforeShowApplyPageEvent)) {
+            this.getView().showForm(formShowParameter);
+        } else {
+            IFormView view = this.getView();
+            String key;
+            String pageId;
+            if (isAddNew) {
+                BillShowParameter parameter = PersonHomePCBusiness.getInstance().getBillShowParameter(view.getFormShowParameter().getAppId(), formId, view);
+                if (parameter == null) {
+                    return;
+                }
+
+                key = formId + "_addNewPageId";
+                pageId = view.getPageCache().get(key);
+                if (StringUtils.isNotBlank(pageId)) {
+                    parameter.setPageId(pageId);
+                } else {
+                    view.getPageCache().put(key, parameter.getPageId());
+                }
+
+                view.showForm(parameter);
+            } else {
+                ListShowParameter listShowParameter = WTCFormUtils.getListShowParameter(formId, ShowType.MainNewTabPage);
+                key = formId + "_listPageId";
+                pageId = view.getPageCache().get(key);
+                if (StringUtils.isNotBlank(pageId)) {
+                    listShowParameter.setPageId(pageId);
+                } else {
+                    view.getPageCache().put(key, listShowParameter.getPageId());
+                }
+
+                view.showForm(listShowParameter);
+            }
+
+        }
+    }
+
+    private void showQTLineDetailList() {
+        int openIndex = this.getModel().getEntryCurrentRowIndex("qtentryentitycount");
+        String openName = (String)this.getModel().getValue("datasounameqt", openIndex);
+        String quotaConfigId = String.valueOf(this.getModel().getValue("quotasourceid", openIndex));
+        List<Long> quotaDetailIdList = JSON.parseArray(this.getView().getPageCache().get(quotaConfigId), Long.class);
+        ListShowParameter listShowParameter = new ListShowParameter();
+        ListFilterParameter listFilterParameter = new ListFilterParameter();
+        List<QFilter> qFilters = Lists.newArrayList();
+        qFilters.add(new QFilter("id", "in", quotaDetailIdList));
+        listFilterParameter.setQFilters(qFilters);
+        listShowParameter.setListFilterParameter(listFilterParameter);
+        listShowParameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
+        listShowParameter.setBillFormId("wtss_qtlinedetaillayout");
+        listShowParameter.setPageId("wtss_qtlinedetaillayout" + this.getView().getPageId() + quotaConfigId);
+        listShowParameter.setCustomParam("selectYear", WTCDateUtils.date2Str(this.getModel().getDataEntity().getDate("qtdate"), "yyyy"));
+        listShowParameter.setCaption(ResManager.loadKDString("定额明细-{0}", "PersonHomePCPlugin_3", "wtc-wtss-formplugin", new Object[]{openName}));
+        this.getView().showForm(listShowParameter);
+    }
+
+    private void showAttConfirmPage() {
+        Long attConfirmId;
+        try {
+            attConfirmId = Long.valueOf(this.getPageCache().get("attConfirmId"));
+        } catch (Exception var9) {
+            LOG.warn("PersonHomePCPlugin.showAttConfirmPage.getAttConfirmIdError:{}", var9.getMessage());
+            throw new KDBizException(ResManager.loadKDString("获取考勤确认记录数据异常,请联系管理员处理。", "PersonHomePCPlugin_6", "wtc-wtss-formplugin", new Object[0]));
+        }
+
+        if (attConfirmId != 0L) {
+            AttConfirmRecordQueryParam queryParam = new AttConfirmRecordQueryParam();
+            queryParam.setIds(Collections.singleton(attConfirmId));
+            queryParam.setQueryNotEffect(true);
+            List<AttConfirmRecordModel> recordModels = AttConfirmQueryServiceImpl.getInstance().queryAttConfirmRecordModelList(queryParam);
+            if (!WTCCollections.isEmpty(recordModels)) {
+                AttConfirmRecordModel currentRecordModel = (AttConfirmRecordModel)recordModels.get(0);
+                AttConRecordStatusEnum status = currentRecordModel.getStatus();
+                AttConfirmDataStatusEnum dataStatus = currentRecordModel.getDataStatus();
+                if (AttConRecordStatusEnum.SEND.equals(status) && AttConfirmDataStatusEnum.EFFECT.equals(dataStatus)) {
+                    MobileFormShowParameter showParameter = new MobileFormShowParameter();
+                    showParameter.setFormId("wtss_attconfirmlistpc");
+                    showParameter.getOpenStyle().setShowType(ShowType.Modal);
+                    showParameter.setParentPageId(this.getView().getPageId());
+                    showParameter.setCloseCallBack(new CloseCallBack(this, "attconf"));
+                    showParameter.setCustomParam("cache_attfile_boid", this.getPageCache().get("cache_attfile_boid"));
+                    showParameter.setCustomParam("cache_id_employeeid", this.getPageCache().get("cache_id_employeeid"));
+                    showParameter.setCustomParam("currentrecordid", String.valueOf(attConfirmId));
+                    showParameter.setCustomParam("confirmtype", currentRecordModel.getType().getCode());
+                    this.getView().showForm(showParameter);
+                } else {
+                    FormShowParameter detailParameter = new FormShowParameter();
+                    OpenStyle openStyle = new OpenStyle();
+                    openStyle.setShowType(ShowType.Modal);
+                    detailParameter.setOpenStyle(openStyle);
+                    detailParameter.setParentPageId(this.getView().getPageId());
+                    detailParameter.setFormId("wtam_attconfirmbill");
+                    detailParameter.setCloseCallBack(new CloseCallBack(this, "attconf"));
+                    detailParameter.setCustomParam("attConfirmBillId", attConfirmId);
+                    detailParameter.setCustomParam("source", "personhome");
+                    detailParameter.setCustomParam("attfile", Long.valueOf(this.getPageCache().get("cache_attfile_boid")));
+                    this.getView().showForm(detailParameter);
+                }
+
+            }
+        }
+    }
+
+    private EntryType getPerEntryEntityType(DynamicObjectCollection dynamicObjects) {
+        String entryTypeJSONStr = this.getPageCache().get("perentryentitycounttype");
+        EntryType entryType;
+        if (WTCStringUtils.isEmpty(entryTypeJSONStr)) {
+            if (!WTCCollections.isNotEmpty(dynamicObjects)) {
+                return null;
+            }
+
+            entryType = (EntryType)((DynamicObject)dynamicObjects.get(0)).getDynamicObjectType();
+            this.getPageCache().put("perentryentitycounttype", WTCSerializationUtils.toJsonString(entryType));
+        } else {
+            try {
+                entryType = (EntryType)WTCSerializationUtils.deSerializeFromBase64(entryTypeJSONStr);
+            } catch (Exception var5) {
+                LOG.warn("PersonHomePCPlugin.getPerEntryEntityType.Error:", var5);
+                throw new KDBizException(ResManager.loadKDString("获取期间统计数据失败,请联系管理员。", "PersonHomePCPlugin_7", "wtc-wtss-formplugin", new Object[0]));
+            }
+        }
+
+        return entryType;
+    }
+}