Merge branch 'main' of http://27.223.88.102:33000/chenx/qhmes
This commit is contained in:
BIN
doc/MCS_SQLServer_表结构说明.docx
Normal file
BIN
doc/MCS_SQLServer_表结构说明.docx
Normal file
Binary file not shown.
3550
doc/MCS_SQLServer_表结构说明.md
Normal file
3550
doc/MCS_SQLServer_表结构说明.md
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/MCS_SQLServer_表结构说明.xlsx
Normal file
BIN
doc/MCS_SQLServer_表结构说明.xlsx
Normal file
Binary file not shown.
@@ -230,6 +230,10 @@ public class ShiroConfig {
|
|||||||
filterChainDefinitionMap.put("/sys/category/anon/**", "anon");
|
filterChainDefinitionMap.put("/sys/category/anon/**", "anon");
|
||||||
// 桌面端用户反同步批量上报(Outbox -> /sys/sync/batch)
|
// 桌面端用户反同步批量上报(Outbox -> /sys/sync/batch)
|
||||||
filterChainDefinitionMap.put("/sys/sync/batch", "anon");
|
filterChainDefinitionMap.put("/sys/sync/batch", "anon");
|
||||||
|
//update-begin---author:cursor ---date:2026-07-20 for:【设备库桥接】桌面代理免密接口-----------
|
||||||
|
filterChainDefinitionMap.put("/sys/device/agent/**", "anon");
|
||||||
|
filterChainDefinitionMap.put("/xslmes/deviceAgent/anon/**", "anon");
|
||||||
|
//update-end---author:cursor ---date:2026-07-20 for:【设备库桥接】桌面代理免密接口-----------
|
||||||
|
|
||||||
// 添加自己的过滤器并且取名为jwt
|
// 添加自己的过滤器并且取名为jwt
|
||||||
Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
|
Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
|
||||||
|
|||||||
@@ -1258,7 +1258,111 @@ JeecgUniapp-master/src/pages/rawMaterialInspect/rawMaterialInspect.vue
|
|||||||
JeecgUniapp-master/src/pages/rawMaterialInspect/inspectResult.vue
|
JeecgUniapp-master/src/pages/rawMaterialInspect/inspectResult.vue
|
||||||
JeecgUniapp-master/src/common/work.ts
|
JeecgUniapp-master/src/common/work.ts
|
||||||
|
|
||||||
-- author:GHT---date:20260730--for: <20><>XSLMES-20260730-DING-PULL<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̨<EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܼ<EFBFBD><EFBFBD><EFBFBD> ---
|
-- author:jiangxh---date:20260728--for: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD>Ϊͬһ<CDAC>豸<EFBFBD><E8B1B8>Ψһ ---
|
||||||
|
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMixerConditionService.java
|
||||||
|
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixerConditionServiceImpl.java
|
||||||
|
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMixerConditionController.java
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/MesXslMixerCondition.api.ts
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/MesXslMixerCondition.data.ts
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD><CFB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λС<CEBB><D0A1> ---
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.data.ts
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaSpecModal.vue
|
||||||
|
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5>3λ<33><CEBB>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3λ<33><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2λ ---
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue
|
||||||
|
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD>λС<CEBB><D0A1> ---
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts
|
||||||
|
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD>ϼ<EFBFBD>ʾ<EFBFBD><CABE>ѡ<EFBFBD>ϸ<EFBFBD>Ϊģ<CEAA><C4A3><EFBFBD><EFBFBD>ѯ ---
|
||||||
|
jeecgboot-vue3/src/views/mes/material/materialQuery.util.ts
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMixerMaterialList.vue
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMaterialList.vue
|
||||||
|
jeecgboot-vue3/src/views/mes/material/modules/MesMixerMaterialSelectModal.vue
|
||||||
|
jeecgboot-vue3/src/views/mes/material/modules/MesMaterialSelectModal.vue
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD>ϡ<EFBFBD><CFA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>༭У<E0BCAD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ψһ ---
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.api.ts
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.data.ts
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMaterial.api.ts
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϡ<EFBFBD><CFA1><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD>365<36><35> ---
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.data.ts
|
||||||
|
yy-admin-master/YY.Admin/ViewModels/MixerMaterial/MixerMaterialEditDialogViewModel.cs
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD><CFB8><EFBFBD><EFBFBD>%/<2F><><EFBFBD>ͳһ<CDB3><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λС<CEBB><D0A1> ---
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java
|
||||||
|
jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_171__mes_xsl_formula_spec_line_decimal3.sql
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.data.ts
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaSpecModal.vue
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><>WebSocket<65><74>pongTimeout 1s<31><73>10s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---
|
||||||
|
jeecgboot-vue3/src/hooks/web/useWebSocket.ts
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><>WebSocket<65><74><EFBFBD><EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Redis<69>ذ<EFBFBD><D8B0><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---
|
||||||
|
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/websocket/WebSocket.java
|
||||||
|
jeecgboot-vue3/src/hooks/web/useWebSocket.ts
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><>HTTP<54><50>Ĭ<EFBFBD>ϳ<EFBFBD>ʱ10s<30><73>60s<30><73><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>120s ---
|
||||||
|
jeecgboot-vue3/src/utils/http/axios/index.ts
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.api.ts
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD>B/F<><46><EFBFBD>ϸ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>ƥ<EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ά<EFBFBD><CEAC> ---
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD><C9A1>ս<EFBFBD><D5BD><EFBFBD>ϸĸ<CFB8><C4B8><EFBFBD>д<EFBFBD><D0B4>뽺<EFBFBD><EBBDBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><>ѡ<EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>/<2F><><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1> ---
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue
|
||||||
|
jeecgboot-vue3/src/views/mes/material/modules/MesMaterialSelectModal.vue
|
||||||
|
jeecgboot-vue3/src/views/mes/material/materialQuery.util.ts
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260730--for: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD><C9A1>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɻ<EFBFBD><C9BB><EFBFBD>ʾ<EFBFBD><CABE>Ԥ<EFBFBD><D4A4>ʱ<EFBFBD><CAB1>ƥ<EFBFBD>佺<EFBFBD><E4BDBA><EFBFBD>б<EFBFBD> ---
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaGenerateMixingModal.vue
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260730--for: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD>B/Fƥ<46><C6A5><EFBFBD>Ž<EFBFBD>ǰ+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƴSA01<30>Ȱ汾<C8B0><E6B1BE> ---
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260730--for: <20><><EFBFBD><EFBFBD><EFBFBD>ϡ<EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1>ҵ<EFBFBD><D2B5><EFBFBD>ֶΣ<D6B6>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---
|
||||||
|
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/entity/MesMaterial.java
|
||||||
|
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java
|
||||||
|
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMaterialService.java
|
||||||
|
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMaterialServiceImpl.java
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixingSpecServiceImpl.java
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMaterial.api.ts
|
||||||
|
jeecgboot-vue3/src/views/mes/material/modules/MesMaterialSelectModal.vue
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260730--for: <20><><EFBFBD><EFBFBD><EFBFBD>ϡ<EFBFBD><CFA1>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD>ŸĶ<C5B8> ---
|
||||||
|
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/entity/MesMaterial.java
|
||||||
|
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java
|
||||||
|
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMaterialService.java
|
||||||
|
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMaterialServiceImpl.java
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixingSpecServiceImpl.java
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMaterial.api.ts
|
||||||
|
jeecgboot-vue3/src/views/mes/material/modules/MesMaterialSelectModal.vue
|
||||||
|
jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260730--for: <20><><EFBFBD><EFBFBD><EFBFBD>ϡ<EFBFBD><CFA1><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>أ<EFBFBD><D8A3><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>Զ<EFBFBD><D4B6>뽺<EFBFBD><EBBDBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> ---
|
||||||
|
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts
|
||||||
|
|
||||||
|
-- author:GHT---date:20260730--for: <20><>XSLMES-20260730-DING-PULL<4C><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̨<EFBFBD><CCA8><EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD>ܼ<EFBFBD><DCBC><EFBFBD> ---
|
||||||
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/approval/integration/engine/IntegrationForceReplayHolder.java
|
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/approval/integration/engine/IntegrationForceReplayHolder.java
|
||||||
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/approval/integration/engine/IntegrationOrchestrator.java
|
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/approval/integration/engine/IntegrationOrchestrator.java
|
||||||
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/dingtalk/stream/DingApprovalManualPullService.java
|
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/dingtalk/stream/DingApprovalManualPullService.java
|
||||||
@@ -1267,4 +1371,4 @@ jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/app
|
|||||||
jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_164__mes_xsl_approval_record_pull_ding_result.sql
|
jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_164__mes_xsl_approval_record_pull_ding_result.sql
|
||||||
jeecgboot-vue3/src/views/xslmes/approval/mesXslApprovalRecord/MesXslApprovalRecordList.vue
|
jeecgboot-vue3/src/views/xslmes/approval/mesXslApprovalRecord/MesXslApprovalRecordList.vue
|
||||||
jeecgboot-vue3/src/views/xslmes/approval/mesXslApprovalRecord/MesXslApprovalRecord.api.ts
|
jeecgboot-vue3/src/views/xslmes/approval/mesXslApprovalRecord/MesXslApprovalRecord.api.ts
|
||||||
-- author:GHT---date:20260730--for: <20><>XSLMES-20260730-DING-PULL<4C><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̨<EFBFBD><CCA8><EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܼ<EFBFBD><EFBFBD><EFBFBD> ---
|
-- author:GHT---date:20260730--for: <20><>XSLMES-20260730-DING-PULL<4C><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̨<EFBFBD><CCA8><EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD>ܼ<EFBFBD><DCBC><EFBFBD> ---
|
||||||
|
|||||||
@@ -36,5 +36,11 @@
|
|||||||
<artifactId>jeecg-module-print</artifactId>
|
<artifactId>jeecg-module-print</artifactId>
|
||||||
<version>${jeecgboot.version}</version>
|
<version>${jeecgboot.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- 设备同步/桌面代理命令总线 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jeecgframework.boot3</groupId>
|
||||||
|
<artifactId>jeecg-module-device-sync</artifactId>
|
||||||
|
<version>${jeecgboot.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ public class MesXslAutoSmallMaterialDemandPlanController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sql.append("GROUP BY ");
|
sql.append("GROUP BY ");
|
||||||
|
sql.append(statDateExpr).append(", ");
|
||||||
if (groupedByMachine) {
|
if (groupedByMachine) {
|
||||||
sql.append(machineExpr).append(", ");
|
sql.append(machineExpr).append(", ");
|
||||||
}
|
}
|
||||||
@@ -160,14 +161,20 @@ public class MesXslAutoSmallMaterialDemandPlanController {
|
|||||||
|
|
||||||
private String buildOrderBy(boolean groupedByMachine) {
|
private String buildOrderBy(boolean groupedByMachine) {
|
||||||
if (groupedByMachine) {
|
if (groupedByMachine) {
|
||||||
return " ORDER BY machineName, rawMaterialName";
|
return " ORDER BY statDate DESC, machineName, rawMaterialName";
|
||||||
}
|
}
|
||||||
return " ORDER BY rawMaterialName";
|
return " ORDER BY statDate DESC, rawMaterialName";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildRowId(MesXslSmallMaterialDemandPlanSummary row, boolean groupedByMachine, int seq) {
|
private String buildRowId(MesXslSmallMaterialDemandPlanSummary row, boolean groupedByMachine, int seq) {
|
||||||
String machine = groupedByMachine ? StringUtils.defaultString(row.getMachineName()) : "ALL";
|
String machine = groupedByMachine ? StringUtils.defaultString(row.getMachineName()) : "ALL";
|
||||||
return machine + "_" + StringUtils.defaultString(row.getRawMaterialName()) + "_" + seq;
|
return StringUtils.defaultString(row.getStatDate())
|
||||||
|
+ "_"
|
||||||
|
+ machine
|
||||||
|
+ "_"
|
||||||
|
+ StringUtils.defaultString(row.getRawMaterialName())
|
||||||
|
+ "_"
|
||||||
|
+ seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String trim(String value) {
|
private String trim(String value) {
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ public class MesXslManualSmallMaterialDemandPlanController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sql.append("GROUP BY ");
|
sql.append("GROUP BY ");
|
||||||
|
sql.append(statDateExpr).append(", ");
|
||||||
if (groupedByMachine) {
|
if (groupedByMachine) {
|
||||||
sql.append(machineExpr).append(", ");
|
sql.append(machineExpr).append(", ");
|
||||||
}
|
}
|
||||||
@@ -160,14 +161,20 @@ public class MesXslManualSmallMaterialDemandPlanController {
|
|||||||
|
|
||||||
private String buildOrderBy(boolean groupedByMachine) {
|
private String buildOrderBy(boolean groupedByMachine) {
|
||||||
if (groupedByMachine) {
|
if (groupedByMachine) {
|
||||||
return " ORDER BY machineName, rawMaterialName";
|
return " ORDER BY statDate DESC, machineName, rawMaterialName";
|
||||||
}
|
}
|
||||||
return " ORDER BY rawMaterialName";
|
return " ORDER BY statDate DESC, rawMaterialName";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildRowId(MesXslSmallMaterialDemandPlanSummary row, boolean groupedByMachine, int seq) {
|
private String buildRowId(MesXslSmallMaterialDemandPlanSummary row, boolean groupedByMachine, int seq) {
|
||||||
String machine = groupedByMachine ? StringUtils.defaultString(row.getMachineName()) : "ALL";
|
String machine = groupedByMachine ? StringUtils.defaultString(row.getMachineName()) : "ALL";
|
||||||
return machine + "_" + StringUtils.defaultString(row.getRawMaterialName()) + "_" + seq;
|
return StringUtils.defaultString(row.getStatDate())
|
||||||
|
+ "_"
|
||||||
|
+ machine
|
||||||
|
+ "_"
|
||||||
|
+ StringUtils.defaultString(row.getRawMaterialName())
|
||||||
|
+ "_"
|
||||||
|
+ seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String trim(String value) {
|
private String trim(String value) {
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package org.jeecg.modules.xslmes.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.modules.xslmes.entity.MesXslMillAction;
|
||||||
|
import org.jeecg.modules.xslmes.service.IMesXslMillActionService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MES 开炼机动作接收表
|
||||||
|
*/
|
||||||
|
@Tag(name = "开炼机动作接收")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/xslmes/mesXslMillAction")
|
||||||
|
public class MesXslMillActionController extends JeecgController<MesXslMillAction, IMesXslMillActionService> {
|
||||||
|
|
||||||
|
@Autowired private IMesXslMillActionService mesXslMillActionService;
|
||||||
|
|
||||||
|
@Operation(summary = "开炼机动作接收-分页列表查询")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<IPage<MesXslMillAction>> queryPageList(
|
||||||
|
MesXslMillAction model,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
QueryWrapper<MesXslMillAction> queryWrapper = QueryGenerator.initQueryWrapper(model, req.getParameterMap());
|
||||||
|
queryWrapper.orderByDesc("update_time");
|
||||||
|
IPage<MesXslMillAction> pageList = mesXslMillActionService.page(new Page<>(pageNo, pageSize), queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "开炼机动作接收-通过id查询")
|
||||||
|
@GetMapping("/queryById")
|
||||||
|
public Result<MesXslMillAction> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
MesXslMillAction entity = mesXslMillActionService.getById(id);
|
||||||
|
if (entity == null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresPermissions("xslmes:mes_xsl_mill_action:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, MesXslMillAction model) {
|
||||||
|
return super.exportXls(request, model, MesXslMillAction.class, "开炼机动作接收");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -110,31 +110,43 @@ public class MesXslMixerConditionController
|
|||||||
return Result.OK(entity);
|
return Result.OK(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "校验条件名称是否重复")
|
@Operation(summary = "校验条件名称是否重复(同一设备下)")
|
||||||
@GetMapping("/checkConditionName")
|
@GetMapping("/checkConditionName")
|
||||||
public Result<String> checkConditionName(
|
public Result<String> checkConditionName(
|
||||||
@RequestParam(name = "conditionName", required = true) String conditionName,
|
@RequestParam(name = "conditionName", required = true) String conditionName,
|
||||||
|
@RequestParam(name = "equipmentId", required = false) String equipmentId,
|
||||||
@RequestParam(name = "dataId", required = false) String dataId) {
|
@RequestParam(name = "dataId", required = false) String dataId) {
|
||||||
if (oConvertUtils.isEmpty(conditionName) || conditionName.trim().isEmpty()) {
|
if (oConvertUtils.isEmpty(conditionName) || conditionName.trim().isEmpty()) {
|
||||||
return Result.OK("该值可用!");
|
return Result.OK("该值可用!");
|
||||||
}
|
}
|
||||||
if (mesXslMixerConditionService.isConditionNameDuplicated(conditionName, dataId)) {
|
//update-begin---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称按设备唯一-----------
|
||||||
return Result.error("条件名称不能重复");
|
if (oConvertUtils.isEmpty(equipmentId) || equipmentId.trim().isEmpty()) {
|
||||||
|
return Result.OK("该值可用!");
|
||||||
}
|
}
|
||||||
|
if (mesXslMixerConditionService.isConditionNameDuplicated(conditionName, equipmentId, dataId)) {
|
||||||
|
return Result.error("同一设备下条件名称不能重复");
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称按设备唯一-----------
|
||||||
return Result.OK("该值可用!");
|
return Result.OK("该值可用!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "校验条件代码是否重复")
|
@Operation(summary = "校验条件代码是否重复(同一设备下)")
|
||||||
@GetMapping("/checkConditionCode")
|
@GetMapping("/checkConditionCode")
|
||||||
public Result<String> checkConditionCode(
|
public Result<String> checkConditionCode(
|
||||||
@RequestParam(name = "conditionCode", required = true) String conditionCode,
|
@RequestParam(name = "conditionCode", required = true) String conditionCode,
|
||||||
|
@RequestParam(name = "equipmentId", required = false) String equipmentId,
|
||||||
@RequestParam(name = "dataId", required = false) String dataId) {
|
@RequestParam(name = "dataId", required = false) String dataId) {
|
||||||
if (oConvertUtils.isEmpty(conditionCode) || conditionCode.trim().isEmpty()) {
|
if (oConvertUtils.isEmpty(conditionCode) || conditionCode.trim().isEmpty()) {
|
||||||
return Result.OK("该值可用!");
|
return Result.OK("该值可用!");
|
||||||
}
|
}
|
||||||
if (mesXslMixerConditionService.isConditionCodeDuplicated(conditionCode, dataId)) {
|
//update-begin---author:jiangxh ---date:20260728 for:【密炼机条件】条件代码按设备唯一-----------
|
||||||
return Result.error("条件代码不能重复");
|
if (oConvertUtils.isEmpty(equipmentId) || equipmentId.trim().isEmpty()) {
|
||||||
|
return Result.OK("该值可用!");
|
||||||
}
|
}
|
||||||
|
if (mesXslMixerConditionService.isConditionCodeDuplicated(conditionCode, equipmentId, dataId)) {
|
||||||
|
return Result.error("同一设备下条件代码不能重复");
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260728 for:【密炼机条件】条件代码按设备唯一-----------
|
||||||
return Result.OK("该值可用!");
|
return Result.OK("该值可用!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,16 +165,20 @@ public class MesXslMixerConditionController
|
|||||||
return "条件名称不能为空";
|
return "条件名称不能为空";
|
||||||
}
|
}
|
||||||
model.setConditionName(model.getConditionName().trim());
|
model.setConditionName(model.getConditionName().trim());
|
||||||
if (mesXslMixerConditionService.isConditionNameDuplicated(model.getConditionName(), excludeId)) {
|
//update-begin---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称/代码按设备唯一-----------
|
||||||
return "条件名称不能重复";
|
if (mesXslMixerConditionService.isConditionNameDuplicated(
|
||||||
|
model.getConditionName(), model.getEquipmentId(), excludeId)) {
|
||||||
|
return "同一设备下条件名称不能重复";
|
||||||
}
|
}
|
||||||
if (oConvertUtils.isEmpty(model.getConditionCode()) || StringUtils.isBlank(model.getConditionCode())) {
|
if (oConvertUtils.isEmpty(model.getConditionCode()) || StringUtils.isBlank(model.getConditionCode())) {
|
||||||
return "条件代码不能为空";
|
return "条件代码不能为空";
|
||||||
}
|
}
|
||||||
model.setConditionCode(model.getConditionCode().trim());
|
model.setConditionCode(model.getConditionCode().trim());
|
||||||
if (mesXslMixerConditionService.isConditionCodeDuplicated(model.getConditionCode(), excludeId)) {
|
if (mesXslMixerConditionService.isConditionCodeDuplicated(
|
||||||
return "条件代码不能重复";
|
model.getConditionCode(), model.getEquipmentId(), excludeId)) {
|
||||||
|
return "同一设备下条件代码不能重复";
|
||||||
}
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称/代码按设备唯一-----------
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,9 +95,12 @@ public class MesXslRawMaterialDemandPlanController {
|
|||||||
|
|
||||||
private String buildGroupedSql(
|
private String buildGroupedSql(
|
||||||
MesXslRawMaterialDemandPlanSummary query, boolean groupedByMachine, List<Object> params) {
|
MesXslRawMaterialDemandPlanSummary query, boolean groupedByMachine, List<Object> params) {
|
||||||
String planDateExpr = "DATE(t.plan_date)";
|
boolean hasPlanDate = hasColumn("mes_xsl_raw_material_demand_plan", "plan_date");
|
||||||
|
boolean hasMaterialId = hasColumn("mes_xsl_raw_material_demand_plan", "material_id");
|
||||||
|
String planDateExpr = hasPlanDate ? "t.plan_date" : "DATE(t.create_time)";
|
||||||
String machineExpr = "COALESCE(NULLIF(TRIM(t.machine_name),''), '')";
|
String machineExpr = "COALESCE(NULLIF(TRIM(t.machine_name),''), '')";
|
||||||
String materialIdExpr = "COALESCE(NULLIF(TRIM(t.material_id),''), '')";
|
String materialIdExpr =
|
||||||
|
hasMaterialId ? "COALESCE(NULLIF(TRIM(t.material_id),''), '')" : "''";
|
||||||
String erpCodeExpr = "COALESCE(NULLIF(TRIM(t.erp_code),''), '')";
|
String erpCodeExpr = "COALESCE(NULLIF(TRIM(t.erp_code),''), '')";
|
||||||
String rawMaterialExpr = "COALESCE(NULLIF(TRIM(t.raw_material_name),''), '')";
|
String rawMaterialExpr = "COALESCE(NULLIF(TRIM(t.raw_material_name),''), '')";
|
||||||
|
|
||||||
@@ -192,4 +195,12 @@ public class MesXslRawMaterialDemandPlanController {
|
|||||||
private String trim(String value) {
|
private String trim(String value) {
|
||||||
return value == null ? "" : value.trim();
|
return value == null ? "" : value.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasColumn(String tableName, String columnName) {
|
||||||
|
String sql =
|
||||||
|
"SELECT COUNT(1) FROM information_schema.COLUMNS "
|
||||||
|
+ "WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?";
|
||||||
|
Long count = jdbcTemplate.queryForObject(sql, Long.class, tableName, columnName);
|
||||||
|
return count != null && count > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package org.jeecg.modules.xslmes.deviceagent;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.modules.device.sync.agent.DeviceAgentCommandService;
|
||||||
|
import org.jeecg.modules.device.sync.agent.DeviceAgentResult;
|
||||||
|
import org.jeecg.modules.device.sync.agent.DeviceAgentSession;
|
||||||
|
import org.jeecg.modules.device.sync.agent.DeviceAgentSessionRegistry;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 桌面设备代理免密接口(注册/心跳/分块回传)。
|
||||||
|
*/
|
||||||
|
@Tag(name = "桌面设备代理")
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/xslmes/deviceAgent/anon")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MesXslDeviceAgentAnonController {
|
||||||
|
|
||||||
|
private final DeviceAgentSessionRegistry sessionRegistry;
|
||||||
|
private final DeviceAgentCommandService commandService;
|
||||||
|
|
||||||
|
@Operation(summary = "注册/心跳")
|
||||||
|
@PostMapping("/register")
|
||||||
|
public Result<Map<String, Object>> register(@RequestBody Map<String, Object> body) {
|
||||||
|
String deviceId = str(body, "deviceId");
|
||||||
|
if (StringUtils.isBlank(deviceId)) {
|
||||||
|
return Result.error("deviceId不能为空");
|
||||||
|
}
|
||||||
|
String hostName = str(body, "hostName");
|
||||||
|
Boolean dbConnected = bool(body.get("dbConnected"));
|
||||||
|
String dbMessage = str(body, "dbMessage");
|
||||||
|
sessionRegistry.registerOrHeartbeat(deviceId, hostName, dbConnected, dbMessage);
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("deviceId", deviceId);
|
||||||
|
data.put("accepted", true);
|
||||||
|
return Result.OK(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "心跳")
|
||||||
|
@PostMapping("/heartbeat")
|
||||||
|
public Result<String> heartbeat(@RequestBody Map<String, Object> body) {
|
||||||
|
String deviceId = str(body, "deviceId");
|
||||||
|
if (StringUtils.isBlank(deviceId)) {
|
||||||
|
return Result.error("deviceId不能为空");
|
||||||
|
}
|
||||||
|
sessionRegistry.registerOrHeartbeat(deviceId, str(body, "hostName"), bool(body.get("dbConnected")), str(body, "dbMessage"));
|
||||||
|
return Result.OK("ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "命令结果分块回传(大数据量)")
|
||||||
|
@PostMapping("/resultChunk")
|
||||||
|
public Result<String> resultChunk(@RequestBody DeviceAgentResult result) {
|
||||||
|
if (result == null || StringUtils.isBlank(result.getRequestId())) {
|
||||||
|
return Result.error("requestId不能为空");
|
||||||
|
}
|
||||||
|
// 当前实现:整包完成;桌面可在单次 chunk 中带 lastChunk=true 直接完成
|
||||||
|
if (Boolean.TRUE.equals(result.getLastChunk()) || result.getChunkTotal() == null || result.getChunkTotal() <= 1) {
|
||||||
|
commandService.completeResult(result);
|
||||||
|
} else {
|
||||||
|
log.info("收到分块回传 requestId={} chunk={}/{}", result.getRequestId(), result.getChunkIndex(), result.getChunkTotal());
|
||||||
|
// 简化:仅最后一块完成;中间块忽略合并(桌面端大结果优先走单次 STOMP 或一次 REST 全量)
|
||||||
|
if (Boolean.TRUE.equals(result.getLastChunk())) {
|
||||||
|
commandService.completeResult(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.OK("ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "在线代理列表")
|
||||||
|
@GetMapping("/online")
|
||||||
|
public Result<List<DeviceAgentSession>> online() {
|
||||||
|
return Result.OK(sessionRegistry.listOnline());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询代理状态")
|
||||||
|
@GetMapping("/status")
|
||||||
|
public Result<DeviceAgentSession> status(@RequestParam(name = "deviceId", required = false) String deviceId) {
|
||||||
|
return Result.OK(sessionRegistry.pickOnlineAgent(deviceId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String str(Map<String, Object> body, String key) {
|
||||||
|
if (body == null || body.get(key) == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String v = String.valueOf(body.get(key)).trim();
|
||||||
|
return v.isEmpty() || "null".equalsIgnoreCase(v) ? null : v;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Boolean bool(Object v) {
|
||||||
|
if (v == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (v instanceof Boolean) {
|
||||||
|
return (Boolean) v;
|
||||||
|
}
|
||||||
|
return Boolean.parseBoolean(String.valueOf(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package org.jeecg.modules.xslmes.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MES 开炼机动作接收表(采集自 MCSToMES_Act_Mill)
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("mes_xsl_mill_action")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description = "MES开炼机动作接收表")
|
||||||
|
public class MesXslMillAction implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Excel(name = "GUID", width = 36)
|
||||||
|
@Schema(description = "源表GUID")
|
||||||
|
private String guid;
|
||||||
|
|
||||||
|
@Excel(name = "动作地址", width = 10)
|
||||||
|
@Schema(description = "动作地址")
|
||||||
|
private Integer actAddr;
|
||||||
|
|
||||||
|
@Excel(name = "动作名称", width = 20)
|
||||||
|
@Schema(description = "动作名称")
|
||||||
|
private String actName;
|
||||||
|
|
||||||
|
@Excel(name = "动作名称(英)", width = 20)
|
||||||
|
@Schema(description = "动作名称(英)")
|
||||||
|
private String actNameEn;
|
||||||
|
|
||||||
|
@Excel(name = "动作备注", width = 15)
|
||||||
|
@Schema(description = "动作备注")
|
||||||
|
private String actMemo;
|
||||||
|
|
||||||
|
@Excel(name = "动作关联地址", width = 12)
|
||||||
|
@Schema(description = "动作关联地址")
|
||||||
|
private Integer actRepaddr;
|
||||||
|
|
||||||
|
@Excel(name = "写入时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "写入时间")
|
||||||
|
private Date writeTime;
|
||||||
|
|
||||||
|
@Excel(name = "读取时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "读取时间")
|
||||||
|
private Date readTime;
|
||||||
|
|
||||||
|
@Excel(name = "读写标识", width = 10)
|
||||||
|
@Schema(description = "读写标识")
|
||||||
|
private Integer rwFlag;
|
||||||
|
|
||||||
|
private Integer tenantId;
|
||||||
|
private String sysOrgCode;
|
||||||
|
private String createBy;
|
||||||
|
|
||||||
|
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
private String updateBy;
|
||||||
|
|
||||||
|
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
private Integer delFlag;
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.jeecg.modules.xslmes.entity.MesXslMillAction;
|
||||||
|
|
||||||
|
public interface MesXslMillActionMapper extends BaseMapper<MesXslMillAction> {}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.access;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.jeecg.modules.device.sync.agent.DeviceAgentCommandService;
|
||||||
|
import org.jeecg.modules.device.sync.agent.DeviceAgentResult;
|
||||||
|
import org.jeecg.modules.device.sync.agent.DeviceAgentSession;
|
||||||
|
import org.jeecg.modules.device.sync.agent.DeviceAgentSessionRegistry;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsDbConfig;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经桌面端代理访问设备库。
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class DesktopAgentMcsDataAccess implements IMcsDataAccess {
|
||||||
|
|
||||||
|
private final DeviceAgentCommandService commandService;
|
||||||
|
private final DeviceAgentSessionRegistry sessionRegistry;
|
||||||
|
private final McsDataSourceManager mcsDataSourceManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAgentMode() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resolveAgentDeviceId() {
|
||||||
|
MesXslMcsDbConfig cfg = mcsDataSourceManager.getCachedConfig();
|
||||||
|
String preferred = cfg == null ? null : cfg.getAgentDeviceId();
|
||||||
|
DeviceAgentSession session = sessionRegistry.pickOnlineAgent(preferred);
|
||||||
|
if (session == null) {
|
||||||
|
throw new IllegalStateException("无在线桌面设备代理,无法访问设备库");
|
||||||
|
}
|
||||||
|
return session.getDeviceId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Map<String, Object>> query(String sql, List<Object> params) {
|
||||||
|
String deviceId = resolveAgentDeviceId();
|
||||||
|
DeviceAgentResult result = commandService.query(deviceId, sql, params, 60_000);
|
||||||
|
return result.getRows() == null ? List.of() : result.getRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int execute(String sql, List<Object> params) {
|
||||||
|
String deviceId = resolveAgentDeviceId();
|
||||||
|
DeviceAgentResult result = commandService.write(deviceId, sql, params, 60_000);
|
||||||
|
return result.getAffected() == null ? 0 : result.getAffected();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int pushRows(String table, String mode, List<String> keys, List<Map<String, Object>> rows) {
|
||||||
|
String deviceId = resolveAgentDeviceId();
|
||||||
|
Map<String, Object> payload = new HashMap<>();
|
||||||
|
payload.put("mode", StringUtils.defaultIfBlank(mode, "insert"));
|
||||||
|
if (keys != null) {
|
||||||
|
payload.put("keys", keys);
|
||||||
|
}
|
||||||
|
payload.put("rows", rows == null ? new ArrayList<>() : rows);
|
||||||
|
DeviceAgentResult result = commandService.syncPush(deviceId, table, payload, 60_000);
|
||||||
|
return result.getAffected() == null ? 0 : result.getAffected();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean testConnection() {
|
||||||
|
try {
|
||||||
|
String deviceId = resolveAgentDeviceId();
|
||||||
|
DeviceAgentResult result = commandService.test(deviceId, 10_000);
|
||||||
|
return result != null && result.isSuccess();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("桌面代理中间库测试失败: {}", e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.access;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务端直连 SQL Server(调试/兼容保留)。
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class DirectJdbcMcsDataAccess implements IMcsDataAccess {
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
private final McsDataSourceManager mcsDataSourceManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAgentMode() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resolveAgentDeviceId() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Map<String, Object>> query(String sql, List<Object> params) {
|
||||||
|
JdbcTemplate jt = new JdbcTemplate(requireDs());
|
||||||
|
if (params == null || params.isEmpty()) {
|
||||||
|
return jt.queryForList(sql);
|
||||||
|
}
|
||||||
|
return jt.queryForList(sql, params.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int execute(String sql, List<Object> params) {
|
||||||
|
JdbcTemplate jt = new JdbcTemplate(requireDs());
|
||||||
|
if (params == null || params.isEmpty()) {
|
||||||
|
return jt.update(sql);
|
||||||
|
}
|
||||||
|
return jt.update(sql, params.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int pushRows(String table, String mode, List<String> keys, List<Map<String, Object>> rows) {
|
||||||
|
if (rows == null || rows.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int affected = 0;
|
||||||
|
for (Map<String, Object> row : rows) {
|
||||||
|
if ("update".equalsIgnoreCase(mode) || "upsert".equalsIgnoreCase(mode)) {
|
||||||
|
int u = updateByKeys(table, keys, row);
|
||||||
|
if (u > 0) {
|
||||||
|
affected += u;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ("update".equalsIgnoreCase(mode)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
affected += insertRow(table, row);
|
||||||
|
}
|
||||||
|
return affected;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean testConnection() {
|
||||||
|
try {
|
||||||
|
query("SELECT 1", null);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("直连中间库测试失败: {}", e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int insertRow(String table, Map<String, Object> row) {
|
||||||
|
List<String> cols = new ArrayList<>(row.keySet());
|
||||||
|
StringBuilder sql = new StringBuilder("INSERT INTO [").append(table).append("] (");
|
||||||
|
StringBuilder values = new StringBuilder(" VALUES (");
|
||||||
|
List<Object> params = new ArrayList<>();
|
||||||
|
for (int i = 0; i < cols.size(); i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
sql.append(',');
|
||||||
|
values.append(',');
|
||||||
|
}
|
||||||
|
sql.append('[').append(cols.get(i)).append(']');
|
||||||
|
values.append('?');
|
||||||
|
params.add(row.get(cols.get(i)));
|
||||||
|
}
|
||||||
|
sql.append(')').append(values).append(')');
|
||||||
|
return execute(sql.toString(), params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int updateByKeys(String table, List<String> keys, Map<String, Object> row) {
|
||||||
|
if (keys == null || keys.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
List<String> setCols = new ArrayList<>();
|
||||||
|
for (String c : row.keySet()) {
|
||||||
|
boolean isKey = keys.stream().anyMatch(k -> k.equalsIgnoreCase(c));
|
||||||
|
if (!isKey) {
|
||||||
|
setCols.add(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (setCols.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
StringBuilder sql = new StringBuilder("UPDATE [").append(table).append("] SET ");
|
||||||
|
List<Object> params = new ArrayList<>();
|
||||||
|
for (int i = 0; i < setCols.size(); i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
sql.append(',');
|
||||||
|
}
|
||||||
|
sql.append('[').append(setCols.get(i)).append("]=?");
|
||||||
|
params.add(getIgnoreCase(row, setCols.get(i)));
|
||||||
|
}
|
||||||
|
sql.append(" WHERE ");
|
||||||
|
for (int i = 0; i < keys.size(); i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
sql.append(" AND ");
|
||||||
|
}
|
||||||
|
sql.append('[').append(keys.get(i)).append("]=?");
|
||||||
|
params.add(getIgnoreCase(row, keys.get(i)));
|
||||||
|
}
|
||||||
|
return execute(sql.toString(), params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getIgnoreCase(Map<String, Object> row, String key) {
|
||||||
|
if (row.containsKey(key)) {
|
||||||
|
return row.get(key);
|
||||||
|
}
|
||||||
|
for (Map.Entry<String, Object> e : row.entrySet()) {
|
||||||
|
if (e.getKey() != null && e.getKey().equalsIgnoreCase(key)) {
|
||||||
|
return e.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataSource requireDs() {
|
||||||
|
DynamicRoutingDataSource routing = (DynamicRoutingDataSource) dataSource;
|
||||||
|
DataSource src = routing.getDataSources().get(McsDataSourceManager.DS_KEY);
|
||||||
|
if (src == null) {
|
||||||
|
throw new IllegalStateException("中间库数据源 " + McsDataSourceManager.DS_KEY + " 未注册");
|
||||||
|
}
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.access;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MCS 中间库访问抽象:直连 JDBC 或经桌面代理。
|
||||||
|
*/
|
||||||
|
public interface IMcsDataAccess {
|
||||||
|
|
||||||
|
boolean isAgentMode();
|
||||||
|
|
||||||
|
String resolveAgentDeviceId();
|
||||||
|
|
||||||
|
List<Map<String, Object>> query(String sql, List<Object> params);
|
||||||
|
|
||||||
|
int execute(String sql, List<Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量写入中间表(EQ_SYNC_PUSH)。
|
||||||
|
*
|
||||||
|
* @param table 白名单表名
|
||||||
|
* @param mode insert / update / upsert
|
||||||
|
* @param keys 匹配键(update/upsert)
|
||||||
|
* @param rows 行数据
|
||||||
|
* @return 影响行数
|
||||||
|
*/
|
||||||
|
int pushRows(String table, String mode, List<String> keys, List<Map<String, Object>> rows);
|
||||||
|
|
||||||
|
boolean testConnection();
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.access;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsDbConfig;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按配置在「桌面代理 / 直连」之间切换。
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class McsDataAccessFacade implements IMcsDataAccess {
|
||||||
|
|
||||||
|
public static final String MODE_DESKTOP_AGENT = "DESKTOP_AGENT";
|
||||||
|
public static final String MODE_DIRECT = "DIRECT";
|
||||||
|
|
||||||
|
private final McsDataSourceManager mcsDataSourceManager;
|
||||||
|
private final DesktopAgentMcsDataAccess desktopAgentMcsDataAccess;
|
||||||
|
private final DirectJdbcMcsDataAccess directJdbcMcsDataAccess;
|
||||||
|
|
||||||
|
public IMcsDataAccess current() {
|
||||||
|
return isAgentMode() ? desktopAgentMcsDataAccess : directJdbcMcsDataAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAgentMode() {
|
||||||
|
MesXslMcsDbConfig cfg = mcsDataSourceManager.getCachedConfig();
|
||||||
|
if (cfg == null) {
|
||||||
|
// 默认优先桌面代理
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String mode = StringUtils.defaultIfBlank(cfg.getAccessMode(), MODE_DESKTOP_AGENT).trim().toUpperCase();
|
||||||
|
return MODE_DESKTOP_AGENT.equals(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resolveAgentDeviceId() {
|
||||||
|
return current().resolveAgentDeviceId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Map<String, Object>> query(String sql, List<Object> params) {
|
||||||
|
return current().query(sql, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int execute(String sql, List<Object> params) {
|
||||||
|
return current().execute(sql, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int pushRows(String table, String mode, List<String> keys, List<Map<String, Object>> rows) {
|
||||||
|
return current().pushRows(table, mode, keys, rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean testConnection() {
|
||||||
|
return current().testConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.access;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MES → MCS 经桌面代理下发(EQ_SYNC_PUSH)。
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MesToMcsPushService {
|
||||||
|
|
||||||
|
private final McsDataAccessFacade mcsDataAccessFacade;
|
||||||
|
|
||||||
|
public int push(String table, String mode, List<String> keys, List<Map<String, Object>> rows) {
|
||||||
|
if (StringUtils.isBlank(table)) {
|
||||||
|
throw new IllegalArgumentException("table 不能为空");
|
||||||
|
}
|
||||||
|
int affected = mcsDataAccessFacade.pushRows(table, mode, keys, rows);
|
||||||
|
log.info("MES→MCS 下发完成 table={} mode={} rows={} affected={}",
|
||||||
|
table, mode, rows == null ? 0 : rows.size(), affected);
|
||||||
|
return affected;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,290 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.access.proxy;
|
||||||
|
|
||||||
|
import org.jeecg.modules.xslmes.mcs.access.IMcsDataAccess;
|
||||||
|
|
||||||
|
import java.sql.Array;
|
||||||
|
import java.sql.Blob;
|
||||||
|
import java.sql.CallableStatement;
|
||||||
|
import java.sql.Clob;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.NClob;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLClientInfoException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.SQLWarning;
|
||||||
|
import java.sql.SQLXML;
|
||||||
|
import java.sql.Savepoint;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.Struct;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
public class AgentProxyConnection implements Connection {
|
||||||
|
|
||||||
|
private final IMcsDataAccess dataAccess;
|
||||||
|
private boolean closed;
|
||||||
|
|
||||||
|
public AgentProxyConnection(IMcsDataAccess dataAccess) {
|
||||||
|
this.dataAccess = dataAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Statement createStatement() {
|
||||||
|
return new AgentProxyStatement(dataAccess, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PreparedStatement prepareStatement(String sql) {
|
||||||
|
return new AgentProxyPreparedStatement(dataAccess, sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CallableStatement prepareCall(String sql) throws SQLException {
|
||||||
|
throw new SQLException("CallableStatement not supported by agent proxy");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String nativeSQL(String sql) {
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAutoCommit(boolean autoCommit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getAutoCommit() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void commit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rollback() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
closed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClosed() {
|
||||||
|
return closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DatabaseMetaData getMetaData() throws SQLException {
|
||||||
|
throw new SQLException("DatabaseMetaData not supported by agent proxy");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReadOnly(boolean readOnly) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReadOnly() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCatalog(String catalog) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCatalog() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTransactionIsolation(int level) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTransactionIsolation() {
|
||||||
|
return Connection.TRANSACTION_READ_COMMITTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SQLWarning getWarnings() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearWarnings() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Statement createStatement(int resultSetType, int resultSetConcurrency) {
|
||||||
|
return createStatement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) {
|
||||||
|
return prepareStatement(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||||
|
throw new SQLException("CallableStatement not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Class<?>> getTypeMap() {
|
||||||
|
return Map.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTypeMap(Map<String, Class<?>> map) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHoldability(int holdability) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHoldability() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Savepoint setSavepoint() throws SQLException {
|
||||||
|
throw new SQLException("Savepoint not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Savepoint setSavepoint(String name) throws SQLException {
|
||||||
|
throw new SQLException("Savepoint not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rollback(Savepoint savepoint) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void releaseSavepoint(Savepoint savepoint) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) {
|
||||||
|
return createStatement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) {
|
||||||
|
return prepareStatement(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
||||||
|
throw new SQLException("CallableStatement not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) {
|
||||||
|
return prepareStatement(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) {
|
||||||
|
return prepareStatement(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PreparedStatement prepareStatement(String sql, String[] columnNames) {
|
||||||
|
return prepareStatement(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Clob createClob() throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Blob createBlob() throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NClob createNClob() throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SQLXML createSQLXML() throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid(int timeout) {
|
||||||
|
return !closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClientInfo(String name, String value) throws SQLClientInfoException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClientInfo(Properties properties) throws SQLClientInfoException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClientInfo(String name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Properties getClientInfo() {
|
||||||
|
return new Properties();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSchema(String schema) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSchema() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void abort(Executor executor) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNetworkTimeout(Executor executor, int milliseconds) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNetworkTimeout() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
|
if (iface.isInstance(this)) {
|
||||||
|
return iface.cast(this);
|
||||||
|
}
|
||||||
|
throw new SQLException("Not a wrapper");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWrapperFor(Class<?> iface) {
|
||||||
|
return iface.isInstance(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.access.proxy;
|
||||||
|
|
||||||
|
import org.jeecg.modules.xslmes.mcs.access.IMcsDataAccess;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.SQLFeatureNotSupportedException;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 JDBC 调用转发到桌面设备代理的 DataSource,供 @DS("sqlserver_mcs") 复用。
|
||||||
|
*/
|
||||||
|
public class AgentProxyDataSource implements DataSource {
|
||||||
|
|
||||||
|
private final IMcsDataAccess dataAccess;
|
||||||
|
|
||||||
|
public AgentProxyDataSource(IMcsDataAccess dataAccess) {
|
||||||
|
this.dataAccess = dataAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnection() {
|
||||||
|
return new AgentProxyConnection(dataAccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnection(String username, String password) {
|
||||||
|
return getConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
|
if (iface.isInstance(this)) {
|
||||||
|
return iface.cast(this);
|
||||||
|
}
|
||||||
|
throw new SQLException("Not a wrapper for " + iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWrapperFor(Class<?> iface) {
|
||||||
|
return iface.isInstance(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PrintWriter getLogWriter() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLogWriter(PrintWriter out) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLoginTimeout(int seconds) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLoginTimeout() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
||||||
|
throw new SQLFeatureNotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,565 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.access.proxy;
|
||||||
|
|
||||||
|
import org.jeecg.modules.xslmes.mcs.access.IMcsDataAccess;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.sql.Array;
|
||||||
|
import java.sql.Blob;
|
||||||
|
import java.sql.Clob;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.sql.NClob;
|
||||||
|
import java.sql.ParameterMetaData;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.Ref;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.RowId;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.SQLWarning;
|
||||||
|
import java.sql.SQLXML;
|
||||||
|
import java.sql.Time;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AgentProxyPreparedStatement implements PreparedStatement {
|
||||||
|
|
||||||
|
private final IMcsDataAccess dataAccess;
|
||||||
|
private final String sql;
|
||||||
|
private final List<Object> params = new ArrayList<>();
|
||||||
|
private ResultSet currentRs;
|
||||||
|
private int updateCount = -1;
|
||||||
|
|
||||||
|
public AgentProxyPreparedStatement(IMcsDataAccess dataAccess, String sql) {
|
||||||
|
this.dataAccess = dataAccess;
|
||||||
|
this.sql = sql;
|
||||||
|
ensureCapacity(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureCapacity(int index1Based) {
|
||||||
|
while (params.size() < index1Based) {
|
||||||
|
params.add(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setParam(int parameterIndex, Object value) {
|
||||||
|
ensureCapacity(parameterIndex);
|
||||||
|
params.set(parameterIndex - 1, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet executeQuery() throws SQLException {
|
||||||
|
try {
|
||||||
|
List<Map<String, Object>> rows = dataAccess.query(sql, new ArrayList<>(params));
|
||||||
|
currentRs = new MapListResultSet(rows);
|
||||||
|
updateCount = -1;
|
||||||
|
return currentRs;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new SQLException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int executeUpdate() throws SQLException {
|
||||||
|
try {
|
||||||
|
updateCount = dataAccess.execute(sql, new ArrayList<>(params));
|
||||||
|
currentRs = null;
|
||||||
|
return updateCount;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new SQLException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute() throws SQLException {
|
||||||
|
String trimmed = sql == null ? "" : sql.trim();
|
||||||
|
if (trimmed.regionMatches(true, 0, "SELECT", 0, 6)) {
|
||||||
|
executeQuery();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
executeUpdate();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNull(int parameterIndex, int sqlType) {
|
||||||
|
setParam(parameterIndex, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBoolean(int parameterIndex, boolean x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setByte(int parameterIndex, byte x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShort(int parameterIndex, short x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInt(int parameterIndex, int x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLong(int parameterIndex, long x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFloat(int parameterIndex, float x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDouble(int parameterIndex, double x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBigDecimal(int parameterIndex, BigDecimal x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setString(int parameterIndex, String x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBytes(int parameterIndex, byte[] x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDate(int parameterIndex, Date x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTime(int parameterIndex, Time x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTimestamp(int parameterIndex, Timestamp x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
|
||||||
|
throw new SQLException("setAsciiStream not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearParameters() {
|
||||||
|
params.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setObject(int parameterIndex, Object x, int targetSqlType) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setObject(int parameterIndex, Object x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBatch() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRef(int parameterIndex, Ref x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlob(int parameterIndex, Blob x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClob(int parameterIndex, Clob x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setArray(int parameterIndex, Array x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSetMetaData getMetaData() {
|
||||||
|
return currentRs == null ? null : safeMeta();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultSetMetaData safeMeta() {
|
||||||
|
try {
|
||||||
|
return currentRs.getMetaData();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDate(int parameterIndex, Date x, Calendar cal) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTime(int parameterIndex, Time x, Calendar cal) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNull(int parameterIndex, int sqlType, String typeName) {
|
||||||
|
setParam(parameterIndex, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setURL(int parameterIndex, URL x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParameterMetaData getParameterMetaData() throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRowId(int parameterIndex, RowId x) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNString(int parameterIndex, String value) {
|
||||||
|
setParam(parameterIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNClob(int parameterIndex, NClob value) {
|
||||||
|
setParam(parameterIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSQLXML(int parameterIndex, SQLXML xmlObject) {
|
||||||
|
setParam(parameterIndex, xmlObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) {
|
||||||
|
setParam(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClob(int parameterIndex, Reader reader) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNClob(int parameterIndex, Reader reader) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Statement methods
|
||||||
|
@Override
|
||||||
|
public ResultSet executeQuery(String sql) throws SQLException {
|
||||||
|
throw new SQLException("use executeQuery()");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int executeUpdate(String sql) throws SQLException {
|
||||||
|
throw new SQLException("use executeUpdate()");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
currentRs = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxFieldSize() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxFieldSize(int max) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxRows() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxRows(int max) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEscapeProcessing(boolean enable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getQueryTimeout() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setQueryTimeout(int seconds) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SQLWarning getWarnings() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearWarnings() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCursorName(String name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(String sql) throws SQLException {
|
||||||
|
throw new SQLException("use execute()");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet getResultSet() {
|
||||||
|
return currentRs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getUpdateCount() {
|
||||||
|
return updateCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getMoreResults() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFetchDirection(int direction) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFetchDirection() {
|
||||||
|
return ResultSet.FETCH_FORWARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFetchSize(int rows) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFetchSize() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getResultSetConcurrency() {
|
||||||
|
return ResultSet.CONCUR_READ_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getResultSetType() {
|
||||||
|
return ResultSet.TYPE_FORWARD_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBatch(String sql) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearBatch() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] executeBatch() {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnection() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getMoreResults(int current) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet getGeneratedKeys() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int executeUpdate(String sql, String[] columnNames) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(String sql, int[] columnIndexes) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(String sql, String[] columnNames) throws SQLException {
|
||||||
|
throw new SQLException("not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getResultSetHoldability() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClosed() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPoolable(boolean poolable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPoolable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeOnCompletion() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCloseOnCompletion() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
|
throw new SQLException("not a wrapper");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWrapperFor(Class<?> iface) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.access.proxy;
|
||||||
|
|
||||||
|
import org.jeecg.modules.xslmes.mcs.access.IMcsDataAccess;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.SQLWarning;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AgentProxyStatement implements Statement {
|
||||||
|
|
||||||
|
private final IMcsDataAccess dataAccess;
|
||||||
|
private ResultSet currentRs;
|
||||||
|
private int updateCount = -1;
|
||||||
|
|
||||||
|
public AgentProxyStatement(IMcsDataAccess dataAccess, String ignored) {
|
||||||
|
this.dataAccess = dataAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet executeQuery(String sql) throws SQLException {
|
||||||
|
try {
|
||||||
|
List<Map<String, Object>> rows = dataAccess.query(sql, new ArrayList<>());
|
||||||
|
currentRs = new MapListResultSet(rows);
|
||||||
|
updateCount = -1;
|
||||||
|
return currentRs;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new SQLException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int executeUpdate(String sql) throws SQLException {
|
||||||
|
try {
|
||||||
|
updateCount = dataAccess.execute(sql, new ArrayList<>());
|
||||||
|
currentRs = null;
|
||||||
|
return updateCount;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new SQLException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
currentRs = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxFieldSize() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxFieldSize(int max) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxRows() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxRows(int max) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEscapeProcessing(boolean enable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getQueryTimeout() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setQueryTimeout(int seconds) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SQLWarning getWarnings() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearWarnings() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCursorName(String name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(String sql) throws SQLException {
|
||||||
|
String trimmed = sql == null ? "" : sql.trim();
|
||||||
|
if (trimmed.regionMatches(true, 0, "SELECT", 0, 6)) {
|
||||||
|
executeQuery(sql);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
executeUpdate(sql);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet getResultSet() {
|
||||||
|
return currentRs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getUpdateCount() {
|
||||||
|
return updateCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getMoreResults() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFetchDirection(int direction) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFetchDirection() {
|
||||||
|
return ResultSet.FETCH_FORWARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFetchSize(int rows) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFetchSize() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getResultSetConcurrency() {
|
||||||
|
return ResultSet.CONCUR_READ_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getResultSetType() {
|
||||||
|
return ResultSet.TYPE_FORWARD_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBatch(String sql) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearBatch() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] executeBatch() {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnection() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getMoreResults(int current) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet getGeneratedKeys() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
|
||||||
|
return executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
|
||||||
|
return executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int executeUpdate(String sql, String[] columnNames) throws SQLException {
|
||||||
|
return executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
|
||||||
|
return execute(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(String sql, int[] columnIndexes) throws SQLException {
|
||||||
|
return execute(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(String sql, String[] columnNames) throws SQLException {
|
||||||
|
return execute(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getResultSetHoldability() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClosed() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPoolable(boolean poolable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPoolable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeOnCompletion() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCloseOnCompletion() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
|
throw new SQLException("not a wrapper");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWrapperFor(Class<?> iface) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,59 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.controller;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.util.McsQueryHelper;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.entity.McsToMesActMill;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.service.IMcsToMesActMillService;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开炼机动作(中间库 MCSToMES_Act_Mill)
|
||||||
|
*/
|
||||||
|
@Tag(name = "开炼机动作(中间库)")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/xslmes/mcs/mcsToMesActMill")
|
||||||
|
@Slf4j
|
||||||
|
public class McsToMesActMillController extends JeecgController<McsToMesActMill, IMcsToMesActMillService> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IMcsToMesActMillService mcsToMesActMillService;
|
||||||
|
|
||||||
|
@Operation(summary = "开炼机动作(中间库)-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<McsToMesActMill>> queryPageList(McsToMesActMill mcsToMesActMill,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
QueryWrapper<McsToMesActMill> queryWrapper = McsQueryHelper.buildWrapper(mcsToMesActMill, req.getParameterMap());
|
||||||
|
Page<McsToMesActMill> page = new Page<>(pageNo, pageSize);
|
||||||
|
IPage<McsToMesActMill> pageList = mcsToMesActMillService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "开炼机动作(中间库)-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<McsToMesActMill> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
McsToMesActMill entity = mcsToMesActMillService.getById(id);
|
||||||
|
if (entity == null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresPermissions("xslmes:mcsToMesActMill:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, McsToMesActMill mcsToMesActMill) {
|
||||||
|
return super.exportXls(request, mcsToMesActMill, McsToMesActMill.class, "开炼机动作(中间库)");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.access.MesToMcsPushService;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MES → MCS 经桌面代理下发。
|
||||||
|
*/
|
||||||
|
@Tag(name = "MES上辅机下发")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/xslmes/mcs/push")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MesToMcsPushController {
|
||||||
|
|
||||||
|
private final MesToMcsPushService mesToMcsPushService;
|
||||||
|
|
||||||
|
@Operation(summary = "经桌面代理写入中间表")
|
||||||
|
@PostMapping("/rows")
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Result<Map<String, Object>> pushRows(@RequestBody Map<String, Object> body) {
|
||||||
|
String table = body == null ? null : String.valueOf(body.getOrDefault("table", ""));
|
||||||
|
String mode = body == null ? "insert" : String.valueOf(body.getOrDefault("mode", "insert"));
|
||||||
|
List<String> keys = body == null ? null : (List<String>) body.get("keys");
|
||||||
|
List<Map<String, Object>> rows = body == null ? null : (List<Map<String, Object>>) body.get("rows");
|
||||||
|
int affected = mesToMcsPushService.push(table, mode, keys, rows);
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("affected", affected);
|
||||||
|
return Result.OK(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,9 @@ public class MesXslMcsDbConfigController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private McsDataSourceManager mcsDataSourceManager;
|
private McsDataSourceManager mcsDataSourceManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private org.jeecg.modules.device.sync.agent.DeviceAgentSessionRegistry agentSessionRegistry;
|
||||||
|
|
||||||
private Integer resolveTenantId(Integer tenantId) {
|
private Integer resolveTenantId(Integer tenantId) {
|
||||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||||
if (tenantId == null) {
|
if (tenantId == null) {
|
||||||
@@ -75,11 +78,21 @@ public class MesXslMcsDbConfigController {
|
|||||||
data.put("dbConfigActive", mcsDataSourceManager.isDbConfigActive());
|
data.put("dbConfigActive", mcsDataSourceManager.isDbConfigActive());
|
||||||
data.put("readEnabled", mcsDataSourceManager.isReadEnabled());
|
data.put("readEnabled", mcsDataSourceManager.isReadEnabled());
|
||||||
data.put("writeEnabled", mcsDataSourceManager.isWriteEnabled());
|
data.put("writeEnabled", mcsDataSourceManager.isWriteEnabled());
|
||||||
|
boolean agentMode = mcsDataSourceManager.isDesktopAgentMode();
|
||||||
|
data.put("accessMode", agentMode ? "DESKTOP_AGENT" : "DIRECT");
|
||||||
|
data.put("agentMode", agentMode);
|
||||||
if (cfg != null) {
|
if (cfg != null) {
|
||||||
data.put("serverHost", cfg.getServerHost());
|
data.put("serverHost", cfg.getServerHost());
|
||||||
data.put("serverPort", cfg.getServerPort());
|
data.put("serverPort", cfg.getServerPort());
|
||||||
data.put("dbName", cfg.getDbName());
|
data.put("dbName", cfg.getDbName());
|
||||||
|
data.put("agentDeviceId", cfg.getAgentDeviceId());
|
||||||
}
|
}
|
||||||
|
var agent = agentSessionRegistry.pickOnlineAgent(cfg == null ? null : cfg.getAgentDeviceId());
|
||||||
|
data.put("agentOnline", agent != null && agent.isOnline());
|
||||||
|
data.put("agentDbConnected", agent != null && agent.isDbConnected());
|
||||||
|
data.put("agentHostName", agent == null ? null : agent.getHostName());
|
||||||
|
data.put("agentDbMessage", agent == null ? null : agent.getDbMessage());
|
||||||
|
data.put("agentLastSeenAt", agent == null ? null : agent.getLastSeenAt());
|
||||||
return Result.OK(data);
|
return Result.OK(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,11 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.jeecg.common.util.dynamic.db.DataSourceCachePool;
|
import org.jeecg.common.util.dynamic.db.DataSourceCachePool;
|
||||||
import org.jeecg.modules.system.util.SecurityUtil;
|
import org.jeecg.modules.system.util.SecurityUtil;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.access.DesktopAgentMcsDataAccess;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.access.McsDataAccessFacade;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.access.proxy.AgentProxyDataSource;
|
||||||
import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsDbConfig;
|
import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsDbConfig;
|
||||||
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -37,6 +41,9 @@ public class McsDataSourceManager {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private DruidDataSourceCreator dataSourceCreator;
|
private DruidDataSourceCreator dataSourceCreator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectProvider<DesktopAgentMcsDataAccess> desktopAgentMcsDataAccessProvider;
|
||||||
|
|
||||||
@Value("${spring.datasource.dynamic.datasource.sqlserver_mcs.url:}")
|
@Value("${spring.datasource.dynamic.datasource.sqlserver_mcs.url:}")
|
||||||
private String ymlUrl;
|
private String ymlUrl;
|
||||||
|
|
||||||
@@ -98,6 +105,17 @@ public class McsDataSourceManager {
|
|||||||
}
|
}
|
||||||
if (Integer.valueOf(1).equals(config.getStatus())) {
|
if (Integer.valueOf(1).equals(config.getStatus())) {
|
||||||
try {
|
try {
|
||||||
|
if (isDesktopAgentMode(config)) {
|
||||||
|
DesktopAgentMcsDataAccess agent = desktopAgentMcsDataAccessProvider.getIfAvailable();
|
||||||
|
if (agent == null) {
|
||||||
|
throw new IllegalStateException("桌面代理访问组件未就绪");
|
||||||
|
}
|
||||||
|
routing.addDataSource(DS_KEY, new AgentProxyDataSource(agent));
|
||||||
|
cachedConfig.set(config);
|
||||||
|
log.info("[MCS中间库] 已切换为桌面代理模式 sqlserver_mcs -> AgentProxy, deviceId={}",
|
||||||
|
config.getAgentDeviceId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
String plainPassword = decryptPassword(config.getDbPassword());
|
String plainPassword = decryptPassword(config.getDbPassword());
|
||||||
DataSourceProperty property = buildDataSourceProperty(config, plainPassword);
|
DataSourceProperty property = buildDataSourceProperty(config, plainPassword);
|
||||||
DataSource mcsDs = dataSourceCreator.createDataSource(property);
|
DataSource mcsDs = dataSourceCreator.createDataSource(property);
|
||||||
@@ -117,6 +135,21 @@ public class McsDataSourceManager {
|
|||||||
log.info("[MCS中间库] 连接未启用,读写开关仍按页面配置生效");
|
log.info("[MCS中间库] 连接未启用,读写开关仍按页面配置生效");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDesktopAgentMode(MesXslMcsDbConfig config) {
|
||||||
|
MesXslMcsDbConfig cfg = config != null ? config : cachedConfig.get();
|
||||||
|
if (cfg == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String mode = StringUtils.isBlank(cfg.getAccessMode())
|
||||||
|
? McsDataAccessFacade.MODE_DESKTOP_AGENT
|
||||||
|
: cfg.getAccessMode().trim().toUpperCase();
|
||||||
|
return McsDataAccessFacade.MODE_DESKTOP_AGENT.equals(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDesktopAgentMode() {
|
||||||
|
return isDesktopAgentMode(null);
|
||||||
|
}
|
||||||
|
|
||||||
private void closeAndRemoveDataSource(DynamicRoutingDataSource routing) {
|
private void closeAndRemoveDataSource(DynamicRoutingDataSource routing) {
|
||||||
if (!routing.getDataSources().containsKey(DS_KEY)) {
|
if (!routing.getDataSources().containsKey(DS_KEY)) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开炼机动作(中间库 MCSToMES_Act_Mill)
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("MCSToMES_Act_Mill")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description = "开炼机动作(中间库)")
|
||||||
|
public class McsToMesActMill implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(value = "GUID", type = IdType.INPUT)
|
||||||
|
@Schema(description = "GUID")
|
||||||
|
@Excel(name = "GUID", width = 36)
|
||||||
|
private String guid;
|
||||||
|
|
||||||
|
@Excel(name = "动作地址", width = 10)
|
||||||
|
@Schema(description = "动作地址")
|
||||||
|
@TableField("act_addr")
|
||||||
|
private Integer actAddr;
|
||||||
|
|
||||||
|
@Excel(name = "动作名称", width = 20)
|
||||||
|
@Schema(description = "动作名称")
|
||||||
|
@TableField("act_name")
|
||||||
|
private String actName;
|
||||||
|
|
||||||
|
@Excel(name = "动作名称(英)", width = 20)
|
||||||
|
@Schema(description = "动作名称(英)")
|
||||||
|
@TableField("act_name_en")
|
||||||
|
private String actNameEn;
|
||||||
|
|
||||||
|
@Excel(name = "动作备注", width = 15)
|
||||||
|
@Schema(description = "动作备注")
|
||||||
|
@TableField("act_memo")
|
||||||
|
private String actMemo;
|
||||||
|
|
||||||
|
@Excel(name = "动作关联地址", width = 12)
|
||||||
|
@Schema(description = "动作关联地址")
|
||||||
|
@TableField("act_Repaddr")
|
||||||
|
private Integer actRepaddr;
|
||||||
|
|
||||||
|
@Excel(name = "写入时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "写入时间")
|
||||||
|
@TableField("WriteTime")
|
||||||
|
private Date writeTime;
|
||||||
|
|
||||||
|
@Excel(name = "读取时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "读取时间")
|
||||||
|
@TableField("ReadTime")
|
||||||
|
private Date readTime;
|
||||||
|
|
||||||
|
@Excel(name = "读写标识", width = 10)
|
||||||
|
@Schema(description = "读写标识")
|
||||||
|
@TableField("RW_Flag")
|
||||||
|
private Integer rwFlag;
|
||||||
|
}
|
||||||
@@ -66,6 +66,14 @@ public class MesXslMcsDbConfig implements Serializable {
|
|||||||
@Schema(description = "备注")
|
@Schema(description = "备注")
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
|
//update-begin---author:cursor ---date:2026-07-20 for:【设备库桥接】访问模式与绑定桌面代理-----------
|
||||||
|
@Schema(description = "访问模式:DESKTOP_AGENT=桌面代理,DIRECT=服务端直连")
|
||||||
|
private String accessMode;
|
||||||
|
|
||||||
|
@Schema(description = "绑定的桌面代理 deviceId")
|
||||||
|
private String agentDeviceId;
|
||||||
|
//update-end---author:cursor ---date:2026-07-20 for:【设备库桥接】访问模式与绑定桌面代理-----------
|
||||||
|
|
||||||
private String createBy;
|
private String createBy;
|
||||||
|
|
||||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.mapper;
|
||||||
|
|
||||||
|
import org.jeecg.modules.xslmes.mcs.entity.McsToMesActMill;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开炼机动作(中间库)
|
||||||
|
*/
|
||||||
|
public interface McsToMesActMillMapper extends BaseMapper<McsToMesActMill> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.service;
|
||||||
|
|
||||||
|
import org.jeecg.modules.xslmes.mcs.entity.McsToMesActMill;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开炼机动作(中间库)
|
||||||
|
*/
|
||||||
|
public interface IMcsToMesActMillService extends IService<McsToMesActMill> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mcs.service.impl;
|
||||||
|
|
||||||
|
import org.jeecg.modules.xslmes.mcs.entity.McsToMesActMill;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.mapper.McsToMesActMillMapper;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.service.IMcsToMesActMillService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开炼机动作(中间库)
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@DS("sqlserver_mcs")
|
||||||
|
public class McsToMesActMillServiceImpl extends ServiceImpl<McsToMesActMillMapper, McsToMesActMill> implements IMcsToMesActMillService {
|
||||||
|
}
|
||||||
@@ -30,6 +30,9 @@ public class MesXslMcsDbConfigServiceImpl extends ServiceImpl<MesXslMcsDbConfigM
|
|||||||
@Autowired
|
@Autowired
|
||||||
private McsDataSourceManager mcsDataSourceManager;
|
private McsDataSourceManager mcsDataSourceManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private org.jeecg.modules.xslmes.mcs.access.McsDataAccessFacade mcsDataAccessFacade;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MesXslMcsDbConfig getCurrentConfig(Integer tenantId) {
|
public MesXslMcsDbConfig getCurrentConfig(Integer tenantId) {
|
||||||
int tid = tenantId != null ? tenantId : 0;
|
int tid = tenantId != null ? tenantId : 0;
|
||||||
@@ -61,10 +64,14 @@ public class MesXslMcsDbConfigServiceImpl extends ServiceImpl<MesXslMcsDbConfigM
|
|||||||
if (config == null) {
|
if (config == null) {
|
||||||
return Result.error("配置不能为空");
|
return Result.error("配置不能为空");
|
||||||
}
|
}
|
||||||
if (StringUtils.isBlank(config.getServerHost())) {
|
if (StringUtils.isBlank(config.getAccessMode())) {
|
||||||
|
config.setAccessMode("DESKTOP_AGENT");
|
||||||
|
}
|
||||||
|
boolean agentMode = "DESKTOP_AGENT".equalsIgnoreCase(config.getAccessMode().trim());
|
||||||
|
if (!agentMode && StringUtils.isBlank(config.getServerHost())) {
|
||||||
return Result.error("服务器地址不能为空");
|
return Result.error("服务器地址不能为空");
|
||||||
}
|
}
|
||||||
if (StringUtils.isBlank(config.getDbUsername())) {
|
if (!agentMode && StringUtils.isBlank(config.getDbUsername())) {
|
||||||
return Result.error("用户名不能为空");
|
return Result.error("用户名不能为空");
|
||||||
}
|
}
|
||||||
if (config.getTenantId() == null) {
|
if (config.getTenantId() == null) {
|
||||||
@@ -93,13 +100,20 @@ public class MesXslMcsDbConfigServiceImpl extends ServiceImpl<MesXslMcsDbConfigM
|
|||||||
}
|
}
|
||||||
|
|
||||||
String plainPassword = resolvePlainPassword(config);
|
String plainPassword = resolvePlainPassword(config);
|
||||||
if (StringUtils.isBlank(plainPassword)) {
|
if (!agentMode && StringUtils.isBlank(plainPassword)) {
|
||||||
return Result.error("密码不能为空");
|
return Result.error("密码不能为空");
|
||||||
}
|
}
|
||||||
|
if (agentMode && StringUtils.isBlank(config.getServerHost())) {
|
||||||
String err = mcsDataSourceManager.testConnection(config, plainPassword);
|
config.setServerHost("desktop-agent");
|
||||||
if (err != null && Integer.valueOf(1).equals(config.getStatus())) {
|
}
|
||||||
return Result.error("连接测试失败:" + err);
|
if (agentMode && StringUtils.isBlank(config.getDbUsername())) {
|
||||||
|
config.setDbUsername("desktop-agent");
|
||||||
|
}
|
||||||
|
if (!agentMode) {
|
||||||
|
String err = mcsDataSourceManager.testConnection(config, plainPassword);
|
||||||
|
if (err != null && Integer.valueOf(1).equals(config.getStatus())) {
|
||||||
|
return Result.error("连接测试失败:" + err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||||
@@ -111,12 +125,16 @@ public class MesXslMcsDbConfigServiceImpl extends ServiceImpl<MesXslMcsDbConfigM
|
|||||||
if (old == null) {
|
if (old == null) {
|
||||||
return Result.error("配置不存在");
|
return Result.error("配置不存在");
|
||||||
}
|
}
|
||||||
config.setDbPassword(mcsDataSourceManager.encryptPassword(plainPassword));
|
if (StringUtils.isNotBlank(plainPassword)) {
|
||||||
|
config.setDbPassword(mcsDataSourceManager.encryptPassword(plainPassword));
|
||||||
|
} else {
|
||||||
|
config.setDbPassword(old.getDbPassword());
|
||||||
|
}
|
||||||
config.setUpdateBy(username);
|
config.setUpdateBy(username);
|
||||||
config.setUpdateTime(now);
|
config.setUpdateTime(now);
|
||||||
updateById(config);
|
updateById(config);
|
||||||
} else {
|
} else {
|
||||||
config.setDbPassword(mcsDataSourceManager.encryptPassword(plainPassword));
|
config.setDbPassword(mcsDataSourceManager.encryptPassword(StringUtils.defaultString(plainPassword)));
|
||||||
config.setCreateBy(username);
|
config.setCreateBy(username);
|
||||||
config.setCreateTime(now);
|
config.setCreateTime(now);
|
||||||
config.setUpdateBy(username);
|
config.setUpdateBy(username);
|
||||||
@@ -151,6 +169,14 @@ public class MesXslMcsDbConfigServiceImpl extends ServiceImpl<MesXslMcsDbConfigM
|
|||||||
if (config == null) {
|
if (config == null) {
|
||||||
return Result.error("尚未配置中间库连接");
|
return Result.error("尚未配置中间库连接");
|
||||||
}
|
}
|
||||||
|
if (mcsDataSourceManager.isDesktopAgentMode(config)) {
|
||||||
|
try {
|
||||||
|
boolean ok = mcsDataAccessFacade.testConnection();
|
||||||
|
return ok ? Result.OK("桌面代理设备库连接成功") : Result.error("桌面代理设备库连接失败(代理离线或库不可达)");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error("桌面代理探测失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
String plainPassword = mcsDataSourceManager.decryptPassword(config.getDbPassword());
|
String plainPassword = mcsDataSourceManager.decryptPassword(config.getDbPassword());
|
||||||
String err = mcsDataSourceManager.testConnection(config, plainPassword);
|
String err = mcsDataSourceManager.testConnection(config, plainPassword);
|
||||||
if (err == null) {
|
if (err == null) {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package org.jeecg.modules.xslmes.mcs.sync;
|
package org.jeecg.modules.xslmes.mcs.sync;
|
||||||
|
|
||||||
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.jeecg.modules.xslmes.mcs.access.McsDataAccessFacade;
|
||||||
import org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager;
|
import org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager;
|
||||||
import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsSyncConfig;
|
import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsSyncConfig;
|
||||||
import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsSyncField;
|
import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsSyncField;
|
||||||
@@ -69,6 +69,9 @@ public class GenericMcsSyncEngine {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager mcsDataSourceManager;
|
private org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager mcsDataSourceManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private McsDataAccessFacade mcsDataAccessFacade;
|
||||||
|
|
||||||
//update-begin---author:GHT ---date:20260617 for:【MES上辅机】采集模式 全量/时间/增量-----------
|
//update-begin---author:GHT ---date:20260617 for:【MES上辅机】采集模式 全量/时间/增量-----------
|
||||||
public String sync(MesXslMcsSyncConfig cfg, List<MesXslMcsSyncField> fields) {
|
public String sync(MesXslMcsSyncConfig cfg, List<MesXslMcsSyncField> fields) {
|
||||||
String sourceTable = trim(cfg.getSourceTable());
|
String sourceTable = trim(cfg.getSourceTable());
|
||||||
@@ -91,7 +94,6 @@ public class GenericMcsSyncEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String mode = StringUtils.isBlank(cfg.getSyncMode()) ? MODE_FULL : cfg.getSyncMode().trim().toUpperCase();
|
String mode = StringUtils.isBlank(cfg.getSyncMode()) ? MODE_FULL : cfg.getSyncMode().trim().toUpperCase();
|
||||||
JdbcTemplate sourceJt = new JdbcTemplate(getSourceDataSource());
|
|
||||||
JdbcTemplate targetJt = new JdbcTemplate(dataSource);
|
JdbcTemplate targetJt = new JdbcTemplate(dataSource);
|
||||||
|
|
||||||
// 目标表标准字段探测 + 自动填充列
|
// 目标表标准字段探测 + 自动填充列
|
||||||
@@ -134,7 +136,7 @@ public class GenericMcsSyncEngine {
|
|||||||
String predicate = flagPredicate(flagCol, cfg.getFlagCondition(), cfg.getFlagMatchValue());
|
String predicate = flagPredicate(flagCol, cfg.getFlagCondition(), cfg.getFlagMatchValue());
|
||||||
String sql = "SELECT TOP " + limit + " " + colList(srcCols) + " FROM [" + sourceTable + "]"
|
String sql = "SELECT TOP " + limit + " " + colList(srcCols) + " FROM [" + sourceTable + "]"
|
||||||
+ " WHERE (" + predicate + ")";
|
+ " WHERE (" + predicate + ")";
|
||||||
rows = sourceJt.queryForList(sql);
|
rows = mcsDataAccessFacade.query(sql, null);
|
||||||
if (rows.isEmpty()) {
|
if (rows.isEmpty()) {
|
||||||
return "增量采集:无待采集数据";
|
return "增量采集:无待采集数据";
|
||||||
}
|
}
|
||||||
@@ -149,10 +151,10 @@ public class GenericMcsSyncEngine {
|
|||||||
sql.append(" AND [").append(incrCol).append("] < ?");
|
sql.append(" AND [").append(incrCol).append("] < ?");
|
||||||
args.add(window[1]);
|
args.add(window[1]);
|
||||||
}
|
}
|
||||||
rows = sourceJt.queryForList(sql.toString(), args.toArray());
|
rows = mcsDataAccessFacade.query(sql.toString(), args);
|
||||||
} else {
|
} else {
|
||||||
// FULL
|
// FULL
|
||||||
rows = sourceJt.queryForList("SELECT " + colList(srcCols) + " FROM [" + sourceTable + "]");
|
rows = mcsDataAccessFacade.query("SELECT " + colList(srcCols) + " FROM [" + sourceTable + "]", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rows.isEmpty()) {
|
if (rows.isEmpty()) {
|
||||||
@@ -209,7 +211,7 @@ public class GenericMcsSyncEngine {
|
|||||||
// INCR(标记回写):对本批所有源行回写标记值,下轮不再采集
|
// INCR(标记回写):对本批所有源行回写标记值,下轮不再采集
|
||||||
if (flagMode) {
|
if (flagMode) {
|
||||||
String writeValue = StringUtils.isBlank(cfg.getFlagWriteValue()) ? FLAG_SYNCED : cfg.getFlagWriteValue();
|
String writeValue = StringUtils.isBlank(cfg.getFlagWriteValue()) ? FLAG_SYNCED : cfg.getFlagWriteValue();
|
||||||
int marked = writeBackFlag(sourceJt, sourceTable, flagCol, cfg.getFlagCondition(), cfg.getFlagMatchValue(), writeValue, keyMaps, rows);
|
int marked = writeBackFlag(sourceTable, flagCol, cfg.getFlagCondition(), cfg.getFlagMatchValue(), writeValue, keyMaps, rows);
|
||||||
return String.format("增量采集:新增%d,更新%d,未变%d,回写标记%d,源%d条",
|
return String.format("增量采集:新增%d,更新%d,未变%d,回写标记%d,源%d条",
|
||||||
ins, upd, unchanged, marked, rows.size());
|
ins, upd, unchanged, marked, rows.size());
|
||||||
}
|
}
|
||||||
@@ -252,14 +254,14 @@ public class GenericMcsSyncEngine {
|
|||||||
* 避免误标在本轮 SELECT 之后才进入中间库、尚未采集的新数据;
|
* 避免误标在本轮 SELECT 之后才进入中间库、尚未采集的新数据;
|
||||||
* 并以采集条件谓词做守卫,避开本轮已被其他进程改动的行。</p>
|
* 并以采集条件谓词做守卫,避开本轮已被其他进程改动的行。</p>
|
||||||
*/
|
*/
|
||||||
private int writeBackFlag(JdbcTemplate sourceJt, String sourceTable, String flagCol, String condition,
|
private int writeBackFlag(String sourceTable, String flagCol, String condition,
|
||||||
String matchValue, String writeValue, List<MesXslMcsSyncField> keyMaps, List<Map<String, Object>> rows) {
|
String matchValue, String writeValue, List<MesXslMcsSyncField> keyMaps, List<Map<String, Object>> rows) {
|
||||||
validateIdent(flagCol);
|
validateIdent(flagCol);
|
||||||
StringBuilder sql = new StringBuilder("UPDATE [").append(sourceTable).append("] SET [")
|
StringBuilder sql = new StringBuilder("UPDATE [").append(sourceTable).append("] SET [")
|
||||||
.append(flagCol).append("] = ? WHERE ");
|
.append(flagCol).append("] = ? WHERE ");
|
||||||
sql.append(keyMaps.stream().map(k -> "[" + k.getSourceField() + "] = ?").collect(Collectors.joining(" AND ")));
|
sql.append(keyMaps.stream().map(k -> "[" + k.getSourceField() + "] = ?").collect(Collectors.joining(" AND ")));
|
||||||
sql.append(" AND (").append(flagPredicate(flagCol, condition, matchValue)).append(")");
|
sql.append(" AND (").append(flagPredicate(flagCol, condition, matchValue)).append(")");
|
||||||
List<Object[]> argsList = new ArrayList<>();
|
int total = 0;
|
||||||
Set<String> handled = new HashSet<>();
|
Set<String> handled = new HashSet<>();
|
||||||
for (Map<String, Object> row : rows) {
|
for (Map<String, Object> row : rows) {
|
||||||
Map<String, Object> rci = ci(row);
|
Map<String, Object> rci = ci(row);
|
||||||
@@ -272,9 +274,9 @@ public class GenericMcsSyncEngine {
|
|||||||
for (MesXslMcsSyncField k : keyMaps) {
|
for (MesXslMcsSyncField k : keyMaps) {
|
||||||
args.add(rci.get(k.getSourceField()));
|
args.add(rci.get(k.getSourceField()));
|
||||||
}
|
}
|
||||||
argsList.add(args.toArray());
|
total += mcsDataAccessFacade.execute(sql.toString(), args);
|
||||||
}
|
}
|
||||||
return batch(sourceJt, sql.toString(), argsList);
|
return total;
|
||||||
}
|
}
|
||||||
//update-end---author:GHT ---date:20260617 for:【MES上辅机】增量匹配改为标记位回写-----------
|
//update-end---author:GHT ---date:20260617 for:【MES上辅机】增量匹配改为标记位回写-----------
|
||||||
|
|
||||||
@@ -502,15 +504,6 @@ public class GenericMcsSyncEngine {
|
|||||||
return maps.stream().anyMatch(m -> m.getTargetField() != null && m.getTargetField().equalsIgnoreCase(targetCol));
|
return maps.stream().anyMatch(m -> m.getTargetField() != null && m.getTargetField().equalsIgnoreCase(targetCol));
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataSource getSourceDataSource() {
|
|
||||||
DynamicRoutingDataSource routing = (DynamicRoutingDataSource) dataSource;
|
|
||||||
DataSource src = routing.getDataSources().get(McsDataSourceManager.DS_KEY);
|
|
||||||
if (src == null) {
|
|
||||||
throw new IllegalStateException("中间库数据源 " + McsDataSourceManager.DS_KEY + " 未注册");
|
|
||||||
}
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateIdent(String name) {
|
private void validateIdent(String name) {
|
||||||
if (name == null || !IDENT.matcher(name).matches()) {
|
if (name == null || !IDENT.matcher(name).matches()) {
|
||||||
throw new IllegalArgumentException("非法的表名或字段名: " + name);
|
throw new IllegalArgumentException("非法的表名或字段名: " + name);
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package org.jeecg.modules.xslmes.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.jeecg.modules.xslmes.entity.MesXslMillAction;
|
||||||
|
|
||||||
|
public interface IMesXslMillActionService extends IService<MesXslMillAction> {}
|
||||||
@@ -7,7 +7,9 @@ public interface IMesXslMixerConditionService extends IService<MesXslMixerCondit
|
|||||||
|
|
||||||
void fillEquipmentName(MesXslMixerCondition model);
|
void fillEquipmentName(MesXslMixerCondition model);
|
||||||
|
|
||||||
boolean isConditionNameDuplicated(String conditionName, String excludeId);
|
//update-begin---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称/代码按设备唯一-----------
|
||||||
|
boolean isConditionNameDuplicated(String conditionName, String equipmentId, String excludeId);
|
||||||
|
|
||||||
boolean isConditionCodeDuplicated(String conditionCode, String excludeId);
|
boolean isConditionCodeDuplicated(String conditionCode, String equipmentId, String excludeId);
|
||||||
|
//update-end---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称/代码按设备唯一-----------
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import java.util.Collection;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -300,6 +301,9 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
//update-begin---author:cursor ---date:20260521 for:配合示方明细重量%按PHR/总PHR自动计算-----------
|
//update-begin---author:cursor ---date:20260521 for:配合示方明细重量%按PHR/总PHR自动计算-----------
|
||||||
fillWeightPercent(line, weightBase);
|
fillWeightPercent(line, weightBase);
|
||||||
//update-end---author:cursor ---date:20260521 for:配合示方明细重量%按PHR/总PHR自动计算-----------
|
//update-end---author:cursor ---date:20260521 for:配合示方明细重量%按PHR/总PHR自动计算-----------
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积统一保留三位小数-----------
|
||||||
|
normalizeLineDecimals(line);
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积统一保留三位小数-----------
|
||||||
if (line.getCreateTime() == null) {
|
if (line.getCreateTime() == null) {
|
||||||
line.setCreateTime(now);
|
line.setCreateTime(now);
|
||||||
}
|
}
|
||||||
@@ -339,7 +343,9 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
if (material == null || material.getSpecificGravity() == null || material.getSpecificGravity().compareTo(BigDecimal.ZERO) <= 0) {
|
if (material == null || material.getSpecificGravity() == null || material.getSpecificGravity().compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
line.setVolume(line.getPhr().divide(material.getSpecificGravity(), 6, RoundingMode.HALF_UP));
|
//update-begin---author:jiangxh ---date:20260729 for:【配合示方】明细体积保留三位小数-----------
|
||||||
|
line.setVolume(line.getPhr().divide(material.getSpecificGravity(), 3, RoundingMode.HALF_UP));
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【配合示方】明细体积保留三位小数-----------
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillWeightPercent(MesXslFormulaSpecLine line, BigDecimal totalPhr) {
|
private void fillWeightPercent(MesXslFormulaSpecLine line, BigDecimal totalPhr) {
|
||||||
@@ -347,10 +353,27 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
if (line.getWeightPercent() != null || line.getPhr() == null || totalPhr == null || totalPhr.compareTo(BigDecimal.ZERO) <= 0) {
|
if (line.getWeightPercent() != null || line.getPhr() == null || totalPhr == null || totalPhr.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
line.setWeightPercent(line.getPhr().multiply(BigDecimal.valueOf(100)).divide(totalPhr, 4, RoundingMode.HALF_UP));
|
//update-begin---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积保留三位小数-----------
|
||||||
|
line.setWeightPercent(line.getPhr().multiply(BigDecimal.valueOf(100)).divide(totalPhr, 3, RoundingMode.HALF_UP));
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积保留三位小数-----------
|
||||||
//update-end---author:cursor ---date:20260521 for:配合示方明细重量%按PHR/总PHR自动计算(可手工覆盖)-----------
|
//update-end---author:cursor ---date:20260521 for:配合示方明细重量%按PHR/总PHR自动计算(可手工覆盖)-----------
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积统一保留三位小数-----------
|
||||||
|
/** 明细重量%、体积统一四舍五入到三位小数(含手工录入值) */
|
||||||
|
private void normalizeLineDecimals(MesXslFormulaSpecLine line) {
|
||||||
|
if (line == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (line.getWeightPercent() != null) {
|
||||||
|
line.setWeightPercent(line.getWeightPercent().setScale(3, RoundingMode.HALF_UP));
|
||||||
|
}
|
||||||
|
if (line.getVolume() != null) {
|
||||||
|
line.setVolume(line.getVolume().setScale(3, RoundingMode.HALF_UP));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积统一保留三位小数-----------
|
||||||
|
|
||||||
//update-begin---author:cursor ---date:20260521 for:【配合示方】保存后汇总A/Q胶比重写入数据库-----------
|
//update-begin---author:cursor ---date:20260521 for:【配合示方】保存后汇总A/Q胶比重写入数据库-----------
|
||||||
/** 根据明细重新汇总主表 TOTAL PHR、A胶TOTAL PHR、比重与人工配料标记 */
|
/** 根据明细重新汇总主表 TOTAL PHR、A胶TOTAL PHR、比重与人工配料标记 */
|
||||||
private void refreshMainSummary(String mainId) {
|
private void refreshMainSummary(String mainId) {
|
||||||
@@ -457,7 +480,9 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
if (material == null || material.getSpecificGravity() == null || material.getSpecificGravity().compareTo(BigDecimal.ZERO) <= 0) {
|
if (material == null || material.getSpecificGravity() == null || material.getSpecificGravity().compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return line.getPhr().divide(material.getSpecificGravity(), 6, RoundingMode.HALF_UP);
|
//update-begin---author:jiangxh ---date:20260729 for:【配合示方】明细体积保留三位小数-----------
|
||||||
|
return line.getPhr().divide(material.getSpecificGravity(), 3, RoundingMode.HALF_UP);
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【配合示方】明细体积保留三位小数-----------
|
||||||
}
|
}
|
||||||
//update-end---author:cursor ---date:20260521 for:【配合示方】保存后汇总A/Q胶比重写入数据库-----------
|
//update-end---author:cursor ---date:20260521 for:【配合示方】保存后汇总A/Q胶比重写入数据库-----------
|
||||||
|
|
||||||
@@ -540,7 +565,6 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
throw new IllegalArgumentException("请先维护混合段数");
|
throw new IllegalArgumentException("请先维护混合段数");
|
||||||
}
|
}
|
||||||
String rubberName = resolveRubberName(main);
|
String rubberName = resolveRubberName(main);
|
||||||
String formulaCodeSuffix = resolveFormulaCodeSuffix(main);
|
|
||||||
boolean hasQ = hasStepQ(main.getLineList());
|
boolean hasQ = hasStepQ(main.getLineList());
|
||||||
List<MesXslFormulaMixingGeneratePreviewItemVO> items = new ArrayList<>();
|
List<MesXslFormulaMixingGeneratePreviewItemVO> items = new ArrayList<>();
|
||||||
int aIndex = 0;
|
int aIndex = 0;
|
||||||
@@ -551,16 +575,24 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
item.setStageIndex(i);
|
item.setStageIndex(i);
|
||||||
if (isQSegment) {
|
if (isQSegment) {
|
||||||
item.setStepType("Q");
|
item.setStepType("Q");
|
||||||
item.setSpecCode(appendFormulaCodeSuffix("F" + rubberName, formulaCodeSuffix));
|
//update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】B/F匹配编号不拼版本后缀-----------
|
||||||
|
item.setSpecCode(buildBfRubberSpecCode("F", rubberName));
|
||||||
|
//update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】B/F匹配编号不拼版本后缀-----------
|
||||||
item.setASegmentIndex(null);
|
item.setASegmentIndex(null);
|
||||||
} else {
|
} else {
|
||||||
aIndex++;
|
aIndex++;
|
||||||
item.setStepType("A");
|
item.setStepType("A");
|
||||||
item.setASegmentIndex(aIndex);
|
item.setASegmentIndex(aIndex);
|
||||||
item.setSpecCode(appendFormulaCodeSuffix("B" + aIndex + rubberName, formulaCodeSuffix));
|
//update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】B/F匹配编号不拼版本后缀-----------
|
||||||
|
item.setSpecCode(buildBfRubberSpecCode("B" + aIndex, rubberName));
|
||||||
|
//update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】B/F匹配编号不拼版本后缀-----------
|
||||||
}
|
}
|
||||||
items.add(item);
|
items.add(item);
|
||||||
}
|
}
|
||||||
|
//update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】列表点生成混炼示方时即匹配胶料列表-----------
|
||||||
|
// 点击「生成混炼示方」打开预览时即校验拼接示方编号是否已在胶料列表维护
|
||||||
|
assertRequiredRubberMaterialsExist(toGenerateRowsFromPreviewItems(items), main, main.getLineList());
|
||||||
|
//update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】列表点生成混炼示方时即匹配胶料列表-----------
|
||||||
MesXslFormulaMixingGeneratePreviewVO preview = new MesXslFormulaMixingGeneratePreviewVO();
|
MesXslFormulaMixingGeneratePreviewVO preview = new MesXslFormulaMixingGeneratePreviewVO();
|
||||||
preview.setFormulaSpecId(formulaSpecId);
|
preview.setFormulaSpecId(formulaSpecId);
|
||||||
preview.setRubberName(rubberName);
|
preview.setRubberName(rubberName);
|
||||||
@@ -598,10 +630,10 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
int created = 0;
|
int created = 0;
|
||||||
int totalStages = normalizeMixingStages(formula.getMixingStages());
|
int totalStages = normalizeMixingStages(formula.getMixingStages());
|
||||||
Date today = Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());
|
Date today = Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||||
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A48】生成混炼示方同步B/F段胶至密炼物料-----------
|
//update-begin---author:jiangxh ---date:20260729 for:【混炼示方生成】B/F胶料改为胶料列表匹配,不存在则提示先维护-----------
|
||||||
Set<String> syncedRubberSpecCodes = new HashSet<>();
|
|
||||||
Map<String, String> categoryIdCache = new HashMap<>();
|
Map<String, String> categoryIdCache = new HashMap<>();
|
||||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A48】生成混炼示方同步B/F段胶至密炼物料-----------
|
assertRequiredRubberMaterialsExist(request.getRows(), formula, lines);
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【混炼示方生成】B/F胶料改为胶料列表匹配,不存在则提示先维护-----------
|
||||||
for (MesXslFormulaMixingGenerateRowVO row : request.getRows()) {
|
for (MesXslFormulaMixingGenerateRowVO row : request.getRows()) {
|
||||||
if (row == null || oConvertUtils.isEmpty(row.getSpecCode()) || row.getStageIndex() == null) {
|
if (row == null || oConvertUtils.isEmpty(row.getSpecCode()) || row.getStageIndex() == null) {
|
||||||
continue;
|
continue;
|
||||||
@@ -609,11 +641,6 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
if (CollectionUtils.isEmpty(row.getMachines())) {
|
if (CollectionUtils.isEmpty(row.getMachines())) {
|
||||||
throw new IllegalArgumentException("示方「" + row.getSpecCode() + "」请至少选择一个机台");
|
throw new IllegalArgumentException("示方「" + row.getSpecCode() + "」请至少选择一个机台");
|
||||||
}
|
}
|
||||||
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A48】生成混炼示方同步B/F段胶至密炼物料-----------
|
|
||||||
if (syncedRubberSpecCodes.add(row.getSpecCode().trim())) {
|
|
||||||
syncGeneratedRubberMixerMaterial(row, formula, compoundSpecificGravity, categoryIdCache);
|
|
||||||
}
|
|
||||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A48】生成混炼示方同步B/F段胶至密炼物料-----------
|
|
||||||
String materialStep = resolveMixingMaterialStep(row);
|
String materialStep = resolveMixingMaterialStep(row);
|
||||||
int mixingColumn = resolveMixingColumn(row, formula);
|
int mixingColumn = resolveMixingColumn(row, formula);
|
||||||
List<MesXslMixingSpecMaterial> materials = buildMixingMaterials(
|
List<MesXslMixingSpecMaterial> materials = buildMixingMaterials(
|
||||||
@@ -647,11 +674,15 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A44】生成混炼示方时按设备有效体积计算填充体积-----------
|
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A44】生成混炼示方时按设备有效体积计算填充体积-----------
|
||||||
mixing.setConvertFactor(BigDecimal.ONE);
|
mixing.setConvertFactor(BigDecimal.ONE);
|
||||||
boolean isFinalStage = "Q".equalsIgnoreCase(row.getStepType());
|
boolean isFinalStage = "Q".equalsIgnoreCase(row.getStepType());
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【混炼示方】母胶/终炼胶比重保留三位小数-----------
|
||||||
if (isFinalStage) {
|
if (isFinalStage) {
|
||||||
mixing.setFinalRubberSg(compoundSpecificGravity);
|
if (compoundSpecificGravity != null) {
|
||||||
} else {
|
mixing.setFinalRubberSg(compoundSpecificGravity.setScale(3, RoundingMode.HALF_UP));
|
||||||
mixing.setMotherRubberSg(formula.getARubberSg());
|
}
|
||||||
|
} else if (formula.getARubberSg() != null) {
|
||||||
|
mixing.setMotherRubberSg(formula.getARubberSg().setScale(3, RoundingMode.HALF_UP));
|
||||||
}
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【混炼示方】母胶/终炼胶比重保留三位小数-----------
|
||||||
BigDecimal specificGravity = isFinalStage ? compoundSpecificGravity : formula.getARubberSg();
|
BigDecimal specificGravity = isFinalStage ? compoundSpecificGravity : formula.getARubberSg();
|
||||||
String machineLabel = StringUtils.defaultIfBlank(machine.getMachineName(), machine.getMachineId());
|
String machineLabel = StringUtils.defaultIfBlank(machine.getMachineName(), machine.getMachineId());
|
||||||
MesXslEquipmentLedger equipment = equipmentCache.computeIfAbsent(
|
MesXslEquipmentLedger equipment = equipmentCache.computeIfAbsent(
|
||||||
@@ -766,15 +797,88 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
.divide(effectiveVolume, 6, RoundingMode.HALF_UP)
|
.divide(effectiveVolume, 6, RoundingMode.HALF_UP)
|
||||||
.multiply(BigDecimal.valueOf(100))
|
.multiply(BigDecimal.valueOf(100))
|
||||||
.multiply(factor)
|
.multiply(factor)
|
||||||
.setScale(6, RoundingMode.HALF_UP);
|
//update-begin---author:jiangxh ---date:20260729 for:【混炼示方】填充体积保留两位小数-----------
|
||||||
|
.setScale(2, RoundingMode.HALF_UP);
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【混炼示方】填充体积保留两位小数-----------
|
||||||
}
|
}
|
||||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A44】生成混炼示方时按设备有效体积计算填充体积-----------
|
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A44】生成混炼示方时按设备有效体积计算填充体积-----------
|
||||||
|
|
||||||
//update-begin---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】生成混炼示方改为同步B/F段胶至胶料信息-----------
|
//update-begin---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】生成混炼示方改为同步B/F段胶至胶料信息-----------
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【混炼示方生成】B/F胶料改为胶料列表匹配,不存在则提示先维护-----------
|
||||||
|
//update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】预览项转生成行供胶料匹配校验-----------
|
||||||
|
/** 预览行转为生成行结构,供胶料匹配校验复用 */
|
||||||
|
private List<MesXslFormulaMixingGenerateRowVO> toGenerateRowsFromPreviewItems(
|
||||||
|
List<MesXslFormulaMixingGeneratePreviewItemVO> items) {
|
||||||
|
List<MesXslFormulaMixingGenerateRowVO> rows = new ArrayList<>();
|
||||||
|
if (CollectionUtils.isEmpty(items)) {
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
for (MesXslFormulaMixingGeneratePreviewItemVO item : items) {
|
||||||
|
if (item == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MesXslFormulaMixingGenerateRowVO row = new MesXslFormulaMixingGenerateRowVO();
|
||||||
|
row.setSpecCode(item.getSpecCode());
|
||||||
|
row.setStageIndex(item.getStageIndex());
|
||||||
|
row.setASegmentIndex(item.getASegmentIndex());
|
||||||
|
row.setStepType(item.getStepType());
|
||||||
|
rows.add(row);
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】预览项转生成行供胶料匹配校验-----------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成混炼示方时,将 B 段/F 段胶料同步写入「胶料信息」(mes_material):
|
* 生成前校验:按 B段序号/F + 胶料名 拼出的示方编号,必须已在胶料信息中存在;不再自动新建。
|
||||||
* 除 ERP 编号留空、编码/名称为示方编号外,其余字段按配合示方所选原胶料信息赋值。
|
* 在列表点击「生成混炼示方」预览时即调用,确认生成时再次校验。
|
||||||
*/
|
*/
|
||||||
|
private void assertRequiredRubberMaterialsExist(
|
||||||
|
List<MesXslFormulaMixingGenerateRowVO> rows,
|
||||||
|
MesXslFormulaSpec formula,
|
||||||
|
List<MesXslFormulaSpecLine> lines) {
|
||||||
|
if (CollectionUtils.isEmpty(rows)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LinkedHashSet<String> requiredCodes = new LinkedHashSet<>();
|
||||||
|
String rubberName = resolveRubberName(formula);
|
||||||
|
for (MesXslFormulaMixingGenerateRowVO row : rows) {
|
||||||
|
if (row == null || StringUtils.isBlank(row.getSpecCode())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
requiredCodes.add(row.getSpecCode().trim());
|
||||||
|
String stepFilter = resolveMixingMaterialStep(row);
|
||||||
|
int mixingColumn = resolveMixingColumn(row, formula);
|
||||||
|
if ("Q".equalsIgnoreCase(stepFilter)) {
|
||||||
|
int lastBSegment = resolveLastBSegmentIndex(formula, lines);
|
||||||
|
if (lastBSegment > 0 && StringUtils.isNotBlank(rubberName)) {
|
||||||
|
//update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶匹配不拼版本后缀-----------
|
||||||
|
requiredCodes.add(buildBfRubberSpecCode("B" + lastBSegment, rubberName));
|
||||||
|
//update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶匹配不拼版本后缀-----------
|
||||||
|
}
|
||||||
|
} else if (mixingColumn > 1 && StringUtils.isNotBlank(rubberName)) {
|
||||||
|
//update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶匹配不拼版本后缀-----------
|
||||||
|
requiredCodes.add(buildBfRubberSpecCode("B" + (mixingColumn - 1), rubberName));
|
||||||
|
//update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶匹配不拼版本后缀-----------
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<String> missing = new ArrayList<>();
|
||||||
|
for (String code : requiredCodes) {
|
||||||
|
if (StringUtils.isBlank(code)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (findRubberMaterialByCodeOrName(code.trim()) == null) {
|
||||||
|
missing.add(code.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!missing.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("请先维护母胶和终胶信息:" + String.join("、", missing));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated 已改为仅匹配胶料列表,保留方法避免历史调用编译缺口;生成流程不再自动写入胶料。
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
private void syncGeneratedRubberMixerMaterial(
|
private void syncGeneratedRubberMixerMaterial(
|
||||||
MesXslFormulaMixingGenerateRowVO row,
|
MesXslFormulaMixingGenerateRowVO row,
|
||||||
MesXslFormulaSpec formula,
|
MesXslFormulaSpec formula,
|
||||||
@@ -784,60 +888,9 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String specCode = row.getSpecCode().trim();
|
String specCode = row.getSpecCode().trim();
|
||||||
boolean isFinalStage = "Q".equalsIgnoreCase(resolveMixingMaterialStep(row));
|
if (findRubberMaterialByCodeOrName(specCode) == null) {
|
||||||
String materialPhase = resolveGeneratedMaterialPhase(row);
|
throw new IllegalArgumentException("请先维护母胶和终胶信息:" + specCode);
|
||||||
MesMaterial sourceRubber = resolveSourceRubberMaterial(formula);
|
|
||||||
String categoryId = sourceRubber != null ? sourceRubber.getCategoryId() : null;
|
|
||||||
String rubberName = resolveRubberName(formula);
|
|
||||||
String generatedName = buildGeneratedRubberMaterialName(row, rubberName);
|
|
||||||
MesMaterial existing = findGeneratedRubberMaterialByCodeOrName(specCode, materialPhase);
|
|
||||||
Date now = new Date();
|
|
||||||
if (existing != null) {
|
|
||||||
copyGeneratedMaterialFieldsFromSource(existing, sourceRubber);
|
|
||||||
if (StringUtils.isNotBlank(categoryId)) {
|
|
||||||
existing.setCategoryId(categoryId);
|
|
||||||
}
|
|
||||||
if (StringUtils.isBlank(existing.getMaterialCode())) {
|
|
||||||
existing.setMaterialCode(specCode);
|
|
||||||
}
|
|
||||||
existing.setMaterialName(generatedName);
|
|
||||||
if (StringUtils.isBlank(existing.getAliasName()) && StringUtils.isNotBlank(rubberName)) {
|
|
||||||
existing.setAliasName(rubberName);
|
|
||||||
}
|
|
||||||
existing.setMaterialPhase(materialPhase);
|
|
||||||
existing.setEnableFlag(existing.getEnableFlag() == null ? 1 : existing.getEnableFlag());
|
|
||||||
existing.setUpdateTime(now);
|
|
||||||
mesMaterialService.updateById(existing);
|
|
||||||
log.info(
|
|
||||||
"[混炼示方生成] 更新胶料信息 id={}, code={}, phase={}, categoryId={}, isFinal={}",
|
|
||||||
existing.getId(),
|
|
||||||
specCode,
|
|
||||||
materialPhase,
|
|
||||||
categoryId,
|
|
||||||
isFinalStage);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MesMaterial material = new MesMaterial();
|
|
||||||
copyGeneratedMaterialFieldsFromSource(material, sourceRubber);
|
|
||||||
material.setMaterialCode(specCode);
|
|
||||||
material.setMaterialName(generatedName);
|
|
||||||
material.setAliasName(StringUtils.isNotBlank(rubberName) ? rubberName : null);
|
|
||||||
material.setCategoryId(categoryId);
|
|
||||||
material.setMaterialPhase(materialPhase);
|
|
||||||
material.setEnableFlag(1);
|
|
||||||
material.setIsSpecialRubber(0);
|
|
||||||
material.setDelFlag(CommonConstant.DEL_FLAG_0);
|
|
||||||
material.setCreateTime(now);
|
|
||||||
material.setUpdateTime(now);
|
|
||||||
mesMaterialService.save(material);
|
|
||||||
log.info(
|
|
||||||
"[混炼示方生成] 新增胶料信息 id={}, code={}, phase={}, categoryId={}, isFinal={}",
|
|
||||||
material.getId(),
|
|
||||||
specCode,
|
|
||||||
materialPhase,
|
|
||||||
categoryId,
|
|
||||||
isFinalStage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyGeneratedMaterialFieldsFromSource(MesMaterial target, MesMaterial source) {
|
private void copyGeneratedMaterialFieldsFromSource(MesMaterial target, MesMaterial source) {
|
||||||
@@ -867,6 +920,7 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
target.setLastErpSyncTime(source.getLastErpSyncTime());
|
target.setLastErpSyncTime(source.getLastErpSyncTime());
|
||||||
target.setRemark(source.getRemark());
|
target.setRemark(source.getRemark());
|
||||||
}
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【混炼示方生成】B/F胶料改为胶料列表匹配,不存在则提示先维护-----------
|
||||||
|
|
||||||
private MesMaterial resolveSourceRubberMaterial(MesXslFormulaSpec formula) {
|
private MesMaterial resolveSourceRubberMaterial(MesXslFormulaSpec formula) {
|
||||||
if (formula == null || StringUtils.isBlank(formula.getRubberMaterialId())) {
|
if (formula == null || StringUtils.isBlank(formula.getRubberMaterialId())) {
|
||||||
@@ -967,8 +1021,10 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配合示方胶料代号/示方编号中,胶料名称之后的后缀原样截取(如 SA01、SB01 等,不做固定拼接)。
|
* 配合示方胶料代号/示方编号中,胶料名称之后的后缀原样截取(如 SA01、SB01 等)。
|
||||||
|
* @deprecated 生成混炼示方匹配胶料已改为仅 B/F+胶料名,不再拼接版本后缀
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
private String resolveFormulaCodeSuffix(MesXslFormulaSpec main) {
|
private String resolveFormulaCodeSuffix(MesXslFormulaSpec main) {
|
||||||
if (main == null) {
|
if (main == null) {
|
||||||
return "";
|
return "";
|
||||||
@@ -995,6 +1051,10 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated 生成混炼示方匹配胶料已改为仅 B/F+胶料名,请使用 {@link #buildBfRubberSpecCode(String, String)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
private String appendFormulaCodeSuffix(String baseSpecCode, String formulaCodeSuffix) {
|
private String appendFormulaCodeSuffix(String baseSpecCode, String formulaCodeSuffix) {
|
||||||
if (StringUtils.isBlank(baseSpecCode)) {
|
if (StringUtils.isBlank(baseSpecCode)) {
|
||||||
return baseSpecCode;
|
return baseSpecCode;
|
||||||
@@ -1005,6 +1065,16 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
return baseSpecCode + formulaCodeSuffix;
|
return baseSpecCode + formulaCodeSuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】B/F匹配编号仅前缀+胶料名-----------
|
||||||
|
/**
|
||||||
|
* 生成/匹配用示方编号:仅「B{n}/F + 胶料名」,不拼接 SA01 等版本号。
|
||||||
|
* 例:胶料 XC001 三段 → B1XC001、B2XC001、FXC001
|
||||||
|
*/
|
||||||
|
private String buildBfRubberSpecCode(String phasePrefix, String rubberName) {
|
||||||
|
return StringUtils.defaultString(phasePrefix) + StringUtils.defaultString(rubberName).trim();
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】B/F匹配编号仅前缀+胶料名-----------
|
||||||
|
|
||||||
private boolean hasStepQ(List<MesXslFormulaSpecLine> lines) {
|
private boolean hasStepQ(List<MesXslFormulaSpecLine> lines) {
|
||||||
if (CollectionUtils.isEmpty(lines)) {
|
if (CollectionUtils.isEmpty(lines)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1071,10 +1141,11 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
if ("Q".equals(stepFilter)) {
|
if ("Q".equals(stepFilter)) {
|
||||||
//update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】F段加入最后一段B炼好胶料一条再加Q配合剂-----------
|
//update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】F段加入最后一段B炼好胶料一条再加Q配合剂-----------
|
||||||
String rubberName = resolveRubberName(formula);
|
String rubberName = resolveRubberName(formula);
|
||||||
String codeSuffix = resolveFormulaCodeSuffix(formula);
|
|
||||||
int lastBSegment = resolveLastBSegmentIndex(formula, lines);
|
int lastBSegment = resolveLastBSegmentIndex(formula, lines);
|
||||||
if (lastBSegment > 0) {
|
if (lastBSegment > 0) {
|
||||||
String motherSpecCode = appendFormulaCodeSuffix("B" + lastBSegment + rubberName, codeSuffix);
|
//update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶编号不拼版本后缀-----------
|
||||||
|
String motherSpecCode = buildBfRubberSpecCode("B" + lastBSegment, rubberName);
|
||||||
|
//update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶编号不拼版本后缀-----------
|
||||||
BigDecimal motherWeight = resolveStageCumulativeTotal(formula, lines, lastBSegment);
|
BigDecimal motherWeight = resolveStageCumulativeTotal(formula, lines, lastBSegment);
|
||||||
materials.add(
|
materials.add(
|
||||||
createMotherRubberMaterial(
|
createMotherRubberMaterial(
|
||||||
@@ -1095,7 +1166,6 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
}
|
}
|
||||||
int bColumn = Math.max(stageIndex, 1);
|
int bColumn = Math.max(stageIndex, 1);
|
||||||
String rubberName = resolveRubberName(formula);
|
String rubberName = resolveRubberName(formula);
|
||||||
String codeSuffix = resolveFormulaCodeSuffix(formula);
|
|
||||||
if (bColumn <= 1) {
|
if (bColumn <= 1) {
|
||||||
appendBStageColumnAgents(lines, 1, materials, mixerCache, categoryNameCache, kindLookup);
|
appendBStageColumnAgents(lines, 1, materials, mixerCache, categoryNameCache, kindLookup);
|
||||||
reindexMaterialSortNo(materials);
|
reindexMaterialSortNo(materials);
|
||||||
@@ -1103,7 +1173,9 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
}
|
}
|
||||||
// B2/B3…:上一段炼好胶料一条(如 B1+胶料名) + 本段列配合剂
|
// B2/B3…:上一段炼好胶料一条(如 B1+胶料名) + 本段列配合剂
|
||||||
int prevB = bColumn - 1;
|
int prevB = bColumn - 1;
|
||||||
String motherSpecCode = appendFormulaCodeSuffix("B" + prevB + rubberName, codeSuffix);
|
//update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶编号不拼版本后缀-----------
|
||||||
|
String motherSpecCode = buildBfRubberSpecCode("B" + prevB, rubberName);
|
||||||
|
//update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶编号不拼版本后缀-----------
|
||||||
BigDecimal motherWeight = resolveStageCumulativeTotal(formula, lines, prevB);
|
BigDecimal motherWeight = resolveStageCumulativeTotal(formula, lines, prevB);
|
||||||
materials.add(
|
materials.add(
|
||||||
createMotherRubberMaterial(
|
createMotherRubberMaterial(
|
||||||
@@ -1205,7 +1277,7 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
//update-end---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】上一段母胶明细行改绑胶料信息-----------
|
//update-end---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】上一段母胶明细行改绑胶料信息-----------
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 上一段 B 段胶尚未写入胶料信息时,按配合示方胶料类别补建一条胶料信息 */
|
/** 上一段 B 段胶必须已在胶料信息中维护,不再自动补建 */
|
||||||
private void ensureMotherRubberMaterialSynced(
|
private void ensureMotherRubberMaterialSynced(
|
||||||
String motherSpecCode,
|
String motherSpecCode,
|
||||||
MesXslFormulaSpec formula,
|
MesXslFormulaSpec formula,
|
||||||
@@ -1214,13 +1286,12 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String normalized = motherSpecCode.trim();
|
String normalized = motherSpecCode.trim();
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【混炼示方生成】上一段母胶改为胶料列表匹配,不存在则提示-----------
|
||||||
if (findRubberMaterialByCodeOrName(normalized) != null) {
|
if (findRubberMaterialByCodeOrName(normalized) != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MesXslFormulaMixingGenerateRowVO stub = new MesXslFormulaMixingGenerateRowVO();
|
throw new IllegalArgumentException("请先维护母胶和终胶信息:" + normalized);
|
||||||
stub.setSpecCode(normalized);
|
//update-end---author:jiangxh ---date:20260729 for:【混炼示方生成】上一段母胶改为胶料列表匹配,不存在则提示-----------
|
||||||
stub.setStepType("A");
|
|
||||||
syncGeneratedRubberMixerMaterial(stub, formula, null, categoryIdCache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 按密炼物料主数据回填混炼示方明细行(名称/大小类/种类) */
|
/** 按密炼物料主数据回填混炼示方明细行(名称/大小类/种类) */
|
||||||
@@ -1272,9 +1343,17 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
material.setMaterialMajor(null);
|
material.setMaterialMajor(null);
|
||||||
material.setMaterialMinor(categoryName);
|
material.setMaterialMinor(categoryName);
|
||||||
material.setMixerMaterialId(rubber.getId());
|
material.setMixerMaterialId(rubber.getId());
|
||||||
material.setMaterialKind(
|
//update-begin---author:jiangxh ---date:20260729 for:【混炼示方生成】母胶行种类按配置解析,未命中则带入胶料兜底种类-----------
|
||||||
mesXslMixerMaterialKindCfgService.resolveMixingMaterialKind(
|
String kind = mesXslMixerMaterialKindCfgService.resolveMixingMaterialKind(
|
||||||
kindLookup, rubber.getCategoryId(), null, categoryName));
|
kindLookup, rubber.getCategoryId(), null, categoryName);
|
||||||
|
if (StringUtils.isBlank(kind) && kindLookup != null && StringUtils.isNotBlank(kindLookup.getRubberKindName())) {
|
||||||
|
kind = kindLookup.getRubberKindName().trim();
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(kind)) {
|
||||||
|
kind = "胶料";
|
||||||
|
}
|
||||||
|
material.setMaterialKind(kind);
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【混炼示方生成】母胶行种类按配置解析,未命中则带入胶料兜底种类-----------
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 未查到胶料信息时,按配合示方胶料类别从配置表解析种类 */
|
/** 未查到胶料信息时,按配合示方胶料类别从配置表解析种类 */
|
||||||
@@ -1287,9 +1366,17 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
|||||||
String categoryName = resolveCategoryName(categoryId, categoryNameCache);
|
String categoryName = resolveCategoryName(categoryId, categoryNameCache);
|
||||||
material.setMaterialMajor(null);
|
material.setMaterialMajor(null);
|
||||||
material.setMaterialMinor(categoryName);
|
material.setMaterialMinor(categoryName);
|
||||||
material.setMaterialKind(
|
//update-begin---author:jiangxh ---date:20260729 for:【混炼示方生成】母胶兜底种类带入胶料种类-----------
|
||||||
mesXslMixerMaterialKindCfgService.resolveMixingMaterialKind(
|
String kind = mesXslMixerMaterialKindCfgService.resolveMixingMaterialKind(
|
||||||
kindLookup, categoryId, null, categoryName));
|
kindLookup, categoryId, null, categoryName);
|
||||||
|
if (StringUtils.isBlank(kind) && kindLookup != null && StringUtils.isNotBlank(kindLookup.getRubberKindName())) {
|
||||||
|
kind = kindLookup.getRubberKindName().trim();
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(kind)) {
|
||||||
|
kind = "胶料";
|
||||||
|
}
|
||||||
|
material.setMaterialKind(kind);
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【混炼示方生成】母胶兜底种类带入胶料种类-----------
|
||||||
}
|
}
|
||||||
//update-end---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】母胶明细行按胶料信息回填-----------
|
//update-end---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】母胶明细行按胶料信息回填-----------
|
||||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A54】母炼胶明细行绑定已同步密炼物料主数据-----------
|
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A54】母炼胶明细行绑定已同步密炼物料主数据-----------
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.jeecg.modules.xslmes.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import org.jeecg.modules.xslmes.entity.MesXslMillAction;
|
||||||
|
import org.jeecg.modules.xslmes.mapper.MesXslMillActionMapper;
|
||||||
|
import org.jeecg.modules.xslmes.service.IMesXslMillActionService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class MesXslMillActionServiceImpl extends ServiceImpl<MesXslMillActionMapper, MesXslMillAction> implements IMesXslMillActionService {}
|
||||||
@@ -18,13 +18,16 @@ public class MesXslMixerConditionServiceImpl
|
|||||||
|
|
||||||
@Autowired private MesXslEquipmentLedgerMapper equipmentLedgerMapper;
|
@Autowired private MesXslEquipmentLedgerMapper equipmentLedgerMapper;
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称/代码按设备唯一-----------
|
||||||
@Override
|
@Override
|
||||||
public boolean isConditionNameDuplicated(String conditionName, String excludeId) {
|
public boolean isConditionNameDuplicated(String conditionName, String equipmentId, String excludeId) {
|
||||||
if (StringUtils.isBlank(conditionName)) {
|
if (StringUtils.isBlank(conditionName) || StringUtils.isBlank(equipmentId)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
LambdaQueryWrapper<MesXslMixerCondition> wrapper =
|
LambdaQueryWrapper<MesXslMixerCondition> wrapper =
|
||||||
new LambdaQueryWrapper<MesXslMixerCondition>().eq(MesXslMixerCondition::getConditionName, conditionName.trim());
|
new LambdaQueryWrapper<MesXslMixerCondition>()
|
||||||
|
.eq(MesXslMixerCondition::getEquipmentId, equipmentId.trim())
|
||||||
|
.eq(MesXslMixerCondition::getConditionName, conditionName.trim());
|
||||||
if (StringUtils.isNotBlank(excludeId)) {
|
if (StringUtils.isNotBlank(excludeId)) {
|
||||||
wrapper.ne(MesXslMixerCondition::getId, excludeId.trim());
|
wrapper.ne(MesXslMixerCondition::getId, excludeId.trim());
|
||||||
}
|
}
|
||||||
@@ -32,17 +35,20 @@ public class MesXslMixerConditionServiceImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isConditionCodeDuplicated(String conditionCode, String excludeId) {
|
public boolean isConditionCodeDuplicated(String conditionCode, String equipmentId, String excludeId) {
|
||||||
if (StringUtils.isBlank(conditionCode)) {
|
if (StringUtils.isBlank(conditionCode) || StringUtils.isBlank(equipmentId)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
LambdaQueryWrapper<MesXslMixerCondition> wrapper =
|
LambdaQueryWrapper<MesXslMixerCondition> wrapper =
|
||||||
new LambdaQueryWrapper<MesXslMixerCondition>().eq(MesXslMixerCondition::getConditionCode, conditionCode.trim());
|
new LambdaQueryWrapper<MesXslMixerCondition>()
|
||||||
|
.eq(MesXslMixerCondition::getEquipmentId, equipmentId.trim())
|
||||||
|
.eq(MesXslMixerCondition::getConditionCode, conditionCode.trim());
|
||||||
if (StringUtils.isNotBlank(excludeId)) {
|
if (StringUtils.isNotBlank(excludeId)) {
|
||||||
wrapper.ne(MesXslMixerCondition::getId, excludeId.trim());
|
wrapper.ne(MesXslMixerCondition::getId, excludeId.trim());
|
||||||
}
|
}
|
||||||
return this.count(wrapper) > 0;
|
return this.count(wrapper) > 0;
|
||||||
}
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称/代码按设备唯一-----------
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fillEquipmentName(MesXslMixerCondition model) {
|
public void fillEquipmentName(MesXslMixerCondition model) {
|
||||||
|
|||||||
@@ -103,6 +103,8 @@ public class MesXslMixingProductionPlanServiceImpl
|
|||||||
|
|
||||||
private void rebuildRawMaterialDemandPlan(List<MesXslMixingProductionPlan> savedPlans) {
|
private void rebuildRawMaterialDemandPlan(List<MesXslMixingProductionPlan> savedPlans) {
|
||||||
jdbcTemplate.update("DELETE FROM mes_xsl_raw_material_demand_plan");
|
jdbcTemplate.update("DELETE FROM mes_xsl_raw_material_demand_plan");
|
||||||
|
jdbcTemplate.update("DELETE FROM mes_xsl_auto_small_material_demand_plan");
|
||||||
|
jdbcTemplate.update("DELETE FROM mes_xsl_manual_small_material_demand_plan");
|
||||||
if (CollectionUtils.isEmpty(savedPlans)) {
|
if (CollectionUtils.isEmpty(savedPlans)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -184,6 +186,8 @@ public class MesXslMixingProductionPlanServiceImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
Map<String, RawDemandAggregate> aggregateMap = new HashMap<>();
|
Map<String, RawDemandAggregate> aggregateMap = new HashMap<>();
|
||||||
|
Map<String, SmallDemandAggregate> autoAggregateMap = new HashMap<>();
|
||||||
|
Map<String, SmallDemandAggregate> manualAggregateMap = new HashMap<>();
|
||||||
for (MesXslMixingProductionPlan plan : validPlans) {
|
for (MesXslMixingProductionPlan plan : validPlans) {
|
||||||
String specId = specIdByName.get(StringUtils.trimToEmpty(plan.getFormulaName()));
|
String specId = specIdByName.get(StringUtils.trimToEmpty(plan.getFormulaName()));
|
||||||
if (StringUtils.isBlank(specId)) {
|
if (StringUtils.isBlank(specId)) {
|
||||||
@@ -241,19 +245,39 @@ public class MesXslMixingProductionPlanServiceImpl
|
|||||||
StringUtils.defaultString(erpCode),
|
StringUtils.defaultString(erpCode),
|
||||||
rawMaterialName));
|
rawMaterialName));
|
||||||
aggregate.demandWeight = aggregate.demandWeight.add(demandWeight);
|
aggregate.demandWeight = aggregate.demandWeight.add(demandWeight);
|
||||||
|
|
||||||
|
String smallKey =
|
||||||
|
String.join(
|
||||||
|
"|",
|
||||||
|
planDateKey,
|
||||||
|
StringUtils.defaultString(plan.getMachineId()),
|
||||||
|
StringUtils.defaultString(plan.getMachineName()),
|
||||||
|
rawMaterialName);
|
||||||
|
boolean isAutoKind = StringUtils.contains(StringUtils.trimToEmpty(detail.getMaterialKind()), "自动");
|
||||||
|
Map<String, SmallDemandAggregate> targetSmallMap = isAutoKind ? autoAggregateMap : manualAggregateMap;
|
||||||
|
SmallDemandAggregate smallAggregate =
|
||||||
|
targetSmallMap.computeIfAbsent(
|
||||||
|
smallKey,
|
||||||
|
k ->
|
||||||
|
new SmallDemandAggregate(
|
||||||
|
plan.getPlanDate(),
|
||||||
|
StringUtils.trimToNull(plan.getMachineId()),
|
||||||
|
StringUtils.trimToNull(plan.getMachineName()),
|
||||||
|
rawMaterialName));
|
||||||
|
smallAggregate.demandWeight = smallAggregate.demandWeight.add(demandWeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aggregateMap.isEmpty()) {
|
if (aggregateMap.isEmpty() && autoAggregateMap.isEmpty() && manualAggregateMap.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Object[]> batchArgs = new ArrayList<>();
|
List<Object[]> rawBatchArgs = new ArrayList<>();
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
for (RawDemandAggregate aggregate : aggregateMap.values()) {
|
for (RawDemandAggregate aggregate : aggregateMap.values()) {
|
||||||
if (aggregate.demandWeight.compareTo(BigDecimal.ZERO) <= 0) {
|
if (aggregate.demandWeight.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
batchArgs.add(
|
rawBatchArgs.add(
|
||||||
new Object[] {
|
new Object[] {
|
||||||
IdWorker.getIdStr(),
|
IdWorker.getIdStr(),
|
||||||
aggregate.machineId,
|
aggregate.machineId,
|
||||||
@@ -270,14 +294,53 @@ public class MesXslMixingProductionPlanServiceImpl
|
|||||||
CommonConstant.DEL_FLAG_0
|
CommonConstant.DEL_FLAG_0
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (batchArgs.isEmpty()) {
|
if (!rawBatchArgs.isEmpty()) {
|
||||||
return;
|
jdbcTemplate.batchUpdate(
|
||||||
|
"INSERT INTO mes_xsl_raw_material_demand_plan "
|
||||||
|
+ "(id, machine_id, machine_name, material_id, erp_code, raw_material_name, demand_weight, standard_weight, actual_weight, plan_date, create_time, update_time, del_flag) "
|
||||||
|
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
rawBatchArgs);
|
||||||
}
|
}
|
||||||
jdbcTemplate.batchUpdate(
|
|
||||||
"INSERT INTO mes_xsl_raw_material_demand_plan "
|
List<Object[]> autoBatchArgs = buildSmallDemandBatchArgs(autoAggregateMap, now);
|
||||||
+ "(id, machine_id, machine_name, material_id, erp_code, raw_material_name, demand_weight, standard_weight, actual_weight, plan_date, create_time, update_time, del_flag) "
|
if (!autoBatchArgs.isEmpty()) {
|
||||||
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
jdbcTemplate.batchUpdate(
|
||||||
batchArgs);
|
"INSERT INTO mes_xsl_auto_small_material_demand_plan "
|
||||||
|
+ "(id, stat_date, machine_id, machine_name, raw_material_name, demand_weight, create_time, update_time, del_flag) "
|
||||||
|
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
autoBatchArgs);
|
||||||
|
}
|
||||||
|
List<Object[]> manualBatchArgs = buildSmallDemandBatchArgs(manualAggregateMap, now);
|
||||||
|
if (!manualBatchArgs.isEmpty()) {
|
||||||
|
jdbcTemplate.batchUpdate(
|
||||||
|
"INSERT INTO mes_xsl_manual_small_material_demand_plan "
|
||||||
|
+ "(id, stat_date, machine_id, machine_name, raw_material_name, demand_weight, create_time, update_time, del_flag) "
|
||||||
|
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
manualBatchArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Object[]> buildSmallDemandBatchArgs(
|
||||||
|
Map<String, SmallDemandAggregate> aggregateMap, Date now) {
|
||||||
|
List<Object[]> batchArgs = new ArrayList<>();
|
||||||
|
for (SmallDemandAggregate aggregate : aggregateMap.values()) {
|
||||||
|
if (aggregate.demandWeight.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
batchArgs.add(
|
||||||
|
new Object[] {
|
||||||
|
IdWorker.getIdStr(),
|
||||||
|
aggregate.statDate,
|
||||||
|
aggregate.machineId,
|
||||||
|
aggregate.machineName,
|
||||||
|
aggregate.rawMaterialName,
|
||||||
|
aggregate.demandWeight,
|
||||||
|
now,
|
||||||
|
now,
|
||||||
|
CommonConstant.DEL_FLAG_0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return batchArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class RawDemandAggregate {
|
private static class RawDemandAggregate {
|
||||||
@@ -305,6 +368,22 @@ public class MesXslMixingProductionPlanServiceImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class SmallDemandAggregate {
|
||||||
|
private final Date statDate;
|
||||||
|
private final String machineId;
|
||||||
|
private final String machineName;
|
||||||
|
private final String rawMaterialName;
|
||||||
|
private BigDecimal demandWeight = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
private SmallDemandAggregate(
|
||||||
|
Date statDate, String machineId, String machineName, String rawMaterialName) {
|
||||||
|
this.statDate = statDate;
|
||||||
|
this.machineId = machineId;
|
||||||
|
this.machineName = machineName;
|
||||||
|
this.rawMaterialName = rawMaterialName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean hasBusinessData(MesXslMixingProductionPlan row) {
|
private boolean hasBusinessData(MesXslMixingProductionPlan row) {
|
||||||
return StringUtils.isNotBlank(row.getMachineId())
|
return StringUtils.isNotBlank(row.getMachineId())
|
||||||
|| StringUtils.isNotBlank(row.getPlanId())
|
|| StringUtils.isNotBlank(row.getPlanId())
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package org.jeecg.modules.device.sync.agent;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MES → 桌面设备库命令。
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class DeviceAgentCommand implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final String CMD_QUERY = "EQ_QUERY";
|
||||||
|
public static final String CMD_WRITE = "EQ_WRITE";
|
||||||
|
public static final String CMD_SYNC_PULL = "EQ_SYNC_PULL";
|
||||||
|
public static final String CMD_SYNC_PUSH = "EQ_SYNC_PUSH";
|
||||||
|
public static final String CMD_TEST = "EQ_TEST";
|
||||||
|
|
||||||
|
private String requestId;
|
||||||
|
private String cmd;
|
||||||
|
private String deviceId;
|
||||||
|
/** 白名单表名(可选,与 sql 二选一或同时校验) */
|
||||||
|
private String table;
|
||||||
|
/** 已登记 sqlKey 或受限 SQL(桌面端白名单校验) */
|
||||||
|
private String sql;
|
||||||
|
private String sqlKey;
|
||||||
|
private List<Object> params;
|
||||||
|
private Map<String, Object> payload;
|
||||||
|
private Integer timeoutMs;
|
||||||
|
private Long sentAt;
|
||||||
|
}
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
package org.jeecg.modules.device.sync.agent;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备代理命令总线:下发 EQ_* 并等待回执。
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class DeviceAgentCommandService {
|
||||||
|
|
||||||
|
public static final int DEFAULT_TIMEOUT_MS = 30_000;
|
||||||
|
|
||||||
|
private final SimpMessagingTemplate messagingTemplate;
|
||||||
|
private final DeviceAgentSessionRegistry sessionRegistry;
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<String, CompletableFuture<DeviceAgentResult>> pending = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public DeviceAgentResult sendAndWait(DeviceAgentCommand command) {
|
||||||
|
if (command == null) {
|
||||||
|
throw new IllegalArgumentException("command 不能为空");
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(command.getRequestId())) {
|
||||||
|
command.setRequestId(UUID.randomUUID().toString().replace("-", ""));
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(command.getDeviceId())) {
|
||||||
|
DeviceAgentSession picked = sessionRegistry.pickOnlineAgent(null);
|
||||||
|
if (picked == null) {
|
||||||
|
throw new IllegalStateException("无在线桌面设备代理,无法访问设备库");
|
||||||
|
}
|
||||||
|
command.setDeviceId(picked.getDeviceId());
|
||||||
|
}
|
||||||
|
if (!sessionRegistry.isOnline(command.getDeviceId())) {
|
||||||
|
throw new IllegalStateException("桌面设备代理不在线: " + command.getDeviceId());
|
||||||
|
}
|
||||||
|
int timeout = command.getTimeoutMs() != null && command.getTimeoutMs() > 0
|
||||||
|
? command.getTimeoutMs() : DEFAULT_TIMEOUT_MS;
|
||||||
|
command.setSentAt(System.currentTimeMillis());
|
||||||
|
|
||||||
|
CompletableFuture<DeviceAgentResult> future = new CompletableFuture<>();
|
||||||
|
CompletableFuture<DeviceAgentResult> previous = pending.putIfAbsent(command.getRequestId(), future);
|
||||||
|
if (previous != null) {
|
||||||
|
throw new IllegalStateException("重复的 requestId: " + command.getRequestId());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
String destination = "/topic/device/" + command.getDeviceId() + "/cmd";
|
||||||
|
messagingTemplate.convertAndSend(destination, JSON.toJSONString(command));
|
||||||
|
log.info("已下发设备库命令 cmd={} requestId={} deviceId={}",
|
||||||
|
command.getCmd(), command.getRequestId(), command.getDeviceId());
|
||||||
|
return future.get(timeout, TimeUnit.MILLISECONDS);
|
||||||
|
} catch (TimeoutException e) {
|
||||||
|
pending.remove(command.getRequestId(), future);
|
||||||
|
throw new IllegalStateException("等待桌面设备库回执超时(" + timeout + "ms), requestId=" + command.getRequestId());
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
pending.remove(command.getRequestId(), future);
|
||||||
|
throw new IllegalStateException("等待桌面设备库回执被中断", e);
|
||||||
|
} catch (Exception e) {
|
||||||
|
pending.remove(command.getRequestId(), future);
|
||||||
|
if (e instanceof IllegalStateException) {
|
||||||
|
throw (IllegalStateException) e;
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("下发设备库命令失败: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void completeResult(DeviceAgentResult result) {
|
||||||
|
if (result == null || StringUtils.isBlank(result.getRequestId())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(result.getDeviceId())) {
|
||||||
|
sessionRegistry.registerOrHeartbeat(
|
||||||
|
result.getDeviceId(),
|
||||||
|
null,
|
||||||
|
result.getDbConnected(),
|
||||||
|
result.getDbMessage());
|
||||||
|
}
|
||||||
|
CompletableFuture<DeviceAgentResult> future = pending.remove(result.getRequestId());
|
||||||
|
if (future != null) {
|
||||||
|
future.complete(result);
|
||||||
|
} else {
|
||||||
|
log.debug("收到无等待方的设备库回执 requestId={}", result.getRequestId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceAgentResult query(String deviceId, String sql, List<Object> params, Integer timeoutMs) {
|
||||||
|
DeviceAgentCommand cmd = new DeviceAgentCommand();
|
||||||
|
cmd.setCmd(DeviceAgentCommand.CMD_QUERY);
|
||||||
|
cmd.setDeviceId(deviceId);
|
||||||
|
cmd.setSql(sql);
|
||||||
|
cmd.setParams(params);
|
||||||
|
cmd.setTimeoutMs(timeoutMs);
|
||||||
|
DeviceAgentResult result = sendAndWait(cmd);
|
||||||
|
ensureSuccess(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceAgentResult write(String deviceId, String sql, List<Object> params, Integer timeoutMs) {
|
||||||
|
DeviceAgentCommand cmd = new DeviceAgentCommand();
|
||||||
|
cmd.setCmd(DeviceAgentCommand.CMD_WRITE);
|
||||||
|
cmd.setDeviceId(deviceId);
|
||||||
|
cmd.setSql(sql);
|
||||||
|
cmd.setParams(params);
|
||||||
|
cmd.setTimeoutMs(timeoutMs);
|
||||||
|
DeviceAgentResult result = sendAndWait(cmd);
|
||||||
|
ensureSuccess(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceAgentResult test(String deviceId, Integer timeoutMs) {
|
||||||
|
DeviceAgentCommand cmd = new DeviceAgentCommand();
|
||||||
|
cmd.setCmd(DeviceAgentCommand.CMD_TEST);
|
||||||
|
cmd.setDeviceId(deviceId);
|
||||||
|
cmd.setTimeoutMs(timeoutMs != null ? timeoutMs : 10_000);
|
||||||
|
return sendAndWait(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceAgentResult syncPull(String deviceId, String table, String sql, List<Object> params, Integer timeoutMs) {
|
||||||
|
DeviceAgentCommand cmd = new DeviceAgentCommand();
|
||||||
|
cmd.setCmd(DeviceAgentCommand.CMD_SYNC_PULL);
|
||||||
|
cmd.setDeviceId(deviceId);
|
||||||
|
cmd.setTable(table);
|
||||||
|
cmd.setSql(sql);
|
||||||
|
cmd.setParams(params);
|
||||||
|
cmd.setTimeoutMs(timeoutMs != null ? timeoutMs : 60_000);
|
||||||
|
DeviceAgentResult result = sendAndWait(cmd);
|
||||||
|
ensureSuccess(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceAgentResult syncPush(String deviceId, String table, Map<String, Object> payload, Integer timeoutMs) {
|
||||||
|
DeviceAgentCommand cmd = new DeviceAgentCommand();
|
||||||
|
cmd.setCmd(DeviceAgentCommand.CMD_SYNC_PUSH);
|
||||||
|
cmd.setDeviceId(deviceId);
|
||||||
|
cmd.setTable(table);
|
||||||
|
cmd.setPayload(payload);
|
||||||
|
cmd.setTimeoutMs(timeoutMs != null ? timeoutMs : 60_000);
|
||||||
|
DeviceAgentResult result = sendAndWait(cmd);
|
||||||
|
ensureSuccess(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureSuccess(DeviceAgentResult result) {
|
||||||
|
if (result == null) {
|
||||||
|
throw new IllegalStateException("桌面设备库无回执");
|
||||||
|
}
|
||||||
|
if (!result.isSuccess()) {
|
||||||
|
throw new IllegalStateException(StringUtils.defaultIfBlank(result.getError(), "桌面设备库执行失败"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package org.jeecg.modules.device.sync.agent;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 桌面 → MES 设备库命令回执。
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class DeviceAgentResult implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String requestId;
|
||||||
|
private String deviceId;
|
||||||
|
private String cmd;
|
||||||
|
private boolean success;
|
||||||
|
private String error;
|
||||||
|
private Integer affected;
|
||||||
|
private List<Map<String, Object>> rows;
|
||||||
|
private Boolean dbConnected;
|
||||||
|
private String dbMessage;
|
||||||
|
private Long respondedAt;
|
||||||
|
/** 分块回传时使用 */
|
||||||
|
private Integer chunkIndex;
|
||||||
|
private Integer chunkTotal;
|
||||||
|
private Boolean lastChunk;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.jeecg.modules.device.sync.agent;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 桌面设备代理在线会话(内存)。
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class DeviceAgentSession implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String deviceId;
|
||||||
|
private String hostName;
|
||||||
|
private boolean online;
|
||||||
|
/** 设备库(SQL Server)是否连通 */
|
||||||
|
private boolean dbConnected;
|
||||||
|
private String dbMessage;
|
||||||
|
private long lastSeenAt;
|
||||||
|
private long registeredAt;
|
||||||
|
}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
package org.jeecg.modules.device.sync.agent;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 桌面设备代理会话注册表。
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class DeviceAgentSessionRegistry {
|
||||||
|
|
||||||
|
private static final long ONLINE_TTL_MS = 60_000L;
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<String, DeviceAgentSession> sessions = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public void registerOrHeartbeat(String deviceId, String hostName, Boolean dbConnected, String dbMessage) {
|
||||||
|
if (StringUtils.isBlank(deviceId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
sessions.compute(deviceId, (id, old) -> {
|
||||||
|
DeviceAgentSession s = old == null ? new DeviceAgentSession() : old;
|
||||||
|
if (old == null) {
|
||||||
|
s.setRegisteredAt(now);
|
||||||
|
}
|
||||||
|
s.setDeviceId(deviceId);
|
||||||
|
if (StringUtils.isNotBlank(hostName)) {
|
||||||
|
s.setHostName(hostName);
|
||||||
|
}
|
||||||
|
s.setOnline(true);
|
||||||
|
if (dbConnected != null) {
|
||||||
|
s.setDbConnected(dbConnected);
|
||||||
|
}
|
||||||
|
if (dbMessage != null) {
|
||||||
|
s.setDbMessage(dbMessage);
|
||||||
|
}
|
||||||
|
s.setLastSeenAt(now);
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void markOffline(String deviceId) {
|
||||||
|
if (StringUtils.isBlank(deviceId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DeviceAgentSession s = sessions.get(deviceId);
|
||||||
|
if (s != null) {
|
||||||
|
s.setOnline(false);
|
||||||
|
s.setLastSeenAt(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceAgentSession get(String deviceId) {
|
||||||
|
if (StringUtils.isBlank(deviceId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
DeviceAgentSession s = sessions.get(deviceId);
|
||||||
|
if (s == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
refreshOnlineFlag(s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOnline(String deviceId) {
|
||||||
|
DeviceAgentSession s = get(deviceId);
|
||||||
|
return s != null && s.isOnline();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选取一个在线代理:优先指定 deviceId,否则取最近心跳的在线设备。
|
||||||
|
*/
|
||||||
|
public DeviceAgentSession pickOnlineAgent(String preferredDeviceId) {
|
||||||
|
if (StringUtils.isNotBlank(preferredDeviceId)) {
|
||||||
|
DeviceAgentSession preferred = get(preferredDeviceId);
|
||||||
|
if (preferred != null && preferred.isOnline()) {
|
||||||
|
return preferred;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return listOnline().stream()
|
||||||
|
.max(Comparator.comparingLong(DeviceAgentSession::getLastSeenAt))
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DeviceAgentSession> listOnline() {
|
||||||
|
List<DeviceAgentSession> list = new ArrayList<>();
|
||||||
|
for (Map.Entry<String, DeviceAgentSession> e : sessions.entrySet()) {
|
||||||
|
DeviceAgentSession s = e.getValue();
|
||||||
|
refreshOnlineFlag(s);
|
||||||
|
if (s.isOnline()) {
|
||||||
|
list.add(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list.sort(Comparator.comparingLong(DeviceAgentSession::getLastSeenAt).reversed());
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DeviceAgentSession> listAll() {
|
||||||
|
List<DeviceAgentSession> list = new ArrayList<>(sessions.values());
|
||||||
|
list.forEach(this::refreshOnlineFlag);
|
||||||
|
list.sort(Comparator.comparingLong(DeviceAgentSession::getLastSeenAt).reversed());
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshOnlineFlag(DeviceAgentSession s) {
|
||||||
|
if (s == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (System.currentTimeMillis() - s.getLastSeenAt() > ONLINE_TTL_MS) {
|
||||||
|
s.setOnline(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,29 @@
|
|||||||
package org.jeecg.modules.device.sync.controller;
|
package org.jeecg.modules.device.sync.controller;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.modules.device.sync.agent.DeviceAgentCommand;
|
||||||
|
import org.jeecg.modules.device.sync.agent.DeviceAgentCommandService;
|
||||||
|
import org.jeecg.modules.device.sync.agent.DeviceAgentResult;
|
||||||
|
import org.jeecg.modules.device.sync.agent.DeviceAgentSession;
|
||||||
|
import org.jeecg.modules.device.sync.agent.DeviceAgentSessionRegistry;
|
||||||
import org.jeecg.modules.device.sync.entity.DeviceStatus;
|
import org.jeecg.modules.device.sync.entity.DeviceStatus;
|
||||||
import org.jeecg.modules.device.sync.mapper.DeviceStatusMapper;
|
import org.jeecg.modules.device.sync.mapper.DeviceStatusMapper;
|
||||||
import org.springframework.messaging.handler.annotation.MessageMapping;
|
import org.springframework.messaging.handler.annotation.MessageMapping;
|
||||||
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -29,6 +38,8 @@ public class DeviceWebSocketController {
|
|||||||
|
|
||||||
private final DeviceStatusMapper deviceStatusMapper;
|
private final DeviceStatusMapper deviceStatusMapper;
|
||||||
private final SimpMessagingTemplate messagingTemplate;
|
private final SimpMessagingTemplate messagingTemplate;
|
||||||
|
private final DeviceAgentSessionRegistry agentSessionRegistry;
|
||||||
|
private final DeviceAgentCommandService agentCommandService;
|
||||||
|
|
||||||
@MessageMapping("/device/status")
|
@MessageMapping("/device/status")
|
||||||
public void receiveDeviceStatus(DeviceStatus payload) {
|
public void receiveDeviceStatus(DeviceStatus payload) {
|
||||||
@@ -70,6 +81,8 @@ public class DeviceWebSocketController {
|
|||||||
if (deviceId.isBlank()) {
|
if (deviceId.isBlank()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// 心跳同时刷新设备代理在线状态
|
||||||
|
agentSessionRegistry.registerOrHeartbeat(deviceId, null, null, null);
|
||||||
Map<String, Object> pong = new HashMap<>();
|
Map<String, Object> pong = new HashMap<>();
|
||||||
pong.put("cmd", "PONG_DEVICE");
|
pong.put("cmd", "PONG_DEVICE");
|
||||||
pong.put("deviceId", deviceId);
|
pong.put("deviceId", deviceId);
|
||||||
@@ -91,6 +104,8 @@ public class DeviceWebSocketController {
|
|||||||
commandPayload.put("sentAt", System.currentTimeMillis());
|
commandPayload.put("sentAt", System.currentTimeMillis());
|
||||||
|
|
||||||
messagingTemplate.convertAndSendToUser(deviceId, "/queue/command", commandPayload);
|
messagingTemplate.convertAndSendToUser(deviceId, "/queue/command", commandPayload);
|
||||||
|
// 匿名桌面同样订阅 /topic/device/{id}/cmd
|
||||||
|
messagingTemplate.convertAndSend("/topic/device/" + deviceId + "/cmd", commandJson);
|
||||||
log.info("下发设备指令成功, deviceId={}", deviceId);
|
log.info("下发设备指令成功, deviceId={}", deviceId);
|
||||||
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
@@ -98,4 +113,87 @@ public class DeviceWebSocketController {
|
|||||||
result.put("queued", true);
|
result.put("queued", true);
|
||||||
return Result.OK(result);
|
return Result.OK(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update-begin---author:cursor ---date:2026-07-20 for:【设备库桥接】代理状态/回执/在线列表-----------
|
||||||
|
/**
|
||||||
|
* 桌面代理上报在线与设备库连通状态。
|
||||||
|
* destination: /app/device/agent/status
|
||||||
|
*/
|
||||||
|
@MessageMapping("/device/agent/status")
|
||||||
|
public void receiveAgentStatus(@org.springframework.messaging.handler.annotation.Payload(required = false) Map<String, Object> payload) {
|
||||||
|
if (payload == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String deviceId = String.valueOf(payload.getOrDefault("deviceId", "")).trim();
|
||||||
|
if (deviceId.isBlank()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String hostName = payload.get("hostName") == null ? null : String.valueOf(payload.get("hostName"));
|
||||||
|
Boolean dbConnected = null;
|
||||||
|
if (payload.get("dbConnected") instanceof Boolean) {
|
||||||
|
dbConnected = (Boolean) payload.get("dbConnected");
|
||||||
|
} else if (payload.get("dbConnected") != null) {
|
||||||
|
dbConnected = Boolean.parseBoolean(String.valueOf(payload.get("dbConnected")));
|
||||||
|
}
|
||||||
|
String dbMessage = payload.get("dbMessage") == null ? null : String.valueOf(payload.get("dbMessage"));
|
||||||
|
agentSessionRegistry.registerOrHeartbeat(deviceId, hostName, dbConnected, dbMessage);
|
||||||
|
messagingTemplate.convertAndSend("/topic/device/" + deviceId + "/status", payload);
|
||||||
|
log.debug("设备代理状态已更新 deviceId={} dbConnected={}", deviceId, dbConnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 桌面代理回传设备库命令结果。
|
||||||
|
* destination: /app/device/agent/result
|
||||||
|
*/
|
||||||
|
@MessageMapping("/device/agent/result")
|
||||||
|
public void receiveAgentResult(@org.springframework.messaging.handler.annotation.Payload(required = false) Map<String, Object> payload) {
|
||||||
|
if (payload == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DeviceAgentResult result = JSON.parseObject(JSON.toJSONString(payload), DeviceAgentResult.class);
|
||||||
|
agentCommandService.completeResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/agent/online")
|
||||||
|
public Result<List<DeviceAgentSession>> listOnlineAgents() {
|
||||||
|
return Result.OK(agentSessionRegistry.listOnline());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/agent/list")
|
||||||
|
public Result<List<DeviceAgentSession>> listAgents() {
|
||||||
|
return Result.OK(agentSessionRegistry.listAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/agent/test")
|
||||||
|
public Result<DeviceAgentResult> testAgentDb(@RequestBody(required = false) Map<String, Object> body) {
|
||||||
|
String deviceId = body == null ? null : String.valueOf(body.getOrDefault("deviceId", "")).trim();
|
||||||
|
if (deviceId == null || deviceId.isBlank()) {
|
||||||
|
DeviceAgentSession picked = agentSessionRegistry.pickOnlineAgent(null);
|
||||||
|
if (picked == null) {
|
||||||
|
return Result.error("无在线桌面代理");
|
||||||
|
}
|
||||||
|
deviceId = picked.getDeviceId();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return Result.OK(agentCommandService.test(deviceId, 10_000));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/agent/command")
|
||||||
|
public Result<DeviceAgentResult> sendAgentCommand(@RequestBody DeviceAgentCommand command) {
|
||||||
|
try {
|
||||||
|
return Result.OK(agentCommandService.sendAndWait(command));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/agent/status")
|
||||||
|
public Result<DeviceAgentSession> agentStatus(@RequestParam(name = "deviceId", required = false) String deviceId) {
|
||||||
|
DeviceAgentSession session = agentSessionRegistry.pickOnlineAgent(deviceId);
|
||||||
|
return Result.OK(session);
|
||||||
|
}
|
||||||
|
//update-end---author:cursor ---date:2026-07-20 for:【设备库桥接】代理状态/回执/在线列表-----------
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -606,3 +606,26 @@ jeecgboot-vue3/src/views/xslmes/mesXslRubberQuickTestRecord/components/MesXslRub
|
|||||||
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/im/service/impl/SysImChatServiceImpl.java
|
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/im/service/impl/SysImChatServiceImpl.java
|
||||||
jeecgboot-vue3/src/views/system/im/imCache.ts
|
jeecgboot-vue3/src/views/system/im/imCache.ts
|
||||||
jeecgboot-vue3/src/views/system/im/ImChat.vue
|
jeecgboot-vue3/src/views/system/im/ImChat.vue
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD>ϡ<EFBFBD><CFA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>༭У<E0BCAD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ψһ ---
|
||||||
|
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMixerMaterialService.java
|
||||||
|
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMixerMaterialServiceImpl.java
|
||||||
|
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMixerMaterialController.java
|
||||||
|
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMaterialService.java
|
||||||
|
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMaterialServiceImpl.java
|
||||||
|
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.api.ts
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.data.ts
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMaterial.api.ts
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϡ<EFBFBD><CFA1><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD>365<36><35> ---
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.data.ts
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><>WebSocket<65><74><EFBFBD><EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Redis<69>ذ<EFBFBD><D8B0><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---
|
||||||
|
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/websocket/WebSocket.java
|
||||||
|
jeecgboot-vue3/src/hooks/web/useWebSocket.ts
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260729--for: <20><><EFBFBD><EFBFBD><EFBFBD>ϡ<EFBFBD><CFA1>б<EFBFBD>/<2F><><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD>ֶ<EFBFBD> ---
|
||||||
|
jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts
|
||||||
|
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java
|
||||||
|
|||||||
@@ -10,11 +10,13 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
import org.jeecg.common.system.base.controller.JeecgController;
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
import org.jeecg.common.system.query.QueryGenerator;
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.jeecg.modules.mes.material.entity.MesMaterial;
|
import org.jeecg.modules.mes.material.entity.MesMaterial;
|
||||||
import org.jeecg.modules.mes.material.service.IMesMaterialService;
|
import org.jeecg.modules.mes.material.service.IMesMaterialService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -59,6 +61,12 @@ public class MesMaterialController extends JeecgController<MesMaterial, IMesMate
|
|||||||
@RequiresPermissions("mes:mes_material:add")
|
@RequiresPermissions("mes:mes_material:add")
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
public Result<String> add(@RequestBody MesMaterial model) {
|
public Result<String> add(@RequestBody MesMaterial model) {
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验-----------
|
||||||
|
String err = validateUnique(model, null);
|
||||||
|
if (err != null) {
|
||||||
|
return Result.error(err);
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验-----------
|
||||||
mesMaterialService.save(model);
|
mesMaterialService.save(model);
|
||||||
mesMaterialService.notifyMaterialChanged("material.created", model);
|
mesMaterialService.notifyMaterialChanged("material.created", model);
|
||||||
return Result.OK("添加成功!");
|
return Result.OK("添加成功!");
|
||||||
@@ -69,6 +77,12 @@ public class MesMaterialController extends JeecgController<MesMaterial, IMesMate
|
|||||||
@RequiresPermissions("mes:mes_material:edit")
|
@RequiresPermissions("mes:mes_material:edit")
|
||||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||||
public Result<String> edit(@RequestBody MesMaterial model) {
|
public Result<String> edit(@RequestBody MesMaterial model) {
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验-----------
|
||||||
|
String err = validateUnique(model, model.getId());
|
||||||
|
if (err != null) {
|
||||||
|
return Result.error(err);
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验-----------
|
||||||
mesMaterialService.updateById(model);
|
mesMaterialService.updateById(model);
|
||||||
mesMaterialService.notifyMaterialChanged("material.updated", model);
|
mesMaterialService.notifyMaterialChanged("material.updated", model);
|
||||||
return Result.OK("编辑成功!");
|
return Result.OK("编辑成功!");
|
||||||
@@ -106,6 +120,57 @@ public class MesMaterialController extends JeecgController<MesMaterial, IMesMate
|
|||||||
return Result.OK(mesMaterialService.getById(id));
|
return Result.OK(mesMaterialService.getById(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验接口-----------
|
||||||
|
@Operation(summary = "校验胶料编码是否重复")
|
||||||
|
@GetMapping("/checkMaterialCode")
|
||||||
|
public Result<String> checkMaterialCode(
|
||||||
|
@RequestParam(name = "materialCode", required = true) String materialCode,
|
||||||
|
@RequestParam(name = "dataId", required = false) String dataId) {
|
||||||
|
if (oConvertUtils.isEmpty(materialCode) || materialCode.trim().isEmpty()) {
|
||||||
|
return Result.OK("该值可用!");
|
||||||
|
}
|
||||||
|
if (mesMaterialService.isMaterialCodeDuplicated(materialCode, dataId)) {
|
||||||
|
return Result.error("胶料编码不能重复");
|
||||||
|
}
|
||||||
|
return Result.OK("该值可用!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "校验胶料名称是否重复")
|
||||||
|
@GetMapping("/checkMaterialName")
|
||||||
|
public Result<String> checkMaterialName(
|
||||||
|
@RequestParam(name = "materialName", required = true) String materialName,
|
||||||
|
@RequestParam(name = "dataId", required = false) String dataId) {
|
||||||
|
if (oConvertUtils.isEmpty(materialName) || materialName.trim().isEmpty()) {
|
||||||
|
return Result.OK("该值可用!");
|
||||||
|
}
|
||||||
|
if (mesMaterialService.isMaterialNameDuplicated(materialName, dataId)) {
|
||||||
|
return Result.error("胶料名称不能重复");
|
||||||
|
}
|
||||||
|
return Result.OK("该值可用!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String validateUnique(MesMaterial model, String excludeId) {
|
||||||
|
if (model == null) {
|
||||||
|
return "数据不能为空";
|
||||||
|
}
|
||||||
|
if (oConvertUtils.isEmpty(model.getMaterialName()) || StringUtils.isBlank(model.getMaterialName())) {
|
||||||
|
return "胶料名称不能为空";
|
||||||
|
}
|
||||||
|
model.setMaterialName(model.getMaterialName().trim());
|
||||||
|
//update-begin---author:jiangxh ---date:20260730 for:【胶料】保存时编号与名称保持一致(界面隐藏编号)-----------
|
||||||
|
// 表单/列表不展示编号,保存时自动用胶料名称回填胶料编号
|
||||||
|
model.setMaterialCode(model.getMaterialName());
|
||||||
|
//update-end---author:jiangxh ---date:20260730 for:【胶料】保存时编号与名称保持一致(界面隐藏编号)-----------
|
||||||
|
if (mesMaterialService.isMaterialNameDuplicated(model.getMaterialName(), excludeId)) {
|
||||||
|
return "胶料名称不能重复";
|
||||||
|
}
|
||||||
|
if (mesMaterialService.isMaterialCodeDuplicated(model.getMaterialCode(), excludeId)) {
|
||||||
|
return "胶料编码不能重复";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验接口-----------
|
||||||
|
|
||||||
@RequiresPermissions("mes:mes_material:exportXls")
|
@RequiresPermissions("mes:mes_material:exportXls")
|
||||||
@RequestMapping("/exportXls")
|
@RequestMapping("/exportXls")
|
||||||
public ModelAndView exportXls(HttpServletRequest request, MesMaterial model) {
|
public ModelAndView exportXls(HttpServletRequest request, MesMaterial model) {
|
||||||
|
|||||||
@@ -11,11 +11,13 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
import org.jeecg.common.system.base.controller.JeecgController;
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
import org.jeecg.common.system.query.QueryGenerator;
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.jeecg.modules.mes.material.entity.MesMixerMaterial;
|
import org.jeecg.modules.mes.material.entity.MesMixerMaterial;
|
||||||
import org.jeecg.modules.mes.material.service.IMesMixerMaterialService;
|
import org.jeecg.modules.mes.material.service.IMesMixerMaterialService;
|
||||||
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
||||||
@@ -52,6 +54,12 @@ public class MesMixerMaterialController extends JeecgController<MesMixerMaterial
|
|||||||
@RequiresPermissions("mes:mes_mixer_material:add")
|
@RequiresPermissions("mes:mes_mixer_material:add")
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
public Result<String> add(@RequestBody MesMixerMaterial model) {
|
public Result<String> add(@RequestBody MesMixerMaterial model) {
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验-----------
|
||||||
|
String err = validateUnique(model, null);
|
||||||
|
if (err != null) {
|
||||||
|
return Result.error(err);
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验-----------
|
||||||
service.save(model);
|
service.save(model);
|
||||||
publishChanged("add", model.getId());
|
publishChanged("add", model.getId());
|
||||||
return Result.OK("添加成功!");
|
return Result.OK("添加成功!");
|
||||||
@@ -62,6 +70,12 @@ public class MesMixerMaterialController extends JeecgController<MesMixerMaterial
|
|||||||
@RequiresPermissions("mes:mes_mixer_material:edit")
|
@RequiresPermissions("mes:mes_mixer_material:edit")
|
||||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||||
public Result<String> edit(@RequestBody MesMixerMaterial model) {
|
public Result<String> edit(@RequestBody MesMixerMaterial model) {
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验-----------
|
||||||
|
String err = validateUnique(model, model.getId());
|
||||||
|
if (err != null) {
|
||||||
|
return Result.error(err);
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验-----------
|
||||||
service.updateById(model);
|
service.updateById(model);
|
||||||
publishChanged("edit", model.getId());
|
publishChanged("edit", model.getId());
|
||||||
return Result.OK("编辑成功!");
|
return Result.OK("编辑成功!");
|
||||||
@@ -110,6 +124,12 @@ public class MesMixerMaterialController extends JeecgController<MesMixerMaterial
|
|||||||
@Operation(summary = "MES-密炼物料信息-免密添加")
|
@Operation(summary = "MES-密炼物料信息-免密添加")
|
||||||
@PostMapping("/anon/add")
|
@PostMapping("/anon/add")
|
||||||
public Result<String> anonAdd(@RequestBody MesMixerMaterial model) {
|
public Result<String> anonAdd(@RequestBody MesMixerMaterial model) {
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验-----------
|
||||||
|
String err = validateUnique(model, null);
|
||||||
|
if (err != null) {
|
||||||
|
return Result.error(err);
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验-----------
|
||||||
service.save(model);
|
service.save(model);
|
||||||
publishChanged("add", model.getId());
|
publishChanged("add", model.getId());
|
||||||
return Result.OK("添加成功!");
|
return Result.OK("添加成功!");
|
||||||
@@ -118,6 +138,12 @@ public class MesMixerMaterialController extends JeecgController<MesMixerMaterial
|
|||||||
@Operation(summary = "MES-密炼物料信息-免密编辑")
|
@Operation(summary = "MES-密炼物料信息-免密编辑")
|
||||||
@RequestMapping(value = "/anon/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
@RequestMapping(value = "/anon/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||||
public Result<String> anonEdit(@RequestBody MesMixerMaterial model) {
|
public Result<String> anonEdit(@RequestBody MesMixerMaterial model) {
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验-----------
|
||||||
|
String err = validateUnique(model, model.getId());
|
||||||
|
if (err != null) {
|
||||||
|
return Result.error(err);
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验-----------
|
||||||
boolean ok = service.updateById(model);
|
boolean ok = service.updateById(model);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
return Result.error("数据已被他人修改,请刷新后重试");
|
return Result.error("数据已被他人修改,请刷新后重试");
|
||||||
@@ -148,6 +174,57 @@ public class MesMixerMaterialController extends JeecgController<MesMixerMaterial
|
|||||||
return Result.OK(service.getById(id));
|
return Result.OK(service.getById(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验接口-----------
|
||||||
|
@Operation(summary = "校验物料编码是否重复")
|
||||||
|
@GetMapping("/checkMaterialCode")
|
||||||
|
public Result<String> checkMaterialCode(
|
||||||
|
@RequestParam(name = "materialCode", required = true) String materialCode,
|
||||||
|
@RequestParam(name = "dataId", required = false) String dataId) {
|
||||||
|
if (oConvertUtils.isEmpty(materialCode) || materialCode.trim().isEmpty()) {
|
||||||
|
return Result.OK("该值可用!");
|
||||||
|
}
|
||||||
|
if (service.isMaterialCodeDuplicated(materialCode, dataId)) {
|
||||||
|
return Result.error("物料编码不能重复");
|
||||||
|
}
|
||||||
|
return Result.OK("该值可用!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "校验物料名称是否重复")
|
||||||
|
@GetMapping("/checkMaterialName")
|
||||||
|
public Result<String> checkMaterialName(
|
||||||
|
@RequestParam(name = "materialName", required = true) String materialName,
|
||||||
|
@RequestParam(name = "dataId", required = false) String dataId) {
|
||||||
|
if (oConvertUtils.isEmpty(materialName) || materialName.trim().isEmpty()) {
|
||||||
|
return Result.OK("该值可用!");
|
||||||
|
}
|
||||||
|
if (service.isMaterialNameDuplicated(materialName, dataId)) {
|
||||||
|
return Result.error("物料名称不能重复");
|
||||||
|
}
|
||||||
|
return Result.OK("该值可用!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String validateUnique(MesMixerMaterial model, String excludeId) {
|
||||||
|
if (model == null) {
|
||||||
|
return "数据不能为空";
|
||||||
|
}
|
||||||
|
if (oConvertUtils.isEmpty(model.getMaterialCode()) || StringUtils.isBlank(model.getMaterialCode())) {
|
||||||
|
return "物料编码不能为空";
|
||||||
|
}
|
||||||
|
model.setMaterialCode(model.getMaterialCode().trim());
|
||||||
|
if (service.isMaterialCodeDuplicated(model.getMaterialCode(), excludeId)) {
|
||||||
|
return "物料编码不能重复";
|
||||||
|
}
|
||||||
|
if (oConvertUtils.isEmpty(model.getMaterialName()) || StringUtils.isBlank(model.getMaterialName())) {
|
||||||
|
return "物料名称不能为空";
|
||||||
|
}
|
||||||
|
model.setMaterialName(model.getMaterialName().trim());
|
||||||
|
if (service.isMaterialNameDuplicated(model.getMaterialName(), excludeId)) {
|
||||||
|
return "物料名称不能重复";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验接口-----------
|
||||||
|
|
||||||
@RequiresPermissions("mes:mes_mixer_material:exportXls")
|
@RequiresPermissions("mes:mes_mixer_material:exportXls")
|
||||||
@RequestMapping("/exportXls")
|
@RequestMapping("/exportXls")
|
||||||
public ModelAndView exportXls(HttpServletRequest request, MesMixerMaterial model) {
|
public ModelAndView exportXls(HttpServletRequest request, MesMixerMaterial model) {
|
||||||
|
|||||||
@@ -5,4 +5,10 @@ import org.jeecg.modules.mes.material.entity.MesMaterial;
|
|||||||
|
|
||||||
public interface IMesMaterialService extends IService<MesMaterial> {
|
public interface IMesMaterialService extends IService<MesMaterial> {
|
||||||
void notifyMaterialChanged(String eventType, MesMaterial material);
|
void notifyMaterialChanged(String eventType, MesMaterial material);
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验-----------
|
||||||
|
boolean isMaterialCodeDuplicated(String materialCode, String excludeId);
|
||||||
|
|
||||||
|
boolean isMaterialNameDuplicated(String materialName, String excludeId);
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验-----------
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,11 @@ package org.jeecg.modules.mes.material.service;
|
|||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import org.jeecg.modules.mes.material.entity.MesMixerMaterial;
|
import org.jeecg.modules.mes.material.entity.MesMixerMaterial;
|
||||||
|
|
||||||
public interface IMesMixerMaterialService extends IService<MesMixerMaterial> {}
|
public interface IMesMixerMaterialService extends IService<MesMixerMaterial> {
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验-----------
|
||||||
|
boolean isMaterialCodeDuplicated(String materialCode, String excludeId);
|
||||||
|
|
||||||
|
boolean isMaterialNameDuplicated(String materialName, String excludeId);
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验-----------
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package org.jeecg.modules.mes.material.service.impl;
|
package org.jeecg.modules.mes.material.service.impl;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.jeecg.modules.mes.material.entity.MesMaterial;
|
import org.jeecg.modules.mes.material.entity.MesMaterial;
|
||||||
import org.jeecg.modules.mes.material.mapper.MesMaterialMapper;
|
import org.jeecg.modules.mes.material.mapper.MesMaterialMapper;
|
||||||
import org.jeecg.modules.mes.material.service.IMesMaterialService;
|
import org.jeecg.modules.mes.material.service.IMesMaterialService;
|
||||||
@@ -25,4 +27,32 @@ public class MesMaterialServiceImpl extends ServiceImpl<MesMaterialMapper, MesMa
|
|||||||
event.put("timestamp", System.currentTimeMillis());
|
event.put("timestamp", System.currentTimeMillis());
|
||||||
webSocket.sendMessage(JSON.toJSONString(event));
|
webSocket.sendMessage(JSON.toJSONString(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验-----------
|
||||||
|
@Override
|
||||||
|
public boolean isMaterialCodeDuplicated(String materialCode, String excludeId) {
|
||||||
|
if (StringUtils.isBlank(materialCode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<MesMaterial> wrapper =
|
||||||
|
new LambdaQueryWrapper<MesMaterial>().eq(MesMaterial::getMaterialCode, materialCode.trim());
|
||||||
|
if (StringUtils.isNotBlank(excludeId)) {
|
||||||
|
wrapper.ne(MesMaterial::getId, excludeId.trim());
|
||||||
|
}
|
||||||
|
return this.count(wrapper) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMaterialNameDuplicated(String materialName, String excludeId) {
|
||||||
|
if (StringUtils.isBlank(materialName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<MesMaterial> wrapper =
|
||||||
|
new LambdaQueryWrapper<MesMaterial>().eq(MesMaterial::getMaterialName, materialName.trim());
|
||||||
|
if (StringUtils.isNotBlank(excludeId)) {
|
||||||
|
wrapper.ne(MesMaterial::getId, excludeId.trim());
|
||||||
|
}
|
||||||
|
return this.count(wrapper) > 0;
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验-----------
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.jeecg.modules.mes.material.service.impl;
|
package org.jeecg.modules.mes.material.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.jeecg.modules.mes.material.entity.MesMixerMaterial;
|
import org.jeecg.modules.mes.material.entity.MesMixerMaterial;
|
||||||
import org.jeecg.modules.mes.material.mapper.MesMixerMaterialMapper;
|
import org.jeecg.modules.mes.material.mapper.MesMixerMaterialMapper;
|
||||||
import org.jeecg.modules.mes.material.service.IMesMixerMaterialService;
|
import org.jeecg.modules.mes.material.service.IMesMixerMaterialService;
|
||||||
@@ -8,4 +10,33 @@ import org.springframework.stereotype.Service;
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class MesMixerMaterialServiceImpl extends ServiceImpl<MesMixerMaterialMapper, MesMixerMaterial>
|
public class MesMixerMaterialServiceImpl extends ServiceImpl<MesMixerMaterialMapper, MesMixerMaterial>
|
||||||
implements IMesMixerMaterialService {}
|
implements IMesMixerMaterialService {
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验-----------
|
||||||
|
@Override
|
||||||
|
public boolean isMaterialCodeDuplicated(String materialCode, String excludeId) {
|
||||||
|
if (StringUtils.isBlank(materialCode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<MesMixerMaterial> wrapper =
|
||||||
|
new LambdaQueryWrapper<MesMixerMaterial>().eq(MesMixerMaterial::getMaterialCode, materialCode.trim());
|
||||||
|
if (StringUtils.isNotBlank(excludeId)) {
|
||||||
|
wrapper.ne(MesMixerMaterial::getId, excludeId.trim());
|
||||||
|
}
|
||||||
|
return this.count(wrapper) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMaterialNameDuplicated(String materialName, String excludeId) {
|
||||||
|
if (StringUtils.isBlank(materialName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<MesMixerMaterial> wrapper =
|
||||||
|
new LambdaQueryWrapper<MesMixerMaterial>().eq(MesMixerMaterial::getMaterialName, materialName.trim());
|
||||||
|
if (StringUtils.isNotBlank(excludeId)) {
|
||||||
|
wrapper.ne(MesMixerMaterial::getId, excludeId.trim());
|
||||||
|
}
|
||||||
|
return this.count(wrapper) > 0;
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验-----------
|
||||||
|
}
|
||||||
|
|||||||
@@ -61,16 +61,30 @@ public class WebSocket {
|
|||||||
@OnOpen
|
@OnOpen
|
||||||
public void onOpen(Session session, @PathParam(value = "userId") String userId) {
|
public void onOpen(Session session, @PathParam(value = "userId") String userId) {
|
||||||
try {
|
try {
|
||||||
sessionPool.put(userId, session);
|
//update-begin---author:jiangxh ---date:20260729 for:【WebSocket】同 userId 新连接顶替旧连接,避免双连接互踢-----------
|
||||||
|
Session previous = sessionPool.put(userId, session);
|
||||||
|
if (previous != null && previous.isOpen() && !previous.getId().equals(session.getId())) {
|
||||||
|
try {
|
||||||
|
previous.close();
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【WebSocket】同 userId 新连接顶替旧连接,避免双连接互踢-----------
|
||||||
log.info("【系统 WebSocket】连接建立 userId={}, sessionId={}, online={}", userId, session.getId(), sessionPool.size());
|
log.info("【系统 WebSocket】连接建立 userId={}, sessionId={}, online={}", userId, session.getId(), sessionPool.size());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClose
|
@OnClose
|
||||||
public void onClose(@PathParam("userId") String userId) {
|
public void onClose(Session session, @PathParam("userId") String userId) {
|
||||||
try {
|
try {
|
||||||
sessionPool.remove(userId);
|
//update-begin---author:jiangxh ---date:20260729 for:【WebSocket】仅移除当前 session,避免旧连接 onClose 清掉新连接-----------
|
||||||
|
Session current = sessionPool.get(userId);
|
||||||
|
if (current != null && session != null && current.getId().equals(session.getId())) {
|
||||||
|
sessionPool.remove(userId, current);
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【WebSocket】仅移除当前 session,避免旧连接 onClose 清掉新连接-----------
|
||||||
log.info("【系统 WebSocket】连接断开 userId={}, online={}", userId, sessionPool.size());
|
log.info("【系统 WebSocket】连接断开 userId={}, online={}", userId, sessionPool.size());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -155,13 +169,24 @@ public class WebSocket {
|
|||||||
* ws接受客户端消息
|
* ws接受客户端消息
|
||||||
*/
|
*/
|
||||||
@OnMessage
|
@OnMessage
|
||||||
public void onMessage(String message, @PathParam(value = "userId") String userId) {
|
public void onMessage(String message, Session session, @PathParam(value = "userId") String userId) {
|
||||||
String normalized = message == null ? "" : message.trim();
|
String normalized = message == null ? "" : message.trim();
|
||||||
if (isHeartbeatOrBlank(normalized)) {
|
if (isHeartbeatOrBlank(normalized)) {
|
||||||
log.debug("【系统 WebSocket】收到客户端心跳/空消息:{}", normalized);
|
log.debug("【系统 WebSocket】收到客户端心跳/空消息:{}", normalized);
|
||||||
if ("ping".equalsIgnoreCase(normalized) || WebsocketConst.CMD_CHECK.equalsIgnoreCase(normalized)) {
|
if ("ping".equalsIgnoreCase(normalized) || WebsocketConst.CMD_CHECK.equalsIgnoreCase(normalized)) {
|
||||||
|
//update-begin---author:jiangxh ---date:20260729 for:【WebSocket】心跳直接回包,避免走 Redis 导致 pong 超时断线-----------
|
||||||
// 代码逻辑说明: 【issues/1161】前端websocket因心跳导致监听不起作用---
|
// 代码逻辑说明: 【issues/1161】前端websocket因心跳导致监听不起作用---
|
||||||
this.sendMessage(userId, "ping");
|
// 心跳必须同连接即时回包;走 Redis 发布订阅可能延迟/失败,触发前端 pongTimeout 断线重连
|
||||||
|
try {
|
||||||
|
if (session != null && session.isOpen()) {
|
||||||
|
synchronized (session) {
|
||||||
|
session.getBasicRemote().sendText("ping");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("【系统 WebSocket】心跳回包失败 userId={}, err={}", userId, e.getMessage());
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260729 for:【WebSocket】心跳直接回包,避免走 Redis 导致 pong 超时断线-----------
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<#if po.fieldDbType=='Blob'>
|
||||||
|
private transient java.lang.String ${po.fieldName}String;
|
||||||
|
|
||||||
|
private byte[] ${po.fieldName};
|
||||||
|
|
||||||
|
public byte[] get${po.fieldName?cap_first}(){
|
||||||
|
if(${po.fieldName}String==null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return ${po.fieldName}String.getBytes("UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String get${po.fieldName?cap_first}String(){
|
||||||
|
if(${po.fieldName}==null || ${po.fieldName}.length==0){
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return new String(${po.fieldName},"UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='switch'>
|
||||||
|
<#assign switch_extend_arr=['Y','N']>
|
||||||
|
<#if po.dictField?default("")?contains("[")>
|
||||||
|
<#assign switch_extend_arr=po.dictField?eval>
|
||||||
|
</#if>
|
||||||
|
<#list switch_extend_arr as a>
|
||||||
|
<#if a_index == 0>
|
||||||
|
<#assign switch_extend_arr1=a>
|
||||||
|
<#else>
|
||||||
|
<#assign switch_extend_arr2=a>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
@Excel(name = "${po.filedComment}", width = 15,replace = {"是_${switch_extend_arr1}","否_${switch_extend_arr2}"} )
|
||||||
|
@Schema(description = "${po.filedComment}")
|
||||||
|
private ${po.fieldType} ${po.fieldName};
|
||||||
|
<#elseif po.classType=='pca'>
|
||||||
|
@Excel(name = "${po.filedComment}", width = 15,exportConvert=true,importConvert = true )
|
||||||
|
@Schema(description = "${po.filedComment}")
|
||||||
|
private ${po.fieldType} ${po.fieldName};
|
||||||
|
|
||||||
|
public String convertis${po.fieldName?cap_first}() {
|
||||||
|
return SpringContextUtils.getBean(ProvinceCityArea.class).getText(${po.fieldName});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void convertset${po.fieldName?cap_first}(String text) {
|
||||||
|
this.${po.fieldName} = SpringContextUtils.getBean(ProvinceCityArea.class).getCode(text);
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
<#assign list_field_dictCode=', dictTable = "sys_category", dicText = "name", dicCode = "id"'>
|
||||||
|
@Excel(name = "${po.filedComment}", width = 15${list_field_dictCode})
|
||||||
|
@Schema(description = "${po.filedComment}")
|
||||||
|
private ${po.fieldType} ${po.fieldName};
|
||||||
|
<#else>
|
||||||
|
@Schema(description = "${po.filedComment}")
|
||||||
|
<#if po.fieldDbName == 'del_flag'>
|
||||||
|
@TableLogic
|
||||||
|
</#if>
|
||||||
|
private ${po.fieldType} ${po.fieldName};
|
||||||
|
</#if>
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<#if need_select_tag>
|
||||||
|
JDictSelectTag,
|
||||||
|
</#if>
|
||||||
|
<#if need_switch>
|
||||||
|
JSwitch,
|
||||||
|
</#if>
|
||||||
|
<#if need_multi>
|
||||||
|
JSelectMultiple,
|
||||||
|
</#if>
|
||||||
|
<#if need_search>
|
||||||
|
JSearchSelect,
|
||||||
|
</#if>
|
||||||
|
<#if need_popup>
|
||||||
|
JPopup,
|
||||||
|
</#if>
|
||||||
|
<#if need_popup_dict>
|
||||||
|
JPopupDict,
|
||||||
|
</#if>
|
||||||
|
<#if need_category>
|
||||||
|
JCategorySelect,
|
||||||
|
</#if>
|
||||||
|
<#if need_dept>
|
||||||
|
JSelectDept,
|
||||||
|
</#if>
|
||||||
|
<#if need_dept_user>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||||
|
JSelectUser,
|
||||||
|
<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||||
|
</#if>
|
||||||
|
<#if need_select_tree>
|
||||||
|
JTreeSelect,
|
||||||
|
</#if>
|
||||||
|
<#if need_time>
|
||||||
|
TimePicker,
|
||||||
|
</#if>
|
||||||
|
<#if need_pca>
|
||||||
|
JAreaLinkage,
|
||||||
|
</#if>
|
||||||
|
<#if need_upload>
|
||||||
|
JUpload,
|
||||||
|
</#if>
|
||||||
|
<#if need_image_upload>
|
||||||
|
JImageUpload,
|
||||||
|
</#if>
|
||||||
|
<#if need_markdown>
|
||||||
|
JMarkdownEditor,
|
||||||
|
</#if>
|
||||||
|
<#if need_editor>
|
||||||
|
JEditor,
|
||||||
|
</#if>
|
||||||
|
<#if need_checkbox>
|
||||||
|
JCheckbox,
|
||||||
|
</#if>
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||||
|
<#if po.isShow =='Y' && po.fieldName != 'id' && po.fieldName !='delFlag' && isNotPidField(tableVo, po.fieldDbName)>
|
||||||
|
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||||
|
<#assign form_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
<a-col :span="${form_span}">
|
||||||
|
<a-form-item label="${po.filedComment}" v-bind="validateInfos.${autoStringSuffixForModel(po)}" id="${formEntityName}-${autoStringSuffixForModel(po)}" name="${autoStringSuffixForModel(po)}">
|
||||||
|
<#if po.classType =='date'>
|
||||||
|
<a-date-picker placeholder="请选择${po.filedComment}" <#if po.extendParams?exists && po.extendParams.picker?exists>picker="${po.extendParams.picker}"</#if> v-model:value="formData.${po.fieldName}" value-format="YYYY-MM-DD" style="width: 100%" <#if po.readonly=='Y'>disabled</#if> allow-clear />
|
||||||
|
<#elseif po.classType =='datetime'>
|
||||||
|
<a-date-picker placeholder="请选择${po.filedComment}" v-model:value="formData.${po.fieldName}" showTime value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" <#if po.readonly=='Y'>disabled</#if> allow-clear />
|
||||||
|
<#elseif po.classType =='time'>
|
||||||
|
<#assign need_time = true>
|
||||||
|
<time-picker placeholder="请选择${po.filedComment}" value-format="HH:mm:ss" v-model:value="formData.${po.fieldName}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if> allow-clear />
|
||||||
|
<#elseif po.classType =='popup'>
|
||||||
|
<#assign need_popup = true>
|
||||||
|
<#assign sourceFields = po.dictField?default("")?trim?split(",")/>
|
||||||
|
<#assign targetFields = po.dictText?default("")?trim?split(",")/>
|
||||||
|
<j-popup
|
||||||
|
placeholder="请选择${po.filedComment}"
|
||||||
|
v-model:value="formData.${po.fieldName}"
|
||||||
|
code="${po.dictTable}"
|
||||||
|
:fieldConfig="[
|
||||||
|
<#list sourceFields as fieldName>
|
||||||
|
{ source: '${fieldName}', target: '${dashedToCamel(targetFields[fieldName_index])}' },
|
||||||
|
</#list>
|
||||||
|
]"
|
||||||
|
:multi="${po.extendParams.popupMulti?c}"
|
||||||
|
:setFieldsValue="setFieldsValue"
|
||||||
|
<#if po.readonly=='Y'>disabled</#if><#rt> allow-clear />
|
||||||
|
<#elseif po.classType =='popup_dict'>
|
||||||
|
<#assign need_popup_dict = true>
|
||||||
|
<#assign sourceFields = po.dictField?default("")?trim?split(",")/>
|
||||||
|
<#assign targetFields = po.dictText?default("")?trim?split(",")/>
|
||||||
|
<j-popup-dict
|
||||||
|
placeholder="请选择${po.filedComment}"
|
||||||
|
v-model:value="formData.${po.fieldName}"
|
||||||
|
dictCode="${po.dictTable},${po.dictText},${po.dictField}"
|
||||||
|
:multi="${po.extendParams.popupMulti?c}" <#if po.readonly=='Y'>disabled</#if> />
|
||||||
|
<#elseif po.classType =='sel_depart'>
|
||||||
|
<#assign need_dept = true>
|
||||||
|
<j-select-dept v-model:value="formData.${po.fieldName}" <#if po.extendParams?exists && po.extendParams.text?exists>labelKey="${po.extendParams.text}"</#if> <#if po.extendParams?exists && po.extendParams.store?exists>rowKey="${po.extendParams.store}"</#if> <#if po.readonly=='Y'>disabled</#if> :multiple="${po.extendParams.multi?default('true')}" checkStrictly <#if po.readonly=='Y'>disabled</#if> allow-clear />
|
||||||
|
<#elseif po.classType =='switch'>
|
||||||
|
<#assign need_switch = true>
|
||||||
|
<j-switch v-model:value="formData.${po.fieldName}" <#if po.dictField != 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch>
|
||||||
|
<#elseif po.classType =='pca'>
|
||||||
|
<#assign need_pca = true>
|
||||||
|
<j-area-linkage v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" saveCode="region" <#if po.readonly=='Y'>disabled</#if> allow-clear />
|
||||||
|
<#elseif po.classType =='markdown'>
|
||||||
|
<#assign need_markdown = true>
|
||||||
|
<j-markdown-editor v-model:value="formData.${autoStringSuffixForModel(po)}" id="${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></j-markdown-editor>
|
||||||
|
<#elseif po.classType =='password'>
|
||||||
|
<a-input-password v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if> allow-clear />
|
||||||
|
<#elseif po.classType =='sel_user'>
|
||||||
|
<#assign need_dept_user = true>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||||
|
<j-select-user v-model:value="formData.${po.fieldName}" <#if po.extendParams?exists && po.extendParams.text?exists>labelKey="${po.extendParams.text}"</#if> <#if po.extendParams?exists && po.extendParams.store?exists>rowKey="${po.extendParams.store}"</#if> <#if po.readonly=='Y'>disabled</#if> allow-clear />
|
||||||
|
<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||||
|
<#elseif po.classType =='textarea'>
|
||||||
|
<a-textarea v-model:value="formData.${autoStringSuffixForModel(po)}" :rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#elseif po.classType=='radio'>
|
||||||
|
<#assign need_select_tag = true>
|
||||||
|
<j-dict-select-tag type='radio' v-model:value="formData.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if> allow-clear />
|
||||||
|
<#elseif po.classType=='list'>
|
||||||
|
<#assign need_select_tag = true>
|
||||||
|
<j-dict-select-tag v-model:value="formData.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if> allow-clear />
|
||||||
|
<#elseif po.classType=='list_multi'>
|
||||||
|
<#assign need_multi = true>
|
||||||
|
<j-select-multiple type="${po.classType}" v-model:value="formData.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if> :triggerChange="false"/>
|
||||||
|
<#elseif po.classType=='checkbox'>
|
||||||
|
<#assign need_checkbox = true>
|
||||||
|
<j-checkbox type="${po.classType}" v-model:value="formData.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if> allow-clear />
|
||||||
|
<#elseif po.classType=='sel_search'>
|
||||||
|
<#assign need_search = true>
|
||||||
|
<j-search-select v-model:value="formData.${po.fieldName}" dict="${form_field_dictCode}" <#if po.readonly=='Y'>disabled</#if> allow-clear />
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
<#assign need_category = true>
|
||||||
|
<j-category-select v-model:value="formData.${po.fieldName}" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${dashedToCamel(po.dictText)}"</#if> <#if po.readonly=='Y'>disabled</#if> @change="(value) => handleFormChange('${po.fieldName}', value)" allow-clear />
|
||||||
|
<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
<a-input-number v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#elseif po.classType=='file'>
|
||||||
|
<#assign need_upload = true>
|
||||||
|
<j-upload v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if> <#if po.uploadnum??>:maxCount=${po.uploadnum}</#if>></j-upload>
|
||||||
|
<#elseif po.classType=='image'>
|
||||||
|
<#assign need_image_upload = true>
|
||||||
|
<j-image-upload <#if po.uploadnum??>:fileMax=${po.uploadnum}<#else>:fileMax="0"</#if> v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>></j-image-upload>
|
||||||
|
<#elseif po.classType=='umeditor'>
|
||||||
|
<#assign need_editor = true>
|
||||||
|
<j-editor v-model:value="formData.${autoStringSuffixForModel(po)}" <#if po.readonly=='Y'>disabled</#if> :autoFocus="false"/>
|
||||||
|
<#elseif po.fieldDbType=='Blob'>
|
||||||
|
<a-input v-model:value="formData.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if> allow-clear ></a-input>
|
||||||
|
<#elseif po.classType == 'sel_tree'>
|
||||||
|
<#assign need_select_tree = true>
|
||||||
|
<j-tree-select
|
||||||
|
<#if po.dictText??>
|
||||||
|
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||||
|
dict="${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}"
|
||||||
|
<#elseif po.dictText?split(',')[1]??>
|
||||||
|
pidField="${po.dictText?split(',')[1]}"
|
||||||
|
<#elseif po.dictText?split(',')[3]??>
|
||||||
|
hasChildField="${po.dictText?split(',')[3]}"
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
pidValue="${po.dictField}"
|
||||||
|
<#if po.readonly=='Y'>disabled</#if>
|
||||||
|
v-model:value="formData.${po.fieldName}"
|
||||||
|
@change="(value) => handleFormChange('${po.fieldName}', value)" allow-clear >
|
||||||
|
</j-tree-select>
|
||||||
|
<#else>
|
||||||
|
<a-input v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if> allow-clear ></a-input>
|
||||||
|
</#if>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</#if>
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<#if need_select_tag>
|
||||||
|
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_switch>
|
||||||
|
import JSwitch from '/@/components/Form/src/jeecg/components/JSwitch.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_multi>
|
||||||
|
import JSelectMultiple from '/@/components/Form/src/jeecg/components/JSelectMultiple.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_search>
|
||||||
|
import JSearchSelect from '/@/components/Form/src/jeecg/components/JSearchSelect.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_popup>
|
||||||
|
import JPopup from '/@/components/Form/src/jeecg/components/JPopup.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_popup_dict>
|
||||||
|
import JPopupDict from '/@/components/Form/src/jeecg/components/JPopupDict.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_category>
|
||||||
|
import JCategorySelect from '/@/components/Form/src/jeecg/components/JCategorySelect.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_dept>
|
||||||
|
import JSelectDept from '/@/components/Form/src/jeecg/components/JSelectDept.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_dept_user>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||||
|
import JSelectUser from '/@/components/Form/src/jeecg/components/JSelectUser.vue';
|
||||||
|
<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||||
|
</#if>
|
||||||
|
<#if need_select_tree>
|
||||||
|
import JTreeSelect from '/@/components/Form/src/jeecg/components/JTreeSelect.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_time>
|
||||||
|
import { TimePicker } from 'ant-design-vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_pca>
|
||||||
|
import JAreaLinkage from '/@/components/Form/src/jeecg/components/JAreaLinkage.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_upload>
|
||||||
|
import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_image_upload>
|
||||||
|
import JImageUpload from '/@/components/Form/src/jeecg/components/JImageUpload.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_markdown>
|
||||||
|
import JMarkdownEditor from '/@/components/Form/src/jeecg/components/JMarkdownEditor.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_editor>
|
||||||
|
import JEditor from '/@/components/Form/src/jeecg/components/JEditor.vue';
|
||||||
|
</#if>
|
||||||
|
<#if need_checkbox>
|
||||||
|
import JCheckbox from "/@/components/Form/src/jeecg/components/JCheckbox.vue";
|
||||||
|
</#if>
|
||||||
|
<#if need_range_number>
|
||||||
|
import JRangeNumber from "/@/components/Form/src/jeecg/components/JRangeNumber.vue";
|
||||||
|
</#if>
|
||||||
|
<#if is_like>
|
||||||
|
import JInput from "/@/components/Form/src/jeecg/components/JInput.vue";
|
||||||
|
</#if>
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||||
|
<#if po.isQuery=='Y' && po.fieldName !='delFlag'>
|
||||||
|
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||||
|
<#assign query_flag=true>
|
||||||
|
<#if query_field_no==2>
|
||||||
|
<template v-if="toggleSearchStatus">
|
||||||
|
</#if>
|
||||||
|
<#assign query_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
<#assign need_select_tag = true>
|
||||||
|
<#assign need_multi = true>
|
||||||
|
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign need_select_tag = true>
|
||||||
|
<#assign need_multi = true>
|
||||||
|
<#assign query_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
<#if po.queryMode=='single'>
|
||||||
|
<#if query_field_no gt 1> </#if><a-col :lg="6">
|
||||||
|
<#if query_field_no gt 1> </#if><a-form-item name="${autoStringSuffixForModel(po)}">
|
||||||
|
<#if query_field_no gt 1> </#if><template #label><span title="${po.filedComment}"><#if po.filedComment?default("")?trim?length gt 4>${po.filedComment?substring(0,4)}<#else>${po.filedComment}</#if></span></template>
|
||||||
|
<#if po.classType=='sel_search'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-search-select placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" dict="${po.dictTable},${po.dictText},${po.dictField}" allow-clear />
|
||||||
|
<#elseif po.classType=='sel_user'>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||||
|
<#if query_field_no gt 1> </#if><j-select-user placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" @change="(value)=>handleFormJoinChange('${po.fieldName}',value)" allow-clear />
|
||||||
|
<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||||
|
<#elseif po.classType=='switch'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-switch placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if> query />
|
||||||
|
<#elseif po.classType=='sel_depart'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-select-dept placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" checkStrictly allow-clear />
|
||||||
|
<#elseif po.classType=='list_multi'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-select-multiple placeholder="请选择${po.filedComment}" dictCode="${query_field_dictCode?default("")}" v-model:value="queryParam.${po.fieldName}" allow-clear />
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-category-select placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" pcode="${po.dictField?default("")}" @change="(value) => handleFormChange('${po.fieldName}', value)" allow-clear />
|
||||||
|
<#elseif po.classType=='date'>
|
||||||
|
<#if query_field_no gt 1> </#if><a-date-picker valueFormat="YYYY-MM-DD" placeholder="请选择${po.filedComment}" <#if po.extendParams?exists && po.extendParams.picker?exists>picker="${po.extendParams.picker}"</#if> v-model:value="queryParam.${po.fieldName}" allow-clear />
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
<#if query_field_no gt 1> </#if><a-date-picker showTime valueFormat="YYYY-MM-DD HH:mm:ss" placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" allow-clear />
|
||||||
|
<#elseif po.classType=='time'>
|
||||||
|
<#if query_field_no gt 1> </#if><time-picker valueFormat="HH:mm:ss" placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" allow-clear />
|
||||||
|
<#elseif po.classType=='pca'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-area-linkage v-model:value="queryParam.${po.fieldName}" placeholder="请选择${po.filedComment}" saveCode="region" @change="(value)=>handleFormJoinChange('${po.fieldName}',value)" allow-clear />
|
||||||
|
<#elseif po.classType=='sel_tree'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-tree-select v-model:value="queryParam.${po.fieldName}" placeholder="请选择${po.filedComment}" <#if po.dictText??><#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>dict="${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}" <#elseif po.dictText?split(',')[1]??>pidField:"${po.dictText?split(',')[1]}", <#elseif po.dictText?split(',')[3]??>hasChildField:"${po.dictText?split(',')[3]}"</#if> </#if>pidValue="${po.dictField}" allow-clear />
|
||||||
|
<#elseif po.classType=='popup'>
|
||||||
|
<#assign sourceFields = po.dictField?default("")?trim?split(",")/>
|
||||||
|
<#assign targetFields = po.dictText?default("")?trim?split(",")/>
|
||||||
|
<#if query_field_no gt 1> </#if><j-popup
|
||||||
|
<#if query_field_no gt 1> </#if>placeholder="请选择${po.filedComment}"
|
||||||
|
<#if query_field_no gt 1> </#if>v-model:value="queryParam.${po.fieldName}"
|
||||||
|
<#if query_field_no gt 1> </#if>code="${po.dictTable}"
|
||||||
|
<#if query_field_no gt 1> </#if>:fieldConfig="[
|
||||||
|
<#list sourceFields as fieldName>
|
||||||
|
<#if query_field_no gt 1> </#if>{ source: '${fieldName}', target: '${dashedToCamel(targetFields[fieldName_index])}' },
|
||||||
|
</#list>
|
||||||
|
<#if query_field_no gt 1> </#if>]"
|
||||||
|
<#if query_field_no gt 1> </#if>:multi="${po.extendParams.popupMulti?c}"
|
||||||
|
<#if query_field_no gt 1> </#if>:setFieldsValue="setFieldsValue" allow-clear />
|
||||||
|
<#elseif po.classType=='popup_dict'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-popup-dict
|
||||||
|
<#if query_field_no gt 1> </#if>placeholder="请选择${po.filedComment}"
|
||||||
|
<#if query_field_no gt 1> </#if>v-model:value="queryParam.${po.fieldName}"
|
||||||
|
<#if query_field_no gt 1> </#if>dictCode="${po.dictTable},${po.dictText},${po.dictField}"
|
||||||
|
<#if query_field_no gt 1> </#if>:multi="${po.extendParams.popupMulti?c}"
|
||||||
|
<#if query_field_no gt 1> </#if><#if po.readonly=='Y'>disabled</#if> />
|
||||||
|
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||||
|
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
<#if query_field_no gt 1> </#if><j-select-multiple placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" dictCode="${po.dictTable},${po.dictText},${po.dictField}" allow-clear />
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#if query_field_no gt 1> </#if><j-select-multiple placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" dictCode="${po.dictField}" allow-clear />
|
||||||
|
<#else>
|
||||||
|
<#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${po.fieldName}" allow-clear ></a-input>
|
||||||
|
</#if>
|
||||||
|
<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
<#if query_field_no gt 1> </#if><a-input-number placeholder="请输入${po.filedComment}" v-model:value="queryParam.${po.fieldName}"></a-input-number>
|
||||||
|
<#else>
|
||||||
|
<#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${autoStringSuffixForModel(po)}" allow-clear ></a-input>
|
||||||
|
</#if>
|
||||||
|
<#if query_field_no gt 1> </#if></a-form-item>
|
||||||
|
<#if query_field_no gt 1> </#if></a-col>
|
||||||
|
<#elseif po.queryMode=='like'>
|
||||||
|
<#if query_field_no gt 1> </#if><a-col :lg="6">
|
||||||
|
<#if query_field_no gt 1> </#if><a-form-item name="${autoStringSuffixForModel(po)}">
|
||||||
|
<#if query_field_no gt 1> </#if><template #label><span title="${po.filedComment}"><#if po.filedComment?default("")?trim?length gt 4>${po.filedComment?substring(0,4)}<#else>${po.filedComment}</#if></span></template>
|
||||||
|
<#if query_field_no gt 1> </#if><JInput v-model:value="queryParam.${po.fieldName}"/>
|
||||||
|
<#if query_field_no gt 1> </#if></a-form-item>
|
||||||
|
<#if query_field_no gt 1> </#if></a-col>
|
||||||
|
<#else>
|
||||||
|
<#if query_field_no gt 1> </#if><a-col :lg="6">
|
||||||
|
<#if query_field_no gt 1> </#if><a-form-item name="${autoStringSuffixForModel(po)}">
|
||||||
|
<#if query_field_no gt 1> </#if><template #label><span title="${po.filedComment}"><#if po.filedComment?default("")?trim?length gt 4>${po.filedComment?substring(0,4)}<#else>${po.filedComment}</#if></span></template>
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
<#if query_field_no gt 1> </#if><a-range-picker value-format="YYYY-MM-DD" <#if po.extendParams?exists && po.extendParams.picker?exists>picker="${po.extendParams.picker}"</#if> v-model:value="queryParam.${po.fieldName}" class="query-group-cust"/>
|
||||||
|
<#elseif po.classType=='time'>
|
||||||
|
<#if query_field_no gt 1> </#if><a-time-range-picker value-format="HH:mm:ss" v-model:value="queryParam.${po.fieldName}" class="query-group-cust" />
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
<#if query_field_no gt 1> </#if><a-range-picker showTime value-format="YYYY-MM-DD HH:mm:ss" v-model:value="queryParam.${po.fieldName}" class="query-group-cust"/>
|
||||||
|
<#else>
|
||||||
|
<#if query_field_no gt 1> </#if><JRangeNumber v-model:value="queryParam.${po.fieldName}" class="query-group-cust"></JRangeNumber>
|
||||||
|
</#if>
|
||||||
|
<#if query_field_no gt 1> </#if></a-form-item>
|
||||||
|
<#if query_field_no gt 1> </#if></a-col>
|
||||||
|
</#if>
|
||||||
|
<#assign query_field_no=query_field_no+1>
|
||||||
|
</#if>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<#-- 原生查询区域样式 -->
|
||||||
|
.jeecg-basic-table-form-container {
|
||||||
|
padding: 0;
|
||||||
|
.table-page-search-submitButtons {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.query-group-cust{
|
||||||
|
min-width: 100px !important;
|
||||||
|
}
|
||||||
|
.query-group-split-cust{
|
||||||
|
width: 30px;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center
|
||||||
|
}
|
||||||
|
.ant-form-item:not(.ant-form-item-with-help){
|
||||||
|
margin-bottom: 16px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
:deep(.ant-picker),:deep(.ant-input-number){
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<#assign sourceFields = col.dictField?default("")?trim?split(",")/>
|
||||||
|
<#assign targetFields = col.dictText?default("")?trim?split(",")/>
|
||||||
|
type: JVxeTypes.popup,
|
||||||
|
popupCode:"${col.dictTable}",
|
||||||
|
fieldConfig: [
|
||||||
|
<#list sourceFields as fieldName>
|
||||||
|
{ source: '${fieldName}', target: '${dashedToCamel(targetFields[fieldName_index])}' },
|
||||||
|
</#list>
|
||||||
|
],
|
||||||
|
props:{
|
||||||
|
multi: ${col.extendParams.popupMulti?c},
|
||||||
|
},
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<#-- 非原生查询区域样式 -->
|
||||||
|
:deep(.ant-picker),:deep(.ant-input-number){
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<#assign sourceFields = po.dictField?default("")?trim?split(",")/>
|
||||||
|
<#assign targetFields = po.dictText?default("")?trim?split(",")/>
|
||||||
|
component: 'JPopup',
|
||||||
|
componentProps: ({ formActionType }) => {
|
||||||
|
const {setFieldsValue} = formActionType;
|
||||||
|
return{
|
||||||
|
setFieldsValue:setFieldsValue,
|
||||||
|
code:"${po.dictTable}",
|
||||||
|
fieldConfig: [
|
||||||
|
<#list sourceFields as fieldName>
|
||||||
|
{ source: '${fieldName}', target: '${dashedToCamel(targetFields[fieldName_index])}' },
|
||||||
|
</#list>
|
||||||
|
],
|
||||||
|
multi:${po.extendParams.popupMulti?c}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<#list columns as po>
|
||||||
|
<#if po.isShow == 'Y'>
|
||||||
|
<#if po.fieldName != 'id'>
|
||||||
|
<#if po.defaultVal??>
|
||||||
|
<#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int">
|
||||||
|
${po.fieldName}:${po.defaultVal},
|
||||||
|
<#else>
|
||||||
|
${po.fieldName}:"${po.defaultVal}",
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<#list sub.colums as po>
|
||||||
|
<#if po.isShow == 'Y'>
|
||||||
|
<#if po.fieldName != 'id'>
|
||||||
|
<#if po.defaultVal??>
|
||||||
|
<#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int">
|
||||||
|
${po.fieldName}:${po.defaultVal},
|
||||||
|
<#else>
|
||||||
|
${po.fieldName}:"${po.defaultVal}",
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<#list columns as po>
|
||||||
|
<#if po.isShow == 'Y' && po.fieldName != 'id'>
|
||||||
|
<#if po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
${po.fieldName}: <#if po.defaultVal??>${po.defaultVal}<#else>undefined</#if>,
|
||||||
|
<#elseif po.fieldDbType=='Blob'>
|
||||||
|
${po.fieldName}String: <#if po.defaultVal??>'${po.defaultVal}'<#else>''</#if>,
|
||||||
|
<#else>
|
||||||
|
${po.fieldName}: <#if po.defaultVal??>'${po.defaultVal}'<#else>''</#if>,
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<#list columns as po>
|
||||||
|
<#if po.isShow == 'Y' && po.fieldName != 'id'>
|
||||||
|
<#if po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
${po.fieldName}: <#if po.defaultVal??>${po.defaultVal}<#else>undefined</#if>,
|
||||||
|
<#elseif po.fieldDbType=='Blob'>
|
||||||
|
${po.fieldName}String: <#if po.defaultVal??>'${po.defaultVal}'<#else>''</#if>,
|
||||||
|
<#else>
|
||||||
|
${po.fieldName}: <#if po.defaultVal??>'${po.defaultVal}'<#else>''</#if>,
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<#list sub.colums as po>
|
||||||
|
<#if po.isShow == 'Y' && po.fieldName != 'id'>
|
||||||
|
<#if po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
${po.fieldName}: <#if po.defaultVal??>${po.defaultVal}<#else>undefined</#if>,
|
||||||
|
<#elseif po.fieldDbType=='Blob'>
|
||||||
|
${po.fieldName}String: <#if po.defaultVal??>'${po.defaultVal}'<#else>''</#if>,
|
||||||
|
<#else>
|
||||||
|
${po.fieldName}: <#if po.defaultVal??>'${po.defaultVal}'<#else>''</#if>,
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
-- 注意:该页面对应的前台目录为views/${entityPackagePath}文件夹下
|
||||||
|
-- 如果你想更改到其他目录,请修改sql中component字段对应的值
|
||||||
|
|
||||||
|
<#assign mainId = "${.now?long}01">
|
||||||
|
<#assign addId = "${.now?long}02">
|
||||||
|
<#assign editId = "${.now?long}03">
|
||||||
|
<#assign delId = "${.now?long}04">
|
||||||
|
<#assign batchDelId = "${.now?long}05">
|
||||||
|
<#assign exportId = "${.now?long}06">
|
||||||
|
<#assign importId = "${.now?long}07">
|
||||||
|
|
||||||
|
-- 主菜单
|
||||||
|
INSERT INTO sys_permission(id, parent_id, name, url, component, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_route, is_leaf, keep_alive, hidden, hide_tab, description, status, del_flag, rule_flag, create_by, create_time, update_by, update_time, internal_or_external)
|
||||||
|
VALUES ('${mainId}', NULL, '${tableVo.ftlDescription}', '/${entityPackagePath}/${entityName?uncap_first}List', '${entityPackagePath}/${entityName}List', NULL, NULL, 0, NULL, '1', 0.00, 0, NULL, 1, 0, 0, 0, 0, NULL, '1', 0, 0, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0);
|
||||||
|
|
||||||
|
-- 新增
|
||||||
|
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
|
||||||
|
VALUES ('${addId}', '${mainId}', '添加${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${entityPackage}:${tableName}:add', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0);
|
||||||
|
|
||||||
|
-- 编辑
|
||||||
|
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
|
||||||
|
VALUES ('${editId}', '${mainId}', '编辑${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${entityPackage}:${tableName}:edit', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0);
|
||||||
|
|
||||||
|
-- 删除
|
||||||
|
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
|
||||||
|
VALUES ('${delId}', '${mainId}', '删除${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${entityPackage}:${tableName}:delete', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0);
|
||||||
|
|
||||||
|
-- 批量删除
|
||||||
|
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
|
||||||
|
VALUES ('${batchDelId}', '${mainId}', '批量删除${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${entityPackage}:${tableName}:deleteBatch', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0);
|
||||||
|
|
||||||
|
-- 导出excel
|
||||||
|
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
|
||||||
|
VALUES ('${exportId}', '${mainId}', '导出excel_${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${entityPackage}:${tableName}:exportXls', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0);
|
||||||
|
|
||||||
|
-- 导入excel
|
||||||
|
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
|
||||||
|
VALUES ('${importId}', '${mainId}', '导入excel_${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${entityPackage}:${tableName}:importExcel', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0);
|
||||||
|
|
||||||
|
-- 角色授权(以 admin 角色为例,role_id 可替换)
|
||||||
|
INSERT INTO sys_role_permission (id, role_id, permission_id, data_rule_ids, operate_date, operate_ip) VALUES ('${.now?long}08', 'f6817f48af4fb3af11b9e8bf182f618b', '${mainId}', NULL, '${.now?string["yyyy-MM-dd HH:mm:ss"]}', '127.0.0.1');
|
||||||
|
INSERT INTO sys_role_permission (id, role_id, permission_id, data_rule_ids, operate_date, operate_ip) VALUES ('${.now?long}09', 'f6817f48af4fb3af11b9e8bf182f618b', '${addId}', NULL, '${.now?string["yyyy-MM-dd HH:mm:ss"]}', '127.0.0.1');
|
||||||
|
INSERT INTO sys_role_permission (id, role_id, permission_id, data_rule_ids, operate_date, operate_ip) VALUES ('${.now?long}10', 'f6817f48af4fb3af11b9e8bf182f618b', '${editId}', NULL, '${.now?string["yyyy-MM-dd HH:mm:ss"]}', '127.0.0.1');
|
||||||
|
INSERT INTO sys_role_permission (id, role_id, permission_id, data_rule_ids, operate_date, operate_ip) VALUES ('${.now?long}11', 'f6817f48af4fb3af11b9e8bf182f618b', '${delId}', NULL, '${.now?string["yyyy-MM-dd HH:mm:ss"]}', '127.0.0.1');
|
||||||
|
INSERT INTO sys_role_permission (id, role_id, permission_id, data_rule_ids, operate_date, operate_ip) VALUES ('${.now?long}12', 'f6817f48af4fb3af11b9e8bf182f618b', '${batchDelId}', NULL, '${.now?string["yyyy-MM-dd HH:mm:ss"]}', '127.0.0.1');
|
||||||
|
INSERT INTO sys_role_permission (id, role_id, permission_id, data_rule_ids, operate_date, operate_ip) VALUES ('${.now?long}13', 'f6817f48af4fb3af11b9e8bf182f618b', '${exportId}', NULL, '${.now?string["yyyy-MM-dd HH:mm:ss"]}', '127.0.0.1');
|
||||||
|
INSERT INTO sys_role_permission (id, role_id, permission_id, data_rule_ids, operate_date, operate_ip) VALUES ('${.now?long}14', 'f6817f48af4fb3af11b9e8bf182f618b', '${importId}', NULL, '${.now?string["yyyy-MM-dd HH:mm:ss"]}', '127.0.0.1');
|
||||||
@@ -0,0 +1,254 @@
|
|||||||
|
<#---->
|
||||||
|
<#-- freemarker 的一些工具方法 -->
|
||||||
|
<#---->
|
||||||
|
<#-- 驼峰转其他字符 -->
|
||||||
|
<#-- @param str 待转换的文本 -->
|
||||||
|
<#-- @param character 要转换成的字符 -->
|
||||||
|
<#-- @param case 转换大小写(normal 不转换,lower 小写,upper 大写) -->
|
||||||
|
<#function camelToChar(str, character, case='normal')>
|
||||||
|
<#assign text=str?replace("([a-z])([A-Z]+)","$1${character}$2","r")/>
|
||||||
|
<#if case=="upper">
|
||||||
|
<#return text?upper_case>
|
||||||
|
<#elseif case=="lower">
|
||||||
|
<#return text?lower_case>
|
||||||
|
<#else>
|
||||||
|
<#return text>
|
||||||
|
</#if>
|
||||||
|
</#function>
|
||||||
|
<#--下划线转驼峰-->
|
||||||
|
<#function dashedToCamel(str)>
|
||||||
|
<#assign text=""/>
|
||||||
|
<#assign strlist = str?split("_")/>
|
||||||
|
<#list strlist as v>
|
||||||
|
<#assign text=text+v?cap_first/>
|
||||||
|
</#list>
|
||||||
|
<#return text?uncap_first>
|
||||||
|
</#function>
|
||||||
|
<#-- 驼峰转下划线 -->
|
||||||
|
<#function camelToDashed(str, case='lower')>
|
||||||
|
<#return camelToChar(str, "_", case)>
|
||||||
|
</#function>
|
||||||
|
<#---->
|
||||||
|
<#-- 驼峰转横线 -->
|
||||||
|
<#function camelToHorizontal(str, case='normal')>
|
||||||
|
<#return camelToChar(str, "-", case)>
|
||||||
|
</#function>
|
||||||
|
<#---->
|
||||||
|
<#-- 获取 v-model 属性 -->
|
||||||
|
<#function getVModel po,suffix="">
|
||||||
|
<#return "v-model=\"queryParam.${po.fieldName}${suffix}\"">
|
||||||
|
</#function>
|
||||||
|
<#-- 获取 placeholder 属性 -->
|
||||||
|
<#function getPlaceholder po,prefix,fillComment=true>
|
||||||
|
<#if fillComment>
|
||||||
|
<#return "placeholder=\"${prefix}${po.filedComment}\"">
|
||||||
|
<#else>
|
||||||
|
<#return "placeholder=\"${prefix}\"">
|
||||||
|
</#if>
|
||||||
|
</#function>
|
||||||
|
<#-- ** 判断某字段是否配置了校验 * -->
|
||||||
|
<#function poHasCheck po>
|
||||||
|
<#if (po.fieldValidType!'')?trim?length gt 0 || po.nullable == 'N'>
|
||||||
|
<#if po.fieldName != 'id'>
|
||||||
|
<#if po.nullable == 'N'
|
||||||
|
|| po.fieldValidType == '*'
|
||||||
|
|| po.fieldValidType == 'only'
|
||||||
|
|| po.fieldValidType == 'n6-16'
|
||||||
|
|| po.fieldValidType == '*6-16'
|
||||||
|
|| po.fieldValidType == 's6-18'
|
||||||
|
|| po.fieldValidType == 'url'
|
||||||
|
|| po.fieldValidType == 'e'
|
||||||
|
|| po.fieldValidType == 'm'
|
||||||
|
|| po.fieldValidType == 'p'
|
||||||
|
|| po.fieldValidType == 's'
|
||||||
|
|| po.fieldValidType == 'n'
|
||||||
|
|| po.fieldValidType == 'z'
|
||||||
|
|| po.fieldValidType == 'money'
|
||||||
|
|| po.fieldValidType != ''
|
||||||
|
>
|
||||||
|
<#return true>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
<#return false>
|
||||||
|
</#function>
|
||||||
|
<#-- ** 如果配置了校验就显示 validatorRules * -->
|
||||||
|
<#function autoWriteRules po>
|
||||||
|
<#if poHasCheck(po)>
|
||||||
|
<#return ", validatorRules.${po.fieldName}">
|
||||||
|
<#else>
|
||||||
|
<#return "">
|
||||||
|
</#if>
|
||||||
|
</#function>
|
||||||
|
|
||||||
|
<#-- ** 如果Blob就显示 String * -->
|
||||||
|
<#function autoStringSuffix po>
|
||||||
|
<#if po.fieldDbType=='Blob'>
|
||||||
|
<#return "'${po.fieldName}String'">
|
||||||
|
<#else>
|
||||||
|
<#return "'${po.fieldName}'">
|
||||||
|
</#if>
|
||||||
|
</#function>
|
||||||
|
|
||||||
|
<#-- ** 如果Blob就显示model方式 String * -->
|
||||||
|
<#function autoStringSuffixForModel po>
|
||||||
|
<#if po.fieldDbType=='Blob'>
|
||||||
|
<#return "${po.fieldName}String">
|
||||||
|
<#else>
|
||||||
|
<#return "${po.fieldName}">
|
||||||
|
</#if>
|
||||||
|
</#function>
|
||||||
|
|
||||||
|
<#-- ** 高级查询生成 * -->
|
||||||
|
<#function superQueryFieldList po>
|
||||||
|
<#assign superQuery_dictTable="">
|
||||||
|
<#assign superQuery_dictText="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
<#assign superQuery_dictTable="${po.dictTable}">
|
||||||
|
</#if>
|
||||||
|
<#if po.dictText?default("")?trim?length gt 1>
|
||||||
|
<#assign superQuery_dictText="${po.dictText}">
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=="popup">
|
||||||
|
<#return "{type:'${po.classType}',value:'${po.fieldName}',text:'${po.filedComment}', popup:{code:'${po.dictTable}',field:'${po.dictField?split(',')[0]}',orgFields:'${po.dictField?split(',')[0]}',destFields:'${po.dictText?split(',')[0]}'}}">
|
||||||
|
<#elseif po.classType=="sel_user" || po.classType=="sel_depart" || po.classType=="datetime" || po.classType=="date" || po.classType=="pca" || po.classType=="switch">
|
||||||
|
<#return "{type:'${po.classType}',value:'${po.fieldName}',text:'${po.filedComment}'}">
|
||||||
|
<#else>
|
||||||
|
<#if po.classType=="sel_search" || po.classType=="list_multi">
|
||||||
|
<#return "{type:'${po.classType}',value:'${po.fieldName}',text:'${po.filedComment}',dictTable:\"${superQuery_dictTable}\", dictText:'${superQuery_dictText}', dictCode:'${po.dictField}'}">
|
||||||
|
<#elseif po.dictTable?? && po.dictTable!="" && po.classType!="sel_tree" && po.classType!="cat_tree" && po.classType!="link_down">
|
||||||
|
<#return "{type:'${po.fieldDbType}',value:'${po.fieldName}',text:'${po.filedComment}',dictCode:\"${po.dictTable},${po.dictText},${po.dictField}\"}">
|
||||||
|
<#elseif po.dictField?? && po.classType!="sel_tree" && po.classType!="cat_tree" && po.classType!="link_down">
|
||||||
|
<#return "{type:'${po.fieldDbType}',value:'${po.fieldName}',text:'${po.filedComment}',dictCode:'${po.dictField}'}">
|
||||||
|
<#elseif po.fieldDbType=="Text" || po.fieldDbType=="LongText">
|
||||||
|
<#return "{type:'string',value:'${po.fieldName}',text:'${po.filedComment}'}">
|
||||||
|
<#elseif po.fieldDbType=="Blob">
|
||||||
|
<#return "{type:'byte',value:'${po.fieldName}',text:'${po.filedComment}'}">
|
||||||
|
<#elseif po.fieldDbType=="BigDecimal" || po.fieldDbType=="double">
|
||||||
|
<#return "{type:'number',value:'${po.fieldName}',text:'${po.filedComment}'}">
|
||||||
|
<#else>
|
||||||
|
<#return "{type:'${po.fieldDbType}',value:'${po.fieldName}',text:'${po.filedComment}'}">
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#function>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||||
|
<#-- ** 高级查询生成(Vue3 * -->
|
||||||
|
<#function superQueryFieldListForVue3(po,order)>
|
||||||
|
<#-- 高级查询日期格式化 -->
|
||||||
|
<#assign picker=''>
|
||||||
|
<#if po.extendParams?exists && po.extendParams.picker?exists>
|
||||||
|
<#assign picker='fieldExtendJson:"{\\"picker\\":\\"${po.extendParams.picker}\\"}",'>
|
||||||
|
</#if>
|
||||||
|
<#-- 字段展示/DB类型 -->
|
||||||
|
<#assign baseAttrs="view: '${po.classType}', type: 'string',">
|
||||||
|
<#if po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
<#assign baseAttrs="view: 'number', type: 'number',">
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#-- 特殊类型控件扩展字段 -->
|
||||||
|
<#assign extAttrs="">
|
||||||
|
<#assign dictCode="">
|
||||||
|
<#if po.dictTable?default('')?trim?length gt 1 && po.dictText?default('')?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20231228 for:fix 带条件字典存在单引号导致js编译错误---------- -->
|
||||||
|
<#assign dictCode="dictTable: \"${po.dictTable}\", dictCode: '${po.dictField}', dictText: '${po.dictText}'">
|
||||||
|
<#-- update-begin---author:chenrui ---date:20231228 for:fix 带条件字典存在单引号导致js编译错误---------- -->
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign dictCode="dictCode: '${po.dictField}'">
|
||||||
|
<#else>
|
||||||
|
<#assign dictCode="dictCode: ''">
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='checkbox' || po.classType=='radio'>
|
||||||
|
<#assign extAttrs="${dictCode},">
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
<#-- 分类字典树 -->
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240109 for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
|
||||||
|
<#assign extAttrs="pcode: '${po.dictField?default('')}',">
|
||||||
|
<#-- update-end---author:chenrui ---date:20240109 for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
|
||||||
|
<#elseif po.classType=='sel_tree'>
|
||||||
|
<#-- 自定义树 -->
|
||||||
|
<#if po.dictText??>
|
||||||
|
<#-- dictText示例:id,pid,name,has_child -->
|
||||||
|
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||||
|
<#assign extAttrs="dict: '${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}'">
|
||||||
|
<#elseif po.dictText?split(',')[1]??>
|
||||||
|
<#assign extAttrs="pidField: '${po.dictText?split(',')[1]}'">
|
||||||
|
<#elseif po.dictText?split(',')[3]??>
|
||||||
|
<#assign extAttrs="hasChildField: '${po.dictText?split(',')[3]}'">
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240109 for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
|
||||||
|
<#assign extAttrs="${extAttrs}, pidValue: '${po.dictField?default('')}',">
|
||||||
|
<#-- update-end---author:chenrui ---date:20240109 for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
|
||||||
|
<#elseif po.classType=='popup'>
|
||||||
|
<#-- popup -->
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240109 for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
|
||||||
|
<#if po.dictText?default("")?trim?length gt 1 && po.dictText?index_of(',') gt 0 && po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240109 for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
|
||||||
|
<#-- 如果有多个回填字段,找到popup字段对应的来源字段 -->
|
||||||
|
<#assign orgFieldIx=po.dictText?split(',')?seq_index_of(po.fieldDbName)>
|
||||||
|
<#assign orgField=po.dictField?split(',')[orgFieldIx]>
|
||||||
|
<#else>
|
||||||
|
<#assign orgField=po.dictField?default("")>
|
||||||
|
</#if>
|
||||||
|
<#assign extAttrs="code: '${po.dictTable?default('')}', orgFields: '${orgField}', destFields: '${po.fieldName}', popupMulti: false,">
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#return "${po.fieldName}: {title: '${po.filedComment}',order: ${order},${baseAttrs}${extAttrs}${picker}}" >
|
||||||
|
</#function>
|
||||||
|
<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||||
|
|
||||||
|
|
||||||
|
<#-- vue3 获取表单modal的宽度-->
|
||||||
|
<#function getModalWidth fieldRowNum>
|
||||||
|
<#assign modal_width = 800>
|
||||||
|
<#if fieldRowNum==2>
|
||||||
|
<#assign modal_width = 896>
|
||||||
|
<#elseif fieldRowNum==3>
|
||||||
|
<#assign modal_width = 1024>
|
||||||
|
<#elseif fieldRowNum==4>
|
||||||
|
<#assign modal_width = 1280>
|
||||||
|
</#if>
|
||||||
|
<#return modal_width>
|
||||||
|
</#function>
|
||||||
|
|
||||||
|
<#-- vue3 获取表单 colspan -->
|
||||||
|
<#function getFormSpan fieldRowNum>
|
||||||
|
<#assign form_span = 24>
|
||||||
|
<#if fieldRowNum==2>
|
||||||
|
<#assign form_span = 12>
|
||||||
|
<#elseif fieldRowNum==3>
|
||||||
|
<#assign form_span = 8>
|
||||||
|
<#elseif fieldRowNum==4>
|
||||||
|
<#assign form_span = 6>
|
||||||
|
</#if>
|
||||||
|
<#return form_span>
|
||||||
|
</#function>
|
||||||
|
|
||||||
|
<#-- vue3 native 判断字段名不是 pidField -->
|
||||||
|
<#function isNotPidField(tableVo, fieldDbName) >
|
||||||
|
<#assign flag = true>
|
||||||
|
<#if tableVo??>
|
||||||
|
<#if tableVo.extendParams??>
|
||||||
|
<#if tableVo.extendParams.pidField?default("")?trim == fieldDbName>
|
||||||
|
<#assign flag = false>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
<#return flag>
|
||||||
|
</#function>
|
||||||
|
|
||||||
|
<#-- vue3 native 获取范围字段 -->
|
||||||
|
<#function getRangeField(columns) >
|
||||||
|
<#assign rangeField = "">
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.isQuery=='Y'>
|
||||||
|
<#if po.queryMode=='group'>
|
||||||
|
<#if po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal' || po.classType=='time' || po.classType=='date' || po.classType=='datetime'>
|
||||||
|
<#assign rangeField = rangeField + "${po.fieldName},">
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#return rangeField>
|
||||||
|
</#function>
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||||
|
<#if po.fieldName != 'id'>
|
||||||
|
${po.fieldName}: [
|
||||||
|
<#assign fieldValidType = po.fieldValidType!''>
|
||||||
|
<#-- 非空校验 -->
|
||||||
|
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||||
|
{ required: true, message: '请输入${po.filedComment}!'},
|
||||||
|
<#elseif fieldValidType!=''>
|
||||||
|
{ required: false},
|
||||||
|
</#if>
|
||||||
|
<#-- 唯一校验 -->
|
||||||
|
<#if fieldValidType == 'only'>
|
||||||
|
{ validator: (rule, value, callback) => validateDuplicateValue(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}', value, this.model.id, callback)},
|
||||||
|
<#-- 6到16位数字 -->
|
||||||
|
<#elseif fieldValidType == 'n6-16'>
|
||||||
|
{ pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'},
|
||||||
|
<#-- 6到16位任意字符 -->
|
||||||
|
<#elseif fieldValidType == '*6-16'>
|
||||||
|
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||||
|
<#-- 6到18位字符串 -->
|
||||||
|
<#elseif fieldValidType == 's6-18'>
|
||||||
|
{ pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
|
||||||
|
<#-- 网址 -->
|
||||||
|
<#elseif fieldValidType == 'url'>
|
||||||
|
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||||
|
<#-- 电子邮件 -->
|
||||||
|
<#elseif fieldValidType == 'e'>
|
||||||
|
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||||
|
<#-- 手机号码 -->
|
||||||
|
<#elseif fieldValidType == 'm'>
|
||||||
|
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||||
|
<#-- 邮政编码 -->
|
||||||
|
<#elseif fieldValidType == 'p'>
|
||||||
|
{ pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||||
|
<#-- 字母 -->
|
||||||
|
<#elseif fieldValidType == 's'>
|
||||||
|
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||||
|
<#-- 数字 -->
|
||||||
|
<#elseif fieldValidType == 'n'>
|
||||||
|
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||||
|
<#-- 整数 -->
|
||||||
|
<#elseif fieldValidType == 'z'>
|
||||||
|
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||||
|
<#-- 金额 -->
|
||||||
|
<#elseif fieldValidType == 'money'>
|
||||||
|
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||||
|
<#-- 正则校验 -->
|
||||||
|
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||||
|
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||||
|
<#-- 无校验 -->
|
||||||
|
<#else>
|
||||||
|
<#t>
|
||||||
|
</#if>
|
||||||
|
],
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
validatorRules: {
|
||||||
|
<#list columns as po>
|
||||||
|
<#include "core.ftl">
|
||||||
|
</#list>
|
||||||
|
},
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<#assign fieldValidType = po.fieldValidType!''>
|
||||||
|
<#-- 非空校验 -->
|
||||||
|
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||||
|
{ required: true, message: '请输入${po.filedComment}!'}<#rt>,
|
||||||
|
<#elseif fieldValidType!=''>
|
||||||
|
{ required: false}<#rt>,
|
||||||
|
</#if>
|
||||||
|
<#-- 唯一校验 -->
|
||||||
|
<#if fieldValidType == 'only'>
|
||||||
|
{ validator: ${po.fieldName}Duplicatevalidate }<#rt>
|
||||||
|
<#-- 6到16位数字 -->
|
||||||
|
<#elseif fieldValidType == 'n6-16'>
|
||||||
|
{ pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'}<#rt>,
|
||||||
|
<#-- 6到16位任意字符 -->
|
||||||
|
<#elseif fieldValidType == '*6-16'>
|
||||||
|
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}<#rt>,
|
||||||
|
<#-- 6到18位字符串 -->
|
||||||
|
<#elseif fieldValidType == 's6-18'>
|
||||||
|
{ pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},<#rt>,
|
||||||
|
<#-- 网址 -->
|
||||||
|
<#elseif fieldValidType == 'url'>
|
||||||
|
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}<#rt>,
|
||||||
|
<#-- 电子邮件 -->
|
||||||
|
<#elseif fieldValidType == 'e'>
|
||||||
|
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}<#rt>,
|
||||||
|
<#-- 手机号码 -->
|
||||||
|
<#elseif fieldValidType == 'm'>
|
||||||
|
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}<#rt>,
|
||||||
|
<#-- 邮政编码 -->
|
||||||
|
<#elseif fieldValidType == 'p'>
|
||||||
|
{ pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'}<#rt>,
|
||||||
|
<#-- 字母 -->
|
||||||
|
<#elseif fieldValidType == 's'>
|
||||||
|
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}<#rt>,
|
||||||
|
<#-- 数字 -->
|
||||||
|
<#elseif fieldValidType == 'n'>
|
||||||
|
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}<#rt>,
|
||||||
|
<#-- 整数 -->
|
||||||
|
<#elseif fieldValidType == 'z'>
|
||||||
|
{ pattern: /^-?\d+$/, message: '请输入整数!'}<#rt>,
|
||||||
|
<#-- 金额 -->
|
||||||
|
<#elseif fieldValidType == 'money'>
|
||||||
|
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}<#rt>,
|
||||||
|
<#-- 正则校验 -->
|
||||||
|
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||||
|
{ pattern: '${fieldValidType}', message: '不符合校验规则!'}<#rt>,
|
||||||
|
<#else>
|
||||||
|
<#t>
|
||||||
|
</#if>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||||
|
${po.fieldName}: [<#include "vue3CoreNative.ftl">],
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<#if col.isShow == 'Y' && poHasCheck(col)>
|
||||||
|
validateRules: [
|
||||||
|
<#if col.fieldName != 'id'>
|
||||||
|
<#assign subFieldValidType = col.fieldValidType!''>
|
||||||
|
<#-- 非空校验 -->
|
||||||
|
<#if col.nullable == 'N' || subFieldValidType == '*'>
|
||||||
|
{ required: true, message: '${'$'}{title}不能为空' },
|
||||||
|
<#elseif subFieldValidType!=''>
|
||||||
|
{ required: false},
|
||||||
|
</#if>
|
||||||
|
<#-- 其他情况下,只要有值就被认为是正则校验 -->
|
||||||
|
<#if subFieldValidType?length gt 0>
|
||||||
|
<#assign subMessage = '格式不正确'>
|
||||||
|
<#if subFieldValidType == 'only' >
|
||||||
|
<#assign subMessage = '不能重复'>
|
||||||
|
</#if>
|
||||||
|
{ pattern: "${subFieldValidType}", message: "${'$'}{title}${subMessage}" }
|
||||||
|
<#t>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
],
|
||||||
|
</#if>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
validatorRules: {
|
||||||
|
<#list sub.colums as po>
|
||||||
|
<#include "core.ftl">
|
||||||
|
</#list>
|
||||||
|
},
|
||||||
@@ -0,0 +1,275 @@
|
|||||||
|
package ${bussiPackage}.${entityPackage}.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import ${bussiPackage}.${entityPackage}.entity.${entityName};
|
||||||
|
import ${bussiPackage}.${entityPackage}.service.I${entityName}Service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
<#assign bpm_flag=false>
|
||||||
|
<#assign has_multi_query_field=false>
|
||||||
|
<#list originalColumns as po>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')>
|
||||||
|
<#assign has_multi_query_field=true>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#assign enhanceJavaList=[]>
|
||||||
|
<#if tableVo.extendParams?? && tableVo.extendParams.enhanceJavaList??>
|
||||||
|
<#assign enhanceJavaList = tableVo.extendParams.enhanceJavaList?filter(enhance -> enhance??)>
|
||||||
|
</#if>
|
||||||
|
/**
|
||||||
|
* @Description: ${tableVo.ftlDescription}
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: ${.now?string["yyyy-MM-dd"]}
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="${tableVo.ftlDescription}")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/${entityPackagePath}/${entityName?uncap_first}")
|
||||||
|
@Slf4j
|
||||||
|
public class ${entityName}Controller extends JeecgController<${entityName}, I${entityName}Service> {
|
||||||
|
@Autowired
|
||||||
|
private I${entityName}Service ${entityName?uncap_first}Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param ${entityName?uncap_first}
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "${tableVo.ftlDescription}-分页列表查询")
|
||||||
|
@Operation(summary="${tableVo.ftlDescription}-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<${entityName}>> queryPageList(${entityName} ${entityName?uncap_first},
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
<#if enhanceJavaList?size gt 0>
|
||||||
|
<#list enhanceJavaList as enhanceJava>
|
||||||
|
<#if enhanceJava.buttonCode=='query' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
|
||||||
|
//TODO 查询前触发的方法,代码生成后,请手工实现增强类逻辑;
|
||||||
|
//${entityName?uncap_first}Service.beforeQuery()
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if has_multi_query_field>
|
||||||
|
// 自定义查询规则
|
||||||
|
Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
|
||||||
|
// 自定义多选的查询规则为:LIKE_WITH_OR
|
||||||
|
<#list originalColumns as po>
|
||||||
|
<#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')>
|
||||||
|
customeRuleMap.put("${po.fieldName}", QueryRuleEnum.LIKE_WITH_OR);
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap(),customeRuleMap);
|
||||||
|
<#else>
|
||||||
|
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap());
|
||||||
|
</#if>
|
||||||
|
Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize);
|
||||||
|
IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper);
|
||||||
|
<#if enhanceJavaList?size gt 0>
|
||||||
|
<#list enhanceJavaList as enhanceJava>
|
||||||
|
<#if enhanceJava.buttonCode=='query' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
|
||||||
|
//TODO 查询后触发的方法,代码生成后,请手工实现增强类逻辑;
|
||||||
|
//${entityName?uncap_first}Service.afterQuery()
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param ${entityName?uncap_first}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "${tableVo.ftlDescription}-添加")
|
||||||
|
@Operation(summary="${tableVo.ftlDescription}-添加")
|
||||||
|
@RequiresPermissions("${entityPackage}:${tableName}:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody ${entityName} ${entityName?uncap_first}) {
|
||||||
|
<#if enhanceJavaList?size gt 0>
|
||||||
|
<#list enhanceJavaList as enhanceJava>
|
||||||
|
<#if enhanceJava.buttonCode=='add' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
|
||||||
|
//TODO 新增前的处理方法,代码生成后,请手工实现增强类逻辑;
|
||||||
|
//${entityName?uncap_first}Service.beforeAdd()
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
<#if bpm_flag>
|
||||||
|
${entityName?uncap_first}.setBpmStatus("1");
|
||||||
|
</#if>
|
||||||
|
${entityName?uncap_first}Service.save(${entityName?uncap_first});
|
||||||
|
|
||||||
|
<#if enhanceJavaList?size gt 0>
|
||||||
|
<#list enhanceJavaList as enhanceJava>
|
||||||
|
<#if enhanceJava.buttonCode=='add' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
|
||||||
|
//TODO 新增后的处理方法,代码生成后,请手工实现增强类逻辑;
|
||||||
|
//${entityName?uncap_first}Service.afterAdd()
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param ${entityName?uncap_first}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "${tableVo.ftlDescription}-编辑")
|
||||||
|
@Operation(summary="${tableVo.ftlDescription}-编辑")
|
||||||
|
@RequiresPermissions("${entityPackage}:${tableName}:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
|
||||||
|
<#if enhanceJavaList?size gt 0>
|
||||||
|
<#list enhanceJavaList as enhanceJava>
|
||||||
|
<#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
|
||||||
|
//TODO 编辑前,代码生成后,请手工实现增强类逻辑;
|
||||||
|
//${entityName?uncap_first}Service.beforeEdit()
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
${entityName?uncap_first}Service.updateById(${entityName?uncap_first});
|
||||||
|
<#if enhanceJavaList?size gt 0>
|
||||||
|
<#list enhanceJavaList as enhanceJava>
|
||||||
|
<#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
|
||||||
|
//TODO 编辑后,代码生成后,请手工实现增强类逻辑;
|
||||||
|
//${entityName?uncap_first}Service.afterEdit()
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "${tableVo.ftlDescription}-通过id删除")
|
||||||
|
@Operation(summary="${tableVo.ftlDescription}-通过id删除")
|
||||||
|
@RequiresPermissions("${entityPackage}:${tableName}:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
${entityName?uncap_first}Service.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "${tableVo.ftlDescription}-批量删除")
|
||||||
|
@Operation(summary="${tableVo.ftlDescription}-批量删除")
|
||||||
|
@RequiresPermissions("${entityPackage}:${tableName}:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.${entityName?uncap_first}Service.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "${tableVo.ftlDescription}-通过id查询")
|
||||||
|
@Operation(summary="${tableVo.ftlDescription}-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<${entityName}> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id);
|
||||||
|
if(${entityName?uncap_first}==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(${entityName?uncap_first});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param ${entityName?uncap_first}
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("${entityPackage}:${tableName}:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) {
|
||||||
|
<#if enhanceJavaList?size gt 0>
|
||||||
|
<#list enhanceJavaList as enhanceJava>
|
||||||
|
<#if enhanceJava.buttonCode=='export' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
|
||||||
|
//TODO 导出前,代码生成后,请手工实现增强类逻辑;
|
||||||
|
//${entityName?uncap_first}Service.beforeExport()
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
return super.exportXls(request, ${entityName?uncap_first}, ${entityName}.class, "${tableVo.ftlDescription}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("${entityPackage}:${tableName}:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
<#if enhanceJavaList?size gt 0>
|
||||||
|
<#list enhanceJavaList as enhanceJava>
|
||||||
|
<#if enhanceJava.buttonCode=='import' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
|
||||||
|
//TODO 导入前,代码生成后,请手工实现增强类逻辑;
|
||||||
|
//${entityName?uncap_first}Service.beforeImport()
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
return super.importExcel(request, response, ${entityName}.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
package ${bussiPackage}.${entityPackage}.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: ${tableVo.ftlDescription}
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: ${.now?string["yyyy-MM-dd"]}
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("${tableName}")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="${tableVo.ftlDescription}")
|
||||||
|
public class ${entityName} implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']>
|
||||||
|
<#assign excel_ignore_classType_arr=['pca','switch','cat_tree']>
|
||||||
|
<#list originalColumns as po>
|
||||||
|
<#-- 生成字典Code -->
|
||||||
|
<#assign list_field_dictCode="">
|
||||||
|
<#if po.classType='sel_user'>
|
||||||
|
<#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'>
|
||||||
|
<#elseif po.classType='sel_depart'>
|
||||||
|
<#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'>
|
||||||
|
<#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'>
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'>
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign list_field_dictCode=', dicCode = "${po.dictField}"'>
|
||||||
|
</#if>
|
||||||
|
<#elseif po.classType=='sel_tree'>
|
||||||
|
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'>
|
||||||
|
<#elseif po.classType=='link_table'>
|
||||||
|
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'>
|
||||||
|
</#if>
|
||||||
|
/**${po.filedComment}*/
|
||||||
|
<#if po.fieldName == primaryKeyField>
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
<#else>
|
||||||
|
<#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'>
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
<#if !excel_ignore_arr?seq_contains("${po.fieldName}")>
|
||||||
|
@Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd")
|
||||||
|
</#if>
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd")
|
||||||
|
<#else>
|
||||||
|
<#if !excel_ignore_arr?seq_contains("${po.fieldName}")>
|
||||||
|
@Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
</#if>
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
<#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")>
|
||||||
|
@Excel(name = "${po.filedComment}", width = 15${list_field_dictCode})
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
<#if list_field_dictCode?length gt 1>
|
||||||
|
@Dict(${list_field_dictCode?substring(2)})
|
||||||
|
</#if>
|
||||||
|
<#-- <#if po.classType!='popup'>
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
@Dict(dicCode="${po.dictField}",dicText="${po.dictText}",dictTable="${po.dictTable}")
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
@Dict(dicCode="${po.dictField}")
|
||||||
|
</#if>
|
||||||
|
</#if>-->
|
||||||
|
</#if>
|
||||||
|
<#include "/common/blob.ftl">
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package ${bussiPackage}.${entityPackage}.mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import ${bussiPackage}.${entityPackage}.entity.${entityName};
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: ${tableVo.ftlDescription}
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: ${.now?string["yyyy-MM-dd"]}
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
public interface ${entityName}Mapper extends BaseMapper<${entityName}> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package ${bussiPackage}.${entityPackage}.service;
|
||||||
|
|
||||||
|
import ${bussiPackage}.${entityPackage}.entity.${entityName};
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: ${tableVo.ftlDescription}
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: ${.now?string["yyyy-MM-dd"]}
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
public interface I${entityName}Service extends IService<${entityName}> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package ${bussiPackage}.${entityPackage}.service.impl;
|
||||||
|
|
||||||
|
import ${bussiPackage}.${entityPackage}.entity.${entityName};
|
||||||
|
import ${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper;
|
||||||
|
import ${bussiPackage}.${entityPackage}.service.I${entityName}Service;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: ${tableVo.ftlDescription}
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: ${.now?string["yyyy-MM-dd"]}
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class ${entityName}ServiceImpl extends ServiceImpl<${entityName}Mapper, ${entityName}> implements I${entityName}Service {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<!--标题和返回-->
|
||||||
|
<cu-custom :bgColor="NavBarColor" isBack :backRouterName="backRouteName">
|
||||||
|
<block slot="backText">返回</block>
|
||||||
|
<block slot="content">${tableVo.ftlDescription}</block>
|
||||||
|
</cu-custom>
|
||||||
|
<!--表单区域-->
|
||||||
|
<view>
|
||||||
|
<form>
|
||||||
|
<#list columns as po><#rt/>
|
||||||
|
<#if po.fieldName !='id'><#rt/>
|
||||||
|
<#if po.classType =='date'>
|
||||||
|
<my-date label="${po.filedComment}:" fields="day" v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"></my-date>
|
||||||
|
<#elseif po.classType =='datetime'>
|
||||||
|
<my-date label="${po.filedComment}:" v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"></my-date>
|
||||||
|
<#else>
|
||||||
|
<view class="cu-form-group">
|
||||||
|
<view class="flex align-center">
|
||||||
|
<view class="title"><text space="ensp">${po.filedComment}:</text></view>
|
||||||
|
<input <#if "int,BigDecimal,double,"?contains(po.fieldDbType)>type="number"</#if> placeholder="请输入${po.filedComment}" v-model="model.${po.fieldName}"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<view class="padding">
|
||||||
|
<button class="cu-btn block bg-blue margin-tb-sm lg" @click="onSubmit">
|
||||||
|
<text v-if="loading" class="cuIcon-loading2 cuIconfont-spin"></text>提交
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</form>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import myDate from '@/components/my-componets/my-date.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "${entityName}Form",
|
||||||
|
components:{ myDate },
|
||||||
|
props:{
|
||||||
|
formData:{
|
||||||
|
type:Object,
|
||||||
|
default:()=>{},
|
||||||
|
required:false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
CustomBar: this.CustomBar,
|
||||||
|
NavBarColor: this.NavBarColor,
|
||||||
|
loading:false,
|
||||||
|
model: {},
|
||||||
|
backRouteName:'index',
|
||||||
|
url: {
|
||||||
|
queryById: "/${entityPackagePath}/${entityName?uncap_first}/queryById",
|
||||||
|
add: "/${entityPackagePath}/${entityName?uncap_first}/add",
|
||||||
|
edit: "/${entityPackagePath}/${entityName?uncap_first}/edit",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created(){
|
||||||
|
this.initFormData();
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
initFormData(){
|
||||||
|
if(this.formData){
|
||||||
|
let dataId = this.formData.dataId;
|
||||||
|
this.$http.get(this.url.queryById,{params:{id:dataId}}).then((res)=>{
|
||||||
|
if(res.data.success){
|
||||||
|
console.log("表单数据",res);
|
||||||
|
this.model = res.data.result;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSubmit() {
|
||||||
|
let myForm = {...this.model};
|
||||||
|
this.loading = true;
|
||||||
|
let url = myForm.id?this.url.edit:this.url.add;
|
||||||
|
this.$http.post(url,myForm).then(res=>{
|
||||||
|
console.log("res",res)
|
||||||
|
this.loading = false
|
||||||
|
this.$Router.push({name:this.backRouteName})
|
||||||
|
}).catch(()=>{
|
||||||
|
this.loading = false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<!--标题和返回-->
|
||||||
|
<cu-custom :bgColor="NavBarColor" isBack>
|
||||||
|
<block slot="backText">返回</block>
|
||||||
|
<block slot="content">${tableVo.ftlDescription}</block>
|
||||||
|
</cu-custom>
|
||||||
|
<!--滚动加载列表-->
|
||||||
|
<mescroll-body ref="mescrollRef" bottom="88" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" @up="upCallback">
|
||||||
|
<view class="cu-list menu">
|
||||||
|
<view class="cu-item" v-for="(item,index) in list" :key="index" @click="goHome">
|
||||||
|
<view class="flex" style="width:100%">
|
||||||
|
<text class="text-lg" style="color: #000;">
|
||||||
|
{{ item.createBy}}
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</mescroll-body>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
|
||||||
|
import Mixin from "@/common/mixin/Mixin.js";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: '${tableVo.ftlDescription}',
|
||||||
|
mixins: [MescrollMixin,Mixin],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
CustomBar:this.CustomBar,
|
||||||
|
NavBarColor:this.NavBarColor,
|
||||||
|
url: "/${entityPackagePath}/${entityName?uncap_first}/list",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
goHome(){
|
||||||
|
this.$Router.push({name: "index"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { render } from '@/common/renderUtils';
|
||||||
|
//列表数据
|
||||||
|
export const columns = [
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'>
|
||||||
|
{
|
||||||
|
title: '${po.filedComment}',
|
||||||
|
align:"center",
|
||||||
|
<#if po.sort=='Y'>
|
||||||
|
sorter: true,
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#elseif po.fieldDbType=='Blob'>
|
||||||
|
dataIndex: '${po.fieldName}String'
|
||||||
|
<#elseif po.classType=='umeditor'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#elseif po.classType=='pca'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#elseif po.classType=='file'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#elseif po.classType=='image'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
customRender:render.renderImage,
|
||||||
|
<#elseif po.classType=='switch'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#assign switch_extend_arr=['Y','N']>
|
||||||
|
<#if po.dictField?default("")?contains("[")>
|
||||||
|
<#assign switch_extend_arr=po.dictField?eval>
|
||||||
|
</#if>
|
||||||
|
<#list switch_extend_arr as a>
|
||||||
|
<#if a_index == 0>
|
||||||
|
<#assign switch_extend_arr1=a>
|
||||||
|
<#else>
|
||||||
|
<#assign switch_extend_arr2=a>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
customRender:({text}) => {
|
||||||
|
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||||
|
},
|
||||||
|
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='popup_dict'>
|
||||||
|
dataIndex: '${po.fieldName}_dictText'
|
||||||
|
<#else>
|
||||||
|
dataIndex: '${po.fieldName}'
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
];
|
||||||
@@ -0,0 +1,560 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom',
|
||||||
|
navigationBarTitleText: '${tableVo.ftlDescription}',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
<template>
|
||||||
|
<#assign onlyFields = []>
|
||||||
|
<PageLayout :navTitle="navTitle" :backRouteName="backRouteName">
|
||||||
|
<scroll-view class="scrollArea" scroll-y>
|
||||||
|
<view class="form-container">
|
||||||
|
<wd-form ref="form" :model="myFormData">
|
||||||
|
<wd-cell-group border>
|
||||||
|
<#list columns as po><#rt/>
|
||||||
|
<#assign form_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
<view class="{ 'mt-14px': ${po_index % 2} == 0 }">
|
||||||
|
<#if po.fieldName !='id' && po.isShow =='Y' && po.fieldName !='delFlag'><#rt/>
|
||||||
|
<#if po.classType =='image'>
|
||||||
|
<!-- 图片 -->
|
||||||
|
<wd-cell
|
||||||
|
:title="get4Label('${po.filedComment}')"
|
||||||
|
title-width="100px"
|
||||||
|
<#if po.nullable == 'N'>
|
||||||
|
:required="true"
|
||||||
|
</#if>
|
||||||
|
>
|
||||||
|
<online-image
|
||||||
|
v-model:value="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
<#if po.uploadnum??>
|
||||||
|
:maxNum="${po.uploadnum}"
|
||||||
|
</#if>
|
||||||
|
/>
|
||||||
|
</wd-cell>
|
||||||
|
<#elseif po.classType =='file'>
|
||||||
|
<wd-cell
|
||||||
|
:title="get4Label('${po.filedComment}')"
|
||||||
|
title-width="100px"
|
||||||
|
<#if po.nullable == 'N'>
|
||||||
|
:required="true"
|
||||||
|
</#if>
|
||||||
|
>
|
||||||
|
|
||||||
|
<online-file-custom
|
||||||
|
v-model:value="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
></online-file-custom>
|
||||||
|
</wd-cell>
|
||||||
|
<#elseif po.classType =='datetime' || po.classType =='time'>
|
||||||
|
<DateTime
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
labelWidth="100px"
|
||||||
|
type="${po.classType}"
|
||||||
|
<#if po.classType =='datetime'>
|
||||||
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
<#else>
|
||||||
|
format="HH:mm:ss"
|
||||||
|
</#if>
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
></DateTime>
|
||||||
|
<#elseif po.classType =='date'>
|
||||||
|
<online-date
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
labelWidth="100px"
|
||||||
|
<#if po.extendParams?exists && po.extendParams.picker?exists>
|
||||||
|
:type="getDateExtendType('${po.extendParams.picker}')"
|
||||||
|
<#else>
|
||||||
|
type="${po.classType}"
|
||||||
|
</#if>
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
v-model:value="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
></online-date>
|
||||||
|
<#elseif po.classType =='switch'>
|
||||||
|
<#assign switch_extend_arr=['Y','N']>
|
||||||
|
<#if po.dictField?default("")?contains("[")>
|
||||||
|
<#assign switch_extend_arr=po.dictField?eval>
|
||||||
|
</#if>
|
||||||
|
<!-- 开关 -->
|
||||||
|
<wd-cell
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
title-width="100px"
|
||||||
|
center
|
||||||
|
>
|
||||||
|
<wd-switch
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
size="18px"
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
active-value="${switch_extend_arr[0]}"
|
||||||
|
inactive-value="${switch_extend_arr[1]}"
|
||||||
|
/>
|
||||||
|
</wd-cell>
|
||||||
|
<#elseif po.classType =='list' || po.classType =='sel_search'>
|
||||||
|
<online-select
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
labelWidth="100px"
|
||||||
|
type="${po.classType}"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
dict="${form_field_dictCode}"
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
></online-select>
|
||||||
|
<#elseif po.classType =='checkbox'>
|
||||||
|
<online-checkbox
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
labelWidth="100px"
|
||||||
|
type="${po.classType}"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
dict="${form_field_dictCode}"
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
></online-checkbox>
|
||||||
|
<#elseif po.classType =='radio'>
|
||||||
|
<online-radio
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
labelWidth="100px"
|
||||||
|
type="${po.classType}"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
dict="${form_field_dictCode}"
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
></online-radio>
|
||||||
|
<#elseif po.classType =='list_multi'>
|
||||||
|
<online-multi
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
labelWidth="100px"
|
||||||
|
type="${po.classType}"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
dict="${form_field_dictCode}"
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
></online-multi>
|
||||||
|
<#elseif po.classType =='textarea' || po.classType =='markdown' || po.classType =='umeditor'>
|
||||||
|
<wd-textarea
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
labelWidth="100px"
|
||||||
|
type="${po.classType}"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
prop=${autoStringSuffix(po)}
|
||||||
|
clearable
|
||||||
|
:maxlength="300"
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
></wd-textarea>
|
||||||
|
<#elseif po.classType =='password'>
|
||||||
|
<wd-input
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
labelWidth="100px"
|
||||||
|
show-password
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
prop=${autoStringSuffix(po)}
|
||||||
|
clearable
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
></wd-input>
|
||||||
|
<#elseif po.classType =='pca'>
|
||||||
|
<online-pca
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
labelWidth="100px"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
prop=${autoStringSuffix(po)}
|
||||||
|
clearable
|
||||||
|
v-model:value="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
></online-pca>
|
||||||
|
<#elseif po.classType =='popup_dict'>
|
||||||
|
<PopupDict
|
||||||
|
labelWidth="100px"
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
:multi="${po.extendParams.popupMulti?c}"
|
||||||
|
dictCode="${po.dictTable},${po.dictText},${po.dictField}"
|
||||||
|
></PopupDict>
|
||||||
|
<#elseif po.classType =='popup'>
|
||||||
|
<#assign sourceFields = po.dictField?default("")?trim?split(",")/>
|
||||||
|
<#assign targetFields = po.dictText?default("")?trim?split(",")/>
|
||||||
|
<Popup
|
||||||
|
labelWidth="100px"
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
:multi="${po.extendParams.popupMulti?c}"
|
||||||
|
code="${po.dictTable}"
|
||||||
|
:setFieldsValue="setFieldsValue"
|
||||||
|
:fieldConfig="[
|
||||||
|
<#list sourceFields as fieldName>
|
||||||
|
{ source: '${fieldName}', target: '${dashedToCamel(targetFields[fieldName_index])}' },
|
||||||
|
</#list>
|
||||||
|
]"
|
||||||
|
></Popup>
|
||||||
|
<#elseif po.classType =='link_table'>
|
||||||
|
<online-popup-link-record
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
labelWidth="100px"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
:formSchema="getFormSchema('${po.dictTable}','${po.dictField}','${po.dictText}')"
|
||||||
|
v-model:value="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
></online-popup-link-record>
|
||||||
|
<#elseif po.classType =='sel_user'>
|
||||||
|
<select-user
|
||||||
|
labelWidth="100px"
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
<#if po.extendParams?exists && po.extendParams.text?exists>labelKey="${po.extendParams.text}"</#if>
|
||||||
|
<#if po.extendParams?exists && po.extendParams.store?exists>rowKey="${po.extendParams.store}"</#if>
|
||||||
|
></select-user>
|
||||||
|
<#elseif po.classType =='sel_depart'>
|
||||||
|
<select-dept
|
||||||
|
labelWidth="100px"
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
<#if po.extendParams?exists && po.extendParams.text?exists>labelKey="${po.extendParams.text}"</#if>
|
||||||
|
<#if po.extendParams?exists && po.extendParams.store?exists>rowKey="${po.extendParams.store}"</#if>
|
||||||
|
:multiple="${po.extendParams.multi?default('true')}"
|
||||||
|
></select-dept>
|
||||||
|
<#elseif po.classType =='cat_tree'>
|
||||||
|
<CategorySelect
|
||||||
|
labelWidth="100px"
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
pcode="${po.dictField?default("")}"
|
||||||
|
></CategorySelect>
|
||||||
|
<#elseif po.classType =='sel_tree'>
|
||||||
|
<TreeSelect
|
||||||
|
labelWidth="100px"
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
<#if po.dictText??>
|
||||||
|
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||||
|
dict="${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}"
|
||||||
|
<#elseif po.dictText?split(',')[1]??>
|
||||||
|
pidField="${po.dictText?split(',')[1]}"
|
||||||
|
<#elseif po.dictText?split(',')[3]??>
|
||||||
|
hasChildField="${po.dictText?split(',')[3]}"
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
:pidValue="`${po.dictField}`"
|
||||||
|
></TreeSelect>
|
||||||
|
<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
<wd-input
|
||||||
|
label-width="100px"
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
prop=${autoStringSuffix(po)}
|
||||||
|
placeholder="请选择${po.filedComment}"
|
||||||
|
inputMode="numeric"
|
||||||
|
:rules="[
|
||||||
|
<#if po.fieldName != 'id'>
|
||||||
|
<#assign fieldValidType = po.fieldValidType!''>
|
||||||
|
<#-- 非空校验 -->
|
||||||
|
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||||
|
{ required: true, message: '请输入${po.filedComment}!'},
|
||||||
|
<#elseif fieldValidType!=''>
|
||||||
|
{ required: false},
|
||||||
|
</#if>
|
||||||
|
<#-- 6到16位数字 -->
|
||||||
|
<#if fieldValidType == 'n6-16'>
|
||||||
|
{ pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'},
|
||||||
|
<#-- 6到16位任意字符 -->
|
||||||
|
<#elseif fieldValidType == '*6-16'>
|
||||||
|
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||||
|
<#-- 6到18位字母 -->
|
||||||
|
<#elseif fieldValidType == 's6-18'>
|
||||||
|
{ pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
|
||||||
|
<#-- 网址 -->
|
||||||
|
<#elseif fieldValidType == 'url'>
|
||||||
|
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||||
|
<#-- 电子邮件 -->
|
||||||
|
<#elseif fieldValidType == 'e'>
|
||||||
|
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||||
|
<#-- 手机号码 -->
|
||||||
|
<#elseif fieldValidType == 'm'>
|
||||||
|
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||||
|
<#-- 邮政编码 -->
|
||||||
|
<#elseif fieldValidType == 'p'>
|
||||||
|
{ pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||||
|
<#-- 字母 -->
|
||||||
|
<#elseif fieldValidType == 's'>
|
||||||
|
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||||
|
<#-- 数字 -->
|
||||||
|
<#elseif fieldValidType == 'n'>
|
||||||
|
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||||
|
<#-- 整数 -->
|
||||||
|
<#elseif fieldValidType == 'z'>
|
||||||
|
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||||
|
<#-- 金额 -->
|
||||||
|
<#elseif fieldValidType == 'money'>
|
||||||
|
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||||
|
<#-- 唯一校验 -->
|
||||||
|
<#elseif fieldValidType != '' && fieldValidType == 'only'>
|
||||||
|
<#assign onlyFields = onlyFields + [autoStringSuffix(po)]>
|
||||||
|
<#-- 正则校验 -->
|
||||||
|
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||||
|
{ pattern: /${fieldValidType}/, message: '不符合校验规则!'},
|
||||||
|
<#-- 无校验 -->
|
||||||
|
<#else>
|
||||||
|
<#t>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
]"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
<#else>
|
||||||
|
<wd-input
|
||||||
|
label-width="100px"
|
||||||
|
v-model="myFormData[${autoStringSuffix(po)}]"
|
||||||
|
:label="get4Label('${po.filedComment}')"
|
||||||
|
name=${autoStringSuffix(po)}
|
||||||
|
prop=${autoStringSuffix(po)}
|
||||||
|
placeholder="请选择${po.filedComment}"
|
||||||
|
:rules="[
|
||||||
|
<#if po.fieldName != 'id'>
|
||||||
|
<#assign fieldValidType = po.fieldValidType!''>
|
||||||
|
<#-- 非空校验 -->
|
||||||
|
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||||
|
{ required: true, message: '请输入${po.filedComment}!'},
|
||||||
|
<#elseif fieldValidType!=''>
|
||||||
|
{ required: false},
|
||||||
|
</#if>
|
||||||
|
<#-- 6到16位数字 -->
|
||||||
|
<#if fieldValidType == 'n6-16'>
|
||||||
|
{ pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'},
|
||||||
|
<#-- 6到16位任意字符 -->
|
||||||
|
<#elseif fieldValidType == '*6-16'>
|
||||||
|
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||||
|
<#-- 6到18位字母 -->
|
||||||
|
<#elseif fieldValidType == 's6-18'>
|
||||||
|
{ pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
|
||||||
|
<#-- 网址 -->
|
||||||
|
<#elseif fieldValidType == 'url'>
|
||||||
|
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||||
|
<#-- 电子邮件 -->
|
||||||
|
<#elseif fieldValidType == 'e'>
|
||||||
|
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||||
|
<#-- 手机号码 -->
|
||||||
|
<#elseif fieldValidType == 'm'>
|
||||||
|
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||||
|
<#-- 邮政编码 -->
|
||||||
|
<#elseif fieldValidType == 'p'>
|
||||||
|
{ pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||||
|
<#-- 字母 -->
|
||||||
|
<#elseif fieldValidType == 's'>
|
||||||
|
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||||
|
<#-- 数字 -->
|
||||||
|
<#elseif fieldValidType == 'n'>
|
||||||
|
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||||
|
<#-- 整数 -->
|
||||||
|
<#elseif fieldValidType == 'z'>
|
||||||
|
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||||
|
<#-- 金额 -->
|
||||||
|
<#elseif fieldValidType == 'money'>
|
||||||
|
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||||
|
<#-- 唯一校验 -->
|
||||||
|
<#elseif fieldValidType != '' && fieldValidType == 'only'>
|
||||||
|
<#assign onlyFields = onlyFields + [autoStringSuffix(po)]>
|
||||||
|
<#-- 正则校验 -->
|
||||||
|
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||||
|
{ pattern: /${fieldValidType}/, message: '不符合校验规则!'},
|
||||||
|
<#-- 无校验 -->
|
||||||
|
<#else>
|
||||||
|
<#t>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
]"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</view>
|
||||||
|
</#list>
|
||||||
|
</wd-cell-group>
|
||||||
|
</wd-form>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view class="footer">
|
||||||
|
<wd-button :disabled="loading" block :loading="loading" @click="handleSubmit">提交</wd-button>
|
||||||
|
</view>
|
||||||
|
</PageLayout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { http } from '@/utils/http'
|
||||||
|
import { useToast } from 'wot-design-uni'
|
||||||
|
import { useRouter } from '@/plugin/uni-mini-router'
|
||||||
|
import { ref, onMounted, computed,reactive } from 'vue'
|
||||||
|
import OnlineImage from '@/components/online/view/online-image.vue'
|
||||||
|
import OnlineFile from '@/components/online/view/online-file.vue'
|
||||||
|
import OnlineFileCustom from '@/components/online/view/online-file-custom.vue'
|
||||||
|
import OnlineSelect from '@/components/online/view/online-select.vue'
|
||||||
|
import OnlineTime from '@/components/online/view/online-time.vue'
|
||||||
|
import OnlineDate from '@/components/online/view/online-date.vue'
|
||||||
|
import OnlineRadio from '@/components/online/view/online-radio.vue'
|
||||||
|
import OnlineCheckbox from '@/components/online/view/online-checkbox.vue'
|
||||||
|
import OnlineMulti from '@/components/online/view/online-multi.vue'
|
||||||
|
import OnlinePopupLinkRecord from '@/components/online/view/online-popup-link-record.vue'
|
||||||
|
import OnlinePca from '@/components/online/view/online-pca.vue'
|
||||||
|
import SelectDept from '@/components/SelectDept/SelectDept.vue'
|
||||||
|
import SelectUser from '@/components/SelectUser/SelectUser.vue'
|
||||||
|
import {duplicateCheck} from "@/service/api";
|
||||||
|
defineOptions({
|
||||||
|
name: '${entityName}Form',
|
||||||
|
options: {
|
||||||
|
styleIsolation: 'shared',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const toast = useToast()
|
||||||
|
const router = useRouter()
|
||||||
|
const form = ref(null)
|
||||||
|
// 定义响应式数据
|
||||||
|
const myFormData = reactive({})
|
||||||
|
const loading = ref(false)
|
||||||
|
const navTitle = ref('新增')
|
||||||
|
const dataId = ref('')
|
||||||
|
const backRouteName = ref('${entityName}List')
|
||||||
|
// 定义 initForm 方法
|
||||||
|
const initForm = (item) => {
|
||||||
|
console.log('initForm item', item)
|
||||||
|
if(item?.dataId){
|
||||||
|
dataId.value = item.dataId;
|
||||||
|
navTitle.value = item.dataId?'编辑':'新增';
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 初始化数据
|
||||||
|
const initData = () => {
|
||||||
|
http.get("/${entityPackagePath}/${entityName?uncap_first}/queryById",{id:dataId.value}).then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
let obj = res.result
|
||||||
|
Object.assign(myFormData, { ...obj })
|
||||||
|
}else{
|
||||||
|
toast.error(res?.message || '表单加载失败!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const handleSuccess = () => {
|
||||||
|
uni.$emit('refreshList');
|
||||||
|
router.back()
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 校验唯一
|
||||||
|
* @param values
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
async function fieldCheck(values: any) {
|
||||||
|
const onlyField = [
|
||||||
|
<#list onlyFields as field>
|
||||||
|
${field}<#sep>, </#sep>
|
||||||
|
</#list>
|
||||||
|
];
|
||||||
|
for (const field of onlyField) {
|
||||||
|
if (values[field]) {
|
||||||
|
// 仅校验有值的字段
|
||||||
|
const res: any = await duplicateCheck({
|
||||||
|
tableName: '${tableName}',
|
||||||
|
fieldName: field, // 使用处理后的字段名
|
||||||
|
fieldVal: values[field],
|
||||||
|
dataId: values.id,
|
||||||
|
});
|
||||||
|
if (!res.success) {
|
||||||
|
toast.warning(res.message);
|
||||||
|
return true; // 校验失败
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false; // 校验通过
|
||||||
|
}
|
||||||
|
// 提交表单
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
// 判断字段必填和正则
|
||||||
|
if (await fieldCheck(myFormData)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let url = dataId.value?'/${entityPackagePath}/${entityName?uncap_first}/edit':'/${entityPackagePath}/${entityName?uncap_first}/add';
|
||||||
|
form.value
|
||||||
|
.validate()
|
||||||
|
.then(({ valid, errors }) => {
|
||||||
|
if (valid) {
|
||||||
|
loading.value = true;
|
||||||
|
http.post(url,myFormData).then((res) => {
|
||||||
|
loading.value = false;
|
||||||
|
if (res.success) {
|
||||||
|
toast.success('保存成功');
|
||||||
|
handleSuccess()
|
||||||
|
}else{
|
||||||
|
toast.error(res?.message || '表单保存失败!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error, 'error')
|
||||||
|
loading.value = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 标题
|
||||||
|
const get4Label = computed(() => {
|
||||||
|
return (label) => {
|
||||||
|
return label && label.length > 4 ? label.substring(0, 4) : label;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 标题
|
||||||
|
const getFormSchema = computed(() => {
|
||||||
|
return (dictTable,dictCode,dictText) => {
|
||||||
|
return {
|
||||||
|
dictCode,
|
||||||
|
dictTable,
|
||||||
|
dictText
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* 获取日期控件的扩展类型
|
||||||
|
* @param picker
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
const getDateExtendType = (picker: string) => {
|
||||||
|
let mapField = {
|
||||||
|
month: 'year-month',
|
||||||
|
year: 'year',
|
||||||
|
quarter: 'quarter',
|
||||||
|
week: 'week',
|
||||||
|
day: 'date',
|
||||||
|
}
|
||||||
|
return picker && mapField[picker]
|
||||||
|
? mapField[picker]
|
||||||
|
: 'date'
|
||||||
|
}
|
||||||
|
//设置pop返回值
|
||||||
|
const setFieldsValue = (data) => {
|
||||||
|
Object.assign(myFormData, {...data })
|
||||||
|
}
|
||||||
|
// onLoad 生命周期钩子
|
||||||
|
onLoad((option) => {
|
||||||
|
initForm(option)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.footer {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 20px;
|
||||||
|
padding-bottom: calc(constant(safe-area-inset-bottom) + 10px);
|
||||||
|
padding-bottom: calc(env(safe-area-inset-bottom) + 10px);
|
||||||
|
}
|
||||||
|
:deep(.wd-cell__label) {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
:deep(.wd-cell__value) {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationBarTitleText: '${tableVo.ftlDescription}',
|
||||||
|
navigationStyle: 'custom',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
<template>
|
||||||
|
<PageLayout navTitle="${tableVo.ftlDescription}" backRouteName="index" routeMethod="pushTab">
|
||||||
|
<view class="wrap">
|
||||||
|
<z-paging
|
||||||
|
ref="paging"
|
||||||
|
:fixed="false"
|
||||||
|
v-model="dataList"
|
||||||
|
@query="queryList"
|
||||||
|
:default-page-size="15"
|
||||||
|
>
|
||||||
|
<template v-for="item in dataList" :key="item.id">
|
||||||
|
<wd-swipe-action>
|
||||||
|
<view class="list" @click="handleEdit(item)">
|
||||||
|
<template v-for="(cItem, cIndex) in columns" :key="cIndex">
|
||||||
|
<view v-if="cIndex < 3" class="box" :style="getBoxStyle">
|
||||||
|
<view class="field ellipsis">{{ cItem.title }}</view>
|
||||||
|
<view class="value cu-text-grey">{{ item[cItem.dataIndex] }}</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
<template #right>
|
||||||
|
<view class="action">
|
||||||
|
<view class="button" @click="handleAction('del', item)">删除</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</wd-swipe-action>
|
||||||
|
</template>
|
||||||
|
</z-paging>
|
||||||
|
<view class="add u-iconfont u-icon-add" @click="handleAdd"></view>
|
||||||
|
</view>
|
||||||
|
</PageLayout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted, computed } from 'vue'
|
||||||
|
import { http } from '@/utils/http'
|
||||||
|
import usePageList from '@/hooks/usePageList'
|
||||||
|
import {columns} from './${entityName}Data';
|
||||||
|
defineOptions({
|
||||||
|
name: '${entityName}List',
|
||||||
|
options: {
|
||||||
|
styleIsolation: 'shared',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//分页加载配置
|
||||||
|
let { toast, router, paging, dataList, queryList } = usePageList('/${entityPackagePath}/${entityName?uncap_first}/list');
|
||||||
|
|
||||||
|
//样式
|
||||||
|
const getBoxStyle = computed(() => {
|
||||||
|
return { width: "calc(33% - 5px)" }
|
||||||
|
})
|
||||||
|
|
||||||
|
// 其他操作
|
||||||
|
const handleAction = (val, item) => {
|
||||||
|
if (val == 'del') {
|
||||||
|
http.delete("/${entityPackagePath}/${entityName?uncap_first}/delete?id="+item.id,{id:item.id}).then((res) => {
|
||||||
|
toast.success('删除成功~')
|
||||||
|
paging.value.reload()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// go 新增页
|
||||||
|
const handleAdd = () => {
|
||||||
|
router.push({
|
||||||
|
name: '${entityName}Form'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//go 编辑页
|
||||||
|
const handleEdit = (record) => {
|
||||||
|
router.push({
|
||||||
|
name: '${entityName}Form',
|
||||||
|
params: {dataId: record.id},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 监听刷新列表事件
|
||||||
|
uni.$on('refreshList', () => {
|
||||||
|
queryList(1,10)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.wrap {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
:deep(.wd-swipe-action) {
|
||||||
|
margin-top: 10px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
.list {
|
||||||
|
padding: 10px 10px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
.box {
|
||||||
|
width: 33%;
|
||||||
|
.field {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.action {
|
||||||
|
width: 60px;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
color: #fff;
|
||||||
|
&:first-child {
|
||||||
|
background-color: #fa4350;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.add {
|
||||||
|
height: 70upx;
|
||||||
|
width: 70upx;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 70upx;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 80upx;
|
||||||
|
right: 30upx;
|
||||||
|
box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.1);
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,426 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<template>
|
||||||
|
<a-card :bordered="false">
|
||||||
|
<!-- 查询区域 -->
|
||||||
|
<div class="table-page-search-wrapper">
|
||||||
|
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<#assign query_field_no=0>
|
||||||
|
<#assign query_flag=false>
|
||||||
|
<#assign list_need_dict=false>
|
||||||
|
<#assign list_need_category=false>
|
||||||
|
<#assign list_need_pca=false>
|
||||||
|
<#assign list_need_switch=false>
|
||||||
|
<#assign bpm_flag=false>
|
||||||
|
|
||||||
|
<#-- 开始循环 -->
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.isQuery=='Y'>
|
||||||
|
<#assign query_flag=true>
|
||||||
|
<#if query_field_no==2>
|
||||||
|
<template v-if="toggleSearchStatus">
|
||||||
|
</#if>
|
||||||
|
<#assign query_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign query_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
<#if po.queryMode=='single'>
|
||||||
|
<#if query_field_no gt 1> </#if><a-col :xl="6" :lg="7" :md="8" :sm="24">
|
||||||
|
<#if query_field_no gt 1> </#if><a-form-item label="${po.filedComment}">
|
||||||
|
<#if po.classType=='sel_search'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-search-select-tag placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" dict="${po.dictTable},${po.dictText},${po.dictField}"/>
|
||||||
|
<#elseif po.classType=='sel_user'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-select-user-by-dep placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}"/>
|
||||||
|
<#elseif po.classType=='switch'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-switch placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if> query></j-switch>
|
||||||
|
<#elseif po.classType=='sel_depart'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-select-depart placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}"/>
|
||||||
|
<#elseif po.classType=='list_multi'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-multi-select-tag placeholder="请选择${po.filedComment}" dictCode="${query_field_dictCode?default("")}" v-model="queryParam.${po.fieldName}"/>
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-category-select placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" pcode="${po.dictField?default("")}"/>
|
||||||
|
<#elseif po.classType=='date'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-date placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}"></j-date>
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}"></j-date>
|
||||||
|
<#elseif po.classType=='pca'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-area-linkage type="cascader" v-model="queryParam.${po.fieldName}" placeholder="请选择省市区"/>
|
||||||
|
<#elseif po.classType=='popup'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-popup placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" code="${po.dictTable}" org-fields="${po.dictField}" dest-fields="${po.dictText}" :field="getPopupField('${po.dictText}')" :multi="${po.extendParams.popupMulti?c}"/>
|
||||||
|
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||||
|
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
<#if query_field_no gt 1> </#if><j-dict-select-tag placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" dictCode="${po.dictTable},${po.dictText},${po.dictField}"/>
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#if query_field_no gt 1> </#if><j-dict-select-tag placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" dictCode="${po.dictField}"/>
|
||||||
|
<#else>
|
||||||
|
<#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model="queryParam.${po.fieldName}"></a-input>
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
<#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model="queryParam.${po.fieldName}"></a-input>
|
||||||
|
</#if>
|
||||||
|
<#if query_field_no gt 1> </#if></a-form-item>
|
||||||
|
<#if query_field_no gt 1> </#if></a-col>
|
||||||
|
<#else>
|
||||||
|
<#if query_field_no gt 1> </#if><a-col :xl="10" :lg="11" :md="12" :sm="24">
|
||||||
|
<#if query_field_no gt 1> </#if><a-form-item label="${po.filedComment}">
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-date placeholder="请选择开始日期" class="query-group-cust" v-model="queryParam.${po.fieldName}_begin"></j-date>
|
||||||
|
<#if query_field_no gt 1> </#if><span class="query-group-split-cust"></span>
|
||||||
|
<#if query_field_no gt 1> </#if><j-date placeholder="请选择结束日期" class="query-group-cust" v-model="queryParam.${po.fieldName}_end"></j-date>
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
<#if query_field_no gt 1> </#if><j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间" class="query-group-cust" v-model="queryParam.${po.fieldName}_begin"></j-date>
|
||||||
|
<#if query_field_no gt 1> </#if><span class="query-group-split-cust"></span>
|
||||||
|
<#if query_field_no gt 1> </#if><j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间" class="query-group-cust" v-model="queryParam.${po.fieldName}_end"></j-date>
|
||||||
|
<#else>
|
||||||
|
<#if query_field_no gt 1> </#if><a-input placeholder="请输入最小值" class="query-group-cust" v-model="queryParam.${po.fieldName}_begin"></a-input>
|
||||||
|
<#if query_field_no gt 1> </#if><span class="query-group-split-cust"></span>
|
||||||
|
<#if query_field_no gt 1> </#if><a-input placeholder="请输入最大值" class="query-group-cust" v-model="queryParam.${po.fieldName}_end"></a-input>
|
||||||
|
</#if>
|
||||||
|
<#if query_field_no gt 1> </#if></a-form-item>
|
||||||
|
<#if query_field_no gt 1> </#if></a-col>
|
||||||
|
</#if>
|
||||||
|
<#assign query_field_no=query_field_no+1>
|
||||||
|
</#if>
|
||||||
|
<#if !list_need_dict && po.fieldShowType!='popup' && po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign list_need_dict=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='cat_tree' && po.dictText?default("")?trim?length == 0>
|
||||||
|
<#assign list_need_category=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='pca'>
|
||||||
|
<#assign list_need_pca=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='switch'>
|
||||||
|
<#assign list_need_switch=true>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#-- 结束循环 -->
|
||||||
|
<#t>
|
||||||
|
<#if query_field_no gt 2>
|
||||||
|
</template>
|
||||||
|
</#if>
|
||||||
|
<#if query_flag>
|
||||||
|
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
||||||
|
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||||
|
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
|
||||||
|
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
|
||||||
|
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||||
|
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||||
|
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</a-col>
|
||||||
|
</#if>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
<!-- 查询区域-END -->
|
||||||
|
|
||||||
|
<!-- 操作按钮区域 -->
|
||||||
|
<div class="table-operator">
|
||||||
|
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
|
||||||
|
<a-button type="primary" icon="download" @click="handleExportXls('${tableVo.ftlDescription}')">导出</a-button>
|
||||||
|
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
|
||||||
|
<a-button type="primary" icon="import">导入</a-button>
|
||||||
|
</a-upload>
|
||||||
|
<!-- 高级查询区域 -->
|
||||||
|
<j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
|
||||||
|
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||||
|
<a-menu slot="overlay">
|
||||||
|
<a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
<a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
|
||||||
|
</a-dropdown>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- table区域-begin -->
|
||||||
|
<div>
|
||||||
|
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
|
||||||
|
<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
|
||||||
|
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-table
|
||||||
|
ref="table"
|
||||||
|
size="middle"
|
||||||
|
<#if tableVo.extendParams.scroll=='1'>
|
||||||
|
:scroll="{x:true}"
|
||||||
|
</#if>
|
||||||
|
bordered
|
||||||
|
rowKey="id"
|
||||||
|
:columns="columns"
|
||||||
|
:dataSource="dataSource"
|
||||||
|
:pagination="ipagination"
|
||||||
|
:loading="loading"
|
||||||
|
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||||
|
class="j-table-force-nowrap"
|
||||||
|
@change="handleTableChange">
|
||||||
|
|
||||||
|
<template slot="htmlSlot" slot-scope="text">
|
||||||
|
<div v-html="text"></div>
|
||||||
|
</template>
|
||||||
|
<template slot="imgSlot" slot-scope="text,record">
|
||||||
|
<span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
|
||||||
|
<img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
|
||||||
|
</template>
|
||||||
|
<#if list_need_pca>
|
||||||
|
<template slot="pcaSlot" slot-scope="text">
|
||||||
|
<div>{{ getPcaText(text) }}</div>
|
||||||
|
</template>
|
||||||
|
</#if>
|
||||||
|
<template slot="fileSlot" slot-scope="text">
|
||||||
|
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||||
|
<a-button
|
||||||
|
v-else
|
||||||
|
:ghost="true"
|
||||||
|
type="primary"
|
||||||
|
icon="download"
|
||||||
|
size="small"
|
||||||
|
@click="downloadFile(text)">
|
||||||
|
下载
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<span slot="action" slot-scope="text, record">
|
||||||
|
<a @click="handleEdit(record)">编辑</a>
|
||||||
|
|
||||||
|
<a-divider type="vertical" />
|
||||||
|
<a-dropdown>
|
||||||
|
<a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
|
||||||
|
<a-menu slot="overlay">
|
||||||
|
<a-menu-item>
|
||||||
|
<a @click="handleDetail(record)">详情</a>
|
||||||
|
</a-menu-item>
|
||||||
|
<#if bpm_flag>
|
||||||
|
<a-menu-item v-if="record.bpmStatus === '1'">
|
||||||
|
<a @click="startProcess(record)">发起流程</a>
|
||||||
|
</a-menu-item>
|
||||||
|
</#if>
|
||||||
|
<a-menu-item>
|
||||||
|
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
|
||||||
|
<a>删除</a>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</a-dropdown>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</a-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<${Format.humpToShortbar(entityName)}-modal ref="modalForm" @ok="modalFormOk"></${Format.humpToShortbar(entityName)}-modal>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import '@/assets/less/TableExpand.less'
|
||||||
|
import { mixinDevice } from '@/utils/mixin'
|
||||||
|
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||||
|
import ${entityName}Modal from './modules/${entityName}Modal'
|
||||||
|
<#if bpm_flag>
|
||||||
|
import { postAction } from '@/api/manage'
|
||||||
|
</#if>
|
||||||
|
<#if list_need_category>
|
||||||
|
import { loadCategoryData } from '@/api/api'
|
||||||
|
</#if>
|
||||||
|
<#if list_need_dict>
|
||||||
|
import {filterMultiDictText} from '@/components/dict/JDictSelectUtil'
|
||||||
|
</#if>
|
||||||
|
<#if list_need_pca>
|
||||||
|
import Area from '@/components/_util/Area'
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: '${entityName}List',
|
||||||
|
mixins:[JeecgListMixin, mixinDevice],
|
||||||
|
components: {
|
||||||
|
${entityName}Modal
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
description: '${tableVo.ftlDescription}管理页面',
|
||||||
|
// 表头
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '#',
|
||||||
|
dataIndex: '',
|
||||||
|
key:'rowIndex',
|
||||||
|
width:60,
|
||||||
|
align:"center",
|
||||||
|
customRender:function (t,r,index) {
|
||||||
|
return parseInt(index)+1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
<#assign showColNum=0>
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||||
|
<#assign showColNum=showColNum+1>
|
||||||
|
{
|
||||||
|
title:'${po.filedComment}',
|
||||||
|
align:"center",
|
||||||
|
<#if po.sort=='Y'>
|
||||||
|
sorter: true,
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
customRender:function (text) {
|
||||||
|
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||||
|
}
|
||||||
|
<#elseif po.fieldDbType=='Blob'>
|
||||||
|
dataIndex: '${po.fieldName}String'
|
||||||
|
<#elseif po.classType=='umeditor'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
scopedSlots: {customRender: 'htmlSlot'}
|
||||||
|
<#elseif po.classType=='pca'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
scopedSlots: {customRender: 'pcaSlot'}
|
||||||
|
<#elseif po.classType=='file'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
scopedSlots: {customRender: 'fileSlot'}
|
||||||
|
<#elseif po.classType=='image'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
scopedSlots: {customRender: 'imgSlot'}
|
||||||
|
<#elseif po.classType=='switch'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
customRender: (text) => (text ? filterMultiDictText(this.dictOptions['${po.fieldName}'], text) : ''),
|
||||||
|
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||||
|
dataIndex: '${po.fieldName}_dictText'
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
<#if list_need_category>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
customRender: (text) => (text ? filterMultiDictText(this.dictOptions['${po.fieldName}'], text) : '')
|
||||||
|
<#else>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
customRender: (text, record) => (text ? record['${dashedToCamel(po.dictText)}'] : '')
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
dataIndex: '${po.fieldName}'
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
align:"center",
|
||||||
|
<#if tableVo.extendParams.scroll=='1'>
|
||||||
|
fixed:"right",
|
||||||
|
width:147,
|
||||||
|
</#if>
|
||||||
|
scopedSlots: { customRender: 'action' }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
url: {
|
||||||
|
list: "/${entityPackagePath}/${entityName?uncap_first}/list",
|
||||||
|
delete: "/${entityPackagePath}/${entityName?uncap_first}/delete",
|
||||||
|
deleteBatch: "/${entityPackagePath}/${entityName?uncap_first}/deleteBatch",
|
||||||
|
exportXlsUrl: "/${entityPackagePath}/${entityName?uncap_first}/exportXls",
|
||||||
|
importExcelUrl: "${entityPackagePath}/${entityName?uncap_first}/importExcel",
|
||||||
|
<#if bpm_flag>startProcess: '/act/process/extActProcess/startMutilProcess'</#if>
|
||||||
|
},
|
||||||
|
<#if bpm_flag>
|
||||||
|
//代码生成后需手动设置流程编码
|
||||||
|
flowCode: 'dev_${tableName}_001',
|
||||||
|
</#if>
|
||||||
|
dictOptions:{},
|
||||||
|
<#if list_need_pca>
|
||||||
|
pcaData:'',
|
||||||
|
</#if>
|
||||||
|
superFieldList:[],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
<#if list_need_pca>
|
||||||
|
this.pcaData = new Area()
|
||||||
|
</#if>
|
||||||
|
<#if list_need_switch>
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.classType=='switch'>
|
||||||
|
<#assign switch_extend_arr=['Y','N']>
|
||||||
|
<#if po.dictField?default("")?contains("[")>
|
||||||
|
<#assign switch_extend_arr=po.dictField?eval>
|
||||||
|
</#if>
|
||||||
|
<#list switch_extend_arr as a>
|
||||||
|
<#if a_index == 0>
|
||||||
|
<#assign switch_extend_arr1=a>
|
||||||
|
<#else>
|
||||||
|
<#assign switch_extend_arr2=a>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
this.$set(this.dictOptions, '${po.fieldName}', [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
this.getSuperFieldList();
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
importExcelUrl: function(){
|
||||||
|
<#noparse>return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;</#noparse>
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
<#if list_need_pca>
|
||||||
|
getPcaText(code){
|
||||||
|
return this.pcaData.getText(code);
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
<#if bpm_flag>
|
||||||
|
startProcess(record){
|
||||||
|
this.$confirm({
|
||||||
|
title:'提示',
|
||||||
|
content:'确认提交流程吗?',
|
||||||
|
onOk:()=>{
|
||||||
|
let params = {
|
||||||
|
flowCode: this.flowCode,
|
||||||
|
id: record.id,
|
||||||
|
formUrl: '${entityPackagePath}/modules/${entityName}Form',
|
||||||
|
formUrlMobile: ''
|
||||||
|
}
|
||||||
|
postAction(this.url.startProcess, params).then(res=>{
|
||||||
|
if(res.success){
|
||||||
|
this.$message.success(res.message);
|
||||||
|
this.loadData();
|
||||||
|
this.onClearSelected();
|
||||||
|
}else{
|
||||||
|
this.$message.warning(res.message);
|
||||||
|
}
|
||||||
|
}).catch((e)=>{
|
||||||
|
this.$message.warning('不识别的请求!');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
initDictConfig(){
|
||||||
|
<#list columns as po>
|
||||||
|
<#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>
|
||||||
|
<#if po.classType=='cat_tree' && list_need_category==true>
|
||||||
|
loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
this.$set(this.dictOptions, '${po.fieldName}', res.result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
},
|
||||||
|
getSuperFieldList(){
|
||||||
|
let fieldList=[];
|
||||||
|
<#list columns as po>
|
||||||
|
fieldList.push(${superQueryFieldList(po)})
|
||||||
|
</#list>
|
||||||
|
this.superFieldList = fieldList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
@import '~@assets/less/common.less';
|
||||||
|
</style>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<#include "/common/sql/menu_insert.ftl">
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<template>
|
||||||
|
<a-spin :spinning="confirmLoading">
|
||||||
|
<j-form-container :disabled="formDisabled">
|
||||||
|
<a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
|
||||||
|
<a-row>
|
||||||
|
<#assign form_popup = false>
|
||||||
|
<#assign form_cat_tree = false>
|
||||||
|
<#assign form_cat_back = "">
|
||||||
|
<#assign bpm_flag=false>
|
||||||
|
<#assign form_span = 24>
|
||||||
|
<#if tableVo.fieldRowNum==2>
|
||||||
|
<#assign form_span = 12>
|
||||||
|
<#elseif tableVo.fieldRowNum==3>
|
||||||
|
<#assign form_span = 8>
|
||||||
|
<#elseif tableVo.fieldRowNum==4>
|
||||||
|
<#assign form_span = 6>
|
||||||
|
</#if>
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.isShow =='Y' && po.fieldName != 'id'>
|
||||||
|
<#assign form_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
<a-col :span="${form_span}">
|
||||||
|
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="${autoStringSuffixForModel(po)}">
|
||||||
|
<#if po.classType =='date'>
|
||||||
|
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#elseif po.classType =='datetime'>
|
||||||
|
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#elseif po.classType =='time'>
|
||||||
|
<j-time placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#elseif po.classType =='popup'>
|
||||||
|
<#assign form_popup=true>
|
||||||
|
<j-popup
|
||||||
|
v-model="model.${po.fieldName}"
|
||||||
|
field="${po.fieldName}"
|
||||||
|
org-fields="${po.dictField}"
|
||||||
|
dest-fields="${Format.underlineToHump(po.dictText)}"
|
||||||
|
code="${po.dictTable}"
|
||||||
|
:multi="${po.extendParams.popupMulti?c}"
|
||||||
|
@input="popupCallback"
|
||||||
|
<#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#elseif po.classType =='sel_depart'>
|
||||||
|
<j-select-depart v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if> />
|
||||||
|
<#elseif po.classType =='switch'>
|
||||||
|
<j-switch v-model="model.${po.fieldName}" <#if po.dictField != 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch>
|
||||||
|
<#elseif po.classType =='pca'>
|
||||||
|
<j-area-linkage type="cascader" v-model="model.${po.fieldName}" placeholder="请输入省市区" <#if po.readonly=='Y'>disabled</#if> />
|
||||||
|
<#elseif po.classType =='markdown'>
|
||||||
|
<j-markdown-editor v-model="model.${autoStringSuffixForModel(po)}" id="${po.fieldName}"></j-markdown-editor>
|
||||||
|
<#elseif po.classType =='password'>
|
||||||
|
<a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#elseif po.classType =='sel_user'>
|
||||||
|
<j-select-user-by-dep v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#elseif po.classType =='textarea'>
|
||||||
|
<a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||||
|
<j-dict-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||||
|
<j-multi-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#elseif po.classType=='sel_search'>
|
||||||
|
<j-search-select-tag v-model="model.${po.fieldName}" dict="${form_field_dictCode}" <#if po.readonly=='Y'>disabled</#if> />
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
<#assign form_cat_tree = true>
|
||||||
|
<j-category-select v-model="model.${po.fieldName}" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${dashedToCamel(po.dictText)}" @change="handleCategoryChange"</#if> <#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#if po.dictText?default("")?trim?length gt 1>
|
||||||
|
<#assign form_cat_back = "${po.dictText}">
|
||||||
|
</#if>
|
||||||
|
<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
<a-input-number v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#elseif po.classType=='file'>
|
||||||
|
<j-upload v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if> <#if po.uploadnum??>:number=${po.uploadnum}</#if>></j-upload>
|
||||||
|
<#elseif po.classType=='image'>
|
||||||
|
<j-image-upload isMultiple <#if po.uploadnum??>:number=${po.uploadnum}</#if> v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>></j-image-upload>
|
||||||
|
<#elseif po.classType=='umeditor'>
|
||||||
|
<j-editor v-model="model.${autoStringSuffixForModel(po)}" <#if po.readonly=='Y'>disabled</#if>/>
|
||||||
|
<#elseif po.fieldDbType=='Blob'>
|
||||||
|
<a-input v-model="model.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
|
||||||
|
<#elseif po.classType == 'sel_tree'>
|
||||||
|
<j-tree-select
|
||||||
|
ref="treeSelect"
|
||||||
|
placeholder="请选择${po.filedComment}"
|
||||||
|
v-model="model.${po.fieldName}"
|
||||||
|
<#if po.dictText??>
|
||||||
|
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||||
|
dict="${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}"
|
||||||
|
<#elseif po.dictText?split(',')[1]??>
|
||||||
|
pidField="${po.dictText?split(',')[1]}"
|
||||||
|
<#elseif po.dictText?split(',')[3]??>
|
||||||
|
hasChildField="${po.dictText?split(',')[3]}"
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
pidValue="${po.dictField}"
|
||||||
|
<#if po.readonly=='Y'>disabled</#if>>
|
||||||
|
</j-tree-select>
|
||||||
|
<#else>
|
||||||
|
<a-input v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if> ></a-input>
|
||||||
|
</#if>
|
||||||
|
</a-form-model-item>
|
||||||
|
</a-col>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#if bpm_flag>
|
||||||
|
<a-col v-if="showFlowSubmitButton" :span="24" style="width: 100%;text-align: center;">
|
||||||
|
<a-button icon="check" style="width: 126px" type="primary" @click="submitForm">提 交</a-button>
|
||||||
|
</a-col>
|
||||||
|
</#if>
|
||||||
|
</a-row>
|
||||||
|
</a-form-model>
|
||||||
|
</j-form-container>
|
||||||
|
</a-spin>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import { httpAction, getAction } from '@/api/manage'
|
||||||
|
import { validateDuplicateValue } from '@/utils/util'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: '${entityName}Form',
|
||||||
|
components: {
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
<#if bpm_flag>
|
||||||
|
//流程表单data
|
||||||
|
formData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
//表单模式:true流程表单 false普通表单
|
||||||
|
formBpm: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
//表单禁用
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
model:{
|
||||||
|
<#include "/common/init/initValue.ftl">
|
||||||
|
},
|
||||||
|
labelCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 5 },
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 16 },
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
<#include "/common/validatorRulesTemplate/main.ftl">
|
||||||
|
url: {
|
||||||
|
add: "/${entityPackagePath}/${entityName?uncap_first}/add",
|
||||||
|
edit: "/${entityPackagePath}/${entityName?uncap_first}/edit",
|
||||||
|
queryById: "/${entityPackagePath}/${entityName?uncap_first}/queryById"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
formDisabled(){
|
||||||
|
<#if bpm_flag>
|
||||||
|
if(this.formBpm===true){
|
||||||
|
if(this.formData.disabled===false){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
return this.disabled
|
||||||
|
},
|
||||||
|
<#if bpm_flag>
|
||||||
|
showFlowSubmitButton(){
|
||||||
|
if(this.formBpm===true){
|
||||||
|
if(this.formData.disabled===false){
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
//备份model原始值
|
||||||
|
this.modelDefault = JSON.parse(JSON.stringify(this.model));
|
||||||
|
<#if bpm_flag>
|
||||||
|
//如果是流程中表单,则需要加载流程表单data
|
||||||
|
this.showFlowData();
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
add () {
|
||||||
|
this.edit(this.modelDefault);
|
||||||
|
},
|
||||||
|
edit (record) {
|
||||||
|
this.model = Object.assign({}, record);
|
||||||
|
this.visible = true;
|
||||||
|
},
|
||||||
|
<#if bpm_flag>
|
||||||
|
//渲染流程表单数据
|
||||||
|
showFlowData(){
|
||||||
|
if(this.formBpm === true){
|
||||||
|
let params = {id:this.formData.dataId};
|
||||||
|
getAction(this.url.queryById,params).then((res)=>{
|
||||||
|
if(res.success){
|
||||||
|
this.edit (res.result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
submitForm () {
|
||||||
|
const that = this;
|
||||||
|
// 触发表单验证
|
||||||
|
this.$refs.form.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
that.confirmLoading = true;
|
||||||
|
let httpurl = '';
|
||||||
|
let method = '';
|
||||||
|
if(!this.model.id){
|
||||||
|
httpurl+=this.url.add;
|
||||||
|
method = 'post';
|
||||||
|
}else{
|
||||||
|
httpurl+=this.url.edit;
|
||||||
|
method = 'put';
|
||||||
|
}
|
||||||
|
httpAction(httpurl,this.model,method).then((res)=>{
|
||||||
|
if(res.success){
|
||||||
|
that.$message.success(res.message);
|
||||||
|
that.$emit('ok');
|
||||||
|
}else{
|
||||||
|
that.$message.warning(res.message);
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
that.confirmLoading = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
},
|
||||||
|
<#if form_popup>
|
||||||
|
popupCallback(value,row){
|
||||||
|
this.model = Object.assign(this.model, row);
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
<#if form_cat_tree>
|
||||||
|
handleCategoryChange(value,backObj){
|
||||||
|
this.model = Object.assign(this.model, backObj);
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<#assign modal_width = 800>
|
||||||
|
<#if tableVo.fieldRowNum==2>
|
||||||
|
<#assign modal_width = 896>
|
||||||
|
<#elseif tableVo.fieldRowNum==3>
|
||||||
|
<#assign modal_width = 1024>
|
||||||
|
<#elseif tableVo.fieldRowNum==4>
|
||||||
|
<#assign modal_width = 1280>
|
||||||
|
</#if>
|
||||||
|
<template>
|
||||||
|
<j-modal
|
||||||
|
:title="title"
|
||||||
|
:width="width"
|
||||||
|
:visible="visible"
|
||||||
|
switchFullscreen
|
||||||
|
@ok="handleOk"
|
||||||
|
:okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
cancelText="关闭">
|
||||||
|
<${Format.humpToShortbar(entityName)}-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></${Format.humpToShortbar(entityName)}-form>
|
||||||
|
</j-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import ${entityName}Form from './${entityName}Form'
|
||||||
|
export default {
|
||||||
|
name: '${entityName}Modal',
|
||||||
|
components: {
|
||||||
|
${entityName}Form
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
title:'',
|
||||||
|
width:${modal_width},
|
||||||
|
visible: false,
|
||||||
|
disableSubmit: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
add () {
|
||||||
|
this.visible=true
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.$refs.realForm.add();
|
||||||
|
})
|
||||||
|
},
|
||||||
|
edit (record) {
|
||||||
|
this.visible=true
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.$refs.realForm.edit(record);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
close () {
|
||||||
|
this.$emit('close');
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
handleOk () {
|
||||||
|
this.$refs.realForm.submitForm();
|
||||||
|
},
|
||||||
|
submitCallback(){
|
||||||
|
this.$emit('ok');
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
handleCancel () {
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<#assign modal_width = 800>
|
||||||
|
<#if tableVo.fieldRowNum==2>
|
||||||
|
<#assign modal_width = 896>
|
||||||
|
<#elseif tableVo.fieldRowNum==3>
|
||||||
|
<#assign modal_width = 1024>
|
||||||
|
<#elseif tableVo.fieldRowNum==4>
|
||||||
|
<#assign modal_width = 1280>
|
||||||
|
</#if>
|
||||||
|
<template>
|
||||||
|
<a-drawer
|
||||||
|
:title="title"
|
||||||
|
:width="width"
|
||||||
|
placement="right"
|
||||||
|
:closable="false"
|
||||||
|
@close="close"
|
||||||
|
destroyOnClose
|
||||||
|
:visible="visible">
|
||||||
|
<${Format.humpToShortbar(entityName)}-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></${Format.humpToShortbar(entityName)}-form>
|
||||||
|
<div class="drawer-footer">
|
||||||
|
<a-button @click="handleCancel" style="margin-bottom: 0;">关闭</a-button>
|
||||||
|
<a-button v-if="!disableSubmit" @click="handleOk" type="primary" style="margin-bottom: 0;">提交</a-button>
|
||||||
|
</div>
|
||||||
|
</a-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import ${entityName}Form from './${entityName}Form'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: '${entityName}Modal',
|
||||||
|
components: {
|
||||||
|
${entityName}Form
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
title:"操作",
|
||||||
|
width:${modal_width},
|
||||||
|
visible: false,
|
||||||
|
disableSubmit: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
add () {
|
||||||
|
this.visible=true
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.$refs.realForm.add();
|
||||||
|
})
|
||||||
|
},
|
||||||
|
edit (record) {
|
||||||
|
this.visible=true
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.$refs.realForm.edit(record);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
close () {
|
||||||
|
this.$emit('close');
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
submitCallback(){
|
||||||
|
this.$emit('ok');
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
handleOk () {
|
||||||
|
this.$refs.realForm.submitForm();
|
||||||
|
},
|
||||||
|
handleCancel () {
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
/** Button按钮间距 */
|
||||||
|
.ant-btn {
|
||||||
|
margin-left: 30px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.drawer-footer{
|
||||||
|
position: absolute;
|
||||||
|
bottom: -8px;
|
||||||
|
width: 100%;
|
||||||
|
border-top: 1px solid #e8e8e8;
|
||||||
|
padding: 10px 16px;
|
||||||
|
text-align: right;
|
||||||
|
left: 0;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 0 0 2px 2px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,443 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<#assign list_need_category=false>
|
||||||
|
<#assign list_need_pca=false>
|
||||||
|
<#assign list_has_popup_dict=false>
|
||||||
|
<#assign bpm_flag=false>
|
||||||
|
|
||||||
|
<#-- 开始循环 -->
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='cat_tree' && po.dictText?default("")?trim?length == 0>
|
||||||
|
<#assign list_need_category=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='popup_dict'>
|
||||||
|
<#assign list_has_popup_dict=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='pca'>
|
||||||
|
<#assign list_need_pca=true>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#assign buttonList=[]>
|
||||||
|
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
|
||||||
|
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
|
||||||
|
</#if>
|
||||||
|
<#-- 结束循环 -->
|
||||||
|
<!--引用表格-->
|
||||||
|
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||||
|
<!--插槽:table标题-->
|
||||||
|
<template #tableTitle>
|
||||||
|
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||||
|
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||||
|
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||||
|
<#if buttonList?size gt 0>
|
||||||
|
<#list buttonList as btn>
|
||||||
|
<#if btn.buttonStyle == 'button'>
|
||||||
|
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu>
|
||||||
|
<a-menu-item key="1" @click="batchHandleDelete">
|
||||||
|
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||||
|
删除
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'">批量操作
|
||||||
|
<Icon icon="mdi:chevron-down"></Icon>
|
||||||
|
</a-button>
|
||||||
|
</a-dropdown>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||||
|
<!-- 高级查询 -->
|
||||||
|
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
|
||||||
|
<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||||
|
</template>
|
||||||
|
<!--操作栏-->
|
||||||
|
<template #action="{ record }">
|
||||||
|
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
|
||||||
|
</template>
|
||||||
|
<!--字段回显插槽-->
|
||||||
|
<template v-slot:bodyCell="{ column, record, index, text }">
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.classType=='umeditor' || po.classType=='pca' || po.classType=='file'>
|
||||||
|
<template v-if="column.dataIndex==='${po.fieldName}'">
|
||||||
|
<#if po.classType=='umeditor'>
|
||||||
|
<!--富文本件字段回显插槽-->
|
||||||
|
<div v-html="text"></div>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='pca'>
|
||||||
|
<!--省市区字段回显插槽-->
|
||||||
|
{{ getAreaTextByCode(text) }}
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='file'>
|
||||||
|
<!--文件字段回显插槽-->
|
||||||
|
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||||
|
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
|
||||||
|
</#if>
|
||||||
|
</template>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</template>
|
||||||
|
</BasicTable>
|
||||||
|
<!-- 表单区域 -->
|
||||||
|
<${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
|
||||||
|
<#if bpm_flag==true>
|
||||||
|
<!-- 审批记录 -->
|
||||||
|
<BpmPictureModal @register="registerBpmModal" />
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup>
|
||||||
|
import {ref, reactive, computed, unref} from 'vue';
|
||||||
|
import {BasicTable, useTable, TableAction} from '/@/components/Table';
|
||||||
|
import {useModal} from '/@/components/Modal';
|
||||||
|
import { useListPage } from '/@/hooks/system/useListPage'
|
||||||
|
import ${entityName}Modal from './components/${entityName}Modal.vue'
|
||||||
|
import {columns, searchFormSchema, superQuerySchema} from './${entityName}.data';
|
||||||
|
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api';
|
||||||
|
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||||
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
|
<#if list_need_pca>
|
||||||
|
import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
|
||||||
|
</#if>
|
||||||
|
<#if list_need_category>
|
||||||
|
import { loadCategoryData } from '/@/api/common/api'
|
||||||
|
import { getAuthCache, setAuthCache } from '/@/utils/auth';
|
||||||
|
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
|
||||||
|
</#if>
|
||||||
|
<#if list_has_popup_dict>
|
||||||
|
import {getPopDictByCode} from "@/utils/dict";
|
||||||
|
import {filterMultiDictText} from "@/utils/dict/JDictSelectUtil";
|
||||||
|
</#if>
|
||||||
|
import { getDateByPicker } from '/@/utils';
|
||||||
|
//日期个性化选择
|
||||||
|
const fieldPickers = reactive({
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.extendParams?exists && po.extendParams.picker?exists>
|
||||||
|
${po.fieldName}: '${po.extendParams.picker}',
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
});
|
||||||
|
<#if bpm_flag==true>
|
||||||
|
import { startProcess } from '/@/api/common/api';
|
||||||
|
const [registerBpmModal, { openModal: bpmPicModal }] = useModal();
|
||||||
|
</#if>
|
||||||
|
const queryParam = reactive<any>({});
|
||||||
|
const checkedKeys = ref<Array<string | number>>([]);
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const { createMessage } = useMessage();
|
||||||
|
//注册model
|
||||||
|
const [registerModal, {openModal}] = useModal();
|
||||||
|
//注册table数据
|
||||||
|
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
|
||||||
|
tableProps:{
|
||||||
|
title: '${tableVo.ftlDescription}',
|
||||||
|
api: list,
|
||||||
|
columns,
|
||||||
|
canResize:true,
|
||||||
|
formConfig: {
|
||||||
|
//labelWidth: 120,
|
||||||
|
schemas: searchFormSchema,
|
||||||
|
autoSubmitOnEnter:true,
|
||||||
|
showAdvancedButton:true,
|
||||||
|
fieldMapToNumber: [
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.isQuery=='Y'>
|
||||||
|
<#if po.queryMode=='group'>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- -->
|
||||||
|
<#if po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal' || po.classType=='time'>
|
||||||
|
<#-- update-end---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- -->
|
||||||
|
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end']],
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
],
|
||||||
|
fieldMapToTime: [
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.isQuery=='Y'>
|
||||||
|
<#if po.queryMode=='group'>
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD'],
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD HH:mm:ss'],
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
],
|
||||||
|
},
|
||||||
|
actionColumn: {
|
||||||
|
width: 120,
|
||||||
|
fixed:'right'
|
||||||
|
},
|
||||||
|
beforeFetch: (params) => {
|
||||||
|
if (params && fieldPickers) {
|
||||||
|
for (let key in fieldPickers) {
|
||||||
|
if (params[key]) {
|
||||||
|
params[key] = getDateByPicker(params[key], fieldPickers[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Object.assign(params, queryParam);
|
||||||
|
},
|
||||||
|
<#if list_has_popup_dict>
|
||||||
|
afterFetch: afterFetch
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
exportConfig: {
|
||||||
|
name:"${tableVo.ftlDescription}",
|
||||||
|
url: getExportUrl,
|
||||||
|
params: queryParam,
|
||||||
|
},
|
||||||
|
importConfig: {
|
||||||
|
url: getImportUrl,
|
||||||
|
success: handleSuccess
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
|
||||||
|
|
||||||
|
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||||
|
// 高级查询配置
|
||||||
|
const superQueryConfig = reactive(superQuerySchema);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高级查询事件
|
||||||
|
*/
|
||||||
|
function handleSuperQuery(params) {
|
||||||
|
Object.keys(params).map((k) => {
|
||||||
|
queryParam[k] = params[k];
|
||||||
|
});
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||||
|
/**
|
||||||
|
* 新增事件
|
||||||
|
*/
|
||||||
|
function handleAdd() {
|
||||||
|
openModal(true, {
|
||||||
|
isUpdate: false,
|
||||||
|
showFooter: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 编辑事件
|
||||||
|
*/
|
||||||
|
function handleEdit(record: Recordable) {
|
||||||
|
openModal(true, {
|
||||||
|
record,
|
||||||
|
isUpdate: true,
|
||||||
|
showFooter: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 详情
|
||||||
|
*/
|
||||||
|
function handleDetail(record: Recordable) {
|
||||||
|
openModal(true, {
|
||||||
|
record,
|
||||||
|
isUpdate: true,
|
||||||
|
showFooter: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 删除事件
|
||||||
|
*/
|
||||||
|
async function handleDelete(record) {
|
||||||
|
await deleteOne({id: record.id}, handleSuccess);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 批量删除事件
|
||||||
|
*/
|
||||||
|
async function batchHandleDelete() {
|
||||||
|
await batchDelete({ids: selectedRowKeys.value}, handleSuccess);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 成功回调
|
||||||
|
*/
|
||||||
|
function handleSuccess() {
|
||||||
|
(selectedRowKeys.value = []) && reload();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 操作栏
|
||||||
|
*/
|
||||||
|
function getTableAction(record){
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: '编辑',
|
||||||
|
onClick: handleEdit.bind(null, record),
|
||||||
|
auth: '${entityPackage}:${tableName}:edit'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 下拉操作栏
|
||||||
|
*/
|
||||||
|
function getDropDownAction(record){
|
||||||
|
<#if bpm_flag==true>
|
||||||
|
let dropDownAction = [
|
||||||
|
{
|
||||||
|
label: '详情',
|
||||||
|
onClick: handleDetail.bind(null, record),
|
||||||
|
}, {
|
||||||
|
label: '删除',
|
||||||
|
popConfirm: {
|
||||||
|
title: '是否确认删除',
|
||||||
|
confirm: handleDelete.bind(null, record),
|
||||||
|
placement: 'topLeft',
|
||||||
|
},
|
||||||
|
auth: '${entityPackage}:${tableName}:delete'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '审批进度',
|
||||||
|
onClick: handlePreviewPic.bind(null, record),
|
||||||
|
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
|
||||||
|
}
|
||||||
|
<#if buttonList?size gt 0>
|
||||||
|
<#list buttonList as btn>
|
||||||
|
<#if btn.buttonStyle == 'link'>
|
||||||
|
,{
|
||||||
|
label: '${btn.buttonName}',
|
||||||
|
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
];
|
||||||
|
if(record.bpmStatus == '1'){
|
||||||
|
dropDownAction.push({
|
||||||
|
label: '发起流程',
|
||||||
|
popConfirm: {
|
||||||
|
title: '确认提交流程吗?',
|
||||||
|
confirm: handleProcess.bind(null, record),
|
||||||
|
placement: 'topLeft',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return dropDownAction;
|
||||||
|
<#else>
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: '详情',
|
||||||
|
onClick: handleDetail.bind(null, record),
|
||||||
|
}, {
|
||||||
|
label: '删除',
|
||||||
|
popConfirm: {
|
||||||
|
title: '是否确认删除',
|
||||||
|
confirm: handleDelete.bind(null, record),
|
||||||
|
placement: 'topLeft',
|
||||||
|
},
|
||||||
|
auth: '${entityPackage}:${tableName}:delete'
|
||||||
|
}
|
||||||
|
<#if buttonList?size gt 0>
|
||||||
|
<#list buttonList as btn>
|
||||||
|
<#if btn.buttonStyle == 'link'>
|
||||||
|
,{
|
||||||
|
label: '${btn.buttonName}',
|
||||||
|
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
]
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
|
||||||
|
<#if bpm_flag==true>
|
||||||
|
/**
|
||||||
|
* 提交流程
|
||||||
|
*/
|
||||||
|
async function handleProcess(record) {
|
||||||
|
let params = {
|
||||||
|
flowCode: 'dev_${tableName}_001',
|
||||||
|
id: record.id,
|
||||||
|
formUrl: '${entityPackagePath}/components/${entityName}Form',
|
||||||
|
formUrlMobile: ''
|
||||||
|
}
|
||||||
|
await startProcess(params);
|
||||||
|
handleSuccess();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 审批进度
|
||||||
|
*/
|
||||||
|
async function handlePreviewPic(record) {
|
||||||
|
bpmPicModal(true, {
|
||||||
|
flowCode: 'dev_${tableName}_001',
|
||||||
|
dataId: record.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if buttonList?size gt 0>
|
||||||
|
<#list buttonList as btn>
|
||||||
|
<#if btn.buttonStyle=='button'>
|
||||||
|
function handle${btn.buttonCode?cap_first}(){
|
||||||
|
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
<#if btn.buttonStyle=='link'>
|
||||||
|
function handle${btn.buttonCode?cap_first}(record){
|
||||||
|
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if list_need_category>
|
||||||
|
/**
|
||||||
|
* 初始化字典配置
|
||||||
|
*/
|
||||||
|
function initDictConfig(){
|
||||||
|
<#list columns as po>
|
||||||
|
<#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>
|
||||||
|
<#if po.classType=='cat_tree' && list_need_category==true>
|
||||||
|
loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => {
|
||||||
|
if (res) {
|
||||||
|
const allDictDate = userStore.getAllDictItems;
|
||||||
|
if(!allDictDate['${po.dictField?default("")}']){
|
||||||
|
userStore.setAllDictItems({...allDictDate,'${po.dictField?default("")}':res});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
initDictConfig();
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if list_has_popup_dict>
|
||||||
|
/**
|
||||||
|
* 翻译Popup字典配置
|
||||||
|
*/
|
||||||
|
async function afterFetch(records){
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.isQuery=='Y' || po.isShowList=='Y'>
|
||||||
|
<#if po.classType=='popup_dict' && list_has_popup_dict==true>
|
||||||
|
const ${po.fieldName}Keys = [...new Set(records.map((item) => item['${po.fieldName}']).flatMap((item) => item && item.split(',')))];
|
||||||
|
if(${po.fieldName}Keys && ${po.fieldName}Keys.length){
|
||||||
|
const dictOptions = await getPopDictByCode(${po.fieldName}Keys.join(','), '${po.dictTable},${po.dictField},${po.dictText}');
|
||||||
|
records.forEach((item) => {
|
||||||
|
item['${po.fieldName}_dictText'] = filterMultiDictText(dictOptions, item['${po.fieldName}']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
return records;
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
<#include "/common/form/vue3SearchStyle.ftl">
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import {defHttp} from '/@/utils/http/axios';
|
||||||
|
import { useMessage } from "/@/hooks/web/useMessage";
|
||||||
|
|
||||||
|
const { createConfirm } = useMessage();
|
||||||
|
|
||||||
|
enum Api {
|
||||||
|
list = '/${entityPackagePath}/${entityName?uncap_first}/list',
|
||||||
|
save='/${entityPackagePath}/${entityName?uncap_first}/add',
|
||||||
|
edit='/${entityPackagePath}/${entityName?uncap_first}/edit',
|
||||||
|
deleteOne = '/${entityPackagePath}/${entityName?uncap_first}/delete',
|
||||||
|
deleteBatch = '/${entityPackagePath}/${entityName?uncap_first}/deleteBatch',
|
||||||
|
importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel',
|
||||||
|
exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls',
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 导出api
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const getExportUrl = Api.exportXls;
|
||||||
|
/**
|
||||||
|
* 导入api
|
||||||
|
*/
|
||||||
|
export const getImportUrl = Api.importExcel;
|
||||||
|
/**
|
||||||
|
* 列表接口
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const list = (params) =>
|
||||||
|
defHttp.get({url: Api.list, params});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除单个
|
||||||
|
*/
|
||||||
|
export const deleteOne = (params,handleSuccess) => {
|
||||||
|
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
||||||
|
handleSuccess();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const batchDelete = (params, handleSuccess) => {
|
||||||
|
createConfirm({
|
||||||
|
iconType: 'warning',
|
||||||
|
title: '确认删除',
|
||||||
|
content: '是否删除选中数据',
|
||||||
|
okText: '确认',
|
||||||
|
cancelText: '取消',
|
||||||
|
onOk: () => {
|
||||||
|
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||||
|
handleSuccess();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 保存或者更新
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const saveOrUpdate = (params, isUpdate,showTip = true) => {
|
||||||
|
let url = isUpdate ? Api.edit : Api.save;
|
||||||
|
return defHttp.post({url: url, params},{successMessageMode:showTip?'success':'none'});
|
||||||
|
}
|
||||||
@@ -0,0 +1,538 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
import {BasicColumn} from '/@/components/Table';
|
||||||
|
import {FormSchema} from '/@/components/Table';
|
||||||
|
import { rules} from '/@/utils/helper/validator';
|
||||||
|
import { render } from '/@/utils/common/renderUtils';
|
||||||
|
import { getWeekMonthQuarterYear } from '/@/utils';
|
||||||
|
//列表数据
|
||||||
|
export const columns: BasicColumn[] = [
|
||||||
|
<#list columns as po>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||||
|
<#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'>
|
||||||
|
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||||
|
{
|
||||||
|
title: '${po.filedComment}',
|
||||||
|
align:"center",
|
||||||
|
<#if po.sort=='Y'>
|
||||||
|
sorter: true,
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
customRender:({text}) =>{
|
||||||
|
text = !text ? "" : (text.length > 10 ? text.substr(0,10) : text);
|
||||||
|
<#if po.extendParams?exists && po.extendParams.picker?exists>
|
||||||
|
if(text) {
|
||||||
|
return getWeekMonthQuarterYear(text)['${po.extendParams.picker}'];
|
||||||
|
} else {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
<#else>
|
||||||
|
return text;
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#elseif po.fieldDbType=='Blob'>
|
||||||
|
dataIndex: '${po.fieldName}String'
|
||||||
|
<#elseif po.classType=='umeditor'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#elseif po.classType=='pca'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#elseif po.classType=='file'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#elseif po.classType=='image'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
customRender:render.renderImage,
|
||||||
|
<#elseif po.classType=='switch'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#assign switch_extend_arr=['Y','N']>
|
||||||
|
<#if po.dictField?default("")?contains("[")>
|
||||||
|
<#assign switch_extend_arr=po.dictField?eval>
|
||||||
|
</#if>
|
||||||
|
<#list switch_extend_arr as a>
|
||||||
|
<#if a_index == 0>
|
||||||
|
<#assign switch_extend_arr1=a>
|
||||||
|
<#else>
|
||||||
|
<#assign switch_extend_arr2=a>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
customRender:({text}) => {
|
||||||
|
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||||
|
},
|
||||||
|
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='popup_dict' || po.classType=='link_table'>
|
||||||
|
dataIndex: '${po.fieldName}_dictText'
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#if po.dictText?default("")?trim?length == 0>
|
||||||
|
customRender:({text}) => {
|
||||||
|
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||||
|
},
|
||||||
|
<#else>
|
||||||
|
customRender: ({text, record}) => (text ? record['${po.dictText}'] : '')
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
dataIndex: '${po.fieldName}'
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
];
|
||||||
|
//查询数据
|
||||||
|
export const searchFormSchema: FormSchema[] = [
|
||||||
|
<#-- 开始循环 -->
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||||
|
<#if po.isQuery=='Y' && po.fieldName !='delFlag'>
|
||||||
|
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||||
|
<#assign query_flag=true>
|
||||||
|
<#assign query_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign query_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
<#if po.queryMode=='single'>
|
||||||
|
{
|
||||||
|
label: "${po.filedComment}",
|
||||||
|
field: ${autoStringSuffix(po)},
|
||||||
|
<#if po.classType=='sel_search'>
|
||||||
|
component: 'JSearchSelect',
|
||||||
|
componentProps:{
|
||||||
|
dict:"${query_field_dictCode}"
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='sel_user'>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||||
|
component: 'JSelectUser',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.extendParams?exists && po.extendParams.text?exists>
|
||||||
|
labelKey: '${po.extendParams.text}',
|
||||||
|
</#if>
|
||||||
|
<#if po.extendParams?exists && po.extendParams.store?exists>
|
||||||
|
rowKey: '${po.extendParams.store}',
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||||
|
<#elseif po.classType=='switch'>
|
||||||
|
component: 'JSwitch',
|
||||||
|
componentProps:{
|
||||||
|
query:true,
|
||||||
|
<#if po.dictField != 'is_open'>
|
||||||
|
options:${po.dictField}
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='sel_depart'>
|
||||||
|
component: 'JSelectDept',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.extendParams?exists && po.extendParams.text?exists>
|
||||||
|
labelKey: '${po.extendParams.text}',
|
||||||
|
</#if>
|
||||||
|
<#if po.extendParams?exists && po.extendParams.store?exists>
|
||||||
|
rowKey: '${po.extendParams.store}',
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='list_multi'>
|
||||||
|
component: 'JSelectMultiple',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
dictCode:"${po.dictTable},${po.dictText},${po.dictField}",
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
dictCode:"${po.dictField}",
|
||||||
|
</#if>
|
||||||
|
triggerChange: true
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
component: 'JCategorySelect',
|
||||||
|
componentProps:{
|
||||||
|
pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='date'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
<#if po.extendParams?exists && po.extendParams.picker?exists>
|
||||||
|
picker: '${po.extendParams.picker}',
|
||||||
|
</#if>
|
||||||
|
valueFormat: 'YYYY-MM-DD'
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime:true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss'
|
||||||
|
},
|
||||||
|
<#elseif po.classType =='time'>
|
||||||
|
component: 'TimePicker',
|
||||||
|
componentProps: {
|
||||||
|
valueFormat: 'HH:mm:ss'
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='pca'>
|
||||||
|
component: 'JAreaLinkage',
|
||||||
|
componentProps: {
|
||||||
|
saveCode: 'region',
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='popup'>
|
||||||
|
<#include "/common/form/vue3popup.ftl">
|
||||||
|
<#elseif po.classType=='popup_dict'>
|
||||||
|
component: 'JPopupDict',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请选择${po.filedComment}',
|
||||||
|
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
|
||||||
|
multi: ${po.extendParams.popupMulti?c}
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||||
|
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||||
|
component: 'JSelectMultiple',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
dictCode:"${po.dictField}"
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#elseif po.classType == 'sel_tree'>
|
||||||
|
component: 'JTreeSelect',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictText??>
|
||||||
|
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||||
|
dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}",
|
||||||
|
<#elseif po.dictText?split(',')[1]??>
|
||||||
|
pidField:"${po.dictText?split(',')[1]}",
|
||||||
|
<#elseif po.dictText?split(',')[3]??>
|
||||||
|
hasChildField:"${po.dictText?split(',')[3]}",
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
pidValue:"${po.dictField}",
|
||||||
|
},
|
||||||
|
<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
component: 'InputNumber',
|
||||||
|
<#else>
|
||||||
|
component: 'Input',
|
||||||
|
</#if>
|
||||||
|
//colProps: {span: 6},
|
||||||
|
},
|
||||||
|
<#elseif po.queryMode=='like'>
|
||||||
|
{
|
||||||
|
label: "${po.filedComment}",
|
||||||
|
field: "${po.fieldName}",
|
||||||
|
component: 'JInput',
|
||||||
|
},
|
||||||
|
<#else>
|
||||||
|
{
|
||||||
|
label: "${po.filedComment}",
|
||||||
|
field: "${po.fieldName}",
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
component: 'RangePicker',
|
||||||
|
componentProps: {
|
||||||
|
<#if po.extendParams?exists && po.extendParams.picker?exists>
|
||||||
|
picker: '${po.extendParams.picker}',
|
||||||
|
</#if>
|
||||||
|
valueType: 'Date',
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
component: 'RangePicker',
|
||||||
|
componentProps: {
|
||||||
|
valueType: 'Date',
|
||||||
|
showTime:true
|
||||||
|
},
|
||||||
|
<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
component: 'JRangeNumber',
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- -->
|
||||||
|
<#elseif po.classType=='time'>
|
||||||
|
component: 'RangeTime',
|
||||||
|
<#-- update-end---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- -->
|
||||||
|
<#else>
|
||||||
|
component: 'Input', //TODO 范围查询
|
||||||
|
</#if>
|
||||||
|
//colProps: {span: 6},
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#-- 结束循环 -->
|
||||||
|
];
|
||||||
|
//表单数据
|
||||||
|
export const formSchema: FormSchema[] = [
|
||||||
|
<#assign form_cat_tree = false>
|
||||||
|
<#assign form_cat_back = "">
|
||||||
|
<#assign bpm_flag=false>
|
||||||
|
<#assign id_exists = false>
|
||||||
|
<#list columns as po><#rt/>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.fieldDbName == 'id'>
|
||||||
|
<#assign id_exists = true>
|
||||||
|
</#if>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||||
|
<#if po.isShow =='Y' && po.fieldName !='delFlag'>
|
||||||
|
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||||
|
<#assign form_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
{
|
||||||
|
label: '${po.filedComment}',
|
||||||
|
field: ${autoStringSuffix(po)},
|
||||||
|
<#-- update-begin-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 -->
|
||||||
|
<#if po.defaultVal??>
|
||||||
|
<#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int">
|
||||||
|
defaultValue: ${po.defaultVal},
|
||||||
|
<#else>
|
||||||
|
defaultValue: "${po.defaultVal}",
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
<#-- update-end-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 -->
|
||||||
|
<#if po.classType =='date'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
<#if po.extendParams?exists && po.extendParams.picker?exists>
|
||||||
|
picker: '${po.extendParams.picker}',
|
||||||
|
</#if>
|
||||||
|
valueFormat: 'YYYY-MM-DD'
|
||||||
|
},
|
||||||
|
<#elseif po.classType =='datetime'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime: true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss'
|
||||||
|
},
|
||||||
|
<#elseif po.classType =='time'>
|
||||||
|
component: 'TimePicker',
|
||||||
|
componentProps: {
|
||||||
|
valueFormat: 'HH:mm:ss'
|
||||||
|
},
|
||||||
|
<#elseif po.classType =='popup'>
|
||||||
|
<#include "/common/form/vue3popup.ftl">
|
||||||
|
<#elseif po.classType=='popup_dict'>
|
||||||
|
component: 'JPopupDict',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请选择${po.filedComment}',
|
||||||
|
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
|
||||||
|
multi: ${po.extendParams.popupMulti?c}
|
||||||
|
},
|
||||||
|
<#elseif po.classType =='sel_depart'>
|
||||||
|
component: 'JSelectDept',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.extendParams?exists && po.extendParams.text?exists>
|
||||||
|
labelKey: '${po.extendParams.text}',
|
||||||
|
</#if>
|
||||||
|
<#if po.extendParams?exists && po.extendParams.store?exists>
|
||||||
|
rowKey: '${po.extendParams.store}',
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#elseif po.classType =='switch'>
|
||||||
|
component: 'JSwitch',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictField != 'is_open'>
|
||||||
|
options:${po.dictField}
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#elseif po.classType =='pca'>
|
||||||
|
component: 'JAreaLinkage',
|
||||||
|
componentProps: {
|
||||||
|
saveCode: 'region',
|
||||||
|
},
|
||||||
|
<#elseif po.classType =='markdown'>
|
||||||
|
component: 'JMarkdownEditor',//注意string转换问题
|
||||||
|
<#elseif po.classType =='password'>
|
||||||
|
component: 'InputPassword',
|
||||||
|
<#elseif po.classType =='sel_user'>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||||
|
component: 'JSelectUser',
|
||||||
|
<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||||
|
componentProps:{
|
||||||
|
<#if po.extendParams?exists && po.extendParams.text?exists>
|
||||||
|
labelKey: '${po.extendParams.text}',
|
||||||
|
</#if>
|
||||||
|
<#if po.extendParams?exists && po.extendParams.store?exists>
|
||||||
|
rowKey: '${po.extendParams.store}',
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#elseif po.classType =='textarea'>
|
||||||
|
component: 'InputTextArea',
|
||||||
|
<#elseif po.classType=='list'>
|
||||||
|
component: 'JDictSelectTag',
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"${form_field_dictCode}",
|
||||||
|
<#if po.fieldDbType=='int'>
|
||||||
|
stringToNumber: true
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='radio'>
|
||||||
|
component: 'JDictSelectTag',
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"${form_field_dictCode}",
|
||||||
|
type: "radio",
|
||||||
|
<#if po.fieldDbType=='int'>
|
||||||
|
stringToNumber: true
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||||
|
<#elseif po.classType=='list_multi'>
|
||||||
|
component: 'JSelectMultiple',
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"${form_field_dictCode}"
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='checkbox'>
|
||||||
|
component: 'JCheckbox',
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"${form_field_dictCode}"
|
||||||
|
},
|
||||||
|
<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||||
|
<#elseif po.classType=='sel_search'>
|
||||||
|
component: 'JSearchSelect',
|
||||||
|
componentProps:{
|
||||||
|
dict:"${form_field_dictCode}"
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
<#assign form_cat_tree = true>
|
||||||
|
component: 'JCategorySelect',
|
||||||
|
componentProps:{
|
||||||
|
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||||
|
},
|
||||||
|
<#if po.dictText?default("")?trim?length gt 1>
|
||||||
|
<#assign form_cat_back = "${po.dictText}">
|
||||||
|
</#if>
|
||||||
|
<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
component: 'InputNumber',
|
||||||
|
<#elseif po.classType=='file'>
|
||||||
|
component: 'JUpload',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.uploadnum??>
|
||||||
|
maxCount:${po.uploadnum}
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='image'>
|
||||||
|
component: 'JImageUpload',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.uploadnum??>
|
||||||
|
fileMax:${po.uploadnum}
|
||||||
|
<#else>
|
||||||
|
fileMax: 0
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='umeditor'>
|
||||||
|
component: 'JEditor',
|
||||||
|
<#elseif po.classType == 'sel_tree'>
|
||||||
|
component: 'JTreeSelect',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictText??>
|
||||||
|
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||||
|
dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}",
|
||||||
|
<#elseif po.dictText?split(',')[1]??>
|
||||||
|
pidField:"${po.dictText?split(',')[1]}",
|
||||||
|
<#elseif po.dictText?split(',')[3]??>
|
||||||
|
hasChildField:"${po.dictText?split(',')[3]}",
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
pidValue:"${po.dictField}",
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='link_table'>
|
||||||
|
component: 'JLinkTableCard',
|
||||||
|
componentProps: {
|
||||||
|
valueField: '${po.dictField}',
|
||||||
|
textField: '${po.dictText}',
|
||||||
|
tableName: '${po.dictTable}',
|
||||||
|
multi: <#if (po.queryMode!"") == "multi">true<#else>false</#if>
|
||||||
|
},
|
||||||
|
<#else>
|
||||||
|
component: 'Input',
|
||||||
|
</#if>
|
||||||
|
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||||
|
dynamicRules: ({model,schema}) => {
|
||||||
|
<#if po.fieldName != 'id'>
|
||||||
|
<#assign fieldValidType = po.fieldValidType!''>
|
||||||
|
return [
|
||||||
|
<#-- 非空校验 -->
|
||||||
|
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||||
|
{ required: true, message: '请输入${po.filedComment}!'},
|
||||||
|
<#elseif fieldValidType!=''>
|
||||||
|
{ required: false},
|
||||||
|
</#if>
|
||||||
|
<#-- 唯一校验 -->
|
||||||
|
<#if fieldValidType == 'only'>
|
||||||
|
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]},
|
||||||
|
<#-- 6到16位数字 -->
|
||||||
|
<#elseif fieldValidType == 'n6-16'>
|
||||||
|
{ pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'},
|
||||||
|
<#-- 6到16位任意字符 -->
|
||||||
|
<#elseif fieldValidType == '*6-16'>
|
||||||
|
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||||
|
<#-- 6到18位字母 -->
|
||||||
|
<#elseif fieldValidType == 's6-18'>
|
||||||
|
{ pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
|
||||||
|
<#-- 网址 -->
|
||||||
|
<#elseif fieldValidType == 'url'>
|
||||||
|
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||||
|
<#-- 电子邮件 -->
|
||||||
|
<#elseif fieldValidType == 'e'>
|
||||||
|
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||||
|
<#-- 手机号码 -->
|
||||||
|
<#elseif fieldValidType == 'm'>
|
||||||
|
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||||
|
<#-- 邮政编码 -->
|
||||||
|
<#elseif fieldValidType == 'p'>
|
||||||
|
{ pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||||
|
<#-- 字母 -->
|
||||||
|
<#elseif fieldValidType == 's'>
|
||||||
|
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||||
|
<#-- 数字 -->
|
||||||
|
<#elseif fieldValidType == 'n'>
|
||||||
|
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||||
|
<#-- 整数 -->
|
||||||
|
<#elseif fieldValidType == 'z'>
|
||||||
|
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||||
|
<#-- 金额 -->
|
||||||
|
<#elseif fieldValidType == 'money'>
|
||||||
|
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||||
|
<#-- 正则校验 -->
|
||||||
|
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||||
|
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||||
|
<#-- 无校验 -->
|
||||||
|
<#else>
|
||||||
|
<#t>
|
||||||
|
</#if>
|
||||||
|
];
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
<#if po.readonly=='Y'>
|
||||||
|
dynamicDisabled:true
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#if id_exists == false>
|
||||||
|
// TODO 主键隐藏字段,目前写死为ID
|
||||||
|
{
|
||||||
|
label: '',
|
||||||
|
field: 'id',
|
||||||
|
component: 'Input',
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
];
|
||||||
|
|
||||||
|
<#-- update-begin-author:chenrui date:2023-12-28 for:[QQYUN-7527]vue3代码生成默认带上高级查询 -->
|
||||||
|
// 高级查询数据
|
||||||
|
export const superQuerySchema = {
|
||||||
|
<#list columns as po>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||||
|
<#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'>
|
||||||
|
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||||
|
${superQueryFieldListForVue3(po,po_index)},
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
};
|
||||||
|
<#-- update-end-author:chenrui date:2023-12-28 for:[QQYUN-7527]vue3代码生成默认带上高级查询 -->
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程表单调用这个方法获取formSchema
|
||||||
|
* @param param
|
||||||
|
*/
|
||||||
|
export function getBpmFormSchema(_formData): FormSchema[]{
|
||||||
|
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||||
|
return formSchema;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<#include "/common/sql/menu_insert.ftl">
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<template>
|
||||||
|
<div style="min-height: 400px">
|
||||||
|
<BasicForm @register="registerForm"></BasicForm>
|
||||||
|
<div style="width: 100%;text-align: center" v-if="!formDisabled && showSubmitButton">
|
||||||
|
<a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||||
|
import {computed, defineComponent} from 'vue';
|
||||||
|
import {defHttp} from '/@/utils/http/axios';
|
||||||
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
|
import {getBpmFormSchema} from '../${entityName}.data';
|
||||||
|
import {saveOrUpdate} from '../${entityName}.api';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "${entityName}Form",
|
||||||
|
components:{
|
||||||
|
BasicForm
|
||||||
|
},
|
||||||
|
props:{
|
||||||
|
formData: propTypes.object.def({}),
|
||||||
|
formBpm: propTypes.bool.def(true),
|
||||||
|
showSubmitButton: propTypes.bool.def(true),
|
||||||
|
},
|
||||||
|
setup(props){
|
||||||
|
const [registerForm, { setFieldsValue, setProps,validate, scrollToField, getFieldsValue }] = useForm({
|
||||||
|
labelWidth: 150,
|
||||||
|
schemas: getBpmFormSchema(props.formData),
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}
|
||||||
|
});
|
||||||
|
|
||||||
|
const formDisabled = computed(()=>{
|
||||||
|
if(props.formData.disabled === false){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
let formData = {};
|
||||||
|
const queryByIdUrl = '/${entityPackagePath}/${entityName?uncap_first}/queryById';
|
||||||
|
async function initFormData(){
|
||||||
|
let params = {id: props.formData.dataId};
|
||||||
|
const data = await defHttp.get({url: queryByIdUrl, params});
|
||||||
|
formData = {...data}
|
||||||
|
//设置表单的值
|
||||||
|
await setFieldsValue(formData);
|
||||||
|
//默认是禁用
|
||||||
|
await setProps({disabled: formDisabled.value})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function submitForm(showTip = true) {
|
||||||
|
try {
|
||||||
|
let values = await validate();
|
||||||
|
console.log('表单数据', values)
|
||||||
|
//提交表单
|
||||||
|
await saveOrUpdate(values, true,showTip);
|
||||||
|
} catch ({ errorFields }) {
|
||||||
|
if (errorFields) {
|
||||||
|
const firstField = errorFields[0];
|
||||||
|
if (firstField) {
|
||||||
|
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.reject(errorFields);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initFormData();
|
||||||
|
|
||||||
|
return {
|
||||||
|
registerForm,
|
||||||
|
formDisabled,
|
||||||
|
submitForm,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<#assign buttonList=[]>
|
||||||
|
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
|
||||||
|
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
|
||||||
|
</#if>
|
||||||
|
<template>
|
||||||
|
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :maxHeight="500" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
|
||||||
|
<BasicForm @register="registerForm" name="${entityName}Form" />
|
||||||
|
<#if buttonList?? && buttonList?size gt 0>
|
||||||
|
<template #insertFooter>
|
||||||
|
<#list buttonList as btn>
|
||||||
|
<#if btn.buttonStyle=='form'>
|
||||||
|
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</template>
|
||||||
|
</#if>
|
||||||
|
</BasicModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {ref, computed, unref, reactive} from 'vue';
|
||||||
|
import {BasicModal, useModalInner} from '/@/components/Modal';
|
||||||
|
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||||
|
import {formSchema} from '../${entityName}.data';
|
||||||
|
import {saveOrUpdate} from '../${entityName}.api';
|
||||||
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
|
import { getDateByPicker } from '/@/utils';
|
||||||
|
const { createMessage } = useMessage();
|
||||||
|
// Emits声明
|
||||||
|
const emit = defineEmits(['register','success']);
|
||||||
|
const isUpdate = ref(true);
|
||||||
|
const isDetail = ref(false);
|
||||||
|
//表单配置
|
||||||
|
const [registerForm, { setProps,resetFields, setFieldsValue, validate, scrollToField }] = useForm({
|
||||||
|
<#if tableVo.fieldRowNum == 1>
|
||||||
|
labelWidth: 150,
|
||||||
|
</#if>
|
||||||
|
schemas: formSchema,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}},
|
||||||
|
baseRowStyle: { padding: "0 20px" }
|
||||||
|
});
|
||||||
|
//表单赋值
|
||||||
|
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||||
|
//重置表单
|
||||||
|
await resetFields();
|
||||||
|
setModalProps({confirmLoading: false,showCancelBtn:!!data?.showFooter,showOkBtn:!!data?.showFooter});
|
||||||
|
isUpdate.value = !!data?.isUpdate;
|
||||||
|
isDetail.value = !!data?.showFooter;
|
||||||
|
if (unref(isUpdate)) {
|
||||||
|
//表单赋值
|
||||||
|
await setFieldsValue({
|
||||||
|
...data.record,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 隐藏底部时禁用整个表单
|
||||||
|
setProps({ disabled: !data?.showFooter })
|
||||||
|
});
|
||||||
|
//日期个性化选择
|
||||||
|
const fieldPickers = reactive({
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.extendParams?exists && po.extendParams.picker?exists>
|
||||||
|
${po.fieldName}: '${po.extendParams.picker}',
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
});
|
||||||
|
//设置标题
|
||||||
|
const title = computed(() => (!unref(isUpdate) ? '新增' : !unref(isDetail) ? '详情' : '编辑'));
|
||||||
|
//表单提交事件
|
||||||
|
async function handleSubmit(v) {
|
||||||
|
try {
|
||||||
|
let values = await validate();
|
||||||
|
// 预处理日期数据
|
||||||
|
changeDateValue(values);
|
||||||
|
setModalProps({confirmLoading: true});
|
||||||
|
//提交表单
|
||||||
|
await saveOrUpdate(values, isUpdate.value);
|
||||||
|
//关闭弹窗
|
||||||
|
closeModal();
|
||||||
|
//刷新列表
|
||||||
|
emit('success');
|
||||||
|
} catch ({ errorFields }) {
|
||||||
|
if (errorFields) {
|
||||||
|
const firstField = errorFields[0];
|
||||||
|
if (firstField) {
|
||||||
|
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.reject(errorFields);
|
||||||
|
} finally {
|
||||||
|
setModalProps({confirmLoading: false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理日期值
|
||||||
|
* @param formData 表单数据
|
||||||
|
*/
|
||||||
|
const changeDateValue = (formData) => {
|
||||||
|
if (formData && fieldPickers) {
|
||||||
|
for (let key in fieldPickers) {
|
||||||
|
if (formData[key]) {
|
||||||
|
formData[key] = getDateByPicker(formData[key], fieldPickers[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
<#if buttonList?size gt 0>
|
||||||
|
<#list buttonList as btn>
|
||||||
|
<#if btn.buttonStyle=='form'>
|
||||||
|
function handle${btn.buttonCode?cap_first}(){
|
||||||
|
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
/** 时间和数字输入框样式 */
|
||||||
|
:deep(.ant-input-number) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-calendar-picker) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,583 @@
|
|||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<template>
|
||||||
|
<div class="p-2">
|
||||||
|
<#assign query_field_no=0>
|
||||||
|
<#assign need_category = false>
|
||||||
|
<#assign need_pca = false>
|
||||||
|
<#assign need_search = false>
|
||||||
|
<#assign need_dept_user = false>
|
||||||
|
<#assign need_switch = false>
|
||||||
|
<#assign need_dept = false>
|
||||||
|
<#assign need_multi = false>
|
||||||
|
<#assign need_popup = false>
|
||||||
|
<#assign need_popup_dict = false>
|
||||||
|
<#assign need_select_tag = false>
|
||||||
|
<#assign need_select_tree = false>
|
||||||
|
<#assign need_time = false>
|
||||||
|
<#assign bpm_flag=false>
|
||||||
|
<#assign need_markdown = false>
|
||||||
|
<#assign need_upload = false>
|
||||||
|
<#assign need_image_upload = false>
|
||||||
|
<#assign need_editor = false>
|
||||||
|
<#assign need_checkbox = false>
|
||||||
|
<#assign need_range_number = false>
|
||||||
|
<#assign is_range = false>
|
||||||
|
<#assign query_flag = false>
|
||||||
|
<#assign buttonList=[]>
|
||||||
|
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
|
||||||
|
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
|
||||||
|
</#if>
|
||||||
|
<#assign is_like = false>
|
||||||
|
<!--查询区域-->
|
||||||
|
<div class="jeecg-basic-table-form-container">
|
||||||
|
<a-form ref="formRef" @keyup.enter.native="searchQuery" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<#-- 开始循环 -->
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='cat_tree' && po.dictText?default("")?trim?length == 0>
|
||||||
|
<#assign need_category=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='pca'>
|
||||||
|
<#assign need_pca=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='sel_search'>
|
||||||
|
<#assign need_search = true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='sel_user'>
|
||||||
|
<#assign need_dept_user = true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='sel_depart'>
|
||||||
|
<#assign need_dept = true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='switch'>
|
||||||
|
<#assign need_switch = true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='list_multi'>
|
||||||
|
<#assign need_multi = true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='popup'>
|
||||||
|
<#assign need_popup = true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='popup_dict'>
|
||||||
|
<#assign need_popup_dict = true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='sel_tree'>
|
||||||
|
<#assign need_select_tree = true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='time'>
|
||||||
|
<#assign need_time = true>
|
||||||
|
</#if>
|
||||||
|
<#if po.queryMode=='group' && (po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal')>
|
||||||
|
<#assign need_range_number = true>
|
||||||
|
</#if>
|
||||||
|
<#if po.queryMode=='group'>
|
||||||
|
<#assign is_range = true>
|
||||||
|
</#if>
|
||||||
|
<#if po.queryMode=='like'>
|
||||||
|
<#assign is_like = true>
|
||||||
|
</#if>
|
||||||
|
<#include "/common/form/native/vue3NativeSearch.ftl">
|
||||||
|
</#list>
|
||||||
|
<#if query_field_no gt 2>
|
||||||
|
</template>
|
||||||
|
</#if>
|
||||||
|
<#if query_flag>
|
||||||
|
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
||||||
|
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
|
||||||
|
<a-col :lg="6">
|
||||||
|
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
|
||||||
|
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset" style="margin-left: 8px">重置</a-button>
|
||||||
|
<a @click="toggleSearchStatus = !toggleSearchStatus" style="margin-left: 8px">
|
||||||
|
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||||
|
<Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" />
|
||||||
|
</a>
|
||||||
|
</a-col>
|
||||||
|
</span>
|
||||||
|
</a-col>
|
||||||
|
</#if>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
<#-- 结束循环 -->
|
||||||
|
<!--引用表格-->
|
||||||
|
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||||
|
<!--插槽:table标题-->
|
||||||
|
<template #tableTitle>
|
||||||
|
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||||
|
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||||
|
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||||
|
<#if buttonList?size gt 0>
|
||||||
|
<#list buttonList as btn>
|
||||||
|
<#if btn.buttonStyle == 'button'>
|
||||||
|
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu>
|
||||||
|
<a-menu-item key="1" @click="batchHandleDelete">
|
||||||
|
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||||
|
删除
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'">批量操作
|
||||||
|
<Icon icon="mdi:chevron-down"></Icon>
|
||||||
|
</a-button>
|
||||||
|
</a-dropdown>
|
||||||
|
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||||
|
<!-- 高级查询 -->
|
||||||
|
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
|
||||||
|
<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||||
|
</template>
|
||||||
|
<!--操作栏-->
|
||||||
|
<template #action="{ record }">
|
||||||
|
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
|
||||||
|
</template>
|
||||||
|
<template v-slot:bodyCell="{ column, record, index, text }">
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.classType=='umeditor' || po.classType=='pca' || po.classType=='file'>
|
||||||
|
<template v-if="column.dataIndex==='${po.fieldName}'">
|
||||||
|
<#if po.classType=='umeditor'>
|
||||||
|
<!--富文本件字段回显插槽-->
|
||||||
|
<div v-html="text"></div>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='pca'>
|
||||||
|
<!--省市区字段回显插槽-->
|
||||||
|
{{ getAreaTextByCode(text) }}
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='file'>
|
||||||
|
<!--文件字段回显插槽-->
|
||||||
|
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||||
|
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
|
||||||
|
</#if>
|
||||||
|
</template>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</template>
|
||||||
|
</BasicTable>
|
||||||
|
<!-- 表单区域 -->
|
||||||
|
<${entityName}Modal ref="registerModal" @success="handleSuccess"></${entityName}Modal>
|
||||||
|
<#if bpm_flag==true>
|
||||||
|
<!-- 审批记录 -->
|
||||||
|
<BpmPictureModal @register="registerBpmModal" />
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup>
|
||||||
|
import { ref, reactive } from 'vue';
|
||||||
|
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
||||||
|
import { useListPage } from '/@/hooks/system/useListPage';
|
||||||
|
import { columns, superQuerySchema } from './${entityName}.data';
|
||||||
|
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './${entityName}.api';
|
||||||
|
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||||
|
import ${entityName}Modal from './components/${entityName}Modal.vue'
|
||||||
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
|
import {useModal} from '/@/components/Modal';
|
||||||
|
<#include "/common/form/native/vue3NativeImport.ftl">
|
||||||
|
<#if need_category>
|
||||||
|
import { loadCategoryData } from '/@/api/common/api';
|
||||||
|
import { getAuthCache, setAuthCache } from '/@/utils/auth';
|
||||||
|
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
|
||||||
|
</#if>
|
||||||
|
<#if need_pca>
|
||||||
|
import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
|
||||||
|
</#if>
|
||||||
|
import { getDateByPicker } from '/@/utils';
|
||||||
|
<#if need_popup_dict>
|
||||||
|
import {getPopDictByCode} from "@/utils/dict";
|
||||||
|
import {filterMultiDictText} from "@/utils/dict/JDictSelectUtil";
|
||||||
|
</#if>
|
||||||
|
<#if bpm_flag==true>
|
||||||
|
import { startProcess } from '/@/api/common/api';
|
||||||
|
const [registerBpmModal, { openModal: bpmPicModal }] = useModal();
|
||||||
|
</#if>
|
||||||
|
<#if is_range>
|
||||||
|
import { cloneDeep } from "lodash-es";
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
const fieldPickers = reactive({
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.extendParams?exists && po.extendParams.picker?exists>
|
||||||
|
${po.fieldName}: '${po.extendParams.picker}',
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const queryParam = reactive<any>({});
|
||||||
|
const toggleSearchStatus = ref<boolean>(false);
|
||||||
|
const registerModal = ref();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const { createMessage } = useMessage();
|
||||||
|
//注册table数据
|
||||||
|
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
||||||
|
tableProps: {
|
||||||
|
title: '${tableVo.ftlDescription}',
|
||||||
|
api: list,
|
||||||
|
columns,
|
||||||
|
canResize:true,
|
||||||
|
useSearchForm: false,
|
||||||
|
actionColumn: {
|
||||||
|
width: 120,
|
||||||
|
fixed: 'right',
|
||||||
|
},
|
||||||
|
beforeFetch: async (params) => {
|
||||||
|
<#if is_range>
|
||||||
|
let rangerQuery = await setRangeQuery();
|
||||||
|
return Object.assign(params, rangerQuery);
|
||||||
|
<#else>
|
||||||
|
for (let key in fieldPickers) {
|
||||||
|
if (queryParam[key] && fieldPickers[key]) {
|
||||||
|
queryParam[key] = getDateByPicker(queryParam[key], fieldPickers[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Object.assign(params, queryParam);
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#if need_popup_dict>
|
||||||
|
afterFetch: afterFetch
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
exportConfig: {
|
||||||
|
name: "${tableVo.ftlDescription}",
|
||||||
|
url: getExportUrl,
|
||||||
|
<#if is_range>
|
||||||
|
params: setRangeQuery,
|
||||||
|
<#else>
|
||||||
|
params: queryParam,
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
importConfig: {
|
||||||
|
url: getImportUrl,
|
||||||
|
success: handleSuccess
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||||
|
const labelCol = reactive({
|
||||||
|
xs:24,
|
||||||
|
sm:4,
|
||||||
|
xl:6,
|
||||||
|
xxl:4
|
||||||
|
});
|
||||||
|
const wrapperCol = reactive({
|
||||||
|
xs: 24,
|
||||||
|
sm: 20,
|
||||||
|
});
|
||||||
|
|
||||||
|
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||||
|
// 高级查询配置
|
||||||
|
const superQueryConfig = reactive(superQuerySchema);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高级查询事件
|
||||||
|
*/
|
||||||
|
function handleSuperQuery(params) {
|
||||||
|
Object.keys(params).map((k) => {
|
||||||
|
queryParam[k] = params[k];
|
||||||
|
});
|
||||||
|
searchQuery();
|
||||||
|
}
|
||||||
|
<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增事件
|
||||||
|
*/
|
||||||
|
function handleAdd() {
|
||||||
|
registerModal.value.disableSubmit = false;
|
||||||
|
registerModal.value.add();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑事件
|
||||||
|
*/
|
||||||
|
function handleEdit(record: Recordable) {
|
||||||
|
registerModal.value.disableSubmit = false;
|
||||||
|
registerModal.value.edit(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 详情
|
||||||
|
*/
|
||||||
|
function handleDetail(record: Recordable) {
|
||||||
|
registerModal.value.disableSubmit = true;
|
||||||
|
registerModal.value.edit(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除事件
|
||||||
|
*/
|
||||||
|
async function handleDelete(record) {
|
||||||
|
await deleteOne({ id: record.id }, handleSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除事件
|
||||||
|
*/
|
||||||
|
async function batchHandleDelete() {
|
||||||
|
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成功回调
|
||||||
|
*/
|
||||||
|
function handleSuccess() {
|
||||||
|
(selectedRowKeys.value = []) && reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作栏
|
||||||
|
*/
|
||||||
|
function getTableAction(record) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: '编辑',
|
||||||
|
onClick: handleEdit.bind(null, record),
|
||||||
|
auth: '${entityPackage}:${tableName}:edit'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下拉操作栏
|
||||||
|
*/
|
||||||
|
function getDropDownAction(record) {
|
||||||
|
<#if bpm_flag==true>
|
||||||
|
let dropDownAction = [
|
||||||
|
{
|
||||||
|
label: '详情',
|
||||||
|
onClick: handleDetail.bind(null, record),
|
||||||
|
}, {
|
||||||
|
label: '删除',
|
||||||
|
popConfirm: {
|
||||||
|
title: '是否确认删除',
|
||||||
|
confirm: handleDelete.bind(null, record),
|
||||||
|
placement: 'topLeft',
|
||||||
|
},
|
||||||
|
auth: '${entityPackage}:${tableName}:delete'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '审批进度',
|
||||||
|
onClick: handlePreviewPic.bind(null, record),
|
||||||
|
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
|
||||||
|
}
|
||||||
|
<#if buttonList?size gt 0>
|
||||||
|
<#list buttonList as btn>
|
||||||
|
<#if btn.buttonStyle == 'link'>
|
||||||
|
,{
|
||||||
|
label: '${btn.buttonName}',
|
||||||
|
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
];
|
||||||
|
if(record.bpmStatus == '1'){
|
||||||
|
dropDownAction.push({
|
||||||
|
label: '发起流程',
|
||||||
|
popConfirm: {
|
||||||
|
title: '确认提交流程吗?',
|
||||||
|
confirm: handleProcess.bind(null, record),
|
||||||
|
placement: 'topLeft',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return dropDownAction;
|
||||||
|
<#else>
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: '详情',
|
||||||
|
onClick: handleDetail.bind(null, record),
|
||||||
|
}, {
|
||||||
|
label: '删除',
|
||||||
|
popConfirm: {
|
||||||
|
title: '是否确认删除',
|
||||||
|
confirm: handleDelete.bind(null, record),
|
||||||
|
placement: 'topLeft',
|
||||||
|
},
|
||||||
|
auth: '${entityPackage}:${tableName}:delete'
|
||||||
|
}
|
||||||
|
<#if buttonList?size gt 0>
|
||||||
|
<#list buttonList as btn>
|
||||||
|
<#if btn.buttonStyle == 'link'>
|
||||||
|
,{
|
||||||
|
label: '${btn.buttonName}',
|
||||||
|
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
]
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询
|
||||||
|
*/
|
||||||
|
function searchQuery() {
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置
|
||||||
|
*/
|
||||||
|
function searchReset() {
|
||||||
|
formRef.value.resetFields();
|
||||||
|
selectedRowKeys.value = [];
|
||||||
|
//刷新数据
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
<#if need_popup>
|
||||||
|
/**
|
||||||
|
* popup组件值改变事件
|
||||||
|
*/
|
||||||
|
function setFieldsValue(map) {
|
||||||
|
Object.keys(map).map((key) => {
|
||||||
|
queryParam[key] = map[key];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if need_pca || need_dept_user>
|
||||||
|
/**
|
||||||
|
* form点击事件(以逗号分割)
|
||||||
|
* @param key
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
function handleFormJoinChange(key, value) {
|
||||||
|
if (typeof value != 'string') {
|
||||||
|
queryParam[key] = value.join(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if bpm_flag==true>
|
||||||
|
/**
|
||||||
|
* 提交流程
|
||||||
|
*/
|
||||||
|
async function handleProcess(record) {
|
||||||
|
let params = {
|
||||||
|
flowCode: 'dev_${tableName}_001',
|
||||||
|
id: record.id,
|
||||||
|
formUrl: '${entityPackagePath}/components/${entityName}Form',
|
||||||
|
formUrlMobile: ''
|
||||||
|
}
|
||||||
|
await startProcess(params);
|
||||||
|
handleSuccess();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 审批进度
|
||||||
|
*/
|
||||||
|
async function handlePreviewPic(record) {
|
||||||
|
bpmPicModal(true, {
|
||||||
|
flowCode: 'dev_${tableName}_001',
|
||||||
|
dataId: record.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if buttonList?size gt 0>
|
||||||
|
<#list buttonList as btn>
|
||||||
|
<#if btn.buttonStyle=='button'>
|
||||||
|
function handle${btn.buttonCode?cap_first}(){
|
||||||
|
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
<#if btn.buttonStyle=='link'>
|
||||||
|
function handle${btn.buttonCode?cap_first}(record){
|
||||||
|
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if need_category>
|
||||||
|
/**
|
||||||
|
* form点击事件
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
function handleFormChange(key, value) {
|
||||||
|
queryParam[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化字典配置
|
||||||
|
*/
|
||||||
|
function initDictConfig() {
|
||||||
|
<#list columns as po>
|
||||||
|
<#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>
|
||||||
|
<#if po.classType=='cat_tree' && need_category==true>
|
||||||
|
loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => {
|
||||||
|
if (res) {
|
||||||
|
const allDictDate = userStore.getAllDictItems;
|
||||||
|
if(!allDictDate['${po.dictField?default("")}']){
|
||||||
|
userStore.setAllDictItems({...allDictDate,'${po.dictField?default("")}':res});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
initDictConfig();
|
||||||
|
</#if>
|
||||||
|
<#if is_range>
|
||||||
|
|
||||||
|
let rangeField = '${getRangeField(columns)}'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置范围查询条件
|
||||||
|
*/
|
||||||
|
async function setRangeQuery(){
|
||||||
|
let queryParamClone = cloneDeep(queryParam);
|
||||||
|
if (rangeField) {
|
||||||
|
let fieldsValue = rangeField.split(',');
|
||||||
|
fieldsValue.forEach(item => {
|
||||||
|
if (queryParamClone[item]) {
|
||||||
|
let range = queryParamClone[item];
|
||||||
|
queryParamClone[item+'_begin'] = range[0];
|
||||||
|
queryParamClone[item+'_end'] = range[1];
|
||||||
|
delete queryParamClone[item];
|
||||||
|
} else {
|
||||||
|
queryParamClone[item+'_begin'] = '';
|
||||||
|
queryParamClone[item+'_end'] = '';
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return queryParamClone;
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if need_popup_dict>
|
||||||
|
/**
|
||||||
|
* 翻译Popup字典配置
|
||||||
|
*/
|
||||||
|
async function afterFetch(records){
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.isQuery=='Y' || po.isShowList=='Y'>
|
||||||
|
<#if po.classType=='popup_dict'>
|
||||||
|
const ${po.fieldName}Keys = [...new Set(records.map((item) => item['${po.fieldName}']).flatMap((item) => item && item.split(',')))];
|
||||||
|
if(${po.fieldName}Keys && ${po.fieldName}Keys.length){
|
||||||
|
const dictOptions = await getPopDictByCode(${po.fieldName}Keys.join(','), '${po.dictTable},${po.dictField},${po.dictText}');
|
||||||
|
records.forEach((item) => {
|
||||||
|
item['${po.fieldName}_dictText'] = filterMultiDictText(dictOptions, item['${po.fieldName}']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
return records;
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
<#include "/common/form/native/vueNativeSearchStyle.ftl">
|
||||||
|
</style>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user