From 7e5256dcd7c88166813492507e9bf7001d893092 Mon Sep 17 00:00:00 2001
From: zhangdaiscott <zhangdaiscott@163.com>
Date: Tue, 21 Jun 2022 18:11:10 +0800
Subject: [PATCH] 代码生成器升级 1.支持插入菜单sql生成 2.vue3模板大升级 3.提供vue3原生表单模板生成

---
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeComponents.ftl                                                          |  48 ++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeForm.ftl                                                                | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeImport.ftl                                                              |  48 ++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeSearch.ftl                                                              |  85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/vue3Jvxepopup.ftl                                                                        |  13 +++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/vue3popup.ftl                                                                            |  17 +++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/sql/menu_insert.ftl                                                                           |   5 +++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/utils.ftl                                                                                     |  42 +++++++++++++++++++++++++++++++++++++++++-
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3CoreNative.ftl                                              |  49 +++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3MainNative.ftl                                              |   6 ++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/sub-vue3.ftl                                                           |  23 +++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai                         |   5 +++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql                  |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei                 |   4 ++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei                        |  20 ++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi                       |  75 +++++++++++++++++++++++++++++++++++++--------------------------------------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql                 |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei            |  11 ++++++++++-
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei                  | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi                  |  69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi                 | 366 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql           |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei       | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei      |  75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai     |  13 +++++--------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai                   |   5 +++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai                     |   5 +++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql            |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei           |   4 ++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei                   |   4 ++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai                        |   5 +++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql                 |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei               |   4 ++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei                       |  98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi                       |   3 +--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi                      |  83 +++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql                |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei           |  33 +++++++++++++++++++++++++++++----
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei                 | 497 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi                 |  90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi                | 399 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql          |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei      | 235 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei     |  81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai                       |   5 +++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai                         |   4 +++-
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei                       |   2 +-
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql                |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei              |   4 ++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Modal.vuei                      |   4 ++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei                      |  34 +++++++++++++++++++++++++++-------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi                     | 102 ++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql               |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/[1-n]List.vuei                              |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei          |  11 ++++++++++-
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Modal.vuei                  |  13 ++++++++++++-
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai |  15 ++++++---------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai               |   5 +++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai                 |   5 +++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql        |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei       |   4 ++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei               |   4 ++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei              |  24 ++++++++++++++++++++++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi             | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql       |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei  |  18 +++++++++++++++---
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei           |  29 +++++++++++++++++++++++------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai        |  15 ++++++---------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai                      |   5 +++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai                        |   5 +++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql               |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei              |   4 ++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei                      |   4 ++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei                     |  24 ++++++++++++++++++++++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi                    | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql              |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei         |  18 +++++++++++++++---
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei                  |  21 ++++++++++++++++++---
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei               | 340 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi               |  82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi              | 714 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql        |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei    | 264 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei   |  69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Form.vuei            | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai         |  19 ++++++++-----------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai                       |   5 +++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai                         |   5 +++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql                |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei               |   4 ++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei                       |   4 ++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei                      |  24 ++++++++++++++++++++++--
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi                     | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql               |   1 +
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei          |  69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei                   |  21 ++++++++++++++++++---
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi                                |   6 +++---
 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template/onetomany2/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi                               |   6 +++++-
 98 files changed, 5297 insertions(+), 526 deletions(-)
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeComponents.ftl
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeForm.ftl
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeImport.ftl
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeSearch.ftl
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/vue3Jvxepopup.ftl
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/vue3popup.ftl
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/sql/menu_insert.ftl
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3CoreNative.ftl
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3MainNative.ftl
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/sub-vue3.ftl
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Form.vuei
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
 create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql

diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeComponents.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeComponents.ftl
new file mode 100644
index 0000000..60ad682
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeComponents.ftl
@@ -0,0 +1,48 @@
+<#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_category>
+      JCategorySelect,
+</#if>
+<#if need_dept>
+      JSelectDept,
+</#if>
+<#if need_dept_user>
+      JSelectUserByDept,
+</#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>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeForm.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeForm.ftl
new file mode 100644
index 0000000..8d28821
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeForm.ftl
@@ -0,0 +1,107 @@
+<#include "/common/utils.ftl">
+<#if po.isShow =='Y' && po.fieldName != 'id' && isNotPidField(tableVo, po.fieldDbName)>
+<#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)}">
+			<#if po.classType =='date'>
+		        <a-date-picker placeholder="请选择${po.filedComment}" v-model:value="formData.${po.fieldName}" value-format="YYYY-MM-DD"  style="width: 100%" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/>
+			<#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<#else>:disabled="disabled"</#if>/>
+			<#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<#else>:disabled="disabled"</#if>/>
+			<#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: '${targetFields[fieldName_index]}' },
+		            </#list>
+		          ]"
+		          :multi="${po.extendParams.popupMulti?c}"
+		          :setFieldsValue="setFieldsValue"
+              <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if><#rt>
+		        />
+		  <#elseif po.classType =='sel_depart'>
+	          <#assign need_dept = true>
+	          <j-select-dept v-model:value="formData.${po.fieldName}" :multiple="${po.extendParams.multi?default('true')}" checkStrictly <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if> />
+		  <#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<#else>:disabled="disabled"</#if>></j-switch>
+			<#elseif po.classType =='pca'>
+	          <#assign need_pca = true>
+	          <j-area-linkage v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if> />
+			<#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<#else>:disabled="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<#else>:disabled="disabled"</#if>/>
+			<#elseif po.classType =='sel_user'>
+	          <#assign need_dept_user = true>
+	          <j-select-user-by-dept v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/>
+			<#elseif po.classType =='textarea'>
+	          <a-textarea v-model:value="formData.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="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<#else>:disabled="disabled"</#if>/>
+			<#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<#else>:disabled="disabled"</#if>/>
+			<#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<#else>:disabled="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<#else>:disabled="disabled"</#if>/>
+			<#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<#else>:disabled="disabled"</#if> />
+		    <#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<#else>:disabled="disabled"</#if> @change="(value) => handleFormChange('${po.fieldName}', value)" />
+			<#elseif po.fieldDbType=='int' || 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<#else>:disabled="disabled"</#if>/>
+			<#elseif po.classType=='file'>
+		        <#assign need_upload = true>
+	          <j-upload v-model:value="formData.${po.fieldName}"  <#if po.readonly=='Y'>disabled<#else>:disabled="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}</#if> v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled<#else>:disabled="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<#else>:disabled="disabled"</#if>/>
+		    <#elseif po.fieldDbType=='Blob'>
+	          <a-input v-model:value="formData.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>></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<#else>:disabled="disabled"</#if>
+	            v-model:value="formData.${po.fieldName}"
+	            @change="(value) => handleFormChange('${po.fieldName}', value)">
+	          </j-tree-select>
+			<#else>
+            <a-input v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>></a-input>
+    </#if>
+          </a-form-item>
+        </a-col>
+</#if>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeImport.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeImport.ftl
new file mode 100644
index 0000000..1c9a3f7
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeImport.ftl
@@ -0,0 +1,48 @@
+<#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_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>
+  import JSelectUserByDept from '/@/components/Form/src/jeecg/components/JSelectUserByDept.vue';
+</#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>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeSearch.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeSearch.ftl
new file mode 100644
index 0000000..a16bf89
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeSearch.ftl
@@ -0,0 +1,85 @@
+<#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 need_select_tag = 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 query_field_dictCode="${po.dictField}">
+	</#if>
+	<#if po.queryMode=='single'>
+          <#if query_field_no gt 1>  </#if><a-col :lg="8">
+            <#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 placeholder="请选择${po.filedComment}" v-model:value="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-dept placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" />
+            <#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 />
+            <#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}" />
+            <#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)" />
+            <#elseif po.classType=='date'>
+              <#if query_field_no gt 1>  </#if><a-date-picker valueFormat="YYYY-MM-DD" placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" />
+            <#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}" />
+            <#elseif po.classType=='pca'>
+              <#if query_field_no gt 1>  </#if><j-area-linkage v-model:value="queryParam.${po.fieldName}" placeholder="请选择${po.filedComment}" @change="(value) => handleAreaChange('${po.fieldName}', value)" /> 
+            <#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}" />
+            <#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: '${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" />
+            <#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:value="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:value="queryParam.${po.fieldName}" dictCode="${po.dictField}"/>
+            <#else>
+              <#if query_field_no gt 1>  </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${po.fieldName}"></a-input>
+         </#if>
+      <#else>
+              <#if query_field_no gt 1>  </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="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 :lg="8">
+            <#if query_field_no gt 1>  </#if><a-form-item label="${po.filedComment}">
+      <#if po.classType=='date'>
+               <#if query_field_no gt 1>  </#if><a-date-picker value-format="YYYY-MM-DD" placeholder="请选择开始时间" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust"/>
+               <#if query_field_no gt 1>  </#if><span class="query-group-split-cust">~</span>
+               <#if query_field_no gt 1>  </#if><a-date-picker value-format="YYYY-MM-DD" placeholder="请选择结束日期" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust"/>
+      <#elseif po.classType=='datetime'>
+               <#if query_field_no gt 1>  </#if><a-date-picker showTime value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust" />
+               <#if query_field_no gt 1>  </#if><span class="query-group-split-cust">~</span>
+               <#if query_field_no gt 1>  </#if><a-date-picker showTime value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust" />
+      <#else>
+               <#if query_field_no gt 1>  </#if><a-input placeholder="请输入最小值" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust"></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="请输入最大值" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust"></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>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/vue3Jvxepopup.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/vue3Jvxepopup.ftl
new file mode 100644
index 0000000..3f671e1
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/vue3Jvxepopup.ftl
@@ -0,0 +1,13 @@
+<#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: '${targetFields[fieldName_index]}' },
+    </#list>
+      ],
+    <#if col.readonly=='Y'>
+        disabled:true,
+    </#if>
+
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/vue3popup.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/vue3popup.ftl
new file mode 100644
index 0000000..21deec1
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/vue3popup.ftl
@@ -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: '${targetFields[fieldName_index]}' },
+                </#list>
+            ],
+            multi:${po.extendParams.popupMulti?c}
+        }
+    },
+
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/sql/menu_insert.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/sql/menu_insert.ftl
new file mode 100644
index 0000000..ac35200
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/sql/menu_insert.ftl
@@ -0,0 +1,5 @@
+-- 注意:该页面对应的前台目录为views/${entityPackage}文件夹下
+-- 如果你想更改到其他目录,请修改sql中component字段对应的值
+
+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 ('${.now?string["yyyyMMddhhmmSSsss"]}', NULL, '${tableVo.ftlDescription}', '/${entityPackage}/${entityName?uncap_first}List', '${entityPackage}/${entityName}List', NULL, NULL, 0, NULL, '1', 1.00, 0, NULL, 1, 1, 0, 0, 0, NULL, '1', 0, 0, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0);
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/utils.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/utils.ftl
index 0acf2d5..c7c5df6 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/utils.ftl
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/utils.ftl
@@ -25,7 +25,7 @@
     <#return text?uncap_first>
 </#function>
 <#-- 驼峰转下划线 -->
-<#function camelToDashed(str, case='normal')>
+<#function camelToDashed(str, case='lower')>
   <#return camelToChar(str, "_", case)>
 </#function>
 <#---->
@@ -130,4 +130,44 @@
           <#return "{type:'${po.fieldDbType}',value:'${po.fieldName}',text:'${po.filedComment}'}">
       </#if>
   </#if>
+</#function>
+
+
+<#-- 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>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3CoreNative.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3CoreNative.ftl
new file mode 100644
index 0000000..45b269f
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3CoreNative.ftl
@@ -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}$/, message: '请输入6到16位数字!'}<#rt>,
+<#-- 6到16位任意字符 -->
+<#elseif fieldValidType == '*6-16'>
+ { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}<#rt>,
+<#-- 6到18位字符串 -->
+<#elseif fieldValidType == 's6-18'>
+ { pattern: /^.{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: /^[1-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>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3MainNative.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3MainNative.ftl
new file mode 100644
index 0000000..e941c4d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3MainNative.ftl
@@ -0,0 +1,6 @@
+<#include "../../utils.ftl">
+<#list columns as po>
+  <#if po.isShow == 'Y' && poHasCheck(po)>
+    ${po.fieldName}: [<#include "vue3CoreNative.ftl">],
+  </#if>
+</#list>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/sub-vue3.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/sub-vue3.ftl
new file mode 100644
index 0000000..d405358
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/sub-vue3.ftl
@@ -0,0 +1,23 @@
+<#include "../utils.ftl">
+    <#if col.isShow == 'Y' && poHasCheck(col)>
+        validateRules: [
+        <#if col.fieldName != 'id'>
+            <#assign subFieldValidType = col.fieldValidType!''>
+        <#-- 非空校验 -->
+            <#if col.nullable == 'N' || fieldValidType == '*'>
+          { required: true, message: '${'$'}{title}不能为空' },
+            <#elseif fieldValidType!=''>
+          { 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>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
index 024fa25..8ffddae 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 package ${bussiPackage}.${entityPackage}.entity;
 
 import java.io.Serializable;
@@ -36,9 +37,9 @@ public class ${entityName} implements Serializable {
     <#-- 生成字典Code -->
     <#assign list_field_dictCode="">
     <#if po.classType='sel_user'>
-      <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'>
+      <#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 = "depart_name", dicCode = "id"'>
+      <#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}"'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
index c0b44d9..3a46fab 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
@@ -48,7 +48,7 @@
                 @input="popupCallback"
                 <#if po.readonly=='Y'>disabled</#if>/>
     <#elseif po.classType =='sel_depart'>
-              <j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if> />
+              <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'>
@@ -58,7 +58,7 @@
     <#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}" <#if po.readonly=='Y'>disabled</#if>/>
+              <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'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
index 167fb6a..3a85e4b 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
@@ -46,6 +46,10 @@
       <template #htmlSlot="{text}">
          <div v-html="text"></div>
       </template>
+      <!--省市区字段回显插槽-->
+      <template #pcaSlot="{text}">
+         {{ getAreaTextByCode(text) }}
+      </template>
       <template #fileSlot="{text}">
          <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>
@@ -64,6 +68,10 @@
   import ${entityName}Modal from './components/${entityName}Modal.vue'
   import {columns, searchFormSchema} from './${entityName}.data';
   import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api';
+  import { downloadFile } from '/@/utils/common/renderUtils';
+  <#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';
@@ -84,6 +92,17 @@
               schemas: searchFormSchema,
               autoSubmitOnEnter:true,
               showAdvancedButton:true,
+              fieldMapToNumber: [
+              <#list columns as po>
+              <#if po.isQuery=='Y'>
+              <#if po.queryMode!='single'>
+              <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+                 ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end']],
+              </#if>
+              </#if>
+              </#if>
+              </#list>
+              ],
               fieldMapToTime: [
               <#list columns as po>
               <#if po.isQuery=='Y'>
@@ -100,6 +119,7 @@
             },
            actionColumn: {
                width: 120,
+               fixed:'right'
             },
       },
        exportConfig: {
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
index dc4cd58..7087240 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 import {BasicColumn} from '/@/components/Table';
 import {FormSchema} from '/@/components/Table';
 import { rules} from '/@/utils/helper/validator';
@@ -24,7 +25,7 @@ export const columns: BasicColumn[] = [
     slots: { customRender: 'htmlSlot' },
     <#elseif po.classType=='pca'>
     dataIndex: '${po.fieldName}',
-    slots: { customRender: 'pcaSlot' },//TODO 未翻译
+    slots: { customRender: 'pcaSlot' },
    <#elseif po.classType=='file'>
     dataIndex: '${po.fieldName}',
     slots: { customRender: 'fileSlot' },
@@ -56,7 +57,7 @@ export const columns: BasicColumn[] = [
        return  render.renderCategoryTree(text,'${po.dictField?default("")}')
    },
    <#else>
-    customRender: (text, record) => (text ? record['${po.dictText}'] : '')
+    customRender: ({text, record}) => (text ? record['${po.dictText}'] : '')
    </#if>
    <#else>
     dataIndex: '${po.fieldName}'
@@ -83,7 +84,7 @@ export const searchFormSchema: FormSchema[] = [
 <#if po.queryMode=='single'>
 	{
       label: "${po.filedComment}",
-      field: "${po.fieldName}",
+      field: ${autoStringSuffix(po)},
 <#if po.classType=='sel_search'>
       component: 'JSearchSelect',
       componentProps:{
@@ -94,17 +95,23 @@ export const searchFormSchema: FormSchema[] = [
 <#elseif po.classType=='switch'>
       component: 'JSwitch',
       componentProps:{
+           query:true,
            <#if po.dictField != 'is_open'>
-           options:"${po.dictField}"
+           options:${po.dictField}
            </#if>
        },
  <#elseif po.classType=='sel_depart'>
       component: 'JSelectDept',
  <#elseif po.classType=='list_multi'>
-      component: 'JMultiSelectTag',//暂无该组件
+      component: 'JSelectMultiple',
       componentProps:{
-          dictCode:"query_field_dictCode?default("")"
-      },
+     <#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:{
@@ -117,19 +124,15 @@ export const searchFormSchema: FormSchema[] = [
       componentProps: {
          showTime:true
        },
+ <#elseif po.classType =='time'>
+     component: 'TimePicker',
+     componentProps: {
+       valueFormat: 'HH:mm:ss'
+     },
 <#elseif po.classType=='pca'>
       component: 'JAreaLinkage',
 <#elseif po.classType=='popup'>
-      component: 'JPopup',
-      componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:"${po.dictField}",
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
 <#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
 <#--  ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
       component: 'JDictSelectTag',
@@ -156,6 +159,8 @@ export const searchFormSchema: FormSchema[] = [
       componentProps: {
           showTime:true
       },
+<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+      component: 'JRangeNumber',
 <#else>
       component: 'Input', //TODO 范围查询
 </#if>
@@ -188,27 +193,22 @@ export const formSchema: FormSchema[] = [
 	</#if>
   {
     label: '${po.filedComment}',
-    field: '${po.fieldName}',
+    field: ${autoStringSuffix(po)},
     <#if po.classType =='date'>
     component: 'DatePicker',
-     <#elseif po.fieldType =='datetime'>
+     <#elseif po.classType =='datetime'>
     component: 'DatePicker',
     componentProps: {
-       showTime:true
+       showTime: true,
+       valueFormat: 'YYYY-MM-DD HH:mm:ss'
      },
-     <#elseif po.fieldType =='time'>
+     <#elseif po.classType =='time'>
     component: 'TimePicker',
+    componentProps: {
+      valueFormat: 'HH:mm:ss'
+    },
     <#elseif po.classType =='popup'>
-    component: 'JPopup',
-    componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:${po.dictField},
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
      <#elseif po.classType =='sel_depart'>
      component: 'JSelectDept',
      <#elseif po.classType =='switch'>
@@ -230,14 +230,14 @@ export const formSchema: FormSchema[] = [
         labelKey:'realname',
      },
     <#elseif po.classType =='textarea'>
-    component: 'InputTextArea',//TODO 注意string转换问题
+    component: 'InputTextArea',
     <#elseif po.classType=='list' || po.classType=='radio'>
     component: 'JDictSelectTag',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
     <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
-    component: 'JMultiSelectTag',//TODO  暂无该组件
+    component: 'JSelectMultiple',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
@@ -272,7 +272,7 @@ export const formSchema: FormSchema[] = [
     </#if>
       },
   <#elseif po.classType=='umeditor'>
-    component: 'JCodeEditor', //TODO String后缀暂未添加
+    component: 'JEditor',
   <#elseif po.classType == 'sel_tree'>
     component: 'JTreeSelect',
     componentProps:{
@@ -290,7 +290,6 @@ export const formSchema: FormSchema[] = [
    <#else>
     component: 'Input',
     </#if>
-     <#include "/common/utils.ftl">
     <#if po.isShow == 'Y' && poHasCheck(po)>
     dynamicRules: ({model,schema}) => {
     <#if po.fieldName != 'id'>
@@ -304,16 +303,16 @@ export const formSchema: FormSchema[] = [
            </#if>
        <#-- 唯一校验 -->
            <#if fieldValidType == 'only'>
-                 {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
+                 {...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}$/, message: '请输入6到16位数字!'},
            <#-- 6到16位任意字符 -->
            <#elseif fieldValidType == '*6-16'>
                  { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
-           <#-- 6到18位字符串 -->
+           <#-- 6到18位字母 -->
            <#elseif fieldValidType == 's6-18'>
-                 { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
+                 { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
            <#-- 网址 -->
            <#elseif fieldValidType == 'url'>
                  { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
index fd54ae4..51dcb22 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
@@ -1,5 +1,6 @@
+<#include "/common/utils.ftl">
 <template>
-  <BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
+  <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
       <BasicForm @register="registerForm"/>
   </BasicModal>
 </template>
@@ -18,6 +19,7 @@
         labelWidth: 150,
         schemas: formSchema,
         showActionButtonGroup: false,
+        baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}
     });
     //表单赋值
     const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
@@ -54,5 +56,12 @@
 </script>
 
 <style lang="less" scoped>
+	/** 时间和数字输入框样式 */
+  :deep(.ant-input-number){
+		width: 100%
+	}
 
+	:deep(.ant-calendar-picker){
+		width: 100%
+	}
 </style>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei
new file mode 100644
index 0000000..7961187
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei
@@ -0,0 +1,348 @@
+<template>
+  <div>
+<#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_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 query_flag = false>
+    <!--查询区域-->
+    <div class="jeecg-basic-table-form-container">
+      <a-form @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=='sel_tree'>
+<#assign need_select_tree = true>
+</#if>
+<#if po.classType=='time'>
+<#assign need_time = 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" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
+        <a-button  type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
+        <j-upload-button  type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
+        <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>批量操作
+            <Icon icon="mdi:chevron-down"></Icon>
+          </a-button>
+        </a-dropdown>
+      </template>
+      <!--操作栏-->
+      <template #action="{ record }">
+        <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
+      </template>
+      <!--字段回显插槽-->
+      <template #htmlSlot="{text}">
+        <div v-html="text"></div>
+      </template>
+      <!--省市区字段回显插槽-->
+      <template #pcaSlot="{text}">
+        {{ getAreaTextByCode(text) }}
+      </template>
+      <template #fileSlot="{text}">
+        <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>
+      </template>
+    </BasicTable>
+    <!-- 表单区域 -->
+    <${entityName}Modal ref="registerModal" @success="handleSuccess"></${entityName}Modal>
+  </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 } 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'
+  <#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>
+
+  const queryParam = ref<any>({});
+  const toggleSearchStatus = ref<boolean>(false);
+  const registerModal = ref();
+  //注册table数据
+  const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
+    tableProps: {
+      title: '${tableVo.ftlDescription}',
+      api: list,
+      columns,
+      canResize:false,
+      useSearchForm: false,
+      actionColumn: {
+        width: 120,
+        fixed: 'right',
+      },
+      beforeFetch: (params) => {
+        return Object.assign(params, queryParam.value);
+      },
+    },
+    exportConfig: {
+      name: "${tableVo.ftlDescription}",
+      url: getExportUrl,
+    },
+	  importConfig: {
+	    url: getImportUrl,
+	    success: handleSuccess
+	  },
+  });
+  const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
+  const labelCol = reactive({
+    xs: { span: 24 },
+    sm: { span: 7 },
+  });
+  const wrapperCol = reactive({
+    xs: { span: 24 },
+    sm: { span: 16 },
+  });
+
+  /**
+   * 新增事件
+   */
+  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),
+      },
+    ];
+  }
+   
+  /**
+   * 下拉操作栏
+   */
+  function getDropDownAction(record) {
+    return [
+      {
+        label: '详情',
+        onClick: handleDetail.bind(null, record),
+      },
+      {
+        label: '删除',
+        popConfirm: {
+          title: '是否确认删除',
+          confirm: handleDelete.bind(null, record),
+        },
+      },
+    ];
+  }
+
+  /**
+   * 查询
+   */
+  function searchQuery() {
+    reload();
+  }
+  
+  /**
+   * 重置
+   */
+  function searchReset() {
+    queryParam.value = {};
+    selectedRowKeys.value = [];
+    //刷新数据
+    reload();
+  }
+  
+  <#if need_popup>
+  /**
+   *  popup组件值改变事件
+   */
+  function setFieldsValue(map) {
+    Object.keys(map).map((key) => {
+      queryParam.value[key] = map[key];
+    });
+  }
+  </#if>
+
+  <#if need_pca>
+  /**
+   * 省市区点击事件
+   * @param key
+   * @param value
+   */
+  function handleAreaChange(key, value) {
+    queryParam.value[key] = value.join(',');
+  }
+  </#if>
+
+  <#if need_category>
+  /**
+   * form点击事件
+   * @param value
+   */
+  function handleFormChange(key, value) {
+    queryParam.value[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) {
+        let allDictDate = getAuthCache(DB_DICT_DATA_KEY);
+        if(!allDictDate['${po.dictField?default("")}']){
+          Object.assign(allDictDate,{'${po.dictField?default("")}':res})
+        }
+        setAuthCache(DB_DICT_DATA_KEY,allDictDate)
+      }
+    });
+     </#if>
+   </#if>
+   </#list>
+  }
+  initDictConfig();
+    </#if>
+</script>
+
+<style lang="less" scoped>
+  .jeecg-basic-table-form-container {
+    .table-page-search-submitButtons {
+      display: block;
+      margin-bottom: 24px;
+      white-space: nowrap;
+    }
+    .query-group-cust{
+      width: calc(50% - 15px);
+      min-width: 100px !important;
+    }
+    .query-group-split-cust{
+      width: 30px;
+      display: inline-block;
+      text-align: center
+    }
+  }
+</style>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi
new file mode 100644
index 0000000..75dfbdf
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi
@@ -0,0 +1,69 @@
+import { defHttp } from '/@/utils/http/axios';
+import { Modal } from 'ant-design-vue';
+
+enum Api {
+  list = '/${entityPackage}/${entityName?uncap_first}/list',
+  save='/${entityPackage}/${entityName?uncap_first}/add',
+  edit='/${entityPackage}/${entityName?uncap_first}/edit',
+  deleteOne = '/${entityPackage}/${entityName?uncap_first}/delete',
+  deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
+  importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
+  exportXls = '/${entityPackage}/${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 });
+
+/**
+ * 删除单个
+ * @param params
+ * @param handleSuccess
+ */
+export const deleteOne = (params,handleSuccess) => {
+  return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
+    handleSuccess();
+  });
+}
+
+/**
+ * 批量删除
+ * @param params
+ * @param handleSuccess
+ */
+export const batchDelete = (params, handleSuccess) => {
+  Modal.confirm({
+    title: '确认删除',
+    content: '是否删除选中数据',
+    okText: '确认',
+    cancelText: '取消',
+    onOk: () => {
+      return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
+        handleSuccess();
+      });
+    }
+  });
+}
+
+/**
+ * 保存或者更新
+ * @param params
+ * @param isUpdate
+ */
+export const saveOrUpdate = (params, isUpdate) => {
+  let url = isUpdate ? Api.edit : Api.save;
+  return defHttp.post({ url: url, params }, { isTransformResponse: false });
+}
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi
new file mode 100644
index 0000000..03a5779
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi
@@ -0,0 +1,366 @@
+<#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';
+//列表数据
+export const columns: BasicColumn[] = [
+ <#list columns as po>
+   <#if po.isShowList =='Y' && po.fieldName !='id'>
+  {
+    title: '${po.filedComment}',
+    align: "center",
+    <#if po.sort=='Y'>
+    sorter: true,
+   </#if>
+    <#if po.classType=='date'>
+    dataIndex: '${po.fieldName}',
+    customRender:({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}',
+    slots: { customRender: 'htmlSlot' },
+    <#elseif po.classType=='pca'>
+    dataIndex: '${po.fieldName}',
+    slots: { customRender: 'pcaSlot' },
+   <#elseif po.classType=='file'>
+    dataIndex: '${po.fieldName}',
+    slots: { customRender: 'fileSlot' },
+   <#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'>
+    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>
+<#if po.isQuery=='Y'>
+<#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: "${po.dictTable},${po.dictText},${po.dictField}"
+    },
+<#elseif po.classType=='sel_user'>
+    component: 'JSelectUserByDept',
+<#elseif po.classType=='switch'>
+    component: 'JSwitch',
+    componentProps:{
+      <#if po.dictField != 'is_open'>
+      options: "${po.dictField}"
+      </#if>
+    },
+ <#elseif po.classType=='sel_depart'>
+    component: 'JSelectDept',
+ <#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>
+    },
+ <#elseif po.classType=='cat_tree'>
+    component: 'JCategorySelect',
+    componentProps:{
+      pcode: "${po.dictField?default("")}",//back和事件未添加,暂时有问题
+    },
+<#elseif po.classType=='date'>
+    component: 'DatePicker',
+<#elseif po.classType=='datetime'>
+    component: 'DatePicker',
+    componentProps: {
+      showTime: true,
+    },
+ <#elseif po.classType =='time'>
+    component: 'TimePicker',
+    componentProps: {
+      valueFormat: 'HH:mm:ss',
+    },
+<#elseif po.classType=='pca'>
+    component: 'JAreaLinkage',
+<#elseif po.classType=='popup'>
+    <#include "/common/form/vue3popup.ftl">
+<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
+<#--  ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
+    component: 'JDictSelectTag',
+    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>
+    },
+<#else>
+    component: 'Input',
+</#if>
+    colProps: {span: 6},
+  },
+<#else>
+  {
+    label: "${po.filedComment}",
+    field: "${po.fieldName}",
+<#if po.classType=='date'>
+    component: 'RangePicker',
+<#elseif po.classType=='datetime'>
+    component: 'RangePicker',
+    componentProps: {
+      showTime: true,
+    },
+<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+    component: 'JRangeNumber',
+<#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>
+<#if po.isShow =='Y'>
+<#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)},
+    <#if po.classType =='date'>
+    component: 'DatePicker',
+     <#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 =='sel_depart'>
+    component: 'JSelectDept',
+    <#elseif po.classType =='switch'>
+    component: 'JSwitch',
+    componentProps:{
+      <#if po.dictField != 'is_open'>
+      options: ${po.dictField}
+      </#if>
+    },
+    <#elseif po.classType =='pca'>
+    component: 'JAreaLinkage',
+    <#elseif po.classType =='markdown'>
+    component: 'JMarkdownEditor',//注意string转换问题
+     <#elseif po.classType =='password'>
+    component: 'InputPassword',
+     <#elseif po.classType =='sel_user'>
+    component: 'JSelectUserByDept',
+    componentProps:{
+      labelKey: 'realname',
+    },
+    <#elseif po.classType =='textarea'>
+    component: 'InputTextArea',
+    <#elseif po.classType=='list' || po.classType=='radio'>
+    component: 'JDictSelectTag',
+    componentProps:{
+      dictCode: "${form_field_dictCode}"
+    },
+    <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
+    component: 'JSelectMultiple',
+    componentProps:{
+      dictCode: "${form_field_dictCode}"
+    },
+    <#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=='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}
+    </#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}",
+    },
+   <#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}$/, message: '请输入6到16位数字!'},
+           <#-- 6到16位任意字符 -->
+           <#elseif fieldValidType == '*6-16'>
+              { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
+           <#-- 6到18位字符串 -->
+           <#elseif fieldValidType == 's6-18'>
+              { pattern: /^.{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: /^[1-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>
+];
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei
new file mode 100644
index 0000000..0a835d2
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei
@@ -0,0 +1,185 @@
+<#include "/common/utils.ftl">
+<template>
+  <a-spin :spinning="confirmLoading">
+    <a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol">
+      <a-row>
+<#assign need_category = false>
+<#assign bpm_flag=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_select_tag = false>
+<#assign need_select_tree = false>
+<#assign need_time = false>
+<#assign need_markdown = false>
+<#assign need_upload = false>
+<#assign need_image_upload = false>
+<#assign need_editor = false>
+<#assign need_checkbox = false>
+<#assign hasOnlyValidate = 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.fieldValidType?default("") == 'only'>
+      <#assign hasOnlyValidate = true>
+</#if>
+  <#include "/common/form/native/vue3NativeForm.ftl">
+</#list>
+      </a-row>
+    </a-form>
+  </a-spin>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, defineExpose, nextTick, defineProps, computed } from 'vue';
+  import { defHttp } from '/@/utils/http/axios';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import moment from 'moment';
+  <#include "/common/form/native/vue3NativeImport.ftl">
+  import { getValueType } from '/@/utils';
+  import { saveOrUpdate } from '../${entityName}.api';
+  import { Form } from 'ant-design-vue';
+  <#if hasOnlyValidate == true>
+  import { duplicateValidate } from '/@/utils/helper/validator'
+  </#if>
+  
+  const props = defineProps({
+    disabled: { type: Boolean, default: false },
+  });
+  const formRef = ref();
+  const useForm = Form.useForm;
+  const emit = defineEmits(['register', 'ok']);
+  const formData = reactive<Record<string, any>>({
+<#list columns as po>
+ <#if po.isShow == 'Y'>
+  <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+    ${po.fieldName}: undefined,
+  <#elseif po.fieldDbType=='Blob'>
+    ${po.fieldName}String: '',
+  <#else>
+    ${po.fieldName}: '',   
+  </#if>
+ </#if>
+</#list>
+  });
+  const { createMessage } = useMessage();
+  const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } });
+  const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } });
+  const confirmLoading = ref<boolean>(false);
+  //表单验证
+  const validatorRules = {
+  <#include "/common/validatorRulesTemplate/native/vue3MainNative.ftl">
+  };
+  const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: true });
+  
+  /**
+   * 新增
+   */
+  function add() {
+    edit({});
+  }
+
+  /**
+   * 编辑
+   */
+  function edit(record) {
+    nextTick(() => {
+      resetFields();
+      //赋值
+      Object.assign(formData, record);
+    });
+  }
+
+  /**
+   * 提交数据
+   */
+  async function submitForm() {
+    // 触发表单验证
+    await validate();
+    confirmLoading.value = true;
+    const isUpdate = ref<boolean>(false);
+    //时间格式化
+    let model = formData;
+    if (model.id) {
+      isUpdate.value = true;
+    }
+    //循环数据
+    for (let data in model) {
+      //如果该数据是数组并且是字符串类型
+      if (model[data] instanceof Array) {
+        let valueType = getValueType(formRef.value.getProps, data);
+        //如果是字符串类型的需要变成以逗号分割的字符串
+        if (valueType === 'string') {
+          model[data] = model[data].join(',');
+        }
+      }
+    }
+    await saveOrUpdate(model, isUpdate.value)
+      .then((res) => {
+        if (res.success) {
+          createMessage.success(res.message);
+          emit('ok');
+        } else {
+          createMessage.warning(res.message);
+        }
+      })
+      .finally(() => {
+        confirmLoading.value = false;
+      });
+  }
+
+	<#if need_popup>
+  /**
+   *  popup组件值改变事件
+   */
+  function setFieldsValue(map) {
+    Object.keys(map).map((key) => {
+      formData[key] = map[key];
+    });
+  }
+	</#if>
+
+	<#if need_category || need_select_tree>
+  /**
+   * 值改变事件触发
+   * @param key
+   * @param value
+   */
+  function handleFormChange(key, value) {
+    formData[key] = value;
+  }
+  </#if>
+ <#list columns as po>
+  <#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'>
+  async function ${po.fieldName}Duplicatevalidate(_r, value) {
+    return duplicateValidate('${tableName}', '${po.fieldDbName}', value, formData.id || '')
+  }
+  </#if>
+  </#list>
+  defineExpose({
+    add,
+    edit,
+    submitForm,
+  });
+</script>
+
+<style lang="less" scoped>
+  .antd-modal-form {
+    height: 500px !important;
+    overflow-y: auto;
+    padding: 24px 24px 24px 24px;
+  }
+</style>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei
new file mode 100644
index 0000000..391bb77
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei
@@ -0,0 +1,75 @@
+<template>
+  <a-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
+    <${entityName}Form ref="registerForm" @ok="submitCallback" :disabled="disableSubmit"></${entityName}Form>
+  </a-modal>
+</template>
+
+<script lang="ts" setup>
+  import { ref, nextTick, defineExpose } from 'vue';
+  import ${entityName}Form from './${entityName}Form.vue'
+  
+  const title = ref<string>('');
+  const width = ref<number>(800);
+  const visible = ref<boolean>(false);
+  const disableSubmit = ref<boolean>(false);
+  const registerForm = ref();
+  const emit = defineEmits(['register', 'success']);
+
+  /**
+   * 新增
+   */
+  function add() {
+    title.value = '新增';
+    visible.value = true;
+    nextTick(() => {
+      registerForm.value.add();
+    });
+  }
+  
+  /**
+   * 编辑
+   * @param record
+   */
+  function edit(record) {
+    title.value = disableSubmit.value ? '详情' : '编辑';
+    visible.value = true;
+    nextTick(() => {
+      registerForm.value.edit(record);
+    });
+  }
+  
+  /**
+   * 确定按钮点击事件
+   */
+  function handleOk() {
+    registerForm.value.submitForm();
+  }
+
+  /**
+   * form保存回调事件
+   */
+  function submitCallback() {
+    handleCancel();
+    emit('success');
+  }
+
+  /**
+   * 取消按钮回调事件
+   */
+  function handleCancel() {
+    visible.value = false;
+  }
+
+  defineExpose({
+    add,
+    edit,
+    disableSubmit,
+  });
+</script>
+
+<style>
+  /**隐藏样式-modal确定按钮 */
+  .jee-hidden {
+    display: none !important;
+  }
+</style>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
index 43919c8..b1d90eb 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
@@ -205,17 +205,14 @@ public class ${entityName}Controller {
       QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap());
       LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
 
-      //Step.2 获取导出数据
-      List<${entityName}> queryList = ${entityName?uncap_first}Service.list(queryWrapper);
-      // 过滤选中数据
+      //配置选中数据查询条件
       String selections = request.getParameter("selections");
-      List<${entityName}> ${entityName?uncap_first}List = new ArrayList<${entityName}>();
-      if(oConvertUtils.isEmpty(selections)) {
-          ${entityName?uncap_first}List = queryList;
-      }else {
+      if(oConvertUtils.isNotEmpty(selections)) {
           List<String> selectionList = Arrays.asList(selections.split(","));
-          ${entityName?uncap_first}List = queryList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
+          queryWrapper.in("id",selectionList);
       }
+      //Step.2 获取导出数据
+      List<${entityName}> ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper);
 
       // Step.3 组装pageList
       List<${entityName}Page> pageList = new ArrayList<${entityName}Page>();
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
index 2c9aba3..8ed5d49 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 package ${bussiPackage}.${entityPackage}.entity;
 
 import java.io.Serializable;
@@ -31,9 +32,9 @@ public class ${entityName} implements Serializable {
     <#-- 生成字典Code -->
     <#assign list_field_dictCode="">
     <#if po.classType='sel_user'>
-      <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'>
+      <#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 = "depart_name", dicCode = "id"'>
+      <#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}"'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
index cfc7129..7530402 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 <#list subTables as subTab>
 #segment#${subTab.entityName}.java
 package ${bussiPackage}.${entityPackage}.entity;
@@ -32,9 +33,9 @@ public class ${subTab.entityName} implements Serializable {
 	<#-- 生成字典Code -->
 	<#assign list_field_dictCode="">
 	<#if po.classType='sel_user'>
-		<#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'>
+		<#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 = "depart_name", dicCode = "id"'>
+		<#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}"'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
index 5cd51c9..255ab0a 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
@@ -48,7 +48,7 @@
                 @input="popupCallback"
                 <#if po.readonly=='Y'>disabled</#if>/>
     <#elseif po.classType =='sel_depart'>
-              <j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/>
+              <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'>
@@ -58,7 +58,7 @@
     <#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}" <#if po.readonly=='Y'>disabled</#if>/>
+              <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'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
index 80dc0f7..acb82d2 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
@@ -44,7 +44,7 @@
                 :multi="${po.extendParams.popupMulti?c}"
                 @input="popupCallback"/>
     <#elseif po.classType =='sel_depart'>
-              <j-select-depart v-model="model.${po.fieldName}" multi/>
+              <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>></j-switch>
 	<#elseif po.classType =='pca'>
@@ -54,7 +54,7 @@
     <#elseif po.classType =='password'>
 	          <a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"/>
 	<#elseif po.classType =='sel_user'>
-              <j-select-user-by-dep v-model="model.${po.fieldName}"/>
+              <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}"/>
 	<#elseif po.classType=='list' || po.classType=='radio'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
index dfcd1b3..f3975bd 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 package ${bussiPackage}.${entityPackage}.entity;
 
 import java.io.Serializable;
@@ -32,9 +33,9 @@ public class ${entityName} implements Serializable {
 	<#-- 生成字典Code -->
 	<#assign list_field_dictCode="">
 	<#if po.classType='sel_user'>
-		<#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'>
+		<#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 = "depart_name", dicCode = "id"'>
+		<#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}"'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei
index 2c8a29d..2f5ff3f 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei
@@ -56,9 +56,9 @@
             @input="popupCallback"
             <#if po.readonly=='Y'>disabled</#if>/>
 	<#elseif po.classType =='sel_depart'>
-          <j-select-depart v-model="model.${po.fieldName}"  <#if po.readonly=='Y'>disabled</#if>/>
+          <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 =='sel_user'>
-          <j-select-user-by-dep v-model="model.${po.fieldName}"  <#if po.readonly=='Y'>disabled</#if>/>
+          <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'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
index 98b2908..d71792a 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
@@ -8,6 +8,13 @@
     <#assign hasChildrenField = po.fieldName>
   </#if>
 </#list>
+<#assign list_need_pca=false>
+<#-- 开始循环 -->
+<#list columns as po>
+<#if po.classType=='pca'>
+<#assign list_need_pca=true>
+</#if>
+</#list>
 <template>
   <div>
     <!--引用表格-->
@@ -34,8 +41,20 @@
       </template>
       <!--操作栏-->
       <template #action="{ record }">
-        <TableAction :actions="getTableAction(record)"/>
+        <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
       </template>
+       <!--字段回显插槽-->
+    <template #htmlSlot="{text}">
+       <div v-html="text"></div>
+    </template>
+    <!--省市区字段回显插槽-->
+    <template #pcaSlot="{text}">
+       {{ getAreaTextByCode(text) }}
+    </template>
+    <template #fileSlot="{text}">
+       <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>
+    </template>
     </BasicTable>
     <!--字典弹窗-->
     <${entityName}Modal @register="registerModal" @success="handleSuccess"/>
@@ -49,9 +68,12 @@
   import {useModal} from '/@/components/Modal';
   import { useListPage } from '/@/hooks/system/useListPage'
   import ${entityName}Modal from './components/${entityName}Modal.vue';
-  import {columns} from './${entityName}.data';
+  import {columns,searchFormSchema} from './${entityName}.data';
+  import { downloadFile } from '/@/utils/common/renderUtils';
   import {list, delete${entityName}, batchDelete${entityName}, getExportUrl,getImportUrl, getChildList,getChildListBatch} from './${entityName}.api';
-
+  <#if list_need_pca>
+  import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
+  </#if>
   const expandedRowKeys = ref([]);
   //字典model
   const [registerModal, {openModal}] = useModal();
@@ -62,6 +84,36 @@
          title: '${tableVo.ftlDescription}',
          columns,
          canResize:false,
+         formConfig: {
+           labelWidth: 120,
+           schemas: searchFormSchema,
+           autoSubmitOnEnter:true,
+           showAdvancedButton:true,
+           fieldMapToNumber: [
+           <#list columns as po>
+           <#if po.isQuery=='Y'>
+           <#if po.queryMode!='single'>
+           <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+              ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end']],
+           </#if>
+           </#if>
+           </#if>
+           </#list>
+           ],
+           fieldMapToTime: [
+           <#list columns as po>
+           <#if po.isQuery=='Y'>
+           <#if po.queryMode!='single'>
+           <#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: 240,
          },
@@ -120,13 +172,13 @@
    */
   async function batchHandleDelete() {
     const ids = selectedRowKeys.value.filter(item => !item.includes('loading'))
-    await batchDelete${entityName}({ids: ids}, importSuccess);
+    await batchDelete${entityName}({id: ids}, importSuccess);
   }
   /**
    * 导入
    */
    function importSuccess() {
-    reload() && (expandedRowKeys.value = []);
+    (selectedRowKeys.value = []) && reload();
   }
   /**
    * 添加下级
@@ -140,12 +192,16 @@
   /**
    * 成功回调
    */
-  async function handleSuccess({isUpdate, values, expandedArr}) {
+  async function handleSuccess({isUpdate, values, expandedArr, changeParent}) {
     if (isUpdate) {
-      //编辑回调
-      updateTableDataRecord(values.id, values);
+      if (changeParent) {
+        reload();
+      } else {
+        // 编辑回调
+        updateTableDataRecord(values.id, values);
+      }
     } else {
-        if(!values['${pidFieldName}']){
+        if(!values['id'] || !values['${pidFieldName}']){
             //新增根节点
             reload();
         }else{
@@ -264,18 +320,28 @@
         onClick: handleEdit.bind(null, record),
       },
       {
-        label: '删除',
-        popConfirm: {
-          title: '确定删除吗?',
-          confirm: handleDelete.bind(null, record),
-        },
-      },
-      {
         label: '添加下级',
         onClick: handleAddSub.bind(null, {${pidFieldName}: record.id}),
       }
     ]
   }
+   /**
+    * 下拉操作栏
+    */
+   function getDropDownAction(record){
+        return [
+             {
+               label: '详情',
+               onClick: handleDetail.bind(null, record),
+             }, {
+               label: '删除',
+               popConfirm: {
+                 title: '确定删除吗?',
+                 confirm: handleDelete.bind(null, record),
+               }
+             }
+        ]
+   }
 </script>
 
 <style scoped>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi
index 2cbeee0..8b52377 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi
@@ -6,7 +6,6 @@ enum Api {
   save='/${entityPackage}/${entityName?uncap_first}/add',
   edit='/${entityPackage}/${entityName?uncap_first}/edit',
   delete${entityName} = '/${entityPackage}/${entityName?uncap_first}/delete',
-  deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
   importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
   exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
   loadTreeData = '/${entityPackage}/${entityName?uncap_first}/loadTreeRoot',
@@ -49,7 +48,7 @@ export const batchDelete${entityName} = (params, handleSuccess) => {
     okText: '确认',
     cancelText: '取消',
     onOk: () => {
-      return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
+      return defHttp.delete({url: Api.delete${entityName}, data: params}, {joinParamsToUrl: true}).then(() => {
         handleSuccess();
       });
     }
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
index d83a727..f9e2486 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 import {BasicColumn} from '/@/components/Table';
 import {FormSchema} from '/@/components/Table';
 import { rules} from '/@/utils/helper/validator';
@@ -28,7 +29,7 @@ export const columns: BasicColumn[] = [
     slots: { customRender: 'htmlSlot' },
     <#elseif po.classType=='pca'>
     dataIndex: '${po.fieldName}',
-    slots: { customRender: 'pcaSlot' },//TODO 未翻译
+    slots: { customRender: 'pcaSlot' },
    <#elseif po.classType=='file'>
     dataIndex: '${po.fieldName}',
     slots: { customRender: 'fileSlot' },
@@ -60,7 +61,7 @@ export const columns: BasicColumn[] = [
        return  render.renderCategoryTree(text,'${po.dictField?default("")}')
    },
    <#else>
-    customRender: (text, record) => (text ? record['${po.dictText}'] : '')
+    customRender: ({text, record}) => (text ? record['${po.dictText}'] : '')
    </#if>
    <#else>
     dataIndex: '${po.fieldName}'
@@ -105,9 +106,14 @@ export const searchFormSchema: FormSchema[] = [
  <#elseif po.classType=='sel_depart'>
       component: 'JSelectDept',
  <#elseif po.classType=='list_multi'>
-      component: 'JMultiSelectTag',//暂无该组件
-      componentProps:{
-          dictCode:"query_field_dictCode?default("")"
+      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',
@@ -124,15 +130,22 @@ export const searchFormSchema: FormSchema[] = [
 <#elseif po.classType=='pca'>
       component: 'JAreaLinkage',
 <#elseif po.classType=='popup'>
-      component: 'JPopup',
-      componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:"${po.dictField}",
-             multi:${po.extendParams.popupMulti?c},
-         }
+    <#include "/common/form/vue3popup.ftl">
+<#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]}",
+           </#if>
+           <#if po.dictText?split(',')[1]??>
+         pidField:"${po.dictText?split(',')[1]}",
+           </#if>
+           <#if po.dictText?split(',')[3]??>
+         hasChildField:"${po.dictText?split(',')[3]}",
+           </#if>
+           </#if>
+         pidValue:"${po.dictField}",
      },
 <#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
 <#--  ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
@@ -160,6 +173,13 @@ export const searchFormSchema: FormSchema[] = [
       componentProps: {
           showTime:true
       },
+<#elseif po.classType == 'time'>
+      component: 'TimePicker',
+      componentProps:{
+        valueFormat: 'HH:mm:ss',
+      },
+<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+      component: 'JRangeNumber',
 <#else>
       component: 'Input', //TODO 范围查询
 </#if>
@@ -192,7 +212,7 @@ export const formSchema: FormSchema[] = [
 	</#if>
   {
     label: '${po.filedComment}',
-    field: '${po.fieldName}',
+    field: ${autoStringSuffix(po)},
     <#if po.fieldDbName == tableVo.extendParams.pidField>
     component: 'JTreeSelect',
     componentProps: {
@@ -203,24 +223,19 @@ export const formSchema: FormSchema[] = [
     },
     <#elseif po.classType =='date'>
     component: 'DatePicker',
-     <#elseif po.fieldType =='datetime'>
+     <#elseif po.classType =='datetime'>
     component: 'DatePicker',
     componentProps: {
-       showTime:true
+       showTime:true,
+       valueFormat: 'YYYY-MM-DD hh:mm:ss'
      },
-     <#elseif po.fieldType =='time'>
+    <#elseif po.classType =='time'>
     component: 'TimePicker',
+    componentProps:{
+      valueFormat: 'HH:mm:ss',
+    },
     <#elseif po.classType =='popup'>
-    component: 'JPopup',
-    componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:${po.dictField},
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
      <#elseif po.classType =='sel_depart'>
      component: 'JSelectDept',
      <#elseif po.classType =='switch'>
@@ -242,14 +257,14 @@ export const formSchema: FormSchema[] = [
         labelKey:'realname',
      },
     <#elseif po.classType =='textarea'>
-    component: 'InputTextArea',//TODO 注意string转换问题
+    component: 'InputTextArea',
     <#elseif po.classType=='list' || po.classType=='radio'>
     component: 'JDictSelectTag',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
     <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
-    component: 'JMultiSelectTag',//TODO  暂无该组件
+    component: 'JSelectMultiple',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
@@ -284,7 +299,7 @@ export const formSchema: FormSchema[] = [
     </#if>
       },
   <#elseif po.classType=='umeditor'>
-    component: 'JCodeEditor', //TODO String后缀暂未添加
+    component: 'JEditor',
   <#elseif po.classType == 'sel_tree'>
     component: 'JTreeSelect',
     componentProps:{
@@ -318,16 +333,16 @@ export const formSchema: FormSchema[] = [
            </#if>
        <#-- 唯一校验 -->
            <#if fieldValidType == 'only'>
-                 {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
+                 {...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}$/, message: '请输入6到16位数字!'},
            <#-- 6到16位任意字符 -->
            <#elseif fieldValidType == '*6-16'>
                  { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
-           <#-- 6到18位字符串 -->
+           <#-- 6到18位字母 -->
            <#elseif fieldValidType == 's6-18'>
-                 { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
+                 { pattern:/^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
            <#-- 网址 -->
            <#elseif fieldValidType == 'url'>
                  { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
index a4294d7..c513462 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 <#assign pidFieldName = "">
 <#assign hasChildrenField = "">
 <#list originalColumns as po>
@@ -9,7 +10,7 @@
   </#if>
 </#list>
 <template>
-  <BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
+  <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" :title="getTitle" @ok="handleSubmit">
     <BasicForm @register="registerForm"/>
   </BasicModal>
 </template>
@@ -24,10 +25,13 @@
   const isUpdate = ref(true);
   const expandedRowKeys = ref([]);
   const treeData = ref([]);
+  // 当前编辑的数据
+  let model:Nullable<Recordable> = null;
   //表单配置
-  const [registerForm, {resetFields, setFieldsValue, validate, updateSchema}] = useForm({
+  const [registerForm, {setProps,resetFields, setFieldsValue, validate, updateSchema}] = useForm({
     schemas: formSchema,
     showActionButtonGroup: false,
+    baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}},
     labelCol: {
       xs: { span: 24 },
       sm: { span: 4 },
@@ -42,16 +46,21 @@
     //重置表单
     await resetFields();
     expandedRowKeys.value = [];
-    setModalProps({confirmLoading: false, minHeight: 80});
+    setModalProps({confirmLoading: false, minHeight: 80 ,showOkBtn: !!!data?.hideFooter});
     isUpdate.value = !!data?.isUpdate;
     if (data?.record) {
+      model = data.record;
       //表单赋值
       await setFieldsValue({
         ...data.record,
       });
+    } else {
+      model = null;
     }
     //父级节点树信息
     treeData.value = await loadTreeData({'async': false,'pcode':''});
+    // 隐藏底部时禁用整个表单
+    setProps({ disabled: !!data?.hideFooter })
   });
   //设置标题
   const getTitle = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
@@ -85,9 +94,25 @@
       //展开的节点信息
       await getExpandKeysByPid(values['${pidFieldName}'],unref(treeData))
       //刷新列表(isUpdate:是否编辑;values:表单信息;expandedArr:展开的节点信息)
-      emit('success', {isUpdate: unref(isUpdate), values:{...values},expandedArr: unref(expandedRowKeys).reverse()});
+      emit('success', {
+        isUpdate: unref(isUpdate),
+        values: {...values},
+        expandedArr: unref(expandedRowKeys).reverse(),
+        // 是否更改了父级节点
+        changeParent: model != null && (model['${pidFieldName}'] != values['${pidFieldName}']),
+      });
     } finally {
       setModalProps({confirmLoading: false});
     }
   }
 </script>
+<style lang="less" scoped>
+	/** 时间和数字输入框样式 */
+    :deep(.ant-input-number){
+		width: 100%
+	}
+
+	:deep(.ant-calendar-picker){
+		width: 100%
+	}
+</style>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei
new file mode 100644
index 0000000..39a9f3c
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei
@@ -0,0 +1,497 @@
+<template>
+  <div>
+<#assign pidFieldName = "">
+<#assign hasChildrenField = "">
+<#list originalColumns as po>
+  <#if po.fieldDbName == tableVo.extendParams.pidField>
+    <#assign pidFieldName = po.fieldName>
+  </#if>
+  <#if po.fieldDbName == tableVo.extendParams.hasChildren>
+    <#assign hasChildrenField = po.fieldName>
+  </#if>
+</#list>  
+<#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_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 query_flag = false>
+    <!--查询区域-->
+    <div class="jeecg-basic-table-form-container">
+      <a-form @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=='sel_tree'>
+<#assign need_select_tree = true>
+</#if>
+<#if po.classType=='time'>
+<#assign need_time = 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" :expandedRowKeys="expandedRowKeys" @expand="handleExpand" @fetch-success="onFetchSuccess">
+      <!--插槽:table标题-->
+      <template #tableTitle>
+        <a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
+        <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
+            >批量操作
+            <Icon icon="ant-design:down-outlined"></Icon>
+          </a-button>
+        </a-dropdown>
+      </template>
+      <!--操作栏-->
+      <template #action="{ record }">
+        <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
+      </template>
+      <!--字段回显插槽-->
+      <template #htmlSlot="{ text }">
+        <div v-html="text"></div>
+      </template>
+      <!--省市区字段回显插槽-->
+      <template #pcaSlot="{ text }">
+        {{ getAreaTextByCode(text) }}
+      </template>
+      <template #fileSlot="{ text }">
+        <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>
+      </template>
+    </BasicTable>
+    <!-- 表单区域 -->
+    <${entityName}Modal ref="registerModal" @success="handleSuccess"></${entityName}Modal>
+  </div>
+</template>
+
+<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup>
+  import { ref, reactive, unref } from 'vue';
+  import { BasicTable, useTable, TableAction } from '/@/components/Table';
+  import { useListPage } from '/@/hooks/system/useListPage';
+  import { columns } from './${entityName}.data';
+  import {list, delete${entityName}, batchDelete${entityName}, getExportUrl,getImportUrl, getChildList,getChildListBatch} from './${entityName}.api';
+  import { downloadFile } from '/@/utils/common/renderUtils';
+  import ${entityName}Modal from './components/${entityName}Modal.vue'
+  <#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>
+
+  const expandedRowKeys = ref([]);
+  const queryParam = ref<any>({});
+  const toggleSearchStatus = ref<boolean>(false);
+  const registerModal = ref();
+  //注册table数据
+  const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
+    tableProps: {
+      title: '${tableVo.ftlDescription}',
+      api: list,
+      columns,
+      canResize:false,
+      useSearchForm: false,
+      actionColumn: {
+        width: 120,
+        fixed: 'right',
+      },
+      beforeFetch: (params) => {
+        return Object.assign(params, queryParam.value);
+      },
+    },
+    exportConfig: {
+      name: "${tableVo.ftlDescription}",
+      url: getExportUrl,
+    },
+	  importConfig: {
+	    url: getImportUrl,
+	    success: success
+	  },
+  });
+  const [registerTable, {reload, collapseAll, updateTableDataRecord, findTableDataRecord,getDataSource},{ rowSelection, selectedRowKeys }] = tableContext
+  const labelCol = reactive({
+    xs: { span: 24 },
+    sm: { span: 7 },
+  });
+  const wrapperCol = reactive({
+    xs: { span: 24 },
+    sm: { span: 16 },
+  });
+
+  /**
+   * 新增事件
+   */
+  function handleAdd() {
+    registerModal.value.disableSubmit = false;
+    registerModal.value.add();
+  }
+
+  /**
+   * 编辑事件
+   */
+  async function handleEdit(record) {
+    registerModal.value.disableSubmit = false;
+    registerModal.value.edit(record);
+  }
+
+  /**
+   * 详情
+   */
+  async function handleDetail(record) {
+    registerModal.value.disableSubmit = true;
+    registerModal.value.edit(record);
+  }
+
+  /**
+   * 删除事件
+   */
+  async function handleDelete(record) {
+    await delete${entityName}({ id: record.id }, success);
+  }
+
+  /**
+   * 批量删除事件
+   */
+  async function batchHandleDelete() {
+    const ids = selectedRowKeys.value.filter((item) => !item.includes('loading'));
+    await batchDelete${entityName}({ id: ids }, success);
+  }
+  
+  /**
+   * 成功回调刷新页面
+   */
+  function success() {
+    (selectedRowKeys.value = []) && reload();
+  }
+
+  /**
+   * 添加下级
+   */
+  function handleAddSub(record) {
+    registerModal.value.disableSubmit = false;
+    registerModal.value.add(record);
+  }
+
+  /**
+   * 成功回调
+   */
+  async function handleSuccess({ isUpdate, values, expandedArr, changeParent }) {
+    if (isUpdate) {
+      if (changeParent) {
+        reload();
+      } else {
+        // 编辑回调
+        updateTableDataRecord(values.id, values);
+      }
+    } else {
+      if (!values['id'] || !values['pid']) {
+        //新增根节点
+        reload();
+      } else {
+        //新增子集
+        expandedRowKeys.value = [];
+        for (let key of unref(expandedArr)) {
+          await expandTreeNode(key);
+        }
+      }
+    }
+  }
+   
+  /**
+   * 接口请求成功后回调
+   */
+  function onFetchSuccess(result) {
+    getDataByResult(result.items) && loadDataByExpandedRows();
+  }
+   
+  /**
+   * 根据已展开的行查询数据(用于保存后刷新时异步加载子级的数据)
+   */
+  async function loadDataByExpandedRows() {
+    if (unref(expandedRowKeys).length > 0) {
+      const res = await getChildListBatch({ parentIds: unref(expandedRowKeys).join(',') });
+      if (res.success && res.result.records.length > 0) {
+        //已展开的数据批量子节点
+        let records = res.result.records;
+        const listMap = new Map();
+        for (let item of records) {
+          let pid = item['${pidFieldName}'];
+          if (unref(expandedRowKeys).includes(pid)) {
+            let mapList = listMap.get(pid);
+            if (mapList == null) {
+              mapList = [];
+            }
+            mapList.push(item);
+            listMap.set(pid, mapList);
+          }
+        }
+        let childrenMap = listMap;
+        let fn = (list) => {
+          if (list) {
+            list.forEach((data) => {
+              if (unref(expandedRowKeys).includes(data.id)) {
+                data.children = getDataByResult(childrenMap.get(data.id));
+                fn(data.children);
+              }
+            });
+          }
+        };
+        fn(getDataSource());
+      }
+    }
+  }
+   
+  /**
+   * 处理数据集
+   */
+  function getDataByResult(result) {
+    if (result && result.length > 0) {
+      return result.map((item) => {
+        //判断是否标记了带有子节点
+        if (item['hasChild'] == '1') {
+          let loadChild = { id: item.id + '_loadChild', name: 'loading...', isLoading: true };
+          item.children = [loadChild];
+        }
+        return item;
+      });
+    }
+  }
+   
+  /**
+   *树节点展开合并
+   */
+  async function handleExpand(expanded, record) {
+    // 判断是否是展开状态,展开状态(expanded)并且存在子集(children)并且未加载过(isLoading)的就去查询子节点数据
+    if (expanded) {
+      expandedRowKeys.value.push(record.id);
+      if (record.children.length > 0 && !!record.children[0].isLoading) {
+        let result = await getChildList({ ${pidFieldName}: record.id});
+        result = result.records ? result.records : result;
+        if (result && result.length > 0) {
+          record.children = getDataByResult(result);
+        } else {
+          record.children = null;
+          record.hasChild = '0';
+        }
+      }
+    } else {
+      let keyIndex = expandedRowKeys.value.indexOf(record.id);
+      if (keyIndex >= 0) {
+        expandedRowKeys.value.splice(keyIndex, 1);
+      }
+    }
+  }
+   
+  /**
+   * 操作表格后处理树节点展开合并
+   */
+  async function expandTreeNode(key) {
+    let record = findTableDataRecord(key);
+    expandedRowKeys.value.push(key);
+    let result = await getChildList({ ${pidFieldName}: key });
+    if (result && result.length > 0) {
+      record.children = getDataByResult(result);
+    } else {
+      record.children = null;
+      record.hasChild = '0';
+    }
+    updateTableDataRecord(key, record);
+  }  
+   
+  /**
+   * 操作栏
+   */
+  function getTableAction(record) {
+    return [
+      {
+        label: '编辑',
+        onClick: handleEdit.bind(null, record),
+      }
+    ];
+  }
+   
+  /**
+   * 下拉操作栏
+   */
+  function getDropDownAction(record) {
+    return [
+      {
+        label: '详情',
+        onClick: handleDetail.bind(null, record),
+      },
+      {
+        label: '添加下级',
+        onClick: handleAddSub.bind(null, { pid: record.id }),
+      },      
+      {
+        label: '删除',
+        popConfirm: {
+          title: '确定删除吗?',
+          confirm: handleDelete.bind(null, record),
+        },
+      },
+    ];
+  }
+
+  /**
+   * 查询
+   */
+  function searchQuery() {
+    reload();
+  }
+  
+  /**
+   * 重置
+   */
+  function searchReset() {
+    queryParam.value = {};
+    selectedRowKeys.value = [];
+    //刷新数据
+    reload();
+  }
+  
+  <#if need_popup>
+  /**
+   *  popup组件值改变事件
+   */
+  function setFieldsValue(map) {
+    Object.keys(map).map((key) => {
+      queryParam.value[key] = map[key];
+    });
+  }
+  </#if>
+
+  <#if need_pca>
+  /**
+   * 省市区点击事件
+   * @param key
+   * @param value
+   */
+  function handleAreaChange(key, value) {
+    queryParam.value[key] = value.join(',');
+  }
+  </#if>
+
+  <#if need_category>
+  /**
+   * form点击事件
+   * @param value
+   */
+  function handleFormChange(key, value) {
+    queryParam.value[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) {
+        let allDictDate = getAuthCache(DB_DICT_DATA_KEY);
+        if(!allDictDate['${po.dictField?default("")}']){
+          Object.assign(allDictDate,{'${po.dictField?default("")}':res})
+        }
+        setAuthCache(DB_DICT_DATA_KEY,allDictDate)
+      }
+    });
+     </#if>
+   </#if>
+   </#list>
+  }
+  initDictConfig();
+    </#if>
+</script>
+
+<style lang="less" scoped>
+  .jeecg-basic-table-form-container {
+    .table-page-search-submitButtons {
+      display: block;
+      margin-bottom: 24px;
+      white-space: nowrap;
+    }
+    .query-group-cust{
+      width: calc(50% - 15px);
+      min-width: 100px !important;
+    }
+    .query-group-split-cust{
+      width: 30px;
+      display: inline-block;
+      text-align: center
+    }
+  }
+</style>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi
new file mode 100644
index 0000000..0ff2ed7
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi
@@ -0,0 +1,90 @@
+import { defHttp } from "/@/utils/http/axios";
+import { Modal } from 'ant-design-vue';
+
+enum Api {
+  list = '/${entityPackage}/${entityName?uncap_first}/rootList',
+  save='/${entityPackage}/${entityName?uncap_first}/add',
+  edit='/${entityPackage}/${entityName?uncap_first}/edit',
+  delete${entityName} = '/${entityPackage}/${entityName?uncap_first}/delete',
+  importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
+  exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
+  loadTreeData = '/${entityPackage}/${entityName?uncap_first}/loadTreeRoot',
+  getChildList = '/${entityPackage}/${entityName?uncap_first}/childList',
+  getChildListBatch = '/${entityPackage}/${entityName?uncap_first}/getChildListBatch',
+}
+
+/**
+ * 导出api
+ * @param params
+ */
+export const getExportUrl = Api.exportXls;
+
+/**
+ * 导入api
+ * @param params
+ */
+export const getImportUrl = Api.importExcel;
+
+/**
+ * 列表接口
+ * @param params
+ */
+export const list = (params) => defHttp.get({ url: Api.list, params });
+
+/**
+ * 删除
+ * @param params
+ * @param handleSuccess
+ */
+export const delete${entityName} = (params,handleSuccess) => {
+  return defHttp.delete({ url: Api.delete${entityName}, params }, { joinParamsToUrl: true }).then(() => {
+    handleSuccess();
+  });
+}
+
+/**
+ * 批量删除
+ * @param params
+ * @param handleSuccess
+ */
+export const batchDelete${entityName} = (params, handleSuccess) => {
+  Modal.confirm({
+    title: '确认删除',
+    content: '是否删除选中数据',
+    okText: '确认',
+    cancelText: '取消',
+    onOk: () => {
+      return defHttp.delete({ url: Api.delete${entityName}, data: params }, { joinParamsToUrl: true }).then(() => {
+        handleSuccess();
+      });
+    }
+  });
+}
+
+/**
+ * 保存或者更新
+ * @param params
+ * @param isUpdate
+ */
+export const saveOrUpdateDict = (params, isUpdate) => {
+  let url = isUpdate ? Api.edit : Api.save;
+  return defHttp.post({ url: url, params },{ isTransformResponse:false });
+}
+
+/**
+ * 查询全部树形节点数据
+ * @param params
+ */
+export const loadTreeData = (params) => defHttp.get({ url: Api.loadTreeData,params });
+
+/**
+ * 查询子节点数据
+ * @param params
+ */
+export const getChildList = (params) => defHttp.get({ url: Api.getChildList, params });
+  
+/**
+ * 批量查询子节点数据
+ * @param params
+ */
+export const getChildListBatch = (params) => defHttp.get({ url: Api.getChildListBatch, params },{ isTransformResponse:false });
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi
new file mode 100644
index 0000000..8a3ecb8
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi
@@ -0,0 +1,399 @@
+<#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';
+//列表数据
+export const columns: BasicColumn[] = [
+ <#list columns as po>
+   <#if po.isShowList =='Y' && po.fieldName !='id'>
+  {
+    title: '${po.filedComment}',
+    <#if po.fieldDbName == tableVo.extendParams.textField>
+    align: 'left',
+    <#else>
+    align: 'center',
+    </#if>
+    <#if po.sort=='Y'>
+    sorter: true,
+   </#if>
+    <#if po.classType=='date'>
+    dataIndex: '${po.fieldName}',
+    customRender:({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}',
+    slots: { customRender: 'htmlSlot' },
+    <#elseif po.classType=='pca'>
+    dataIndex: '${po.fieldName}',
+    slots: { customRender: 'pcaSlot' },
+   <#elseif po.classType=='file'>
+    dataIndex: '${po.fieldName}',
+    slots: { customRender: 'fileSlot' },
+   <#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'>
+    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>
+<#if po.isQuery=='Y'>
+<#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: "${po.fieldName}",
+<#if po.classType=='sel_search'>
+    component: 'JSearchSelect',
+    componentProps: {
+      dict:"${po.dictTable},${po.dictText},${po.dictField}"
+    },
+<#elseif po.classType=='sel_user'>
+    component: 'JSelectUserByDept',
+<#elseif po.classType=='switch'>
+    component: 'JSwitch',
+    componentProps: {
+      <#if po.dictField != 'is_open'>
+      options: '${po.dictField}',
+      </#if>
+    },
+ <#elseif po.classType=='sel_depart'>
+    component: 'JSelectDept',
+ <#elseif po.classType=='list_multi'>
+    component: 'JSelectMultiple',
+    componentProps: {
+      <#if po.dictTable?default("")?trim?length gt 1>
+      options: "${po.dictField}",
+      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',
+<#elseif po.classType=='datetime'>
+    component: 'DatePicker',
+    componentProps: {
+      showTime: true
+    },
+<#elseif po.classType=='pca'>
+    component: 'JAreaLinkage',
+<#elseif po.classType=='popup'>
+    <#include "/common/form/vue3popup.ftl">
+<#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]}",
+         </#if>
+         <#if po.dictText?split(',')[1]??>
+      pidField: "${po.dictText?split(',')[1]}",
+         </#if>
+         <#if po.dictText?split(',')[3]??>
+      hasChildField: "${po.dictText?split(',')[3]}",
+         </#if>
+         </#if>
+      pidValue: "${po.dictField}",
+    },
+<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
+<#--  ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
+    component: 'JDictSelectTag',
+    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>
+    },
+<#else>
+    component: 'Input',
+</#if>
+    colProps: {span: 6},
+  },
+<#else>
+  {
+    label: "${po.filedComment}",
+    field: "${po.fieldName}",
+<#if po.classType=='date'>
+    component: 'RangePicker',
+<#elseif po.classType=='datetime'>
+    component: 'RangePicker',
+    componentProps: {
+      showTime: true
+    },
+<#elseif po.classType == 'time'>
+    component: 'TimePicker',
+    componentProps:{
+      valueFormat: 'HH:mm:ss',
+    },
+<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+    component: 'JRangeNumber',
+<#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>
+<#if po.isShow =='Y'>
+<#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)},
+    <#if po.fieldDbName == tableVo.extendParams.pidField>
+    component: 'JTreeSelect',
+    componentProps: {
+      dict: "${tableVo.tableName},${tableVo.extendParams.textField},id",
+      pidField: "${tableVo.extendParams.pidField}",
+      pidValue: "0",
+      hasChildField: "${tableVo.extendParams.hasChildren}",
+    },
+    <#elseif po.classType =='date'>
+    component: 'DatePicker',
+     <#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 =='sel_depart'>
+     component: 'JSelectDept',
+     <#elseif po.classType =='switch'>
+     component: 'JSwitch',
+     componentProps:{
+         <#if po.dictField != 'is_open'>
+         options:${po.dictField}
+         </#if>
+     },
+     <#elseif po.classType =='pca'>
+    component: 'JAreaLinkage',
+    <#elseif po.classType =='markdown'>
+    component: 'JMarkdownEditor',//注意string转换问题
+     <#elseif po.classType =='password'>
+    component: 'InputPassword',
+     <#elseif po.classType =='sel_user'>
+    component: 'JSelectUserByDept',
+    componentProps:{
+        labelKey: 'realname',
+     },
+    <#elseif po.classType =='textarea'>
+    component: 'InputTextArea',
+    <#elseif po.classType=='list' || po.classType=='radio'>
+    component: 'JDictSelectTag',
+    componentProps:{
+        dictCode: "${form_field_dictCode}"
+     },
+    <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
+    component: 'JSelectMultiple',
+    componentProps:{
+        dictCode: "${form_field_dictCode}"
+     },
+    <#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=='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}
+    </#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]}",
+          </#if>
+          <#if po.dictText?split(',')[1]??>
+        pidField: "${po.dictText?split(',')[1]}",
+          </#if>
+          <#if po.dictText?split(',')[3]??>
+        hasChildField: "${po.dictText?split(',')[3]}",
+          </#if>
+        </#if>
+        pidValue: "${po.dictField}",
+    },
+   <#else>
+    component: 'Input',
+    </#if>
+     <#include "/common/utils.ftl">
+    <#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}$/, 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: /^[1-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>
+];
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei
new file mode 100644
index 0000000..a5b550f
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei
@@ -0,0 +1,235 @@
+<#include "/common/utils.ftl">
+<template>
+  <a-spin :spinning="confirmLoading">
+    <a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol">
+      <a-row>
+<#assign need_category = false>
+<#assign bpm_flag=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_select_tag = false>
+<#assign need_select_tree = false>
+<#assign need_time = false>
+<#assign need_markdown = false>
+<#assign need_upload = false>
+<#assign need_image_upload = false>
+<#assign need_editor = false>
+<#assign need_checkbox = false>
+<#assign pidFieldName = "">
+<#assign hasOnlyValidate = 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.fieldValidType?default("") == 'only'>
+  <#assign hasOnlyValidate = true>
+</#if>
+			<#if po.fieldDbName == tableVo.extendParams.pidField>
+						<#assign pidFieldName = po.fieldName>
+        <a-col :span="${form_span}">
+          <a-form-item label="父级节点" v-bind="validateInfos.${autoStringSuffixForModel(po)}">
+            <j-tree-select
+              placeholder="请选择${po.filedComment}"
+              v-model:value="formData.${po.fieldName}"
+              dict="${tableVo.tableName},${tableVo.extendParams.textField},id"
+              pidField="${tableVo.extendParams.pidField}"
+              pidValue="0"
+              hasChildField="${tableVo.extendParams.hasChildren}"
+              <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>>
+            </j-tree-select>
+          </a-form-item>
+        </a-col>
+      </#if>    
+  <#include "/common/form/native/vue3NativeForm.ftl">
+</#list>
+      </a-row>
+    </a-form>
+  </a-spin>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, defineExpose, nextTick, unref, defineProps, computed } from 'vue';
+  import { defHttp } from '/@/utils/http/axios';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import moment from 'moment';
+  <#include "/common/form/native/vue3NativeImport.ftl">
+  import { getValueType } from '/@/utils';
+  import { validateDuplicateValue } from '/@/utils/helper/validator';
+  import {loadTreeData, saveOrUpdateDict} from '../${entityName}.api';
+  import { Form } from 'ant-design-vue';
+  <#if hasOnlyValidate == true>
+  import { duplicateValidate } from '/@/utils/helper/validator'
+  </#if>
+  
+  const useForm = Form.useForm;
+  const formRef = ref();
+  const isUpdate = ref(true);
+  const expandedRowKeys = ref([]);
+  const treeData = ref([]);
+  const pidField = ref<string>('pid');
+  const emit = defineEmits(['register', 'ok']);
+  let model: Nullable<Recordable> = null;
+  const formData = reactive<Record<string, any>>({
+<#list columns as po>
+ <#if po.isShow == 'Y'>
+  <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+    ${po.fieldName}: undefined,
+  <#elseif po.fieldDbType=='Blob'>
+    ${po.fieldName}String: '',
+  <#else>
+    ${po.fieldName}: '',   
+  </#if>
+ </#if>
+</#list>
+  });
+  const { createMessage } = useMessage();
+  const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } });
+  const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } });
+  const confirmLoading = ref<boolean>(false);
+  //表单验证
+  const validatorRules = {
+  <#include "/common/validatorRulesTemplate/native/vue3MainNative.ftl">
+  };
+  const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: true });
+  const props = defineProps({
+    disabled: { type: Boolean, default: false },
+  });
+  
+  /**
+   * 新增
+   */
+  function add(obj = {}) {
+    edit(obj);
+  }
+
+  /**
+   * 编辑
+   */
+  function edit(record) {
+    nextTick(async () => {
+      resetFields();
+      expandedRowKeys.value = [];
+      treeData.value = await loadTreeData({ async: false, pcode: '' });
+      //赋值
+      Object.assign(formData, record);
+    });
+  }
+
+  /**
+   * 根据pid获取展开的节点
+   * @param pid
+   * @param arr
+   */
+  function getExpandKeysByPid(pid, arr) {
+    if (pid && arr && arr.length > 0) {
+      for (let i = 0; i < arr.length; i++) {
+        if (arr[i].key == pid && unref(expandedRowKeys).indexOf(pid) < 0) {
+          expandedRowKeys.value.push(arr[i].key);
+          getExpandKeysByPid(arr[i]['parentId'], unref(treeData));
+        } else {
+          getExpandKeysByPid(pid, arr[i].children);
+        }
+      }
+    }
+  }
+
+  /**
+   * 提交数据
+   */
+  async function submitForm() {
+    // 触发表单验证
+    await validate();
+    confirmLoading.value = true;
+    const isUpdate = ref<boolean>(false);
+    //时间格式化
+    if (formData.id) {
+      isUpdate.value = true;
+    }
+    //循环数据
+    for (let data in formData) {
+      //如果该数据是数组并且是字符串类型
+      if (formData[data] instanceof Array) {
+        let valueType = getValueType(formRef.value.getProps, data);
+        //如果是字符串类型的需要变成以逗号分割的字符串
+        if (valueType === 'string') {
+          formData[data] = formData[data].join(',');
+        }
+      }
+    }
+    await saveOrUpdateDict(formData, isUpdate.value)
+      .then(async (res) => {
+        if (res.success) {
+          await getExpandKeysByPid(formData['${pidFieldName}'], unref(treeData));
+          emit('ok', {
+            isUpdate: unref(isUpdate),
+            values: { ...formData },
+            expandedArr: unref(expandedRowKeys).reverse(),
+            // 是否更改了父级节点
+            changeParent: model != null && model['${pidFieldName}'] != formData['${pidFieldName}'],
+          });
+          createMessage.success(res.message);
+        } else {
+          createMessage.warning(res.message);
+        }
+      })
+      .finally(() => {
+        confirmLoading.value = false;
+      });
+  }
+
+	<#if need_popup>
+  /**
+   *  popup组件值改变事件
+   */
+  function setFieldsValue(map) {
+    Object.keys(map).map((key) => {
+      formData[key] = map[key];
+    });
+  }
+	</#if>
+
+	<#if need_category || need_select_tree>
+  /**
+   * 值改变事件触发
+   * @param key
+   * @param value
+   */
+  function handleFormChange(key, value) {
+    formData[key] = value;
+  }
+  </#if>
+
+  <#list columns as po>
+  <#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'>
+  async function ${po.fieldName}Duplicatevalidate(_r, value) {
+    return duplicateValidate('${tableName}', '${po.fieldDbName}', value, formData.id || '')
+  }
+  </#if>
+  </#list>
+  defineExpose({
+    add,
+    edit,
+    submitForm,
+  });
+</script>
+
+<style lang="less" scoped>
+  .antd-modal-form {
+    height: 500px !important;
+    overflow-y: auto;
+    padding: 24px 24px 24px 24px;
+  }
+</style>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei
new file mode 100644
index 0000000..70dfb5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei
@@ -0,0 +1,81 @@
+<template>
+  <a-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
+    <${entityName}Form ref="registerForm" @ok="submitCallback" :disabled="disableSubmit"></${entityName}Form>
+  </a-modal>
+</template>
+
+<script lang="ts" setup>
+  import { ref, nextTick, defineExpose } from 'vue';
+  import ${entityName}Form from './${entityName}Form.vue'
+  
+  const title = ref<string>('');
+  const width = ref<number>(800);
+  const visible = ref<boolean>(false);
+  const disableSubmit = ref<boolean>(false);
+  const registerForm = ref();
+  const emit = defineEmits(['register', 'success']);
+  
+  /**
+   * 新增
+   */
+  function add(obj={}) {
+    title.value = '新增';
+    visible.value = true;
+    nextTick(() => {
+      registerForm.value.add(obj);
+    });
+  }
+  
+  /**
+   * 编辑
+   * @param record
+   */
+  function edit(record) {
+    title.value = disableSubmit.value ? '详情' : '编辑';
+    visible.value = true;
+    nextTick(() => {
+      registerForm.value.edit(record);
+    });
+  }
+  
+  /**
+   * 确定按钮点击事件
+   */
+  function handleOk() {
+    registerForm.value.submitForm();
+  }
+
+  /**
+   * form保存回调事件
+   */
+  function submitCallback({ isUpdate, values, expandedArr, changeParent }) {
+    handleCancel();
+    emit('success', {
+      isUpdate: isUpdate,
+      values: values,
+      expandedArr: expandedArr,
+      // 是否更改了父级节点
+      changeParent: changeParent,
+    });
+  }
+  
+  /**
+   * 取消按钮回调事件
+   */
+  function handleCancel() {
+    visible.value = false;
+  }
+
+  defineExpose({
+    add,
+    edit,
+    disableSubmit,
+  });
+</script>
+
+<style>
+  /**隐藏样式-modal确定按钮 */
+  .jee-hidden {
+    display: none !important;
+  }
+</style>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
index 7bf649a..9196325 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 package ${bussiPackage}.${entityPackage}.entity;
 
 import java.io.Serializable;
@@ -31,9 +32,9 @@ public class ${entityName} implements Serializable {
     <#-- 生成字典Code -->
     <#assign list_field_dictCode="">
     <#if po.classType='sel_user'>
-      <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'>
+      <#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 = "depart_name", dicCode = "id"'>
+      <#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}"'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
index d549c98..03fe3eb 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 <#list subTables as subTab>
 #segment#${subTab.entityName}.java
 package ${bussiPackage}.${entityPackage}.entity;
@@ -65,7 +66,8 @@ public class ${subTab.entityName} implements Serializable {
     @Dict(dicCode = "id",dicText = "name",dictTable = "sys_category")
 </#if>
 <#if po.classType =='sel_depart'>
-    @Dict(dicCode = "id",dicText = "depart_name",dictTable = "sys_depart")
+    <#assign list_field_dictCode='dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dictTable = "sys_depart"'>
+    @Dict(${list_field_dictCode})
 </#if>
 	<#-- 大字段转换 -->
     <#include "/common/blob.ftl">
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei
index 1cf248a..494ff9f 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei
@@ -193,7 +193,7 @@
     <#assign sub_seq=1>
     <#list subTables as sub>
       <a-tab-pane tab="${sub.ftlDescription}" key="${sub_seq}" <#if sub_seq gt 1>forceRender</#if>>
-        <${sub.entityName}List :mainId="selectedMainId" />
+        <${sub.entityName}List :mainId="${sub.entityName?uncap_first}MainId" />
       </a-tab-pane>
     <#assign sub_seq=sub_seq+1>
     </#list>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei
index 120bdd0..1df9859 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei
@@ -44,7 +44,7 @@
                 @input="popupCallback"
                 <#if po.readonly=='Y'>disabled</#if>/>
     <#elseif po.classType =='sel_depart'>
-              <j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/>
+              <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'>
@@ -54,7 +54,7 @@
     <#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}" <#if po.readonly=='Y'>disabled</#if>/>
+              <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'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Modal.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Modal.vuei
index 1af2447..37a1a11 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Modal.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Modal.vuei
@@ -46,7 +46,7 @@
                 @input="popupCallback"
                 <#if po.readonly=='Y'>disabled</#if>/>
     <#elseif po.classType =='sel_depart'>
-              <j-select-depart v-model="model.${po.fieldName}"multi <#if po.readonly=='Y'>disabled</#if>/>
+              <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'>
@@ -56,7 +56,7 @@
     <#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}"<#if po.readonly=='Y'>disabled</#if>/>
+              <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'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
index 9aa4df2..45f4359 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
@@ -46,6 +46,10 @@
       <template #htmlSlot="{text}">
          <div v-html="text"></div>
       </template>
+       <!--省市区字段回显插槽-->
+       <template #pcaSlot="{text}">
+         {{ getAreaTextByCode(text) }}
+       </template>
       <template #fileSlot="{text}">
          <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>
@@ -77,6 +81,10 @@
 </#list>
   import {columns, searchFormSchema} from './${entityName}.data';
   import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api';
+  import {downloadFile} from '/@/utils/common/renderUtils';
+ <#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';
@@ -94,6 +102,17 @@
            rowSelection: {type: 'radio'},
            formConfig: {
                 schemas: searchFormSchema,
+                fieldMapToNumber: [
+                   <#list columns as po>
+                   <#if po.isQuery=='Y'>
+                   <#if po.queryMode!='single'>
+                   <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+                   ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end']],
+                   </#if>
+                   </#if>
+                   </#if>
+                   </#list>
+                ],
                 fieldMapToTime: [
                 <#list columns as po>
                 <#if po.isQuery=='Y'>
@@ -108,14 +127,15 @@
                 </#list>
                 ],
             },
-            actionColumn: {
+           actionColumn: {
                width: 120,
-            },
-            pagination:{
-                current: 1,
-                pageSize: 5,
-                pageSizeOptions: ['5', '10', '20'],
-            }
+               fixed:'right'
+           },
+           pagination:{
+               current: 1,
+               pageSize: 5,
+               pageSizeOptions: ['5', '10', '20'],
+           }
         },
         exportConfig: {
             name:"${tableVo.ftlDescription}",
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
index 19bf9d3..47f36da 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 import {BasicColumn} from '/@/components/Table';
 import {FormSchema} from '/@/components/Table';
 import { rules} from '/@/utils/helper/validator';
@@ -24,7 +25,7 @@ export const columns: BasicColumn[] = [
     slots: { customRender: 'htmlSlot' },
     <#elseif po.classType=='pca'>
     dataIndex: '${po.fieldName}',
-    slots: { customRender: 'pcaSlot' },//TODO 未翻译
+    slots: { customRender: 'pcaSlot' },
    <#elseif po.classType=='file'>
     dataIndex: '${po.fieldName}',
     slots: { customRender: 'fileSlot' },
@@ -91,17 +92,23 @@ export const searchFormSchema: FormSchema[] = [
 <#elseif po.classType=='switch'>
       component: 'JSwitch',
       componentProps:{
+           query:true,
            <#if po.dictField != 'is_open'>
-           options:"${po.dictField}"
+           options:${po.dictField}
            </#if>
        },
  <#elseif po.classType=='sel_depart'>
       component: 'JSelectDept',
  <#elseif po.classType=='list_multi'>
-      component: 'JMultiSelectTag',//暂无该组件
+      component: 'JSelectMultiple',
       componentProps:{
-          dictCode:"query_field_dictCode?default("")"
-      },
+     <#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:{
@@ -117,16 +124,7 @@ export const searchFormSchema: FormSchema[] = [
 <#elseif po.classType=='pca'>
       component: 'JAreaLinkage',
 <#elseif po.classType=='popup'>
-      component: 'JPopup',
-      componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:"${po.dictField}",
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
 <#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
 <#--  ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
       component: 'JDictSelectTag',
@@ -153,6 +151,8 @@ export const searchFormSchema: FormSchema[] = [
       componentProps: {
           showTime:true
       },
+<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+      component: 'JRangeNumber',
 <#else>
       component: 'Input', //TODO 范围查询
 </#if>
@@ -186,27 +186,22 @@ export const formSchema: FormSchema[] = [
 	</#if>
   {
     label: '${po.filedComment}',
-    field: '${po.fieldName}',
+    field: ${autoStringSuffix(po)},
     <#if po.classType =='date'>
     component: 'DatePicker',
-     <#elseif po.fieldType =='datetime'>
+     <#elseif po.classType =='datetime'>
     component: 'DatePicker',
     componentProps: {
-       showTime:true
+       showTime:true,
+       valueFormat: 'YYYY-MM-DD HH:mm:ss'
      },
-     <#elseif po.fieldType =='time'>
+     <#elseif po.classType =='time'>
     component: 'TimePicker',
+    componentProps: {
+      valueFormat: 'HH:mm:ss'
+    },
     <#elseif po.classType =='popup'>
-    component: 'JPopup',
-    componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:${po.dictField},
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
      <#elseif po.classType =='sel_depart'>
      component: 'JSelectDept',
      <#elseif po.classType =='switch'>
@@ -235,7 +230,7 @@ export const formSchema: FormSchema[] = [
         dictCode:"${form_field_dictCode}"
      },
     <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
-    component: 'JMultiSelectTag',//TODO  暂无该组件
+    component: 'JSelectMultiple',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
@@ -270,7 +265,7 @@ export const formSchema: FormSchema[] = [
     </#if>
       },
   <#elseif po.classType=='umeditor'>
-    component: 'JCodeEditor', //TODO String后缀暂未添加
+    component: 'JEditor',
   <#elseif po.classType == 'sel_tree'>
     component: 'JTreeSelect',
     componentProps:{
@@ -302,16 +297,16 @@ export const formSchema: FormSchema[] = [
            </#if>
        <#-- 唯一校验 -->
            <#if fieldValidType == 'only'>
-                 {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
+                 {...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}$/, message: '请输入6到16位数字!'},
            <#-- 6到16位任意字符 -->
            <#elseif fieldValidType == '*6-16'>
                  { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
-           <#-- 6到18位字符串 -->
+           <#-- 6到18位字母 -->
            <#elseif fieldValidType == 's6-18'>
-                 { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
+                 { pattern:/^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
            <#-- 网址 -->
            <#elseif fieldValidType == 'url'>
                  { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
@@ -387,7 +382,7 @@ export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [
     slots: { customRender: 'htmlSlot' },
     <#elseif po.classType=='pca'>
     dataIndex: '${po.fieldName}',
-    slots: { customRender: 'pcaSlot' },//TODO 未翻译
+    slots: { customRender: 'pcaSlot' },
    <#elseif po.classType=='file'>
     dataIndex: '${po.fieldName}',
     slots: { customRender: 'fileSlot' },
@@ -419,7 +414,7 @@ export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [
        return  render.renderCategoryTree(text,'${po.dictField?default("")}')
    },
    <#else>
-    customRender: (text, record) => (text ? record['${po.dictText}'] : '')
+    customRender: ({text, record}) => (text ? record['${po.dictText}'] : '')
    </#if>
    <#else>
     dataIndex: '${po.fieldName}'
@@ -452,27 +447,22 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
 	</#if>
   {
     label: '${po.filedComment}',
-    field: '${po.fieldName}',
+    field: ${autoStringSuffix(po)},
     <#if po.classType =='date'>
     component: 'DatePicker',
-     <#elseif po.fieldType =='datetime'>
+     <#elseif po.classType =='datetime'>
     component: 'DatePicker',
     componentProps: {
-       showTime:true
+       showTime:true,
+       valueFormat: 'YYYY-MM-DD HH:mm:ss'
      },
-     <#elseif po.fieldType =='time'>
+     <#elseif po.classType =='time'>
     component: 'TimePicker',
+    componentProps: {
+      valueFormat: 'HH:mm:ss'
+    },
     <#elseif po.classType =='popup'>
-    component: 'JPopup',
-    componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:${po.dictField},
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
      <#elseif po.classType =='sel_depart'>
      component: 'JSelectDept',
      <#elseif po.classType =='switch'>
@@ -494,14 +484,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
         labelKey:'realname',
      },
     <#elseif po.classType =='textarea'>
-    component: 'InputTextArea',//TODO 注意string转换问题
+    component: 'InputTextArea',
     <#elseif po.classType=='list' || po.classType=='radio'>
     component: 'JDictSelectTag',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
     <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
-    component: 'JMultiSelectTag',//TODO  暂无该组件
+    component: 'JSelectMultiple',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
@@ -536,7 +526,7 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
     </#if>
       },
   <#elseif po.classType=='umeditor'>
-    component: 'JCodeEditor', //TODO String后缀暂未添加
+    component: 'JEditor',
   <#elseif po.classType == 'sel_tree'>
     component: 'JTreeSelect',
     componentProps:{
@@ -568,16 +558,16 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
            </#if>
        <#-- 唯一校验 -->
            <#if fieldValidType == 'only'>
-                 {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
+                 {...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}$/, message: '请输入6到16位数字!'},
            <#-- 6到16位任意字符 -->
            <#elseif fieldValidType == '*6-16'>
                  { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
-           <#-- 6到18位字符串 -->
+           <#-- 6到18位字母 -->
            <#elseif fieldValidType == 's6-18'>
-                 { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
+                 { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
            <#-- 网址 -->
            <#elseif fieldValidType == 'url'>
                  { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/[1-n]List.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/[1-n]List.vuei
index ceb367b..a7b39a7 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/[1-n]List.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/[1-n]List.vuei
@@ -51,6 +51,7 @@
   import {${sub.entityName?uncap_first}List, ${sub.entityName?uncap_first}Delete, ${sub.entityName?uncap_first}DeleteBatch, ${sub.entityName?uncap_first}ExportXlsUrl, ${sub.entityName?uncap_first}ImportUrl } from './${entityName}.api';
   import {isEmpty} from "/@/utils/is";
   import {useMessage} from '/@/hooks/web/useMessage';
+  import {downloadFile} from '/@/utils/common/renderUtils';
 
     //接收主表id
     const mainId = inject('mainId') || '';
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
index fd54ae4..9d11f25 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
@@ -1,5 +1,6 @@
+<#include "/common/utils.ftl">
 <template>
-  <BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
+  <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
       <BasicForm @register="registerForm"/>
   </BasicModal>
 </template>
@@ -18,6 +19,7 @@
         labelWidth: 150,
         schemas: formSchema,
         showActionButtonGroup: false,
+        baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}
     });
     //表单赋值
     const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
@@ -54,5 +56,12 @@
 </script>
 
 <style lang="less" scoped>
+	/** 时间和数字输入框样式 */
+    :deep(.ant-input-number){
+		width: 100%
+	}
 
+	:deep(.ant-calendar-picker){
+		width: 100%
+	}
 </style>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Modal.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Modal.vuei
index a328e79..d2ea771 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Modal.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Modal.vuei
@@ -2,7 +2,7 @@
 <#list subTables as sub>
 #segment#${sub.entityName}Modal.vue
 <template>
-  <BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
+  <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
       <BasicForm @register="registerForm"/>
   </BasicModal>
 </template>
@@ -24,6 +24,7 @@
         labelWidth: 150,
         schemas: ${sub.entityName?uncap_first}FormSchema,
         showActionButtonGroup: false,
+        baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}
     });
     //表单赋值
     const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
@@ -63,4 +64,14 @@
         }
     }
 </script>
+<style lang="less" scoped>
+	/** 时间和数字输入框样式 */
+    :deep(.ant-input-number){
+		width: 100%
+	}
+
+	:deep(.ant-calendar-picker){
+		width: 100%
+	}
+</style>
 </#list>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
index 36fb9fc..579ab5f 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
@@ -200,17 +200,14 @@ public class ${entityName}Controller {
       QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap());
       LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
 
-      //Step.2 获取导出数据
-      List<${entityName}> queryList = ${entityName?uncap_first}Service.list(queryWrapper);
-      // 过滤选中数据
+     //配置选中数据查询条件
       String selections = request.getParameter("selections");
-      List<${entityName}> ${entityName?uncap_first}List = new ArrayList<${entityName}>();
-      if(oConvertUtils.isEmpty(selections)) {
-          ${entityName?uncap_first}List = queryList;
-      }else {
-          List<String> selectionList = Arrays.asList(selections.split(","));
-          ${entityName?uncap_first}List = queryList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
+      if(oConvertUtils.isNotEmpty(selections)) {
+           List<String> selectionList = Arrays.asList(selections.split(","));
+           queryWrapper.in("id",selectionList);
       }
+      //Step.2 获取导出数据
+      List<${entityName}>  ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper);
 
       // Step.3 组装pageList
       List<${entityName}Page> pageList = new ArrayList<${entityName}Page>();
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
index ed071ad..ee8d8cc 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 package ${bussiPackage}.${entityPackage}.entity;
 
 import java.io.Serializable;
@@ -31,9 +32,9 @@ public class ${entityName} implements Serializable {
     <#-- 生成字典Code -->
     <#assign list_field_dictCode="">
     <#if po.classType='sel_user'>
-      <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'>
+      <#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 = "depart_name", dicCode = "id"'>
+      <#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}"'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
index 30ba2dd..bca19fd 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 <#list subTables as subTab>
 #segment#${subTab.entityName}.java
 package ${bussiPackage}.${entityPackage}.entity;
@@ -33,9 +34,9 @@ public class ${subTab.entityName} implements Serializable {
 	<#-- 生成字典Code -->
 	<#assign list_field_dictCode="">
 	<#if po.classType='sel_user'>
-		<#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'>
+		<#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 = "depart_name", dicCode = "id"'>
+		<#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}"'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
index ad814c0..74784e9 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
@@ -41,7 +41,7 @@
                 @input="popupCallback"
                 <#if po.readonly=='Y'>disabled</#if>/>
     <#elseif po.classType =='sel_depart'>
-              <j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/>
+              <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'>
@@ -51,7 +51,7 @@
     <#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}" <#if po.readonly=='Y'>disabled</#if>/>
+              <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-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
 	<#elseif po.classType=='list' || po.classType=='radio'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
index 4252c92..96d9559 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
@@ -36,9 +36,9 @@
     <#elseif po.classType =='switch'>
             <j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if>></j-switch>
 	<#elseif po.classType =='sel_depart'>
-            <j-select-depart v-model="model.${po.fieldName}" />
+            <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 =='sel_user'>
-            <j-select-user-by-dep v-model="model.${po.fieldName}" />
+            <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}"/>
 	<#elseif po.classType=='list' || po.classType=='radio'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
index 23fe713..a62d4fb 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
@@ -60,6 +60,10 @@
       <template #htmlSlot="{text}">
          <div v-html="text"></div>
       </template>
+      <!--省市区字段回显插槽-->
+      <template #pcaSlot="{text}">
+         {{ getAreaTextByCode(text) }}
+      </template>
       <template #fileSlot="{text}">
          <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>
@@ -81,6 +85,10 @@
   </#list>
   import {columns, searchFormSchema} from './${entityName}.data';
   import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api';
+  import {downloadFile} from '/@/utils/common/renderUtils';
+  <#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';
@@ -102,6 +110,17 @@
                 schemas: searchFormSchema,
                 autoSubmitOnEnter:true,
                 showAdvancedButton:true,
+                fieldMapToNumber: [
+                   <#list columns as po>
+                   <#if po.isQuery=='Y'>
+                   <#if po.queryMode!='single'>
+                   <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+                   ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end']],
+                   </#if>
+                   </#if>
+                   </#if>
+                   </#list>
+                ],
                 fieldMapToTime: [
                 <#list columns as po>
                 <#if po.isQuery=='Y'>
@@ -116,9 +135,10 @@
                 </#list>
                 ],
             },
-            actionColumn: {
+           actionColumn: {
                width: 120,
-            },
+               fixed:'right'
+           },
         },
         exportConfig: {
             name:"${tableVo.ftlDescription}",
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
index a8f8224..cecb7bf 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 import {BasicColumn} from '/@/components/Table';
 import {FormSchema} from '/@/components/Table';
 import { rules} from '/@/utils/helper/validator';
@@ -25,7 +26,7 @@ export const columns: BasicColumn[] = [
     slots: { customRender: 'htmlSlot' },
     <#elseif po.classType=='pca'>
     dataIndex: '${po.fieldName}',
-    slots: { customRender: 'pcaSlot' },//TODO 未翻译
+    slots: { customRender: 'pcaSlot' },
    <#elseif po.classType=='file'>
     dataIndex: '${po.fieldName}',
     slots: { customRender: 'fileSlot' },
@@ -57,7 +58,7 @@ export const columns: BasicColumn[] = [
        return  render.renderCategoryTree(text,'${po.dictField?default("")}')
    },
    <#else>
-    customRender: (text, record) => (text ? record['${po.dictText}'] : '')
+    customRender: ({text, record}) => (text ? record['${po.dictText}'] : '')
    </#if>
    <#else>
     dataIndex: '${po.fieldName}'
@@ -84,7 +85,7 @@ export const searchFormSchema: FormSchema[] = [
 <#if po.queryMode=='single'>
 	{
       label: "${po.filedComment}",
-      field: "${po.fieldName}",
+      field: ${autoStringSuffix(po)},
 <#if po.classType=='sel_search'>
       component: 'JSearchSelect',
       componentProps:{
@@ -95,16 +96,22 @@ export const searchFormSchema: FormSchema[] = [
 <#elseif po.classType=='switch'>
       component: 'JSwitch',
       componentProps:{
+           query:true,
            <#if po.dictField != 'is_open'>
-           options:"${po.dictField}"
+           options:${po.dictField}
            </#if>
        },
  <#elseif po.classType=='sel_depart'>
       component: 'JSelectDept',
  <#elseif po.classType=='list_multi'>
-      component: 'JMultiSelectTag',//暂无该组件
-      componentProps:{
-          dictCode:"query_field_dictCode?default("")"
+      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',
@@ -121,16 +128,7 @@ export const searchFormSchema: FormSchema[] = [
 <#elseif po.classType=='pca'>
       component: 'JAreaLinkage',
 <#elseif po.classType=='popup'>
-      component: 'JPopup',
-      componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:"${po.dictField}",
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
 <#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
 <#--  ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
       component: 'JDictSelectTag',
@@ -157,6 +155,8 @@ export const searchFormSchema: FormSchema[] = [
       componentProps: {
           showTime:true
       },
+<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+      component: 'JRangeNumber',
 <#else>
       component: 'Input', //TODO 范围查询
 </#if>
@@ -189,28 +189,23 @@ export const formSchema: FormSchema[] = [
 	</#if>
   {
     label: '${po.filedComment}',
-    field: '${po.fieldName}',
+    field: ${autoStringSuffix(po)},
     <#if po.classType =='date'>
     component: 'DatePicker',
-     <#elseif po.fieldType =='datetime'>
+     <#elseif po.classType =='datetime'>
     component: 'DatePicker',
     componentProps: {
-       showTime:true
+       showTime:true,
+       valueFormat: 'YYYY-MM-DD HH:mm:ss'
      },
-     <#elseif po.fieldType =='time'>
+     <#elseif po.classType =='time'>
     component: 'TimePicker',
+    componentProps: {
+      valueFormat: 'HH:mm:ss'
+    },
     <#elseif po.classType =='popup'>
-    component: 'JPopup',
-    componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:${po.dictField},
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
-     <#elseif po.classType =='sel_depart'>
+    <#include "/common/form/vue3popup.ftl">
+    <#elseif po.classType =='sel_depart'>
      component: 'JSelectDept',
      <#elseif po.classType =='switch'>
      component: 'JSwitch',
@@ -231,14 +226,14 @@ export const formSchema: FormSchema[] = [
         labelKey:'realname',
      },
     <#elseif po.classType =='textarea'>
-    component: 'InputTextArea',//TODO 注意string转换问题
+    component: 'InputTextArea',
     <#elseif po.classType=='list' || po.classType=='radio'>
     component: 'JDictSelectTag',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
     <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
-    component: 'JMultiSelectTag',//TODO  暂无该组件
+    component: 'JSelectMultiple',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
@@ -273,7 +268,7 @@ export const formSchema: FormSchema[] = [
     </#if>
       },
   <#elseif po.classType=='umeditor'>
-    component: 'JCodeEditor', //TODO String后缀暂未添加
+    component: 'JEditor',
   <#elseif po.classType == 'sel_tree'>
     component: 'JTreeSelect',
     componentProps:{
@@ -305,16 +300,16 @@ export const formSchema: FormSchema[] = [
            </#if>
        <#-- 唯一校验 -->
            <#if fieldValidType == 'only'>
-                 {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
+                 {...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}$/, message: '请输入6到16位数字!'},
            <#-- 6到16位任意字符 -->
            <#elseif fieldValidType == '*6-16'>
                  { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
-           <#-- 6到18位字符串 -->
+           <#-- 6到18位字母 -->
            <#elseif fieldValidType == 's6-18'>
-                 { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
+                 { pattern:/^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
            <#-- 网址 -->
            <#elseif fieldValidType == 'url'>
                  { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
@@ -390,7 +385,7 @@ export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [
     slots: { customRender: 'htmlSlot' },
     <#elseif po.classType=='pca'>
     dataIndex: '${po.fieldName}',
-    slots: { customRender: 'pcaSlot' },//TODO 未翻译
+    slots: { customRender: 'pcaSlot' },
    <#elseif po.classType=='file'>
     dataIndex: '${po.fieldName}',
     slots: { customRender: 'fileSlot' },
@@ -422,7 +417,7 @@ export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [
        return  render.renderCategoryTree(text,'${po.dictField?default("")}')
    },
    <#else>
-    customRender: (text, record) => (text ? record['${po.dictText}'] : '')
+    customRender: ({text, record}) => (text ? record['${po.dictText}'] : '')
    </#if>
    <#else>
     dataIndex: '${po.fieldName}'
@@ -436,10 +431,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
 <#assign form_cat_tree = false>
 <#assign form_cat_back = "">
 <#assign bpm_flag=false>
+<#assign sub_id_exists=false>
 <#list sub.colums as po><#rt/>
 <#if po.fieldDbName=='bpm_status'>
   <#assign bpm_flag=true>
 </#if>
+<#if po.fieldDbName=='id'>
+  <#assign sub_id_exists=true>
+</#if>
 <#if po.isShow =='Y'>
 <#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>
@@ -449,27 +448,22 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
 	</#if>
   {
     label: '${po.filedComment}',
-    field: '${po.fieldName}',
+    field: ${autoStringSuffix(po)},
     <#if po.classType =='date'>
     component: 'DatePicker',
-     <#elseif po.fieldType =='datetime'>
+     <#elseif po.classType =='datetime'>
     component: 'DatePicker',
     componentProps: {
-       showTime:true
+       showTime:true,
+       valueFormat: 'YYYY-MM-DD HH:mm:ss'
      },
-     <#elseif po.fieldType =='time'>
+     <#elseif po.classType =='time'>
     component: 'TimePicker',
+    componentProps: {
+      valueFormat: 'HH:mm:ss'
+    },
     <#elseif po.classType =='popup'>
-    component: 'JPopup',
-    componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:${po.dictField},
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
      <#elseif po.classType =='sel_depart'>
      component: 'JSelectDept',
      <#elseif po.classType =='switch'>
@@ -491,14 +485,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
         labelKey:'realname',
      },
     <#elseif po.classType =='textarea'>
-    component: 'InputTextArea',//TODO 注意string转换问题
+    component: 'InputTextArea',
     <#elseif po.classType=='list' || po.classType=='radio'>
     component: 'JDictSelectTag',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
     <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
-    component: 'JMultiSelectTag',//TODO  暂无该组件
+    component: 'JSelectMultiple',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
@@ -533,7 +527,7 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
     </#if>
       },
   <#elseif po.classType=='umeditor'>
-    component: 'JCodeEditor', //TODO String后缀暂未添加
+    component: 'JEditor',
   <#elseif po.classType == 'sel_tree'>
     component: 'JTreeSelect',
     componentProps:{
@@ -565,16 +559,16 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
            </#if>
        <#-- 唯一校验 -->
            <#if fieldValidType == 'only'>
-                 {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
+                 {...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}$/, message: '请输入6到16位数字!'},
            <#-- 6到16位任意字符 -->
            <#elseif fieldValidType == '*6-16'>
                  { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
-           <#-- 6到18位字符串 -->
+           <#-- 6到18位字母 -->
            <#elseif fieldValidType == 's6-18'>
-                 { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
+                 { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
            <#-- 网址 -->
            <#elseif fieldValidType == 'url'>
                  { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
@@ -616,6 +610,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
   },
 </#if>
 </#list>
+<#if sub_id_exists == false>
+	{
+	  label: '',
+	  field: 'id',
+	  component: 'Input',
+	  show: false
+	},
+</#if>
 ];
 </#if>
 </#list>
@@ -642,12 +644,20 @@ export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [
       <#if col.readonly=='Y'>
       disabled:true,
       </#if>
+<#elseif col.classType =='time'>
+      type: JVxeTypes.time,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
 <#elseif col.classType =='textarea'>
       type: JVxeTypes.textarea,
        <#if col.readonly=='Y'>
       disabled:true,
        </#if>
-<#elseif "int,decimal,double,"?contains(col.classType)>
+<#-- update-begin-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 -->
+<#-- elseif "int,decimal,double,"?contains(col.classType) -->
+<#elseif col.fieldDbType=='int' || col.fieldDbType=='double' || col.fieldDbType=='BigDecimal'>
+<#-- update-end-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 -->
       type: JVxeTypes.inputNumber,
       <#if col.readonly=='Y'>
       disabled:true,
@@ -684,6 +694,16 @@ export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [
       <#if col.readonly=='Y'>
       disabled:true,
       </#if>
+<#elseif col.classType =='sel_depart'>
+      type: JVxeTypes.departSelect,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+<#elseif col.classType =='sel_user'>
+      type: JVxeTypes.userSelect,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
 <#elseif col.classType =='image'>
       type: JVxeTypes.image,
       token:true,
@@ -707,9 +727,9 @@ export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [
 <#elseif col.classType =='switch'>
       type: JVxeTypes.checkbox,
        <#if col.dictField == 'is_open'>
-        customValue: ['Y', 'N'],
+      customValue: ['Y', 'N'],
         <#else>
-        customValue: ${col.dictField},
+      customValue: ${col.dictField},
         </#if>
       <#if col.readonly=='Y'>
       disabled:true,
@@ -720,18 +740,11 @@ export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [
 <#else>
     <#assign popupBackFields = "${col.dictText}">
 </#if>
-      type: JVxeTypes.popup,
-      popupCode:"${col.dictTable}",
-      field:"${col.dictField}",
-      orgFields:"${col.dictField}",
-      destFields:"${Format.underlineToHump(col.dictText)}",
-      <#if col.readonly=='Y'>
-      disabled:true,
-      </#if>
+    <#include "/common/form/vue3Jvxepopup.ftl">
 <#else>
-       type: JVxeTypes.input,
+      type: JVxeTypes.input,
        <#if col.readonly=='Y'>
-       disabled:true,
+      disabled:true,
        </#if>
 </#if>
 <#if col.classType =='list_multi' || col.classType =='checkbox'>
@@ -754,18 +767,7 @@ export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [
       defaultValue:'',
 </#if>
 <#-- 子表的校验 -->
-<#assign subFieldValidType = col.fieldValidType!''>
-<#-- 非空校验 -->
-<#if col.nullable == 'N' || subFieldValidType == '*'>
-      validateRules: [{ required: true, message: '${'$'}{title}不能为空' }],
-<#-- 其他情况下,只要有值就被认为是正则校验 -->
-<#elseif subFieldValidType?length gt 0>
-<#assign subMessage = '格式不正确'>
-<#if subFieldValidType == 'only' >
-  <#assign subMessage = '不能重复'>
-</#if>
-      validateRules: [{ pattern: "${subFieldValidType}", message: "${'$'}{title}${subMessage}" }],
-</#if>
+ <#include "/common/validatorRulesTemplate/sub-vue3.ftl">
     },
 </#if>
 </#if>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
index 4996cb5..b641c5d 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
@@ -1,5 +1,6 @@
+<#include "/common/utils.ftl">
 <template>
-  <BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
+  <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
       <BasicForm @register="registerForm" ref="formRef"/>
   <!-- 子表单区域 -->
     <a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs">
@@ -7,7 +8,7 @@
   <#assign refKey = sub.entityName?uncap_first/>
   <#if sub.foreignRelationType =='1'>
       <a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true">
-        <${sub.entityName}Form ref="${sub.entityName?uncap_first}Form"></${sub.entityName}Form>
+        <${sub.entityName}Form ref="${sub.entityName?uncap_first}Form" :disabled="formDisabled"></${sub.entityName}Form>
       </a-tab-pane>
 
   <#else>
@@ -19,7 +20,8 @@
           :loading="${sub.entityName?uncap_first}Table.loading"
           :columns="${sub.entityName?uncap_first}Table.columns"
           :dataSource="${sub.entityName?uncap_first}Table.dataSource"
-          :maxHeight="300"
+          :height="340"
+          :disabled="formDisabled"
           :rowNumber="true"
           :rowSelection="true"
           :toolbar="true"
@@ -48,6 +50,7 @@
     // Emits声明
     const emit = defineEmits(['register','success']);
     const isUpdate = ref(true);
+    const formDisabled = ref(false);
     const refKeys = ref([<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]);
     <#assign hasOne2Many = false>
     <#assign hasOne2One = false>
@@ -77,6 +80,7 @@
         labelWidth: 150,
         schemas: formSchema,
         showActionButtonGroup: false,
+        baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}
     });
      //表单赋值
     const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
@@ -84,6 +88,7 @@
         await reset();
         setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter});
         isUpdate.value = !!data?.isUpdate;
+        formDisabled.value = !data?.showFooter;
         if (unref(isUpdate)) {
             //表单赋值
             await setFieldsValue({
@@ -176,5 +181,12 @@
 </script>
 
 <style lang="less" scoped>
+	/** 时间和数字输入框样式 */
+    :deep(.ant-input-number){
+		width: 100%
+	}
 
+	:deep(.ant-calendar-picker){
+		width: 100%
+	}
 </style>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei
index 062fa1b..37dde1f 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 <#list subTables as sub>
 <#if sub.foreignRelationType=='1'>
 #segment#${sub.entityName}Form.vue
@@ -15,11 +16,18 @@
         name:"${sub.entityName}Form",
         components: {BasicForm},
         emits:['register'],
-        setup(_,{emit}) {
-            const [registerForm, {resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
+        props:{
+            disabled: {
+                type: Boolean,
+                default: false
+            }
+        },
+        setup(props,{emit}) {
+            const [registerForm, {setProps, resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
                 labelWidth: 150,
                 schemas: ${sub.entityName?uncap_first}FormSchema,
                 showActionButtonGroup: false,
+                baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}
             });
             /**
             *初始化加载数据
@@ -30,13 +38,22 @@
                        res.success && setFieldsValue({...res.result.records[0]});
                     })
                 }
+                setProps({disabled: props.disabled})
             }
-           /**
-            *获取表单数据
-            */
+
+            /**
+             *获取表单数据
+             */
             function getFormData(){
-               return [getFieldsValue()];
+                let formData = getFieldsValue();
+                Object.keys(formData).map(k=>{
+                    if(formData[k] instanceof Array){
+                        formData[k] = formData[k].join(',')
+                    }
+                });
+                return [formData];
             }
+
             /**
             *表单校验
             */
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
index 43919c8..f9e34db 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
@@ -205,17 +205,14 @@ public class ${entityName}Controller {
       QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap());
       LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
 
-      //Step.2 获取导出数据
-      List<${entityName}> queryList = ${entityName?uncap_first}Service.list(queryWrapper);
-      // 过滤选中数据
+      //配置选中数据查询条件
       String selections = request.getParameter("selections");
-      List<${entityName}> ${entityName?uncap_first}List = new ArrayList<${entityName}>();
-      if(oConvertUtils.isEmpty(selections)) {
-          ${entityName?uncap_first}List = queryList;
-      }else {
-          List<String> selectionList = Arrays.asList(selections.split(","));
-          ${entityName?uncap_first}List = queryList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
+      if(oConvertUtils.isNotEmpty(selections)) {
+         List<String> selectionList = Arrays.asList(selections.split(","));
+         queryWrapper.in("id",selectionList);
       }
+      //Step.2 获取导出数据
+      List<${entityName}> ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper);
 
       // Step.3 组装pageList
       List<${entityName}Page> pageList = new ArrayList<${entityName}Page>();
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
index c861c4a..4d1b425 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 package ${bussiPackage}.${entityPackage}.entity;
 
 import java.io.Serializable;
@@ -31,9 +32,9 @@ public class ${entityName} implements Serializable {
     <#-- 生成字典Code -->
     <#assign list_field_dictCode="">
     <#if po.classType='sel_user'>
-      <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'>
+      <#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 = "depart_name", dicCode = "id"'>
+      <#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}"'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
index b6aabe8..93ddf95 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 <#list subTables as subTab>
 #segment#${subTab.entityName}.java
 package ${bussiPackage}.${entityPackage}.entity;
@@ -32,9 +33,9 @@ public class ${subTab.entityName} implements Serializable {
 	<#-- 生成字典Code -->
 	<#assign list_field_dictCode="">
 	<#if po.classType='sel_user'>
-		<#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'>
+		<#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 = "depart_name", dicCode = "id"'>
+		<#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}"'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
index f387f76..51b96c7 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
@@ -48,7 +48,7 @@
                 @input="popupCallback"
                 <#if po.readonly=='Y'>disabled</#if>/>
     <#elseif po.classType =='sel_depart'>
-              <j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/>
+              <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'>
@@ -58,7 +58,7 @@
     <#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}" <#if po.readonly=='Y'>disabled</#if>/>
+              <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'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
index 96cfc11..97d1203 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
@@ -44,7 +44,7 @@
                 :multi="${po.extendParams.popupMulti?c}"
                 @input="popupCallback"/>
     <#elseif po.classType =='sel_depart'>
-              <j-select-depart v-model="model.${po.fieldName}" multi/>
+              <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>></j-switch>
 	<#elseif po.classType =='pca'>
@@ -54,7 +54,7 @@
     <#elseif po.classType =='password'>
 	          <a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"/>
 	<#elseif po.classType =='sel_user'>
-              <j-select-user-by-dep v-model="model.${po.fieldName}"/>
+              <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}"/>
 	<#elseif po.classType=='list' || po.classType=='radio'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
index b75bbbd..b8cfe02 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
@@ -46,6 +46,10 @@
       <template #htmlSlot="{text}">
          <div v-html="text"></div>
       </template>
+      <!--省市区字段回显插槽-->
+      <template #pcaSlot="{text}">
+        {{ getAreaTextByCode(text) }}
+      </template>
       <template #fileSlot="{text}">
          <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>
@@ -64,6 +68,10 @@
   import ${entityName}Modal from './components/${entityName}Modal.vue'
   import {columns, searchFormSchema} from './${entityName}.data';
   import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api';
+  import {downloadFile} from '/@/utils/common/renderUtils';
+<#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';
@@ -84,6 +92,17 @@
                 schemas: searchFormSchema,
                 autoSubmitOnEnter:true,
                 showAdvancedButton:true,
+                fieldMapToNumber: [
+                   <#list columns as po>
+                   <#if po.isQuery=='Y'>
+                   <#if po.queryMode!='single'>
+                   <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+                   ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end']],
+                   </#if>
+                   </#if>
+                   </#if>
+                   </#list>
+                ],
                 fieldMapToTime: [
                 <#list columns as po>
                 <#if po.isQuery=='Y'>
@@ -98,9 +117,10 @@
                 </#list>
                 ],
             },
-            actionColumn: {
+           actionColumn: {
                width: 120,
-            },
+               fixed:'right'
+           },
         },
         exportConfig: {
             name:"${tableVo.ftlDescription}",
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
index c52445a..bb4097f 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 import {BasicColumn} from '/@/components/Table';
 import {FormSchema} from '/@/components/Table';
 import { rules} from '/@/utils/helper/validator';
@@ -25,7 +26,7 @@ export const columns: BasicColumn[] = [
     slots: { customRender: 'htmlSlot' },
     <#elseif po.classType=='pca'>
     dataIndex: '${po.fieldName}',
-    slots: { customRender: 'pcaSlot' },//TODO 未翻译
+    slots: { customRender: 'pcaSlot' },
    <#elseif po.classType=='file'>
     dataIndex: '${po.fieldName}',
     slots: { customRender: 'fileSlot' },
@@ -57,7 +58,7 @@ export const columns: BasicColumn[] = [
        return  render.renderCategoryTree(text,'${po.dictField?default("")}')
    },
    <#else>
-    customRender: (text, record) => (text ? record['${po.dictText}'] : '')
+    customRender: ({text, record}) => (text ? record['${po.dictText}'] : '')
    </#if>
    <#else>
     dataIndex: '${po.fieldName}'
@@ -95,16 +96,22 @@ export const searchFormSchema: FormSchema[] = [
 <#elseif po.classType=='switch'>
       component: 'JSwitch',
       componentProps:{
+           query:true,
            <#if po.dictField != 'is_open'>
-           options:"${po.dictField}"
+           options:${po.dictField}
            </#if>
        },
  <#elseif po.classType=='sel_depart'>
       component: 'JSelectDept',
  <#elseif po.classType=='list_multi'>
-      component: 'JMultiSelectTag',//暂无该组件
+      component: 'JSelectMultiple',
       componentProps:{
-          dictCode:"query_field_dictCode?default("")"
+        <#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',
@@ -121,16 +128,7 @@ export const searchFormSchema: FormSchema[] = [
 <#elseif po.classType=='pca'>
       component: 'JAreaLinkage',
 <#elseif po.classType=='popup'>
-      component: 'JPopup',
-      componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:"${po.dictField}",
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
 <#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
 <#--  ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
       component: 'JDictSelectTag',
@@ -157,6 +155,8 @@ export const searchFormSchema: FormSchema[] = [
       componentProps: {
           showTime:true
       },
+<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+      component: 'JRangeNumber',
 <#else>
       component: 'Input', //TODO 范围查询
 </#if>
@@ -189,27 +189,22 @@ export const formSchema: FormSchema[] = [
 	</#if>
   {
     label: '${po.filedComment}',
-    field: '${po.fieldName}',
+    field: ${autoStringSuffix(po)},
     <#if po.classType =='date'>
     component: 'DatePicker',
-     <#elseif po.fieldType =='datetime'>
+     <#elseif po.classType =='datetime'>
     component: 'DatePicker',
     componentProps: {
-       showTime:true
+       showTime:true,
+       valueFormat: 'YYYY-MM-DD HH:mm:ss'
      },
-     <#elseif po.fieldType =='time'>
+     <#elseif po.classType =='time'>
     component: 'TimePicker',
+    componentProps: {
+      valueFormat: 'HH:mm:ss'
+    },
     <#elseif po.classType =='popup'>
-    component: 'JPopup',
-    componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:${po.dictField},
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
      <#elseif po.classType =='sel_depart'>
      component: 'JSelectDept',
      <#elseif po.classType =='switch'>
@@ -231,14 +226,14 @@ export const formSchema: FormSchema[] = [
         labelKey:'realname',
      },
     <#elseif po.classType =='textarea'>
-    component: 'InputTextArea',//TODO 注意string转换问题
+    component: 'InputTextArea',
     <#elseif po.classType=='list' || po.classType=='radio'>
     component: 'JDictSelectTag',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
     <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
-    component: 'JMultiSelectTag',//TODO  暂无该组件
+    component: 'JSelectMultiple',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
@@ -273,7 +268,7 @@ export const formSchema: FormSchema[] = [
     </#if>
       },
   <#elseif po.classType=='umeditor'>
-    component: 'JCodeEditor', //TODO String后缀暂未添加
+    component: 'JEditor',
   <#elseif po.classType == 'sel_tree'>
     component: 'JTreeSelect',
     componentProps:{
@@ -305,16 +300,16 @@ export const formSchema: FormSchema[] = [
            </#if>
        <#-- 唯一校验 -->
            <#if fieldValidType == 'only'>
-                 {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
+                 {...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}$/, message: '请输入6到16位数字!'},
            <#-- 6到16位任意字符 -->
            <#elseif fieldValidType == '*6-16'>
                  { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
-           <#-- 6到18位字符串 -->
+           <#-- 6到18位字母 -->
            <#elseif fieldValidType == 's6-18'>
-                 { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
+                 { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
            <#-- 网址 -->
            <#elseif fieldValidType == 'url'>
                  { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
@@ -373,10 +368,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
 <#assign form_cat_tree = false>
 <#assign form_cat_back = "">
 <#assign bpm_flag=false>
+<#assign sub_id_exists=false>
 <#list sub.colums as po><#rt/>
 <#if po.fieldDbName=='bpm_status'>
   <#assign bpm_flag=true>
 </#if>
+<#if po.fieldDbName=='id'>
+  <#assign sub_id_exists=true>
+</#if>
 <#if po.isShow =='Y'>
 <#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>
@@ -386,27 +385,22 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
 	</#if>
   {
     label: '${po.filedComment}',
-    field: '${po.fieldName}',
+    field: ${autoStringSuffix(po)},
     <#if po.classType =='date'>
     component: 'DatePicker',
-     <#elseif po.fieldType =='datetime'>
+     <#elseif po.classType =='datetime'>
     component: 'DatePicker',
     componentProps: {
-       showTime:true
+       showTime:true,
+       valueFormat: 'YYYY-MM-DD HH:mm:ss'
      },
-     <#elseif po.fieldType =='time'>
+     <#elseif po.classType =='time'>
     component: 'TimePicker',
+    componentProps: {
+      valueFormat: 'HH:mm:ss'
+    },
     <#elseif po.classType =='popup'>
-    component: 'JPopup',
-    componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:${po.dictField},
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
      <#elseif po.classType =='sel_depart'>
      component: 'JSelectDept',
      <#elseif po.classType =='switch'>
@@ -428,14 +422,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
         labelKey:'realname',
      },
     <#elseif po.classType =='textarea'>
-    component: 'InputTextArea',//TODO 注意string转换问题
+    component: 'InputTextArea',
     <#elseif po.classType=='list' || po.classType=='radio'>
     component: 'JDictSelectTag',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
     <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
-    component: 'JMultiSelectTag',//TODO  暂无该组件
+    component: 'JSelectMultiple',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      }
@@ -470,7 +464,7 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
     </#if>
       },
   <#elseif po.classType=='umeditor'>
-    component: 'JCodeEditor', //TODO String后缀暂未添加
+    component: 'JEditor',
   <#elseif po.classType == 'sel_tree'>
     component: 'JTreeSelect',
     componentProps:{
@@ -502,16 +496,16 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
            </#if>
        <#-- 唯一校验 -->
            <#if fieldValidType == 'only'>
-                 {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
+                 {...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}$/, message: '请输入6到16位数字!'},
            <#-- 6到16位任意字符 -->
            <#elseif fieldValidType == '*6-16'>
                  { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
-           <#-- 6到18位字符串 -->
+           <#-- 6到18位字母 -->
            <#elseif fieldValidType == 's6-18'>
-                 { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
+                 { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
            <#-- 网址 -->
            <#elseif fieldValidType == 'url'>
                  { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
@@ -553,6 +547,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
   },
 </#if>
 </#list>
+<#if sub_id_exists == false>
+	{
+	  label: '',
+	  field: 'id',
+	  component: 'Input',
+	  show: false
+	},
+</#if>
 ];
 </#if>
 </#list>
@@ -579,12 +581,20 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
       <#if col.readonly=='Y'>
       disabled:true,
       </#if>
+<#elseif col.classType =='time'>
+      type: JVxeTypes.time,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
 <#elseif col.classType =='textarea'>
       type: JVxeTypes.textarea,
        <#if col.readonly=='Y'>
       disabled:true,
        </#if>
-<#elseif "int,decimal,double,"?contains(col.classType)>
+<#-- update-begin-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 -->
+<#-- elseif "int,decimal,double,"?contains(col.classType) -->
+<#elseif col.fieldDbType=='int' || col.fieldDbType=='double' || col.fieldDbType=='BigDecimal'>
+<#-- update-end-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 -->
       type: JVxeTypes.inputNumber,
       <#if col.readonly=='Y'>
       disabled:true,
@@ -621,6 +631,16 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
       <#if col.readonly=='Y'>
       disabled:true,
       </#if>
+<#elseif col.classType =='sel_depart'>
+      type: JVxeTypes.departSelect,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+<#elseif col.classType =='sel_user'>
+      type: JVxeTypes.userSelect,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
 <#elseif col.classType =='image'>
       type: JVxeTypes.image,
       token:true,
@@ -644,9 +664,9 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
 <#elseif col.classType =='switch'>
       type: JVxeTypes.checkbox,
        <#if col.dictField == 'is_open'>
-        customValue: ['Y', 'N'],
+      customValue: ['Y', 'N'],
         <#else>
-        customValue: ${col.dictField},
+      customValue: ${col.dictField},
         </#if>
       <#if col.readonly=='Y'>
       disabled:true,
@@ -657,18 +677,11 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
 <#else>
     <#assign popupBackFields = "${col.dictText}">
 </#if>
-      type: JVxeTypes.popup,
-      popupCode:"${col.dictTable}",
-      field:"${col.dictField}",
-      orgFields:"${col.dictField}",
-      destFields:"${Format.underlineToHump(col.dictText)}",
-      <#if col.readonly=='Y'>
-      disabled:true,
-      </#if>
+    <#include "/common/form/vue3Jvxepopup.ftl">
 <#else>
-       type: JVxeTypes.input,
+      type: JVxeTypes.input,
        <#if col.readonly=='Y'>
-       disabled:true,
+      disabled:true,
        </#if>
 </#if>
 <#if col.classType =='list_multi' || col.classType =='checkbox'>
@@ -691,18 +704,7 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
       defaultValue:'',
 </#if>
 <#-- 子表的校验 -->
-<#assign subFieldValidType = col.fieldValidType!''>
-<#-- 非空校验 -->
-<#if col.nullable == 'N' || subFieldValidType == '*'>
-      validateRules: [{ required: true, message: '${'$'}{title}不能为空' }],
-<#-- 其他情况下,只要有值就被认为是正则校验 -->
-<#elseif subFieldValidType?length gt 0>
-<#assign subMessage = '格式不正确'>
-<#if subFieldValidType == 'only' >
-  <#assign subMessage = '不能重复'>
-</#if>
-      validateRules: [{ pattern: "${subFieldValidType}", message: "${'$'}{title}${subMessage}" }],
-</#if>
+ <#include "/common/validatorRulesTemplate/sub-vue3.ftl">
     },
 </#if>
 </#if>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..7292339
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
index 6a2e26b..85ffc47 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
@@ -1,5 +1,6 @@
+<#include "/common/utils.ftl">
 <template>
-  <BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
+  <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
       <BasicForm @register="registerForm" ref="formRef"/>
   <!-- 子表单区域 -->
     <a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs">
@@ -7,7 +8,7 @@
   <#assign refKey = sub.entityName?uncap_first/>
   <#if sub.foreignRelationType =='1'>
       <a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true">
-        <${sub.entityName}Form ref="${sub.entityName?uncap_first}Form"></${sub.entityName}Form>
+        <${sub.entityName}Form ref="${sub.entityName?uncap_first}Form" :disabled="formDisabled"></${sub.entityName}Form>
       </a-tab-pane>
 
   <#else>
@@ -19,9 +20,10 @@
           :loading="${sub.entityName?uncap_first}Table.loading"
           :columns="${sub.entityName?uncap_first}Table.columns"
           :dataSource="${sub.entityName?uncap_first}Table.dataSource"
-          :maxHeight="300"
+          :height="340"
           :rowNumber="true"
           :rowSelection="true"
+          :disabled="formDisabled"
           :toolbar="true"
           />
       </a-tab-pane>
@@ -48,6 +50,7 @@
     // Emits声明
     const emit = defineEmits(['register','success']);
     const isUpdate = ref(true);
+    const formDisabled = ref(false);
     const refKeys = ref([<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]);
     <#assign hasOne2Many = false>
     <#assign hasOne2One = false>
@@ -77,6 +80,7 @@
         labelWidth: 150,
         schemas: formSchema,
         showActionButtonGroup: false,
+        baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}
     });
      //表单赋值
     const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
@@ -84,6 +88,7 @@
         await reset();
         setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter});
         isUpdate.value = !!data?.isUpdate;
+        formDisabled.value = !data?.showFooter;
         if (unref(isUpdate)) {
             //表单赋值
             await setFieldsValue({
@@ -176,5 +181,12 @@
 </script>
 
 <style lang="less" scoped>
+	/** 时间和数字输入框样式 */
+    :deep(.ant-input-number){
+		width: 100%
+	}
 
+	:deep(.ant-calendar-picker){
+		width: 100%
+	}
 </style>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei
index 6af0c52..dbb8c09 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 <#list subTables as sub>
 <#if sub.foreignRelationType=='1'>
 #segment#${sub.entityName}Form.vue
@@ -15,11 +16,18 @@
         name:"${sub.entityName}Form",
         components: {BasicForm},
         emits:['register'],
-        setup(_,{emit}) {
-            const [registerForm, {resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
+        props:{
+            disabled: {
+                type: Boolean,
+                default: false
+            }
+        },
+        setup(props,{emit}) {
+            const [registerForm, {setProps, resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
                 labelWidth: 150,
                 schemas: ${sub.entityName?uncap_first}FormSchema,
                 showActionButtonGroup: false,
+                baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}
             });
             /**
             *初始化加载数据
@@ -30,12 +38,19 @@
                        res.success && setFieldsValue({...res.result[0]});
                     })
                 }
+                setProps({disabled: props.disabled})
             }
            /**
             *获取表单数据
             */
             function getFormData(){
-               return [getFieldsValue()];
+               let formData = getFieldsValue();
+               Object.keys(formData).map(k=>{
+                    if(formData[k] instanceof Array){
+                        formData[k] = formData[k].join(',')
+                    }
+               });
+               return [formData];
             }
             /**
             *表单校验
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei
new file mode 100644
index 0000000..75691fc
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei
@@ -0,0 +1,340 @@
+<template>
+  <div>
+    <#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_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>
+    <!--查询区域-->
+    <div class="jeecg-basic-table-form-container">
+      <a-form @keyup.enter.native="reload" :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=='sel_tree'>
+              <#assign need_select_tree = true>
+            </#if>
+            <#if po.classType=='time'>
+              <#assign need_time = 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="reload">查询</a-button>
+                <a-button 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" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
+          <a-button  type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
+          <j-upload-button  type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
+          <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>批量操作
+                <Icon icon="mdi:chevron-down"></Icon>
+              </a-button>
+        </a-dropdown>
+      </template>
+       <!--操作栏-->
+      <template #action="{ record }">
+        <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
+      </template>
+      <!--字段回显插槽-->
+      <template #htmlSlot="{text}">
+         <div v-html="text"></div>
+      </template>
+      <!--省市区字段回显插槽-->
+      <template #pcaSlot="{text}">
+        {{ getAreaTextByCode(text) }}
+      </template>
+      <template #fileSlot="{text}">
+         <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>
+      </template>
+    </BasicTable>
+    <!-- 表单区域 -->
+    <${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
+  </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 { useListPage } from '/@/hooks/system/useListPage'
+  import {useModal} from '/@/components/Modal';
+  import ${entityName}Modal from './components/${entityName}Modal.vue'
+  import {columns, searchFormSchema} from './${entityName}.data';
+  import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api';
+  import {downloadFile} from '/@/utils/common/renderUtils';
+  <#include "/common/form/native/vue3NativeImport.ftl">
+<#if need_pca>
+  import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
+</#if>
+  <#if need_category>
+  import { loadCategoryData } from '/@/api/common/api'
+  import { getAuthCache, setAuthCache } from '/@/utils/auth';
+  import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
+  </#if>
+  const checkedKeys = ref<Array<string | number>>([]);
+  //注册model
+  const [registerModal, {openModal}] = useModal();
+   //注册table数据
+  const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
+      tableProps:{
+           title: '${tableVo.ftlDescription}',
+           api: list,
+           columns,
+           canResize:false,
+           useSearchForm: false,
+           actionColumn: {
+               width: 120,
+               fixed:'right'
+           },
+           beforeFetch: (params) => {
+             return Object.assign(params, queryParam.value);
+           },
+        },
+        exportConfig: {
+            name:"${tableVo.ftlDescription}",
+            url: getExportUrl,
+        },
+        importConfig: {
+            url: getImportUrl,
+            success: handleSuccess
+        },
+    })
+
+  const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
+
+   /**
+    * 新增事件
+    */
+  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),
+         }
+       ]
+   }
+     /**
+        * 下拉操作栏
+        */
+  function getDropDownAction(record){
+      return [
+           {
+             label: '详情',
+             onClick: handleDetail.bind(null, record),
+           }, {
+             label: '删除',
+             popConfirm: {
+               title: '是否确认删除',
+               confirm: handleDelete.bind(null, record),
+             }
+           }
+      ]
+   }
+    <#if need_category>
+  /**
+   * form点击事件
+   * @param value
+   */
+  function handleFormChange(key, value) {
+    queryParam.value[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) {
+             let allDictDate = getAuthCache(DB_DICT_DATA_KEY);
+             if(!allDictDate['${po.dictField?default("")}']){
+               Object.assign(allDictDate,{'${po.dictField?default("")}':res})
+             }
+             setAuthCache(DB_DICT_DATA_KEY,allDictDate)
+         }
+       })
+       </#if>
+     </#if>
+     </#list>
+   }
+   initDictConfig();
+    </#if>
+
+  /* ----------------------以下为原生查询需要添加的-------------------------- */
+  const queryParam = ref<any>({});
+  const toggleSearchStatus = ref<boolean>(false);
+  const labelCol = reactive({
+    xs: { span: 24 },
+    sm: { span: 7 },
+  });
+  const wrapperCol = reactive({
+    xs: { span: 24 },
+    sm: { span: 16 },
+  });
+  /**
+   * 重置
+   */
+  function searchReset() {
+    queryParam.value = {};
+    selectedRowKeys.value = [];
+    //刷新数据
+    reload();
+  }
+  <#if need_popup>
+  /**
+   *  popup组件值改变事件
+   */
+  function setFieldsValue(map) {
+    Object.keys(map).map((key) => {
+      queryParam.value[key] = map[key];
+    });
+  }
+  </#if>
+
+  <#if need_pca>
+  /**
+   * 省市区点击事件
+   * @param key
+   * @param value
+   */
+  function handleAreaChange(key, value) {
+    queryParam.value[key] = value.join(',');
+  }
+  </#if>
+</script>
+<style lang="less" scoped>
+  .jeecg-basic-table-form-container {
+  .table-page-search-submitButtons {
+    display: block;
+    margin-bottom: 24px;
+    white-space: nowrap;
+  }
+  .query-group-cust{
+    width: calc(50% - 15px);
+    min-width: 100px !important;
+  }
+  .query-group-split-cust{
+    width: 30px;
+    display: inline-block;
+    text-align: center
+  }
+  }
+</style>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi
new file mode 100644
index 0000000..74f56d1
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi
@@ -0,0 +1,82 @@
+import {defHttp} from '/@/utils/http/axios';
+import {Modal} from 'ant-design-vue';
+
+enum Api {
+  list = '/${entityPackage}/${entityName?uncap_first}/list',
+  save='/${entityPackage}/${entityName?uncap_first}/add',
+  edit='/${entityPackage}/${entityName?uncap_first}/edit',
+  deleteOne = '/${entityPackage}/${entityName?uncap_first}/delete',
+  deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
+  importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
+  exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
+  queryDataById = '/${entityPackage}/${entityName?uncap_first}/queryById',
+<#list subTables as sub><#rt/>
+  ${sub.entityName?uncap_first}List = '/${entityPackage}/${entityName?uncap_first}/query${sub.entityName}ByMainId',
+</#list>
+}
+/**
+ * 导出api
+ * @param params
+ */
+export const getExportUrl = Api.exportXls;
+
+/**
+ * 导入api
+ */
+export const getImportUrl = Api.importExcel;
+
+<#list subTables as sub><#rt/>
+/**
+ * 查询子表数据
+ * @param params
+ */
+export const query${sub.entityName}ListByMainId = (id) => defHttp.get({url: Api.${sub.entityName?uncap_first}List, params:{ id }});
+</#list>
+
+/**
+ * 列表接口
+ * @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) => {
+  Modal.confirm({
+    title: '确认删除',
+    content: '是否删除选中数据',
+    okText: '确认',
+    cancelText: '取消',
+    onOk: () => {
+      return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
+        handleSuccess();
+      });
+    }
+  });
+}
+/**
+ * 保存或者更新
+ * @param params
+ */
+export const saveOrUpdate = (params, isUpdate) => {
+  let url = isUpdate ? Api.edit : Api.save;
+  return defHttp.post({url: url, params});
+}
+
+/**
+* 根据id查询数据
+* @param params
+*/
+export const queryDataById = (id) => defHttp.get({url: Api.queryDataById, params:{ id }});
+
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi
new file mode 100644
index 0000000..243f984
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi
@@ -0,0 +1,714 @@
+<#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 {JVxeTypes,JVxeColumn} from '/@/components/jeecg/JVxeTable/types'
+//列表数据
+export const columns: BasicColumn[] = [
+ <#list columns as po>
+   <#if po.isShowList =='Y' && po.fieldName !='id'>
+   {
+    title: '${po.filedComment}',
+    align:"center",
+    <#if po.sort=='Y'>
+    sorter: true,
+   </#if>
+    <#if po.classType=='date'>
+    dataIndex: '${po.fieldName}',
+    customRender:({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}',
+    slots: { customRender: 'htmlSlot' },
+    <#elseif po.classType=='pca'>
+    dataIndex: '${po.fieldName}',
+    slots: { customRender: 'pcaSlot' },
+   <#elseif po.classType=='file'>
+    dataIndex: '${po.fieldName}',
+    slots: { customRender: 'fileSlot' },
+   <#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'>
+    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>
+<#if po.isQuery=='Y'>
+<#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: "${po.fieldName}",
+<#if po.classType=='sel_search'>
+      component: 'JSearchSelect',
+      componentProps:{
+         dict:"${po.dictTable},${po.dictText},${po.dictField}"
+      },
+<#elseif po.classType=='sel_user'>
+      component: 'JSelectUserByDept',
+<#elseif po.classType=='switch'>
+      component: 'JSwitch',
+      componentProps:{
+           <#if po.dictField != 'is_open'>
+           options:"${po.dictField}"
+           </#if>
+       },
+ <#elseif po.classType=='sel_depart'>
+      component: 'JSelectDept',
+ <#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',
+<#elseif po.classType=='datetime'>
+      component: 'DatePicker',
+      componentProps: {
+         showTime:true
+       },
+<#elseif po.classType=='pca'>
+      component: 'JAreaLinkage',
+<#elseif po.classType=='popup'>
+    <#include "/common/form/vue3popup.ftl">
+<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
+<#--  ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
+      component: 'JDictSelectTag',
+      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>
+      },
+<#else>
+      component: 'Input',
+</#if>
+      colProps: {span: 6},
+ 	},
+<#else>
+     {
+      label: "${po.filedComment}",
+      field: "${po.fieldName}",
+<#if po.classType=='date'>
+      component: 'RangePicker',
+<#elseif po.classType=='datetime'>
+      component: 'RangePicker',
+      componentProps: {
+          showTime:true
+      },
+<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+      component: 'JRangeNumber',
+<#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>
+<#if po.isShow =='Y'>
+<#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)},
+    <#if po.classType =='date'>
+    component: 'DatePicker',
+     <#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 =='sel_depart'>
+     component: 'JSelectDept',
+     <#elseif po.classType =='switch'>
+     component: 'JSwitch',
+     componentProps:{
+         <#if po.dictField != 'is_open'>
+         options:${po.dictField}
+         </#if>
+     },
+     <#elseif po.classType =='pca'>
+    component: 'JAreaLinkage',
+    <#elseif po.classType =='markdown'>
+    component: 'JMarkdownEditor',//注意string转换问题
+     <#elseif po.classType =='password'>
+    component: 'InputPassword',
+     <#elseif po.classType =='sel_user'>
+    component: 'JSelectUserByDept',
+    componentProps:{
+        labelKey:'realname',
+     },
+    <#elseif po.classType =='textarea'>
+    component: 'InputTextArea',
+    <#elseif po.classType=='list' || po.classType=='radio'>
+    component: 'JDictSelectTag',
+    componentProps:{
+        dictCode:"${form_field_dictCode}"
+     },
+    <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
+    component: 'JSelectMultiple',
+    componentProps:{
+        dictCode:"${form_field_dictCode}"
+     },
+    <#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=='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}
+    </#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}",
+    },
+   <#else>
+    component: 'Input',
+    </#if>
+     <#include "/common/utils.ftl">
+    <#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}$/, message: '请输入6到16位数字!'},
+           <#-- 6到16位任意字符 -->
+           <#elseif fieldValidType == '*6-16'>
+                 { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
+           <#-- 6到18位字符串 -->
+           <#elseif fieldValidType == 's6-18'>
+                 { pattern: /^.{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: /^[1-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>
+];
+//子表单数据
+<#list subTables as sub>
+<#if sub.foreignRelationType =='1'>
+export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
+<#assign form_cat_tree = false>
+<#assign form_cat_back = "">
+<#assign bpm_flag=false>
+<#assign sub_id_exists=false>
+<#list sub.colums as po><#rt/>
+<#if po.fieldDbName=='bpm_status'>
+  <#assign bpm_flag=true>
+</#if>
+<#if po.fieldDbName=='id'>
+  <#assign sub_id_exists=true>
+</#if>
+<#if po.isShow =='Y'>
+<#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)},
+    <#if po.classType =='date'>
+    component: 'DatePicker',
+     <#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 =='sel_depart'>
+     component: 'JSelectDept',
+     <#elseif po.classType =='switch'>
+     component: 'JSwitch',
+     componentProps:{
+         <#if po.dictField != 'is_open'>
+         options:${po.dictField}
+         </#if>
+     },
+     <#elseif po.classType =='pca'>
+    component: 'JAreaLinkage',
+    <#elseif po.classType =='markdown'>
+    component: 'JMarkdownEditor',//注意string转换问题
+     <#elseif po.classType =='password'>
+    component: 'InputPassword',
+     <#elseif po.classType =='sel_user'>
+    component: 'JSelectUserByDept',
+    componentProps:{
+        labelKey:'realname',
+     },
+    <#elseif po.classType =='textarea'>
+    component: 'InputTextArea',
+    <#elseif po.classType=='list' || po.classType=='radio'>
+    component: 'JDictSelectTag',
+    componentProps:{
+        dictCode:"${form_field_dictCode}"
+     },
+    <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
+    component: 'JSelectMultiple',
+    componentProps:{
+        dictCode:"${form_field_dictCode}"
+     }
+    <#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=='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}
+    </#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}",
+    },
+   <#else>
+    component: 'Input',
+    </#if>
+     <#include "/common/utils.ftl">
+    <#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}$/, message: '请输入6到16位数字!'},
+           <#-- 6到16位任意字符 -->
+           <#elseif fieldValidType == '*6-16'>
+                 { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
+           <#-- 6到18位字符串 -->
+           <#elseif fieldValidType == 's6-18'>
+                 { pattern: /^.{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: /^[1-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 sub_id_exists == false>
+	{
+	  label: '',
+	  field: 'id',
+	  component: 'Input',
+	  show: false
+	},
+</#if>
+];
+</#if>
+</#list>
+//子表表格配置
+<#list subTables as sub>
+<#if sub.foreignRelationType =='0'>
+export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
+<#assign popupBackFields = "">
+
+<#-- 循环子表的列 开始 -->
+<#list sub.colums as col><#rt/>
+<#if col.isShow =='Y'>
+<#if col.filedComment !='外键' >
+    {
+      title: '${col.filedComment}',
+      key: '${autoStringSuffixForModel(col)}',
+<#if col.classType =='date'>
+      type: JVxeTypes.date,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+<#elseif col.classType =='datetime'>
+      type: JVxeTypes.datetime,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+<#elseif col.classType =='time'>
+      type: JVxeTypes.time,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+<#elseif col.classType =='textarea'>
+      type: JVxeTypes.textarea,
+       <#if col.readonly=='Y'>
+      disabled:true,
+       </#if>
+<#-- update-begin-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 -->
+<#-- elseif "int,decimal,double,"?contains(col.classType) -->
+<#elseif col.fieldDbType=='int' || col.fieldDbType=='double' || col.fieldDbType=='BigDecimal'>
+<#-- update-end-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 -->
+      type: JVxeTypes.inputNumber,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+<#elseif col.classType =='list' || col.classType =='radio'>
+      type: JVxeTypes.select,
+      options:[],
+      <#if col.dictTable?default("")?trim?length gt 1>
+      dictCode:"${col.dictTable},${col.dictText},${col.dictField}",
+      <#else>
+      dictCode:"${col.dictField}",
+      </#if>
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+<#elseif col.classType =='list_multi' || col.classType =='checkbox'>
+      type: JVxeTypes.selectMultiple,
+      options:[],
+      <#if col.dictTable?default("")?trim?length gt 1>
+      dictCode:"${col.dictTable},${col.dictText},${col.dictField}",
+      <#else>
+      dictCode:"${col.dictField}",
+      </#if>
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+<#elseif col.classType =='sel_search'>
+      type: JVxeTypes.selectSearch,
+      <#if col.dictTable?default("")?trim?length gt 1>
+      dictCode:"${col.dictTable},${col.dictText},${col.dictField}",
+      <#else>
+      dictCode:"${col.dictField}",
+      </#if>
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+<#elseif col.classType =='sel_depart'>
+      type: JVxeTypes.departSelect,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+<#elseif col.classType =='sel_user'>
+      type: JVxeTypes.userSelect,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+<#elseif col.classType =='image'>
+      type: JVxeTypes.image,
+      token:true,
+      responseName:"message",
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+      <#if col.uploadnum??>
+      number: ${col.uploadnum},
+      </#if>
+<#elseif col.classType =='file'>
+      type: JVxeTypes.file,
+      token:true,
+      responseName:"message",
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+      <#if col.uploadnum??>
+      number: ${col.uploadnum},
+      </#if>
+<#elseif col.classType =='switch'>
+      type: JVxeTypes.checkbox,
+       <#if col.dictField == 'is_open'>
+      customValue: ['Y', 'N'],
+        <#else>
+      customValue: ${col.dictField},
+        </#if>
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+<#elseif col.classType =='popup'>
+<#if popupBackFields?length gt 0>
+    <#assign popupBackFields = "${popupBackFields}"+","+"${col.dictText}">
+<#else>
+    <#assign popupBackFields = "${col.dictText}">
+</#if>
+    <#include "/common/form/vue3Jvxepopup.ftl">
+<#else>
+      type: JVxeTypes.input,
+       <#if col.readonly=='Y'>
+      disabled:true,
+       </#if>
+</#if>
+<#if col.classType =='list_multi' || col.classType =='checkbox'>
+      width:"250px",
+<#else>
+      width:"200px",
+</#if>
+<#if col.classType =='file'>
+      placeholder: '请选择文件',
+<#else>
+      placeholder: '请输入${'$'}{title}',
+</#if>
+<#if col.defaultVal??>
+<#if col.fieldDbType=="BigDecimal" || col.fieldDbType=="double" || col.fieldDbType=="int">
+      defaultValue:${col.defaultVal},
+      <#else>
+      defaultValue:"${col.defaultVal}",
+</#if>
+<#else>
+      defaultValue:'',
+</#if>
+<#-- 子表的校验 -->
+ <#include "/common/validatorRulesTemplate/sub-vue3.ftl">
+    },
+</#if>
+</#if>
+</#list>
+<#-- 循环子表的列 结束 -->
+  ]
+</#if>
+</#list>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei
new file mode 100644
index 0000000..e3e4cf8
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei
@@ -0,0 +1,264 @@
+<#include "/common/utils.ftl">
+<#assign need_category = false>
+<#assign bpm_flag=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_select_tag = false>
+<#assign need_select_tree = false>
+<#assign need_time = false>
+<#assign need_markdown = false>
+<#assign need_upload = false>
+<#assign need_image_upload = false>
+<#assign need_editor = false>
+<#assign need_checkbox = 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>
+<#assign hasOne2manyTable = false>
+<#assign subTabActiveKey = ''>
+<#assign subMainFieldMap={}>
+<#assign subTableColumnsKey=[]>
+<#assign hasOnlyValidate = false>
+<template>
+  <a-spin :spinning="loading">
+    <a-form v-bind="formItemLayout">
+      <a-row>
+			<#list columns as po>
+        <#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'>
+          <#assign hasOnlyValidate = true>
+        </#if>
+				<#if po.fieldDbName=='bpm_status'>
+				    <#assign bpm_flag=true>
+				</#if>
+<#include "/common/form/native/vue3NativeForm.ftl">
+      </#list>
+      </a-row>
+    </a-form>
+
+		<!-- 子表单区域 -->
+    <a-tabs v-model:activeKey="activeKey">
+<#list subTables as sub><#rt/>
+      <a-tab-pane tab="${sub.ftlDescription}" key="${sub.entityName?uncap_first}" :forceRender="true">
+			  <#if sub.foreignRelationType =='1'>
+        <${Format.humpToShortbar(sub.entityName)}-form ref="${sub.entityName?uncap_first}FormRef" :disabled="formDisabled"></${Format.humpToShortbar(sub.entityName)}-form>
+			  <#else>
+        <j-vxe-table
+          :keep-source="true"
+          ref="${sub.entityName?uncap_first}TableRef"
+          :loading="${sub.entityName?uncap_first}Table.loading"
+          :columns="${sub.entityName?uncap_first}Table.columns"
+          :dataSource="${sub.entityName?uncap_first}Table.dataSource"
+          :maxHeight="300"
+          :disabled="formDisabled"
+          :rowNumber="true"
+          :rowSelection="true"
+          :toolbar="true"/>
+			  </#if>
+      </a-tab-pane>
+</#list>
+    </a-tabs>
+  </a-spin>
+</template>
+
+<script lang="ts">
+  import { defineComponent, ref, reactive, computed, toRaw } from 'vue';
+  import { useValidateAntFormAndTable } from '/@/hooks/system/useJvxeMethods';
+  import { <#list subTables as sub><#if sub.foreignRelationType =='0'>query${sub.entityName}ListByMainId, </#if></#list>queryDataById, saveOrUpdate } from '../${entityName}.api';
+  <#list subTables as sub>
+  <#if sub.foreignRelationType =='1'>
+  import ${sub.entityName}Form from './${sub.entityName}Form.vue'
+	<#else>
+  <#assign hasOne2manyTable = true>
+  <#assign subTableColumnsKey += ['${sub.entityName?uncap_first}Columns']>
+  </#if>
+	<#if sub?? && (sub.foreignMainKeys)??>
+    <#list sub.foreignMainKeys as key>
+      <#assign subMainFieldMap += {"${sub.entityName}": "${dashedToCamel(key)}"}>
+    </#list>
+  </#if>
+  </#list>
+  <#if hasOne2manyTable == true>
+  import { JVxeTable } from '/@/components/jeecg/JVxeTable';
+  import {<#list subTableColumnsKey as columnsKey><#if columnsKey_index gt 0>, </#if>${columnsKey}</#list>} from '../${entityName}.data';
+  </#if>
+  <#include "/common/form/native/vue3NativeImport.ftl">
+  <#if hasOnlyValidate == true>
+  import { duplicateValidate } from '/@/utils/helper/validator'
+  </#if>
+  import { Form } from 'ant-design-vue';
+  const useForm = Form.useForm;
+
+  export default defineComponent({
+    name: "${entityName}Form",
+    components:{
+			<#include "/common/form/native/vue3NativeComponents.ftl">
+			<#if hasOne2manyTable == true>
+      JVxeTable,
+			</#if>
+<#list subTables as sub>
+	<#if sub.foreignRelationType =='1'>
+      ${sub.entityName}Form,
+	</#if>
+</#list>
+    },
+    props:{
+      disabled:{
+        type: Boolean,
+        default: false
+      }
+    },
+    emits:['success'],
+    setup(props, {emit}) {
+      const loading = ref(false);
+      <#list subTables as sub>
+      <#if sub_index == 0>
+      <#assign subTabActiveKey = '${sub.entityName?uncap_first}'>
+      </#if>
+      <#if sub.foreignRelationType =='1'>
+      const ${sub.entityName?uncap_first}FormRef = ref();
+      <#else>
+      const ${sub.entityName?uncap_first}TableRef = ref();
+      const ${sub.entityName?uncap_first}Table = reactive<Record<string, any>>({
+        loading: false,
+        columns: ${sub.entityName?uncap_first}Columns,
+        dataSource: []
+      });
+      </#if>
+      </#list>
+      const activeKey = ref('${subTabActiveKey}');
+      const formData = reactive<Record<string, any>>({
+      <#list columns as po>
+      <#if po.isShow == 'Y'>
+        ${po.fieldName}: '',
+      </#if>
+      </#list>
+      });
+
+      //表单验证
+      const validatorRules = reactive({
+      <#list columns as po>
+      <#if po.isShow == 'Y' && poHasCheck(po)>
+        ${po.fieldName}: [<#include "/common/validatorRulesTemplate/native/vue3CoreNative.ftl">],
+      </#if>
+      </#list>
+      });
+      const {resetFields, validate, validateInfos} = useForm(formData, validatorRules, {immediate: true});
+      const dbData = {};
+      const formItemLayout = {
+        labelCol: {xs: {span: 24}, sm: {span: 5}},
+        wrapperCol: {xs: {span: 24}, sm: {span: 16}},
+      };
+
+      const formDisabled = computed(() => {
+        return props.disabled;
+      });
+
+      function add() {
+        resetFields();
+        <#list subTables as sub>
+        <#if sub.foreignRelationType =='1'>
+        ${sub.entityName?uncap_first}FormRef.value.initFormData();
+        <#else>
+        ${sub.entityName?uncap_first}Table.dataSource = [];
+        </#if>
+        </#list>
+      }
+
+      async function edit(row) {
+        //主表数据
+        await queryMainData(row.id);
+        //子表数据
+        <#list subTables as sub>
+        <#if sub.foreignRelationType =='1'>
+        await ${sub.entityName?uncap_first}FormRef.value.initFormData(row['${subMainFieldMap[sub.entityName]}']);
+        <#else>
+        const ${sub.entityName?uncap_first}DataList = await query${sub.entityName}ListByMainId(row['${subMainFieldMap[sub.entityName]}']);
+        ${sub.entityName?uncap_first}Table.dataSource = [...${sub.entityName?uncap_first}DataList];
+        </#if>
+        </#list>
+      }
+
+      async function queryMainData(id) {
+        const row = await queryDataById(id);
+        Object.keys(row).map(k => {
+          formData[k] = row[k];
+        });
+      }
+
+      const {getSubFormAndTableData, transformData} = useValidateAntFormAndTable(activeKey, {
+        <#list subTables as sub>
+        <#if sub.foreignRelationType =='1'>
+        '${sub.entityName?uncap_first}': ${sub.entityName?uncap_first}FormRef,
+        <#else>
+        '${sub.entityName?uncap_first}': ${sub.entityName?uncap_first}TableRef,
+        </#if>
+        </#list>
+      });
+
+      async function getFormData() {
+        await validate();
+        return transformData(toRaw(formData))
+      }
+
+      async function submitForm() {
+        const mainData = await getFormData();
+        const subData = await getSubFormAndTableData();
+        const values = Object.assign({}, dbData, mainData, subData);
+        console.log('表单提交数据', values)
+        const isUpdate = values.id ? true : false
+        await saveOrUpdate(values, isUpdate);
+        //关闭弹窗
+        emit('success');
+      }
+      
+      function setFieldsValue(values) {
+        if(values){
+          Object.keys(values).map(k=>{
+            formData[k] = values[k];
+          });
+        }
+      }
+
+      <#list columns as po>
+      <#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'>
+      async function ${po.fieldName}Duplicatevalidate(_r, value) {
+        return duplicateValidate('${tableName}', '${po.fieldDbName}', value, formData.id || '')
+      }
+      </#if>
+      </#list>
+
+      return {
+        <#list subTables as sub>
+        <#if sub.foreignRelationType =='1'>
+        ${sub.entityName?uncap_first}FormRef,
+        <#else>
+        ${sub.entityName?uncap_first}TableRef,
+        ${sub.entityName?uncap_first}Table,
+        </#if>
+        </#list>
+        validatorRules,
+        validateInfos,
+        activeKey,
+        loading,
+        formData,
+        setFieldsValue,
+        formItemLayout,
+        formDisabled,
+        getFormData,
+        submitForm,
+        add,
+        edit
+      }
+    }
+  });
+</script>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei
new file mode 100644
index 0000000..24366e8
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei
@@ -0,0 +1,69 @@
+<#include "/common/utils.ftl">
+<template>
+  <BasicModal v-bind="$attrs" @register="registerModal" :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
+    <${Format.humpToShortbar(entityName)}-form ref="formComponent" :disabled="formDisabled" @success="submitSuccess"></${Format.humpToShortbar(entityName)}-form>
+  </BasicModal>
+</template>
+
+<script lang="ts">
+  import { ref, unref } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import ${entityName}Form from './${entityName}Form.vue';
+
+  export default {
+    name: "TestCgMainVxeModal",
+    components:{
+      BasicModal,
+      ${entityName}Form
+    },
+    emits:['register','success'],
+    setup(_p, {emit}){
+      const formComponent = ref()
+      const isUpdate = ref(true);
+      const formDisabled = ref(false);
+      const title = ref('')
+
+      //表单赋值
+      const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
+        setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter});
+        isUpdate.value = !!data?.isUpdate;
+        title.value = data?.isUpdate?'编辑':'新增'
+        formDisabled.value = !data?.showFooter;
+        if (unref(isUpdate)) {
+          console.log('data', data)
+          formComponent.value.edit(data.record)
+        }else{
+          formComponent.value.add()
+        }
+      });
+
+      function handleSubmit() {
+        formComponent.value.submitForm();
+      }
+
+      function submitSuccess(){
+        emit('success');
+        closeModal();
+      }
+
+      return {
+        registerModal,
+        title,
+        formComponent,
+        formDisabled,
+        handleSubmit,
+        submitSuccess
+      }
+    }
+  }
+</script>
+<style lang="less" scoped>
+	/** 时间和数字输入框样式 */
+    :deep(.ant-input-number){
+		width: 100%
+	}
+
+	:deep(.ant-calendar-picker){
+		width: 100%
+	}
+</style>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Form.vuei
new file mode 100644
index 0000000..303fdbe
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Form.vuei
@@ -0,0 +1,149 @@
+<#include "/common/utils.ftl">
+<#list subTables as sub>
+<#if sub.foreignRelationType=='1'>
+#segment#${sub.entityName}Form.vue
+<#include "/common/utils.ftl">
+<#assign need_category = false>
+<#assign bpm_flag=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_select_tag = false>
+<#assign need_select_tree = false>
+<#assign need_time = false>
+<#assign need_markdown = false>
+<#assign need_upload = false>
+<#assign need_image_upload = false>
+<#assign need_editor = false>
+<#assign need_checkbox = 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>
+  <#assign hasOnlyValidate = false>
+<template>
+  <a-spin :spinning="loading">
+    <a-form v-bind="formItemLayout">
+      <a-row>
+        <#list sub.colums as po>
+          <#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'>
+            <#assign hasOnlyValidate = true>
+          </#if>
+          <#if po.fieldDbName=='bpm_status'>
+            <#assign bpm_flag=true>
+          </#if>
+          <#include "/common/form/native/vue3NativeForm.ftl">
+        </#list>
+      </a-row>
+    </a-form>
+  </a-spin>
+</template>
+
+<script lang="ts">
+  import { defineComponent, ref, reactive, toRaw } from 'vue';
+  import { query${sub.entityName}ListByMainId } from '../${entityName}.api';
+<#include "/common/form/native/vue3NativeImport.ftl">
+<#if hasOnlyValidate == true>
+  import { duplicateValidate } from '/@/utils/helper/validator'
+</#if>
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { Form } from 'ant-design-vue';
+  const useForm = Form.useForm;
+
+  export default defineComponent({
+    name: '${sub.entityName}Form',
+    components:{
+    <#include "/common/form/native/vue3NativeComponents.ftl">
+    },
+    props:{
+      disabled:{
+        type: Boolean,
+        default: false
+      }
+    },
+    setup(){
+      const { createMessage } = useMessage();
+      const isForm = true;
+      const loading = ref(false);
+      const formData = reactive<Record<string, any>>({
+    <#list sub.colums as po>
+    <#if po.isShow == 'Y'>
+        ${po.fieldName}: '',
+    </#if>
+    </#list>
+      });
+      //表单验证
+      const validatorRules = reactive({
+    <#list sub.colums as po>
+    <#if po.isShow == 'Y' && poHasCheck(po)>
+        ${po.fieldName}: [<#include "/common/validatorRulesTemplate/native/vue3CoreNative.ftl">],
+    </#if>
+    </#list>
+      })
+      const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, {immediate: true});
+      const formItemLayout = {
+        labelCol: { xs: { span: 24 }, sm: { span: 5 } },
+        wrapperCol: { xs: { span: 24 }, sm: { span: 16 } },
+      };
+
+      async function initFormData(mainId) {
+        resetFields();
+        if(mainId){
+          let list = await query${sub.entityName}ListByMainId(mainId);
+          if(list && list.length>0){
+            let temp = list[0];
+            Object.keys(temp).map(k=>{
+              formData[k] = temp[k];
+            })
+          }
+        }
+      }
+
+      async function getFormData() {
+        await validate();
+        let subFormData = toRaw(formData);
+        if(Object.keys(subFormData).length>0){
+          return subFormData
+        }
+        return false;
+      }
+
+      function setFieldsValue(values) {
+        if(values){
+          Object.keys(values).map(k=>{
+            formData[k] = values[k];
+          });
+        }
+      }
+
+    <#list sub.colums as po>
+    <#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'>
+      async function ${po.fieldName}Duplicatevalidate(_r, value) {
+        return duplicateValidate('${sub.tableName}', '${po.fieldDbName}', value, formData.id || '')
+      }
+    </#if>
+    </#list>
+
+      return {
+        loading,
+        formData,
+        formItemLayout,
+        initFormData,
+        getFormData,
+        setFieldsValue,
+        isForm,
+        validateInfos
+      }
+    }
+  });
+</script>
+</#if>
+</#list>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
index 4877656..b2581f9 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
@@ -196,17 +196,14 @@ public class ${entityName}Controller {
       QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap());
       LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
 
-      //Step.2 获取导出数据
-      List<${entityName}> queryList = ${entityName?uncap_first}Service.list(queryWrapper);
-      // 过滤选中数据
-      String selections = request.getParameter("selections");
-      List<${entityName}> ${entityName?uncap_first}List = new ArrayList<${entityName}>();
-      if(oConvertUtils.isEmpty(selections)) {
-          ${entityName?uncap_first}List = queryList;
-      }else {
-          List<String> selectionList = Arrays.asList(selections.split(","));
-          ${entityName?uncap_first}List = queryList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
-      }
+      //配置选中数据查询条件
+       String selections = request.getParameter("selections");
+       if(oConvertUtils.isNotEmpty(selections)) {
+            List<String> selectionList = Arrays.asList(selections.split(","));
+            queryWrapper.in("id",selectionList);
+       }
+       //Step.2 获取导出数据
+       List<${entityName}> ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper);
 
       // Step.3 组装pageList
       List<${entityName}Page> pageList = new ArrayList<${entityName}Page>();
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
index c861c4a..4d1b425 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 package ${bussiPackage}.${entityPackage}.entity;
 
 import java.io.Serializable;
@@ -31,9 +32,9 @@ public class ${entityName} implements Serializable {
     <#-- 生成字典Code -->
     <#assign list_field_dictCode="">
     <#if po.classType='sel_user'>
-      <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'>
+      <#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 = "depart_name", dicCode = "id"'>
+      <#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}"'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
index b6aabe8..93ddf95 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 <#list subTables as subTab>
 #segment#${subTab.entityName}.java
 package ${bussiPackage}.${entityPackage}.entity;
@@ -32,9 +33,9 @@ public class ${subTab.entityName} implements Serializable {
 	<#-- 生成字典Code -->
 	<#assign list_field_dictCode="">
 	<#if po.classType='sel_user'>
-		<#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'>
+		<#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 = "depart_name", dicCode = "id"'>
+		<#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}"'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
index c503847..5e82b9e 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
@@ -39,7 +39,7 @@
                         @input="popupCallback"
                         <#if po.readonly=='Y'>disabled</#if>/>
             <#elseif po.classType =='sel_depart'>
-                      <j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/>
+                      <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'>
@@ -49,7 +49,7 @@
             <#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}" <#if po.readonly=='Y'>disabled</#if>/>
+                      <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'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
index ca111ff..ff5e255 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
@@ -44,7 +44,7 @@
                 :multi="${po.extendParams.popupMulti?c}"
                 @input="popupCallback"/>
     <#elseif po.classType =='sel_depart'>
-              <j-select-depart v-model="model.${po.fieldName}" multi/>
+              <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>></j-switch>
 	<#elseif po.classType =='pca'>
@@ -54,7 +54,7 @@
     <#elseif po.classType =='password'>
 	          <a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"/>
 	<#elseif po.classType =='sel_user'>
-              <j-select-user-by-dep v-model="model.${po.fieldName}"/>
+              <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}"/>
 	<#elseif po.classType=='list' || po.classType=='radio'>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
index fd577a1..6ba0f5b 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
@@ -46,6 +46,10 @@
       <template #htmlSlot="{text}">
          <div v-html="text"></div>
       </template>
+      <!--省市区字段回显插槽-->
+      <template #pcaSlot="{text}">
+         {{ getAreaTextByCode(text) }}
+      </template>
       <template #fileSlot="{text}">
          <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>
@@ -64,6 +68,10 @@
   import ${entityName}Modal from './components/${entityName}Modal.vue'
   import {columns, searchFormSchema} from './${entityName}.data';
   import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api';
+  import {downloadFile} from '/@/utils/common/renderUtils';
+<#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';
@@ -84,6 +92,17 @@
                 schemas: searchFormSchema,
                 autoSubmitOnEnter:true,
                 showAdvancedButton:true,
+                fieldMapToNumber: [
+                   <#list columns as po>
+                   <#if po.isQuery=='Y'>
+                   <#if po.queryMode!='single'>
+                   <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+                   ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end']],
+                   </#if>
+                   </#if>
+                   </#if>
+                   </#list>
+                ],
                 fieldMapToTime: [
                 <#list columns as po>
                 <#if po.isQuery=='Y'>
@@ -98,9 +117,10 @@
                 </#list>
                 ],
             },
-            actionColumn: {
+           actionColumn: {
                width: 120,
-            },
+               fixed:'right'
+           },
         },
         exportConfig: {
             name:"${tableVo.ftlDescription}",
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
index 6d77bc2..09e94e9 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 import {BasicColumn} from '/@/components/Table';
 import {FormSchema} from '/@/components/Table';
 import { rules} from '/@/utils/helper/validator';
@@ -25,7 +26,7 @@ export const columns: BasicColumn[] = [
     slots: { customRender: 'htmlSlot' },
     <#elseif po.classType=='pca'>
     dataIndex: '${po.fieldName}',
-    slots: { customRender: 'pcaSlot' },//TODO 未翻译
+    slots: { customRender: 'pcaSlot' },
    <#elseif po.classType=='file'>
     dataIndex: '${po.fieldName}',
     slots: { customRender: 'fileSlot' },
@@ -57,7 +58,7 @@ export const columns: BasicColumn[] = [
        return  render.renderCategoryTree(text,'${po.dictField?default("")}')
    },
    <#else>
-    customRender: (text, record) => (text ? record['${po.dictText}'] : '')
+    customRender: ({text, record}) => (text ? record['${po.dictText}'] : '')
    </#if>
    <#else>
     dataIndex: '${po.fieldName}'
@@ -95,16 +96,22 @@ export const searchFormSchema: FormSchema[] = [
 <#elseif po.classType=='switch'>
       component: 'JSwitch',
       componentProps:{
+           query:true,
            <#if po.dictField != 'is_open'>
-           options:"${po.dictField}"
+           options:${po.dictField}
            </#if>
        },
  <#elseif po.classType=='sel_depart'>
       component: 'JSelectDept',
  <#elseif po.classType=='list_multi'>
-      component: 'JMultiSelectTag',//暂无该组件
+      component: 'JSelectMultiple',
       componentProps:{
-          dictCode:"query_field_dictCode?default("")"
+      <#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',
@@ -121,16 +128,7 @@ export const searchFormSchema: FormSchema[] = [
 <#elseif po.classType=='pca'>
       component: 'JAreaLinkage',
 <#elseif po.classType=='popup'>
-      component: 'JPopup',
-      componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:"${po.dictField}",
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
 <#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
 <#--  ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
       component: 'JDictSelectTag',
@@ -157,6 +155,8 @@ export const searchFormSchema: FormSchema[] = [
       componentProps: {
           showTime:true
       },
+<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
+      component: 'JRangeNumber',
 <#else>
       component: 'Input', //TODO 范围查询
 </#if>
@@ -189,27 +189,19 @@ export const formSchema: FormSchema[] = [
 	</#if>
   {
     label: '${po.filedComment}',
-    field: '${po.fieldName}',
+    field: ${autoStringSuffix(po)},
     <#if po.classType =='date'>
     component: 'DatePicker',
-     <#elseif po.fieldType =='datetime'>
+     <#elseif po.classType =='datetime'>
     component: 'DatePicker',
     componentProps: {
-       showTime:true
+       showTime:true,
+       valueFormat: 'YYYY-MM-DD HH:mm:ss'
      },
-     <#elseif po.fieldType =='time'>
+     <#elseif po.classType =='time'>
     component: 'TimePicker',
     <#elseif po.classType =='popup'>
-    component: 'JPopup',
-    componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:${po.dictField},
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
      <#elseif po.classType =='sel_depart'>
      component: 'JSelectDept',
      <#elseif po.classType =='switch'>
@@ -231,14 +223,14 @@ export const formSchema: FormSchema[] = [
         labelKey:'realname',
      },
     <#elseif po.classType =='textarea'>
-    component: 'InputTextArea',//TODO 注意string转换问题
+    component: 'InputTextArea',
     <#elseif po.classType=='list' || po.classType=='radio'>
     component: 'JDictSelectTag',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
     <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
-    component: 'JMultiSelectTag',//TODO  暂无该组件
+    component: 'JSelectMultiple',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
@@ -273,7 +265,7 @@ export const formSchema: FormSchema[] = [
     </#if>
       },
   <#elseif po.classType=='umeditor'>
-    component: 'JCodeEditor', //TODO String后缀暂未添加
+    component: 'JEditor',
   <#elseif po.classType == 'sel_tree'>
     component: 'JTreeSelect',
     componentProps:{
@@ -305,16 +297,16 @@ export const formSchema: FormSchema[] = [
            </#if>
        <#-- 唯一校验 -->
            <#if fieldValidType == 'only'>
-                 {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
+                 {...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}$/, message: '请输入6到16位数字!'},
            <#-- 6到16位任意字符 -->
            <#elseif fieldValidType == '*6-16'>
                  { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
-           <#-- 6到18位字符串 -->
+           <#-- 6到18位字母 -->
            <#elseif fieldValidType == 's6-18'>
-                 { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
+                 { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
            <#-- 网址 -->
            <#elseif fieldValidType == 'url'>
                  { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
@@ -373,10 +365,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
 <#assign form_cat_tree = false>
 <#assign form_cat_back = "">
 <#assign bpm_flag=false>
+<#assign sub_id_exists = false>
 <#list sub.colums as po><#rt/>
 <#if po.fieldDbName=='bpm_status'>
   <#assign bpm_flag=true>
 </#if>
+<#if po.fieldDbName == 'id'>
+	<#assign sub_id_exists = true>
+</#if>
 <#if po.isShow =='Y'>
 <#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>
@@ -386,27 +382,19 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
 	</#if>
   {
     label: '${po.filedComment}',
-    field: '${po.fieldName}',
+    field: ${autoStringSuffix(po)},
     <#if po.classType =='date'>
     component: 'DatePicker',
-     <#elseif po.fieldType =='datetime'>
+     <#elseif po.classType =='datetime'>
     component: 'DatePicker',
     componentProps: {
-       showTime:true
+       showTime:true,
+       valueFormat: 'YYYY-MM-DD HH:mm:ss'
      },
-     <#elseif po.fieldType =='time'>
+     <#elseif po.classType =='time'>
     component: 'TimePicker',
     <#elseif po.classType =='popup'>
-    component: 'JPopup',
-    componentProps: ({ formActionType }) => {
-         const {setFieldsValue} = formActionType;
-         return{
-             setFieldsValue:setFieldsValue,
-             code:"${po.dictTable}",
-             fieldConfig:${po.dictField},
-             multi:${po.extendParams.popupMulti?c},
-         }
-     },
+    <#include "/common/form/vue3popup.ftl">
      <#elseif po.classType =='sel_depart'>
      component: 'JSelectDept',
      <#elseif po.classType =='switch'>
@@ -428,14 +416,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
         labelKey:'realname',
      },
     <#elseif po.classType =='textarea'>
-    component: 'InputTextArea',//TODO 注意string转换问题
+    component: 'InputTextArea',
     <#elseif po.classType=='list' || po.classType=='radio'>
     component: 'JDictSelectTag',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
     <#elseif po.classType=='list_multi' || po.classType=='checkbox'>
-    component: 'JMultiSelectTag',//TODO  暂无该组件
+    component: 'JSelectMultiple',
     componentProps:{
         dictCode:"${form_field_dictCode}"
      },
@@ -470,7 +458,7 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
     </#if>
       },
   <#elseif po.classType=='umeditor'>
-    component: 'JCodeEditor', //TODO String后缀暂未添加
+    component: 'JEditor',
   <#elseif po.classType == 'sel_tree'>
     component: 'JTreeSelect',
     componentProps:{
@@ -502,16 +490,16 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
            </#if>
        <#-- 唯一校验 -->
            <#if fieldValidType == 'only'>
-                 {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
+                 {...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}$/, message: '请输入6到16位数字!'},
            <#-- 6到16位任意字符 -->
            <#elseif fieldValidType == '*6-16'>
                  { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
-           <#-- 6到18位字符串 -->
+           <#-- 6到18位字母 -->
            <#elseif fieldValidType == 's6-18'>
-                 { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
+                 { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'},
            <#-- 网址 -->
            <#elseif fieldValidType == 'url'>
                  { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
@@ -553,6 +541,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
   },
 </#if>
 </#list>
+<#if sub_id_exists == false>
+	{
+	  label: '',
+	  field: 'id',
+	  component: 'Input',
+	  show: false
+	},
+</#if>
 ];
 </#if>
 </#list>
@@ -579,12 +575,20 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
       <#if col.readonly=='Y'>
       disabled:true,
       </#if>
+<#elseif col.classType =='time'>
+      type: JVxeTypes.time,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
 <#elseif col.classType =='textarea'>
       type: JVxeTypes.textarea,
        <#if col.readonly=='Y'>
       disabled:true,
        </#if>
-<#elseif "int,decimal,double,"?contains(col.classType)>
+<#-- update-begin-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 -->
+<#-- elseif "int,decimal,double,"?contains(col.classType) -->
+<#elseif col.fieldDbType=='int' || col.fieldDbType=='double' || col.fieldDbType=='BigDecimal'>
+<#-- update-end-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 -->
       type: JVxeTypes.inputNumber,
       <#if col.readonly=='Y'>
       disabled:true,
@@ -621,6 +625,16 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
       <#if col.readonly=='Y'>
       disabled:true,
       </#if>
+<#elseif col.classType =='sel_depart'>
+      type: JVxeTypes.departSelect,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
+<#elseif col.classType =='sel_user'>
+      type: JVxeTypes.userSelect,
+      <#if col.readonly=='Y'>
+      disabled:true,
+      </#if>
 <#elseif col.classType =='image'>
       type: JVxeTypes.image,
       token:true,
@@ -644,9 +658,9 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
 <#elseif col.classType =='switch'>
       type: JVxeTypes.checkbox,
        <#if col.dictField == 'is_open'>
-        customValue: ['Y', 'N'],
+      customValue: ['Y', 'N'],
         <#else>
-        customValue: ${col.dictField},
+      customValue: ${col.dictField},
         </#if>
       <#if col.readonly=='Y'>
       disabled:true,
@@ -657,14 +671,7 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
 <#else>
     <#assign popupBackFields = "${col.dictText}">
 </#if>
-      type: JVxeTypes.popup,
-      popupCode:"${col.dictTable}",
-      field:"${col.dictField}",
-      orgFields:"${col.dictField}",
-      destFields:"${Format.underlineToHump(col.dictText)}",
-      <#if col.readonly=='Y'>
-      disabled:true,
-      </#if>
+    <#include "/common/form/vue3Jvxepopup.ftl">
 <#else>
       type: JVxeTypes.input,
       <#if col.readonly=='Y'>
@@ -691,18 +698,7 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
       defaultValue:'',
 </#if>
 <#-- 子表的校验 -->
-<#assign subFieldValidType = col.fieldValidType!''>
-<#-- 非空校验 -->
-<#if col.nullable == 'N' || subFieldValidType == '*'>
-      validateRules: [{ required: true, message: '${'$'}{title}不能为空' }],
-<#-- 其他情况下,只要有值就被认为是正则校验 -->
-<#elseif subFieldValidType?length gt 0>
-<#assign subMessage = '格式不正确'>
-<#if subFieldValidType == 'only' >
-  <#assign subMessage = '不能重复'>
-</#if>
-      validateRules: [{ pattern: "${subFieldValidType}", message: "${'$'}{title}${subMessage}" }],
-</#if>
+ <#include "/common/validatorRulesTemplate/sub-vue3.ftl">
     },
 </#if>
 </#if>
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
new file mode 100644
index 0000000..5396d5d
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
@@ -0,0 +1 @@
+<#include "/common/sql/menu_insert.ftl">
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
index aa5fe59..eade8bb 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
@@ -1,21 +1,22 @@
+<#include "/common/utils.ftl">
 <template>
-  <BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
+  <BasicModal ref="modalRef" destroyOnClose wrapClassName="j-cgform-tab-modal" v-bind="$attrs" @register="registerModal" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
   <!-- 子表单区域 -->
     <a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs">
      <!--主表区域 -->
-     <a-tab-pane tab="${tableVo.ftlDescription}" :key="refKeys[0]" :forceRender="true">
+     <a-tab-pane tab="${tableVo.ftlDescription}" :key="refKeys[0]" :forceRender="true" :style="tabsStyle">
        <BasicForm @register="registerForm" ref="formRef"/>
      </a-tab-pane>
   <!--子表单区域 -->
 <#list subTables as sub><#rt/>
   <#assign refKey = sub.entityName?uncap_first/>
   <#if sub.foreignRelationType =='1'>
-      <a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true">
-        <${sub.entityName}Form ref="${sub.entityName?uncap_first}Form"></${sub.entityName}Form>
+      <a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true" :style="tabsStyle">
+        <${sub.entityName}Form ref="${sub.entityName?uncap_first}Form" :disabled="formDisabled"></${sub.entityName}Form>
       </a-tab-pane>
 
   <#else>
-      <a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true">
+      <a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true" :style="tabsStyle">
         <JVxeTable
           keep-source
           resizable
@@ -23,7 +24,8 @@
           :loading="${sub.entityName?uncap_first}Table.loading"
           :columns="${sub.entityName?uncap_first}Table.columns"
           :dataSource="${sub.entityName?uncap_first}Table.dataSource"
-          :maxHeight="300"
+          :height="340"
+          :disabled="formDisabled"
           :rowNumber="true"
           :rowSelection="true"
           :toolbar="true"
@@ -52,6 +54,8 @@
     // Emits声明
     const emit = defineEmits(['register','success']);
     const isUpdate = ref(true);
+    const formDisabled = ref(false);
+    const modalRef = ref();
     const refKeys = ref(['${tableVo.entityName?uncap_first}',<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]);
     <#assign hasOne2Many = false>
     <#assign hasOne2One = false>
@@ -81,6 +85,7 @@
         labelWidth: 150,
         schemas: formSchema,
         showActionButtonGroup: false,
+        baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}
     });
      //表单赋值
     const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
@@ -88,6 +93,7 @@
         await reset();
         setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter});
         isUpdate.value = !!data?.isUpdate;
+        formDisabled.value = !data?.showFooter;
         if (unref(isUpdate)) {
             //表单赋值
             await setFieldsValue({
@@ -109,9 +115,21 @@
     });
     //方法配置
     const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys<#if hasOne2One==true>,validateSubForm</#if>);
-
-    //设置标题
-    const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
+    // 弹窗tabs滚动区域的高度
+    const tabsStyle = computed(() => {
+      let height: Nullable<string> = null
+      let minHeight = '100px'
+      let maxHeight: Nullable<string> = '500px'
+      // 弹窗wrapper
+      let modalWrapperRef = modalRef.value?.modalWrapperRef
+      if (modalWrapperRef) {
+        if (modalWrapperRef.fullScreen) {
+          height = 'calc(' + modalWrapperRef.spinStyle.height + ' - 50px)';
+          maxHeight = null
+        }
+      }
+      return {height, minHeight, maxHeight}
+    })
 
     async function reset(){
       await resetFields();
@@ -180,5 +198,38 @@
 </script>
 
 <style lang="less" scoped>
+/** 时间和数字输入框样式 */
+    :deep(.ant-input-number){
+        width: 100%
+    }
+
+    :deep(.ant-calendar-picker){
+        width: 100%
+    }
+</style>
+
+<style lang="less">
+// Online表单Tab风格专属样式
+.j-cgform-tab-modal {
+  .ant-modal-header {
+    padding-top: 8px;
+    padding-bottom: 8px;
+    border-bottom: none !important;
+  }
+
+  .ant-modal .ant-modal-body > .scrollbar,
+  .ant-tabs-nav .ant-tabs-tab {
+    padding-top: 0;
+  }
+
+  .ant-tabs-top-bar {
+    width: calc(100% - 55px);
+    position: relative;
+    left: -14px;
+  }
 
+  .ant-tabs .ant-tabs-top-content > .ant-tabs-tabpane {
+    overflow: hidden auto;
+  }
+}
 </style>
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei
index 6af0c52..9969aaf 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei
@@ -1,3 +1,4 @@
+<#include "/common/utils.ftl">
 <#list subTables as sub>
 <#if sub.foreignRelationType=='1'>
 #segment#${sub.entityName}Form.vue
@@ -15,11 +16,18 @@
         name:"${sub.entityName}Form",
         components: {BasicForm},
         emits:['register'],
-        setup(_,{emit}) {
-            const [registerForm, {resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
+        props:{
+            disabled: {
+                type: Boolean,
+                default: false
+            }
+        },
+        setup(props,{emit}) {
+            const [registerForm, {setProps, resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
                 labelWidth: 150,
                 schemas: ${sub.entityName?uncap_first}FormSchema,
                 showActionButtonGroup: false,
+                baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}
             });
             /**
             *初始化加载数据
@@ -30,12 +38,19 @@
                        res.success && setFieldsValue({...res.result[0]});
                     })
                 }
+                setProps({disabled: props.disabled})
             }
            /**
             *获取表单数据
             */
             function getFormData(){
-               return [getFieldsValue()];
+               let formData = getFieldsValue();
+               Object.keys(formData).map(k=>{
+                   if(formData[k] instanceof Array){
+                       formData[k] = formData[k].join(',')
+                   }
+               });
+               return [formData];
             }
             /**
             *表单校验
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
index 98092f3..79b8d13 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
@@ -78,11 +78,11 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
     {
       title: '${col.filedComment}',
        key: '${col.fieldName}',
-<#if col.classType =='date'>
+<#if col.fieldType =='date'>
       type: JVxeTypes.date,
-<#elseif col.classType =='datetime'>
+<#elseif col.fieldType =='datetime'>
       type: JVxeTypes.datetime,
-<#elseif "int,decimal,double,"?contains(col.classType)>
+<#elseif "int,decimal,double,"?contains(col.fieldType)>
       type: JVxeTypes.inputNumber,
 <#else>
       type: JVxeTypes.input,
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template/onetomany2/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template/onetomany2/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
index 8b14748..8d8ac1c 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template/onetomany2/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template/onetomany2/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
@@ -103,7 +103,11 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
         <#if po.fieldType =='date'>
        component: 'DatePicker',
         <#elseif po.fieldType =='datetime'>
-       component: 'TimePicker',
+       component: 'DatePicker',
+       componentProps: {
+         showTime: true,
+         valueFormat: 'YYYY-MM-DD hh:mm:ss',
+       },
         <#elseif "int,decimal,double,"?contains(po.fieldType)>
        component: 'InputNumber',
         <#else>
--
libgit2 0.22.2