Commit 10e67cfb5ffba04473a8ed85be6f77dd5e8859d0

Authored by bbb
0 parents

风险场景优化

Showing 91 changed files with 5542 additions and 0 deletions
  1 +# =============================================================================
  2 +# 风险场景统计配置(外显配置,放在 jar 运行目录,Spring Boot 自动加载)
  3 +# 修改本文件后无需重新打包,重启应用即可生效。
  4 +#
  5 +# 新增场景:复制一段 jdy-risk.scenarios[n].xxx,n 递增,按场景类型填字段:
  6 +# type=scenario1:全量,满足 总计>=5 且 差值>=1 且 flowState=in-progress-state
  7 +# 需填 total-field / diff-field / in-progress-state
  8 +# type=scenario2:当月,按 group-field 分组,SI数量/问题数量合计>60% 且 合计>=5 的分组数
  9 +# 需填 date-field / group-field / si-field / qty-field / month-only
  10 +# type=scenario3:当月,SI占比>60% 且 总问题数>=5 的行数
  11 +# 需填 date-field / total-field / ratio-field / month-only
  12 +# 每个场景的 sync-code 对应启效目标记录的 syncCode,统计结果写入 qx.count-field 字段。
  13 +# =============================================================================
  14 +
  15 +# ---------- 简道云(长安) ----------
  16 +jdy-risk.host=https://jdy.changan.com.cn/api
  17 +jdy-risk.api-key=lOnr4ms8jfc0gbCwVYS7YtbYQXjBFq979Cc06BcC866427b2a7aAd054598Bc7bB
  18 +
  19 +# ---------- 启效(QX) 写回目标 ----------
  20 +jdy-risk.qx.base-url=https://hfca.uat3.qgutech.com
  21 +jdy-risk.qx.username=15077901670
  22 +jdy-risk.qx.password=000000
  23 +jdy-risk.qx.corp-code=hfca
  24 +jdy-risk.qx.app-id=sEOSZ8EPwdrzJB41amD
  25 +jdy-risk.qx.query-code=ilr3ne7bPage
  26 +jdy-risk.qx.sync-query-param=pcqqjoquery
  27 +jdy-risk.qx.update-code=11a41Update
  28 +jdy-risk.qx.count-field=chcbxt
  29 +jdy-risk.qx.attach-field=hciwkz
  30 +
  31 +# ---------- 场景1:3mis 风险监控(全量) ----------
  32 +jdy-risk.scenarios[0].id=count_1
  33 +jdy-risk.scenarios[0].name=3mis风险监控
  34 +jdy-risk.scenarios[0].type=scenario1
  35 +jdy-risk.scenarios[0].sync-code=SYNC0001
  36 +jdy-risk.scenarios[0].app-id=65fd5c0e0d1f1a7ae4f038ec
  37 +jdy-risk.scenarios[0].entry-id=696f1754f141344a6b794f9c
  38 +jdy-risk.scenarios[0].total-field=_widget_1768888148020
  39 +jdy-risk.scenarios[0].diff-field=_widget_1768888148019
  40 +jdy-risk.scenarios[0].in-progress-state=0
  41 +jdy-risk.scenarios[0].month-only=false
  42 +
  43 +# ---------- 场景2:供应商 SI 占比风险监控(当月,按供应商分组) ----------
  44 +jdy-risk.scenarios[1].id=count_2
  45 +jdy-risk.scenarios[1].name=供应商SI占比风险监控
  46 +jdy-risk.scenarios[1].type=scenario2
  47 +jdy-risk.scenarios[1].sync-code=SYNC0002
  48 +jdy-risk.scenarios[1].app-id=65f8060f8666b8a5d1b98d57
  49 +jdy-risk.scenarios[1].entry-id=6a03dd3386f7148aadb98990
  50 +jdy-risk.scenarios[1].date-field=_widget_1778638131411
  51 +jdy-risk.scenarios[1].group-field=_widget_1778638131431
  52 +jdy-risk.scenarios[1].si-field=_widget_1778638131430
  53 +jdy-risk.scenarios[1].qty-field=_widget_1778638131418
  54 +jdy-risk.scenarios[1].month-only=true
  55 +
  56 +# ---------- 场景3:工程师 SI 占比风险监控(当月) ----------
  57 +jdy-risk.scenarios[2].id=count_3
  58 +jdy-risk.scenarios[2].name=工程师SI占比风险监控
  59 +jdy-risk.scenarios[2].type=scenario3
  60 +jdy-risk.scenarios[2].sync-code=SYNC0003
  61 +jdy-risk.scenarios[2].app-id=65f8060f8666b8a5d1b98d57
  62 +jdy-risk.scenarios[2].entry-id=6a193f03e88046f554dc10bc
  63 +jdy-risk.scenarios[2].date-field=_widget_1780039427416
  64 +jdy-risk.scenarios[2].total-field=_widget_1780039427422
  65 +jdy-risk.scenarios[2].ratio-field=_widget_1780039778663
  66 +jdy-risk.scenarios[2].month-only=true
  67 +jdy-risk.scenarios[2].extra-field=_widget_1780039427417
  68 +
  69 +# ---------- 场景4:CR导出-按供应商(升级不含QR/空白,当季度) ----------
  70 +jdy-risk.scenarios[3].id=count_4
  71 +jdy-risk.scenarios[3].name=供应商升级风险监控
  72 +jdy-risk.scenarios[3].type=scenario4
  73 +jdy-risk.scenarios[3].sync-code=SYNC0004
  74 +jdy-risk.scenarios[3].app-id=65f8060f8666b8a5d1b98d57
  75 +jdy-risk.scenarios[3].entry-id=6875b1ed729e8f4038955c62
  76 +jdy-risk.scenarios[3].date-field=_widget_1752543725802
  77 +jdy-risk.scenarios[3].group-field=_widget_1752543725816
  78 +jdy-risk.scenarios[3].up-field=_widget_1752543725813
  79 +jdy-risk.scenarios[3].exclude-values[0]=QR
  80 +jdy-risk.scenarios[3].min-count=3
  81 +jdy-risk.scenarios[3].quarter-only=true
  82 +
  83 +# ---------- 场景5:CR导出-按IQ工程师(升级不含QR/空白,当季度) ----------
  84 +jdy-risk.scenarios[4].id=count_5
  85 +jdy-risk.scenarios[4].name=工程师升级风险监控
  86 +jdy-risk.scenarios[4].type=scenario5
  87 +jdy-risk.scenarios[4].sync-code=SYNC0005
  88 +jdy-risk.scenarios[4].app-id=65f8060f8666b8a5d1b98d57
  89 +jdy-risk.scenarios[4].entry-id=6875b1ed729e8f4038955c62
  90 +jdy-risk.scenarios[4].date-field=_widget_1752543725802
  91 +jdy-risk.scenarios[4].group-field=_widget_1752543725822
  92 +jdy-risk.scenarios[4].up-field=_widget_1752543725813
  93 +jdy-risk.scenarios[4].exclude-values[0]=QR
  94 +jdy-risk.scenarios[4].min-count=3
  95 +jdy-risk.scenarios[4].quarter-only=true
  96 +
  97 +# ---------- 场景6:三包索赔申诉台账-经销商(当年,次数>=3) ----------
  98 +jdy-risk.scenarios[5].id=count_6
  99 +jdy-risk.scenarios[5].name=经销商三包索赔风险监控
  100 +jdy-risk.scenarios[5].type=scenario6
  101 +jdy-risk.scenarios[5].sync-code=SYNC0007
  102 +jdy-risk.scenarios[5].app-id=65f8060f8666b8a5d1b98d57
  103 +jdy-risk.scenarios[5].entry-id=688336be2fbf78b3d44d7174
  104 +jdy-risk.scenarios[5].date-field=_widget_1753429694910
  105 +jdy-risk.scenarios[5].group-field=_widget_1753429694911
  106 +jdy-risk.scenarios[5].min-count=3
  107 +jdy-risk.scenarios[5].year-only=true
  108 +
  109 +# ---------- 场景7:三包库房进库-超期未处理(180天,排除已出库/已抵扣) ----------
  110 +jdy-risk.scenarios[6].id=count_7
  111 +jdy-risk.scenarios[6].name=三包库房超期未处理风险监控
  112 +jdy-risk.scenarios[6].type=scenario7
  113 +jdy-risk.scenarios[6].sync-code=SYNC0008
  114 +jdy-risk.scenarios[6].app-id=65f8060f8666b8a5d1b98d57
  115 +jdy-risk.scenarios[6].entry-id=686b6f72fcb3f02a8ffc8fcd
  116 +jdy-risk.scenarios[6].barcode-field=_widget_1751871346824
  117 +jdy-risk.scenarios[6].date-field=_widget_1751871346820
  118 +jdy-risk.scenarios[6].max-age-days=180
  119 +# 主表只取这几列(经销商代码/经销商名称/入库时间/条码),减小传输
  120 +jdy-risk.scenarios[6].fields[0]=_widget_1751871346816
  121 +jdy-risk.scenarios[6].fields[1]=_widget_1751871346817
  122 +jdy-risk.scenarios[6].fields[2]=_widget_1751871346820
  123 +jdy-risk.scenarios[6].fields[3]=_widget_1751871346824
  124 +jdy-risk.scenarios[6].exclude-forms[0].entry-id=686b6fd1e3cdf473acade9ac
  125 +jdy-risk.scenarios[6].exclude-forms[0].barcode-field=_widget_1751871441626
  126 +jdy-risk.scenarios[6].exclude-forms[1].entry-id=686b781c11159446bb2583fc
  127 +jdy-risk.scenarios[6].exclude-forms[1].barcode-field=_widget_1751873565337
  128 +
  129 +# ---------- 场景8:料废登记台账-供应商(上月,未开CR占比>70%) ----------
  130 +jdy-risk.scenarios[7].id=count_8
  131 +jdy-risk.scenarios[7].name=供应商未开CR风险监控
  132 +jdy-risk.scenarios[7].type=scenario8
  133 +jdy-risk.scenarios[7].sync-code=SYNC0010
  134 +jdy-risk.scenarios[7].app-id=65f8060f8666b8a5d1b98d57
  135 +jdy-risk.scenarios[7].entry-id=69676b83f96b846da4443c42
  136 +jdy-risk.scenarios[7].date-field=_widget_1768385411429
  137 +jdy-risk.scenarios[7].group-field=_widget_1783921957534
  138 +jdy-risk.scenarios[7].flag-field=_widget_1769502015250
  139 +jdy-risk.scenarios[7].flag-value=\u5426
  140 +jdy-risk.scenarios[7].ratio-threshold=0.7
  141 +jdy-risk.scenarios[7].prev-month-only=true
  142 +
  143 +# ---------- 场景9:料废登记台账-工程师(上月,未开CR占比>70%) ----------
  144 +jdy-risk.scenarios[8].id=count_9
  145 +jdy-risk.scenarios[8].name=工程师未开CR风险监控
  146 +jdy-risk.scenarios[8].type=scenario9
  147 +jdy-risk.scenarios[8].sync-code=SYNC0011
  148 +jdy-risk.scenarios[8].app-id=65f8060f8666b8a5d1b98d57
  149 +jdy-risk.scenarios[8].entry-id=69676b83f96b846da4443c42
  150 +jdy-risk.scenarios[8].date-field=_widget_1768385411429
  151 +jdy-risk.scenarios[8].group-field=_widget_1769498221213
  152 +jdy-risk.scenarios[8].flag-field=_widget_1769502015250
  153 +jdy-risk.scenarios[8].flag-value=\u5426
  154 +jdy-risk.scenarios[8].ratio-threshold=0.7
  155 +jdy-risk.scenarios[8].prev-month-only=true
  156 +
  157 +# =============================================================================
  158 +# 表单同步配置(简道云表单结构/数据 -> 启效指定应用)
  159 +# 结构同步接口:POST /api/jdy/form/sync-structure
  160 +# 数据同步接口:POST /api/jdy/form/sync-data(当月数据,当天已存在则先删当天再同步)
  161 +# 新增表单:复制一段 jdy-form-sync.forms[n].xxx,n 递增
  162 +# =============================================================================
  163 +jdy-form-sync.jdy.host=https://jdy.changan.com.cn/api
  164 +jdy-form-sync.jdy.api-key=lOnr4ms8jfc0gbCwVYS7YtbYQXjBFq979Cc06BcC866427b2a7aAd054598Bc7bB
  165 +# 可选:指定同步月份(yyyy-MM)用于补数/测试;留空=当前自然月(仅 month-only=true 时生效)
  166 +# jdy-form-sync.month=2026-08
  167 +# Excel 导出目录(相对 jar 运行目录)
  168 +jdy-form-sync.export-dir=./export
  169 +
  170 +jdy-form-sync.qx.base-url=https://hfca.uat3.qgutech.com
  171 +jdy-form-sync.qx.username=15077901670
  172 +jdy-form-sync.qx.password=000000
  173 +jdy-form-sync.qx.corp-code=hfca
  174 +jdy-form-sync.qx.app-id=sEOSZ8EPwdrzJB41amD
  175 +jdy-form-sync.qx.app-name=风险预警平台
  176 +
  177 +# 待同步表单:3mis争议件大于确定件(合肥长安_技术处)
  178 +# 注意:表单名默认从简道云接口取(避免 .properties 的 ISO-8859-1 中文乱码),此处不写中文名
  179 +jdy-form-sync.forms[0].app-id=65fd5c0e0d1f1a7ae4f038ec
  180 +jdy-form-sync.forms[0].entry-id=696f1754f141344a6b794f9c
  181 +jdy-form-sync.forms[0].fun-code=misDispute
  182 +# 已有模型 id:填了则原地更新(不新建)。首次同步可留空
  183 +jdy-form-sync.forms[0].model-id=P1Vgt89QvFStKh7rDzl
  184 +# 日期字段(用于「当月」过滤):简道云 日期时间
  185 +jdy-form-sync.forms[0].date-field=_widget_1773622123700
  186 +# 是否只同步当月;false=同步全部数据(本表单改为全量)
  187 +jdy-form-sync.forms[0].month-only=false
  188 +
... ...
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
  1 +2026-09-16 10:25:30.680 INFO 7456 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Starting QxApaasSyncApplication v1.0.0-SNAPSHOT on CQCA7304093 with PID 7456 (D:\code\qx-apaas-sync\target\qx-apaas-sync-1.0.0-SNAPSHOT.jar started by Administrator in D:\code\qx-apaas-sync)
  2 +2026-09-16 10:25:30.777 INFO 7456 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : No active profile set, falling back to default profiles: default
  3 +2026-09-16 10:25:30.837 INFO 7456 --- [main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@7907ec20: startup date [Wed Sep 16 10:25:30 CST 2026]; root of context hierarchy
  4 +2026-09-16 10:25:32.569 INFO 7456 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8090 (http)
  5 +2026-09-16 10:25:32.617 INFO 7456 --- [main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
  6 +2026-09-16 10:25:32.618 INFO 7456 --- [main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.39
  7 +2026-09-16 10:25:32.635 INFO 7456 --- [localhost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\nodejs\;D:\apache-maven-3.5.3\bin;C:\mysql\mysql-8.4.9-winx64\bin;C:\Program Files\Git\cmd;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\AppData\Roaming\npm;C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\bin;.]
  8 +2026-09-16 10:25:32.751 INFO 7456 --- [localhost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
  9 +2026-09-16 10:25:32.752 INFO 7456 --- [localhost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1916 ms
  10 +2026-09-16 10:25:32.848 INFO 7456 --- [localhost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
  11 +2026-09-16 10:25:32.854 INFO 7456 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
  12 +2026-09-16 10:25:32.855 INFO 7456 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
  13 +2026-09-16 10:25:32.855 INFO 7456 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
  14 +2026-09-16 10:25:32.856 INFO 7456 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
  15 +2026-09-16 10:25:33.130 INFO 7456 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  16 +2026-09-16 10:25:33.429 INFO 7456 --- [main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@7907ec20: startup date [Wed Sep 16 10:25:30 CST 2026]; root of context hierarchy
  17 +2026-09-16 10:25:33.662 INFO 7456 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.count()
  18 +2026-09-16 10:25:33.664 INFO 7456 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.sync()
  19 +2026-09-16 10:25:33.665 INFO 7456 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countGet()
  20 +2026-09-16 10:25:33.666 INFO 7456 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncGet()
  21 +2026-09-16 10:25:33.670 INFO 7456 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcel()
  22 +2026-09-16 10:25:33.671 INFO 7456 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-data],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncData()
  23 +2026-09-16 10:25:33.672 INFO 7456 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel-form],methods=[POST]}" onto public java.lang.String com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcelForm(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)
  24 +2026-09-16 10:25:33.675 INFO 7456 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-structure],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncStructure()
  25 +2026-09-16 10:25:33.677 INFO 7456 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/all],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncAll()
  26 +2026-09-16 10:25:33.678 INFO 7456 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/{appName}],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncOne(java.lang.String)
  27 +2026-09-16 10:25:33.682 INFO 7456 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
  28 +2026-09-16 10:25:33.684 INFO 7456 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
  29 +2026-09-16 10:25:33.724 INFO 7456 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  30 +2026-09-16 10:25:33.725 INFO 7456 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  31 +2026-09-16 10:25:33.914 INFO 7456 --- [main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
  32 +2026-09-16 10:25:33.932 INFO 7456 --- [main] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
  33 +2026-09-16 10:25:34.024 INFO 7456 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8090 (http) with context path ''
  34 +2026-09-16 10:25:34.028 INFO 7456 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Started QxApaasSyncApplication in 4.597 seconds (JVM running for 5.29)
  35 +2026-09-16 10:25:56.811 INFO 7456 --- [http-nio-8090-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
  36 +2026-09-16 10:25:56.813 INFO 7456 --- [http-nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
  37 +2026-09-16 10:25:56.842 INFO 7456 --- [http-nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 29 ms
  38 +2026-09-16 10:25:58.044 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65fd5c0e0d1f1a7ae4f038ec entry=696f1754f141344a6b794f9c 第 1 页 14 条, 累计 14 条
  39 +2026-09-16 10:25:58.045 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65fd5c0e0d1f1a7ae4f038ec entry=696f1754f141344a6b794f9c 共 14 条
  40 +2026-09-16 10:25:58.245 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 1 页 100 条, 累计 100 条
  41 +2026-09-16 10:25:58.417 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 2 页 100 条, 累计 200 条
  42 +2026-09-16 10:25:58.530 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 3 页 100 条, 累计 300 条
  43 +2026-09-16 10:25:58.666 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 4 页 100 条, 累计 400 条
  44 +2026-09-16 10:25:58.893 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 5 页 100 条, 累计 500 条
  45 +2026-09-16 10:25:59.033 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 6 页 100 条, 累计 600 条
  46 +2026-09-16 10:25:59.179 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 7 页 100 条, 累计 700 条
  47 +2026-09-16 10:25:59.327 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 8 页 100 条, 累计 800 条
  48 +2026-09-16 10:25:59.458 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 9 页 100 条, 累计 900 条
  49 +2026-09-16 10:25:59.636 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 10 页 100 条, 累计 1000 条
  50 +2026-09-16 10:25:59.848 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 11 页 100 条, 累计 1100 条
  51 +2026-09-16 10:25:59.972 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 12 页 100 条, 累计 1200 条
  52 +2026-09-16 10:26:00.140 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 13 页 100 条, 累计 1300 条
  53 +2026-09-16 10:26:00.373 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 14 页 100 条, 累计 1400 条
  54 +2026-09-16 10:26:00.498 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 15 页 100 条, 累计 1500 条
  55 +2026-09-16 10:26:00.640 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 16 页 100 条, 累计 1600 条
  56 +2026-09-16 10:26:00.817 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 17 页 100 条, 累计 1700 条
  57 +2026-09-16 10:26:01.065 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 18 页 100 条, 累计 1800 条
  58 +2026-09-16 10:26:01.295 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 19 页 100 条, 累计 1900 条
  59 +2026-09-16 10:26:01.676 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 20 页 100 条, 累计 2000 条
  60 +2026-09-16 10:26:01.832 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 21 页 100 条, 累计 2100 条
  61 +2026-09-16 10:26:01.953 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 22 页 100 条, 累计 2200 条
  62 +2026-09-16 10:26:02.086 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 23 页 100 条, 累计 2300 条
  63 +2026-09-16 10:26:02.310 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 24 页 45 条, 累计 2345 条
  64 +2026-09-16 10:26:02.312 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 共 2345 条
  65 +2026-09-16 10:26:02.541 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a193f03e88046f554dc10bc 第 1 页 100 条, 累计 100 条
  66 +2026-09-16 10:26:02.604 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a193f03e88046f554dc10bc 第 2 页 31 条, 累计 131 条
  67 +2026-09-16 10:26:02.606 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=6a193f03e88046f554dc10bc 共 131 条
  68 +2026-09-16 10:26:02.857 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 1 页 100 条, 累计 100 条
  69 +2026-09-16 10:26:03.096 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 2 页 100 条, 累计 200 条
  70 +2026-09-16 10:26:03.238 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 3 页 100 条, 累计 300 条
  71 +2026-09-16 10:26:04.153 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 4 页 100 条, 累计 400 条
  72 +2026-09-16 10:26:04.337 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 5 页 100 条, 累计 500 条
  73 +2026-09-16 10:26:04.628 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 6 页 100 条, 累计 600 条
  74 +2026-09-16 10:26:04.845 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 7 页 100 条, 累计 700 条
  75 +2026-09-16 10:26:04.995 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 8 页 100 条, 累计 800 条
  76 +2026-09-16 10:26:05.251 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 9 页 100 条, 累计 900 条
  77 +2026-09-16 10:26:05.436 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 10 页 100 条, 累计 1000 条
  78 +2026-09-16 10:26:05.601 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 11 页 100 条, 累计 1100 条
  79 +2026-09-16 10:26:05.746 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 12 页 100 条, 累计 1200 条
  80 +2026-09-16 10:26:06.014 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 13 页 100 条, 累计 1300 条
  81 +2026-09-16 10:26:06.141 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 14 页 100 条, 累计 1400 条
  82 +2026-09-16 10:26:06.312 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 15 页 100 条, 累计 1500 条
  83 +2026-09-16 10:26:06.487 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 16 页 100 条, 累计 1600 条
  84 +2026-09-16 10:26:06.704 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 17 页 100 条, 累计 1700 条
  85 +2026-09-16 10:26:06.908 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 18 页 100 条, 累计 1800 条
  86 +2026-09-16 10:26:07.181 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 19 页 100 条, 累计 1900 条
  87 +2026-09-16 10:26:08.401 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 20 页 100 条, 累计 2000 条
  88 +2026-09-16 10:26:08.580 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 21 页 100 条, 累计 2100 条
  89 +2026-09-16 10:26:08.871 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 22 页 100 条, 累计 2200 条
  90 +2026-09-16 10:26:09.016 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 23 页 100 条, 累计 2300 条
  91 +2026-09-16 10:26:09.266 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 24 页 100 条, 累计 2400 条
  92 +2026-09-16 10:26:09.403 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 25 页 100 条, 累计 2500 条
  93 +2026-09-16 10:26:09.633 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 26 页 100 条, 累计 2600 条
  94 +2026-09-16 10:26:09.751 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 27 页 100 条, 累计 2700 条
  95 +2026-09-16 10:26:10.676 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 28 页 100 条, 累计 2800 条
  96 +2026-09-16 10:26:10.806 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 29 页 100 条, 累计 2900 条
  97 +2026-09-16 10:26:11.093 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 30 页 100 条, 累计 3000 条
  98 +2026-09-16 10:26:11.249 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 31 页 100 条, 累计 3100 条
  99 +2026-09-16 10:26:11.382 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 32 页 100 条, 累计 3200 条
  100 +2026-09-16 10:26:11.524 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 33 页 100 条, 累计 3300 条
  101 +2026-09-16 10:26:11.678 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 34 页 100 条, 累计 3400 条
  102 +2026-09-16 10:26:11.871 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 35 页 100 条, 累计 3500 条
  103 +2026-09-16 10:26:12.010 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 36 页 100 条, 累计 3600 条
  104 +2026-09-16 10:26:13.243 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 37 页 100 条, 累计 3700 条
  105 +2026-09-16 10:26:13.448 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 38 页 100 条, 累计 3800 条
  106 +2026-09-16 10:26:13.590 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 39 页 55 条, 累计 3855 条
  107 +2026-09-16 10:26:13.591 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 共 3855 条
  108 +2026-09-16 10:26:13.832 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 1 页 100 条, 累计 100 条
  109 +2026-09-16 10:26:14.072 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 2 页 100 条, 累计 200 条
  110 +2026-09-16 10:26:14.210 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 3 页 100 条, 累计 300 条
  111 +2026-09-16 10:26:14.345 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 4 页 100 条, 累计 400 条
  112 +2026-09-16 10:26:14.458 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 5 页 100 条, 累计 500 条
  113 +2026-09-16 10:26:14.633 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 6 页 100 条, 累计 600 条
  114 +2026-09-16 10:26:14.746 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 7 页 100 条, 累计 700 条
  115 +2026-09-16 10:26:14.936 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 8 页 100 条, 累计 800 条
  116 +2026-09-16 10:26:15.111 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 9 页 100 条, 累计 900 条
  117 +2026-09-16 10:26:15.331 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 10 页 100 条, 累计 1000 条
  118 +2026-09-16 10:26:15.460 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 11 页 100 条, 累计 1100 条
  119 +2026-09-16 10:26:15.568 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 12 页 100 条, 累计 1200 条
  120 +2026-09-16 10:26:15.778 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 13 页 100 条, 累计 1300 条
  121 +2026-09-16 10:26:15.950 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 14 页 100 条, 累计 1400 条
  122 +2026-09-16 10:26:16.083 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 15 页 100 条, 累计 1500 条
  123 +2026-09-16 10:26:16.259 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 16 页 100 条, 累计 1600 条
  124 +2026-09-16 10:26:16.379 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 17 页 100 条, 累计 1700 条
  125 +2026-09-16 10:26:16.495 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 18 页 100 条, 累计 1800 条
  126 +2026-09-16 10:26:16.616 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 19 页 100 条, 累计 1900 条
  127 +2026-09-16 10:26:16.785 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 20 页 100 条, 累计 2000 条
  128 +2026-09-16 10:26:16.899 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 21 页 100 条, 累计 2100 条
  129 +2026-09-16 10:26:17.643 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 22 页 100 条, 累计 2200 条
  130 +2026-09-16 10:26:17.764 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 23 页 100 条, 累计 2300 条
  131 +2026-09-16 10:26:18.111 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 24 页 100 条, 累计 2400 条
  132 +2026-09-16 10:26:18.222 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 25 页 100 条, 累计 2500 条
  133 +2026-09-16 10:26:18.359 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 26 页 100 条, 累计 2600 条
  134 +2026-09-16 10:26:18.539 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 27 页 100 条, 累计 2700 条
  135 +2026-09-16 10:26:18.658 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 28 页 100 条, 累计 2800 条
  136 +2026-09-16 10:26:18.847 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 29 页 100 条, 累计 2900 条
  137 +2026-09-16 10:26:19.055 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 30 页 100 条, 累计 3000 条
  138 +2026-09-16 10:26:19.284 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 31 页 100 条, 累计 3100 条
  139 +2026-09-16 10:26:19.435 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 32 页 100 条, 累计 3200 条
  140 +2026-09-16 10:26:19.708 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 33 页 100 条, 累计 3300 条
  141 +2026-09-16 10:26:19.832 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 34 页 100 条, 累计 3400 条
  142 +2026-09-16 10:26:19.999 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 35 页 100 条, 累计 3500 条
  143 +2026-09-16 10:26:20.178 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 36 页 100 条, 累计 3600 条
  144 +2026-09-16 10:26:20.284 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 37 页 100 条, 累计 3700 条
  145 +2026-09-16 10:26:20.525 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 38 页 100 条, 累计 3800 条
  146 +2026-09-16 10:26:20.616 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 39 页 55 条, 累计 3855 条
  147 +2026-09-16 10:26:20.617 INFO 7456 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 共 3855 条
  148 +2026-09-16 10:36:37.787 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : ========== 开始风险场景统计并写回启效 ==========
  149 +2026-09-16 10:36:38.363 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 启效登录成功: https://hfca.uat3.qgutech.com (corpCode=hfca, user=15077901670)
  150 +2026-09-16 10:36:38.873 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 启效记录总数=48(按 syncCode 本地匹配)
  151 +2026-09-16 10:36:39.030 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65fd5c0e0d1f1a7ae4f038ec entry=696f1754f141344a6b794f9c 第 1 页 14 条, 累计 14 条
  152 +2026-09-16 10:36:39.030 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65fd5c0e0d1f1a7ae4f038ec entry=696f1754f141344a6b794f9c 共 14 条
  153 +2026-09-16 10:36:39.031 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_1] 命中=0 (全量14条 -> 周期内14条)
  154 +2026-09-16 10:36:39.774 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyExcelExportService : 导出 Excel: D:\code\qx-apaas-sync\.\export\20260916103639.xlsx (14 条)
  155 +2026-09-16 10:36:40.581 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 文件上传成功: 20260916103639.xlsx -> fileId=8203325050259456
  156 +2026-09-16 10:36:40.584 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新业务数据: 11a41Update id=HZgohhpJ4e3KUR4yf1b
  157 +2026-09-16 10:36:41.056 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新成功: id=HZgohhpJ4e3KUR4yf1b
  158 +2026-09-16 10:36:41.057 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 写回成功: syncCode=SYNC0001 id=HZgohhpJ4e3KUR4yf1b chcbxt=0 附件=20260916103639.xlsx
  159 +2026-09-16 10:36:41.204 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 1 页 100 条, 累计 100 条
  160 +2026-09-16 10:36:41.340 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 2 页 100 条, 累计 200 条
  161 +2026-09-16 10:36:41.478 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 3 页 100 条, 累计 300 条
  162 +2026-09-16 10:36:41.620 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 4 页 100 条, 累计 400 条
  163 +2026-09-16 10:36:41.751 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 5 页 100 条, 累计 500 条
  164 +2026-09-16 10:36:41.891 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 6 页 100 条, 累计 600 条
  165 +2026-09-16 10:36:42.064 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 7 页 100 条, 累计 700 条
  166 +2026-09-16 10:36:42.237 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 8 页 100 条, 累计 800 条
  167 +2026-09-16 10:36:42.370 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 9 页 100 条, 累计 900 条
  168 +2026-09-16 10:36:42.491 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 10 页 100 条, 累计 1000 条
  169 +2026-09-16 10:36:42.634 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 11 页 100 条, 累计 1100 条
  170 +2026-09-16 10:36:42.841 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 12 页 100 条, 累计 1200 条
  171 +2026-09-16 10:36:42.967 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 13 页 100 条, 累计 1300 条
  172 +2026-09-16 10:36:43.100 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 14 页 100 条, 累计 1400 条
  173 +2026-09-16 10:36:43.229 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 15 页 100 条, 累计 1500 条
  174 +2026-09-16 10:36:43.336 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 16 页 100 条, 累计 1600 条
  175 +2026-09-16 10:36:43.481 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 17 页 100 条, 累计 1700 条
  176 +2026-09-16 10:36:44.106 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 18 页 100 条, 累计 1800 条
  177 +2026-09-16 10:36:44.298 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 19 页 100 条, 累计 1900 条
  178 +2026-09-16 10:36:44.445 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 20 页 100 条, 累计 2000 条
  179 +2026-09-16 10:36:44.576 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 21 页 100 条, 累计 2100 条
  180 +2026-09-16 10:36:44.754 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 22 页 100 条, 累计 2200 条
  181 +2026-09-16 10:36:44.956 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 23 页 100 条, 累计 2300 条
  182 +2026-09-16 10:36:45.058 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 24 页 45 条, 累计 2345 条
  183 +2026-09-16 10:36:45.059 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 共 2345 条
  184 +2026-09-16 10:36:45.097 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_2] 命中=3 (全量2345条 -> 周期内61条)
  185 +2026-09-16 10:36:45.448 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyExcelExportService : 导出 Excel: D:\code\qx-apaas-sync\.\export\20260916103645.xlsx (61 条)
  186 +2026-09-16 10:36:46.049 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 文件上传成功: 20260916103645.xlsx -> fileId=8203325139830784
  187 +2026-09-16 10:36:46.050 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新业务数据: 11a41Update id=zdoFcKVlaCqnNJEohAb
  188 +2026-09-16 10:36:46.497 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新成功: id=zdoFcKVlaCqnNJEohAb
  189 +2026-09-16 10:36:46.498 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 写回成功: syncCode=SYNC0002 id=zdoFcKVlaCqnNJEohAb chcbxt=3 附件=20260916103645.xlsx
  190 +2026-09-16 10:36:46.714 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a193f03e88046f554dc10bc 第 1 页 100 条, 累计 100 条
  191 +2026-09-16 10:36:46.795 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a193f03e88046f554dc10bc 第 2 页 31 条, 累计 131 条
  192 +2026-09-16 10:36:46.797 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=6a193f03e88046f554dc10bc 共 131 条
  193 +2026-09-16 10:36:46.799 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_3] 命中=1 (全量131条 -> 周期内10条)
  194 +2026-09-16 10:36:46.908 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyExcelExportService : 导出 Excel: D:\code\qx-apaas-sync\.\export\20260916103646.xlsx (10 条)
  195 +2026-09-16 10:36:47.475 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 文件上传成功: 20260916103646.xlsx -> fileId=8203325163309056
  196 +2026-09-16 10:36:47.476 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新业务数据: 11a41Update id=zK0oiCddbZeyCPSgRVF
  197 +2026-09-16 10:36:47.819 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新成功: id=zK0oiCddbZeyCPSgRVF
  198 +2026-09-16 10:36:47.820 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 写回成功: syncCode=SYNC0003 id=zK0oiCddbZeyCPSgRVF chcbxt=1 附件=20260916103646.xlsx
  199 +2026-09-16 10:36:47.968 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 1 页 100 条, 累计 100 条
  200 +2026-09-16 10:36:48.104 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 2 页 100 条, 累计 200 条
  201 +2026-09-16 10:36:49.066 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 3 页 100 条, 累计 300 条
  202 +2026-09-16 10:36:49.197 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 4 页 100 条, 累计 400 条
  203 +2026-09-16 10:36:49.320 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 5 页 100 条, 累计 500 条
  204 +2026-09-16 10:36:49.439 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 6 页 100 条, 累计 600 条
  205 +2026-09-16 10:36:49.643 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 7 页 100 条, 累计 700 条
  206 +2026-09-16 10:36:49.870 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 8 页 100 条, 累计 800 条
  207 +2026-09-16 10:36:49.995 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 9 页 100 条, 累计 900 条
  208 +2026-09-16 10:36:50.241 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 10 页 100 条, 累计 1000 条
  209 +2026-09-16 10:36:50.441 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 11 页 100 条, 累计 1100 条
  210 +2026-09-16 10:36:50.607 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 12 页 100 条, 累计 1200 条
  211 +2026-09-16 10:36:50.858 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 13 页 100 条, 累计 1300 条
  212 +2026-09-16 10:36:51.037 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 14 页 100 条, 累计 1400 条
  213 +2026-09-16 10:36:51.205 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 15 页 100 条, 累计 1500 条
  214 +2026-09-16 10:36:51.364 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 16 页 100 条, 累计 1600 条
  215 +2026-09-16 10:36:51.512 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 17 页 100 条, 累计 1700 条
  216 +2026-09-16 10:36:51.743 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 18 页 100 条, 累计 1800 条
  217 +2026-09-16 10:36:51.927 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 19 页 100 条, 累计 1900 条
  218 +2026-09-16 10:36:52.074 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 20 页 100 条, 累计 2000 条
  219 +2026-09-16 10:36:52.206 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 21 页 100 条, 累计 2100 条
  220 +2026-09-16 10:36:52.336 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 22 页 100 条, 累计 2200 条
  221 +2026-09-16 10:36:52.449 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 23 页 100 条, 累计 2300 条
  222 +2026-09-16 10:36:52.628 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 24 页 100 条, 累计 2400 条
  223 +2026-09-16 10:36:52.751 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 25 页 100 条, 累计 2500 条
  224 +2026-09-16 10:36:52.974 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 26 页 100 条, 累计 2600 条
  225 +2026-09-16 10:36:53.118 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 27 页 100 条, 累计 2700 条
  226 +2026-09-16 10:36:53.296 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 28 页 100 条, 累计 2800 条
  227 +2026-09-16 10:36:53.423 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 29 页 100 条, 累计 2900 条
  228 +2026-09-16 10:36:53.578 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 30 页 100 条, 累计 3000 条
  229 +2026-09-16 10:36:53.784 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 31 页 100 条, 累计 3100 条
  230 +2026-09-16 10:36:53.938 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 32 页 100 条, 累计 3200 条
  231 +2026-09-16 10:36:54.080 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 33 页 100 条, 累计 3300 条
  232 +2026-09-16 10:36:54.289 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 34 页 100 条, 累计 3400 条
  233 +2026-09-16 10:36:54.449 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 35 页 100 条, 累计 3500 条
  234 +2026-09-16 10:36:54.589 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 36 页 100 条, 累计 3600 条
  235 +2026-09-16 10:36:54.763 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 37 页 100 条, 累计 3700 条
  236 +2026-09-16 10:36:54.934 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 38 页 100 条, 累计 3800 条
  237 +2026-09-16 10:36:55.103 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 39 页 55 条, 累计 3855 条
  238 +2026-09-16 10:36:55.104 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 共 3855 条
  239 +2026-09-16 10:36:55.133 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_4] 命中=0 (全量3855条 -> 周期内188条)
  240 +2026-09-16 10:36:55.733 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyExcelExportService : 导出 Excel: D:\code\qx-apaas-sync\.\export\20260916103655.xlsx (188 条)
  241 +2026-09-16 10:36:56.377 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 文件上传成功: 20260916103655.xlsx -> fileId=8203325309061120
  242 +2026-09-16 10:36:56.379 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新业务数据: 11a41Update id=NoDnb3xksxFcaqDO265
  243 +2026-09-16 10:36:56.840 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新成功: id=NoDnb3xksxFcaqDO265
  244 +2026-09-16 10:36:56.846 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 写回成功: syncCode=SYNC0004 id=NoDnb3xksxFcaqDO265 chcbxt=0 附件=20260916103655.xlsx
  245 +2026-09-16 10:36:56.974 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 1 页 100 条, 累计 100 条
  246 +2026-09-16 10:36:57.105 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 2 页 100 条, 累计 200 条
  247 +2026-09-16 10:36:57.225 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 3 页 100 条, 累计 300 条
  248 +2026-09-16 10:36:57.433 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 4 页 100 条, 累计 400 条
  249 +2026-09-16 10:36:58.218 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 5 页 100 条, 累计 500 条
  250 +2026-09-16 10:36:58.524 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 6 页 100 条, 累计 600 条
  251 +2026-09-16 10:36:58.661 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 7 页 100 条, 累计 700 条
  252 +2026-09-16 10:36:58.789 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 8 页 100 条, 累计 800 条
  253 +2026-09-16 10:36:58.935 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 9 页 100 条, 累计 900 条
  254 +2026-09-16 10:36:59.077 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 10 页 100 条, 累计 1000 条
  255 +2026-09-16 10:36:59.205 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 11 页 100 条, 累计 1100 条
  256 +2026-09-16 10:36:59.333 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 12 页 100 条, 累计 1200 条
  257 +2026-09-16 10:36:59.453 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 13 页 100 条, 累计 1300 条
  258 +2026-09-16 10:36:59.599 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 14 页 100 条, 累计 1400 条
  259 +2026-09-16 10:36:59.776 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 15 页 100 条, 累计 1500 条
  260 +2026-09-16 10:36:59.907 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 16 页 100 条, 累计 1600 条
  261 +2026-09-16 10:37:00.067 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 17 页 100 条, 累计 1700 条
  262 +2026-09-16 10:37:00.339 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 18 页 100 条, 累计 1800 条
  263 +2026-09-16 10:37:00.499 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 19 页 100 条, 累计 1900 条
  264 +2026-09-16 10:37:00.636 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 20 页 100 条, 累计 2000 条
  265 +2026-09-16 10:37:00.783 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 21 页 100 条, 累计 2100 条
  266 +2026-09-16 10:37:00.933 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 22 页 100 条, 累计 2200 条
  267 +2026-09-16 10:37:01.164 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 23 页 100 条, 累计 2300 条
  268 +2026-09-16 10:37:01.303 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 24 页 100 条, 累计 2400 条
  269 +2026-09-16 10:37:01.499 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 25 页 100 条, 累计 2500 条
  270 +2026-09-16 10:37:01.640 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 26 页 100 条, 累计 2600 条
  271 +2026-09-16 10:37:01.778 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 27 页 100 条, 累计 2700 条
  272 +2026-09-16 10:37:01.954 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 28 页 100 条, 累计 2800 条
  273 +2026-09-16 10:37:05.100 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 29 页 100 条, 累计 2900 条
  274 +2026-09-16 10:37:05.333 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 30 页 100 条, 累计 3000 条
  275 +2026-09-16 10:37:05.444 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 31 页 100 条, 累计 3100 条
  276 +2026-09-16 10:37:05.639 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 32 页 100 条, 累计 3200 条
  277 +2026-09-16 10:37:05.817 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 33 页 100 条, 累计 3300 条
  278 +2026-09-16 10:37:06.053 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 34 页 100 条, 累计 3400 条
  279 +2026-09-16 10:37:06.898 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 35 页 100 条, 累计 3500 条
  280 +2026-09-16 10:37:07.023 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 36 页 100 条, 累计 3600 条
  281 +2026-09-16 10:37:07.190 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 37 页 100 条, 累计 3700 条
  282 +2026-09-16 10:37:07.397 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 38 页 100 条, 累计 3800 条
  283 +2026-09-16 10:37:07.502 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 39 页 55 条, 累计 3855 条
  284 +2026-09-16 10:37:07.504 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 共 3855 条
  285 +2026-09-16 10:37:07.520 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_5] 命中=1 (全量3855条 -> 周期内188条)
  286 +2026-09-16 10:37:07.951 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyExcelExportService : 导出 Excel: D:\code\qx-apaas-sync\.\export\20260916103707.xlsx (188 条)
  287 +2026-09-16 10:37:08.518 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 文件上传成功: 20260916103707.xlsx -> fileId=8203325508241408
  288 +2026-09-16 10:37:08.519 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新业务数据: 11a41Update id=0kr6DKOoQYXugmZbl05
  289 +2026-09-16 10:37:08.982 INFO 7456 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新成功: id=0kr6DKOoQYXugmZbl05
  290 +2026-09-16 10:37:08.983 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 写回成功: syncCode=SYNC0005 id=0kr6DKOoQYXugmZbl05 chcbxt=1 附件=20260916103707.xlsx
  291 +2026-09-16 10:37:09.000 INFO 7456 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : ========== 风险场景统计并写回完成 ==========
  292 +2026-09-16 18:09:38.793 INFO 3020 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Starting QxApaasSyncApplication v1.0.0-SNAPSHOT on CQCA7304093 with PID 3020 (D:\code\qx-apaas-sync\target\qx-apaas-sync-1.0.0-SNAPSHOT.jar started by Administrator in D:\code\qx-apaas-sync)
  293 +2026-09-16 18:09:38.832 INFO 3020 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : No active profile set, falling back to default profiles: default
  294 +2026-09-16 18:09:38.915 INFO 3020 --- [main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@3aa9e816: startup date [Wed Sep 16 18:09:38 CST 2026]; root of context hierarchy
  295 +2026-09-16 18:09:41.203 INFO 3020 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8090 (http)
  296 +2026-09-16 18:09:41.308 INFO 3020 --- [main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
  297 +2026-09-16 18:09:41.310 INFO 3020 --- [main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.39
  298 +2026-09-16 18:09:41.330 INFO 3020 --- [localhost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\nodejs\;D:\apache-maven-3.5.3\bin;C:\mysql\mysql-8.4.9-winx64\bin;C:\Program Files\Git\cmd;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\AppData\Roaming\npm;C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\bin;.]
  299 +2026-09-16 18:09:41.462 INFO 3020 --- [localhost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
  300 +2026-09-16 18:09:41.463 INFO 3020 --- [localhost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2548 ms
  301 +2026-09-16 18:09:41.582 INFO 3020 --- [localhost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
  302 +2026-09-16 18:09:41.588 INFO 3020 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
  303 +2026-09-16 18:09:41.589 INFO 3020 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
  304 +2026-09-16 18:09:41.589 INFO 3020 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
  305 +2026-09-16 18:09:41.590 INFO 3020 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
  306 +2026-09-16 18:09:41.947 INFO 3020 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  307 +2026-09-16 18:09:42.326 INFO 3020 --- [main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@3aa9e816: startup date [Wed Sep 16 18:09:38 CST 2026]; root of context hierarchy
  308 +2026-09-16 18:09:42.570 INFO 3020 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-structure],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncStructure()
  309 +2026-09-16 18:09:42.572 INFO 3020 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-data],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncData()
  310 +2026-09-16 18:09:42.573 INFO 3020 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcel()
  311 +2026-09-16 18:09:42.577 INFO 3020 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel-form],methods=[POST]}" onto public java.lang.String com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcelForm(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)
  312 +2026-09-16 18:09:42.591 INFO 3020 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/all],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncAll()
  313 +2026-09-16 18:09:42.593 INFO 3020 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/{appName}],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncOne(java.lang.String)
  314 +2026-09-16 18:09:42.600 INFO 3020 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.count()
  315 +2026-09-16 18:09:42.602 INFO 3020 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.sync()
  316 +2026-09-16 18:09:42.603 INFO 3020 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countGet()
  317 +2026-09-16 18:09:42.604 INFO 3020 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncGet()
  318 +2026-09-16 18:09:42.608 INFO 3020 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
  319 +2026-09-16 18:09:42.610 INFO 3020 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
  320 +2026-09-16 18:09:42.653 INFO 3020 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  321 +2026-09-16 18:09:42.654 INFO 3020 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  322 +2026-09-16 18:09:42.892 INFO 3020 --- [main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
  323 +2026-09-16 18:09:42.910 INFO 3020 --- [main] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
  324 +2026-09-16 18:09:43.026 INFO 3020 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8090 (http) with context path ''
  325 +2026-09-16 18:09:43.032 INFO 3020 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Started QxApaasSyncApplication in 5.412 seconds (JVM running for 6.12)
  326 +2026-09-16 18:10:05.308 INFO 3020 --- [http-nio-8090-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
  327 +2026-09-16 18:10:05.314 INFO 3020 --- [http-nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
  328 +2026-09-16 18:10:05.338 INFO 3020 --- [http-nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 24 ms
  329 +2026-09-16 18:10:06.629 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65fd5c0e0d1f1a7ae4f038ec entry=696f1754f141344a6b794f9c 第 1 页 14 条, 累计 14 条
  330 +2026-09-16 18:10:06.630 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65fd5c0e0d1f1a7ae4f038ec entry=696f1754f141344a6b794f9c 共 14 条
  331 +2026-09-16 18:10:06.800 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 1 页 100 条, 累计 100 条
  332 +2026-09-16 18:10:07.138 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 2 页 100 条, 累计 200 条
  333 +2026-09-16 18:10:07.257 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 3 页 100 条, 累计 300 条
  334 +2026-09-16 18:10:07.399 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 4 页 100 条, 累计 400 条
  335 +2026-09-16 18:10:07.519 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 5 页 100 条, 累计 500 条
  336 +2026-09-16 18:10:07.665 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 6 页 100 条, 累计 600 条
  337 +2026-09-16 18:10:07.822 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 7 页 100 条, 累计 700 条
  338 +2026-09-16 18:10:08.654 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 8 页 100 条, 累计 800 条
  339 +2026-09-16 18:10:08.852 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 9 页 100 条, 累计 900 条
  340 +2026-09-16 18:10:09.046 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 10 页 100 条, 累计 1000 条
  341 +2026-09-16 18:10:09.187 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 11 页 100 条, 累计 1100 条
  342 +2026-09-16 18:10:09.337 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 12 页 100 条, 累计 1200 条
  343 +2026-09-16 18:10:09.465 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 13 页 100 条, 累计 1300 条
  344 +2026-09-16 18:10:09.705 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 14 页 100 条, 累计 1400 条
  345 +2026-09-16 18:10:09.821 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 15 页 100 条, 累计 1500 条
  346 +2026-09-16 18:10:09.958 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 16 页 100 条, 累计 1600 条
  347 +2026-09-16 18:10:10.111 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 17 页 100 条, 累计 1700 条
  348 +2026-09-16 18:10:10.228 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 18 页 100 条, 累计 1800 条
  349 +2026-09-16 18:10:10.507 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 19 页 100 条, 累计 1900 条
  350 +2026-09-16 18:10:10.725 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 20 页 100 条, 累计 2000 条
  351 +2026-09-16 18:10:10.980 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 21 页 100 条, 累计 2100 条
  352 +2026-09-16 18:10:11.144 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 22 页 100 条, 累计 2200 条
  353 +2026-09-16 18:10:12.329 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 23 页 100 条, 累计 2300 条
  354 +2026-09-16 18:10:12.424 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 第 24 页 45 条, 累计 2345 条
  355 +2026-09-16 18:10:12.428 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=6a03dd3386f7148aadb98990 共 2345 条
  356 +2026-09-16 18:10:12.901 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a193f03e88046f554dc10bc 第 1 页 100 条, 累计 100 条
  357 +2026-09-16 18:10:12.974 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6a193f03e88046f554dc10bc 第 2 页 31 条, 累计 131 条
  358 +2026-09-16 18:10:13.092 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=6a193f03e88046f554dc10bc 共 131 条
  359 +2026-09-16 18:10:13.416 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 1 页 100 条, 累计 100 条
  360 +2026-09-16 18:10:13.609 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 2 页 100 条, 累计 200 条
  361 +2026-09-16 18:10:13.744 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 3 页 100 条, 累计 300 条
  362 +2026-09-16 18:10:14.105 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 4 页 100 条, 累计 400 条
  363 +2026-09-16 18:10:14.330 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 5 页 100 条, 累计 500 条
  364 +2026-09-16 18:10:14.451 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 6 页 100 条, 累计 600 条
  365 +2026-09-16 18:10:14.563 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 7 页 100 条, 累计 700 条
  366 +2026-09-16 18:10:14.773 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 8 页 100 条, 累计 800 条
  367 +2026-09-16 18:10:14.915 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 9 页 100 条, 累计 900 条
  368 +2026-09-16 18:10:15.056 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 10 页 100 条, 累计 1000 条
  369 +2026-09-16 18:10:15.195 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 11 页 100 条, 累计 1100 条
  370 +2026-09-16 18:10:15.319 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 12 页 100 条, 累计 1200 条
  371 +2026-09-16 18:10:15.529 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 13 页 100 条, 累计 1300 条
  372 +2026-09-16 18:10:15.787 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 14 页 100 条, 累计 1400 条
  373 +2026-09-16 18:10:16.196 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 15 页 100 条, 累计 1500 条
  374 +2026-09-16 18:10:16.411 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 16 页 100 条, 累计 1600 条
  375 +2026-09-16 18:10:16.607 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 17 页 100 条, 累计 1700 条
  376 +2026-09-16 18:10:17.076 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 18 页 100 条, 累计 1800 条
  377 +2026-09-16 18:10:17.241 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 19 页 100 条, 累计 1900 条
  378 +2026-09-16 18:10:17.392 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 20 页 100 条, 累计 2000 条
  379 +2026-09-16 18:10:17.562 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 21 页 100 条, 累计 2100 条
  380 +2026-09-16 18:10:17.686 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 22 页 100 条, 累计 2200 条
  381 +2026-09-16 18:10:17.909 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 23 页 100 条, 累计 2300 条
  382 +2026-09-16 18:10:18.049 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 24 页 100 条, 累计 2400 条
  383 +2026-09-16 18:10:18.502 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 25 页 100 条, 累计 2500 条
  384 +2026-09-16 18:10:18.618 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 26 页 100 条, 累计 2600 条
  385 +2026-09-16 18:10:18.782 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 27 页 100 条, 累计 2700 条
  386 +2026-09-16 18:10:19.004 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 28 页 100 条, 累计 2800 条
  387 +2026-09-16 18:10:19.229 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 29 页 100 条, 累计 2900 条
  388 +2026-09-16 18:10:19.370 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 30 页 100 条, 累计 3000 条
  389 +2026-09-16 18:10:19.540 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 31 页 100 条, 累计 3100 条
  390 +2026-09-16 18:10:19.704 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 32 页 100 条, 累计 3200 条
  391 +2026-09-16 18:10:19.831 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 33 页 100 条, 累计 3300 条
  392 +2026-09-16 18:10:20.019 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 34 页 100 条, 累计 3400 条
  393 +2026-09-16 18:10:20.157 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 35 页 100 条, 累计 3500 条
  394 +2026-09-16 18:10:20.278 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 36 页 100 条, 累计 3600 条
  395 +2026-09-16 18:10:20.464 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 37 页 100 条, 累计 3700 条
  396 +2026-09-16 18:10:20.776 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 38 页 100 条, 累计 3800 条
  397 +2026-09-16 18:10:20.954 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 39 页 55 条, 累计 3855 条
  398 +2026-09-16 18:10:20.955 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 共 3855 条
  399 +2026-09-16 18:10:21.368 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 1 页 100 条, 累计 100 条
  400 +2026-09-16 18:10:21.628 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 2 页 100 条, 累计 200 条
  401 +2026-09-16 18:10:21.747 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 3 页 100 条, 累计 300 条
  402 +2026-09-16 18:10:21.870 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 4 页 100 条, 累计 400 条
  403 +2026-09-16 18:10:22.066 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 5 页 100 条, 累计 500 条
  404 +2026-09-16 18:10:22.194 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 6 页 100 条, 累计 600 条
  405 +2026-09-16 18:10:22.321 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 7 页 100 条, 累计 700 条
  406 +2026-09-16 18:10:22.733 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 8 页 100 条, 累计 800 条
  407 +2026-09-16 18:10:22.944 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 9 页 100 条, 累计 900 条
  408 +2026-09-16 18:10:23.150 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 10 页 100 条, 累计 1000 条
  409 +2026-09-16 18:10:23.299 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 11 页 100 条, 累计 1100 条
  410 +2026-09-16 18:10:23.612 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 12 页 100 条, 累计 1200 条
  411 +2026-09-16 18:10:23.771 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 13 页 100 条, 累计 1300 条
  412 +2026-09-16 18:10:23.901 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 14 页 100 条, 累计 1400 条
  413 +2026-09-16 18:10:25.066 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 15 页 100 条, 累计 1500 条
  414 +2026-09-16 18:10:25.296 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 16 页 100 条, 累计 1600 条
  415 +2026-09-16 18:10:25.501 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 17 页 100 条, 累计 1700 条
  416 +2026-09-16 18:10:25.832 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 18 页 100 条, 累计 1800 条
  417 +2026-09-16 18:10:25.962 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 19 页 100 条, 累计 1900 条
  418 +2026-09-16 18:10:26.104 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 20 页 100 条, 累计 2000 条
  419 +2026-09-16 18:10:26.596 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 21 页 100 条, 累计 2100 条
  420 +2026-09-16 18:10:26.724 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 22 页 100 条, 累计 2200 条
  421 +2026-09-16 18:10:26.881 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 23 页 100 条, 累计 2300 条
  422 +2026-09-16 18:10:27.233 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 24 页 100 条, 累计 2400 条
  423 +2026-09-16 18:10:27.371 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 25 页 100 条, 累计 2500 条
  424 +2026-09-16 18:10:27.763 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 26 页 100 条, 累计 2600 条
  425 +2026-09-16 18:10:27.892 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 27 页 100 条, 累计 2700 条
  426 +2026-09-16 18:10:28.081 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 28 页 100 条, 累计 2800 条
  427 +2026-09-16 18:10:28.391 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 29 页 100 条, 累计 2900 条
  428 +2026-09-16 18:10:28.504 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 30 页 100 条, 累计 3000 条
  429 +2026-09-16 18:10:28.641 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 31 页 100 条, 累计 3100 条
  430 +2026-09-16 18:10:28.790 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 32 页 100 条, 累计 3200 条
  431 +2026-09-16 18:10:28.904 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 33 页 100 条, 累计 3300 条
  432 +2026-09-16 18:10:29.019 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 34 页 100 条, 累计 3400 条
  433 +2026-09-16 18:10:29.263 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 35 页 100 条, 累计 3500 条
  434 +2026-09-16 18:10:29.378 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 36 页 100 条, 累计 3600 条
  435 +2026-09-16 18:10:29.583 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 37 页 100 条, 累计 3700 条
  436 +2026-09-16 18:10:29.972 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 38 页 100 条, 累计 3800 条
  437 +2026-09-16 18:10:30.080 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 第 39 页 55 条, 累计 3855 条
  438 +2026-09-16 18:10:30.092 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=6875b1ed729e8f4038955c62 共 3855 条
  439 +2026-09-16 18:10:30.493 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=688336be2fbf78b3d44d7174 第 1 页 12 条, 累计 12 条
  440 +2026-09-16 18:10:30.507 INFO 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=688336be2fbf78b3d44d7174 共 12 条
  441 +2026-09-16 18:11:10.958 WARN 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.util.JsonHttpUtils : HTTP POST -> https://jdy.changan.com.cn/api/v5/app/entry/data/list : {"code":8303,"msg":"The call frequency of the company/team exceeds the frequency limit."}
  442 +2026-09-16 18:11:10.971 ERROR 3020 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_7] 统计失败
  443 +
  444 +java.lang.IllegalStateException: 简道云数据拉取失败 code=8303 msg=The call frequency of the company/team exceeds the frequency limit.
  445 + at com.qgutech.qgyun.apaas.sync.jdy.api.JiandaoYunApi.forEachPage(JiandaoYunApi.java:183) ~[classes!/:1.0.0-SNAPSHOT]
  446 + at com.qgutech.qgyun.apaas.sync.jdy.service.JdyRiskStatisticsService.buildScenario7Rows(JdyRiskStatisticsService.java:335) ~[classes!/:1.0.0-SNAPSHOT]
  447 + at com.qgutech.qgyun.apaas.sync.jdy.service.JdyRiskStatisticsService.countAll(JdyRiskStatisticsService.java:51) ~[classes!/:1.0.0-SNAPSHOT]
  448 + at com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.count(JdyRiskController.java:27) [classes!/:1.0.0-SNAPSHOT]
  449 + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_504]
  450 + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_504]
  451 + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_504]
  452 + at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_504]
  453 + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  454 + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  455 + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  456 + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  457 + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  458 + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  459 + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  460 + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  461 + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:981) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  462 + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:884) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  463 + at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  464 + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:858) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  465 + at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  466 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  467 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  468 + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.39.jar!/:8.5.39]
  469 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  470 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  471 + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  472 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  473 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  474 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  475 + at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  476 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  477 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  478 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  479 + at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  480 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  481 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  482 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  483 + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  484 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  485 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  486 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  487 + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  488 + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  489 + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  490 + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  491 + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  492 + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  493 + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  494 + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  495 + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  496 + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  497 + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  498 + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  499 + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_504]
  500 + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_504]
  501 + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  502 + at java.lang.Thread.run(Thread.java:750) [na:1.8.0_504]
  503 +
  504 +2026-09-16 18:11:11.143 WARN 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.util.JsonHttpUtils : HTTP POST -> https://jdy.changan.com.cn/api/v5/app/entry/data/list : {"code":8303,"msg":"The call frequency of the company/team exceeds the frequency limit."}
  505 +2026-09-16 18:11:11.155 ERROR 3020 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_8] 统计失败
  506 +
  507 +java.lang.IllegalStateException: 简道云数据拉取失败 code=8303 msg=The call frequency of the company/team exceeds the frequency limit.
  508 + at com.qgutech.qgyun.apaas.sync.jdy.api.JiandaoYunApi.listAllData(JiandaoYunApi.java:130) ~[classes!/:1.0.0-SNAPSHOT]
  509 + at com.qgutech.qgyun.apaas.sync.jdy.service.JdyRiskStatisticsService.countAll(JdyRiskStatisticsService.java:53) ~[classes!/:1.0.0-SNAPSHOT]
  510 + at com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.count(JdyRiskController.java:27) [classes!/:1.0.0-SNAPSHOT]
  511 + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_504]
  512 + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_504]
  513 + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_504]
  514 + at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_504]
  515 + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  516 + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  517 + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  518 + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  519 + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  520 + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  521 + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  522 + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  523 + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:981) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  524 + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:884) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  525 + at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  526 + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:858) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  527 + at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  528 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  529 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  530 + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.39.jar!/:8.5.39]
  531 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  532 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  533 + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  534 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  535 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  536 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  537 + at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  538 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  539 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  540 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  541 + at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  542 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  543 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  544 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  545 + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  546 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  547 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  548 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  549 + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  550 + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  551 + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  552 + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  553 + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  554 + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  555 + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  556 + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  557 + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  558 + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  559 + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  560 + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  561 + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_504]
  562 + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_504]
  563 + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  564 + at java.lang.Thread.run(Thread.java:750) [na:1.8.0_504]
  565 +
  566 +2026-09-16 18:11:11.306 WARN 3020 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.util.JsonHttpUtils : HTTP POST -> https://jdy.changan.com.cn/api/v5/app/entry/data/list : {"code":8303,"msg":"The call frequency of the company/team exceeds the frequency limit."}
  567 +2026-09-16 18:11:11.309 ERROR 3020 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_9] 统计失败
  568 +
  569 +java.lang.IllegalStateException: 简道云数据拉取失败 code=8303 msg=The call frequency of the company/team exceeds the frequency limit.
  570 + at com.qgutech.qgyun.apaas.sync.jdy.api.JiandaoYunApi.listAllData(JiandaoYunApi.java:130) ~[classes!/:1.0.0-SNAPSHOT]
  571 + at com.qgutech.qgyun.apaas.sync.jdy.service.JdyRiskStatisticsService.countAll(JdyRiskStatisticsService.java:53) ~[classes!/:1.0.0-SNAPSHOT]
  572 + at com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.count(JdyRiskController.java:27) [classes!/:1.0.0-SNAPSHOT]
  573 + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_504]
  574 + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_504]
  575 + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_504]
  576 + at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_504]
  577 + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  578 + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  579 + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  580 + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  581 + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  582 + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  583 + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  584 + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  585 + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:981) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  586 + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:884) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  587 + at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  588 + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:858) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  589 + at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  590 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  591 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  592 + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.39.jar!/:8.5.39]
  593 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  594 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  595 + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  596 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  597 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  598 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  599 + at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  600 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  601 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  602 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  603 + at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  604 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  605 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  606 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  607 + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  608 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  609 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  610 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  611 + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  612 + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  613 + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  614 + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  615 + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  616 + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  617 + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  618 + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  619 + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  620 + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  621 + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  622 + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  623 + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_504]
  624 + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_504]
  625 + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  626 + at java.lang.Thread.run(Thread.java:750) [na:1.8.0_504]
  627 +
  628 +2026-09-16 18:20:13.952 INFO 4144 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Starting QxApaasSyncApplication v1.0.0-SNAPSHOT on CQCA7304093 with PID 4144 (D:\code\qx-apaas-sync\target\qx-apaas-sync-1.0.0-SNAPSHOT.jar started by Administrator in D:\code\qx-apaas-sync)
  629 +2026-09-16 18:20:13.969 INFO 4144 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : No active profile set, falling back to default profiles: default
  630 +2026-09-16 18:20:14.092 INFO 4144 --- [main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@34033bd0: startup date [Wed Sep 16 18:20:14 CST 2026]; root of context hierarchy
  631 +2026-09-16 18:20:16.112 INFO 4144 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8090 (http)
  632 +2026-09-16 18:20:16.157 INFO 4144 --- [main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
  633 +2026-09-16 18:20:16.158 INFO 4144 --- [main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.39
  634 +2026-09-16 18:20:16.177 INFO 4144 --- [localhost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\nodejs\;D:\apache-maven-3.5.3\bin;C:\mysql\mysql-8.4.9-winx64\bin;C:\Program Files\Git\cmd;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\AppData\Roaming\npm;C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\bin;.]
  635 +2026-09-16 18:20:16.298 INFO 4144 --- [localhost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
  636 +2026-09-16 18:20:16.299 INFO 4144 --- [localhost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2207 ms
  637 +2026-09-16 18:20:16.390 INFO 4144 --- [localhost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
  638 +2026-09-16 18:20:16.394 INFO 4144 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
  639 +2026-09-16 18:20:16.395 INFO 4144 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
  640 +2026-09-16 18:20:16.395 INFO 4144 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
  641 +2026-09-16 18:20:16.396 INFO 4144 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
  642 +2026-09-16 18:20:16.672 INFO 4144 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  643 +2026-09-16 18:20:16.894 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@34033bd0: startup date [Wed Sep 16 18:20:14 CST 2026]; root of context hierarchy
  644 +2026-09-16 18:20:17.228 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.count()
  645 +2026-09-16 18:20:17.230 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.sync()
  646 +2026-09-16 18:20:17.232 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count/{scenarioId}],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countOneGet(java.lang.String)
  647 +2026-09-16 18:20:17.233 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countGet()
  648 +2026-09-16 18:20:17.234 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync/{scenarioId}],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOneGet(java.lang.String)
  649 +2026-09-16 18:20:17.235 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync/{scenarioId}],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOne(java.lang.String)
  650 +2026-09-16 18:20:17.236 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count/{scenarioId}],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countOne(java.lang.String)
  651 +2026-09-16 18:20:17.237 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncGet()
  652 +2026-09-16 18:20:17.242 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-data],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncData()
  653 +2026-09-16 18:20:17.244 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel-form],methods=[POST]}" onto public java.lang.String com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcelForm(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)
  654 +2026-09-16 18:20:17.245 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-structure],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncStructure()
  655 +2026-09-16 18:20:17.246 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcel()
  656 +2026-09-16 18:20:17.248 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/all],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncAll()
  657 +2026-09-16 18:20:17.249 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/{appName}],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncOne(java.lang.String)
  658 +2026-09-16 18:20:17.255 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
  659 +2026-09-16 18:20:17.268 INFO 4144 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
  660 +2026-09-16 18:20:17.346 INFO 4144 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  661 +2026-09-16 18:20:17.347 INFO 4144 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  662 +2026-09-16 18:20:17.632 INFO 4144 --- [main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
  663 +2026-09-16 18:20:17.649 INFO 4144 --- [main] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
  664 +2026-09-16 18:20:17.718 INFO 4144 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8090 (http) with context path ''
  665 +2026-09-16 18:20:17.721 INFO 4144 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Started QxApaasSyncApplication in 4.782 seconds (JVM running for 5.628)
  666 +2026-09-16 18:20:40.150 INFO 4144 --- [http-nio-8090-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
  667 +2026-09-16 18:20:40.151 INFO 4144 --- [http-nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
  668 +2026-09-16 18:20:40.174 INFO 4144 --- [http-nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 23 ms
  669 +2026-09-16 18:20:41.189 INFO 4144 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=688336be2fbf78b3d44d7174 第 1 页 12 条, 累计 12 条
  670 +2026-09-16 18:20:41.190 INFO 4144 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=688336be2fbf78b3d44d7174 共 12 条
  671 +2026-09-16 18:20:41.715 INFO 4144 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 1 页 100 条, 累计 100 条
  672 +2026-09-16 18:20:41.866 INFO 4144 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 2 页 100 条, 累计 200 条
  673 +2026-09-16 18:20:42.007 INFO 4144 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 3 页 100 条, 累计 300 条
  674 +2026-09-16 18:20:42.201 INFO 4144 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 4 页 100 条, 累计 400 条
  675 +2026-09-16 18:20:42.331 INFO 4144 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 5 页 100 条, 累计 500 条
  676 +2026-09-16 18:20:42.471 INFO 4144 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 6 页 13 条, 累计 513 条
  677 +2026-09-16 18:20:42.472 INFO 4144 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 共 513 条
  678 +2026-09-16 18:20:42.598 INFO 4144 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 1 页 100 条, 累计 100 条
  679 +2026-09-16 18:20:42.702 INFO 4144 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 2 页 100 条, 累计 200 条
  680 +2026-09-16 18:20:42.808 INFO 4144 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 3 页 100 条, 累计 300 条
  681 +2026-09-16 18:20:42.940 INFO 4144 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 4 页 100 条, 累计 400 条
  682 +2026-09-16 18:20:43.041 INFO 4144 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 5 页 100 条, 累计 500 条
  683 +2026-09-16 18:20:43.109 INFO 4144 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 6 页 13 条, 累计 513 条
  684 +2026-09-16 18:20:43.111 INFO 4144 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 共 513 条
  685 +2026-09-16 19:00:19.419 WARN 4144 --- [http-nio-8090-exec-5] c.q.q.apaas.sync.jdy.util.JsonHttpUtils : HTTP POST -> https://jdy.changan.com.cn/api/v5/app/entry/data/list : {"code":8303,"msg":"The call frequency of the company/team exceeds the frequency limit."}
  686 +2026-09-16 19:00:19.421 WARN 4144 --- [http-nio-8090-exec-5] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云频率限制(8303),2000ms 后重试(第1次)
  687 +2026-09-16 19:01:08.176 INFO 2200 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Starting QxApaasSyncApplication v1.0.0-SNAPSHOT on CQCA7304093 with PID 2200 (D:\code\qx-apaas-sync\target\qx-apaas-sync-1.0.0-SNAPSHOT.jar started by Administrator in D:\code\qx-apaas-sync)
  688 +2026-09-16 19:01:08.199 INFO 2200 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : No active profile set, falling back to default profiles: default
  689 +2026-09-16 19:01:08.316 INFO 2200 --- [main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2ff4f00f: startup date [Wed Sep 16 19:01:08 CST 2026]; root of context hierarchy
  690 +2026-09-16 19:01:10.008 INFO 2200 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8090 (http)
  691 +2026-09-16 19:01:10.056 INFO 2200 --- [main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
  692 +2026-09-16 19:01:10.056 INFO 2200 --- [main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.39
  693 +2026-09-16 19:01:10.073 INFO 2200 --- [localhost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\nodejs\;D:\apache-maven-3.5.3\bin;C:\mysql\mysql-8.4.9-winx64\bin;C:\Program Files\Git\cmd;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\AppData\Roaming\npm;C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\bin;.]
  694 +2026-09-16 19:01:10.185 INFO 2200 --- [localhost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
  695 +2026-09-16 19:01:10.186 INFO 2200 --- [localhost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1871 ms
  696 +2026-09-16 19:01:10.271 INFO 2200 --- [localhost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
  697 +2026-09-16 19:01:10.275 INFO 2200 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
  698 +2026-09-16 19:01:10.276 INFO 2200 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
  699 +2026-09-16 19:01:10.277 INFO 2200 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
  700 +2026-09-16 19:01:10.277 INFO 2200 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
  701 +2026-09-16 19:01:10.662 INFO 2200 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  702 +2026-09-16 19:01:11.150 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2ff4f00f: startup date [Wed Sep 16 19:01:08 CST 2026]; root of context hierarchy
  703 +2026-09-16 19:01:11.392 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.count()
  704 +2026-09-16 19:01:11.395 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.sync()
  705 +2026-09-16 19:01:11.397 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countGet()
  706 +2026-09-16 19:01:11.399 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncGet()
  707 +2026-09-16 19:01:11.400 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count/{scenarioId}],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countOne(java.lang.String)
  708 +2026-09-16 19:01:11.402 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count/{scenarioId}],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countOneGet(java.lang.String)
  709 +2026-09-16 19:01:11.403 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync/{scenarioId}],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOne(java.lang.String)
  710 +2026-09-16 19:01:11.404 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync/{scenarioId}],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOneGet(java.lang.String)
  711 +2026-09-16 19:01:11.407 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-structure],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncStructure()
  712 +2026-09-16 19:01:11.408 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcel()
  713 +2026-09-16 19:01:11.409 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel-form],methods=[POST]}" onto public java.lang.String com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcelForm(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)
  714 +2026-09-16 19:01:11.410 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-data],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncData()
  715 +2026-09-16 19:01:11.415 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/all],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncAll()
  716 +2026-09-16 19:01:11.416 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/{appName}],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncOne(java.lang.String)
  717 +2026-09-16 19:01:11.421 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
  718 +2026-09-16 19:01:11.423 INFO 2200 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
  719 +2026-09-16 19:01:11.457 INFO 2200 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  720 +2026-09-16 19:01:11.458 INFO 2200 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  721 +2026-09-16 19:01:11.749 INFO 2200 --- [main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
  722 +2026-09-16 19:01:11.767 INFO 2200 --- [main] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
  723 +2026-09-16 19:01:11.868 INFO 2200 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8090 (http) with context path ''
  724 +2026-09-16 19:01:11.875 INFO 2200 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Started QxApaasSyncApplication in 4.89 seconds (JVM running for 5.521)
  725 +2026-09-16 19:01:34.368 INFO 2200 --- [http-nio-8090-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
  726 +2026-09-16 19:01:34.369 INFO 2200 --- [http-nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
  727 +2026-09-16 19:01:34.405 INFO 2200 --- [http-nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 35 ms
  728 +2026-09-16 19:04:49.828 INFO 2200 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景7 排除来源 entry=686b6fd1e3cdf473acade9ac 累计条码=213358
  729 +2026-09-16 19:04:52.708 INFO 2200 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景7 排除来源 entry=686b781c11159446bb2583fc 累计条码=215549
  730 +2026-09-16 19:08:42.121 INFO 2200 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景7 主表扫描=208438条, 过滤后保留=53条 (排除条码=215549, 超期阈值=180天)
  731 +2026-09-16 19:14:42.787 INFO 2200 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : ========== 开始单场景统计并写回: count_6 ==========
  732 +2026-09-16 19:14:43.531 INFO 2200 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 启效登录成功: https://hfca.uat3.qgutech.com (corpCode=hfca, user=15077901670)
  733 +2026-09-16 19:14:44.070 INFO 2200 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 启效记录总数=48(按 syncCode 本地匹配)
  734 +2026-09-16 19:14:44.251 INFO 2200 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=688336be2fbf78b3d44d7174 第 1 页 12 条, 累计 12 条
  735 +2026-09-16 19:14:44.252 INFO 2200 --- [http-nio-8090-exec-3] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=688336be2fbf78b3d44d7174 共 12 条
  736 +2026-09-16 19:14:44.260 INFO 2200 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_6] 命中=0 (参与统计2条)
  737 +2026-09-16 19:14:45.714 INFO 2200 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyExcelExportService : 导出 Excel: D:\code\qx-apaas-sync\.\export\20260916191444.xlsx (2 条)
  738 +2026-09-16 19:14:46.652 INFO 2200 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 文件上传成功: 20260916191444.xlsx -> fileId=8203834371557376
  739 +2026-09-16 19:14:46.653 INFO 2200 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新业务数据: 11a41Update id=I23LdTlZnwT5ro467JZ
  740 +2026-09-16 19:14:47.111 INFO 2200 --- [http-nio-8090-exec-3] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新成功: id=I23LdTlZnwT5ro467JZ
  741 +2026-09-16 19:14:47.112 INFO 2200 --- [http-nio-8090-exec-3] c.q.q.a.s.j.s.JdyRiskStatisticsService : 写回成功: syncCode=SYNC0007 id=I23LdTlZnwT5ro467JZ chcbxt=0 附件=20260916191444.xlsx
  742 +2026-09-16 19:14:47.222 INFO 2200 --- [http-nio-8090-exec-4] c.q.q.a.s.j.s.JdyRiskStatisticsService : ========== 开始单场景统计并写回: count_8 ==========
  743 +2026-09-16 19:14:47.552 INFO 2200 --- [http-nio-8090-exec-4] c.q.qgyun.apaas.sync.jdy.api.QxApi : 启效登录成功: https://hfca.uat3.qgutech.com (corpCode=hfca, user=15077901670)
  744 +2026-09-16 19:14:48.065 INFO 2200 --- [http-nio-8090-exec-4] c.q.q.a.s.j.s.JdyRiskStatisticsService : 启效记录总数=48(按 syncCode 本地匹配)
  745 +2026-09-16 19:14:48.243 INFO 2200 --- [http-nio-8090-exec-4] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 1 页 100 条, 累计 100 条
  746 +2026-09-16 19:14:48.379 INFO 2200 --- [http-nio-8090-exec-4] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 2 页 100 条, 累计 200 条
  747 +2026-09-16 19:14:48.527 INFO 2200 --- [http-nio-8090-exec-4] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 3 页 100 条, 累计 300 条
  748 +2026-09-16 19:14:48.631 INFO 2200 --- [http-nio-8090-exec-4] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 4 页 100 条, 累计 400 条
  749 +2026-09-16 19:14:48.775 INFO 2200 --- [http-nio-8090-exec-4] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 5 页 100 条, 累计 500 条
  750 +2026-09-16 19:14:48.848 INFO 2200 --- [http-nio-8090-exec-4] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 6 页 13 条, 累计 513 条
  751 +2026-09-16 19:14:48.849 INFO 2200 --- [http-nio-8090-exec-4] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 共 513 条
  752 +2026-09-16 19:14:48.852 INFO 2200 --- [http-nio-8090-exec-4] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_8] 命中=8 (参与统计21条)
  753 +2026-09-16 19:14:49.009 INFO 2200 --- [http-nio-8090-exec-4] c.q.q.a.s.j.s.JdyExcelExportService : 导出 Excel: D:\code\qx-apaas-sync\.\export\20260916191448.xlsx (21 条)
  754 +2026-09-16 19:14:49.579 INFO 2200 --- [http-nio-8090-exec-4] c.q.qgyun.apaas.sync.jdy.api.QxApi : 文件上传成功: 20260916191448.xlsx -> fileId=8203834419447808
  755 +2026-09-16 19:14:49.589 WARN 2200 --- [http-nio-8090-exec-4] c.q.q.a.s.j.s.JdyRiskStatisticsService : 按 syncCode=SYNC00010 未查到记录,跳过写回
  756 +2026-09-16 19:14:49.614 INFO 2200 --- [http-nio-8090-exec-5] c.q.q.a.s.j.s.JdyRiskStatisticsService : ========== 开始单场景统计并写回: count_9 ==========
  757 +2026-09-16 19:14:49.952 INFO 2200 --- [http-nio-8090-exec-5] c.q.qgyun.apaas.sync.jdy.api.QxApi : 启效登录成功: https://hfca.uat3.qgutech.com (corpCode=hfca, user=15077901670)
  758 +2026-09-16 19:14:50.460 INFO 2200 --- [http-nio-8090-exec-5] c.q.q.a.s.j.s.JdyRiskStatisticsService : 启效记录总数=48(按 syncCode 本地匹配)
  759 +2026-09-16 19:14:50.553 INFO 2200 --- [http-nio-8090-exec-5] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 1 页 100 条, 累计 100 条
  760 +2026-09-16 19:14:51.655 INFO 2200 --- [http-nio-8090-exec-5] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 2 页 100 条, 累计 200 条
  761 +2026-09-16 19:14:51.765 INFO 2200 --- [http-nio-8090-exec-5] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 3 页 100 条, 累计 300 条
  762 +2026-09-16 19:14:51.920 INFO 2200 --- [http-nio-8090-exec-5] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 4 页 100 条, 累计 400 条
  763 +2026-09-16 19:14:52.024 INFO 2200 --- [http-nio-8090-exec-5] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 5 页 100 条, 累计 500 条
  764 +2026-09-16 19:14:52.095 INFO 2200 --- [http-nio-8090-exec-5] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 6 页 13 条, 累计 513 条
  765 +2026-09-16 19:14:52.097 INFO 2200 --- [http-nio-8090-exec-5] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 共 513 条
  766 +2026-09-16 19:14:52.120 INFO 2200 --- [http-nio-8090-exec-5] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_9] 命中=4 (参与统计21条)
  767 +2026-09-16 19:14:52.239 INFO 2200 --- [http-nio-8090-exec-5] c.q.q.a.s.j.s.JdyExcelExportService : 导出 Excel: D:\code\qx-apaas-sync\.\export\20260916191452.xlsx (21 条)
  768 +2026-09-16 19:14:52.797 INFO 2200 --- [http-nio-8090-exec-5] c.q.qgyun.apaas.sync.jdy.api.QxApi : 文件上传成功: 20260916191452.xlsx -> fileId=8203834472335360
  769 +2026-09-16 19:14:52.798 WARN 2200 --- [http-nio-8090-exec-5] c.q.q.a.s.j.s.JdyRiskStatisticsService : 按 syncCode=SYNC00011 未查到记录,跳过写回
  770 +2026-09-16 19:14:59.765 INFO 2200 --- [http-nio-8090-exec-7] c.q.q.a.s.j.s.JdyRiskStatisticsService : ========== 开始单场景统计并写回: count_7 ==========
  771 +2026-09-16 19:15:00.108 INFO 2200 --- [http-nio-8090-exec-7] c.q.qgyun.apaas.sync.jdy.api.QxApi : 启效登录成功: https://hfca.uat3.qgutech.com (corpCode=hfca, user=15077901670)
  772 +2026-09-16 19:15:00.678 INFO 2200 --- [http-nio-8090-exec-7] c.q.q.a.s.j.s.JdyRiskStatisticsService : 启效记录总数=48(按 syncCode 本地匹配)
  773 +2026-09-16 19:17:52.576 ERROR 2200 --- [http-nio-8090-exec-7] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_7] 写回失败
  774 +
  775 +java.lang.RuntimeException: 请求失败: https://jdy.changan.com.cn/api/v5/app/entry/data/list -> Read timed out
  776 + at com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils.run(JsonHttpUtils.java:111) ~[classes!/:1.0.0-SNAPSHOT]
  777 + at com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils.execute(JsonHttpUtils.java:96) ~[classes!/:1.0.0-SNAPSHOT]
  778 + at com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils.postJson(JsonHttpUtils.java:54) ~[classes!/:1.0.0-SNAPSHOT]
  779 + at com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils.postJson2Obj(JsonHttpUtils.java:61) ~[classes!/:1.0.0-SNAPSHOT]
  780 + at com.qgutech.qgyun.apaas.sync.jdy.api.JiandaoYunApi.dataList(JiandaoYunApi.java:117) ~[classes!/:1.0.0-SNAPSHOT]
  781 + at com.qgutech.qgyun.apaas.sync.jdy.api.JiandaoYunApi.forEachPage(JiandaoYunApi.java:206) ~[classes!/:1.0.0-SNAPSHOT]
  782 + at com.qgutech.qgyun.apaas.sync.jdy.service.JdyRiskStatisticsService.buildScenario7Rows(JdyRiskStatisticsService.java:406) [classes!/:1.0.0-SNAPSHOT]
  783 + at com.qgutech.qgyun.apaas.sync.jdy.service.JdyRiskStatisticsService.syncOneScenario(JdyRiskStatisticsService.java:162) [classes!/:1.0.0-SNAPSHOT]
  784 + at com.qgutech.qgyun.apaas.sync.jdy.service.JdyRiskStatisticsService.countAndSyncOne(JdyRiskStatisticsService.java:86) [classes!/:1.0.0-SNAPSHOT]
  785 + at com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOne(JdyRiskController.java:65) [classes!/:1.0.0-SNAPSHOT]
  786 + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_504]
  787 + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_504]
  788 + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_504]
  789 + at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_504]
  790 + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  791 + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  792 + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  793 + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  794 + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  795 + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  796 + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  797 + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  798 + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:981) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  799 + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:884) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  800 + at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  801 + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:858) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  802 + at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  803 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  804 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  805 + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.39.jar!/:8.5.39]
  806 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  807 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  808 + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  809 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  810 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  811 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  812 + at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  813 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  814 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  815 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  816 + at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  817 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  818 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  819 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  820 + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  821 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  822 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  823 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  824 + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  825 + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  826 + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  827 + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  828 + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  829 + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  830 + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  831 + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  832 + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  833 + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  834 + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  835 + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  836 + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_504]
  837 + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_504]
  838 + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  839 + at java.lang.Thread.run(Thread.java:750) [na:1.8.0_504]
  840 +Caused by: java.net.SocketTimeoutException: Read timed out
  841 + at java.net.SocketInputStream.socketRead0(Native Method) ~[na:1.8.0_504]
  842 + at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) ~[na:1.8.0_504]
  843 + at java.net.SocketInputStream.read(SocketInputStream.java:171) ~[na:1.8.0_504]
  844 + at java.net.SocketInputStream.read(SocketInputStream.java:141) ~[na:1.8.0_504]
  845 + at sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:464) ~[na:1.8.0_504]
  846 + at sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:68) ~[na:1.8.0_504]
  847 + at sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1350) ~[na:1.8.0_504]
  848 + at sun.security.ssl.SSLSocketImpl.access$300(SSLSocketImpl.java:73) ~[na:1.8.0_504]
  849 + at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:966) ~[na:1.8.0_504]
  850 + at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137) ~[httpcore-4.4.11.jar!/:4.4.11]
  851 + at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153) ~[httpcore-4.4.11.jar!/:4.4.11]
  852 + at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:280) ~[httpcore-4.4.11.jar!/:4.4.11]
  853 + at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138) ~[httpclient-4.5.14.jar!/:4.5.14]
  854 + at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56) ~[httpclient-4.5.14.jar!/:4.5.14]
  855 + at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259) ~[httpcore-4.4.11.jar!/:4.4.11]
  856 + at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163) ~[httpcore-4.4.11.jar!/:4.4.11]
  857 + at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157) ~[httpclient-4.5.14.jar!/:4.5.14]
  858 + at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273) ~[httpcore-4.4.11.jar!/:4.4.11]
  859 + at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125) ~[httpcore-4.4.11.jar!/:4.4.11]
  860 + at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272) ~[httpclient-4.5.14.jar!/:4.5.14]
  861 + at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) ~[httpclient-4.5.14.jar!/:4.5.14]
  862 + at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) ~[httpclient-4.5.14.jar!/:4.5.14]
  863 + at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[httpclient-4.5.14.jar!/:4.5.14]
  864 + at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.14.jar!/:4.5.14]
  865 + at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) ~[httpclient-4.5.14.jar!/:4.5.14]
  866 + at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) ~[httpclient-4.5.14.jar!/:4.5.14]
  867 + at com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils.run(JsonHttpUtils.java:102) ~[classes!/:1.0.0-SNAPSHOT]
  868 + ... 63 common frames omitted
  869 +
  870 +2026-09-16 19:18:49.758 INFO 13164 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Starting QxApaasSyncApplication v1.0.0-SNAPSHOT on CQCA7304093 with PID 13164 (D:\code\qx-apaas-sync\target\qx-apaas-sync-1.0.0-SNAPSHOT.jar started by Administrator in D:\code\qx-apaas-sync)
  871 +2026-09-16 19:18:49.772 INFO 13164 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : No active profile set, falling back to default profiles: default
  872 +2026-09-16 19:18:49.964 INFO 13164 --- [main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@1888ff2c: startup date [Wed Sep 16 19:18:49 CST 2026]; root of context hierarchy
  873 +2026-09-16 19:18:51.919 INFO 13164 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8090 (http)
  874 +2026-09-16 19:18:51.958 INFO 13164 --- [main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
  875 +2026-09-16 19:18:51.959 INFO 13164 --- [main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.39
  876 +2026-09-16 19:18:51.980 INFO 13164 --- [localhost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\nodejs\;D:\apache-maven-3.5.3\bin;C:\mysql\mysql-8.4.9-winx64\bin;C:\Program Files\Git\cmd;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\AppData\Roaming\npm;C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\bin;.]
  877 +2026-09-16 19:18:52.115 INFO 13164 --- [localhost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
  878 +2026-09-16 19:18:52.116 INFO 13164 --- [localhost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2152 ms
  879 +2026-09-16 19:18:52.235 INFO 13164 --- [localhost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
  880 +2026-09-16 19:18:52.241 INFO 13164 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
  881 +2026-09-16 19:18:52.247 INFO 13164 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
  882 +2026-09-16 19:18:52.253 INFO 13164 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
  883 +2026-09-16 19:18:52.255 INFO 13164 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
  884 +2026-09-16 19:18:52.804 INFO 13164 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  885 +2026-09-16 19:18:53.065 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@1888ff2c: startup date [Wed Sep 16 19:18:49 CST 2026]; root of context hierarchy
  886 +2026-09-16 19:18:53.303 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel-form],methods=[POST]}" onto public java.lang.String com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcelForm(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)
  887 +2026-09-16 19:18:53.305 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcel()
  888 +2026-09-16 19:18:53.306 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-data],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncData()
  889 +2026-09-16 19:18:53.307 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-structure],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncStructure()
  890 +2026-09-16 19:18:53.314 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.count()
  891 +2026-09-16 19:18:53.320 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.sync()
  892 +2026-09-16 19:18:53.321 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count/{scenarioId}],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countOne(java.lang.String)
  893 +2026-09-16 19:18:53.322 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync/{scenarioId}],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOne(java.lang.String)
  894 +2026-09-16 19:18:53.323 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count/{scenarioId}],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countOneGet(java.lang.String)
  895 +2026-09-16 19:18:53.324 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countGet()
  896 +2026-09-16 19:18:53.325 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync/{scenarioId}],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOneGet(java.lang.String)
  897 +2026-09-16 19:18:53.326 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncGet()
  898 +2026-09-16 19:18:53.328 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/all],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncAll()
  899 +2026-09-16 19:18:53.329 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/{appName}],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncOne(java.lang.String)
  900 +2026-09-16 19:18:53.333 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
  901 +2026-09-16 19:18:53.335 INFO 13164 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
  902 +2026-09-16 19:18:53.366 INFO 13164 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  903 +2026-09-16 19:18:53.368 INFO 13164 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  904 +2026-09-16 19:18:53.562 INFO 13164 --- [main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
  905 +2026-09-16 19:18:53.579 INFO 13164 --- [main] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
  906 +2026-09-16 19:18:53.671 INFO 13164 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8090 (http) with context path ''
  907 +2026-09-16 19:18:53.677 INFO 13164 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Started QxApaasSyncApplication in 5.162 seconds (JVM running for 5.93)
  908 +2026-09-16 19:19:15.476 INFO 13164 --- [http-nio-8090-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
  909 +2026-09-16 19:19:15.477 INFO 13164 --- [http-nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
  910 +2026-09-16 19:19:15.504 INFO 13164 --- [http-nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 27 ms
  911 +2026-09-16 19:19:15.542 INFO 13164 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : ========== 开始单场景统计并写回: count_8 ==========
  912 +2026-09-16 19:19:16.893 INFO 13164 --- [http-nio-8090-exec-1] c.q.qgyun.apaas.sync.jdy.api.QxApi : 启效登录成功: https://hfca.uat3.qgutech.com (corpCode=hfca, user=15077901670)
  913 +2026-09-16 19:19:17.382 INFO 13164 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : 启效记录总数=48(按 syncCode 本地匹配)
  914 +2026-09-16 19:19:17.605 INFO 13164 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 1 页 100 条, 累计 100 条
  915 +2026-09-16 19:19:17.791 INFO 13164 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 2 页 100 条, 累计 200 条
  916 +2026-09-16 19:19:17.949 INFO 13164 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 3 页 100 条, 累计 300 条
  917 +2026-09-16 19:19:18.063 INFO 13164 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 4 页 100 条, 累计 400 条
  918 +2026-09-16 19:19:18.169 INFO 13164 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 5 页 100 条, 累计 500 条
  919 +2026-09-16 19:19:18.236 INFO 13164 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 6 页 13 条, 累计 513 条
  920 +2026-09-16 19:19:18.237 INFO 13164 --- [http-nio-8090-exec-1] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 共 513 条
  921 +2026-09-16 19:19:18.281 INFO 13164 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_8] 命中=8 (参与统计21条)
  922 +2026-09-16 19:19:19.206 INFO 13164 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyExcelExportService : 导出 Excel: D:\code\qx-apaas-sync\.\export\20260916191918.xlsx (21 条)
  923 +2026-09-16 19:19:19.976 INFO 13164 --- [http-nio-8090-exec-1] c.q.qgyun.apaas.sync.jdy.api.QxApi : 文件上传成功: 20260916191918.xlsx -> fileId=8203838849779712
  924 +2026-09-16 19:19:19.976 INFO 13164 --- [http-nio-8090-exec-1] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新业务数据: 11a41Update id=KERaeyE4i8WF8QdLnPl
  925 +2026-09-16 19:19:20.333 INFO 13164 --- [http-nio-8090-exec-1] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新成功: id=KERaeyE4i8WF8QdLnPl
  926 +2026-09-16 19:19:20.338 INFO 13164 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : 写回成功: syncCode=SYNC0010 id=KERaeyE4i8WF8QdLnPl chcbxt=8 附件=20260916191918.xlsx
  927 +2026-09-16 19:19:20.458 INFO 13164 --- [http-nio-8090-exec-2] c.q.q.a.s.j.s.JdyRiskStatisticsService : ========== 开始单场景统计并写回: count_9 ==========
  928 +2026-09-16 19:19:20.773 INFO 13164 --- [http-nio-8090-exec-2] c.q.qgyun.apaas.sync.jdy.api.QxApi : 启效登录成功: https://hfca.uat3.qgutech.com (corpCode=hfca, user=15077901670)
  929 +2026-09-16 19:19:21.238 INFO 13164 --- [http-nio-8090-exec-2] c.q.q.a.s.j.s.JdyRiskStatisticsService : 启效记录总数=48(按 syncCode 本地匹配)
  930 +2026-09-16 19:19:21.341 INFO 13164 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 1 页 100 条, 累计 100 条
  931 +2026-09-16 19:19:21.494 INFO 13164 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 2 页 100 条, 累计 200 条
  932 +2026-09-16 19:19:21.603 INFO 13164 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 3 页 100 条, 累计 300 条
  933 +2026-09-16 19:19:21.700 INFO 13164 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 4 页 100 条, 累计 400 条
  934 +2026-09-16 19:19:21.787 INFO 13164 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 5 页 100 条, 累计 500 条
  935 +2026-09-16 19:19:21.850 INFO 13164 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云分页: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 第 6 页 13 条, 累计 513 条
  936 +2026-09-16 19:19:21.851 INFO 13164 --- [http-nio-8090-exec-2] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云拉取完成: app=65f8060f8666b8a5d1b98d57 entry=69676b83f96b846da4443c42 共 513 条
  937 +2026-09-16 19:19:21.871 INFO 13164 --- [http-nio-8090-exec-2] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_9] 命中=4 (参与统计21条)
  938 +2026-09-16 19:19:22.026 INFO 13164 --- [http-nio-8090-exec-2] c.q.q.a.s.j.s.JdyExcelExportService : 导出 Excel: D:\code\qx-apaas-sync\.\export\20260916191921.xlsx (21 条)
  939 +2026-09-16 19:19:22.588 INFO 13164 --- [http-nio-8090-exec-2] c.q.qgyun.apaas.sync.jdy.api.QxApi : 文件上传成功: 20260916191921.xlsx -> fileId=8203838892640256
  940 +2026-09-16 19:19:22.589 INFO 13164 --- [http-nio-8090-exec-2] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新业务数据: 11a41Update id=dgKAi0wIefVw0YIdnyV
  941 +2026-09-16 19:19:22.900 INFO 13164 --- [http-nio-8090-exec-2] c.q.qgyun.apaas.sync.jdy.api.QxApi : 更新成功: id=dgKAi0wIefVw0YIdnyV
  942 +2026-09-16 19:19:22.901 INFO 13164 --- [http-nio-8090-exec-2] c.q.q.a.s.j.s.JdyRiskStatisticsService : 写回成功: syncCode=SYNC0011 id=dgKAi0wIefVw0YIdnyV chcbxt=4 附件=20260916191921.xlsx
  943 +2026-09-16 19:31:58.801 INFO 13164 --- [http-nio-8090-exec-4] c.q.q.a.s.j.s.JdyRiskStatisticsService : ========== 开始单场景统计并写回: count_7 ==========
  944 +2026-09-16 19:31:58.899 ERROR 13164 --- [http-nio-8090-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: 请求失败: https://hfca.uat3.qgutech.com/qx-api/qx-apaas-uc/user/securityImg -> Connection reset] with root cause
  945 +
  946 +java.net.SocketException: Connection reset
  947 + at java.net.SocketInputStream.read(SocketInputStream.java:210) ~[na:1.8.0_504]
  948 + at java.net.SocketInputStream.read(SocketInputStream.java:141) ~[na:1.8.0_504]
  949 + at sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:464) ~[na:1.8.0_504]
  950 + at sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:68) ~[na:1.8.0_504]
  951 + at sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1350) ~[na:1.8.0_504]
  952 + at sun.security.ssl.SSLSocketImpl.access$300(SSLSocketImpl.java:73) ~[na:1.8.0_504]
  953 + at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:966) ~[na:1.8.0_504]
  954 + at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137) ~[httpcore-4.4.11.jar!/:4.4.11]
  955 + at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153) ~[httpcore-4.4.11.jar!/:4.4.11]
  956 + at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:280) ~[httpcore-4.4.11.jar!/:4.4.11]
  957 + at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138) ~[httpclient-4.5.14.jar!/:4.5.14]
  958 + at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56) ~[httpclient-4.5.14.jar!/:4.5.14]
  959 + at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259) ~[httpcore-4.4.11.jar!/:4.4.11]
  960 + at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163) ~[httpcore-4.4.11.jar!/:4.4.11]
  961 + at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157) ~[httpclient-4.5.14.jar!/:4.5.14]
  962 + at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273) ~[httpcore-4.4.11.jar!/:4.4.11]
  963 + at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125) ~[httpcore-4.4.11.jar!/:4.4.11]
  964 + at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272) ~[httpclient-4.5.14.jar!/:4.5.14]
  965 + at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) ~[httpclient-4.5.14.jar!/:4.5.14]
  966 + at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) ~[httpclient-4.5.14.jar!/:4.5.14]
  967 + at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[httpclient-4.5.14.jar!/:4.5.14]
  968 + at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.14.jar!/:4.5.14]
  969 + at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) ~[httpclient-4.5.14.jar!/:4.5.14]
  970 + at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) ~[httpclient-4.5.14.jar!/:4.5.14]
  971 + at com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils.run(JsonHttpUtils.java:102) ~[classes!/:1.0.0-SNAPSHOT]
  972 + at com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils.execute(JsonHttpUtils.java:96) ~[classes!/:1.0.0-SNAPSHOT]
  973 + at com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils.get(JsonHttpUtils.java:71) ~[classes!/:1.0.0-SNAPSHOT]
  974 + at com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils.getJson2Obj(JsonHttpUtils.java:78) ~[classes!/:1.0.0-SNAPSHOT]
  975 + at com.qgutech.qgyun.apaas.sync.jdy.api.QxApi.login(QxApi.java:45) ~[classes!/:1.0.0-SNAPSHOT]
  976 + at com.qgutech.qgyun.apaas.sync.jdy.service.JdyRiskStatisticsService.context(JdyRiskStatisticsService.java:129) ~[classes!/:1.0.0-SNAPSHOT]
  977 + at com.qgutech.qgyun.apaas.sync.jdy.service.JdyRiskStatisticsService.countAndSyncOne(JdyRiskStatisticsService.java:86) ~[classes!/:1.0.0-SNAPSHOT]
  978 + at com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOne(JdyRiskController.java:65) ~[classes!/:1.0.0-SNAPSHOT]
  979 + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_504]
  980 + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_504]
  981 + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_504]
  982 + at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_504]
  983 + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  984 + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  985 + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  986 + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  987 + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) ~[spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  988 + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  989 + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) ~[spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  990 + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  991 + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:981) ~[spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  992 + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:884) ~[spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  993 + at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  994 + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:858) ~[spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  995 + at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  996 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  997 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  998 + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.39.jar!/:8.5.39]
  999 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1000 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1001 + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1002 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1003 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1004 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1005 + at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) ~[spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1006 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1007 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1008 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1009 + at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1010 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1011 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1012 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1013 + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1014 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1015 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1016 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1017 + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1018 + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1019 + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1020 + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1021 + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1022 + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1023 + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1024 + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1025 + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1026 + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1027 + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1028 + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1029 + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_504]
  1030 + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_504]
  1031 + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1032 + at java.lang.Thread.run(Thread.java:750) [na:1.8.0_504]
  1033 +
  1034 +2026-09-16 19:32:14.286 INFO 13164 --- [http-nio-8090-exec-5] c.q.q.a.s.j.s.JdyRiskStatisticsService : ========== 开始单场景统计并写回: count_7 ==========
  1035 +2026-09-16 19:32:14.808 INFO 13164 --- [http-nio-8090-exec-5] c.q.qgyun.apaas.sync.jdy.api.QxApi : 启效登录成功: https://hfca.uat3.qgutech.com (corpCode=hfca, user=15077901670)
  1036 +2026-09-16 19:32:15.349 INFO 13164 --- [http-nio-8090-exec-5] c.q.q.a.s.j.s.JdyRiskStatisticsService : 启效记录总数=48(按 syncCode 本地匹配)
  1037 +2026-09-16 19:35:51.126 INFO 13164 --- [http-nio-8090-exec-5] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景7 排除来源 entry=686b6fd1e3cdf473acade9ac 累计条码=213358
  1038 +2026-09-16 19:35:53.600 INFO 13164 --- [http-nio-8090-exec-5] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景7 排除来源 entry=686b781c11159446bb2583fc 累计条码=215549
  1039 +2026-09-16 19:40:00.860 WARN 13164 --- [http-nio-8090-exec-5] c.q.q.apaas.sync.jdy.util.JsonHttpUtils : HTTP POST -> https://jdy.changan.com.cn/api/v5/app/entry/data/list : {"code":8303,"msg":"The call frequency of the company/team exceeds the frequency limit."}
  1040 +2026-09-16 19:40:00.861 WARN 13164 --- [http-nio-8090-exec-5] c.q.q.apaas.sync.jdy.api.JiandaoYunApi : 简道云频率限制(8303),2000ms 后重试(第1次)
  1041 +2026-09-16 19:40:39.754 INFO 13164 --- [http-nio-8090-exec-5] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景7 主表扫描=208438条, 过滤后保留=53条 (排除条码=215549, 超期阈值=180天)
  1042 +2026-09-16 19:40:39.755 INFO 13164 --- [http-nio-8090-exec-5] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_7] 命中=53 (参与统计53条)
  1043 +2026-09-16 19:40:39.920 INFO 13164 --- [http-nio-8090-exec-5] c.q.q.a.s.j.s.JdyExcelExportService : 导出 Excel: D:\code\qx-apaas-sync\.\export\20260916194039.xlsx (53 条)
  1044 +2026-09-16 19:40:40.155 ERROR 13164 --- [http-nio-8090-exec-5] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景[count_7] 写回失败
  1045 +
  1046 +java.lang.RuntimeException: 上传文件失败: 请求失败: https://uat3.qgutech.com/qx-api/qgyun-service-fs-store/file/uploadChunk?__tk=NOT_REQUIRED -> Connection reset
  1047 + at com.qgutech.qgyun.apaas.sync.jdy.api.QxApi.uploadFile(QxApi.java:373) ~[classes!/:1.0.0-SNAPSHOT]
  1048 + at com.qgutech.qgyun.apaas.sync.jdy.service.JdyRiskStatisticsService.syncOneScenario(JdyRiskStatisticsService.java:191) [classes!/:1.0.0-SNAPSHOT]
  1049 + at com.qgutech.qgyun.apaas.sync.jdy.service.JdyRiskStatisticsService.countAndSyncOne(JdyRiskStatisticsService.java:86) [classes!/:1.0.0-SNAPSHOT]
  1050 + at com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOne(JdyRiskController.java:65) [classes!/:1.0.0-SNAPSHOT]
  1051 + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_504]
  1052 + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_504]
  1053 + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_504]
  1054 + at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_504]
  1055 + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1056 + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1057 + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1058 + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1059 + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1060 + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1061 + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1062 + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1063 + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:981) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1064 + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:884) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1065 + at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1066 + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:858) [spring-webmvc-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1067 + at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1068 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1069 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1070 + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.39.jar!/:8.5.39]
  1071 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1072 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1073 + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1074 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1075 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1076 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1077 + at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1078 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1079 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1080 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1081 + at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1082 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1083 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1084 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1085 + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1086 + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.13.RELEASE.jar!/:5.0.13.RELEASE]
  1087 + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1088 + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1089 + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1090 + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1091 + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1092 + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1093 + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1094 + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1095 + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1096 + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1097 + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1098 + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1099 + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1100 + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1101 + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_504]
  1102 + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_504]
  1103 + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.39.jar!/:8.5.39]
  1104 + at java.lang.Thread.run(Thread.java:750) [na:1.8.0_504]
  1105 +Caused by: java.lang.RuntimeException: 请求失败: https://uat3.qgutech.com/qx-api/qgyun-service-fs-store/file/uploadChunk?__tk=NOT_REQUIRED -> Connection reset
  1106 + at com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils.run(JsonHttpUtils.java:111) ~[classes!/:1.0.0-SNAPSHOT]
  1107 + at com.qgutech.qgyun.apaas.sync.jdy.api.QxApi.uploadFile(QxApi.java:351) ~[classes!/:1.0.0-SNAPSHOT]
  1108 + ... 57 common frames omitted
  1109 +Caused by: javax.net.ssl.SSLException: Connection reset
  1110 + at sun.security.ssl.Alert.createSSLException(Alert.java:127) ~[na:1.8.0_504]
  1111 + at sun.security.ssl.TransportContext.fatal(TransportContext.java:332) ~[na:1.8.0_504]
  1112 + at sun.security.ssl.TransportContext.fatal(TransportContext.java:275) ~[na:1.8.0_504]
  1113 + at sun.security.ssl.TransportContext.fatal(TransportContext.java:270) ~[na:1.8.0_504]
  1114 + at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1572) ~[na:1.8.0_504]
  1115 + at sun.security.ssl.SSLSocketImpl.access$400(SSLSocketImpl.java:73) ~[na:1.8.0_504]
  1116 + at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:982) ~[na:1.8.0_504]
  1117 + at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137) ~[httpcore-4.4.11.jar!/:4.4.11]
  1118 + at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153) ~[httpcore-4.4.11.jar!/:4.4.11]
  1119 + at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:280) ~[httpcore-4.4.11.jar!/:4.4.11]
  1120 + at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138) ~[httpclient-4.5.14.jar!/:4.5.14]
  1121 + at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56) ~[httpclient-4.5.14.jar!/:4.5.14]
  1122 + at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259) ~[httpcore-4.4.11.jar!/:4.4.11]
  1123 + at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163) ~[httpcore-4.4.11.jar!/:4.4.11]
  1124 + at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157) ~[httpclient-4.5.14.jar!/:4.5.14]
  1125 + at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273) ~[httpcore-4.4.11.jar!/:4.4.11]
  1126 + at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125) ~[httpcore-4.4.11.jar!/:4.4.11]
  1127 + at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272) ~[httpclient-4.5.14.jar!/:4.5.14]
  1128 + at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) ~[httpclient-4.5.14.jar!/:4.5.14]
  1129 + at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) ~[httpclient-4.5.14.jar!/:4.5.14]
  1130 + at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[httpclient-4.5.14.jar!/:4.5.14]
  1131 + at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.14.jar!/:4.5.14]
  1132 + at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) ~[httpclient-4.5.14.jar!/:4.5.14]
  1133 + at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) ~[httpclient-4.5.14.jar!/:4.5.14]
  1134 + at com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils.run(JsonHttpUtils.java:102) ~[classes!/:1.0.0-SNAPSHOT]
  1135 + ... 58 common frames omitted
  1136 + Suppressed: java.net.SocketException: Connection reset by peer: socket write error
  1137 + at java.net.SocketOutputStream.socketWrite0(Native Method) ~[na:1.8.0_504]
  1138 + at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111) ~[na:1.8.0_504]
  1139 + at java.net.SocketOutputStream.write(SocketOutputStream.java:155) ~[na:1.8.0_504]
  1140 + at sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81) ~[na:1.8.0_504]
  1141 + at sun.security.ssl.TransportContext.fatal(TransportContext.java:368) ~[na:1.8.0_504]
  1142 + ... 81 common frames omitted
  1143 +Caused by: java.net.SocketException: Connection reset
  1144 + at java.net.SocketInputStream.read(SocketInputStream.java:210) ~[na:1.8.0_504]
  1145 + at java.net.SocketInputStream.read(SocketInputStream.java:141) ~[na:1.8.0_504]
  1146 + at sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:464) ~[na:1.8.0_504]
  1147 + at sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:68) ~[na:1.8.0_504]
  1148 + at sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1350) ~[na:1.8.0_504]
  1149 + at sun.security.ssl.SSLSocketImpl.access$300(SSLSocketImpl.java:73) ~[na:1.8.0_504]
  1150 + at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:966) ~[na:1.8.0_504]
  1151 + ... 76 common frames omitted
  1152 +
  1153 +2026-09-16 19:41:10.256 INFO 12724 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Starting QxApaasSyncApplication v1.0.0-SNAPSHOT on CQCA7304093 with PID 12724 (D:\code\qx-apaas-sync\target\qx-apaas-sync-1.0.0-SNAPSHOT.jar started by Administrator in D:\code\qx-apaas-sync)
  1154 +2026-09-16 19:41:10.275 INFO 12724 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : No active profile set, falling back to default profiles: default
  1155 +2026-09-16 19:41:10.368 INFO 12724 --- [main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2b80d80f: startup date [Wed Sep 16 19:41:10 CST 2026]; root of context hierarchy
  1156 +2026-09-16 19:41:12.797 INFO 12724 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8090 (http)
  1157 +2026-09-16 19:41:12.888 INFO 12724 --- [main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
  1158 +2026-09-16 19:41:12.889 INFO 12724 --- [main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.39
  1159 +2026-09-16 19:41:12.914 INFO 12724 --- [localhost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\nodejs\;D:\apache-maven-3.5.3\bin;C:\mysql\mysql-8.4.9-winx64\bin;C:\Program Files\Git\cmd;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\AppData\Roaming\npm;C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\bin;.]
  1160 +2026-09-16 19:41:13.107 INFO 12724 --- [localhost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
  1161 +2026-09-16 19:41:13.107 INFO 12724 --- [localhost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2740 ms
  1162 +2026-09-16 19:41:13.237 INFO 12724 --- [localhost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
  1163 +2026-09-16 19:41:13.244 INFO 12724 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
  1164 +2026-09-16 19:41:13.245 INFO 12724 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
  1165 +2026-09-16 19:41:13.246 INFO 12724 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
  1166 +2026-09-16 19:41:13.247 INFO 12724 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
  1167 +2026-09-16 19:41:13.570 INFO 12724 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  1168 +2026-09-16 19:41:14.024 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2b80d80f: startup date [Wed Sep 16 19:41:10 CST 2026]; root of context hierarchy
  1169 +2026-09-16 19:41:14.412 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel-form],methods=[POST]}" onto public java.lang.String com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcelForm(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)
  1170 +2026-09-16 19:41:14.429 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-data],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncData()
  1171 +2026-09-16 19:41:14.435 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcel()
  1172 +2026-09-16 19:41:14.436 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-structure],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncStructure()
  1173 +2026-09-16 19:41:14.450 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.count()
  1174 +2026-09-16 19:41:14.461 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.sync()
  1175 +2026-09-16 19:41:14.462 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync/{scenarioId}],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOneGet(java.lang.String)
  1176 +2026-09-16 19:41:14.463 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncGet()
  1177 +2026-09-16 19:41:14.464 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count/{scenarioId}],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countOneGet(java.lang.String)
  1178 +2026-09-16 19:41:14.466 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync/{scenarioId}],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOne(java.lang.String)
  1179 +2026-09-16 19:41:14.467 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countGet()
  1180 +2026-09-16 19:41:14.468 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count/{scenarioId}],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countOne(java.lang.String)
  1181 +2026-09-16 19:41:14.473 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/all],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncAll()
  1182 +2026-09-16 19:41:14.484 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/{appName}],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncOne(java.lang.String)
  1183 +2026-09-16 19:41:14.490 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
  1184 +2026-09-16 19:41:14.495 INFO 12724 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
  1185 +2026-09-16 19:41:14.534 INFO 12724 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  1186 +2026-09-16 19:41:14.535 INFO 12724 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  1187 +2026-09-16 19:41:14.916 INFO 12724 --- [main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
  1188 +2026-09-16 19:41:14.938 INFO 12724 --- [main] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
  1189 +2026-09-16 19:41:15.146 INFO 12724 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8090 (http) with context path ''
  1190 +2026-09-16 19:41:15.154 INFO 12724 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Started QxApaasSyncApplication in 6.492 seconds (JVM running for 7.526)
  1191 +2026-09-16 19:41:35.396 INFO 12724 --- [http-nio-8090-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
  1192 +2026-09-16 19:41:35.396 INFO 12724 --- [http-nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
  1193 +2026-09-16 19:41:35.426 INFO 12724 --- [http-nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 29 ms
  1194 +2026-09-16 19:41:35.478 INFO 12724 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : ========== 开始单场景统计并写回: count_7 ==========
  1195 +2026-09-16 19:41:43.784 INFO 12724 --- [http-nio-8090-exec-1] c.q.qgyun.apaas.sync.jdy.api.QxApi : 启效登录成功: https://hfca.uat3.qgutech.com (corpCode=hfca, user=15077901670)
  1196 +2026-09-16 19:41:44.313 INFO 12724 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : 启效记录总数=48(按 syncCode 本地匹配)
  1197 +2026-09-16 19:45:46.480 INFO 12724 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景7 排除来源 entry=686b6fd1e3cdf473acade9ac 累计条码=213358
  1198 +2026-09-16 19:45:48.985 INFO 12724 --- [http-nio-8090-exec-1] c.q.q.a.s.j.s.JdyRiskStatisticsService : 场景7 排除来源 entry=686b781c11159446bb2583fc 累计条码=215549
  1199 +2026-09-16 19:53:05.461 INFO 296 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Starting QxApaasSyncApplication v1.0.0-SNAPSHOT on CQCA7304093 with PID 296 (D:\code\qx-apaas-sync\target\qx-apaas-sync-1.0.0-SNAPSHOT.jar started by Administrator in D:\code\qx-apaas-sync)
  1200 +2026-09-16 19:53:05.486 INFO 296 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : No active profile set, falling back to default profiles: default
  1201 +2026-09-16 19:53:05.594 INFO 296 --- [main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@721e0f4f: startup date [Wed Sep 16 19:53:05 CST 2026]; root of context hierarchy
  1202 +2026-09-16 19:53:07.604 INFO 296 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8090 (http)
  1203 +2026-09-16 19:53:07.648 INFO 296 --- [main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
  1204 +2026-09-16 19:53:07.649 INFO 296 --- [main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.39
  1205 +2026-09-16 19:53:07.666 INFO 296 --- [localhost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\nodejs\;D:\apache-maven-3.5.3\bin;C:\mysql\mysql-8.4.9-winx64\bin;C:\Program Files\Git\cmd;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\AppData\Roaming\npm;C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\bin;.]
  1206 +2026-09-16 19:53:07.782 INFO 296 --- [localhost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
  1207 +2026-09-16 19:53:07.783 INFO 296 --- [localhost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2189 ms
  1208 +2026-09-16 19:53:07.894 INFO 296 --- [localhost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
  1209 +2026-09-16 19:53:07.900 INFO 296 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
  1210 +2026-09-16 19:53:07.901 INFO 296 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
  1211 +2026-09-16 19:53:07.902 INFO 296 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
  1212 +2026-09-16 19:53:07.902 INFO 296 --- [localhost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
  1213 +2026-09-16 19:53:08.265 INFO 296 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  1214 +2026-09-16 19:53:08.548 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@721e0f4f: startup date [Wed Sep 16 19:53:05 CST 2026]; root of context hierarchy
  1215 +2026-09-16 19:53:08.779 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-data],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncData()
  1216 +2026-09-16 19:53:08.781 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel-form],methods=[POST]}" onto public java.lang.String com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcelForm(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)
  1217 +2026-09-16 19:53:08.782 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-structure],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncStructure()
  1218 +2026-09-16 19:53:08.783 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcel()
  1219 +2026-09-16 19:53:08.790 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.count()
  1220 +2026-09-16 19:53:08.791 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.sync()
  1221 +2026-09-16 19:53:08.792 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncGet()
  1222 +2026-09-16 19:53:08.793 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countGet()
  1223 +2026-09-16 19:53:08.794 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count/{scenarioId}],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countOne(java.lang.String)
  1224 +2026-09-16 19:53:08.795 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count/{scenarioId}],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countOneGet(java.lang.String)
  1225 +2026-09-16 19:53:08.796 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync/{scenarioId}],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOne(java.lang.String)
  1226 +2026-09-16 19:53:08.798 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync/{scenarioId}],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOneGet(java.lang.String)
  1227 +2026-09-16 19:53:08.800 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/all],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncAll()
  1228 +2026-09-16 19:53:08.801 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/{appName}],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncOne(java.lang.String)
  1229 +2026-09-16 19:53:08.807 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
  1230 +2026-09-16 19:53:08.809 INFO 296 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
  1231 +2026-09-16 19:53:08.843 INFO 296 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  1232 +2026-09-16 19:53:08.855 INFO 296 --- [main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  1233 +2026-09-16 19:53:09.092 INFO 296 --- [main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
  1234 +2026-09-16 19:53:09.109 INFO 296 --- [main] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
  1235 +2026-09-16 19:53:09.200 INFO 296 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8090 (http) with context path ''
  1236 +2026-09-16 19:53:09.206 INFO 296 --- [main] c.q.q.apaas.sync.QxApaasSyncApplication : Started QxApaasSyncApplication in 4.749 seconds (JVM running for 5.387)
... ...
No preview for this file type
No preview for this file type
  1 +
  2 + . ____ _ __ _ _
  3 + /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
  4 +( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
  5 + \\/ ___)| |_)| | | | | || (_| | ) ) ) )
  6 + ' |____| .__|_| |_|_| |_\__, | / / / /
  7 + =========|_|==============|___/=/_/_/_/
  8 + :: Spring Boot :: (v2.0.9.RELEASE)
  9 +
  10 +2026-09-16 19:53:05.461 INFO 296 --- [ main] c.q.q.apaas.sync.QxApaasSyncApplication : Starting QxApaasSyncApplication v1.0.0-SNAPSHOT on CQCA7304093 with PID 296 (D:\code\qx-apaas-sync\target\qx-apaas-sync-1.0.0-SNAPSHOT.jar started by Administrator in D:\code\qx-apaas-sync)
  11 +2026-09-16 19:53:05.486 INFO 296 --- [ main] c.q.q.apaas.sync.QxApaasSyncApplication : No active profile set, falling back to default profiles: default
  12 +2026-09-16 19:53:05.594 INFO 296 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@721e0f4f: startup date [Wed Sep 16 19:53:05 CST 2026]; root of context hierarchy
  13 +2026-09-16 19:53:07.604 INFO 296 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8090 (http)
  14 +2026-09-16 19:53:07.648 INFO 296 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
  15 +2026-09-16 19:53:07.649 INFO 296 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.39
  16 +2026-09-16 19:53:07.666 INFO 296 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\nodejs\;D:\apache-maven-3.5.3\bin;C:\mysql\mysql-8.4.9-winx64\bin;C:\Program Files\Git\cmd;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\AppData\Roaming\npm;C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\bin;.]
  17 +2026-09-16 19:53:07.782 INFO 296 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
  18 +2026-09-16 19:53:07.783 INFO 296 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2189 ms
  19 +2026-09-16 19:53:07.894 INFO 296 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
  20 +2026-09-16 19:53:07.900 INFO 296 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
  21 +2026-09-16 19:53:07.901 INFO 296 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
  22 +2026-09-16 19:53:07.902 INFO 296 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
  23 +2026-09-16 19:53:07.902 INFO 296 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
  24 +2026-09-16 19:53:08.265 INFO 296 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  25 +2026-09-16 19:53:08.548 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@721e0f4f: startup date [Wed Sep 16 19:53:05 CST 2026]; root of context hierarchy
  26 +2026-09-16 19:53:08.779 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-data],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncData()
  27 +2026-09-16 19:53:08.781 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel-form],methods=[POST]}" onto public java.lang.String com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcelForm(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)
  28 +2026-09-16 19:53:08.782 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/sync-structure],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.syncStructure()
  29 +2026-09-16 19:53:08.783 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/form/export-excel],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyFormController.exportExcel()
  30 +2026-09-16 19:53:08.790 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.count()
  31 +2026-09-16 19:53:08.791 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.sync()
  32 +2026-09-16 19:53:08.792 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncGet()
  33 +2026-09-16 19:53:08.793 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countGet()
  34 +2026-09-16 19:53:08.794 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count/{scenarioId}],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countOne(java.lang.String)
  35 +2026-09-16 19:53:08.795 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/count/{scenarioId}],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.countOneGet(java.lang.String)
  36 +2026-09-16 19:53:08.796 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync/{scenarioId}],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOne(java.lang.String)
  37 +2026-09-16 19:53:08.798 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/risk/sync/{scenarioId}],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Object> com.qgutech.qgyun.apaas.sync.jdy.controller.JdyRiskController.syncOneGet(java.lang.String)
  38 +2026-09-16 19:53:08.800 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/all],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncAll()
  39 +2026-09-16 19:53:08.801 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/jdy/sync/{appName}],methods=[POST]}" onto public java.util.List<java.lang.String> com.qgutech.qgyun.apaas.sync.jdy.controller.JdySyncController.syncOne(java.lang.String)
  40 +2026-09-16 19:53:08.807 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
  41 +2026-09-16 19:53:08.809 INFO 296 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
  42 +2026-09-16 19:53:08.843 INFO 296 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  43 +2026-09-16 19:53:08.855 INFO 296 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
  44 +2026-09-16 19:53:09.092 INFO 296 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
  45 +2026-09-16 19:53:09.109 INFO 296 --- [ main] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
  46 +2026-09-16 19:53:09.200 INFO 296 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8090 (http) with context path ''
  47 +2026-09-16 19:53:09.206 INFO 296 --- [ main] c.q.q.apaas.sync.QxApaasSyncApplication : Started QxApaasSyncApplication in 4.749 seconds (JVM running for 5.387)
... ...
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <modelVersion>4.0.0</modelVersion>
  6 +
  7 + <groupId>com.qgutech.qgyun.apaas</groupId>
  8 + <artifactId>qx-apaas-sync</artifactId>
  9 + <version>1.0.0-SNAPSHOT</version>
  10 + <packaging>jar</packaging>
  11 + <name>qx-apaas-sync</name>
  12 + <description>简道云 -> 启效 独立同步工具(无中间件依赖,java -jar 运行)</description>
  13 +
  14 + <parent>
  15 + <groupId>org.springframework.boot</groupId>
  16 + <artifactId>spring-boot-starter-parent</artifactId>
  17 + <version>2.0.9.RELEASE</version>
  18 + <relativePath/>
  19 + </parent>
  20 +
  21 + <properties>
  22 + <java.version>1.8</java.version>
  23 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  24 + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  25 + <fastjson.version>2.0.6</fastjson.version>
  26 + <httpclient.version>4.5.14</httpclient.version>
  27 + <poi.version>4.1.2</poi.version>
  28 + </properties>
  29 +
  30 + <dependencies>
  31 + <!-- Web:提供内嵌 Tomcat 容器 + Spring MVC(REST 触发接口),非外部中间件 -->
  32 + <dependency>
  33 + <groupId>org.springframework.boot</groupId>
  34 + <artifactId>spring-boot-starter-web</artifactId>
  35 + </dependency>
  36 +
  37 + <!-- JSON 处理 -->
  38 + <dependency>
  39 + <groupId>com.alibaba</groupId>
  40 + <artifactId>fastjson</artifactId>
  41 + <version>${fastjson.version}</version>
  42 + </dependency>
  43 +
  44 + <!-- HTTP 客户端(简道云 / 启效写侧调用) -->
  45 + <dependency>
  46 + <groupId>org.apache.httpcomponents</groupId>
  47 + <artifactId>httpclient</artifactId>
  48 + <version>${httpclient.version}</version>
  49 + </dependency>
  50 +
  51 + <!-- multipart(启效附件上传) -->
  52 + <dependency>
  53 + <groupId>org.apache.httpcomponents</groupId>
  54 + <artifactId>httpmime</artifactId>
  55 + <version>${httpclient.version}</version>
  56 + </dependency>
  57 +
  58 + <!-- Excel 处理(导出简道云数据) -->
  59 + <dependency>
  60 + <groupId>org.apache.poi</groupId>
  61 + <artifactId>poi-ooxml</artifactId>
  62 + <version>${poi.version}</version>
  63 + </dependency>
  64 +
  65 + <!-- 简化代码 -->
  66 + <dependency>
  67 + <groupId>org.projectlombok</groupId>
  68 + <artifactId>lombok</artifactId>
  69 + <version>1.18.20</version>
  70 + <scope>provided</scope>
  71 + </dependency>
  72 +
  73 + <!-- 测试 -->
  74 + <dependency>
  75 + <groupId>org.springframework.boot</groupId>
  76 + <artifactId>spring-boot-starter-test</artifactId>
  77 + <scope>test</scope>
  78 + </dependency>
  79 + </dependencies>
  80 +
  81 + <build>
  82 + <plugins>
  83 + <plugin>
  84 + <groupId>org.springframework.boot</groupId>
  85 + <artifactId>spring-boot-maven-plugin</artifactId>
  86 + <executions>
  87 + <execution>
  88 + <goals>
  89 + <goal>repackage</goal>
  90 + </goals>
  91 + </execution>
  92 + </executions>
  93 + </plugin>
  94 + <plugin>
  95 + <groupId>org.apache.maven.plugins</groupId>
  96 + <artifactId>maven-compiler-plugin</artifactId>
  97 + <configuration>
  98 + <source>${java.version}</source>
  99 + <target>${java.version}</target>
  100 + <encoding>${project.build.sourceEncoding}</encoding>
  101 + </configuration>
  102 + </plugin>
  103 + </plugins>
  104 + </build>
  105 +</project>
... ...
  1 +@echo off
  2 +chcp 65001 >nul
  3 +rem ============================================================
  4 +rem qx-apaas-sync 前台启动:日志实时刷新到本窗口
  5 +rem Ctrl+C 停止应用
  6 +rem ============================================================
  7 +set "JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-8.0.504.1-hotspot"
  8 +set "JAR=target\qx-apaas-sync-1.0.0-SNAPSHOT.jar"
  9 +cd /d "%~dp0"
  10 +
  11 +echo ============================================================
  12 +echo 启动 qx-apaas-sync(前台运行,日志实时刷新)
  13 +echo Ctrl+C 停止应用
  14 +echo ============================================================
  15 +"%JAVA_HOME%\bin\java.exe" -Dfile.encoding=UTF-8 -jar "%JAR%"
  16 +
  17 +echo.
  18 +echo [exit] 应用已退出,按任意键关闭窗口...
  19 +pause >nul
... ...
  1 +package com.qgutech.qgyun.apaas.sync;
  2 +
  3 +import org.springframework.boot.SpringApplication;
  4 +import org.springframework.boot.autoconfigure.SpringBootApplication;
  5 +
  6 +/**
  7 + * 简道云 -> 启效 独立同步工具启动类。
  8 + * <p>
  9 + * 无中间件依赖:单 jar(内嵌 Tomcat)+ 仅 Java 环境即可运行。配置在 application.yml(jdy-sync.*)。
  10 + */
  11 +@SpringBootApplication
  12 +public class QxApaasSyncApplication {
  13 +
  14 + public static void main(String[] args) {
  15 + SpringApplication.run(QxApaasSyncApplication.class, args);
  16 + }
  17 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.api;
  2 +
  3 +import com.alibaba.fastjson.JSONArray;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +
  8 +import java.util.Arrays;
  9 +import java.util.HashMap;
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +/**
  14 + * 简道云开放平台 v5 客户端。
  15 + * <p>
  16 + * 鉴权:{@code Authorization: Bearer <apiKey>}。HOST:
  17 + * 公有云 {@code https://api.jiandaoyun.com/api};独立域名/独享版 {@code https://<域名>/api}。
  18 + * <p>
  19 + * 普通类,由 JdyToQxSyncService 按配置实例化。
  20 + */
  21 +@Slf4j
  22 +public class JiandaoYunApi {
  23 +
  24 + private final String host;
  25 +
  26 + public JiandaoYunApi(String host) {
  27 + this.host = host == null || host.isEmpty() ? "https://api.jiandaoyun.com/api" : stripSlash(host);
  28 + }
  29 +
  30 + private static String stripSlash(String s) {
  31 + return s.endsWith("/") ? s.substring(0, s.length() - 1) : s;
  32 + }
  33 +
  34 + /**
  35 + * 按名称在权限内查找应用,返回 app_id;找不到返回 null。
  36 + */
  37 + public String findAppId(String apiKey, String appName) {
  38 + JSONObject resp = JsonHttpUtils.postJson2Obj(host + "/v5/app/list",
  39 + JsonHttpUtils.bearer(apiKey), json("skip", 0, "limit", 100));
  40 + JSONArray apps = resp.getJSONArray("apps");
  41 + if (apps == null) {
  42 + return null;
  43 + }
  44 + for (int i = 0; i < apps.size(); i++) {
  45 + JSONObject app = apps.getJSONObject(i);
  46 + if (appName.equals(app.getString("name"))) {
  47 + return app.getString("app_id");
  48 + }
  49 + }
  50 + return null;
  51 + }
  52 +
  53 + /**
  54 + * 应用下表单列表。返回元素的字段:name, app_id, entry_id。
  55 + */
  56 + public JSONArray listForms(String apiKey, String appId) {
  57 + JSONObject resp = JsonHttpUtils.postJson2Obj(host + "/v5/app/entry/list",
  58 + JsonHttpUtils.bearer(apiKey), json("app_id", appId, "skip", 0, "limit", 100));
  59 + return resp.getJSONArray("forms") == null ? new JSONArray() : resp.getJSONArray("forms");
  60 + }
  61 +
  62 + /**
  63 + * 分页拉取应用下全部表单(v5 /v5/app/entry/list 单页 limit 上限 100,需按 skip 翻页直到返回不足一页)。
  64 + */
  65 + public JSONArray listAllForms(String apiKey, String appId) {
  66 + JSONArray all = new JSONArray();
  67 + int skip = 0;
  68 + int limit = 100;
  69 + while (true) {
  70 + JSONObject resp = JsonHttpUtils.postJson2Obj(host + "/v5/app/entry/list",
  71 + JsonHttpUtils.bearer(apiKey), json("app_id", appId, "skip", skip, "limit", limit));
  72 + JSONArray forms = resp.getJSONArray("forms");
  73 + if (forms == null || forms.isEmpty()) {
  74 + break;
  75 + }
  76 + all.addAll(forms);
  77 + if (forms.size() < limit) {
  78 + break;
  79 + }
  80 + skip += limit;
  81 + }
  82 + return all;
  83 + }
  84 +
  85 + /**
  86 + * 表单字段(控件)列表。字段:name(=表单字段code), label(中文名), type。
  87 + */
  88 + public JSONArray listWidgets(String apiKey, String appId, String entryId) {
  89 + JSONObject resp = JsonHttpUtils.postJson2Obj(host + "/v5/app/entry/widget/list",
  90 + JsonHttpUtils.bearer(apiKey), json("app_id", appId, "entry_id", entryId));
  91 + return resp.getJSONArray("widgets") == null ? new JSONArray() : resp.getJSONArray("widgets");
  92 + }
  93 +
  94 + /**
  95 + * 表单数据列表(单页)。
  96 + */
  97 + public JSONArray listData(String apiKey, String appId, String entryId, int limit) {
  98 + JSONObject resp = JsonHttpUtils.postJson2Obj(host + "/v5/app/entry/data/list",
  99 + JsonHttpUtils.bearer(apiKey), dataPageBody(appId, entryId, limit, null));
  100 + return resp.getJSONArray("data") == null ? new JSONArray() : resp.getJSONArray("data");
  101 + }
  102 +
  103 + /** 带限流重试的数据拉取(遇到 code=8303 频率限制时退避重试)。fields 非空时只取这些列。 */
  104 + private JSONObject dataList(String apiKey, String appId, String entryId, String dataId, List<String> fields) {
  105 + Map<String, Object> body = new HashMap<>();
  106 + body.put("app_id", appId);
  107 + body.put("entry_id", entryId);
  108 + body.put("limit", 100);
  109 + if (dataId != null && !dataId.isEmpty()) {
  110 + body.put("data_id", dataId);
  111 + }
  112 + if (fields != null && !fields.isEmpty()) {
  113 + body.put("fields", fields);
  114 + }
  115 + RuntimeException last = null;
  116 + for (int attempt = 1; attempt <= 8; attempt++) {
  117 + JSONObject resp;
  118 + try {
  119 + resp = JsonHttpUtils.postJson2Obj(host + "/v5/app/entry/data/list",
  120 + JsonHttpUtils.bearer(apiKey), body);
  121 + } catch (RuntimeException ex) {
  122 + long wait = 3000L * attempt;
  123 + log.warn("简道云请求异常({}),{}ms 后重试(第{}次)", ex.getMessage(), wait, attempt);
  124 + try {
  125 + Thread.sleep(wait);
  126 + } catch (InterruptedException ignored) {
  127 + Thread.currentThread().interrupt();
  128 + }
  129 + last = ex;
  130 + continue;
  131 + }
  132 + Integer code = resp.getInteger("code");
  133 + if (code != null && code == 8303) {
  134 + long wait = 2000L * attempt;
  135 + log.warn("简道云频率限制(8303),{}ms 后重试(第{}次)", wait, attempt);
  136 + try {
  137 + Thread.sleep(wait);
  138 + } catch (InterruptedException ignored) {
  139 + Thread.currentThread().interrupt();
  140 + }
  141 + last = new IllegalStateException("简道云频率限制: " + resp.getString("msg"));
  142 + continue;
  143 + }
  144 + if (code != null && code != 0) {
  145 + throw new IllegalStateException("简道云数据拉取失败 code=" + code + " msg=" + resp.getString("msg"));
  146 + }
  147 + return resp;
  148 + }
  149 + throw last == null ? new IllegalStateException("简道云数据拉取失败") : last;
  150 + }
  151 +
  152 + private JSONObject dataList(String apiKey, String appId, String entryId, String dataId) {
  153 + return dataList(apiKey, appId, entryId, dataId, null);
  154 + }
  155 +
  156 + /**
  157 + * 全量拉取表单数据。
  158 + * <p>
  159 + * 注意:v5 /v5/app/entry/data/list 不返回 next_id,翻页用上一页最后一条的 _id 作为 data_id 继续取。
  160 + * 单页 limit 上限 100。
  161 + */
  162 + public JSONArray listAllData(String apiKey, String appId, String entryId) {
  163 + JSONArray all = new JSONArray();
  164 + String dataId = null;
  165 + int guard = 0;
  166 + int page = 0;
  167 + while (true) {
  168 + if (++guard > 100000) {
  169 + break;
  170 + }
  171 + page++;
  172 + JSONObject resp = dataList(apiKey, appId, entryId, dataId);
  173 + JSONArray data = resp.getJSONArray("data");
  174 + if (data == null || data.isEmpty()) {
  175 + break;
  176 + }
  177 + all.addAll(data);
  178 + log.info("简道云分页: app={} entry={} 第 {} 页 {} 条, 累计 {} 条",
  179 + appId, entryId, page, data.size(), all.size());
  180 + dataId = data.getJSONObject(data.size() - 1).getString("_id");
  181 + if (data.size() < 100) {
  182 + break;
  183 + }
  184 + }
  185 + log.info("简道云拉取完成: app={} entry={} 共 {} 条", appId, entryId, all.size());
  186 + return all;
  187 + }
  188 +
  189 + /**
  190 + * 构建表单数据分页请求 body;nextId 为 null 时不带 next_id(首屏),否则带 next_id 继续翻页。
  191 + */
  192 + public Map<String, Object> dataPageBody(String appId, String entryId, int limit, String nextId) {
  193 + Map<String, Object> m = new HashMap<>();
  194 + m.put("app_id", appId);
  195 + m.put("entry_id", entryId);
  196 + m.put("limit", limit);
  197 + if (nextId != null && !nextId.isEmpty()) {
  198 + m.put("next_id", nextId);
  199 + }
  200 + return m;
  201 + }
  202 +
  203 + /**
  204 + * 分页遍历表单数据(分批回调,避免一次性载入内存,适合大表)。
  205 + */
  206 + public void forEachPage(String apiKey, String appId, String entryId, java.util.function.Consumer<JSONArray> consumer) {
  207 + forEachPage(apiKey, appId, entryId, null, consumer);
  208 + }
  209 +
  210 + /** 分页遍历表单数据(可只取指定 fields,分批回调,适合大表)。 */
  211 + public void forEachPage(String apiKey, String appId, String entryId, List<String> fields,
  212 + java.util.function.Consumer<JSONArray> consumer) {
  213 + String dataId = null;
  214 + int guard = 0;
  215 + while (true) {
  216 + if (++guard > 1000000) {
  217 + break;
  218 + }
  219 + JSONObject resp = dataList(apiKey, appId, entryId, dataId, fields);
  220 + JSONArray data = resp.getJSONArray("data");
  221 + if (data == null || data.isEmpty()) {
  222 + break;
  223 + }
  224 + consumer.accept(data);
  225 + dataId = data.getJSONObject(data.size() - 1).getString("_id");
  226 + if (data.size() < 100) {
  227 + break;
  228 + }
  229 + }
  230 + }
  231 +
  232 + public String getHost() {
  233 + return host;
  234 + }
  235 +
  236 + private static Map<String, Object> json(Object... kv) {
  237 + Map<String, Object> m = new HashMap<>();
  238 + for (int i = 0; i < kv.length; i += 2) {
  239 + m.put(String.valueOf(kv[i]), kv[i + 1]);
  240 + }
  241 + return m;
  242 + }
  243 +
  244 + public static List<String> DATE_JDY_TYPES = Arrays.asList("datetime", "date");
  245 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.api;
  2 +
  3 +import com.alibaba.fastjson.JSONArray;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.apache.http.client.methods.HttpPost;
  8 +import org.apache.http.entity.ContentType;
  9 +import org.apache.http.entity.mime.MultipartEntityBuilder;
  10 +
  11 +import java.io.File;
  12 +import java.nio.charset.StandardCharsets;
  13 +import java.security.MessageDigest;
  14 +import java.util.ArrayList;
  15 +import java.util.HashMap;
  16 +import java.util.LinkedHashMap;
  17 +import java.util.List;
  18 +import java.util.Map;
  19 +
  20 +/**
  21 + * 启效(QX) v3 写侧客户端(HTTP 直连,可配置 base-url)。
  22 + * <p>
  23 + * 关键:鉴权头 {@code Authorization: <token>}(不带 Bearer、不带 businesscode),请求必须带 User-Agent。
  24 + * 写数据用表单「新增接口」{@code POST /qx-api/qx-apaas-run/ar/{appId}/{code}},body 直接用 fieldKey,日期传毫秒时间戳。
  25 + * <p>
  26 + * 普通类,由 JdyToQxSyncService 按配置实例化。
  27 + */
  28 +@Slf4j
  29 +public class QxApi {
  30 +
  31 + private static final String DSN_ID = "jJT229EDx5omwj1p5Ra";
  32 +
  33 + /** 应用元数据模型(用于查询应用列表/判断应用是否已存在)。 */
  34 + private static final String APP_DSN_ID = "MRZtdB0Z7E1nh8YfXdm";
  35 + private static final String APP_MODEL_ID = "BJzqlD5ANPR4DOic4uZ";
  36 +
  37 + private final String baseUrl;
  38 +
  39 + public QxApi(String baseUrl) {
  40 + this.baseUrl = baseUrl == null ? "" : (baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl);
  41 + }
  42 +
  43 + /** 登录:securityImg 取动态 key -> auth/login(明文密码)。返回 token。 */
  44 + public String login(String username, String password, String corpCode) {
  45 + JSONObject img = JsonHttpUtils.getJson2Obj(baseUrl + "/qx-api/qx-apaas-uc/user/securityImg",
  46 + new HashMap<>());
  47 + String key = img.getJSONObject("data").getString("key");
  48 + if (key == null) {
  49 + throw new IllegalStateException("securityImg 取 key 失败: " + img);
  50 + }
  51 + Map<String, Object> body = new HashMap<>();
  52 + body.put("autoLogin", false);
  53 + body.put("protocol1", true);
  54 + body.put("key", key);
  55 + body.put("loginType", "PWD");
  56 + body.put("username", username);
  57 + body.put("password", password);
  58 + body.put("corpCode", corpCode == null ? "default" : corpCode);
  59 + JSONObject resp = JsonHttpUtils.postJson2Obj(baseUrl + "/qx-api/qx-apaas-auth/server/auth/login",
  60 + new HashMap<>(), body);
  61 + if (!Boolean.TRUE.equals(resp.getBoolean("success"))) {
  62 + throw new IllegalStateException("启效登录失败: " + resp);
  63 + }
  64 + log.info("启效登录成功: {} (corpCode={}, user={})", baseUrl, corpCode, username);
  65 + return resp.getString("data");
  66 + }
  67 +
  68 + /** 建应用,返回 appId。 */
  69 + public String createApp(String token, String appName) {
  70 + Map<String, Object> body = new HashMap<>();
  71 + body.put("standardName", "默认规格");
  72 + body.put("cloudStatus", "WAIT_TO_CLOUD");
  73 + body.put("sourceCorpCode", "default");
  74 + body.put("source", "DEV");
  75 + body.put("type", "NORMAL");
  76 + body.put("useStatus", "ENABLED");
  77 + body.put("appName", appName);
  78 + JSONObject resp = JsonHttpUtils.postJson2Obj(
  79 + baseUrl + "/qx-api/qx-apaas-run/rt/MRZtdB0Z7E1nh8YfXdm/m/BJzqlD5ANPR4DOic4uZ/saveOrUpdate",
  80 + JsonHttpUtils.token(token), body);
  81 + return resp.getString("data");
  82 + }
  83 +
  84 + /**
  85 + * 按应用名查询启效应用 id;不存在返回 null。
  86 + * <p>
  87 + * 应用元数据模型:appId={@link #APP_DSN_ID},modelId={@link #APP_MODEL_ID},用 search 接口分页拉取后本地匹配。
  88 + */
  89 + public String findAppByName(String token, String appName) {
  90 + if (appName == null || appName.isEmpty()) {
  91 + return null;
  92 + }
  93 + int pageNum = 1;
  94 + int pageSize = 1000;
  95 + while (true) {
  96 + Map<String, Object> body = new HashMap<>();
  97 + body.put("pageNum", pageNum);
  98 + body.put("pageSize", pageSize);
  99 + JSONObject resp = JsonHttpUtils.postJson2Obj(
  100 + baseUrl + "/qx-api/qx-apaas-run/rt/" + APP_DSN_ID + "/m/" + APP_MODEL_ID + "/search",
  101 + JsonHttpUtils.token(token), body);
  102 + JSONObject data = resp.getJSONObject("data");
  103 + if (data == null) {
  104 + return null;
  105 + }
  106 + JSONArray list = data.getJSONArray("list");
  107 + if (list == null || list.isEmpty()) {
  108 + return null;
  109 + }
  110 + for (int i = 0; i < list.size(); i++) {
  111 + JSONObject app = list.getJSONObject(i);
  112 + if (appName.equals(app.getString("appName"))) {
  113 + return app.getString("id");
  114 + }
  115 + }
  116 + Integer total = data.getInteger("total");
  117 + if (total == null || pageNum * pageSize >= total) {
  118 + return null;
  119 + }
  120 + pageNum++;
  121 + }
  122 + }
  123 +
  124 + /** 查询某应用下所有内部接口。元素含:name, code, modelId, requestType, apiPluginCode。 */
  125 + public JSONArray listApiManages(String token, String appId) {
  126 + Map<String, String> headers = new HashMap<>(JsonHttpUtils.token(token));
  127 + String url = baseUrl + "/qx-api/qx-apaas-run/ar/apicentermanagement/oysPage"
  128 + + "?pageSize=100&pageNum=1&appId=" + appId + "&dataId=" + appId + "&pluginId=" + appId;
  129 + JSONObject resp = JsonHttpUtils.postJson2Obj(url, headers, new HashMap<String, Object>() {{
  130 + put("orderBy", new ArrayList<>());
  131 + put("searchConditions", null);
  132 + }});
  133 + JSONObject data = resp.getJSONObject("data");
  134 + return data == null ? new JSONArray() : data.getJSONArray("list");
  135 + }
  136 +
  137 + /** 取某表单「新增接口」对象。 */
  138 + public JSONObject findAddApi(JSONArray apiManages, String formName) {
  139 + if (apiManages == null) {
  140 + return null;
  141 + }
  142 + for (int i = 0; i < apiManages.size(); i++) {
  143 + JSONObject api = apiManages.getJSONObject(i);
  144 + String name = api.getString("name");
  145 + if (name != null && name.contains("新增") && (name.startsWith(formName) || name.equals(formName + "新增接口"))) {
  146 + return api;
  147 + }
  148 + }
  149 + return null;
  150 + }
  151 +
  152 + /** 按名字片段取接口(如"分页查询"、"删除")。 */
  153 + public JSONObject findApiByKeyword(JSONArray apiManages, String formName, String keyword) {
  154 + if (apiManages == null) {
  155 + return null;
  156 + }
  157 + for (int i = 0; i < apiManages.size(); i++) {
  158 + JSONObject api = apiManages.getJSONObject(i);
  159 + String name = api.getString("name");
  160 + if (name != null && name.contains(keyword) && name.startsWith(formName)) {
  161 + return api;
  162 + }
  163 + }
  164 + return null;
  165 + }
  166 +
  167 + /** 建表单模型,返回 modelId。 */
  168 + public String createFormModel(String token, String appId, String funName, String funCode) {
  169 + Map<String, Object> icon = new HashMap<>();
  170 + icon.put("name", "file");
  171 + icon.put("code", "file");
  172 + icon.put("type", "system");
  173 + icon.put("isSystem", true);
  174 + icon.put("groupName", "操作");
  175 + icon.put("lib", "图标库");
  176 + icon.put("iconColor", "var(--colorPrimary)");
  177 + icon.put("bgColor", "var(--colorPrimaryBg)");
  178 +
  179 + Map<String, Object> dsnObj = new HashMap<>();
  180 + dsnObj.put("icon", icon);
  181 + dsnObj.put("standards", new ArrayList<>());
  182 + dsnObj.put("engineVersion", "3.3");
  183 + dsnObj.put("funName", funName);
  184 + dsnObj.put("appId", appId);
  185 + dsnObj.put("funCode", funCode);
  186 + dsnObj.put("dsnCode", DSN_ID);
  187 + dsnObj.put("dsnId", DSN_ID);
  188 +
  189 + Map<String, Object> body = new HashMap<>();
  190 + body.put("category", "");
  191 + body.put("dsnObj", dsnObj);
  192 + JSONObject resp = JsonHttpUtils.postJson2Obj(baseUrl + "/qx-api/qx-apaas-run/app/modelDsnV2",
  193 + JsonHttpUtils.token(token), body);
  194 + if (!Boolean.TRUE.equals(resp.getBoolean("success"))) {
  195 + throw new IllegalStateException("建表单模型失败(" + funName + "): " + resp);
  196 + }
  197 + return resp.getString("data");
  198 + }
  199 +
  200 + /** 保存设计对象(表单字段),fields 为 [{title, fieldKey, type}]。 */
  201 + public void saveDesignObj(String token, String appId, String appName, String modelId,
  202 + String funName, String funCode, List<Field> fields) {
  203 + Map<String, Object> dsnObj = new HashMap<>();
  204 + dsnObj.put("id", modelId);
  205 + dsnObj.put("appId", appId);
  206 + Map<String, Object> app = new HashMap<>();
  207 + app.put("id", appId);
  208 + app.put("dataTitle", appName);
  209 + dsnObj.put("app", app);
  210 + dsnObj.put("funName", funName);
  211 + dsnObj.put("funCode", funCode);
  212 + dsnObj.put("dsnCode", DSN_ID);
  213 +
  214 + Map<String, Object> designCfg = new HashMap<>();
  215 + List<Map<String, Object>> comps = new ArrayList<>();
  216 + for (Field f : fields) {
  217 + comps.add(buildComp(f));
  218 + }
  219 + designCfg.put("comps", comps);
  220 + designCfg.put("columns", 1);
  221 + designCfg.put("type", "QxCompFormPage");
  222 + designCfg.put("dataType", appId + "." + modelId);
  223 + designCfg.put("layout", "vertical");
  224 + designCfg.put("formGridComponent", "__inherit");
  225 + designCfg.put("formPagePadding", "__inherit");
  226 + designCfg.put("formPageBg", "__inherit");
  227 + designCfg.put("formPageBgFillMode", "cover");
  228 + designCfg.put("formPageBgOpacity", "80.0");
  229 + designCfg.put("appId", appId);
  230 + designCfg.put("modelId", modelId);
  231 + designCfg.put("winCfg", winCfg());
  232 + designCfg.put("servicesCfg", new ArrayList<>());
  233 + designCfg.put("apisCfg", new ArrayList<>());
  234 + designCfg.put("events", new ArrayList<>());
  235 + dsnObj.put("designCfg", designCfg);
  236 +
  237 + dsnObj.put("engineVersion", "3.2");
  238 + Map<String, Object> icon = new HashMap<>();
  239 + icon.put("code", "info-circle");
  240 + icon.put("iconColor", "var(--colorPrimary)");
  241 + icon.put("bgColor", "var(--colorPrimaryBg)");
  242 + dsnObj.put("icon", icon);
  243 + dsnObj.put("name", "未命名");
  244 +
  245 + Map<String, Object> body = new HashMap<>();
  246 + body.put("id", DSN_ID);
  247 + body.put("dsnObj", dsnObj);
  248 +
  249 + Map<String, String> headers = new HashMap<>(JsonHttpUtils.token(token));
  250 + headers.put("pageType", "FORM");
  251 + JSONObject resp = JsonHttpUtils.postJson2Obj(baseUrl + "/qx-api/qx-apaas-plugin/dsn/saveDsnObj",
  252 + headers, body);
  253 + if (!Boolean.TRUE.equals(resp.getBoolean("success"))) {
  254 + throw new IllegalStateException("保存字段失败(" + funName + "): " + resp);
  255 + }
  256 + }
  257 +
  258 + /** 写一条数据(新增接口)。 */
  259 + public String insertData(String token, String appId, String code, Map<String, Object> payload) {
  260 + JSONObject resp = JsonHttpUtils.postJson2Obj(
  261 + baseUrl + "/qx-api/qx-apaas-run/ar/" + appId + "/" + code,
  262 + JsonHttpUtils.token(token), payload);
  263 + if (!Boolean.TRUE.equals(resp.getBoolean("success"))) {
  264 + throw new IllegalStateException("写入数据失败: " + resp);
  265 + }
  266 + return resp.getString("data");
  267 + }
  268 +
  269 + /**
  270 + * 按 syncCode 查询一条业务数据(分页接口 + 查询参数),返回首条记录 JSONObject;无则 null。
  271 + * <p>
  272 + * 例:POST /ar/{appId}/ilr3ne7bPage?pageSize=10&pageNum=1&pcqqjoquery=SYNC0002
  273 + */
  274 + public JSONObject queryBySyncCode(String token, String appId, String queryCode,
  275 + String syncQueryParam, String syncCode) {
  276 + String url = baseUrl + "/qx-api/qx-apaas-run/ar/" + appId + "/" + queryCode
  277 + + "?pageSize=10&pageNum=1&" + syncQueryParam + "=" + urlEncode(syncCode);
  278 + log.info("查询业务数据: {}?{}={}", queryCode, syncQueryParam, syncCode);
  279 + JSONObject resp = JsonHttpUtils.postJson2Obj(url, JsonHttpUtils.token(token), new HashMap<String, Object>());
  280 + JSONObject data = resp.getJSONObject("data");
  281 + JSONArray list = data == null ? null : data.getJSONArray("list");
  282 + if (list == null || list.isEmpty()) {
  283 + log.warn("未查询到记录: syncCode={}", syncCode);
  284 + return null;
  285 + }
  286 + JSONObject rec = list.getJSONObject(0);
  287 + log.info("查询到记录: syncCode={} id={}", syncCode, rec.getString("id"));
  288 + return rec;
  289 + }
  290 +
  291 + /** 更新整条业务数据(更新接口,body 需含 id 及全部字段)。 */
  292 + public void updateData(String token, String appId, String code, JSONObject body) {
  293 + String dataId = body.getString("id");
  294 + log.info("更新业务数据: {} id={}", code, dataId);
  295 + JSONObject resp = JsonHttpUtils.postJson2Obj(
  296 + baseUrl + "/qx-api/qx-apaas-run/ar/" + appId + "/" + code,
  297 + JsonHttpUtils.token(token), body);
  298 + if (!Boolean.TRUE.equals(resp.getBoolean("success"))) {
  299 + throw new IllegalStateException("更新数据失败: " + resp);
  300 + }
  301 + log.info("更新成功: id={}", dataId);
  302 + }
  303 +
  304 + private static String urlEncode(String s) {
  305 + try {
  306 + return java.net.URLEncoder.encode(s == null ? "" : s, "UTF-8");
  307 + } catch (java.io.UnsupportedEncodingException e) {
  308 + return s;
  309 + }
  310 + }
  311 +
  312 + /**
  313 + * 上传文件到启效文件服务,返回 fileId。
  314 + * <p>
  315 + * 流程:checkFile(按 md5 检存)→ uploadChunk(multipart 单分片)→ mergeFileChunk。
  316 + */
  317 + public String uploadFile(String token, File file, String fileName) {
  318 + try {
  319 + String md5 = md5Hex(file);
  320 + String ext = (fileName != null && fileName.lastIndexOf('.') >= 0)
  321 + ? fileName.substring(fileName.lastIndexOf('.')) : "";
  322 + String checkUrl = baseUrl + "/qx-api/qgyun-service-fs-manager/file/checkFile"
  323 + + "?fileMd5=" + md5 + "&publicFile=false&fileExt=" + urlEncode(ext);
  324 + JSONObject check = JsonHttpUtils.getJson2Obj(checkUrl, JsonHttpUtils.token(token));
  325 + if (Boolean.TRUE.equals(check.getBoolean("success"))) {
  326 + String existId = check.getString("msg");
  327 + if (existId != null && !existId.isEmpty()) {
  328 + log.info("文件已存在, 复用 fileId={}", existId);
  329 + return existId;
  330 + }
  331 + }
  332 + JSONObject data = check.getJSONObject("data");
  333 + if (data == null) {
  334 + throw new IllegalStateException("checkFile 返回异常: " + check);
  335 + }
  336 + final String uploadUrl = data.getString("uploadUrl");
  337 + final String tk = data.getString("token");
  338 + final long size = file.length();
  339 +
  340 + RuntimeException last = null;
  341 + for (int attempt = 1; attempt <= 5; attempt++) {
  342 + try {
  343 + HttpPost post = new HttpPost(uploadUrl + "file/uploadChunk?__tk=" + tk);
  344 + post.setHeader("Authorization", token);
  345 + post.setHeader("User-Agent", JsonHttpUtils.USER_AGENT);
  346 + post.setEntity(MultipartEntityBuilder.create()
  347 + .addBinaryBody("file", file, ContentType.create("application/octet-stream"), fileName)
  348 + .addTextBody("name", fileName, ContentType.create("text/plain", StandardCharsets.UTF_8))
  349 + .addTextBody("fileMd5", md5, ContentType.create("text/plain", StandardCharsets.UTF_8))
  350 + .addTextBody("size", String.valueOf(size), ContentType.create("text/plain", StandardCharsets.UTF_8))
  351 + .addTextBody("chunkIndex", "0", ContentType.create("text/plain", StandardCharsets.UTF_8))
  352 + .addTextBody("chunkSize", "10485760", ContentType.create("text/plain", StandardCharsets.UTF_8))
  353 + .build());
  354 + String upResp = JsonHttpUtils.run(post);
  355 + JSONObject upObj = JsonHttpUtils.parse(upResp);
  356 + if (!Boolean.TRUE.equals(upObj.getBoolean("success"))) {
  357 + throw new IllegalStateException("上传分片失败: " + upResp);
  358 + }
  359 +
  360 + Map<String, Object> mergeBody = new HashMap<>();
  361 + mergeBody.put("fileName", fileName);
  362 + mergeBody.put("fileMd5", md5);
  363 + mergeBody.put("chunkCount", 1);
  364 + mergeBody.put("chunkSize", 10485760);
  365 + JSONObject merge = JsonHttpUtils.postJson2Obj(uploadUrl + "file/mergeFileChunk?__tk=" + tk,
  366 + JsonHttpUtils.token(token), mergeBody);
  367 + if (!Boolean.TRUE.equals(merge.getBoolean("success"))) {
  368 + throw new IllegalStateException("合并分片失败: " + merge);
  369 + }
  370 + String fileId = merge.getJSONObject("data").getString("fileId");
  371 + log.info("文件上传成功: {} -> fileId={}", fileName, fileId);
  372 + return fileId;
  373 + } catch (RuntimeException ex) {
  374 + long wait = 3000L * attempt;
  375 + log.warn("上传附件异常({}),{}ms 后重试(第{}次)", ex.getMessage(), wait, attempt);
  376 + try {
  377 + Thread.sleep(wait);
  378 + } catch (InterruptedException ignored) {
  379 + Thread.currentThread().interrupt();
  380 + }
  381 + last = ex;
  382 + }
  383 + }
  384 + throw last == null ? new IllegalStateException("上传文件失败") : last;
  385 + } catch (IllegalStateException e) {
  386 + throw e;
  387 + } catch (Exception e) {
  388 + throw new RuntimeException("上传文件失败: " + e.getMessage(), e);
  389 + }
  390 + }
  391 +
  392 + private static String md5Hex(File file) throws Exception {
  393 + MessageDigest md = MessageDigest.getInstance("MD5");
  394 + byte[] digest = md.digest(java.nio.file.Files.readAllBytes(file.toPath()));
  395 + StringBuilder sb = new StringBuilder();
  396 + for (byte b : digest) {
  397 + sb.append(String.format("%02x", b));
  398 + }
  399 + return sb.toString();
  400 + }
  401 +
  402 + /** 分页查询某表单数据,返回记录数组(含 id)。 */
  403 + public JSONArray pageQuery(String token, String appId, String pageCode) {
  404 + Map<String, Object> body = new HashMap<>();
  405 + body.put("pageNum", 1);
  406 + body.put("pageSize", 1000);
  407 + body.put("searchConditions", null);
  408 + JSONObject resp = JsonHttpUtils.postJson2Obj(
  409 + baseUrl + "/qx-api/qx-apaas-run/ar/" + appId + "/" + pageCode,
  410 + JsonHttpUtils.token(token), body);
  411 + JSONObject data = resp.getJSONObject("data");
  412 + return data == null ? new JSONArray() : data.getJSONArray("list");
  413 + }
  414 +
  415 + /** 分页拉取某表单全部数据(分页参数走 URL query),返回记录数组。 */
  416 + public JSONArray pageAll(String token, String appId, String pageCode) {
  417 + JSONArray all = new JSONArray();
  418 + int pageNum = 1;
  419 + int pageSize = 200;
  420 + while (true) {
  421 + String url = baseUrl + "/qx-api/qx-apaas-run/ar/" + appId + "/" + pageCode
  422 + + "?pageSize=" + pageSize + "&pageNum=" + pageNum;
  423 + JSONObject resp = JsonHttpUtils.postJson2Obj(url, JsonHttpUtils.token(token),
  424 + new HashMap<String, Object>());
  425 + if (!Boolean.TRUE.equals(resp.getBoolean("success"))) {
  426 + throw new IllegalStateException("分页查询失败(" + pageCode + "): " + resp.getString("msg")
  427 + + " [" + resp.getString("errCode") + "]");
  428 + }
  429 + JSONObject data = resp.getJSONObject("data");
  430 + JSONArray list = data == null ? null : data.getJSONArray("list");
  431 + if (list == null || list.isEmpty()) {
  432 + break;
  433 + }
  434 + all.addAll(list);
  435 + if (list.size() < pageSize) {
  436 + break;
  437 + }
  438 + pageNum++;
  439 + if (pageNum > 10000) {
  440 + break;
  441 + }
  442 + }
  443 + return all;
  444 + }
  445 +
  446 + /** 删除一条数据(单次删除接口,GET ?id=)。 */
  447 + public void deleteData(String token, String appId, String deleteCode, String dataId) {
  448 + String url = baseUrl + "/qx-api/qx-apaas-run/ar/" + appId + "/" + deleteCode + "?id=" + dataId;
  449 + JsonHttpUtils.get(url, JsonHttpUtils.token(token));
  450 + }
  451 +
  452 + private static Map<String, Object> buildComp(Field f) {
  453 + String compId = randomCompId();
  454 + String t = f.type;
  455 + Map<String, Object> props = new HashMap<>();
  456 + props.put("type", "string");
  457 + props.put("title", f.title);
  458 + props.put("compType", compType(t));
  459 + props.put("fieldKey", f.fieldKey);
  460 + props.put("descType", "icon");
  461 + props.put("propType", propType(t));
  462 + Map<String, Object> deco = new HashMap<>();
  463 + Map<String, Object> style = new HashMap<>();
  464 + style.put("width", "calc(100% - (var(--formGridColumnGap, 0px) / 2) * 0)");
  465 + deco.put("style", style);
  466 + props.put("decoratorProps", deco);
  467 + props.put("defaultConfig", new HashMap<>());
  468 + props.put("events", new ArrayList<>());
  469 + props.put("required", false);
  470 + if ("number".equals(t)) {
  471 + Map<String, Object> mpc = new HashMap<>();
  472 + mpc.put("unitPosition", "prefix");
  473 + mpc.put("isLimit", false);
  474 + mpc.put("isFormat", false);
  475 + props.put("modelPropCfg", mpc);
  476 + } else if ("text".equals(t)) {
  477 + // 文本字段默认限 50 字符,显式放开到 2000,避免长文本写入失败
  478 + Map<String, Object> mpc = new HashMap<>();
  479 + mpc.put("isLimit", true);
  480 + Map<String, Object> limit = new HashMap<>();
  481 + limit.put("min", 0);
  482 + limit.put("max", 2000);
  483 + mpc.put("limit", limit);
  484 + mpc.put("formatRules", new ArrayList<>());
  485 + props.put("modelPropCfg", mpc);
  486 + } else if ("date".equals(t)) {
  487 + Map<String, Object> mpc = new HashMap<>();
  488 + mpc.put("isLimit", false);
  489 + Map<String, Object> limit = new HashMap<>();
  490 + limit.put("max", "");
  491 + limit.put("min", "");
  492 + mpc.put("limit", limit);
  493 + mpc.put("timeLimit", false);
  494 + mpc.put("weekLimit", false);
  495 + mpc.put("minuteStep", 1);
  496 + mpc.put("secondStep", 1);
  497 + props.put("modelPropCfg", mpc);
  498 + props.put("format", "YYYY-MM-DD HH:mm");
  499 + props.put("showTime", false);
  500 + }
  501 + Map<String, Object> comp = new HashMap<>();
  502 + comp.put("compId", compId);
  503 + comp.put("compProps", props);
  504 + comp.put("compType", compType(t));
  505 + comp.put("pluginType", pluginType(t));
  506 + comp.put("decoratorCompType", "FormItem");
  507 + return comp;
  508 + }
  509 +
  510 + private static Map<String, Object> winCfg() {
  511 + Map<String, Object> win = new HashMap<>();
  512 + win.put("ADD_FORM", winForm("新增", "ADD_FORM"));
  513 + win.put("EDIT_FORM", winForm("编辑", "EDIT_FORM"));
  514 + Map<String, Object> view = new HashMap<>();
  515 + view.put("title", "查看");
  516 + view.put("code", "VIEW_FORM");
  517 + win.put("VIEW_FORM", view);
  518 + return win;
  519 + }
  520 +
  521 + private static Map<String, Object> winForm(String title, String code) {
  522 + Map<String, Object> wf = new HashMap<>();
  523 + wf.put("title", title);
  524 + wf.put("code", code);
  525 + List<Map<String, Object>> btns = new ArrayList<>();
  526 + Map<String, Object> cancel = new HashMap<>();
  527 + cancel.put("btnCode", "cancel");
  528 + cancel.put("position", "BR");
  529 + cancel.put("title", "取消");
  530 + btns.add(cancel);
  531 + Map<String, Object> save = new HashMap<>();
  532 + save.put("btnCode", "save");
  533 + save.put("position", "BR");
  534 + save.put("title", "保存");
  535 + btns.add(save);
  536 + wf.put("btns", btns);
  537 + return wf;
  538 + }
  539 +
  540 + private static final Map<String, String> COMP = new HashMap<>();
  541 + private static final Map<String, String> PROP = new HashMap<>();
  542 + private static final Map<String, String> PLUGIN = new HashMap<>();
  543 +
  544 + static {
  545 + COMP.put("text", "QxCompInput");
  546 + COMP.put("number", "QxCompInputNumber");
  547 + COMP.put("percent", "QxCompPercent");
  548 + COMP.put("switch", "QxCompSwitch");
  549 + COMP.put("date", "QxCompDatePicker");
  550 + PROP.put("text", "QxString");
  551 + PROP.put("number", "QxNumber");
  552 + PROP.put("percent", "QxPercent");
  553 + PROP.put("switch", "QxBoolean");
  554 + PROP.put("date", "QxDate");
  555 + PLUGIN.put("text", "Ge5BHkj7HRUDktxTHwm.8SEfp20rm8YjoveHwzZ");
  556 + PLUGIN.put("number", "OuiaGY2Ik57Op9UWJ2x.vgRH7o3nbajAN7zvPHP");
  557 + PLUGIN.put("percent", "6oU3NyeGbABi49acDSx.EU68OPxMm8EtonRCgra");
  558 + PLUGIN.put("switch", "Wvaw42w8NqIhAHM2oBU.rYFlWbFV2SvdqpSV6Cy");
  559 + PLUGIN.put("date", "HM01fexzlT73F6PKzhq.sdWqQBWPaItOAC31tCa");
  560 + }
  561 +
  562 + private static String compType(String t) {
  563 + return COMP.getOrDefault(t, "QxCompInput");
  564 + }
  565 +
  566 + private static String propType(String t) {
  567 + return PROP.getOrDefault(t, "QxString");
  568 + }
  569 +
  570 + private static String pluginType(String t) {
  571 + return PLUGIN.getOrDefault(t, "Ge5BHkj7HRUDktxTHwm.8SEfp20rm8YjoveHwzZ");
  572 + }
  573 +
  574 + private static String randomCompId() {
  575 + final String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  576 + StringBuilder sb = new StringBuilder();
  577 + java.util.concurrent.ThreadLocalRandom r = java.util.concurrent.ThreadLocalRandom.current();
  578 + for (int i = 0; i < 19; i++) {
  579 + sb.append(chars.charAt(r.nextInt(chars.length())));
  580 + }
  581 + return sb.toString();
  582 + }
  583 +
  584 + /** 表单字段定义:字段标题 + 语义 fieldKey + 启效类型(text/number/date/percent/switch)。 */
  585 + public static class Field {
  586 + private final String title;
  587 + private final String fieldKey;
  588 + private final String type;
  589 +
  590 + public Field(String title, String fieldKey, String type) {
  591 + this.title = title;
  592 + this.fieldKey = fieldKey;
  593 + this.type = type;
  594 + }
  595 +
  596 + public String getTitle() {
  597 + return title;
  598 + }
  599 +
  600 + public String getFieldKey() {
  601 + return fieldKey;
  602 + }
  603 +
  604 + public String getType() {
  605 + return type;
  606 + }
  607 + }
  608 +
  609 + public String getBaseUrl() {
  610 + return baseUrl;
  611 + }
  612 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.config;
  2 +
  3 +import org.springframework.boot.context.properties.ConfigurationProperties;
  4 +
  5 +import java.util.ArrayList;
  6 +import java.util.LinkedHashMap;
  7 +import java.util.List;
  8 +import java.util.Map;
  9 +
  10 +/**
  11 + * 表单结构/数据同步配置(简道云 -> 启效指定应用)。
  12 + * <p>
  13 + * 对应 application.yml / application.properties 的 jdy-form-sync 段。
  14 + * 用途:把简道云表单的字段结构镜像到启效某应用下(新建表单模型),
  15 + * 数据同步则只取当月数据、按天留存(当天已存在先删再同步)。
  16 + */
  17 +@ConfigurationProperties(prefix = "jdy-form-sync")
  18 +public class JdyFormSyncProperties {
  19 +
  20 + /** 简道云配置 */
  21 + private Jdy jdy = new Jdy();
  22 +
  23 + /** 启效(QX)目标配置 */
  24 + private Qx qx = new Qx();
  25 +
  26 + /** 可选:指定同步月份(yyyy-MM),用于补数/测试;留空=当前自然月 */
  27 + private String month;
  28 +
  29 + /** Excel 导出目录(相对 jar 运行目录),默认 ./export */
  30 + private String exportDir = "./export";
  31 +
  32 + /** 待同步的表单列表 */
  33 + private List<Form> forms = new ArrayList<>();
  34 +
  35 + public String getMonth() {
  36 + return month;
  37 + }
  38 +
  39 + public void setMonth(String month) {
  40 + this.month = month;
  41 + }
  42 +
  43 + public String getExportDir() {
  44 + return exportDir;
  45 + }
  46 +
  47 + public void setExportDir(String exportDir) {
  48 + this.exportDir = exportDir;
  49 + }
  50 +
  51 + public Jdy getJdy() {
  52 + return jdy;
  53 + }
  54 +
  55 + public void setJdy(Jdy jdy) {
  56 + this.jdy = jdy;
  57 + }
  58 +
  59 + public Qx getQx() {
  60 + return qx;
  61 + }
  62 +
  63 + public void setQx(Qx qx) {
  64 + this.qx = qx;
  65 + }
  66 +
  67 + public List<Form> getForms() {
  68 + return forms;
  69 + }
  70 +
  71 + public void setForms(List<Form> forms) {
  72 + this.forms = forms;
  73 + }
  74 +
  75 + /** 简道云侧配置。 */
  76 + public static class Jdy {
  77 + /** 简道云基础地址(长安:https://jdy.changan.com.cn/api) */
  78 + private String host = "https://jdy.changan.com.cn/api";
  79 + /** 简道云 API_KEY */
  80 + private String apiKey;
  81 +
  82 + public String getHost() {
  83 + return host;
  84 + }
  85 +
  86 + public void setHost(String host) {
  87 + this.host = host;
  88 + }
  89 +
  90 + public String getApiKey() {
  91 + return apiKey;
  92 + }
  93 +
  94 + public void setApiKey(String apiKey) {
  95 + this.apiKey = apiKey;
  96 + }
  97 + }
  98 +
  99 + /** 启效(QX)侧目标配置。 */
  100 + public static class Qx {
  101 + private String baseUrl;
  102 + private String username;
  103 + private String password;
  104 + private String corpCode = "default";
  105 + /** 目标应用 appId(表单建在该应用下) */
  106 + private String appId;
  107 + /** 目标应用名称(saveDesignObj 需要) */
  108 + private String appName;
  109 +
  110 + public String getBaseUrl() {
  111 + return baseUrl;
  112 + }
  113 +
  114 + public void setBaseUrl(String baseUrl) {
  115 + this.baseUrl = baseUrl;
  116 + }
  117 +
  118 + public String getUsername() {
  119 + return username;
  120 + }
  121 +
  122 + public void setUsername(String username) {
  123 + this.username = username;
  124 + }
  125 +
  126 + public String getPassword() {
  127 + return password;
  128 + }
  129 +
  130 + public void setPassword(String password) {
  131 + this.password = password;
  132 + }
  133 +
  134 + public String getCorpCode() {
  135 + return corpCode;
  136 + }
  137 +
  138 + public void setCorpCode(String corpCode) {
  139 + this.corpCode = corpCode;
  140 + }
  141 +
  142 + public String getAppId() {
  143 + return appId;
  144 + }
  145 +
  146 + public void setAppId(String appId) {
  147 + this.appId = appId;
  148 + }
  149 +
  150 + public String getAppName() {
  151 + return appName;
  152 + }
  153 +
  154 + public void setAppName(String appName) {
  155 + this.appName = appName;
  156 + }
  157 + }
  158 +
  159 + /** 单个待同步表单。 */
  160 + public static class Form {
  161 + /** 简道云应用 app_id */
  162 + private String appId;
  163 + /** 简道云表单 entry_id */
  164 + private String entryId;
  165 + /** 启效表单名(默认用简道云表单名;.properties 读为 ISO-8859-1,不建议在此写中文) */
  166 + private String name;
  167 + /** 启效表单 funCode(默认按名称语义生成) */
  168 + private String funCode;
  169 + /** 已有启效表单模型 id;填了则原地更新该模型(不新建) */
  170 + private String modelId;
  171 + /** 简道云日期字段 code(用于「当月」过滤),如 _widget_xxx */
  172 + private String dateField;
  173 + /** 是否只同步当月数据;false=同步全部数据 */
  174 + private boolean monthOnly = true;
  175 + /** 字段映射覆盖(简道云字段中文名 -> 语义 fieldKey) */
  176 + private Map<String, String> fieldMapping = new LinkedHashMap<>();
  177 +
  178 + public String getAppId() {
  179 + return appId;
  180 + }
  181 +
  182 + public void setAppId(String appId) {
  183 + this.appId = appId;
  184 + }
  185 +
  186 + public String getEntryId() {
  187 + return entryId;
  188 + }
  189 +
  190 + public void setEntryId(String entryId) {
  191 + this.entryId = entryId;
  192 + }
  193 +
  194 + public String getName() {
  195 + return name;
  196 + }
  197 +
  198 + public void setName(String name) {
  199 + this.name = name;
  200 + }
  201 +
  202 + public String getFunCode() {
  203 + return funCode;
  204 + }
  205 +
  206 + public void setFunCode(String funCode) {
  207 + this.funCode = funCode;
  208 + }
  209 +
  210 + public String getModelId() {
  211 + return modelId;
  212 + }
  213 +
  214 + public void setModelId(String modelId) {
  215 + this.modelId = modelId;
  216 + }
  217 +
  218 + public String getDateField() {
  219 + return dateField;
  220 + }
  221 +
  222 + public void setDateField(String dateField) {
  223 + this.dateField = dateField;
  224 + }
  225 +
  226 + public boolean isMonthOnly() {
  227 + return monthOnly;
  228 + }
  229 +
  230 + public void setMonthOnly(boolean monthOnly) {
  231 + this.monthOnly = monthOnly;
  232 + }
  233 +
  234 + public Map<String, String> getFieldMapping() {
  235 + return fieldMapping;
  236 + }
  237 +
  238 + public void setFieldMapping(Map<String, String> fieldMapping) {
  239 + this.fieldMapping = fieldMapping;
  240 + }
  241 + }
  242 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.config;
  2 +
  3 +import org.springframework.boot.context.properties.ConfigurationProperties;
  4 +
  5 +import java.util.ArrayList;
  6 +import java.util.List;
  7 +
  8 +/**
  9 + * 风险场景统计配置。
  10 + * <p>
  11 + * 对应 application.yml 的 jdy-risk 段:调用长安简道云开放 API,读取指定表单数据,
  12 + * 按预定义规则过滤,输出各场景命中计数(count_1/count_2/count_3)。
  13 + */
  14 +@ConfigurationProperties(prefix = "jdy-risk")
  15 +public class JdyRiskProperties {
  16 +
  17 + /** 简道云基础地址(独立域名/独享版 https://<域名>/api) */
  18 + private String host = "https://jdy.changan.com.cn/api";
  19 +
  20 + /** 简道云 API_KEY(Bearer token) */
  21 + private String apiKey;
  22 +
  23 + /** 启效(QX)写回配置(把统计结果更新到目标应用表单) */
  24 + private Qx qx = new Qx();
  25 +
  26 + /** 场景清单 */
  27 + private List<Scenario> scenarios = new ArrayList<>();
  28 +
  29 + public String getHost() {
  30 + return host;
  31 + }
  32 +
  33 + public void setHost(String host) {
  34 + this.host = host;
  35 + }
  36 +
  37 + public String getApiKey() {
  38 + return apiKey;
  39 + }
  40 +
  41 + public void setApiKey(String apiKey) {
  42 + this.apiKey = apiKey;
  43 + }
  44 +
  45 + public Qx getQx() {
  46 + return qx;
  47 + }
  48 +
  49 + public void setQx(Qx qx) {
  50 + this.qx = qx;
  51 + }
  52 +
  53 + public List<Scenario> getScenarios() {
  54 + return scenarios;
  55 + }
  56 +
  57 + public void setScenarios(List<Scenario> scenarios) {
  58 + this.scenarios = scenarios;
  59 + }
  60 +
  61 + /** 启效(QX)写回目标配置。 */
  62 + public static class Qx {
  63 + /** 启效环境地址,如 https://hfca.uat3.qgutech.com */
  64 + private String baseUrl;
  65 + private String username;
  66 + private String password;
  67 + private String corpCode = "default";
  68 + /** 目标应用 appId */
  69 + private String appId;
  70 + /** 按 syncCode 查询记录的分页接口 code(如 ilr3ne7bPage) */
  71 + private String queryCode;
  72 + /** 查询时 syncCode 对应的查询参数名(如 pcqqjoquery) */
  73 + private String syncQueryParam;
  74 + /** 更新接口 code(如 11a41Update) */
  75 + private String updateCode;
  76 + /** 写回数量的字段编号(如 chcbxt) */
  77 + private String countField;
  78 + /** 附件字段编号(如 hciwkz);配置了则把简道云数据 Excel 作为附件写入(关联ID字段自动取 {attachField}Id) */
  79 + private String attachField;
  80 +
  81 + public String getBaseUrl() {
  82 + return baseUrl;
  83 + }
  84 +
  85 + public void setBaseUrl(String baseUrl) {
  86 + this.baseUrl = baseUrl;
  87 + }
  88 +
  89 + public String getUsername() {
  90 + return username;
  91 + }
  92 +
  93 + public void setUsername(String username) {
  94 + this.username = username;
  95 + }
  96 +
  97 + public String getPassword() {
  98 + return password;
  99 + }
  100 +
  101 + public void setPassword(String password) {
  102 + this.password = password;
  103 + }
  104 +
  105 + public String getCorpCode() {
  106 + return corpCode;
  107 + }
  108 +
  109 + public void setCorpCode(String corpCode) {
  110 + this.corpCode = corpCode;
  111 + }
  112 +
  113 + public String getAppId() {
  114 + return appId;
  115 + }
  116 +
  117 + public void setAppId(String appId) {
  118 + this.appId = appId;
  119 + }
  120 +
  121 + public String getQueryCode() {
  122 + return queryCode;
  123 + }
  124 +
  125 + public void setQueryCode(String queryCode) {
  126 + this.queryCode = queryCode;
  127 + }
  128 +
  129 + public String getSyncQueryParam() {
  130 + return syncQueryParam;
  131 + }
  132 +
  133 + public void setSyncQueryParam(String syncQueryParam) {
  134 + this.syncQueryParam = syncQueryParam;
  135 + }
  136 +
  137 + public String getUpdateCode() {
  138 + return updateCode;
  139 + }
  140 +
  141 + public void setUpdateCode(String updateCode) {
  142 + this.updateCode = updateCode;
  143 + }
  144 +
  145 + public String getCountField() {
  146 + return countField;
  147 + }
  148 +
  149 + public void setCountField(String countField) {
  150 + this.countField = countField;
  151 + }
  152 +
  153 + public String getAttachField() {
  154 + return attachField;
  155 + }
  156 +
  157 + public void setAttachField(String attachField) {
  158 + this.attachField = attachField;
  159 + }
  160 + }
  161 +
  162 + /**
  163 + * 单个统计场景。
  164 + * <p>
  165 + * type 取值:
  166 + * <ul>
  167 + * <li>scenario1:全量,满足 总计&gt;=5 且 差值&gt;=1 且 flowState=进行中 的行数</li>
  168 + * <li>scenario2:当月,按供应商分组,SI问题数量/问题数量合计&gt;60% 且 问题数量合计&gt;=5 的供应商个数</li>
  169 + * <li>scenario3:当月,SI占比&gt;60% 且 总问题数&gt;=5 的行数(工程师个数)</li>
  170 + * </ul>
  171 + */
  172 + public static class Scenario {
  173 + /** 输出键,如 count_1 */
  174 + private String id;
  175 + /** 场景名称 */
  176 + private String name;
  177 + /** 场景类型:scenario1 / scenario2 / scenario3 */
  178 + private String type;
  179 + /** 简道云应用 app_id */
  180 + private String appId;
  181 + /** 简道云表单 entry_id */
  182 + private String entryId;
  183 + /** 日期字段(当月过滤用) */
  184 + private String dateField;
  185 + /** 总计/总问题数字段 */
  186 + private String totalField;
  187 + /** 差值字段(scenario1) */
  188 + private String diffField;
  189 + /** 分组字段(scenario2,供应商名称) */
  190 + private String groupField;
  191 + /** 责任判定字段(scenario2,取值 SI 表示供应商责任) */
  192 + private String siField;
  193 + /** 问题数量字段(scenario2) */
  194 + private String qtyField;
  195 + /** SI占比字段(scenario3,表单已算好) */
  196 + private String ratioField;
  197 + /** 进行中对应的 flowState 值(scenario1,默认 0) */
  198 + private int inProgressState = 0;
  199 + /** 是否仅统计当月数据 */
  200 + private boolean monthOnly = false;
  201 + /** 是否仅统计当季度数据(scenario4/5) */
  202 + private boolean quarterOnly = false;
  203 + /** 是否仅统计当前年份(1月1日至今,scenario6) */
  204 + private boolean yearOnly = false;
  205 + /** 是否仅统计上个月(scenario8/9) */
  206 + private boolean prevMonthOnly = false;
  207 + /** 「升级」字段 code(scenario4/5) */
  208 + private String upField;
  209 + /** 「升级」需排除的取值(scenario4/5,空白始终排除);如 [QR] */
  210 + private List<String> excludeValues = new ArrayList<>();
  211 + /** 分组命中阈值(scenario4/5/6:分组次数 >= minCount 才算命中) */
  212 + private int minCount = 0;
  213 + /** 比率字段 code(scenario8/9,如 是否开启CR) */
  214 + private String flagField;
  215 + /** 比率字段命中值(scenario8/9,如 否) */
  216 + private String flagValue;
  217 + /** 比率阈值(scenario8/9,默认 0.7) */
  218 + private double ratioThreshold = 0.7;
  219 + /** 条码字段 code(scenario7,主表) */
  220 + private String barcodeField;
  221 + /** 需要排除的条码来源表单(scenario7) */
  222 + private List<ExcludeForm> excludeForms = new ArrayList<>();
  223 + /** 超期天数(scenario7:入库时间距今超过该天数才保留,默认 180) */
  224 + private int maxAgeDays = 180;
  225 + /** 只取这些字段列(scenario7:主表只拉需要的列,减小传输;空=全字段) */
  226 + private List<String> fields = new ArrayList<>();
  227 + /** Excel 附加列取值的字段 code(为空时 scenario1 默认写「命中」) */
  228 + private String extraField;
  229 + /** 写回启效目标记录的 syncCode(如 SYNC0001) */
  230 + private String syncCode;
  231 +
  232 + public String getId() {
  233 + return id;
  234 + }
  235 +
  236 + public void setId(String id) {
  237 + this.id = id;
  238 + }
  239 +
  240 + public String getName() {
  241 + return name;
  242 + }
  243 +
  244 + public void setName(String name) {
  245 + this.name = name;
  246 + }
  247 +
  248 + public String getType() {
  249 + return type;
  250 + }
  251 +
  252 + public void setType(String type) {
  253 + this.type = type;
  254 + }
  255 +
  256 + public String getAppId() {
  257 + return appId;
  258 + }
  259 +
  260 + public void setAppId(String appId) {
  261 + this.appId = appId;
  262 + }
  263 +
  264 + public String getEntryId() {
  265 + return entryId;
  266 + }
  267 +
  268 + public void setEntryId(String entryId) {
  269 + this.entryId = entryId;
  270 + }
  271 +
  272 + public String getDateField() {
  273 + return dateField;
  274 + }
  275 +
  276 + public void setDateField(String dateField) {
  277 + this.dateField = dateField;
  278 + }
  279 +
  280 + public String getTotalField() {
  281 + return totalField;
  282 + }
  283 +
  284 + public void setTotalField(String totalField) {
  285 + this.totalField = totalField;
  286 + }
  287 +
  288 + public String getDiffField() {
  289 + return diffField;
  290 + }
  291 +
  292 + public void setDiffField(String diffField) {
  293 + this.diffField = diffField;
  294 + }
  295 +
  296 + public String getGroupField() {
  297 + return groupField;
  298 + }
  299 +
  300 + public void setGroupField(String groupField) {
  301 + this.groupField = groupField;
  302 + }
  303 +
  304 + public String getSiField() {
  305 + return siField;
  306 + }
  307 +
  308 + public void setSiField(String siField) {
  309 + this.siField = siField;
  310 + }
  311 +
  312 + public String getQtyField() {
  313 + return qtyField;
  314 + }
  315 +
  316 + public void setQtyField(String qtyField) {
  317 + this.qtyField = qtyField;
  318 + }
  319 +
  320 + public String getRatioField() {
  321 + return ratioField;
  322 + }
  323 +
  324 + public void setRatioField(String ratioField) {
  325 + this.ratioField = ratioField;
  326 + }
  327 +
  328 + public int getInProgressState() {
  329 + return inProgressState;
  330 + }
  331 +
  332 + public void setInProgressState(int inProgressState) {
  333 + this.inProgressState = inProgressState;
  334 + }
  335 +
  336 + public boolean isMonthOnly() {
  337 + return monthOnly;
  338 + }
  339 +
  340 + public void setMonthOnly(boolean monthOnly) {
  341 + this.monthOnly = monthOnly;
  342 + }
  343 +
  344 + public boolean isQuarterOnly() {
  345 + return quarterOnly;
  346 + }
  347 +
  348 + public void setQuarterOnly(boolean quarterOnly) {
  349 + this.quarterOnly = quarterOnly;
  350 + }
  351 +
  352 + public boolean isYearOnly() {
  353 + return yearOnly;
  354 + }
  355 +
  356 + public void setYearOnly(boolean yearOnly) {
  357 + this.yearOnly = yearOnly;
  358 + }
  359 +
  360 + public boolean isPrevMonthOnly() {
  361 + return prevMonthOnly;
  362 + }
  363 +
  364 + public void setPrevMonthOnly(boolean prevMonthOnly) {
  365 + this.prevMonthOnly = prevMonthOnly;
  366 + }
  367 +
  368 + public String getFlagField() {
  369 + return flagField;
  370 + }
  371 +
  372 + public void setFlagField(String flagField) {
  373 + this.flagField = flagField;
  374 + }
  375 +
  376 + public String getFlagValue() {
  377 + return flagValue;
  378 + }
  379 +
  380 + public void setFlagValue(String flagValue) {
  381 + this.flagValue = flagValue;
  382 + }
  383 +
  384 + public double getRatioThreshold() {
  385 + return ratioThreshold;
  386 + }
  387 +
  388 + public void setRatioThreshold(double ratioThreshold) {
  389 + this.ratioThreshold = ratioThreshold;
  390 + }
  391 +
  392 + public String getBarcodeField() {
  393 + return barcodeField;
  394 + }
  395 +
  396 + public void setBarcodeField(String barcodeField) {
  397 + this.barcodeField = barcodeField;
  398 + }
  399 +
  400 + public List<ExcludeForm> getExcludeForms() {
  401 + return excludeForms;
  402 + }
  403 +
  404 + public void setExcludeForms(List<ExcludeForm> excludeForms) {
  405 + this.excludeForms = excludeForms;
  406 + }
  407 +
  408 + public int getMaxAgeDays() {
  409 + return maxAgeDays;
  410 + }
  411 +
  412 + public void setMaxAgeDays(int maxAgeDays) {
  413 + this.maxAgeDays = maxAgeDays;
  414 + }
  415 +
  416 + public List<String> getFields() {
  417 + return fields;
  418 + }
  419 +
  420 + public void setFields(List<String> fields) {
  421 + this.fields = fields;
  422 + }
  423 +
  424 + public String getUpField() {
  425 + return upField;
  426 + }
  427 +
  428 + public void setUpField(String upField) {
  429 + this.upField = upField;
  430 + }
  431 +
  432 + public List<String> getExcludeValues() {
  433 + return excludeValues;
  434 + }
  435 +
  436 + public void setExcludeValues(List<String> excludeValues) {
  437 + this.excludeValues = excludeValues;
  438 + }
  439 +
  440 + public int getMinCount() {
  441 + return minCount;
  442 + }
  443 +
  444 + public void setMinCount(int minCount) {
  445 + this.minCount = minCount;
  446 + }
  447 +
  448 + public String getExtraField() {
  449 + return extraField;
  450 + }
  451 +
  452 + public void setExtraField(String extraField) {
  453 + this.extraField = extraField;
  454 + }
  455 +
  456 + public String getSyncCode() {
  457 + return syncCode;
  458 + }
  459 +
  460 + public void setSyncCode(String syncCode) {
  461 + this.syncCode = syncCode;
  462 + }
  463 + }
  464 +
  465 + /** scenario7:需要排除的条码来源表单。 */
  466 + public static class ExcludeForm {
  467 + /** 简道云表单 entry_id */
  468 + private String entryId;
  469 + /** 条码字段 code(取值与主表 barcode-field 匹配则排除主表该行) */
  470 + private String barcodeField;
  471 +
  472 + public String getEntryId() {
  473 + return entryId;
  474 + }
  475 +
  476 + public void setEntryId(String entryId) {
  477 + this.entryId = entryId;
  478 + }
  479 +
  480 + public String getBarcodeField() {
  481 + return barcodeField;
  482 + }
  483 +
  484 + public void setBarcodeField(String barcodeField) {
  485 + this.barcodeField = barcodeField;
  486 + }
  487 + }
  488 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.config;
  2 +
  3 +import org.springframework.boot.context.properties.EnableConfigurationProperties;
  4 +import org.springframework.context.annotation.Configuration;
  5 +import org.springframework.scheduling.annotation.EnableScheduling;
  6 +
  7 +/**
  8 + * 简道云同步相关配置装配:启用定时任务与配置属性。
  9 + */
  10 +@Configuration
  11 +@EnableScheduling
  12 +@EnableConfigurationProperties({JdySyncProperties.class, JdyRiskProperties.class, JdyFormSyncProperties.class})
  13 +public class JdySyncConfig {
  14 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.config;
  2 +
  3 +import org.springframework.boot.context.properties.ConfigurationProperties;
  4 +
  5 +import java.util.ArrayList;
  6 +import java.util.LinkedHashMap;
  7 +import java.util.List;
  8 +import java.util.Map;
  9 +
  10 +/**
  11 + * 简道云 -> 启效 同步配置。
  12 + * <p>
  13 + * 对应 application.yml 的 jdy-sync 段:
  14 + * <pre>
  15 + * jdy-sync:
  16 + * enabled: true
  17 + * qx:
  18 + * base-url: https://dev3.qgutech.com
  19 + * username: xx
  20 + * password: xx
  21 + * corp-code: default
  22 + * apps:
  23 + * - name: 组织管理
  24 + * api-key: xxx
  25 + * qx-app-id: xxx # 不填则按 name 自动在启效建应用
  26 + * replace: true # 是=每天清空后重建镜像;否=追加
  27 + * field-mapping: {姓名: name, 年龄: age} # 可选覆盖内置字典
  28 + * form-names: [人员管理, 部门管理] # 可选,空=同步全部表单
  29 + * </pre>
  30 + */
  31 +@ConfigurationProperties(prefix = "jdy-sync")
  32 +public class JdySyncProperties {
  33 +
  34 + /** 是否启用同步任务 */
  35 + private boolean enabled = true;
  36 +
  37 + /** 简道云基础地址(公有云 https://api.jiandaoyun.com/api;独立域名 https://<域名>/api) */
  38 + private String host = "https://api.jiandaoyun.com/api";
  39 +
  40 + /** 启效(QX)配置 */
  41 + private Qx qx = new Qx();
  42 +
  43 + public String getHost() {
  44 + return host;
  45 + }
  46 +
  47 + public void setHost(String host) {
  48 + this.host = host;
  49 + }
  50 +
  51 + /** 待同步的应用列表 */
  52 + private List<App> apps = new ArrayList<>();
  53 +
  54 + /** 每日执行 cron,默认每天 02:00 */
  55 + private String cron = "0 0 2 * * ?";
  56 +
  57 + public boolean isEnabled() {
  58 + return enabled;
  59 + }
  60 +
  61 + public void setEnabled(boolean enabled) {
  62 + this.enabled = enabled;
  63 + }
  64 +
  65 + public Qx getQx() {
  66 + return qx;
  67 + }
  68 +
  69 + public void setQx(Qx qx) {
  70 + this.qx = qx;
  71 + }
  72 +
  73 + public List<App> getApps() {
  74 + return apps;
  75 + }
  76 +
  77 + public void setApps(List<App> apps) {
  78 + this.apps = apps;
  79 + }
  80 +
  81 + public String getCron() {
  82 + return cron;
  83 + }
  84 +
  85 + public void setCron(String cron) {
  86 + this.cron = cron;
  87 + }
  88 +
  89 + public static class Qx {
  90 + private String baseUrl;
  91 + private String username;
  92 + private String password;
  93 + private String corpCode = "default";
  94 +
  95 + public String getBaseUrl() {
  96 + return baseUrl;
  97 + }
  98 +
  99 + public void setBaseUrl(String baseUrl) {
  100 + this.baseUrl = baseUrl;
  101 + }
  102 +
  103 + public String getUsername() {
  104 + return username;
  105 + }
  106 +
  107 + public void setUsername(String username) {
  108 + this.username = username;
  109 + }
  110 +
  111 + public String getPassword() {
  112 + return password;
  113 + }
  114 +
  115 + public void setPassword(String password) {
  116 + this.password = password;
  117 + }
  118 +
  119 + public String getCorpCode() {
  120 + return corpCode;
  121 + }
  122 +
  123 + public void setCorpCode(String corpCode) {
  124 + this.corpCode = corpCode;
  125 + }
  126 + }
  127 +
  128 + public static class App {
  129 + /** 简道云应用名 */
  130 + private String name;
  131 + /** 简道云 API_KEY(Bearer token) */
  132 + private String apiKey;
  133 + /** 简道云应用 app_id;不填则按 name 调用 /v5/app/list 反查(需应用列表权限) */
  134 + private String appId;
  135 + /** 可选:仅同步这些简道云表单 entry_id;空=同步该应用下全部表单 */
  136 + private List<String> entryIds = new ArrayList<>();
  137 + /** 目标启效应用 id;不填则按 name 自动创建 */
  138 + private String qxAppId;
  139 + /** 是=每天清空目标表单数据后重建镜像;否=追加 */
  140 + private boolean replace = true;
  141 + /** 可选字段映射(中文名 -> 语义 fieldKey),覆盖内置字典 */
  142 + private Map<String, String> fieldMapping = new LinkedHashMap<>();
  143 + /** 可选:仅同步这些表单(简道云表单名);空=全部 */
  144 + private List<String> formNames = new ArrayList<>();
  145 +
  146 + public String getName() {
  147 + return name;
  148 + }
  149 +
  150 + public void setName(String name) {
  151 + this.name = name;
  152 + }
  153 +
  154 + public String getApiKey() {
  155 + return apiKey;
  156 + }
  157 +
  158 + public void setApiKey(String apiKey) {
  159 + this.apiKey = apiKey;
  160 + }
  161 +
  162 + public String getAppId() {
  163 + return appId;
  164 + }
  165 +
  166 + public void setAppId(String appId) {
  167 + this.appId = appId;
  168 + }
  169 +
  170 + public List<String> getEntryIds() {
  171 + return entryIds;
  172 + }
  173 +
  174 + public void setEntryIds(List<String> entryIds) {
  175 + this.entryIds = entryIds;
  176 + }
  177 +
  178 + public String getQxAppId() {
  179 + return qxAppId;
  180 + }
  181 +
  182 + public void setQxAppId(String qxAppId) {
  183 + this.qxAppId = qxAppId;
  184 + }
  185 +
  186 + public boolean isReplace() {
  187 + return replace;
  188 + }
  189 +
  190 + public void setReplace(boolean replace) {
  191 + this.replace = replace;
  192 + }
  193 +
  194 + public Map<String, String> getFieldMapping() {
  195 + return fieldMapping;
  196 + }
  197 +
  198 + public void setFieldMapping(Map<String, String> fieldMapping) {
  199 + this.fieldMapping = fieldMapping;
  200 + }
  201 +
  202 + public List<String> getFormNames() {
  203 + return formNames;
  204 + }
  205 +
  206 + public void setFormNames(List<String> formNames) {
  207 + this.formNames = formNames;
  208 + }
  209 + }
  210 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.controller;
  2 +
  3 +import com.qgutech.qgyun.apaas.sync.jdy.service.JdyExcelExportService;
  4 +import com.qgutech.qgyun.apaas.sync.jdy.service.JdyFormSyncService;
  5 +import lombok.extern.slf4j.Slf4j;
  6 +import org.springframework.web.bind.annotation.PostMapping;
  7 +import org.springframework.web.bind.annotation.RequestMapping;
  8 +import org.springframework.web.bind.annotation.RequestParam;
  9 +import org.springframework.web.bind.annotation.RestController;
  10 +
  11 +import javax.annotation.Resource;
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * 简道云表单同步接口(结构 / 数据 / 导出)。
  16 + */
  17 +@Slf4j
  18 +@RestController
  19 +@RequestMapping("/api/jdy/form")
  20 +public class JdyFormController {
  21 +
  22 + @Resource
  23 + private JdyFormSyncService formSyncService;
  24 +
  25 + @Resource
  26 + private JdyExcelExportService excelExportService;
  27 +
  28 + /** 同步表单结构(字段),在目标应用下新建表单模型。 */
  29 + @PostMapping("/sync-structure")
  30 + public List<String> syncStructure() {
  31 + return formSyncService.syncStructures();
  32 + }
  33 +
  34 + /** 同步表单数据:当月数据、当天已存在先删当天再同步。 */
  35 + @PostMapping("/sync-data")
  36 + public List<String> syncData() {
  37 + return formSyncService.syncData();
  38 + }
  39 +
  40 + /** 把简道云表单数据导出为 Excel,保存到导出目录,返回文件路径。 */
  41 + @PostMapping("/export-excel")
  42 + public List<String> exportExcel() {
  43 + return excelExportService.exportAll();
  44 + }
  45 +
  46 + /**
  47 + * 临时导出单个简道云表单(供演示/手动上传)。
  48 + * 例:/api/jdy/form/export-excel-form?appId=xxx&entryId=xxx&month=2026-09
  49 + */
  50 + @PostMapping("/export-excel-form")
  51 + public String exportExcelForm(@RequestParam(required = false) String appId,
  52 + @RequestParam(required = false) String entryId,
  53 + @RequestParam(required = false) String name,
  54 + @RequestParam(required = false) String month,
  55 + @RequestParam(required = false) String dateField) {
  56 + return excelExportService.exportOne(appId, entryId, name, month, dateField);
  57 + }
  58 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.controller;
  2 +
  3 +import com.qgutech.qgyun.apaas.sync.jdy.service.JdyRiskStatisticsService;
  4 +import lombok.extern.slf4j.Slf4j;
  5 +import org.springframework.web.bind.annotation.GetMapping;
  6 +import org.springframework.web.bind.annotation.PathVariable;
  7 +import org.springframework.web.bind.annotation.PostMapping;
  8 +import org.springframework.web.bind.annotation.RequestMapping;
  9 +import org.springframework.web.bind.annotation.RestController;
  10 +
  11 +import javax.annotation.Resource;
  12 +import java.util.Map;
  13 +
  14 +/**
  15 + * 风险场景统计接口。
  16 + * <p>
  17 + * 全部场景:`/api/jdy/risk/count`、`/api/jdy/risk/sync`
  18 + * 单个场景:`/api/jdy/risk/count/{场景id或syncCode}`、`/api/jdy/risk/sync/{场景id或syncCode}`
  19 + * (场景 id 如 count_1;syncCode 如 SYNC0001。浏览器直接输地址即可,GET/POST 均可)
  20 + */
  21 +@Slf4j
  22 +@RestController
  23 +@RequestMapping("/api/jdy/risk")
  24 +public class JdyRiskController {
  25 +
  26 + @Resource
  27 + private JdyRiskStatisticsService riskService;
  28 +
  29 + /** 统计全部场景。 */
  30 + @PostMapping("/count")
  31 + public Map<String, Object> count() {
  32 + return riskService.countAll();
  33 + }
  34 +
  35 + @GetMapping("/count")
  36 + public Map<String, Object> countGet() {
  37 + return riskService.countAll();
  38 + }
  39 +
  40 + /** 统计全部场景,并按 syncCode 更新到启效目标表单。 */
  41 + @PostMapping("/sync")
  42 + public Map<String, Object> sync() {
  43 + return riskService.countAndSync();
  44 + }
  45 +
  46 + @GetMapping("/sync")
  47 + public Map<String, Object> syncGet() {
  48 + return riskService.countAndSync();
  49 + }
  50 +
  51 + /** 只统计单个场景(id 或 syncCode)。 */
  52 + @PostMapping("/count/{scenarioId}")
  53 + public Map<String, Object> countOne(@PathVariable String scenarioId) {
  54 + return riskService.countOne(scenarioId);
  55 + }
  56 +
  57 + @GetMapping("/count/{scenarioId}")
  58 + public Map<String, Object> countOneGet(@PathVariable String scenarioId) {
  59 + return riskService.countOne(scenarioId);
  60 + }
  61 +
  62 + /** 只同步单个场景(id 或 syncCode):统计 + 写回 chcbxt + 上传 Excel 附件。 */
  63 + @PostMapping("/sync/{scenarioId}")
  64 + public Map<String, Object> syncOne(@PathVariable String scenarioId) {
  65 + return riskService.countAndSyncOne(scenarioId);
  66 + }
  67 +
  68 + @GetMapping("/sync/{scenarioId}")
  69 + public Map<String, Object> syncOneGet(@PathVariable String scenarioId) {
  70 + return riskService.countAndSyncOne(scenarioId);
  71 + }
  72 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.controller;
  2 +
  3 +import com.qgutech.qgyun.apaas.sync.jdy.config.JdySyncProperties;
  4 +import com.qgutech.qgyun.apaas.sync.jdy.service.JdyToQxSyncService;
  5 +import lombok.extern.slf4j.Slf4j;
  6 +import org.springframework.web.bind.annotation.PathVariable;
  7 +import org.springframework.web.bind.annotation.PostMapping;
  8 +import org.springframework.web.bind.annotation.RequestMapping;
  9 +import org.springframework.web.bind.annotation.RestController;
  10 +
  11 +import javax.annotation.Resource;
  12 +import java.util.Collections;
  13 +import java.util.List;
  14 +
  15 +/**
  16 + * 简道云同步手动触发接口(方便联调/补跑)。
  17 + */
  18 +@Slf4j
  19 +@RestController
  20 +@RequestMapping("/api/jdy/sync")
  21 +public class JdySyncController {
  22 +
  23 + @Resource
  24 + private JdyToQxSyncService syncService;
  25 +
  26 + @Resource
  27 + private JdySyncProperties props;
  28 +
  29 + /** 同步全部配置应用。 */
  30 + @PostMapping("/all")
  31 + public List<String> syncAll() {
  32 + return syncService.syncAll();
  33 + }
  34 +
  35 + /** 按简道云应用名同步单个应用。 */
  36 + @PostMapping("/{appName}")
  37 + public List<String> syncOne(@PathVariable String appName) {
  38 + for (JdySyncProperties.App app : props.getApps()) {
  39 + if (appName.equals(app.getName())) {
  40 + return Collections.singletonList(syncService.syncApp(app));
  41 + }
  42 + }
  43 + return Collections.singletonList("NOT_FOUND: " + appName);
  44 + }
  45 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.service;
  2 +
  3 +import java.util.Arrays;
  4 +import java.util.HashMap;
  5 +import java.util.HashSet;
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +import java.util.Set;
  9 +import java.util.concurrent.ThreadLocalRandom;
  10 +
  11 +/**
  12 + * 中文字段/表单名 -> 语义英文 code 的映射与类型转换(遵循 qx-design-app 命名规范)。
  13 + */
  14 +public final class FieldMapping {
  15 +
  16 + /** 常见中文字段名 -> 语义 fieldKey */
  17 + private static final Map<String, String> FIELD_DICT = new HashMap<>();
  18 + /** 常见中文字单名 -> 语义 funCode */
  19 + private static final Map<String, String> FORM_DICT = new HashMap<>();
  20 + /** 简道云类型 -> 启效字段类型 */
  21 + private static final Map<String, String> TYPE_MAP = new HashMap<>();
  22 + /** 日期类简道云类型(写入需毫秒时间戳) */
  23 + private static final List<String> DATE_JDY_TYPES = Arrays.asList("datetime", "date");
  24 +
  25 + static {
  26 + putField("姓名", "name"); putField("名称", "name"); putField("用户名", "username"); putField("账号", "account");
  27 + putField("年龄", "age"); putField("性别", "gender"); putField("手机号", "phone"); putField("电话", "phone");
  28 + putField("邮箱", "email"); putField("地址", "address"); putField("备注", "remark"); putField("说明", "remark");
  29 + putField("描述", "description"); putField("编号", "code"); putField("编码", "code"); putField("部门编号", "deptNo");
  30 + putField("部门名称", "deptName"); putField("部门", "department"); putField("职位", "position");
  31 + putField("数量", "quantity"); putField("金额", "amount"); putField("价格", "price"); putField("单价", "price");
  32 + putField("日期", "date"); putField("创建日期", "createDate"); putField("出生日期", "birthDate");
  33 + putField("开始日期", "startDate"); putField("结束日期", "endDate"); putField("时间", "time");
  34 + putField("类型", "type"); putField("状态", "status"); putField("是否启用", "enabled");
  35 + putField("标题", "title"); putField("内容", "content"); putField("负责人", "owner"); putField("经手人", "handler");
  36 +
  37 + // 3mis 争议件大于确定件(合肥长安_技术处)
  38 + putField("日期时间", "dateTime"); putField("在用期", "inUsePeriod"); putField("车型", "vehicleModel");
  39 + putField("旧件名称", "oldPartName"); putField("牵头人", "leadUser"); putField("非零件问题", "nonPartIssue");
  40 + putField("确定故障件", "confirmedFaultPart"); putField("争议故障件", "disputedFaultPart");
  41 + putField("差值(争议-确定≥1)", "diffValue"); putField("总计≥5", "totalCount"); putField("情况说明", "description");
  42 +
  43 + putForm("人员管理", "personnel"); putForm("部门管理", "department"); putForm("员工管理", "employee");
  44 + putForm("客户管理", "customer"); putForm("订单管理", "order"); putForm("产品管理", "product");
  45 + putForm("供应商管理", "supplier"); putForm("设备管理", "equipment"); putForm("库存管理", "inventory");
  46 + putForm("采购管理", "purchase"); putForm("合同管理", "contract"); putForm("项目管理", "project");
  47 + putForm("用户管理", "user"); putForm("角色管理", "role"); putForm("菜单管理", "menu");
  48 +
  49 + TYPE_MAP.put("text", "text"); TYPE_MAP.put("number", "number"); TYPE_MAP.put("datetime", "date");
  50 + TYPE_MAP.put("date", "date"); TYPE_MAP.put("textarea", "text"); TYPE_MAP.put("percent", "percent");
  51 + TYPE_MAP.put("switch", "switch");
  52 + }
  53 +
  54 + private static void putField(String zh, String en) {
  55 + FIELD_DICT.putIfAbsent(zh, en);
  56 + }
  57 +
  58 + private static void putForm(String zh, String en) {
  59 + FORM_DICT.putIfAbsent(zh, en);
  60 + }
  61 +
  62 + private FieldMapping() {
  63 + }
  64 +
  65 + /** 生成字段 fieldKey;未识别中文则随机 6 位并在日志标记。 */
  66 + public static String genFieldKey(String label, Map<String, String> override, Set<String> used) {
  67 + String fk = null;
  68 + if (override != null) {
  69 + fk = override.get(label);
  70 + }
  71 + if (fk == null || fk.isEmpty()) {
  72 + fk = FIELD_DICT.get(label);
  73 + }
  74 + if (fk == null || fk.isEmpty()) {
  75 + fk = randomLower(6);
  76 + }
  77 + while (!used.add(fk)) {
  78 + fk = fk + "x";
  79 + }
  80 + return fk;
  81 + }
  82 +
  83 + /** 生成表单 funCode;未识别中文表单名则随机 6 位。 */
  84 + public static String genFunCode(String formName) {
  85 + String fc = FORM_DICT.get(formName);
  86 + if (fc == null || fc.isEmpty()) {
  87 + fc = randomLower(6);
  88 + }
  89 + return fc;
  90 + }
  91 +
  92 + /** 简道云字段类型 -> 启效字段类型(未识别默认 text)。 */
  93 + public static String mapType(String jdyType) {
  94 + if (jdyType == null) {
  95 + return "text";
  96 + }
  97 + return TYPE_MAP.getOrDefault(jdyType.toLowerCase(), "text");
  98 + }
  99 +
  100 + public static boolean isDateJdy(String jdyType) {
  101 + return jdyType != null && DATE_JDY_TYPES.contains(jdyType.toLowerCase());
  102 + }
  103 +
  104 + public static String randomLower(int len) {
  105 + String chars = "abcdefghijklmnopqrstuvwxyz";
  106 + StringBuilder sb = new StringBuilder();
  107 + ThreadLocalRandom r = ThreadLocalRandom.current();
  108 + for (int i = 0; i < len; i++) {
  109 + sb.append(chars.charAt(r.nextInt(chars.length())));
  110 + }
  111 + return sb.toString();
  112 + }
  113 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.service;
  2 +
  3 +import com.alibaba.fastjson.JSONArray;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.qgutech.qgyun.apaas.sync.jdy.api.JiandaoYunApi;
  6 +import com.qgutech.qgyun.apaas.sync.jdy.config.JdyFormSyncProperties;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.apache.poi.ss.usermodel.Cell;
  9 +import org.apache.poi.ss.usermodel.CellStyle;
  10 +import org.apache.poi.ss.usermodel.Font;
  11 +import org.apache.poi.ss.usermodel.Row;
  12 +import org.apache.poi.ss.usermodel.Sheet;
  13 +import org.apache.poi.ss.usermodel.Workbook;
  14 +import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  15 +import org.springframework.stereotype.Service;
  16 +
  17 +import java.io.File;
  18 +import java.io.FileOutputStream;
  19 +import java.io.OutputStream;
  20 +import java.time.Instant;
  21 +import java.time.ZoneId;
  22 +import java.time.ZonedDateTime;
  23 +import java.time.format.DateTimeFormatter;
  24 +import java.util.ArrayList;
  25 +import java.util.List;
  26 +
  27 +/**
  28 + * 把简道云表单数据导出为 Excel(.xlsx),保存到配置的导出目录。
  29 + * <p>文件名统一为 yyyyMMddHHmmss.xlsx。
  30 + */
  31 +@Slf4j
  32 +@Service
  33 +public class JdyExcelExportService {
  34 +
  35 + private static final ZoneId ZONE = ZoneId.of("Asia/Shanghai");
  36 + private static final DateTimeFormatter TS = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
  37 +
  38 + private final JdyFormSyncProperties props;
  39 +
  40 + public JdyExcelExportService(JdyFormSyncProperties props) {
  41 + this.props = props;
  42 + }
  43 +
  44 + public File exportDir() {
  45 + File dir = new File(props.getExportDir());
  46 + if (!dir.exists() && !dir.mkdirs()) {
  47 + log.warn("导出目录创建失败: {}", dir.getAbsolutePath());
  48 + }
  49 + return dir;
  50 + }
  51 +
  52 + public static String nowFileName() {
  53 + return ZonedDateTime.now(ZONE).format(TS) + ".xlsx";
  54 + }
  55 +
  56 + /** 导出所有配置表单的数据到 Excel,返回生成的文件路径列表。 */
  57 + public List<String> exportAll() {
  58 + List<String> files = new ArrayList<>();
  59 + JiandaoYunApi jdy = new JiandaoYunApi(props.getJdy().getHost());
  60 + File dir = exportDir();
  61 + String ts = ZonedDateTime.now(ZONE).format(TS);
  62 + for (JdyFormSyncProperties.Form f : props.getForms()) {
  63 + try {
  64 + JSONArray widgets = jdy.listWidgets(props.getJdy().getApiKey(), f.getAppId(), f.getEntryId());
  65 + JSONArray data = jdy.listAllData(props.getJdy().getApiKey(), f.getAppId(), f.getEntryId());
  66 + File outFile = new File(dir, ts + ".xlsx");
  67 + writeWorkbook(widgets, data, null, null, outFile);
  68 + log.info("导出 Excel: {} ({} 条)", outFile.getAbsolutePath(), data.size());
  69 + files.add(outFile.getAbsolutePath());
  70 + } catch (Exception e) {
  71 + log.error("导出 Excel 失败: {}", f.getEntryId(), e);
  72 + files.add("FAIL " + f.getEntryId() + " : " + e.getMessage());
  73 + }
  74 + }
  75 + return files;
  76 + }
  77 +
  78 + /**
  79 + * 临时导出单个简道云表单(供演示/手动上传用)。
  80 + *
  81 + * @param month 可选,yyyy-MM(按日期字段过滤当月)
  82 + * @param dateField 可选,日期字段 code;不传则自动取第一个日期型字段
  83 + */
  84 + public String exportOne(String appId, String entryId, String name, String month, String dateField) {
  85 + try {
  86 + JiandaoYunApi jdy = new JiandaoYunApi(props.getJdy().getHost());
  87 + File dir = exportDir();
  88 + JSONArray widgets = jdy.listWidgets(props.getJdy().getApiKey(), appId, entryId);
  89 + JSONArray data = jdy.listAllData(props.getJdy().getApiKey(), appId, entryId);
  90 + if (month != null && !month.isEmpty()) {
  91 + String df = (dateField != null && !dateField.isEmpty()) ? dateField : firstDateField(widgets);
  92 + data = filterByMonth(data, df, month);
  93 + }
  94 + File outFile = new File(dir, nowFileName());
  95 + writeWorkbook(widgets, data, null, null, outFile);
  96 + log.info("导出 Excel: {} ({} 条, 表单={})", outFile.getAbsolutePath(), data.size(), name);
  97 + return outFile.getAbsolutePath();
  98 + } catch (Exception e) {
  99 + log.error("导出 Excel 失败: {}", entryId, e);
  100 + return "FAIL " + entryId + " : " + e.getMessage();
  101 + }
  102 + }
  103 +
  104 + /**
  105 + * 导出指定行到 Excel(供风险场景附件用),可在最右增加一列。
  106 + *
  107 + * @param extraHeader 附加列标题(为 null 则不附加)
  108 + * @param extraValues 附加列每行的值(与 rows 一一对应)
  109 + * @return 生成的文件路径
  110 + */
  111 + public String exportRows(JSONArray widgets, JSONArray rows, String extraHeader,
  112 + List<String> extraValues, String fileName) {
  113 + try {
  114 + File dir = exportDir();
  115 + File outFile = new File(dir, fileName);
  116 + writeWorkbook(widgets, rows, extraHeader, extraValues, outFile);
  117 + log.info("导出 Excel: {} ({} 条)", outFile.getAbsolutePath(), rows.size());
  118 + return outFile.getAbsolutePath();
  119 + } catch (Exception e) {
  120 + log.error("导出 Excel 失败: {}", fileName, e);
  121 + return "FAIL " + fileName + " : " + e.getMessage();
  122 + }
  123 + }
  124 +
  125 + private void writeWorkbook(JSONArray widgets, JSONArray data, String extraHeader,
  126 + List<String> extraValues, File outFile) throws Exception {
  127 + try (Workbook wb = new XSSFWorkbook()) {
  128 + Sheet sheet = wb.createSheet("数据");
  129 + CellStyle headerStyle = wb.createCellStyle();
  130 + Font bold = wb.createFont();
  131 + bold.setBold(true);
  132 + headerStyle.setFont(bold);
  133 +
  134 + Row header = sheet.createRow(0);
  135 + for (int c = 0; c < widgets.size(); c++) {
  136 + JSONObject w = widgets.getJSONObject(c);
  137 + String label = w.getString("label");
  138 + if (label == null || label.isEmpty()) {
  139 + label = w.getString("widgetName");
  140 + }
  141 + Cell cell = header.createCell(c);
  142 + cell.setCellValue(label);
  143 + cell.setCellStyle(headerStyle);
  144 + }
  145 + boolean hasExtra = extraHeader != null && !extraHeader.isEmpty();
  146 + if (hasExtra) {
  147 + Cell cell = header.createCell(widgets.size());
  148 + cell.setCellValue(extraHeader);
  149 + cell.setCellStyle(headerStyle);
  150 + }
  151 +
  152 + for (int r = 0; r < data.size(); r++) {
  153 + JSONObject rec = data.getJSONObject(r);
  154 + Row row = sheet.createRow(r + 1);
  155 + for (int c = 0; c < widgets.size(); c++) {
  156 + String code = widgets.getJSONObject(c).getString("name");
  157 + row.createCell(c).setCellValue(formatValue(rec.get(code)));
  158 + }
  159 + if (hasExtra) {
  160 + String v = (extraValues != null && r < extraValues.size() && extraValues.get(r) != null)
  161 + ? extraValues.get(r) : "";
  162 + row.createCell(widgets.size()).setCellValue(v);
  163 + }
  164 + }
  165 + for (int c = 0; c <= widgets.size(); c++) {
  166 + sheet.setColumnWidth(c, 20 * 256);
  167 + }
  168 + try (OutputStream os = new FileOutputStream(outFile)) {
  169 + wb.write(os);
  170 + }
  171 + }
  172 + }
  173 +
  174 + private JSONArray filterByMonth(JSONArray data, String dateField, String month) {
  175 + JSONArray out = new JSONArray();
  176 + for (int i = 0; i < data.size(); i++) {
  177 + JSONObject rec = data.getJSONObject(i);
  178 + String iso = rec.getString(dateField);
  179 + if (iso != null && iso.length() >= 7) {
  180 + String m;
  181 + try {
  182 + m = Instant.parse(iso).atZone(ZONE).format(DateTimeFormatter.ofPattern("yyyy-MM"));
  183 + } catch (Exception e) {
  184 + m = iso.substring(0, 7);
  185 + }
  186 + if (month.equals(m)) {
  187 + out.add(rec);
  188 + }
  189 + }
  190 + }
  191 + return out;
  192 + }
  193 +
  194 + private String firstDateField(JSONArray widgets) {
  195 + for (int i = 0; i < widgets.size(); i++) {
  196 + JSONObject w = widgets.getJSONObject(i);
  197 + String t = w.getString("type");
  198 + if ("datetime".equalsIgnoreCase(t) || "date".equalsIgnoreCase(t)) {
  199 + return w.getString("name");
  200 + }
  201 + }
  202 + return null;
  203 + }
  204 +
  205 + /** 值格式化:时间->北京时间字符串;用户对象->name;数组->逗号连接。 */
  206 + private String formatValue(Object v) {
  207 + if (v == null) {
  208 + return "";
  209 + }
  210 + if (v instanceof JSONObject) {
  211 + String n = ((JSONObject) v).getString("name");
  212 + return n != null ? n : ((JSONObject) v).toJSONString();
  213 + }
  214 + if (v instanceof JSONArray) {
  215 + JSONArray arr = (JSONArray) v;
  216 + StringBuilder sb = new StringBuilder();
  217 + for (int i = 0; i < arr.size(); i++) {
  218 + Object o = arr.get(i);
  219 + String s;
  220 + if (o instanceof JSONObject) {
  221 + String n = ((JSONObject) o).getString("name");
  222 + s = n != null ? n : ((JSONObject) o).toJSONString();
  223 + } else {
  224 + s = String.valueOf(o);
  225 + }
  226 + if (sb.length() > 0) {
  227 + sb.append(",");
  228 + }
  229 + sb.append(s);
  230 + }
  231 + return sb.toString();
  232 + }
  233 + String s = String.valueOf(v);
  234 + if (s.matches("\\d{4}-\\d{2}-\\d{2}T.*")) {
  235 + try {
  236 + return Instant.parse(s).atZone(ZONE).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
  237 + } catch (Exception ignored) {
  238 + return s;
  239 + }
  240 + }
  241 + return s;
  242 + }
  243 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.service;
  2 +
  3 +import com.alibaba.fastjson.JSONArray;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.qgutech.qgyun.apaas.sync.jdy.api.JiandaoYunApi;
  6 +import com.qgutech.qgyun.apaas.sync.jdy.api.QxApi;
  7 +import com.qgutech.qgyun.apaas.sync.jdy.config.JdyFormSyncProperties;
  8 +import lombok.extern.slf4j.Slf4j;
  9 +import org.springframework.stereotype.Service;
  10 +
  11 +import java.time.Instant;
  12 +import java.time.ZoneId;
  13 +import java.time.ZonedDateTime;
  14 +import java.time.format.DateTimeFormatter;
  15 +import java.util.ArrayList;
  16 +import java.util.HashSet;
  17 +import java.util.LinkedHashMap;
  18 +import java.util.LinkedHashSet;
  19 +import java.util.List;
  20 +import java.util.Map;
  21 +import java.util.Set;
  22 +
  23 +/**
  24 + * 简道云表单 -> 启效 结构/数据同步。
  25 + * <p>
  26 + * 结构同步:把简道云表单字段镜像到启效指定应用下(新建表单模型 + 写字段)。
  27 + * 数据同步:只抓当月数据;每次新增一份完整数据留存;若「当天」已有同步数据,先删当天再同步。
  28 + */
  29 +@Slf4j
  30 +@Service
  31 +public class JdyFormSyncService {
  32 +
  33 + private static final ZoneId ZONE = ZoneId.of("Asia/Shanghai");
  34 + private static final DateTimeFormatter MONTH_FMT = DateTimeFormatter.ofPattern("yyyy-MM");
  35 + private static final DateTimeFormatter DAY_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  36 +
  37 + private final JdyFormSyncProperties props;
  38 +
  39 + public JdyFormSyncService(JdyFormSyncProperties props) {
  40 + this.props = props;
  41 + }
  42 +
  43 + /* ==================== 结构同步 ==================== */
  44 +
  45 + /** 同步所有配置表单的「结构」(字段),返回摘要。 */
  46 + public List<String> syncStructures() {
  47 + List<String> result = new ArrayList<>();
  48 + JdyFormSyncProperties.Qx qx = props.getQx();
  49 + QxApi qxApi = new QxApi(qx.getBaseUrl());
  50 + String token = qxApi.login(qx.getUsername(), qx.getPassword(), qx.getCorpCode());
  51 + JiandaoYunApi jdy = new JiandaoYunApi(props.getJdy().getHost());
  52 +
  53 + for (JdyFormSyncProperties.Form f : props.getForms()) {
  54 + String formName = resolveFormName(jdy, f);
  55 + String funCode = funCode(f, formName);
  56 + JSONArray widgets = jdy.listWidgets(props.getJdy().getApiKey(), f.getAppId(), f.getEntryId());
  57 + List<QxApi.Field> fields = buildFields(widgets, f);
  58 +
  59 + String modelId = f.getModelId();
  60 + boolean createNew = (modelId == null || modelId.isEmpty());
  61 + if (createNew) {
  62 + modelId = qxApi.createFormModel(token, qx.getAppId(), formName, funCode);
  63 + }
  64 + qxApi.saveDesignObj(token, qx.getAppId(), qx.getAppName(), modelId, formName, funCode, fields);
  65 + String summary = (createNew ? "OK 新建" : "OK 更新") + "表单「" + formName + "」 funCode=" + funCode
  66 + + " modelId=" + modelId + " 字段数=" + fields.size() + " -> " + fieldsText(fields);
  67 + log.info(summary);
  68 + result.add(summary);
  69 + }
  70 + return result;
  71 + }
  72 +
  73 + /* ==================== 数据同步 ==================== */
  74 +
  75 + /**
  76 + * 同步所有配置表单的「数据」:当月数据、当天去重。
  77 + * <p>
  78 + * 流程:解析接口 code -> 删除启效中「当天」已同步的记录 -> 拉简道云当月数据 -> 逐条新增。
  79 + */
  80 + public List<String> syncData() {
  81 + List<String> result = new ArrayList<>();
  82 + JdyFormSyncProperties.Qx qx = props.getQx();
  83 + QxApi qxApi = new QxApi(qx.getBaseUrl());
  84 + String token = qxApi.login(qx.getUsername(), qx.getPassword(), qx.getCorpCode());
  85 + JiandaoYunApi jdy = new JiandaoYunApi(props.getJdy().getHost());
  86 + String month = (props.getMonth() != null && !props.getMonth().isEmpty())
  87 + ? props.getMonth() : ZonedDateTime.now(ZONE).format(MONTH_FMT);
  88 +
  89 + for (JdyFormSyncProperties.Form f : props.getForms()) {
  90 + try {
  91 + String formName = resolveFormName(jdy, f);
  92 + if (f.getModelId() == null || f.getModelId().isEmpty()) {
  93 + throw new IllegalStateException("未配置 model-id,无法定位启效表单接口");
  94 + }
  95 + log.info("开始同步数据: 表单「{}」 modelId={} 当月={}", formName, f.getModelId(), month);
  96 +
  97 + // 字段映射:简道云控件 code -> 启效 fieldKey;并记录日期字段
  98 + JSONArray widgets = jdy.listWidgets(props.getJdy().getApiKey(), f.getAppId(), f.getEntryId());
  99 + Map<String, String> codeToField = new LinkedHashMap<>();
  100 + Set<String> dateFieldKeys = new HashSet<>();
  101 + buildFieldMapping(widgets, f, codeToField, dateFieldKeys);
  102 +
  103 + // 解析启效接口 code(新增/分页/删除)
  104 + JSONArray ifaces = qxApi.listApiManages(token, qx.getAppId());
  105 + String addCode = findModelCode(ifaces, f.getModelId(), "Add");
  106 + String pageCode = findModelCode(ifaces, f.getModelId(), "Page");
  107 + String delCode = findModelCode(ifaces, f.getModelId(), "Del");
  108 + if (addCode == null || pageCode == null || delCode == null) {
  109 + throw new IllegalStateException("未找到接口 code add=" + addCode + " page=" + pageCode + " del=" + delCode);
  110 + }
  111 + log.info("启效接口: add={} page={} del={}", addCode, pageCode, delCode);
  112 +
  113 + // 删除「当天」已同步的记录
  114 + int deleted = deleteTodayData(qxApi, token, qx.getAppId(), pageCode, delCode);
  115 + log.info("删除当天已存在数据 {} 条", deleted);
  116 +
  117 + // 拉简道云当月数据
  118 + List<JSONObject> records = fetchMonthData(jdy, f, month, dateFieldKeys);
  119 + // 注意: fetchMonthData 内部按配置的 date-field 过滤
  120 +
  121 + // 逐条新增
  122 + int ok = 0, fail = 0;
  123 + for (JSONObject rec : records) {
  124 + try {
  125 + Map<String, Object> payload = buildPayload(rec, widgets, codeToField, dateFieldKeys);
  126 + qxApi.insertData(token, qx.getAppId(), addCode, payload);
  127 + ok++;
  128 + } catch (Exception e) {
  129 + fail++;
  130 + log.error("新增失败(继续下一条): {}", e.getMessage());
  131 + }
  132 + }
  133 + String summary = "OK " + formName + " 当月=" + month + " 删除当天=" + deleted
  134 + + " 新增=" + ok + " 失败=" + fail;
  135 + log.info(summary);
  136 + result.add(summary);
  137 + } catch (Exception e) {
  138 + log.error("同步表单数据失败", e);
  139 + result.add("FAIL " + f.getEntryId() + " : " + e.getMessage());
  140 + }
  141 + }
  142 + return result;
  143 + }
  144 +
  145 + /** 拉取简道云「当月」数据(按配置 date-field 过滤)。 */
  146 + private List<JSONObject> fetchMonthData(JiandaoYunApi jdy, JdyFormSyncProperties.Form f,
  147 + String month, Set<String> dateFieldKeys) {
  148 + JSONArray all = jdy.listAllData(props.getJdy().getApiKey(), f.getAppId(), f.getEntryId());
  149 + List<JSONObject> monthRecords = new ArrayList<>();
  150 + String dateField = f.getDateField();
  151 + if (!f.isMonthOnly() || dateField == null || dateField.isEmpty()) {
  152 + // 全量同步
  153 + for (int i = 0; i < all.size(); i++) {
  154 + monthRecords.add(all.getJSONObject(i));
  155 + }
  156 + log.info("简道云全量 {} 条(未按月份过滤)", all.size());
  157 + return monthRecords;
  158 + }
  159 + for (int i = 0; i < all.size(); i++) {
  160 + JSONObject rec = all.getJSONObject(i);
  161 + String iso = rec.getString(dateField);
  162 + if (month.equals(toMonth(iso))) {
  163 + monthRecords.add(rec);
  164 + }
  165 + }
  166 + log.info("简道云全量 {} 条, 当月({}) {} 条", all.size(), month, monthRecords.size());
  167 + return monthRecords;
  168 + }
  169 +
  170 + /** 删除启效中「当天」已同步的记录,返回删除条数。 */
  171 + private int deleteTodayData(QxApi qxApi, String token, String appId, String pageCode, String delCode) {
  172 + JSONArray existing = qxApi.pageAll(token, appId, pageCode);
  173 + String today = ZonedDateTime.now(ZONE).format(DAY_FMT);
  174 + int deleted = 0;
  175 + for (int i = 0; i < existing.size(); i++) {
  176 + JSONObject rec = existing.getJSONObject(i);
  177 + if (isToday(rec, today)) {
  178 + String id = rec.getString("id");
  179 + if (id != null && !id.isEmpty()) {
  180 + qxApi.deleteData(token, appId, delCode, id);
  181 + deleted++;
  182 + }
  183 + }
  184 + }
  185 + return deleted;
  186 + }
  187 +
  188 + private boolean isToday(JSONObject rec, String today) {
  189 + Long ca = rec.getLong("createdAt");
  190 + if (ca != null) {
  191 + return Instant.ofEpochMilli(ca).atZone(ZONE).format(DAY_FMT).equals(today);
  192 + }
  193 + Object ct = rec.get("createTime");
  194 + if (ct != null) {
  195 + String day = toDay(String.valueOf(ct));
  196 + return today.equals(day);
  197 + }
  198 + return false;
  199 + }
  200 +
  201 + /** 在接口列表中,按 modelId 找 code 以指定后缀结尾的接口(Add/Page/Del)。 */
  202 + private String findModelCode(JSONArray ifaces, String modelId, String suffix) {
  203 + if (ifaces == null) {
  204 + return null;
  205 + }
  206 + for (int i = 0; i < ifaces.size(); i++) {
  207 + JSONObject api = ifaces.getJSONObject(i);
  208 + String mid = api.getString("modelId");
  209 + String code = api.getString("code");
  210 + if (code != null && code.endsWith(suffix) && modelId.equals(mid)) {
  211 + return code;
  212 + }
  213 + }
  214 + return null;
  215 + }
  216 +
  217 + /* ==================== 公共辅助 ==================== */
  218 +
  219 + /** 解析简道云表单名:优先从简道云 entry/list 取(UTF-8,避免配置编码问题),取不到再用配置名。 */
  220 + private String resolveFormName(JiandaoYunApi jdy, JdyFormSyncProperties.Form f) {
  221 + JSONArray forms = jdy.listAllForms(props.getJdy().getApiKey(), f.getAppId());
  222 + for (int i = 0; i < forms.size(); i++) {
  223 + JSONObject form = forms.getJSONObject(i);
  224 + if (f.getEntryId().equals(form.getString("entry_id"))) {
  225 + String name = form.getString("name");
  226 + if (name != null && !name.isEmpty()) {
  227 + return name;
  228 + }
  229 + }
  230 + }
  231 + if (f.getName() != null && !f.getName().isEmpty()) {
  232 + return f.getName();
  233 + }
  234 + throw new IllegalStateException("简道云未找到表单 entry_id=" + f.getEntryId());
  235 + }
  236 +
  237 + private String funCode(JdyFormSyncProperties.Form f, String formName) {
  238 + return (f.getFunCode() == null || f.getFunCode().isEmpty())
  239 + ? FieldMapping.genFunCode(formName) : f.getFunCode();
  240 + }
  241 +
  242 + /** 构建启效字段列表(结构同步用)。 */
  243 + private List<QxApi.Field> buildFields(JSONArray widgets, JdyFormSyncProperties.Form f) {
  244 + List<QxApi.Field> fields = new ArrayList<>();
  245 + Set<String> usedFieldKey = new LinkedHashSet<>();
  246 + Set<String> usedLabel = new HashSet<>();
  247 + for (int i = 0; i < widgets.size(); i++) {
  248 + JSONObject w = widgets.getJSONObject(i);
  249 + String label = w.getString("label");
  250 + if (label == null || label.isEmpty()) {
  251 + label = w.getString("widgetName");
  252 + }
  253 + if (label == null || label.isEmpty() || !usedLabel.add(label)) {
  254 + continue;
  255 + }
  256 + String fieldKey = FieldMapping.genFieldKey(label, f.getFieldMapping(), usedFieldKey);
  257 + String qxType = FieldMapping.mapType(w.getString("type"));
  258 + fields.add(new QxApi.Field(label, fieldKey, qxType));
  259 + }
  260 + return fields;
  261 + }
  262 +
  263 + /** 构建 控件code -> fieldKey 映射,并收集日期字段(数据同步用)。 */
  264 + private void buildFieldMapping(JSONArray widgets, JdyFormSyncProperties.Form f,
  265 + Map<String, String> codeToField, Set<String> dateFieldKeys) {
  266 + Set<String> usedFieldKey = new LinkedHashSet<>();
  267 + Set<String> usedLabel = new HashSet<>();
  268 + for (int i = 0; i < widgets.size(); i++) {
  269 + JSONObject w = widgets.getJSONObject(i);
  270 + String code = w.getString("name");
  271 + String label = w.getString("label");
  272 + if (label == null || label.isEmpty()) {
  273 + label = w.getString("widgetName");
  274 + }
  275 + if (label == null || label.isEmpty() || !usedLabel.add(label)) {
  276 + continue;
  277 + }
  278 + String jdyType = w.getString("type");
  279 + String fieldKey = FieldMapping.genFieldKey(label, f.getFieldMapping(), usedFieldKey);
  280 + codeToField.put(code, fieldKey);
  281 + if (FieldMapping.isDateJdy(jdyType)) {
  282 + dateFieldKeys.add(fieldKey);
  283 + }
  284 + }
  285 + }
  286 +
  287 + /** 组装单条写入 payload:日期转毫秒;用户/人员字段取 name。 */
  288 + private Map<String, Object> buildPayload(JSONObject record, JSONArray widgets,
  289 + Map<String, String> codeToField, Set<String> dateFieldKeys) {
  290 + Map<String, Object> payload = new LinkedHashMap<>();
  291 + for (int i = 0; i < widgets.size(); i++) {
  292 + JSONObject w = widgets.getJSONObject(i);
  293 + String code = w.getString("name");
  294 + String fieldKey = codeToField.get(code);
  295 + if (fieldKey == null) {
  296 + continue;
  297 + }
  298 + Object v = record.get(code);
  299 + if (v == null) {
  300 + continue;
  301 + }
  302 + if (dateFieldKeys.contains(fieldKey) && v instanceof String) {
  303 + v = toMs((String) v);
  304 + } else if (v instanceof JSONObject) {
  305 + JSONObject o = (JSONObject) v;
  306 + v = o.getString("name") != null ? o.getString("name") : o.toJSONString();
  307 + } else if (v instanceof JSONArray) {
  308 + JSONArray arr = (JSONArray) v;
  309 + StringBuilder sb = new StringBuilder();
  310 + for (int k = 0; k < arr.size(); k++) {
  311 + JSONObject o = arr.getJSONObject(k);
  312 + String n = o == null ? null : o.getString("name");
  313 + if (n == null) {
  314 + n = String.valueOf(arr.get(k));
  315 + }
  316 + if (sb.length() > 0) {
  317 + sb.append(",");
  318 + }
  319 + sb.append(n);
  320 + }
  321 + v = sb.toString();
  322 + }
  323 + payload.put(fieldKey, v);
  324 + }
  325 + return payload;
  326 + }
  327 +
  328 + private static String fieldsText(List<QxApi.Field> fields) {
  329 + StringBuilder sb = new StringBuilder();
  330 + for (QxApi.Field f : fields) {
  331 + if (sb.length() > 0) {
  332 + sb.append(", ");
  333 + }
  334 + sb.append(f.getTitle()).append("->").append(f.getFieldKey()).append("(").append(f.getType()).append(")");
  335 + }
  336 + return sb.toString();
  337 + }
  338 +
  339 + /** ISO 时间 -> 北京时间 yyyy-MM;解析失败返回 null。 */
  340 + private static String toMonth(String iso) {
  341 + String day = toDay(iso);
  342 + return day == null ? null : day.substring(0, 7);
  343 + }
  344 +
  345 + /** ISO 时间 -> 北京时间 yyyy-MM-dd;解析失败返回 null。 */
  346 + private static String toDay(String iso) {
  347 + if (iso == null || iso.isEmpty()) {
  348 + return null;
  349 + }
  350 + try {
  351 + return Instant.parse(iso).atZone(ZONE).format(DAY_FMT);
  352 + } catch (Exception e) {
  353 + return null;
  354 + }
  355 + }
  356 +
  357 + public static Object toMs(String iso) {
  358 + try {
  359 + return Instant.parse(iso).toEpochMilli();
  360 + } catch (Exception e) {
  361 + try {
  362 + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  363 + sdf.setTimeZone(java.util.TimeZone.getTimeZone("Asia/Shanghai"));
  364 + return sdf.parse(iso).getTime();
  365 + } catch (Exception ex) {
  366 + return iso;
  367 + }
  368 + }
  369 + }
  370 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.service;
  2 +
  3 +import com.alibaba.fastjson.JSONArray;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.qgutech.qgyun.apaas.sync.jdy.api.JiandaoYunApi;
  6 +import com.qgutech.qgyun.apaas.sync.jdy.api.QxApi;
  7 +import com.qgutech.qgyun.apaas.sync.jdy.config.JdyRiskProperties;
  8 +import lombok.extern.slf4j.Slf4j;
  9 +import org.springframework.stereotype.Service;
  10 +
  11 +import java.io.File;
  12 +import java.time.Instant;
  13 +import java.time.ZoneId;
  14 +import java.time.ZonedDateTime;
  15 +import java.time.format.DateTimeFormatter;
  16 +import java.time.temporal.ChronoUnit;
  17 +import java.util.ArrayList;
  18 +import java.util.LinkedHashMap;
  19 +import java.util.LinkedHashSet;
  20 +import java.util.List;
  21 +import java.util.Map;
  22 +import java.util.Set;
  23 +
  24 +/**
  25 + * 风险场景统计:调用长安简道云开放 API 读取表单数据,按规则过滤并输出命中计数;
  26 + * 并可按 syncCode 把「计数 + 简道云原始数据 Excel 附件」写回启效表单。
  27 + */
  28 +@Slf4j
  29 +@Service
  30 +public class JdyRiskStatisticsService {
  31 +
  32 + private static final ZoneId ZONE = ZoneId.of("Asia/Shanghai");
  33 + private static final DateTimeFormatter MONTH_FMT = DateTimeFormatter.ofPattern("yyyy-MM");
  34 +
  35 + private final JdyRiskProperties props;
  36 + private final JdyExcelExportService excelExportService;
  37 +
  38 + public JdyRiskStatisticsService(JdyRiskProperties props, JdyExcelExportService excelExportService) {
  39 + this.props = props;
  40 + this.excelExportService = excelExportService;
  41 + }
  42 +
  43 + /** 只统计,返回 {count_1:.., count_2:.., ...}。 */
  44 + public Map<String, Object> countAll() {
  45 + Map<String, Object> result = new LinkedHashMap<>();
  46 + JiandaoYunApi jdy = new JiandaoYunApi(props.getHost());
  47 + for (JdyRiskProperties.Scenario s : props.getScenarios()) {
  48 + try {
  49 + String type = s.getType() == null ? "" : s.getType().toLowerCase();
  50 + if ("scenario7".equals(type)) {
  51 + result.put(s.getId(), buildScenario7Rows(jdy, s).size());
  52 + } else {
  53 + JSONArray all = jdy.listAllData(props.getApiKey(), s.getAppId(), s.getEntryId());
  54 + JSONArray rows = filterScope(all, s);
  55 + result.put(s.getId(), count(s, rows));
  56 + }
  57 + } catch (Exception e) {
  58 + log.error("场景[{}] 统计失败", s.getId(), e);
  59 + result.put(s.getId(), "ERROR: " + e.getMessage());
  60 + }
  61 + }
  62 + return result;
  63 + }
  64 +
  65 + /** 统计全部场景并按 syncCode 把计数 + Excel 附件写回启效。 */
  66 + public Map<String, Object> countAndSync() {
  67 + log.info("========== 开始风险场景统计并写回启效(全部 {} 个场景) ==========", props.getScenarios().size());
  68 + Map<String, Object> result = new LinkedHashMap<>();
  69 + Context ctx = context();
  70 + for (JdyRiskProperties.Scenario s : props.getScenarios()) {
  71 + syncOneScenario(s, ctx, result);
  72 + }
  73 + log.info("========== 风险场景统计并写回完成 ==========");
  74 + return result;
  75 + }
  76 +
  77 + /** 只处理单个场景(参数为场景 id 如 count_1,或 syncCode 如 SYNC0001)。 */
  78 + public Map<String, Object> countAndSyncOne(String scenarioId) {
  79 + Map<String, Object> result = new LinkedHashMap<>();
  80 + JdyRiskProperties.Scenario s = findScenario(scenarioId);
  81 + if (s == null) {
  82 + result.put("error", "场景不存在: " + scenarioId);
  83 + return result;
  84 + }
  85 + log.info("========== 开始单场景统计并写回: {} ==========", scenarioId);
  86 + syncOneScenario(s, context(), result);
  87 + return result;
  88 + }
  89 +
  90 + /** 只统计单个场景(不写回)。 */
  91 + public Map<String, Object> countOne(String scenarioId) {
  92 + Map<String, Object> result = new LinkedHashMap<>();
  93 + JdyRiskProperties.Scenario s = findScenario(scenarioId);
  94 + if (s == null) {
  95 + result.put("error", "场景不存在: " + scenarioId);
  96 + return result;
  97 + }
  98 + JiandaoYunApi jdy = new JiandaoYunApi(props.getHost());
  99 + try {
  100 + String type = s.getType() == null ? "" : s.getType().toLowerCase();
  101 + if ("scenario7".equals(type)) {
  102 + result.put(s.getId(), buildScenario7Rows(jdy, s).size());
  103 + } else {
  104 + JSONArray all = jdy.listAllData(props.getApiKey(), s.getAppId(), s.getEntryId());
  105 + result.put(s.getId(), count(s, filterScope(all, s)));
  106 + }
  107 + } catch (Exception e) {
  108 + result.put(s.getId(), "ERROR: " + e.getMessage());
  109 + }
  110 + return result;
  111 + }
  112 +
  113 + private JdyRiskProperties.Scenario findScenario(String scenarioId) {
  114 + if (scenarioId == null) {
  115 + return null;
  116 + }
  117 + for (JdyRiskProperties.Scenario s : props.getScenarios()) {
  118 + if (scenarioId.equals(s.getId()) || scenarioId.equals(s.getSyncCode())) {
  119 + return s;
  120 + }
  121 + }
  122 + return null;
  123 + }
  124 +
  125 + /** 登录启效并一次性拉取全部记录(本地按 syncCode 匹配)。 */
  126 + private Context context() {
  127 + JdyRiskProperties.Qx qx = props.getQx();
  128 + QxApi qxApi = new QxApi(qx.getBaseUrl());
  129 + String token = qxApi.login(qx.getUsername(), qx.getPassword(), qx.getCorpCode());
  130 + JiandaoYunApi jdy = new JiandaoYunApi(props.getHost());
  131 + JSONArray allRecords = qxApi.pageAll(token, qx.getAppId(), qx.getQueryCode());
  132 + log.info("启效记录总数={}(按 syncCode 本地匹配)", allRecords.size());
  133 + return new Context(qxApi, token, jdy, allRecords);
  134 + }
  135 +
  136 + private static class Context {
  137 + final QxApi qxApi;
  138 + final String token;
  139 + final JiandaoYunApi jdy;
  140 + final JSONArray allRecords;
  141 +
  142 + Context(QxApi qxApi, String token, JiandaoYunApi jdy, JSONArray allRecords) {
  143 + this.qxApi = qxApi;
  144 + this.token = token;
  145 + this.jdy = jdy;
  146 + this.allRecords = allRecords;
  147 + }
  148 + }
  149 +
  150 + /** 单场景:统计 -> 生成 Excel -> 上传附件 -> 更新记录。 */
  151 + private void syncOneScenario(JdyRiskProperties.Scenario s, Context ctx, Map<String, Object> result) {
  152 + JdyRiskProperties.Qx qx = props.getQx();
  153 + QxApi qxApi = ctx.qxApi;
  154 + String token = ctx.token;
  155 + JiandaoYunApi jdy = ctx.jdy;
  156 + JSONArray allRecords = ctx.allRecords;
  157 + try {
  158 + String type = s.getType() == null ? "" : s.getType().toLowerCase();
  159 + JSONArray rows;
  160 + long count;
  161 + if ("scenario7".equals(type)) {
  162 + rows = buildScenario7Rows(jdy, s);
  163 + count = rows.size();
  164 + } else {
  165 + JSONArray all = jdy.listAllData(props.getApiKey(), s.getAppId(), s.getEntryId());
  166 + rows = filterScope(all, s);
  167 + count = count(s, rows);
  168 + }
  169 + result.put(s.getId(), count);
  170 + log.info("场景[{}] 命中={} (参与统计{}条)", s.getId(), count, rows.size());
  171 +
  172 + JSONArray widgets = jdy.listWidgets(props.getApiKey(), s.getAppId(), s.getEntryId());
  173 + String extraHeader = null;
  174 + List<String> extraValues = null;
  175 + if (!"scenario7".equals(type)) {
  176 + if ("scenario4".equals(type) || "scenario6".equals(type) || "scenario8".equals(type)) {
  177 + extraHeader = "预警供应商";
  178 + } else if ("scenario5".equals(type) || "scenario9".equals(type)) {
  179 + extraHeader = "预警工程师";
  180 + } else {
  181 + extraHeader = "筛选结果";
  182 + }
  183 + extraValues = buildExtraValues(s, rows);
  184 + }
  185 + String fileName = JdyExcelExportService.nowFileName();
  186 + String path = excelExportService.exportRows(widgets, rows, extraHeader, extraValues, fileName);
  187 + if (path == null || path.startsWith("FAIL")) {
  188 + throw new IllegalStateException("Excel 导出失败: " + path);
  189 + }
  190 +
  191 + String fileId = qxApi.uploadFile(token, new File(path), fileName);
  192 +
  193 + String syncCode = s.getSyncCode();
  194 + JSONObject rec = findRecordBySyncCode(allRecords, syncCode);
  195 + if (rec == null) {
  196 + log.warn("按 syncCode={} 未查到记录,跳过写回", syncCode);
  197 + return;
  198 + }
  199 + rec.put(qx.getCountField(), count);
  200 + if (qx.getAttachField() != null && !qx.getAttachField().isEmpty()) {
  201 + JSONObject rel = new JSONObject();
  202 + rel.put("id", fileId);
  203 + rel.put("dataTitle", fileName);
  204 + rec.put(qx.getAttachField(), rel);
  205 + rec.put(qx.getAttachField() + "Id", fileId);
  206 + }
  207 + qxApi.updateData(token, qx.getAppId(), qx.getUpdateCode(), rec);
  208 + log.info("写回成功: syncCode={} id={} {}={} 附件={}", syncCode, rec.getString("id"),
  209 + qx.getCountField(), count, fileName);
  210 + } catch (Exception e) {
  211 + log.error("场景[{}] 写回失败", s.getId(), e);
  212 + result.put(s.getId() + "_error", e.getMessage());
  213 + }
  214 + }
  215 +
  216 + /* ==================== 范围过滤 ==================== */
  217 +
  218 + /** 按场景统计周期过滤数据:全量 / 当月 / 当季度 / 当年 / 上月。 */
  219 + private JSONArray filterScope(JSONArray all, JdyRiskProperties.Scenario s) {
  220 + if (!s.isMonthOnly() && !s.isQuarterOnly() && !s.isYearOnly() && !s.isPrevMonthOnly()) {
  221 + return all;
  222 + }
  223 + ZonedDateTime now = ZonedDateTime.now(ZONE);
  224 + ZonedDateTime qStart = quarterStart(now);
  225 + ZonedDateTime qEnd = qStart.plusMonths(3);
  226 + ZonedDateTime yStart = now.withDayOfYear(1).truncatedTo(ChronoUnit.DAYS);
  227 + ZonedDateTime pmStart = now.minusMonths(1).withDayOfMonth(1).truncatedTo(ChronoUnit.DAYS);
  228 + ZonedDateTime pmEnd = now.withDayOfMonth(1).truncatedTo(ChronoUnit.DAYS);
  229 + String month = now.format(MONTH_FMT);
  230 + JSONArray out = new JSONArray();
  231 + for (int i = 0; i < all.size(); i++) {
  232 + JSONObject row = all.getJSONObject(i);
  233 + ZonedDateTime dt = parseTime(row.getString(s.getDateField()));
  234 + if (dt == null) {
  235 + continue;
  236 + }
  237 + boolean keep = false;
  238 + if (s.isQuarterOnly()) {
  239 + keep = !dt.isBefore(qStart) && dt.isBefore(qEnd);
  240 + } else if (s.isYearOnly()) {
  241 + keep = !dt.isBefore(yStart) && !dt.isAfter(now);
  242 + } else if (s.isPrevMonthOnly()) {
  243 + keep = !dt.isBefore(pmStart) && dt.isBefore(pmEnd);
  244 + } else if (s.isMonthOnly()) {
  245 + keep = month.equals(dt.format(MONTH_FMT));
  246 + }
  247 + if (keep) {
  248 + out.add(row);
  249 + }
  250 + }
  251 + return out;
  252 + }
  253 +
  254 + /* ==================== 计数 ==================== */
  255 +
  256 + private long count(JdyRiskProperties.Scenario s, JSONArray rows) {
  257 + String type = s.getType() == null ? "" : s.getType().toLowerCase();
  258 + switch (type) {
  259 + case "scenario1":
  260 + return countScenario1(s, rows);
  261 + case "scenario2":
  262 + return countScenario2(s, rows);
  263 + case "scenario3":
  264 + return countScenario3(s, rows);
  265 + case "scenario4":
  266 + case "scenario5":
  267 + return countGroupByUp(s, rows);
  268 + case "scenario6":
  269 + return warningGroupsByCount(s, rows).size();
  270 + case "scenario8":
  271 + case "scenario9":
  272 + return warningGroupsByRatio(s, rows).size();
  273 + default:
  274 + throw new IllegalStateException("未知场景类型: " + s.getType());
  275 + }
  276 + }
  277 +
  278 + /** 场景1:总计>=5 且 差值>=1 且 flowState=进行中。 */
  279 + private long countScenario1(JdyRiskProperties.Scenario s, JSONArray data) {
  280 + long hit = 0;
  281 + for (int i = 0; i < data.size(); i++) {
  282 + JSONObject row = data.getJSONObject(i);
  283 + double total = num(row, s.getTotalField());
  284 + double diff = num(row, s.getDiffField());
  285 + Integer flow = row.getInteger("flowState");
  286 + if (total >= 5 && diff >= 1 && flow != null && flow == s.getInProgressState()) {
  287 + hit++;
  288 + }
  289 + }
  290 + return hit;
  291 + }
  292 +
  293 + /** 场景2:按供应商分组,SI数量/问题数量合计>60% 且 合计>=5 的供应商个数。 */
  294 + private long countScenario2(JdyRiskProperties.Scenario s, JSONArray data) {
  295 + Map<String, double[]> byGroup = new LinkedHashMap<>();
  296 + for (int i = 0; i < data.size(); i++) {
  297 + JSONObject row = data.getJSONObject(i);
  298 + String group = orEmpty(row.getString(s.getGroupField()));
  299 + double qty = num(row, s.getQtyField());
  300 + double[] agg = byGroup.computeIfAbsent(group, k -> new double[2]);
  301 + agg[0] += qty;
  302 + if ("SI".equalsIgnoreCase(row.getString(s.getSiField()))) {
  303 + agg[1] += qty;
  304 + }
  305 + }
  306 + long hit = 0;
  307 + for (double[] agg : byGroup.values()) {
  308 + if (agg[0] >= 5 && (agg[1] / agg[0]) > 0.6) {
  309 + hit++;
  310 + }
  311 + }
  312 + return hit;
  313 + }
  314 +
  315 + /** 场景3:SI占比>60% 且 总问题数>=5 的行数(工程师个数)。 */
  316 + private long countScenario3(JdyRiskProperties.Scenario s, JSONArray data) {
  317 + long hit = 0;
  318 + for (int i = 0; i < data.size(); i++) {
  319 + JSONObject row = data.getJSONObject(i);
  320 + double total = num(row, s.getTotalField());
  321 + double ratio = num(row, s.getRatioField());
  322 + if (total >= 5 && ratio > 0.6) {
  323 + hit++;
  324 + }
  325 + }
  326 + return hit;
  327 + }
  328 +
  329 + /** 场景4/5:升级不含排除值且非空,按分组计数,分组次数 >= minCount 的命中分组个数。 */
  330 + private long countGroupByUp(JdyRiskProperties.Scenario s, JSONArray data) {
  331 + return warningGroupsByUp(s, data).size();
  332 + }
  333 +
  334 + /** 场景4/5:命中分组集合(升级不含排除值且非空,分组计数 >= minCount)。 */
  335 + private Set<String> warningGroupsByUp(JdyRiskProperties.Scenario s, JSONArray data) {
  336 + Map<String, Integer> counts = new LinkedHashMap<>();
  337 + for (int i = 0; i < data.size(); i++) {
  338 + JSONObject row = data.getJSONObject(i);
  339 + if (isUpHit(s, row)) {
  340 + String g = orEmpty(row.getString(s.getGroupField()));
  341 + counts.merge(g, 1, Integer::sum);
  342 + }
  343 + }
  344 + int threshold = Math.max(1, s.getMinCount());
  345 + Set<String> warn = new LinkedHashSet<>();
  346 + for (Map.Entry<String, Integer> e : counts.entrySet()) {
  347 + if (e.getValue() >= threshold) {
  348 + warn.add(e.getKey());
  349 + }
  350 + }
  351 + return warn;
  352 + }
  353 +
  354 + /** 场景6:按分组字段计数,分组次数 >= minCount 的命中分组集合。 */
  355 + private Set<String> warningGroupsByCount(JdyRiskProperties.Scenario s, JSONArray data) {
  356 + Map<String, Integer> counts = new LinkedHashMap<>();
  357 + for (int i = 0; i < data.size(); i++) {
  358 + JSONObject row = data.getJSONObject(i);
  359 + String g = orEmpty(row.getString(s.getGroupField()));
  360 + counts.merge(g, 1, Integer::sum);
  361 + }
  362 + int threshold = Math.max(1, s.getMinCount());
  363 + Set<String> warn = new LinkedHashSet<>();
  364 + for (Map.Entry<String, Integer> e : counts.entrySet()) {
  365 + if (e.getValue() >= threshold) {
  366 + warn.add(e.getKey());
  367 + }
  368 + }
  369 + return warn;
  370 + }
  371 +
  372 + /** 场景8/9:按分组字段,flagField==flagValue 的条数 / 总条数 > ratioThreshold 的命中分组集合。 */
  373 + private Set<String> warningGroupsByRatio(JdyRiskProperties.Scenario s, JSONArray data) {
  374 + Map<String, int[]> byGroup = new LinkedHashMap<>(); // [总数, 命中数]
  375 + for (int i = 0; i < data.size(); i++) {
  376 + JSONObject row = data.getJSONObject(i);
  377 + String g = orEmpty(row.getString(s.getGroupField()));
  378 + int[] agg = byGroup.computeIfAbsent(g, k -> new int[2]);
  379 + agg[0]++;
  380 + if (s.getFlagValue() != null && s.getFlagValue().equalsIgnoreCase(row.getString(s.getFlagField()))) {
  381 + agg[1]++;
  382 + }
  383 + }
  384 + Set<String> warn = new LinkedHashSet<>();
  385 + double th = s.getRatioThreshold();
  386 + for (Map.Entry<String, int[]> e : byGroup.entrySet()) {
  387 + int[] agg = e.getValue();
  388 + if (agg[0] > 0 && ((double) agg[1] / agg[0]) > th) {
  389 + warn.add(e.getKey());
  390 + }
  391 + }
  392 + return warn;
  393 + }
  394 +
  395 + /**
  396 + * 场景7:多表关联 + 超期过滤(分批流式,防大表 OOM)。
  397 + * <p>① 收集排除表单的条码集合;② 流式遍历主表:条码命中排除集合则丢弃;③ 剩余按入库时间超过 maxAgeDays 天保留。
  398 + */
  399 + private JSONArray buildScenario7Rows(JiandaoYunApi jdy, JdyRiskProperties.Scenario s) {
  400 + Set<String> exclude = new LinkedHashSet<>();
  401 + for (JdyRiskProperties.ExcludeForm ef : s.getExcludeForms()) {
  402 + if (ef == null || ef.getEntryId() == null || ef.getBarcodeField() == null) {
  403 + continue;
  404 + }
  405 + final JdyRiskProperties.ExcludeForm cur = ef;
  406 + jdy.forEachPage(props.getApiKey(), s.getAppId(), cur.getEntryId(),
  407 + java.util.Collections.singletonList(cur.getBarcodeField()), page -> {
  408 + for (int i = 0; i < page.size(); i++) {
  409 + String b = page.getJSONObject(i).getString(cur.getBarcodeField());
  410 + if (b != null && !b.trim().isEmpty()) {
  411 + exclude.add(b.trim());
  412 + }
  413 + }
  414 + });
  415 + log.info("场景7 排除来源 entry={} 累计条码={}", ef.getEntryId(), exclude.size());
  416 + }
  417 +
  418 + java.time.Instant cutoff = ZonedDateTime.now(ZONE)
  419 + .minusDays(Math.max(0, s.getMaxAgeDays())).toInstant();
  420 + JSONArray kept = new JSONArray();
  421 + final int[] scanned = {0};
  422 + jdy.forEachPage(props.getApiKey(), s.getAppId(), s.getEntryId(), s.getFields(), page -> {
  423 + for (int i = 0; i < page.size(); i++) {
  424 + scanned[0]++;
  425 + JSONObject row = page.getJSONObject(i);
  426 + String barcode = row.getString(s.getBarcodeField());
  427 + if (barcode != null && exclude.contains(barcode.trim())) {
  428 + continue; // 条码在出库/抵扣表中出现 → 过滤掉
  429 + }
  430 + ZonedDateTime inTime = parseTime(row.getString(s.getDateField()));
  431 + if (inTime == null) {
  432 + continue;
  433 + }
  434 + if (inTime.toInstant().isBefore(cutoff)) {
  435 + kept.add(row); // 入库时间超过 maxAgeDays 天
  436 + }
  437 + }
  438 + });
  439 + log.info("场景7 主表扫描={}条, 过滤后保留={}条 (排除条码={}, 超期阈值={}天)",
  440 + scanned[0], kept.size(), exclude.size(), s.getMaxAgeDays());
  441 + return kept;
  442 + }
  443 +
  444 + /** 场景2:命中供应商集合(SI数量/问题数量合计>60% 且 合计>=5)。 */
  445 + private Set<String> warningSuppliers2(JdyRiskProperties.Scenario s, JSONArray data) {
  446 + Map<String, double[]> byGroup = new LinkedHashMap<>();
  447 + for (int i = 0; i < data.size(); i++) {
  448 + JSONObject row = data.getJSONObject(i);
  449 + String group = orEmpty(row.getString(s.getGroupField()));
  450 + double qty = num(row, s.getQtyField());
  451 + double[] agg = byGroup.computeIfAbsent(group, k -> new double[2]);
  452 + agg[0] += qty;
  453 + if ("SI".equalsIgnoreCase(row.getString(s.getSiField()))) {
  454 + agg[1] += qty;
  455 + }
  456 + }
  457 + Set<String> warn = new LinkedHashSet<>();
  458 + for (Map.Entry<String, double[]> e : byGroup.entrySet()) {
  459 + double[] agg = e.getValue();
  460 + if (agg[0] >= 5 && (agg[1] / agg[0]) > 0.6) {
  461 + warn.add(e.getKey());
  462 + }
  463 + }
  464 + return warn;
  465 + }
  466 +
  467 + /**
  468 + * Excel 最右附加列的值(各场景统一):
  469 + * 命中/预警的行显示对应名称,其余为空。
  470 + * 取值优先级:extra-field > group-field > 「命中」。
  471 + */
  472 + private List<String> buildExtraValues(JdyRiskProperties.Scenario s, JSONArray data) {
  473 + String type = s.getType() == null ? "" : s.getType().toLowerCase();
  474 + Set<String> warnGroups = null;
  475 + if ("scenario2".equals(type)) {
  476 + warnGroups = warningSuppliers2(s, data);
  477 + } else if ("scenario4".equals(type) || "scenario5".equals(type)) {
  478 + warnGroups = warningGroupsByUp(s, data);
  479 + } else if ("scenario6".equals(type)) {
  480 + warnGroups = warningGroupsByCount(s, data);
  481 + } else if ("scenario8".equals(type) || "scenario9".equals(type)) {
  482 + warnGroups = warningGroupsByRatio(s, data);
  483 + }
  484 + List<String> values = new ArrayList<>();
  485 + for (int i = 0; i < data.size(); i++) {
  486 + JSONObject row = data.getJSONObject(i);
  487 + String v = "";
  488 + if ("scenario1".equals(type)) {
  489 + v = rowHitScenario1(s, row) ? displayName(s, row) : "";
  490 + } else if ("scenario3".equals(type)) {
  491 + v = rowHitScenario3(s, row) ? displayName(s, row) : "";
  492 + } else if (warnGroups != null) {
  493 + String g = orEmpty(row.getString(s.getGroupField()));
  494 + v = warnGroups.contains(g) ? displayName(s, row) : "";
  495 + }
  496 + values.add(v);
  497 + }
  498 + return values;
  499 + }
  500 +
  501 + private String displayName(JdyRiskProperties.Scenario s, JSONObject row) {
  502 + if (s.getExtraField() != null && !s.getExtraField().isEmpty()) {
  503 + return orEmpty(row.getString(s.getExtraField()));
  504 + }
  505 + if (s.getGroupField() != null && !s.getGroupField().isEmpty()) {
  506 + return orEmpty(row.getString(s.getGroupField()));
  507 + }
  508 + return "命中";
  509 + }
  510 +
  511 + private boolean rowHitScenario1(JdyRiskProperties.Scenario s, JSONObject row) {
  512 + double total = num(row, s.getTotalField());
  513 + double diff = num(row, s.getDiffField());
  514 + Integer flow = row.getInteger("flowState");
  515 + return total >= 5 && diff >= 1 && flow != null && flow == s.getInProgressState();
  516 + }
  517 +
  518 + private boolean rowHitScenario3(JdyRiskProperties.Scenario s, JSONObject row) {
  519 + double total = num(row, s.getTotalField());
  520 + double ratio = num(row, s.getRatioField());
  521 + return total >= 5 && ratio > 0.6;
  522 + }
  523 +
  524 + /** 升级字段是否命中:非空 且 不在排除值内。 */
  525 + private boolean isUpHit(JdyRiskProperties.Scenario s, JSONObject row) {
  526 + String up = row.getString(s.getUpField());
  527 + if (up == null || up.trim().isEmpty()) {
  528 + return false;
  529 + }
  530 + if (s.getExcludeValues() != null) {
  531 + for (String ex : s.getExcludeValues()) {
  532 + if (ex != null && ex.equalsIgnoreCase(up.trim())) {
  533 + return false;
  534 + }
  535 + }
  536 + }
  537 + return true;
  538 + }
  539 +
  540 + /* ==================== 工具 ==================== */
  541 +
  542 + /** 在启效记录中按 syncCode 匹配(重复时取第一条并告警)。 */
  543 + private JSONObject findRecordBySyncCode(JSONArray records, String syncCode) {
  544 + if (records == null || syncCode == null || syncCode.isEmpty()) {
  545 + return null;
  546 + }
  547 + JSONObject found = null;
  548 + for (int i = 0; i < records.size(); i++) {
  549 + JSONObject r = records.getJSONObject(i);
  550 + if (syncCode.equals(r.getString("syncCode"))) {
  551 + if (found == null) {
  552 + found = r;
  553 + } else {
  554 + log.warn("syncCode={} 存在多条记录(id={} 与 id={}),使用第一条",
  555 + syncCode, found.getString("id"), r.getString("id"));
  556 + }
  557 + }
  558 + }
  559 + return found;
  560 + }
  561 +
  562 + private static ZonedDateTime quarterStart(ZonedDateTime now) {
  563 + int qStartMonth = ((now.getMonthValue() - 1) / 3) * 3 + 1;
  564 + return now.withMonth(qStartMonth).withDayOfMonth(1).truncatedTo(ChronoUnit.DAYS);
  565 + }
  566 +
  567 + private static ZonedDateTime parseTime(String iso) {
  568 + if (iso == null || iso.isEmpty()) {
  569 + return null;
  570 + }
  571 + try {
  572 + return Instant.parse(iso).atZone(ZONE);
  573 + } catch (Exception e) {
  574 + return null;
  575 + }
  576 + }
  577 +
  578 + private static double num(JSONObject row, String field) {
  579 + if (field == null) {
  580 + return 0d;
  581 + }
  582 + Object v = row.get(field);
  583 + if (v == null) {
  584 + return 0d;
  585 + }
  586 + if (v instanceof Number) {
  587 + return ((Number) v).doubleValue();
  588 + }
  589 + try {
  590 + return Double.parseDouble(String.valueOf(v));
  591 + } catch (NumberFormatException e) {
  592 + return 0d;
  593 + }
  594 + }
  595 +
  596 + private static String orEmpty(String s) {
  597 + return (s == null || s.isEmpty()) ? "(空)" : s;
  598 + }
  599 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.service;
  2 +
  3 +import com.alibaba.fastjson.JSONArray;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.qgutech.qgyun.apaas.sync.jdy.api.JiandaoYunApi;
  6 +import com.qgutech.qgyun.apaas.sync.jdy.api.QxApi;
  7 +import com.qgutech.qgyun.apaas.sync.jdy.config.JdySyncProperties;
  8 +import com.qgutech.qgyun.apaas.sync.jdy.util.JsonHttpUtils;
  9 +import lombok.extern.slf4j.Slf4j;
  10 +import org.springframework.stereotype.Service;
  11 +
  12 +import java.time.OffsetDateTime;
  13 +import java.time.format.DateTimeParseException;
  14 +import java.util.ArrayList;
  15 +import java.util.HashSet;
  16 +import java.util.LinkedHashMap;
  17 +import java.util.List;
  18 +import java.util.Map;
  19 +import java.util.Set;
  20 +
  21 +/**
  22 + * 简道云 -> 启效 同步编排:找应用 -> 列表单/字段/数据 -> 建/复用启效表单+字段 -> 写数据(镜像或追加)。
  23 + * <p>
  24 + * 依赖:仅有 HTTP 调用(简道云 V5 + 启效平台),无任何中间件,独立进程可跑。
  25 + */
  26 +@Slf4j
  27 +@Service
  28 +public class JdyToQxSyncService {
  29 +
  30 + private final JdySyncProperties props;
  31 +
  32 + public JdyToQxSyncService(JdySyncProperties props) {
  33 + this.props = props;
  34 + }
  35 +
  36 + /** 同步全部配置的应用。 */
  37 + public List<String> syncAll() {
  38 + List<String> summary = new ArrayList<>();
  39 + for (JdySyncProperties.App app : props.getApps()) {
  40 + try {
  41 + summary.add(syncApp(app));
  42 + } catch (Exception e) {
  43 + log.error("同步应用「{}」失败", app.getName(), e);
  44 + summary.add("FAIL " + app.getName() + " : " + e.getMessage());
  45 + }
  46 + }
  47 + return summary;
  48 + }
  49 +
  50 + /** 同步单个应用,返回摘要。 */
  51 + public String syncApp(JdySyncProperties.App app) {
  52 + JiandaoYunApi jdy = new JiandaoYunApi(props.getHost());
  53 + QxApi qx = new QxApi(props.getQx().getBaseUrl());
  54 + String token = qx.login(props.getQx().getUsername(), props.getQx().getPassword(), props.getQx().getCorpCode());
  55 +
  56 + String qxAppId = app.getQxAppId();
  57 + if (qxAppId == null || qxAppId.isEmpty()) {
  58 + qxAppId = qx.findAppByName(token, app.getName());
  59 + if (qxAppId == null || qxAppId.isEmpty()) {
  60 + qxAppId = qx.createApp(token, app.getName());
  61 + log.info("启效无同名应用,自动创建: {} -> {}", app.getName(), qxAppId);
  62 + } else {
  63 + log.info("启效已存在同名应用,直接复用: {} -> {}", app.getName(), qxAppId);
  64 + }
  65 + }
  66 +
  67 + String jdyAppId = app.getAppId();
  68 + if (jdyAppId == null || jdyAppId.isEmpty()) {
  69 + jdyAppId = jdy.findAppId(app.getApiKey(), app.getName());
  70 + }
  71 + if (jdyAppId == null || jdyAppId.isEmpty()) {
  72 + throw new IllegalStateException("简道云未找到应用: " + app.getName());
  73 + }
  74 +
  75 + JSONArray forms = jdy.listAllForms(app.getApiKey(), jdyAppId);
  76 + int formCount = 0;
  77 + int recordCount = 0;
  78 + for (int i = 0; i < forms.size(); i++) {
  79 + JSONObject form = forms.getJSONObject(i);
  80 + String formName = form.getString("name");
  81 + String entryId = form.getString("entry_id");
  82 + if (!app.getFormNames().isEmpty() && !app.getFormNames().contains(formName)) {
  83 + continue;
  84 + }
  85 + if (!app.getEntryIds().isEmpty() && !app.getEntryIds().contains(entryId)) {
  86 + log.info("按 entryIds 过滤,跳过表单 {} ({})", formName, entryId);
  87 + continue;
  88 + }
  89 + int cnt = syncForm(app, jdy, qx, token, qxAppId, jdyAppId, form);
  90 + formCount++;
  91 + recordCount += cnt;
  92 + }
  93 + String summary = "OK " + app.getName() + " | 表单=" + formCount + " 数据=" + recordCount;
  94 + log.info(summary);
  95 + return summary;
  96 + }
  97 +
  98 + private int syncForm(JdySyncProperties.App app, JiandaoYunApi jdy, QxApi qx, String token,
  99 + String qxAppId, String jdyAppId, JSONObject form) {
  100 + String formName = form.getString("name");
  101 + String entryId = form.getString("entry_id");
  102 +
  103 + JSONArray widgets = jdy.listWidgets(app.getApiKey(), jdyAppId, entryId);
  104 +
  105 + // 构建字段 + 映射(widget.code -> fieldKey)+ 日期字段
  106 + List<QxApi.Field> fields = new ArrayList<>();
  107 + Map<String, String> widgetToFieldKey = new LinkedHashMap<>();
  108 + Set<String> dateFieldKeys = new HashSet<>();
  109 + Set<String> usedFieldKey = new HashSet<>();
  110 + for (int i = 0; i < widgets.size(); i++) {
  111 + JSONObject w = widgets.getJSONObject(i);
  112 + String widgetCode = w.getString("name");
  113 + String label = w.getString("label");
  114 + if (label == null || label.isEmpty()) {
  115 + label = w.getString("widgetName");
  116 + }
  117 + String jdyType = w.getString("type");
  118 + String fieldKey = FieldMapping.genFieldKey(label, app.getFieldMapping(), usedFieldKey);
  119 + String qxType = FieldMapping.mapType(jdyType);
  120 + fields.add(new QxApi.Field(label, fieldKey, qxType));
  121 + widgetToFieldKey.put(widgetCode, fieldKey);
  122 + if (FieldMapping.isDateJdy(jdyType)) {
  123 + dateFieldKeys.add(fieldKey);
  124 + }
  125 + }
  126 +
  127 + // 确保启效表单存在(按「表单名+新增接口」判断)
  128 + JSONArray apiManages = qx.listApiManages(token, qxAppId);
  129 + JSONObject addApi = qx.findAddApi(apiManages, formName);
  130 + if (addApi == null) {
  131 + String funCode = FieldMapping.genFunCode(formName);
  132 + String modelId = qx.createFormModel(token, qxAppId, formName, funCode);
  133 + qx.saveDesignObj(token, qxAppId, app.getName(), modelId, formName, funCode, fields);
  134 + log.info("创建启效表单 {}: funCode={} modelId={} 字段={}", formName, funCode, modelId, buildFieldsText(fields));
  135 + apiManages = qx.listApiManages(token, qxAppId);
  136 + addApi = qx.findAddApi(apiManages, formName);
  137 + }
  138 + if (addApi == null) {
  139 + throw new IllegalStateException("未找到表单「" + formName + "」新增接口");
  140 + }
  141 + String addCode = addApi.getString("code");
  142 +
  143 + // replace 模式:先清空目标表单数据(分页查全量 -> 单次删除)
  144 + if (app.isReplace()) {
  145 + JSONObject pageApi = qx.findApiByKeyword(apiManages, formName, "分页查询");
  146 + JSONObject delApi = qx.findApiByKeyword(apiManages, formName, "删除");
  147 + if (pageApi != null && delApi != null) {
  148 + JSONArray existing = qx.pageQuery(token, qxAppId, pageApi.getString("code"));
  149 + int del = 0;
  150 + for (int i = 0; i < existing.size(); i++) {
  151 + JSONObject row = existing.getJSONObject(i);
  152 + qx.deleteData(token, qxAppId, delApi.getString("code"), row.getString("id"));
  153 + del++;
  154 + }
  155 + log.info("清空 {} 已有数据 {} 条", formName, del);
  156 + } else {
  157 + log.warn("未找到分页查询/删除接口,跳过清空: {}", formName);
  158 + }
  159 + }
  160 +
  161 + // 拉简道云数据(next_id 分页,limit 上限 100)并写入
  162 + List<JSONObject> records = fetchAll(jdy, app.getApiKey(), jdyAppId, entryId);
  163 + int ok = 0;
  164 + int fail = 0;
  165 + for (JSONObject rec : records) {
  166 + try {
  167 + Map<String, Object> payload = buildPayload(rec, widgets, widgetToFieldKey, dateFieldKeys);
  168 + qx.insertData(token, qxAppId, addCode, payload);
  169 + ok++;
  170 + } catch (Exception e) {
  171 + fail++;
  172 + log.error("写入单条失败({}),继续下一条: {}", formName, e.getMessage());
  173 + }
  174 + }
  175 + log.info("同步 {}: 写入 {} 条, 失败 {} 条", formName, ok, fail);
  176 + return ok;
  177 + }
  178 +
  179 + /** 全量拉取数据:v5 不返回 next_id,用上一页最后一条 _id 作为 data_id 继续翻页,直到不足一页。 */
  180 + private List<JSONObject> fetchAll(JiandaoYunApi jdy, String apiKey, String appId, String entryId) {
  181 + List<JSONObject> result = new ArrayList<>();
  182 + String dataId = null;
  183 + int page = 0;
  184 + do {
  185 + page++;
  186 + Map<String, Object> body = new LinkedHashMap<>();
  187 + body.put("app_id", appId);
  188 + body.put("entry_id", entryId);
  189 + body.put("limit", 100);
  190 + if (dataId != null && !dataId.isEmpty()) {
  191 + body.put("data_id", dataId);
  192 + }
  193 + JSONObject resp = JsonHttpUtils.postJson2Obj(jdy.getHost() + "/v5/app/entry/data/list",
  194 + JsonHttpUtils.bearer(apiKey), body);
  195 + checkJdyError(resp);
  196 + JSONArray data = resp.getJSONArray("data");
  197 + int size = data == null ? 0 : data.size();
  198 + if (data != null) {
  199 + for (int i = 0; i < size; i++) {
  200 + result.add(data.getJSONObject(i));
  201 + }
  202 + }
  203 + dataId = size > 0 ? data.getJSONObject(size - 1).getString("_id") : null;
  204 + log.info("分页第 {} 页, 本页 {} 条, data_id={}", page, size, dataId);
  205 + if (size < 100) {
  206 + break;
  207 + }
  208 + } while (dataId != null && !dataId.isEmpty());
  209 + return result;
  210 + }
  211 +
  212 + /** 校验简道云返回错误码,失败并带说明抛出。 */
  213 + private void checkJdyError(JSONObject resp) {
  214 + if (resp == null) {
  215 + throw new IllegalStateException("简道云返回为空");
  216 + }
  217 + Integer code = resp.getInteger("code");
  218 + if (code != null && !Integer.valueOf(0).equals(code)) {
  219 + throw new IllegalStateException("简道云 error code=" + code + " msg=" + resp.getString("msg")
  220 + + (resp.getJSONObject("meta") == null ? "" : " ip=" + resp.getJSONObject("meta").getString("ip")));
  221 + }
  222 + }
  223 +
  224 + private Map<String, Object> buildPayload(JSONObject record, JSONArray widgets,
  225 + Map<String, String> widgetToFieldKey, Set<String> dateFieldKeys) {
  226 + Map<String, Object> payload = new LinkedHashMap<>();
  227 + for (int i = 0; i < widgets.size(); i++) {
  228 + JSONObject w = widgets.getJSONObject(i);
  229 + String widgetCode = w.getString("name");
  230 + String fieldKey = widgetToFieldKey.get(widgetCode);
  231 + if (fieldKey == null) {
  232 + continue;
  233 + }
  234 + Object v = record.get(widgetCode);
  235 + if (dateFieldKeys.contains(fieldKey) && v instanceof String) {
  236 + v = toMs((String) v);
  237 + }
  238 + payload.put(fieldKey, v);
  239 + }
  240 + return payload;
  241 + }
  242 +
  243 + private String buildFieldsText(List<QxApi.Field> fields) {
  244 + StringBuilder sb = new StringBuilder();
  245 + for (QxApi.Field f : fields) {
  246 + if (sb.length() > 0) {
  247 + sb.append(", ");
  248 + }
  249 + sb.append(f.getTitle()).append("->").append(f.getFieldKey());
  250 + }
  251 + return sb.toString();
  252 + }
  253 +
  254 + public static Object toMs(String iso) {
  255 + try {
  256 + return OffsetDateTime.parse(iso).toInstant().toEpochMilli();
  257 + } catch (DateTimeParseException e) {
  258 + try {
  259 + return OffsetDateTime.parse(iso.replace(" ", "T")).toInstant().toEpochMilli();
  260 + } catch (Exception ex) {
  261 + return iso;
  262 + }
  263 + }
  264 + }
  265 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.task;
  2 +
  3 +import com.qgutech.qgyun.apaas.sync.jdy.config.JdySyncProperties;
  4 +import com.qgutech.qgyun.apaas.sync.jdy.service.JdyToQxSyncService;
  5 +import lombok.extern.slf4j.Slf4j;
  6 +import org.springframework.scheduling.annotation.Scheduled;
  7 +import org.springframework.stereotype.Component;
  8 +
  9 +import javax.annotation.Resource;
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * 简道云 -> 启效 每日定时同步任务。
  14 + */
  15 +@Slf4j
  16 +@Component
  17 +public class JdySyncScheduledTask {
  18 +
  19 + @Resource
  20 + private JdyToQxSyncService syncService;
  21 +
  22 + @Resource
  23 + private JdySyncProperties props;
  24 +
  25 + @Scheduled(cron = "${jdy-sync.cron:0 0 2 * * ?}")
  26 + public void dailySync() {
  27 + if (!props.isEnabled()) {
  28 + log.info("jdy-sync.enabled=false,跳过每日同步");
  29 + return;
  30 + }
  31 + log.info("开始简道云每日同步,应用数: {}", props.getApps().size());
  32 + List<String> result = syncService.syncAll();
  33 + result.forEach(r -> log.info("同步结果: {}", r));
  34 + }
  35 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.util;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import lombok.extern.slf4j.Slf4j;
  6 +import org.apache.http.HttpEntity;
  7 +import org.apache.http.HttpStatus;
  8 +import org.apache.http.client.methods.CloseableHttpResponse;
  9 +import org.apache.http.client.methods.HttpGet;
  10 +import org.apache.http.client.methods.HttpPost;
  11 +import org.apache.http.client.methods.HttpUriRequest;
  12 +import org.apache.http.entity.ContentType;
  13 +import org.apache.http.entity.StringEntity;
  14 +import org.apache.http.impl.client.CloseableHttpClient;
  15 +import org.apache.http.util.EntityUtils;
  16 +
  17 +import java.util.HashMap;
  18 +import java.util.Map;
  19 +
  20 +/**
  21 + * JSON HTTP 工具类。
  22 + * <p>
  23 + * 关键:启效(dev)网关对无 {@code User-Agent} 的请求返回 500,因此所有请求都强制带 UA。
  24 + */
  25 +@Slf4j
  26 +public class JsonHttpUtils {
  27 +
  28 + public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) qx-apaas-sync";
  29 +
  30 + private JsonHttpUtils() {
  31 + }
  32 +
  33 + public static CloseableHttpClient client() {
  34 + try {
  35 + return SSLClientCustom.getHttpClinet();
  36 + } catch (Exception e) {
  37 + throw new RuntimeException("创建 http client 失败", e);
  38 + }
  39 + }
  40 +
  41 + /**
  42 + * POST JSON,返回响应 body 字符串。
  43 + */
  44 + public static String postJson(String url, Map<String, String> headers, String jsonBody) {
  45 + HttpPost post = new HttpPost(url);
  46 + for (Map.Entry<String, String> e : headers.entrySet()) {
  47 + post.setHeader(e.getKey(), e.getValue());
  48 + }
  49 + post.setHeader("User-Agent", USER_AGENT);
  50 + post.setHeader("Content-Type", "application/json;charset=UTF-8");
  51 + if (jsonBody != null) {
  52 + post.setEntity(new StringEntity(jsonBody, ContentType.APPLICATION_JSON));
  53 + }
  54 + return execute(post);
  55 + }
  56 +
  57 + /**
  58 + * POST JSON,解析为 JSONObject。
  59 + */
  60 + public static JSONObject postJson2Obj(String url, Map<String, String> headers, Object jsonBody) {
  61 + String body = postJson(url, headers, jsonBody == null ? null : JSON.toJSONString(jsonBody));
  62 + return parse(body);
  63 + }
  64 +
  65 + public static String get(String url, Map<String, String> headers) {
  66 + HttpGet get = new HttpGet(url);
  67 + for (Map.Entry<String, String> e : headers.entrySet()) {
  68 + get.setHeader(e.getKey(), e.getValue());
  69 + }
  70 + get.setHeader("User-Agent", USER_AGENT);
  71 + return execute(get);
  72 + }
  73 +
  74 + /**
  75 + * GET JSON,解析为 JSONObject。
  76 + */
  77 + public static JSONObject getJson2Obj(String url, Map<String, String> headers) {
  78 + return parse(get(url, headers));
  79 + }
  80 +
  81 + public static JSONObject parse(String body) {
  82 + if (body == null || body.isEmpty()) {
  83 + return new JSONObject();
  84 + }
  85 + try {
  86 + return JSON.parseObject(body);
  87 + } catch (Exception e) {
  88 + log.warn("非 JSON 响应: {}", body);
  89 + JSONObject o = new JSONObject();
  90 + o.put("_raw", body);
  91 + return o;
  92 + }
  93 + }
  94 +
  95 + private static String execute(HttpUriRequest request) {
  96 + return run(request);
  97 + }
  98 +
  99 + /** 执行请求并返回响应体(公共,供 multipart 等场景复用)。 */
  100 + public static String run(HttpUriRequest request) {
  101 + CloseableHttpClient client = client();
  102 + try (CloseableHttpResponse resp = client.execute(request)) {
  103 + int code = resp.getStatusLine().getStatusCode();
  104 + HttpEntity entity = resp.getEntity();
  105 + String body = entity == null ? "" : EntityUtils.toString(entity);
  106 + if (code != HttpStatus.SC_OK) {
  107 + log.warn("HTTP {} -> {} : {}", request.getMethod(), request.getURI(), body);
  108 + }
  109 + return body;
  110 + } catch (Exception e) {
  111 + throw new RuntimeException("请求失败: " + request.getURI() + " -> " + e.getMessage(), e);
  112 + } finally {
  113 + try {
  114 + client.close();
  115 + } catch (Exception ignored) {
  116 + // ignore
  117 + }
  118 + }
  119 + }
  120 +
  121 + public static Map<String, String> bearer(String token) {
  122 + Map<String, String> m = new HashMap<>();
  123 + m.put("Authorization", "Bearer " + token);
  124 + return m;
  125 + }
  126 +
  127 + public static Map<String, String> token(String token) {
  128 + Map<String, String> m = new HashMap<>();
  129 + m.put("Authorization", token);
  130 + return m;
  131 + }
  132 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.jdy.util;
  2 +
  3 +import org.apache.http.config.Registry;
  4 +import org.apache.http.config.RegistryBuilder;
  5 +import org.apache.http.conn.socket.ConnectionSocketFactory;
  6 +import org.apache.http.conn.socket.PlainConnectionSocketFactory;
  7 +import org.apache.http.conn.ssl.NoopHostnameVerifier;
  8 +import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
  9 +import org.apache.http.conn.ssl.TrustStrategy;
  10 +import org.apache.http.impl.client.CloseableHttpClient;
  11 +import org.apache.http.impl.client.HttpClients;
  12 +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
  13 +import org.apache.http.ssl.SSLContextBuilder;
  14 +
  15 +import java.security.KeyManagementException;
  16 +import java.security.KeyStoreException;
  17 +import java.security.NoSuchAlgorithmException;
  18 +import java.security.cert.CertificateException;
  19 +import java.security.cert.X509Certificate;
  20 +
  21 +/**
  22 + * SSL 客户端工厂(信任所有站点,兼容自定义证书域名)。
  23 + */
  24 +public class SSLClientCustom {
  25 +
  26 + private static final String HTTP = "http";
  27 + private static final String HTTPS = "https";
  28 + private static SSLConnectionSocketFactory sslConnectionSocketFactory = null;
  29 + //连接池管理类
  30 + private static PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = null;
  31 + //管理Https连接的上下文类
  32 + private static SSLContextBuilder sslContextBuilder = null;
  33 +
  34 + static {
  35 + try {
  36 + sslContextBuilder = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
  37 + @Override
  38 + public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
  39 +// 信任所有站点 直接返回true
  40 + return true;
  41 + }
  42 + });
  43 + sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(),
  44 + new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);
  45 + Registry<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory>create()
  46 + .register(HTTP, new PlainConnectionSocketFactory())
  47 + .register(HTTPS, sslConnectionSocketFactory)
  48 + .build();
  49 + poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(registryBuilder);
  50 + poolingHttpClientConnectionManager.setMaxTotal(200);
  51 + } catch (NoSuchAlgorithmException e) {
  52 + e.printStackTrace();
  53 + } catch (KeyStoreException e) {
  54 + e.printStackTrace();
  55 + } catch (KeyManagementException e) {
  56 + e.printStackTrace();
  57 + }
  58 + }
  59 +
  60 + /**
  61 + * 获取连接
  62 + *
  63 + * @return
  64 + * @throws Exception
  65 + */
  66 + public static CloseableHttpClient getHttpClinet() throws Exception {
  67 + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory)
  68 + .setConnectionManager(poolingHttpClientConnectionManager)
  69 + .setConnectionManagerShared(true)
  70 + .build();
  71 + return httpClient;
  72 + }
  73 +}
... ...
  1 +server:
  2 + port: 8090
  3 +
  4 +spring:
  5 + application:
  6 + name: qx-apaas-sync
  7 +
  8 +logging:
  9 + path: ./logs
  10 + level:
  11 + com.qgutech.qgyun.apaas.sync: INFO
  12 +
  13 +# 简道云 -> 启效 同步
  14 +jdy-sync:
  15 + enabled: false # true=启用每日定时任务;false=仅通过 REST 接口手动触发
  16 + cron: "0 0 2 * * ?" # 每天 02:00
  17 + # 简道云基础地址:独立域名/独享版用 https://<域名>/api(长安: https://jdy.changan.com.cn/api);公有云用 https://api.jiandaoyun.com/api
  18 + host: https://jdy.changan.com.cn/api
  19 + qx:
  20 + base-url: https://dev3.qgutech.com # 启效3.0 环境地址
  21 + username: 15077901670
  22 + password: "000000"
  23 + corp-code: default
  24 + apps:
  25 + - name: 合肥长安_技术处 # 简道云应用名
  26 + app-id: 65fd5c0e0d1f1a7ae4f038ec # 简道云 app_id(今日实测)
  27 + api-key: lOnr4ms8jfc0gbCwVYS7YtbYQXjBFq979Cc06BcC866427b2a7aAd054598Bc7bB
  28 + entry-ids: # 仅同步这些表单 entry_id(实测可访问)
  29 + - 696f1754f141344a6b794f9c
  30 + qx-app-id: # 目标启效应用id(不填则按 name 自动创建;已存在同名应用会直接复用)
  31 + replace: true # 是=每天清空目标表单后重建镜像;否=追加
  32 + # field-mapping: {姓名: name, 姓名: name} # 可选,覆盖内置字典
  33 + # form-names: [人员管理, 部门管理] # 可选,仅同步这些表单
  34 +
... ...
  1 +@echo off
  2 +rem ============================================================
  3 +rem 在新窗口启动 qx-apaas-sync,并实时显示日志
  4 +rem 关闭该窗口 / Ctrl+C 即停止应用
  5 +rem ============================================================
  6 +cd /d "%~dp0"
  7 +start "qx-apaas-sync 日志" cmd /k run.bat
... ...
  1 +@echo off
  2 +chcp 65001 >nul
  3 +echo 停止 qx-apaas-sync 应用 ...
  4 +powershell -NoProfile -Command "Get-CimInstance Win32_Process -Filter \"Name='java.exe'\" | Where-Object { $_.CommandLine -like '*qx-apaas-sync*' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force; Write-Output ('已停止 PID=' + $_.ProcessId) }"
  5 +echo 完成
  6 +pause
... ...
  1 +@echo off
  2 +chcp 65001 >nul
  3 +rem 实时查看日志文件(应用已在运行;日志文件为 logs\spring.log)
  4 +cd /d "%~dp0"
  5 +if not exist "logs\spring.log" (
  6 + echo 未找到 logs\spring.log,请先用 run.bat / start.bat 启动应用
  7 + pause
  8 + exit /b 1
  9 +)
  10 +powershell -NoProfile -Command "Get-Content -Path '.\logs\spring.log' -Wait -Tail 60 -Encoding UTF8"
... ...
  1 +server:
  2 + port: 8090
  3 +
  4 +spring:
  5 + application:
  6 + name: qx-apaas-sync
  7 +
  8 +logging:
  9 + path: ./logs
  10 + level:
  11 + com.qgutech.qgyun.apaas.sync: INFO
  12 +
  13 +# 简道云 -> 启效 同步
  14 +jdy-sync:
  15 + enabled: false # true=启用每日定时任务;false=仅通过 REST 接口手动触发
  16 + cron: "0 0 2 * * ?" # 每天 02:00
  17 + # 简道云基础地址:独立域名/独享版用 https://<域名>/api(长安: https://jdy.changan.com.cn/api);公有云用 https://api.jiandaoyun.com/api
  18 + host: https://jdy.changan.com.cn/api
  19 + qx:
  20 + base-url: https://dev3.qgutech.com # 启效3.0 环境地址
  21 + username: 15077901670
  22 + password: "000000"
  23 + corp-code: default
  24 + apps:
  25 + - name: 合肥长安_技术处 # 简道云应用名
  26 + app-id: 65fd5c0e0d1f1a7ae4f038ec # 简道云 app_id(今日实测)
  27 + api-key: lOnr4ms8jfc0gbCwVYS7YtbYQXjBFq979Cc06BcC866427b2a7aAd054598Bc7bB
  28 + entry-ids: # 仅同步这些表单 entry_id(实测可访问)
  29 + - 696f1754f141344a6b794f9c
  30 + qx-app-id: # 目标启效应用id(不填则按 name 自动创建;已存在同名应用会直接复用)
  31 + replace: true # 是=每天清空目标表单后重建镜像;否=追加
  32 + # field-mapping: {姓名: name, 姓名: name} # 可选,覆盖内置字典
  33 + # form-names: [人员管理, 部门管理] # 可选,仅同步这些表单
  34 +
... ...
  1 +#Created by Apache Maven 3.5.3
  2 +version=1.0.0-SNAPSHOT
  3 +groupId=com.qgutech.qgyun.apaas
  4 +artifactId=qx-apaas-sync
... ...
  1 +com\qgutech\qgyun\apaas\sync\jdy\config\JdyRiskProperties$ExcludeForm.class
... ...
  1 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\config\JdySyncProperties.java
  2 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\controller\JdyFormController.java
  3 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\controller\JdyRiskController.java
  4 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\QxApaasSyncApplication.java
  5 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\api\JiandaoYunApi.java
  6 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\config\JdySyncConfig.java
  7 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\service\JdyRiskStatisticsService.java
  8 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\util\SSLClientCustom.java
  9 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\service\JdyToQxSyncService.java
  10 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\api\QxApi.java
  11 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\util\JsonHttpUtils.java
  12 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\service\FieldMapping.java
  13 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\service\JdyExcelExportService.java
  14 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\config\JdyRiskProperties.java
  15 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\controller\JdySyncController.java
  16 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\task\JdySyncScheduledTask.java
  17 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\config\JdyFormSyncProperties.java
  18 +D:\code\qx-apaas-sync\src\main\java\com\qgutech\qgyun\apaas\sync\jdy\service\JdyFormSyncService.java
... ...
No preview for this file type