mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-15 06:29:01 +08:00
Compare commits
89
Commits
60a0ccfcd3
...
a6d0705e40
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6d0705e40 | ||
|
|
c0034f3799 | ||
|
|
db23fd2d0c | ||
|
|
fd5cd572a4 | ||
|
|
ab91447941 | ||
|
|
e3440353ae | ||
|
|
ff98dcc3fb | ||
|
|
467a1fea1b | ||
|
|
8d37e48d1f | ||
|
|
589d17f0d3 | ||
|
|
5f4d9d6621 | ||
|
|
d6adbfa36e | ||
|
|
b003a1b444 | ||
|
|
0974a56294 | ||
|
|
2f089f029f | ||
|
|
93c52e41dc | ||
|
|
2053cc5766 | ||
|
|
ddfc2b41d9 | ||
|
|
14cb5dfe0a | ||
|
|
f8742f5e69 | ||
|
|
e0d43f41a1 | ||
|
|
b04588ffae | ||
|
|
fbb5bd121c | ||
|
|
72ac720fb6 | ||
|
|
cf917b5988 | ||
|
|
d0aa3a7284 | ||
|
|
4f6e796c55 | ||
|
|
085235710b | ||
|
|
749931b53e | ||
|
|
a177f3073a | ||
|
|
d927a5b984 | ||
|
|
daad35902e | ||
|
|
e4bda833bc | ||
|
|
cbdd0e202c | ||
|
|
ccdbde5229 | ||
|
|
3b15ea4235 | ||
|
|
3fd14644cd | ||
|
|
4471c363cb | ||
|
|
c0a2b97679 | ||
|
|
45250841a5 | ||
|
|
57877b951f | ||
|
|
618a29be52 | ||
|
|
67608f76ba | ||
|
|
22f55b8ba3 | ||
|
|
9d5ff9c022 | ||
|
|
ec93f78417 | ||
|
|
65f184ace6 | ||
|
|
ca84985d63 | ||
|
|
b8fda524f8 | ||
|
|
dc663491b6 | ||
|
|
cca41756c8 | ||
|
|
cb08f11a5d | ||
|
|
e63dc8678e | ||
|
|
abf10a2a19 | ||
|
|
1db9bdc636 | ||
|
|
60babcbc3d | ||
|
|
2bc231f1bf | ||
|
|
464c6df5b8 | ||
|
|
7720ea8547 | ||
|
|
ee27036339 | ||
|
|
db60b48f6c | ||
|
|
7712a1bb3c | ||
|
|
816a63f0c2 | ||
|
|
545b0a4642 | ||
|
|
1dc58c60cf | ||
|
|
75ec99389c | ||
|
|
b6681ed578 | ||
|
|
53e7a6c2eb | ||
|
|
a810bf8f0b | ||
|
|
840732c52d | ||
|
|
6a4b8b1f1d | ||
|
|
3f4d1dbf6e | ||
|
|
39ea9a6eae | ||
|
|
c80d5bc44a | ||
|
|
50b68563a6 | ||
|
|
2a6ce673f5 | ||
|
|
08c081304a | ||
|
|
bca999535c | ||
|
|
d46af13a2e | ||
|
|
4023b142d1 | ||
|
|
269d7fe5e4 | ||
|
|
2edc478f73 | ||
|
|
cbb68a0e5b | ||
|
|
66e55f3258 | ||
|
|
9d198266d7 | ||
|
|
fe64bf38c2 | ||
|
|
f759865202 | ||
|
|
b553787cfd | ||
|
|
2c70387ace |
No files matched your search
@@ -17,6 +17,8 @@ updates:
|
||||
update-types:
|
||||
- version-update:semver-minor
|
||||
ignore:
|
||||
# 完全忽略 IJPay 的所有升级。
|
||||
- dependency-name: "com.github.javen205:IJPay-*"
|
||||
# 完全忽略 MyBatis-Plus BOM 的所有升级。
|
||||
- dependency-name: "com.baomidou:mybatis-plus-bom"
|
||||
# 完全忽略 MyBatis-Plus-Join 的所有升级。
|
||||
|
||||
@@ -11,19 +11,15 @@ layout.
|
||||
|
||||
## Build, Test, and Development Commands
|
||||
|
||||
- `mvn -T 1C clean install -DskipTests` compiles all modules with the managed BOM; add `-pl pigx-gateway -am` to limit
|
||||
the build to a single service.
|
||||
- `mvn -pl pigx-gateway spring-boot:run` (swap the module name as needed) starts a service with dev profiles for live
|
||||
reloads.
|
||||
- `docker-compose up -d pigx-mysql pigx-redis pigx-register` brings up local infrastructure; run
|
||||
`docker-compose up --build pigx-auth pigx-upms` when you need the auth stack.
|
||||
- `mvn -pl pigx-knowledge test` executes module tests; append `-DskipITs` to bypass integration suites.
|
||||
Focused Maven commands are allowed only for test execution. They must not be used to package, start, or restart
|
||||
services.
|
||||
|
||||
## Testing Guidelines
|
||||
|
||||
Use `spring-boot-starter-test` (JUnit 5, AssertJ, Mockito) for unit and slice tests. Name classes `*Tests.java` and
|
||||
colocate fixtures in `src/test/resources`. Target >70% line coverage on the service layer that guards authentication,
|
||||
gateway filters, and approval flows. Run `mvn verify` before opening a PR to exercise the full plugin stack.
|
||||
gateway filters, and approval flows. Before opening a PR, run the focused tests required by the change, then perform
|
||||
the required runtime validation. Do not use `mvn verify` as a build shortcut unless the user explicitly requests it.
|
||||
|
||||
## Commit & Pull Request Guidelines
|
||||
|
||||
|
||||
+326
-275
@@ -1,3 +1,4 @@
|
||||
-- 本文件仅用于初始化,不用于升级已有数据库。
|
||||
-- pigx 单体模式的数据库【可选】
|
||||
create database `pigxx_boot` default character set utf8mb4 collate utf8mb4_general_ci;
|
||||
|
||||
@@ -94,7 +95,7 @@ CREATE TABLE `sys_api_key` (
|
||||
`update_by` varchar(64) DEFAULT NULL COMMENT '更新者',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`tenant_id` bigint DEFAULT NULL COMMENT '租���ID',
|
||||
`tenant_id` bigint DEFAULT NULL COMMENT '租户ID',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_api_key_hash` (`api_key_hash`),
|
||||
KEY `idx_user_id` (`user_id`)
|
||||
@@ -131,8 +132,8 @@ CREATE TABLE `sys_dept` (
|
||||
`dept_id` bigint(20) NOT NULL COMMENT '部门ID',
|
||||
`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '部门名称',
|
||||
`sort_order` int(11) NOT NULL DEFAULT '0' COMMENT '排序',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标志',
|
||||
@@ -169,8 +170,8 @@ CREATE TABLE `sys_dict` (
|
||||
`id` bigint(20) NOT NULL COMMENT '编号',
|
||||
`dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字典类型',
|
||||
`description` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '描述',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注信息',
|
||||
@@ -228,8 +229,8 @@ CREATE TABLE `sys_dict_item` (
|
||||
`description` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字典项描述',
|
||||
`list_class` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '标签类型',
|
||||
`sort_order` int(11) NOT NULL DEFAULT '0' COMMENT '排序(升序)',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注信息',
|
||||
@@ -281,8 +282,6 @@ INSERT INTO `sys_dict_item` VALUES (33, 11, '0', '正常', 'status_type', '状
|
||||
INSERT INTO `sys_dict_item` VALUES (34, 11, '9', '冻结', 'status_type', '状态冻结', NULL, 1, ' ', ' ', '2019-05-15 16:31:56', '2019-05-16 22:30:50', '状态冻结', '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (35, 12, '1', '系统类', 'dict_type', '系统类字典', NULL, 0, ' ', ' ', '2019-05-16 14:20:40', '2019-05-16 14:20:40', '不能修改删除', '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (36, 12, '0', '业务类', 'dict_type', '业务类字典', NULL, 0, ' ', ' ', '2019-05-16 14:20:59', '2019-05-16 14:20:59', '可以修改', '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (37, 2, 'GITEE', '码云', 'social_type', '码云', NULL, 2, ' ', ' ', '2019-06-28 09:59:12', '2019-06-28 09:59:12', '码云', '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (38, 2, 'OSC', '开源中国', 'social_type', '开源中国登录', NULL, 2, ' ', ' ', '2019-06-28 10:04:32', '2019-06-28 10:04:32', '', '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (39, 14, 'password', '密码模式', 'grant_types', '支持oauth密码模式', NULL, 0, ' ', ' ', '2019-08-13 07:35:28', '2019-08-13 07:35:28', NULL, '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (40, 14, 'authorization_code', '授权码模式', 'grant_types', 'oauth2 授权码模式', NULL, 1, ' ', ' ', '2019-08-13 07:36:07', '2019-08-13 07:36:07', NULL, '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (41, 14, 'client_credentials', '客户端模式', 'grant_types', 'oauth2 客户端模式', NULL, 2, ' ', ' ', '2019-08-13 07:36:30', '2019-08-13 07:36:30', NULL, '0', 1);
|
||||
@@ -341,6 +340,7 @@ INSERT INTO `sys_dict_item` VALUES (95, 29, '0', '黑名单', 'sensitive_type',
|
||||
INSERT INTO `sys_dict_item` VALUES (96, 29, '1', '白名单', 'sensitive_type', '失败', NULL, 3, 'admin', ' ', '2023-10-27 10:30:47', NULL, NULL, '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (97,2,'MINI','小程序登录','social_type','小程序登录',NULL,3,' ',' ','2022-02-18 13:56:25','2022-02-18 13:56:28',NULL,'0',1);
|
||||
INSERT INTO `sys_dict_item` VALUES (98,2,'clarity','clarity','social_type','clarity',NULL,3,' ',' ','2022-02-18 13:56:25','2022-02-18 13:56:28',NULL,'0',1);
|
||||
INSERT INTO `sys_dict_item` VALUES (100,2,'FEISHU','企业飞书','social_type','企业飞书扫码登录',NULL,5,' ',' ','2026-09-18 00:00:00','2026-09-18 00:00:00',NULL,'0',1);
|
||||
INSERT INTO `sys_dict_item` VALUES (99,2,'umami','umami','social_type','umami',NULL,4,' ',' ','2026-06-23 00:00:00','2026-06-23 00:00:00',NULL,'0',1);
|
||||
COMMIT;
|
||||
|
||||
@@ -358,8 +358,8 @@ CREATE TABLE `sys_file` (
|
||||
`type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '文件类型',
|
||||
`hash` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '文件hash',
|
||||
`file_size` bigint(20) DEFAULT NULL COMMENT '文件大小',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '上传时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标志',
|
||||
@@ -391,9 +391,9 @@ CREATE TABLE `sys_i18n` (
|
||||
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'name',
|
||||
`zh_cn` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '中文',
|
||||
`en` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '英文',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
|
||||
PRIMARY KEY (`id`)
|
||||
@@ -403,80 +403,83 @@ CREATE TABLE `sys_i18n` (
|
||||
-- Records of sys_i18n
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_i18n` VALUES (1, 'router.permissionManagement', '权限管理', 'Permission Management', '', '2023-02-14 02:03:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (2, 'router.userManagement', '用户管理', 'User Management', 'admin', '2023-02-14 10:39:08', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (3, 'router.menuManagement', '菜单管理', 'Menu Management', 'admin', '2023-02-15 23:14:39', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (4, 'router.roleManagement', '角色管理', 'Role Management', 'admin', '2023-02-15 23:15:51', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (5, 'router.departmentManagement', '部门管理', 'Department Management', 'admin', '2023-02-15 23:16:52', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (6, 'router.tenantManagement', '租户管理', 'Tenant Management', 'admin', '2023-02-24 10:08:29', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (7, 'router.postManagement', '岗位管理', 'Post Management', 'admin', '2023-02-24 10:12:58', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (8, 'router.systemManagement', '系统管理', 'System Management', 'admin', '2023-02-24 10:13:34', 'admin', '2023-02-24 10:58:30', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (9, 'router.operationLog', '操作日志', 'Operation Log', 'admin', '2023-02-24 10:14:47', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (10, 'router.dictManagement', '字典管理', 'Dictionary Management', 'admin', '2023-02-24 10:16:21', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (11, 'router.parameterManagement', '参数管理', 'Parameter Management', 'admin', '2023-02-24 10:17:04', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (12, 'router.codeGeneration', '代码生成', 'Code Generation', 'admin', '2023-02-24 10:19:16', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (13, 'router.terminalManagement', '终端管理', 'Terminal Management', 'admin', '2023-02-24 10:21:45', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (14, 'router.keyManagement', '密钥管理', 'Key Management', 'admin', '2023-02-24 10:22:52', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (15, 'router.tokenManagement', '令牌管理', 'Token Management', 'admin', '2023-02-24 10:23:22', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (16, 'router.quartzManagement', 'Quartz管理', 'Quartz Management', 'admin', '2023-02-24 10:24:32', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (17, 'router.metadataManagement', '元数据管理', 'Metadata Management', 'admin', '2023-02-24 10:25:11', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (1, 'router.permissionManagement', '权限管理', 'Permissions', '', '2023-02-14 02:03:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (2, 'router.userManagement', '用户管理', 'Users', 'admin', '2023-02-14 10:39:08', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (3, 'router.menuManagement', '菜单管理', 'Menus', 'admin', '2023-02-15 23:14:39', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (4, 'router.roleManagement', '角色管理', 'Roles', 'admin', '2023-02-15 23:15:51', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (5, 'router.departmentManagement', '部门管理', 'Departments', 'admin', '2023-02-15 23:16:52', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (6, 'router.tenantManagement', '租户管理', 'Tenants', 'admin', '2023-02-24 10:08:29', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (7, 'router.postManagement', '岗位管理', 'Positions', 'admin', '2023-02-24 10:12:58', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (8, 'router.systemManagement', '系统管理', 'System', 'admin', '2023-02-24 10:13:34', 'admin', '2023-02-24 10:58:30', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (9, 'router.operationLog', '操作日志', 'Operation Logs', 'admin', '2023-02-24 10:14:47', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (10, 'router.dictManagement', '字典管理', 'Dictionaries', 'admin', '2023-02-24 10:16:21', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (11, 'router.parameterManagement', '参数管理', 'Parameters', 'admin', '2023-02-24 10:17:04', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (12, 'router.codeGeneration', '代码生成', 'Code Generator', 'admin', '2023-02-24 10:19:16', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (13, 'router.terminalManagement', '终端管理', 'OAuth Clients', 'admin', '2023-02-24 10:21:45', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (14, 'router.keyManagement', '密钥管理', 'Keys', 'admin', '2023-02-24 10:22:52', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (15, 'router.tokenManagement', '令牌管理', 'Tokens', 'admin', '2023-02-24 10:23:22', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (16, 'router.quartzManagement', 'Quartz管理', 'Quartz Jobs', 'admin', '2023-02-24 10:24:32', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (17, 'router.metadataManagement', '元数据管理', 'Metadata', 'admin', '2023-02-24 10:25:11', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (18, 'router.documentExtension', '文档扩展', 'Document Extension', 'admin', '2023-02-24 10:27:23', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (19, 'router.fileManagement', '文件管理', 'File Management', 'admin', '2023-02-24 10:28:44', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (20, 'router.platformDevelopment', '开发平台', 'Platform Development', 'admin', '2023-02-24 10:29:28', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (21, 'router.dataSourceManagement', '数据源管理', 'Data Source Management', 'admin', '2023-02-24 10:30:33', 'admin', '2023-03-06 14:33:20', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (22, 'router.formDesign', '表单设计', 'Form Design', 'admin', '2023-02-24 10:31:33', 'admin', '2023-03-06 14:33:28', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (23, 'router.appManagement', 'APP管理', 'App Management', 'admin', '2023-02-24 10:33:22', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (24, 'router.customerManagement', '客户管理', 'Customer Management', 'admin', '2023-02-24 10:35:30', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (19, 'router.fileManagement', '文件管理', 'Files', 'admin', '2023-02-24 10:28:44', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (20, 'router.platformDevelopment', '开发平台', 'Development', 'admin', '2023-02-24 10:29:28', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (21, 'router.dataSourceManagement', '数据源管理', 'Data Sources', 'admin', '2023-02-24 10:30:33', 'admin', '2023-03-06 14:33:20', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (23, 'router.appManagement', 'APP管理', 'Apps', 'admin', '2023-02-24 10:33:22', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (24, 'router.customerManagement', '客户管理', 'Customers', 'admin', '2023-02-24 10:35:30', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (25, 'router.appRole', 'APP角色', 'App Role', 'admin', '2023-02-24 10:36:17', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (26, 'router.appPermission', 'APP权限', 'App Permission', 'admin', '2023-02-24 10:36:59', 'admin', '2023-02-24 10:37:47', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (27, 'router.appKey', 'APP秘钥', 'App Key', 'admin', '2023-02-24 10:36:59', 'admin', '2023-02-24 10:40:27', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (28, 'router.internationalizationManagement', '国际化管理', 'Internationalization Management', 'admin', '2023-02-24 10:36:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (29, 'router.auditLog', '审计日志', 'Audit Log', 'admin', '2023-02-24 10:36:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (27, 'router.appKey', 'APP秘钥', 'App Keys', 'admin', '2023-02-24 10:36:59', 'admin', '2023-02-24 10:40:27', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (28, 'router.internationalizationManagement', '国际化管理', 'Translations', 'admin', '2023-02-24 10:36:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (29, 'router.auditLog', '审计日志', 'Audit Logs', 'admin', '2023-02-24 10:36:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (30, 'router.systemMonitoring', '系统监控', 'System Monitoring', 'admin', '2023-02-24 10:36:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (31, 'router.generatePages', '生成页面', 'Generate Pages', 'admin', '2023-02-24 10:44:04', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (32, 'router.templateManagement', '模板管理', 'Template Management', 'admin', '2023-02-24 10:44:31', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (33, 'router.templateGroup', '模板分组', 'Template Group', 'admin', '2023-02-24 10:45:10', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (34, 'router.fieldManagement', '字段管理', 'Field Management', 'admin', '2023-02-24 10:46:04', 'admin', '2023-03-07 14:27:48', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (35, 'router.wechatPlatform', '公众号平台', 'WeChat Platform', 'admin', '2023-02-24 10:48:51', 'admin', '2023-02-24 11:03:41', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (36, 'router.accountManagement', '账号管理', 'Account Management', 'admin', '2023-02-24 10:13:34', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (37, 'router.menuSettings', '菜单设置', 'Menu Settings', 'admin', '2023-02-24 14:02:22', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (38, 'router.fanManagement', '粉丝管理', 'Fan Management', 'admin', '2023-02-24 14:03:44', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (39, 'router.messageManagement', '消息管理', 'Message Management', 'admin', '2023-02-24 14:03:45', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (40, 'router.paymentSystem', '支付系统', 'Payment System', 'admin', '2023-02-24 14:03:46', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (41, 'router.checkoutCounter', '收银台', 'Checkout Counter', 'admin', '2023-02-24 14:03:47', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (42, 'router.mediaManagement', '素材管理', 'Media Management', 'admin', '2023-02-24 14:03:48', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (43, 'router.paymentChannel', '支付渠道', 'Payment Channel', 'admin', '2023-02-24 14:03:49', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (44, 'router.productOrder', '商品订单', 'Product Order', 'admin', '2023-02-24 14:03:50', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (45, 'router.notificationRecord', '通知记录', 'Notification Record', 'admin', '2023-02-24 14:03:51', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (46, 'router.refundOrder', '退款订单', 'Refund Order', 'admin', '2023-02-24 14:03:52', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (47, 'router.paymentOrder', '支付订单', 'Payment Order', 'admin', '2023-02-24 14:03:53', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (48, 'router.autoReply', '自动回复', 'Auto Reply', 'admin', '2023-02-24 14:03:54', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (49, 'router.operationalData', '运营数据', 'Operational Data', 'admin', '2023-02-24 14:03:55', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (50, 'router.logManagement', '日志管理', 'Log Management', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (51, 'router.collaborativeOffice', '协同办公', 'Collaborative Office', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (32, 'router.templateManagement', '模板管理', 'Templates', 'admin', '2023-02-24 10:44:31', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (33, 'router.templateGroup', '模板分组', 'Template Groups', 'admin', '2023-02-24 10:45:10', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (34, 'router.fieldManagement', '字段管理', 'Fields', 'admin', '2023-02-24 10:46:04', 'admin', '2023-03-07 14:27:48', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (35, 'router.wechatPlatform', '公众号平台', 'WeChat', 'admin', '2023-02-24 10:48:51', 'admin', '2023-02-24 11:03:41', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (36, 'router.accountManagement', '账号管理', 'Accounts', 'admin', '2023-02-24 10:13:34', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (37, 'router.menuSettings', '菜单设置', 'Menus', 'admin', '2023-02-24 14:02:22', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (38, 'router.fanManagement', '粉丝管理', 'Followers', 'admin', '2023-02-24 14:03:44', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (39, 'router.messageManagement', '消息管理', 'Messages', 'admin', '2023-02-24 14:03:45', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (40, 'router.paymentSystem', '支付系统', 'Payments', 'admin', '2023-02-24 14:03:46', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (41, 'router.checkoutCounter', '收银台', 'Checkout', 'admin', '2023-02-24 14:03:47', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (42, 'router.mediaManagement', '素材管理', 'Media', 'admin', '2023-02-24 14:03:48', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (43, 'router.paymentChannel', '支付渠道', 'Channels', 'admin', '2023-02-24 14:03:49', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (44, 'router.productOrder', '商品订单', 'Product Orders', 'admin', '2023-02-24 14:03:50', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (45, 'router.notificationRecord', '通知记录', 'Notifications', 'admin', '2023-02-24 14:03:51', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (46, 'router.refundOrder', '退款订单', 'Refunds', 'admin', '2023-02-24 14:03:52', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (47, 'router.paymentOrder', '支付订单', 'Payment Orders', 'admin', '2023-02-24 14:03:53', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (48, 'router.autoReply', '自动回复', 'Auto Replies', 'admin', '2023-02-24 14:03:54', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (49, 'router.operationalData', '运营数据', 'Analytics', 'admin', '2023-02-24 14:03:55', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (50, 'router.logManagement', '日志管理', 'Logs', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (51, 'router.collaborativeOffice', '协同办公', 'Office', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (52, 'router.modelManagement', '模型管理', 'Model Management', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (53, 'router.modelDiagramView', '模型图查看', 'Model Diagram View', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (54, 'router.processManagement', '流程管理', 'Process Management', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (54, 'router.processManagement', '流程管理', 'Workflows', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (55, 'router.leaveWorkOrder', '请假工单', 'Leave Work Order', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (56, 'router.todoTask', '待办任务', 'Todo Task', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (57, 'router.tagManagement', '标签管理', 'Tag Management', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (58, 'router.articleInformation', '文章资讯', 'Article Information', ' ', '2023-08-10 13:40:09', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (59, 'router.articleCategory', '文章分类', 'Article Category', ' ', '2023-08-10 13:40:48', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (60, 'router.interfaceSettings', '界面设置', 'Interface Settings', ' ', '2023-08-10 13:41:21', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (62, 'router.cacheMonitoring', '缓存监控', 'Cache Monitoring', ' ', '2023-08-10 13:42:35', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (63, 'rotuer. initiateProcess', '发起流程', 'Initiate Process', ' ', '2023-08-10 13:44:23', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (64, 'router.taskManagement', '任务管理', 'Task Management', ' ', '2023-08-10 13:44:53', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (65, 'router.myInitiations', '我的发起', 'My Initiations', ' ', '2023-08-10 13:45:17', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (56, 'router.todoTask', '待办任务', 'Pending Tasks', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (57, 'router.tagManagement', '标签管理', 'Tags', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (58, 'router.articleInformation', '文章资讯', 'Articles', ' ', '2023-08-10 13:40:09', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (59, 'router.articleCategory', '文章分类', 'Categories', ' ', '2023-08-10 13:40:48', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (60, 'router.interfaceSettings', '界面设置', 'Page Settings', ' ', '2023-08-10 13:41:21', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (62, 'router.cacheMonitoring', '缓存监控', 'Cache Monitor', ' ', '2023-08-10 13:42:35', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (63, 'rotuer. initiateProcess', '发起流程', 'Start Workflow', ' ', '2023-08-10 13:44:23', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (64, 'router.taskManagement', '任务管理', 'Tasks', ' ', '2023-08-10 13:44:53', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (65, 'router.myInitiations', '我的发起', 'My Requests', ' ', '2023-08-10 13:45:17', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (66, 'router.copiedtoMe', '抄送给我', 'Copied to Me', ' ', '2023-08-10 13:45:46', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (67, 'router.completedTasks', '我的已办', 'Completed Tasks', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (68, 'router.bizPlatform', '业务平台', 'Biz Platform', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (69, 'router.baseTools', '基础工具', 'Base Tools', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (70, 'router.route', '路由管理', 'Route Management', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (71, 'router.datav', '大屏看板', 'Data Visual', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (72, 'router.bi', '数据报表', 'Bi Report', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (73, 'router.message', '信息推送', 'Message', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (74, 'router.sensitiveWords', '敏感词管理', 'Sensitive words', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (67, 'router.completedTasks', '我的已办', 'Handled Tasks', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (68, 'router.bizPlatform', '业务平台', 'Business', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (69, 'router.baseTools', '基础工具', 'Tools', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (70, 'router.route', '路由管理', 'Routes', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (71, 'router.datav', '大屏看板', 'Dashboards', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (72, 'router.bi', '数据报表', 'Reports', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (73, 'router.message', '信息推送', 'Message Push', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (74, 'router.sensitiveWords', '敏感词管理', 'Sensitive Words', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (75, 'router.clarityMonitoring', '站点统计', 'Site Analytics', 'admin', '2026-03-26 00:00:00', 'admin', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (128, 'router.siteConfig', '网站配置', 'Site Settings', 'admin', '2026-11-03 00:00:00', 'admin', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (129, 'router.sysArea', '行政区划', 'Admin Divisions', 'admin', '2026-11-03 00:00:00', 'admin', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (130, 'router.businessForm', '业务表单', 'Business Forms', 'admin', '2026-11-03 00:00:00', 'admin', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (131, 'router.databaseTables', '数据表管理', 'Database Tables', 'admin', '2026-11-03 00:00:00', 'admin', NULL, '0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
@@ -488,8 +491,8 @@ CREATE TABLE `sys_log` (
|
||||
`log_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '日志类型',
|
||||
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '日志标题',
|
||||
`service_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '服务ID',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remote_addr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '远程地址',
|
||||
@@ -543,9 +546,9 @@ CREATE TABLE `sys_menu` (
|
||||
`keep_alive` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '是否缓存,0否,1是',
|
||||
`embedded` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否内嵌,0否,1是',
|
||||
`menu_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '菜单类型,0:菜单 1:按钮',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标志,0未删除,1已删除',
|
||||
`tenant_id` bigint(20) unsigned DEFAULT NULL COMMENT '租户ID',
|
||||
@@ -703,6 +706,7 @@ INSERT INTO `sys_menu` VALUES (4011,'信息推送查看','sys_message_view',NULL
|
||||
INSERT INTO `sys_menu` VALUES (4012,'信息推送新增','sys_message_add',NULL,NULL,4010,'1','1',1,'0',NULL,'1','',NULL,'admin','2023-10-25 14:52:00','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (4013,'信息推送修改','sys_message_edit',NULL,NULL,4010,'1','1',2,'0',NULL,'1','',NULL,'admin','2023-10-25 14:52:04','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (4014,'信息推送删除','sys_message_del',NULL,NULL,4010,'1','1',3,'0',NULL,'1','',NULL,'admin','2023-10-25 14:52:09','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (4015, '信息推送导出', 'sys_message_export', NULL, NULL, 4010, NULL, '1', 10, '0', '0', '1', 'admin', NOW(), 'admin', NOW(), '0', 1);
|
||||
INSERT INTO `sys_menu` VALUES (5000,'支付系统',NULL,'/pay',NULL,9900,'iconfont icon-duoqudaozhifuxitongguanli','1',1,'0','0','0','admin','2023-02-27 10:57:14','admin','2023-11-27 14:52:11','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (5001,'收银台',NULL,'/biz/pay/cd/index',NULL,5000,'iconfont icon-shouyintai','1',0,'0','0','0','admin','2023-02-27 10:58:13','admin','2023-11-01 17:28:57','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (5002,'支付渠道',NULL,'/biz/pay/channel/index',NULL,5000,'iconfont icon-zhifuqudao','1',1,'0','0','0','admin','2023-02-27 19:36:55','admin','2023-11-01 17:29:01','0',1);
|
||||
@@ -776,7 +780,6 @@ INSERT INTO `sys_menu` VALUES (7804,'删除','app_appContacts_del',NULL,NULL,780
|
||||
INSERT INTO `sys_menu` VALUES (7805,'导入导出','app_appContacts_export',NULL,NULL,7800,NULL,'1',1,'0',NULL,'1','admin','2025-05-29 17:30:31',' ',NULL,'0',1);
|
||||
INSERT INTO `sys_menu` VALUES (9000,'开发平台',NULL,'/gen',NULL,-1,'iconfont icon-DevOps','1',9,'0','0','0','','2019-08-12 09:35:16','admin','2025-01-26 22:38:09','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (9005,'数据源管理',NULL,'/gen/datasource/index',NULL,9000,'iconfont icon-shujuyuanguanli','1',0,'0',NULL,'0','','2019-08-12 09:42:11','admin','2025-01-26 22:26:51','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (9006,'表单设计',NULL,'/gen/design/index',NULL,9000,'iconfont icon-AIshiyanshi','0',2,'0','0','0','','2019-08-16 10:08:56','admin','2023-02-23 14:06:50','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (9007,'生成页面',NULL,'/gen/gener/index',NULL,9000,'iconfont icon-tongzhi4','0',1,'0','0','0','admin','2023-02-20 09:58:23','admin','2023-02-20 14:41:43','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (9050,'元数据管理',NULL,'/gen/metadata',NULL,9000,'iconfont icon-yuanshujuguanli','1',9,'0','0','0','','2018-07-27 01:13:21','admin','2023-02-23 19:55:10','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (9051,'模板管理',NULL,'/gen/template/index',NULL,9050,'iconfont icon-mti-mobanguanli','1',5,'0','0','0','admin','2023-02-21 11:22:54','admin','2023-02-23 19:56:03','0',1);
|
||||
@@ -821,8 +824,8 @@ CREATE TABLE `sys_oauth_client_details` (
|
||||
`additional_information` varchar(4096) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '附加信息',
|
||||
`autoapprove` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '自动授权',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记,0未删除,1已删除',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '所属租户ID',
|
||||
@@ -833,11 +836,11 @@ CREATE TABLE `sys_oauth_client_details` (
|
||||
-- Records of sys_oauth_client_details
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (1, 'app', NULL, 'app', 'server', 'password,refresh_token,authorization_code,client_credentials,mobile', 'http://localhost:4040/sso1/login,http://localhost:4041/sso1/login,http://localhost:8080/renren-admin/sys/oauth2-sso,http://localhost:8090/sys/oauth2-sso', NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\",\"online_quantity\":\"1\"}', 'true', '0', '', 'admin', NULL, '2023-02-09 13:54:54', 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (1, 'app', NULL, 'app', 'server', 'password,refresh_token,authorization_code,mobile', 'http://localhost:4040/sso1/login,http://localhost:4041/sso1/login,http://localhost:8080/renren-admin/sys/oauth2-sso,http://localhost:8090/sys/oauth2-sso', NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\",\"online_quantity\":\"1\"}', 'true', '0', '', 'admin', NULL, '2023-02-09 13:54:54', 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (2, 'daemon', NULL, 'daemon', 'server', 'password,refresh_token', NULL, NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\"}', 'true', '0', ' ', ' ', NULL, NULL, 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (3, 'gen', NULL, 'gen', 'server', 'password,refresh_token', NULL, NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\"}', 'true', '0', ' ', ' ', NULL, NULL, 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (4, 'mp', NULL, 'mp', 'server', 'password,refresh_token', NULL, NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\"}', 'true', '0', ' ', ' ', NULL, NULL, 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (5, 'pig', NULL, 'pig', 'server', 'password,refresh_token,authorization_code,client_credentials,mobile', 'http://localhost:4040/sso1/login,http://localhost:4041/sso1/login,http://localhost:8080/renren-admin/sys/oauth2-sso,http://localhost:8090/sys/oauth2-sso', NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\",\"online_quantity\":\"1\"}', 'false', '0', '', 'admin', NULL, '2023-03-08 11:32:41', 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (5, 'pig', NULL, 'pig', 'server', 'password,refresh_token,authorization_code,mobile', 'http://localhost:4040/sso1/login,http://localhost:4041/sso1/login,http://localhost:8080/renren-admin/sys/oauth2-sso,http://localhost:8090/sys/oauth2-sso', NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\",\"online_quantity\":\"1\"}', 'false', '0', '', 'admin', NULL, '2023-03-08 11:32:41', 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (6, 'test', NULL, 'test', 'server', 'password,refresh_token', NULL, NULL, 43200, 2592001, '{ \"enc_flag\":\"1\",\"captcha_flag\":\"0\"}', 'true', '0', ' ', ' ', NULL, NULL, 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (7, 'social', NULL, 'social', 'server', 'password,refresh_token,mobile', NULL, NULL, 43200, 2592001, '{ \"enc_flag\":\"0\",\"captcha_flag\":\"0\"}', 'true', '0', ' ', ' ', NULL, NULL, 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (8, 'mini', NULL, 'mini', 'server', 'password,mobile', NULL, NULL, 160000000, 160000000, '{\"captcha_flag\":\"0\",\"enc_flag\":\"0\",\"online_quantity\":\"1\"}', 'true', '0', 'admin', 'admin', '2023-01-29 16:38:06', '2023-01-29 17:21:56', 1);
|
||||
@@ -880,8 +883,8 @@ CREATE TABLE `sys_public_param` (
|
||||
`public_value` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '值',
|
||||
`status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '状态,0禁用,1启用',
|
||||
`validate_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '校验码',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`public_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '类型,0未知,1系统,2业务',
|
||||
@@ -910,8 +913,8 @@ INSERT INTO `sys_public_param` VALUES (12, '强制重置密码', 'SITE_FORCE_RES
|
||||
INSERT INTO `sys_public_param` VALUES (13, '强制退出', 'SITE_FORCE_LOGOUT', '0', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (14, '短信登录开关', 'SITE_SMS_LOGIN_ENABLE', '1', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (15, '社交登录开关', 'SITE_SOCIAL_LOGIN_ENABLE', '1', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (16, '前端注册开关', 'SITE_REGISTER_ENABLE', '1', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (17, '找回/重置密码开关', 'SITE_RESET_PASSWORD', '1', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (16, '前端注册开关', 'SITE_REGISTER_ENABLE', '0', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (17, '找回/重置密码开关', 'SITE_RESET_PASSWORD', '0', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (18, '国际化切换开关', 'SITE_I18N_ENABLE', '1', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (19, '亮暗模式切换开关', 'SITE_DARK_MODE_ENABLE', '1', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (20, '反调试保护', 'SITE_ANTI_DEBUG_ENABLE', '0', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
@@ -940,8 +943,8 @@ CREATE TABLE `sys_role` (
|
||||
`role_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '角色描述',
|
||||
`ds_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '2' COMMENT '数据权限类型,0全部,1自定义,2本部门及以下,3本部门,4仅本人',
|
||||
`ds_scope` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据权限范围',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记,0未删除,1已删除',
|
||||
@@ -1122,6 +1125,7 @@ INSERT INTO `sys_role_menu` VALUES (1, 4011);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 4012);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 4013);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 4014);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 4015);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 5000);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 5001);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 5002);
|
||||
@@ -1195,7 +1199,6 @@ INSERT INTO `sys_role_menu` VALUES (1, 7804);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 7805);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 9000);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 9005);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 9006);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 9007);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 9050);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 9051);
|
||||
@@ -1247,18 +1250,18 @@ CREATE TABLE `sys_role_widget` (
|
||||
DROP TABLE IF EXISTS `sys_route_conf`;
|
||||
CREATE TABLE `sys_route_conf` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键',
|
||||
`route_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
|
||||
`route_id` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
|
||||
`route_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`route_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`predicates` json DEFAULT NULL COMMENT '断言',
|
||||
`filters` json DEFAULT NULL COMMENT '过滤器',
|
||||
`uri` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
|
||||
`uri` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`sort_order` int(11) DEFAULT '0' COMMENT '排序',
|
||||
`metadata` json DEFAULT NULL COMMENT '路由元信息',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '0',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='路由配置表';
|
||||
|
||||
@@ -1295,9 +1298,9 @@ CREATE TABLE `sys_schedule` (
|
||||
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '内容',
|
||||
`schedule_time` time DEFAULT NULL COMMENT '时间',
|
||||
`schedule_date` date DEFAULT NULL COMMENT '日期',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
|
||||
`tenant_id` bigint(20) unsigned DEFAULT NULL COMMENT '租户ID',
|
||||
@@ -1322,8 +1325,8 @@ CREATE TABLE `sys_social_details` (
|
||||
`app_secret` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '应用密钥',
|
||||
`redirect_url` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '回调地址',
|
||||
`ext` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '拓展字段',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记,0未删除,1已删除',
|
||||
@@ -1412,21 +1415,14 @@ CREATE TABLE `sys_user` (
|
||||
`nickname` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '昵称',
|
||||
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名',
|
||||
`email` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '邮箱地址',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
`lock_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '锁定标记,0未锁定,9已锁定',
|
||||
`password_expire_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '密码是否过期,0未过期,9已过期',
|
||||
`password_modify_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记,0未删除,1已删除',
|
||||
`wx_openid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '微信登录openId',
|
||||
`mini_openid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '小程序openId',
|
||||
`qq_openid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'QQ openId',
|
||||
`gitee_login` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '码云标识',
|
||||
`osc_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '开源中国标识',
|
||||
`wx_cp_userid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '企业微信唯一ID',
|
||||
`wx_ding_userid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '钉钉唯一ID',
|
||||
`dept_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '主部门ID',
|
||||
`tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '所属租户ID',
|
||||
PRIMARY KEY (`user_id`) USING BTREE
|
||||
@@ -1436,9 +1432,24 @@ CREATE TABLE `sys_user` (
|
||||
-- Records of sys_user
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_user` VALUES (1, 'admin', '$2a$10$c/Ae0pRjJtMZg3BnvVpO.eIK6WYWVbKTzqgdy3afR7w.vd.xi3Mgy', '', '17338122125', '/admin/sys-file/local/2a14ae08150e483c93e12ac8934173e2.png', '管理员666777', '管理员', 'sw@mail.pigxl.vip', ' ', 'admin', '2018-04-20 07:15:18', '2023-04-03 14:00:06', '0', '0', NULL, '0', NULL, 'oBxPy5E-v82xWGsfzZVzkD3wEX64', NULL, 'log4j', NULL, NULL,NULL,1,1);
|
||||
INSERT INTO `sys_user` (`user_id`, `username`, `password`, `salt`, `phone`, `avatar`, `nickname`, `name`, `email`, `create_by`, `update_by`, `create_time`, `update_time`, `lock_flag`, `password_expire_flag`, `password_modify_time`, `del_flag`, `dept_id`, `tenant_id`) VALUES (1, 'admin', '$2a$10$c/Ae0pRjJtMZg3BnvVpO.eIK6WYWVbKTzqgdy3afR7w.vd.xi3Mgy', '', '17338122125', '/admin/sys-file/local/2a14ae08150e483c93e12ac8934173e2.png', '管理员666777', '管理员', 'sw@mail.pigxl.vip', ' ', 'admin', '2018-04-20 07:15:18', '2023-04-03 14:00:06', '0', '0', NULL, '0', 1, 1);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_user_social
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_user_social`;
|
||||
CREATE TABLE `sys_user_social` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
|
||||
`type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '社交平台类型',
|
||||
`identifier` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '唯一凭据',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE KEY `uk_social_identifier` (`type`,`identifier`) USING BTREE,
|
||||
UNIQUE KEY `uk_user_social_type` (`user_id`,`type`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户社交登录身份表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_user_post
|
||||
-- ----------------------------
|
||||
@@ -1528,7 +1539,11 @@ CREATE TABLE `sys_message` (
|
||||
`update_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除时间',
|
||||
`tenant_id` bigint DEFAULT NULL COMMENT '租户',
|
||||
PRIMARY KEY (`id`)
|
||||
`business_type` varchar(32) DEFAULT NULL COMMENT '业务类型',
|
||||
`business_id` varchar(64) DEFAULT NULL COMMENT '业务记录ID',
|
||||
`request_key` varchar(100) DEFAULT NULL COMMENT '调用方事件标识',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_message_request` (`tenant_id`,`request_key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='站内信息';
|
||||
|
||||
-- ----------------------------
|
||||
@@ -1553,7 +1568,8 @@ CREATE TABLE `sys_message_relation` (
|
||||
`update_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除时间',
|
||||
`tenant_id` bigint DEFAULT NULL COMMENT '租户',
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_relation_msg_user` (`msg_id`,`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='系统消息推送记录';
|
||||
|
||||
|
||||
@@ -1696,11 +1712,13 @@ CREATE TABLE `process_node_data` (
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标志',
|
||||
`create_time` datetime COMMENT '创建时间',
|
||||
`update_time` datetime COMMENT '更新时间',
|
||||
`process_definition_id` varchar(64) DEFAULT NULL COMMENT '引擎流程定义ID,发布版本快照',
|
||||
`flow_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '流程id',
|
||||
`data` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '表单数据',
|
||||
`node_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '所属租户id',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE KEY `uk_node_definition` (`tenant_id`,`process_definition_id`,`node_id`),
|
||||
KEY `data_idx_id` (`id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1195 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='流程节点数据';
|
||||
|
||||
@@ -1761,9 +1779,21 @@ CREATE TABLE `process_node_record_assign_user` (
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE KEY `uk_node_record_user` (`tenant_id`,`node_record_id`,`user_id`) USING BTREE,
|
||||
KEY `user_idx_id` (`id`) USING BTREE,
|
||||
KEY `idx_add_sign_record_id` (`add_sign_record_id`) USING BTREE
|
||||
KEY `idx_add_sign_record_id` (`add_sign_record_id`) USING BTREE,
|
||||
KEY `idx_assign_tenant_instance_del` (`tenant_id`,`process_instance_id`,`del_flag`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=597 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='流程节点记录-执行人';
|
||||
|
||||
-- Flowable 列表查询索引:act_* 表由引擎初始化,不在本脚本中创建。
|
||||
-- 首次启动完成后,在业务库手动执行以下 SQL 一次;已有同名索引时不要重复执行。
|
||||
-- 待办:按审批人筛选、创建时间排序。
|
||||
-- ALTER TABLE `act_ru_task`
|
||||
-- ADD INDEX `idx_task_assignee_create` (`ASSIGNEE_`, `CREATE_TIME_`),
|
||||
-- ALGORITHM=INPLACE, LOCK=NONE;
|
||||
-- 已办:按审批人及结束时间查询、统计。
|
||||
-- ALTER TABLE `act_hi_actinst`
|
||||
-- ADD INDEX `idx_act_assignee_end` (`ASSIGNEE_`, `END_TIME_`),
|
||||
-- ALGORITHM=INPLACE, LOCK=NONE;
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for process_task_add_sign_record
|
||||
@@ -1791,6 +1821,50 @@ CREATE TABLE `process_task_add_sign_record` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='流程动态加签批次记录';
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for flow_draft
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `flow_draft`;
|
||||
CREATE TABLE `flow_draft` (
|
||||
`id` varchar(36) COLLATE utf8mb4_general_ci NOT NULL COMMENT '草稿ID',
|
||||
`tenant_id` bigint NOT NULL COMMENT '所属租户ID',
|
||||
`user_id` bigint NOT NULL COMMENT '草稿所属用户ID',
|
||||
`kind` varchar(16) COLLATE utf8mb4_general_ci NOT NULL COMMENT '草稿类型:DESIGN 流程设计,APPLICATION 申请',
|
||||
`flow_id` varchar(64) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '关联流程ID,未建立流程时为空串',
|
||||
`title` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT '草稿标题',
|
||||
`payload` longtext COLLATE utf8mb4_general_ci NOT NULL COMMENT '草稿内容 JSON,最多 1 MB',
|
||||
`revision` bigint NOT NULL COMMENT '乐观锁版本号',
|
||||
`updated_at` timestamp(3) NOT NULL COMMENT '最后保存时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_draft_owner` (`tenant_id`,`user_id`,`kind`,`updated_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='个人流程草稿';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for flow_notice
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `flow_notice`;
|
||||
CREATE TABLE `flow_notice` (
|
||||
`id` varchar(36) COLLATE utf8mb4_general_ci NOT NULL COMMENT '通知事件ID',
|
||||
`tenant_id` bigint NOT NULL COMMENT '所属租户ID',
|
||||
`user_id` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '接收人ID,超时提醒到期前为空串',
|
||||
`event_key` varchar(180) COLLATE utf8mb4_general_ci NOT NULL COMMENT '事件去重键',
|
||||
`kind` varchar(16) COLLATE utf8mb4_general_ci NOT NULL COMMENT '通知类型:TODO 待办,URGE 催办,OVERDUE 超时提醒',
|
||||
`title` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT '通知标题',
|
||||
`task_id` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '引擎任务ID',
|
||||
`instance_id` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '引擎流程实例ID',
|
||||
`created_at` timestamp(3) NOT NULL COMMENT '创建时间',
|
||||
`status` varchar(16) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'SENT' COMMENT '状态:PENDING 待到期,READY 待投递,SENT 已投递,REMOVING 待撤销,CANCELLED 已取消,DISABLED 已停用',
|
||||
`scheduled_at` timestamp(3) NULL DEFAULT NULL COMMENT '计划投递或到期时间',
|
||||
`sent_at` timestamp(3) NULL DEFAULT NULL COMMENT '投递到统一站内信的时间',
|
||||
`reminder_key` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '超时提醒任务ID,每个任务最多一条',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_notice_event` (`tenant_id`,`user_id`,`event_key`),
|
||||
UNIQUE KEY `uk_notice_reminder` (`tenant_id`,`reminder_key`),
|
||||
KEY `idx_notice_owner` (`tenant_id`,`user_id`,`created_at`),
|
||||
KEY `idx_notice_due` (`status`,`scheduled_at`),
|
||||
KEY `idx_notice_task` (`tenant_id`,`task_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='流程通知事件';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for process_starter
|
||||
-- ----------------------------
|
||||
@@ -1814,31 +1888,31 @@ CREATE TABLE `process_starter` (
|
||||
DROP TABLE IF EXISTS `bmp_oa_leave`;
|
||||
CREATE TABLE `bmp_oa_leave` (
|
||||
`id` bigint NOT NULL COMMENT '请假表单主键',
|
||||
`username` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '申请人',
|
||||
`username` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '申请人',
|
||||
`leave_type` int NOT NULL COMMENT '请假类型',
|
||||
`leave_reason` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '请假原因',
|
||||
`leave_reason` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '请假原因',
|
||||
`start_time` datetime NOT NULL COMMENT '开始时间',
|
||||
`end_time` datetime NOT NULL COMMENT '结束时间',
|
||||
`leave_day` int NOT NULL COMMENT '请假天数',
|
||||
`leave_status` int DEFAULT NULL COMMENT '请假结果',
|
||||
`process_instance_id` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '流程实例的编号',
|
||||
`create_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',
|
||||
`process_instance_id` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '流程实例的编号',
|
||||
`create_by` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
|
||||
`update_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者',
|
||||
`update_by` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
|
||||
`del_flag` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '是否删除',
|
||||
`del_flag` char(1) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='请假表单';
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='请假表单';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for qrtz_blob_triggers
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_blob_triggers`;
|
||||
CREATE TABLE `qrtz_blob_triggers` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`blob_data` blob,
|
||||
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`) USING BTREE,
|
||||
CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
|
||||
@@ -1855,8 +1929,8 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_calendars`;
|
||||
CREATE TABLE `qrtz_calendars` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`calendar_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`calendar_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`calendar` blob NOT NULL,
|
||||
PRIMARY KEY (`sched_name`,`calendar_name`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
@@ -1872,11 +1946,11 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_cron_triggers`;
|
||||
CREATE TABLE `qrtz_cron_triggers` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`cron_expression` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`time_zone_id` varchar(80) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`cron_expression` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`time_zone_id` varchar(80) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`) USING BTREE,
|
||||
CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
@@ -1892,19 +1966,19 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_fired_triggers`;
|
||||
CREATE TABLE `qrtz_fired_triggers` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`entry_id` varchar(95) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`instance_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`entry_id` varchar(95) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`instance_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`fired_time` bigint NOT NULL,
|
||||
`sched_time` bigint NOT NULL,
|
||||
`priority` int NOT NULL,
|
||||
`state` varchar(16) CHARACTER SET utf8 NOT NULL,
|
||||
`job_name` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`job_group` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`is_nonconcurrent` varchar(1) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`requests_recovery` varchar(1) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`state` varchar(16) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`job_name` varchar(200) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`job_group` varchar(200) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`is_nonconcurrent` varchar(1) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`requests_recovery` varchar(1) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
PRIMARY KEY (`sched_name`,`entry_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
@@ -1919,15 +1993,15 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_job_details`;
|
||||
CREATE TABLE `qrtz_job_details` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`job_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`job_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`description` varchar(250) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`job_class_name` varchar(250) CHARACTER SET utf8 NOT NULL,
|
||||
`is_durable` varchar(1) CHARACTER SET utf8 NOT NULL,
|
||||
`is_nonconcurrent` varchar(1) CHARACTER SET utf8 NOT NULL,
|
||||
`is_update_data` varchar(1) CHARACTER SET utf8 NOT NULL,
|
||||
`requests_recovery` varchar(1) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`job_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`job_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`description` varchar(250) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`job_class_name` varchar(250) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`is_durable` varchar(1) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`is_nonconcurrent` varchar(1) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`is_update_data` varchar(1) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`requests_recovery` varchar(1) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`job_data` blob,
|
||||
PRIMARY KEY (`sched_name`,`job_name`,`job_group`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
@@ -1943,8 +2017,8 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_locks`;
|
||||
CREATE TABLE `qrtz_locks` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`lock_name` varchar(40) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`lock_name` varchar(40) CHARACTER SET utf8mb4 NOT NULL,
|
||||
PRIMARY KEY (`sched_name`,`lock_name`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
@@ -1959,8 +2033,8 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_paused_trigger_grps`;
|
||||
CREATE TABLE `qrtz_paused_trigger_grps` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
PRIMARY KEY (`sched_name`,`trigger_group`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
@@ -1975,8 +2049,8 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_scheduler_state`;
|
||||
CREATE TABLE `qrtz_scheduler_state` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`instance_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`instance_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`last_checkin_time` bigint NOT NULL,
|
||||
`checkin_interval` bigint NOT NULL,
|
||||
PRIMARY KEY (`sched_name`,`instance_name`) USING BTREE
|
||||
@@ -1993,9 +2067,9 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_simple_triggers`;
|
||||
CREATE TABLE `qrtz_simple_triggers` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`repeat_count` bigint NOT NULL,
|
||||
`repeat_interval` bigint NOT NULL,
|
||||
`times_triggered` bigint NOT NULL,
|
||||
@@ -2014,20 +2088,20 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_simprop_triggers`;
|
||||
CREATE TABLE `qrtz_simprop_triggers` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`str_prop_1` varchar(512) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`str_prop_2` varchar(512) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`str_prop_3` varchar(512) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`str_prop_1` varchar(512) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`str_prop_2` varchar(512) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`str_prop_3` varchar(512) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`int_prop_1` int DEFAULT NULL,
|
||||
`int_prop_2` int DEFAULT NULL,
|
||||
`long_prop_1` bigint DEFAULT NULL,
|
||||
`long_prop_2` bigint DEFAULT NULL,
|
||||
`dec_prop_1` decimal(13,4) DEFAULT NULL,
|
||||
`dec_prop_2` decimal(13,4) DEFAULT NULL,
|
||||
`bool_prop_1` varchar(1) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`bool_prop_2` varchar(1) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`bool_prop_1` varchar(1) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`bool_prop_2` varchar(1) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`) USING BTREE,
|
||||
CONSTRAINT `QRTZ_SIMPROP_TRIGGERS_IBFK_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
@@ -2043,20 +2117,20 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_triggers`;
|
||||
CREATE TABLE `qrtz_triggers` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`job_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`job_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`description` varchar(250) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`job_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`job_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`description` varchar(250) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`next_fire_time` bigint DEFAULT NULL,
|
||||
`prev_fire_time` bigint DEFAULT NULL,
|
||||
`priority` int DEFAULT NULL,
|
||||
`trigger_state` varchar(16) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_type` varchar(8) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_state` varchar(16) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_type` varchar(8) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`start_time` bigint NOT NULL,
|
||||
`end_time` bigint DEFAULT NULL,
|
||||
`calendar_name` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`calendar_name` varchar(200) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`misfire_instr` smallint DEFAULT NULL,
|
||||
`job_data` blob,
|
||||
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`) USING BTREE,
|
||||
@@ -2114,22 +2188,22 @@ DROP TABLE IF EXISTS `sys_job_log`;
|
||||
CREATE TABLE `sys_job_log` (
|
||||
`job_log_id` bigint NOT NULL COMMENT '任务日志ID',
|
||||
`job_id` bigint NOT NULL COMMENT '任务id',
|
||||
`job_name` varchar(64) CHARACTER SET utf8 DEFAULT NULL COMMENT '任务名称',
|
||||
`job_group` varchar(64) CHARACTER SET utf8 DEFAULT NULL COMMENT '任务组名',
|
||||
`job_order` char(1) CHARACTER SET utf8 DEFAULT NULL COMMENT '组内执行顺利,值越大执行优先级越高,最大值9,最小值1',
|
||||
`job_type` char(1) CHARACTER SET utf8 NOT NULL DEFAULT '1' COMMENT '1、java类;2、spring bean名称;3、rest调用;4、jar调用;9其他',
|
||||
`execute_path` varchar(500) CHARACTER SET utf8 DEFAULT NULL COMMENT 'job_type=3时,rest调用地址,仅支持post协议;job_type=4时,jar路径;其它值为空',
|
||||
`class_name` varchar(500) CHARACTER SET utf8 DEFAULT NULL COMMENT 'job_type=1时,类完整路径;job_type=2时,spring bean名称;其它值为空',
|
||||
`method_name` varchar(500) CHARACTER SET utf8 DEFAULT NULL COMMENT '任务方法',
|
||||
`method_params_value` varchar(2000) CHARACTER SET utf8 DEFAULT NULL COMMENT '参数值',
|
||||
`cron_expression` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT 'cron执行表达式',
|
||||
`job_message` varchar(500) CHARACTER SET utf8 DEFAULT NULL COMMENT '日志信息',
|
||||
`job_log_status` char(1) CHARACTER SET utf8 DEFAULT '0' COMMENT '执行状态(0正常 1失败)',
|
||||
`execute_time` varchar(30) CHARACTER SET utf8 DEFAULT NULL COMMENT '执行时间',
|
||||
`exception_info` varchar(2000) CHARACTER SET utf8 DEFAULT '' COMMENT '异常信息',
|
||||
`job_name` varchar(64) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '任务名称',
|
||||
`job_group` varchar(64) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '任务组名',
|
||||
`job_order` char(1) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '组内执行顺利,值越大执行优先级越高,最大值9,最小值1',
|
||||
`job_type` char(1) CHARACTER SET utf8mb4 NOT NULL DEFAULT '1' COMMENT '1、java类;2、spring bean名称;3、rest调用;4、jar调用;9其他',
|
||||
`execute_path` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'job_type=3时,rest调用地址,仅支持post协议;job_type=4时,jar路径;其它值为空',
|
||||
`class_name` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'job_type=1时,类完整路径;job_type=2时,spring bean名称;其它值为空',
|
||||
`method_name` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '任务方法',
|
||||
`method_params_value` varchar(2000) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '参数值',
|
||||
`cron_expression` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'cron执行表达式',
|
||||
`job_message` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '日志信息',
|
||||
`job_log_status` char(1) CHARACTER SET utf8mb4 DEFAULT '0' COMMENT '执行状态(0正常 1失败)',
|
||||
`execute_time` varchar(30) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '执行时间',
|
||||
`exception_info` varchar(2000) CHARACTER SET utf8mb4 DEFAULT '' COMMENT '异常信息',
|
||||
`scheduled_fire_time` datetime DEFAULT NULL COMMENT '计划触发时间',
|
||||
`fire_instance_id` varchar(128) CHARACTER SET utf8 DEFAULT NULL COMMENT 'Quartz触发实例ID',
|
||||
`dedup_status` char(1) CHARACTER SET utf8 DEFAULT '0' COMMENT '去重状态(0正常执行 1同一触发点重复 2任务运行中跳过)',
|
||||
`fire_instance_id` varchar(128) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'Quartz触发实例ID',
|
||||
`dedup_status` char(1) CHARACTER SET utf8mb4 DEFAULT '0' COMMENT '去重状态(0正常执行 1同一触发点重复 2任务运行中跳过)',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`tenant_id` bigint NOT NULL DEFAULT '1' COMMENT '租户id',
|
||||
PRIMARY KEY (`job_log_id`) USING BTREE
|
||||
@@ -2249,8 +2323,8 @@ CREATE TABLE `wx_auto_reply` (
|
||||
`rep_thumb_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '缩略图url',
|
||||
`content` json DEFAULT NULL COMMENT '图文消息的内容',
|
||||
`app_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '公众号ID',
|
||||
`remark` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '备注',
|
||||
`del_flag` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '0' COMMENT '逻辑删除标记(0:显示;1:隐藏)',
|
||||
`remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '逻辑删除标记(0:显示;1:隐藏)',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`tenant_id` bigint(20) DEFAULT NULL COMMENT '租户ID',
|
||||
@@ -2295,7 +2369,7 @@ CREATE TABLE `wx_msg` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键',
|
||||
`app_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '公众号名称',
|
||||
`app_logo` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '公众号logo',
|
||||
`wx_user_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '微信用户ID',
|
||||
`wx_user_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '微信用户ID',
|
||||
`nick_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '微信用户昵称',
|
||||
`headimg_url` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '微信用户头像',
|
||||
`type` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '消息分类(1、用户发给公众号;2、公众号发给用户;)',
|
||||
@@ -2313,11 +2387,11 @@ CREATE TABLE `wx_msg` (
|
||||
`rep_location_x` double DEFAULT NULL COMMENT '地理位置维度',
|
||||
`rep_location_y` double DEFAULT NULL COMMENT '地理位置经度',
|
||||
`rep_scale` double DEFAULT NULL COMMENT '地图缩放大小',
|
||||
`read_flag` char(2) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '1' COMMENT '已读标记(1:是;0:否)',
|
||||
`read_flag` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '1' COMMENT '已读标记(1:是;0:否)',
|
||||
`app_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '公众号ID',
|
||||
`open_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '微信唯一标识',
|
||||
`remark` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '备注',
|
||||
`del_flag` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '0' COMMENT '逻辑删除标记(0:显示;1:隐藏)',
|
||||
`remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '逻辑删除标记(0:显示;1:隐藏)',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`tenant_id` bigint(20) DEFAULT NULL COMMENT '租户ID',
|
||||
@@ -2607,29 +2681,6 @@ INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`,
|
||||
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (49,'bytea','String',NULL,'textarea','text','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for gen_form_conf
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `gen_form_conf`;
|
||||
CREATE TABLE `gen_form_conf` (
|
||||
`id` bigint NOT NULL COMMENT 'ID',
|
||||
`ds_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据库名称',
|
||||
`table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '表名称',
|
||||
`form_info` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '表单信息',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0',
|
||||
`tenant_id` bigint DEFAULT NULL COMMENT '所属租户',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `table_name` (`table_name`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='表单配置';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of gen_form_conf
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for gen_group
|
||||
-- ----------------------------
|
||||
@@ -2639,8 +2690,8 @@ CREATE TABLE `gen_group` (
|
||||
`group_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '分组名称',
|
||||
`group_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '分组描述',
|
||||
`tenant_id` bigint NOT NULL COMMENT '租户ID',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建人',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '修改人',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
|
||||
@@ -2651,10 +2702,10 @@ CREATE TABLE `gen_group` (
|
||||
-- Records of gen_group
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (1,'单表增删改查V2026001',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (2,'主子表增删改查V2026001',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (3,'树形表格增删改查V2026001',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (4,'左树右表增删改查V2026001',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (1,'单表增删改查V202611',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (2,'主子表增删改查V202611',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (3,'树形表格增删改查V202611',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (4,'左树右表增删改查V202611',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
@@ -2750,8 +2801,8 @@ CREATE TABLE `gen_template` (
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '删除标记',
|
||||
`tenant_id` bigint NOT NULL COMMENT '租户ID',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='模板';
|
||||
|
||||
@@ -2759,51 +2810,51 @@ CREATE TABLE `gen_template` (
|
||||
-- Records of gen_template
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (1,'ControllerV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','ControllerV2026001','package ${package}.${moduleName}.controller;\n\n#if($queryList)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"分页查询\" , description = \"分页查询\" )\n @GetMapping(\"/page\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#foreach ($field in $queryList)\n#set($getAttrName=$str.getProperty($field.attrName))\n#set($var=\"${className}.$getAttrName()\")\n#if($field.attrType == \'String\')\n#set($expression=\"StrUtil.isNotBlank\")\n#else\n#set($expression=\"Objects.nonNull\")\n#end\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n if (ArrayUtil.isNotEmpty(${className}.${getAttrName}Range())) {\n wrapper.between(${ClassName}Entity::$getAttrName, ${className}.${getAttrName}Range()[0], ${className}.${getAttrName}Range()[1]);\n }\n#elseif($field.queryType == \'=\')\n wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'like\' )\n wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'!-\' )\n wrapper.ne($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>\' )\n wrapper.gt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<\' )\n wrapper.lt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>=\' )\n wrapper.ge($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<=\' )\n wrapper.le($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'left like\' )\n wrapper.likeLeft($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'right like\' )\n wrapper.likeRight($expression($var),${ClassName}Entity::$getAttrName,$var);\n#end\n#end\n return R.ok(${className}Service.page(page, wrapper));\n }\n\n\n /**\n * 通过条件查询${tableComment}\n * @param ${className} 查询条件\n * @return R 对象列表\n */\n @Operation(summary = \"通过条件查询\" , description = \"通过条件查询对象\" )\n @GetMapping(\"/details\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #elsLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (2,'ServiceV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','ServiceV2026001','package ${package}.${moduleName}.service;\n\nimport com.baomidou.mybatisplus.extension.service.IService;\nimport ${entityClassName};\n\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (3,'ServiceImplV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','ServiceImplV2026001','package ${package}.${moduleName}.service.impl;\n\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport org.springframework.stereotype.Service;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (4,'实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(\"${tableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (5,'MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV2026001','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (6,'Mapper.xmlV2026001','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV2026001','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (7,'权限菜单V2026001','${backendPath}/menu/${functionName}_menu.sql','权限菜单V2026001','-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (8,'api.tsV2026001','${frontendPath}/src/api/${moduleName}/${functionName}.ts','api.tsV2026001','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n\n#if($ChildClassName)\n// ========== 子表相关接口 ==========\n\n/**\n * 删除子表数据\n * @param ids - 要删除的子表数据ID数组\n * @returns Promise<操作结果>\n */\nexport function delChildObj(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/child\',\n method: \'delete\',\n data: ids\n })\n}\n#end\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (9,'表格V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','表格V2026001','<template>\n <div class=\"layout-padding\">\n <div class=\"layout-padding-auto layout-padding-view\">\n#if($queryList)\n <!-- 查询表单区域 -->\n <el-row v-show=\"showSearch\">\n <el-form :model=\"state.queryForm\" ref=\"queryRef\" :inline=\"true\" @keyup.enter=\"getDataList\">\n#foreach($field in $queryList)\n#if($field.queryFormType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"state.queryForm.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option \n :label=\"item.label\" \n :value=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n :key=\"index\"\n />\n#else\n <el-option label=\"请选择\" value=\"0\" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"date\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"daterange\"\n range-separator=\"至\"\n start-placeholder=\"开始日期\"\n end-placeholder=\"结束日期\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"datetime\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"datetimerange\"\n range-separator=\"至\"\n start-placeholder=\"开始时间\"\n end-placeholder=\"结束时间\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"state.queryForm.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio \n :label=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n border \n :key=\"index\"\n >\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>\n ${field.fieldComment}\n </el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input \n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" \n v-model=\"state.queryForm.${field.attrName}\" \n />\n </el-form-item>\n#end\n#end\n <el-form-item>\n <el-button icon=\"search\" type=\"primary\" @click=\"getDataList\">\n 查询\n </el-button>\n <el-button icon=\"Refresh\" @click=\"resetQuery\">重置</el-button>\n </el-form-item>\n </el-form>\n </el-row>\n#end\n\n <!-- 操作按钮区域 -->\n <el-row>\n <div class=\"mb8\" style=\"width: 100Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (10,'表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','表单V2026001','<template>\n <el-dialog :title=\"form.${pk.attrName} ? \'编辑\' : \'新增\'\" v-model=\"visible\"\n :close-on-click-modal=\"false\" draggable>\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" label-width=\"90px\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetime\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"daterange\" range-separator=\"至\" start-placeholder=\"开始日期\" end-placeholder=\"结束日期\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (11,'主子ServiceV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','主子ServiceV2026001','package ${package}.${moduleName}.service;\n\nimport com.github.yulichang.extension.mapping.base.MPJDeepService;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\n\npublic interface ${ClassName}Service extends MPJDeepService<${ClassName}Entity> {\n Boolean saveDeep(${ClassName}Entity ${className});\n\n Boolean updateDeep(${ClassName}Entity ${className});\n\n Boolean removeDeep(Long[] ids);\n\n Boolean removeChild(Long[] ids);\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (12,'主子ServiceImplV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','主子ServiceImplV2026001','package ${package}.${moduleName}.service.impl;\n\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport org.springframework.stereotype.Service;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${package}.${moduleName}.mapper.${ChildClassName}Mapper;\nimport org.springframework.transaction.annotation.Transactional;\nimport lombok.RequiredArgsConstructor;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n private final ${ChildClassName}Mapper ${childClassName}Mapper;\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean saveDeep(${ClassName}Entity ${className}) {\n baseMapper.insert(${className});\n for (${ChildClassName}Entity ${childClassName} : ${className}.get${ChildClassName}List()) {\n ${childClassName}.$str.setProperty($childField)(${className}.$str.getProperty($mainField)());\n ${childClassName}Mapper.insert( ${childClassName});\n }\n\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean updateDeep(${ClassName}Entity ${className}) {\n baseMapper.updateById(${className});\n for (${ChildClassName}Entity ${childClassName} : ${className}.get${ChildClassName}List()) {\n#set($getChildPkName=$str.getProperty(${pk.attrName}))\n if (Objects.isNull(${childClassName}.$getChildPkName())) {\n ${childClassName}.$str.setProperty($childField)(${className}.$str.getProperty($mainField)());\n ${childClassName}Mapper.insert(${childClassName});\n } else {\n ${childClassName}Mapper.updateById(${childClassName});\n }\n }\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeDeep(Long[] ids) {\n baseMapper.deleteBatchIds(CollUtil.toList(ids));\n ${childClassName}Mapper.delete(Wrappers.<${ChildClassName}Entity>lambdaQuery().in(${ChildClassName}Entity::$str.getProperty($childField), ids));\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeChild(Long[] ids) {\n ${childClassName}Mapper.deleteBatchIds(CollUtil.toList(ids));\n return Boolean.TRUE;\n }\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (13,'主实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','主实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\nimport $import;\n#end\nimport org.apache.fesod.sheet.annotation.ExcelIgnore;\nimport com.github.yulichang.annotation.EntityMapping;\nimport java.util.List;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(\"${tableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n @TableField(typeHandler = JacksonTypeHandler.class)\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n @ExcelIgnore\n @TableField(exist = false)\n @EntityMapping(thisField = \"$mainField\", joinField = \"$childField\")\n private List<${ChildClassName}Entity> ${childClassName}List;\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (14,'MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV2026001','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (15,'Mapper.xmlV2026001','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV2026001','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (16,'权限菜单V2026001','${backendPath}/menu/${functionName}_menu.sql','权限菜单V2026001','-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (17,'api.tsV2026001','${frontendPath}/src/api/${moduleName}/${functionName}.ts','api.tsV2026001','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n\n#if($ChildClassName)\n// ========== 子表相关接口 ==========\n\n/**\n * 删除子表数据\n * @param ids - 要删除的子表数据ID数组\n * @returns Promise<操作结果>\n */\nexport function delChildObj(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/child\',\n method: \'delete\',\n data: ids\n })\n}\n#end\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (18,'子实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ChildClassName}Entity.java','子实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\n#if($isChildTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isChildTenant)\n@TenantTable\n#end\n@TableName(\"${childTableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${childTableName}\")\npublic class ${ChildClassName}Entity extends Model<${ChildClassName}Entity> {\n\n#foreach ($field in $childFieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end \n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (19,'主子ControllerV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','主子ControllerV2026001','package ${package}.${moduleName}.controller;\n\n#if($queryList)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"分页查询\" , description = \"分页查询\" )\n @GetMapping(\"/page\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#foreach ($field in $queryList)\n#set($getAttrName=$str.getProperty($field.attrName))\n#set($var=\"${className}.$getAttrName()\")\n#if($field.attrType == \'String\')\n#set($expression=\"StrUtil.isNotBlank\")\n#else\n#set($expression=\"Objects.nonNull\")\n#end\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n if (ArrayUtil.isNotEmpty(${className}.${getAttrName}Range())) {\n wrapper.between(${ClassName}Entity::$getAttrName, ${className}.${getAttrName}Range()[0], ${className}.${getAttrName}Range()[1]);\n }\n#elseif($field.queryType == \'=\')\n wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'like\' )\n wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'!-\' )\n wrapper.ne($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>\' )\n wrapper.gt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<\' )\n wrapper.lt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>=\' )\n wrapper.ge($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<=\' )\n wrapper.le($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'left like\' )\n wrapper.likeLeft($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'right like\' )\n wrapper.likeRight($expression($var),${ClassName}Entity::$getAttrName,$var);\n#end\n#end\n return R.ok(${className}Service.page(page, wrapper));\n }\n\n\n /**\n * 通过条件查询${tableComment}\n * @param ${className} 查询条件\n * @return R 对象列表\n */\n @Operation(summary = \"通过条件查询\" , description = \"通过条件查询对象\" )\n @GetMapping(\"/details\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (20,'主子表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','主子表单V2026001','<template>\n <el-drawer :title=\"form.${pk.attrName} ? (detail ? \'详情\' : \'编辑\') : \'添加\'\" v-model=\"visible\" size=\"50%\">\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" :disabled=\"detail\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetime\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"daterange\" range-separator=\"至\" start-placeholder=\"开始日期\" end-placeholder=\"结束日期\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldNaLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (21,'主子表格V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','主子表格V2026001','<template>\n <div class=\"layout-padding\">\n <div class=\"layout-padding-auto layout-padding-view\">\n#if($queryList)\n <el-row v-show=\"showSearch\">\n <el-form :model=\"state.queryForm\" ref=\"queryRef\" :inline=\"true\" @keyup.enter=\"getDataList\">\n#foreach($field in $queryList)\n#if($field.queryFormType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"state.queryForm.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option \n :label=\"item.label\" \n :value=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n :key=\"index\">\n </el-option>\n#else\n <el-option label=\"请选择\">0</el-option>\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"date\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n :value-format=\"dateStr\"\n v-model=\"state.queryForm.${field.attrName}\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"daterange\"\n range-separator=\"至\"\n start-placeholder=\"开始日期\"\n end-placeholder=\"结束日期\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"datetime\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n :value-format=\"dateTimeStr\"\n v-model=\"state.queryForm.${field.attrName}\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"datetimerange\"\n range-separator=\"至\"\n start-placeholder=\"开始时间\"\n end-placeholder=\"结束时间\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"state.queryForm.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio \n :label=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n border \n :key=\"index\">\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input \n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" \n v-model=\"state.queryForm.${field.attrName}\"\n style=\"max-width: 180px\" \n />\n </el-form-item>\n#end\n#end\n <el-form-item>\n <el-button icon=\"search\" type=\"primary\" @click=\"getDataList\">\n 查询\n </el-button>\n <el-button icon=\"Refresh\" @click=\"resetQuery\">重置</el-button>\n </el-form-item>\n </el-form>\n </el-row>\n#end\n <el-row>\n <div class=\"mb8\" style=\"width: 100%\">\n <el-button \n icon=\"folder-adLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (22,'子MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ChildClassName}Mapper.java','子MapperV2026001','package ${package}.${moduleName}.mapper;\n\nimport ${package}.common.data.datascope.PigxBaseMapper;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ChildClassName}Mapper extends PigxBaseMapper<${ChildClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (23,'树形ControllerV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','树形ControllerV2026001','package ${package}.${moduleName}.controller;\n\n#if($queryList)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 获取树形列表\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"获取树形列表\" , description = \"获取树形列表\" )\n @GetMapping(\"/tree\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R get${ClassName}Tree(@ParameterObject ${ClassName}Entity ${className}) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#foreach ($field in $queryList)\n#set($getAttrName=$str.getProperty($field.attrName))\n#set($var=\"${className}.$getAttrName()\")\n#if($field.attrType == \'String\')\n#set($expression=\"StrUtil.isNotBlank\")\n#else\n#set($expression=\"Objects.nonNull\")\n#end\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n if (ArrayUtil.isNotEmpty(${className}.${getAttrName}Range())) {\n wrapper.between(${ClassName}Entity::$getAttrName, ${className}.${getAttrName}Range()[0], ${className}.${getAttrName}Range()[1]);\n }\n#elseif($field.queryType == \'=\')\n wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'like\' )\n wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'!-\' )\n wrapper.ne($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>\' )\n wrapper.gt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<\' )\n wrapper.lt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>=\' )\n wrapper.ge($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<=\' )\n wrapper.le($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'left like\' )\n wrapper.likeLeft($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'right like\' )\n wrapper.likeRight($expression($var),${ClassName}Entity::$getAttrName,$var);\n#end\n#end\n return R.ok(${className}Service.buildTree(wrapper));\n }\n\n /**\n * 通过条件查询${tableComment}\n * @param ${className} 查询条件\n * @return R 对象列表\n */\n @Operation(summary = \"通过条件查询\" , description = \"通过条件查询对象\" )\n @GetMapping(\"/details\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (24,'树形ServiceV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','树形ServiceV2026001','package ${package}.${moduleName}.service;\n\nimport cn.hutool.core.lang.tree.Tree;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.extension.service.IService;\nimport ${entityClassName};\n\nimport java.util.List;\n\n/**\n * ${tableComment} Service接口\n *\n * @author ${author}\n * @date ${datetime}\n */\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n List<Tree<${pk.attrType}>> buildTree(LambdaQueryWrapper<${ClassName}Entity> wrapper);\n\n /**\n * 递归删除节点及其子节点\n * @param ids 要删除的节点ID列表\n * @return 删除结果\n */\n boolean removeBatchByIds(List<${pk.attrType}> ids);\n} ','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (25,'树形ServiceImplV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','树形ServiceImplV2026001','package ${package}.${moduleName}.service.impl;\n\nimport cn.hutool.core.collection.CollUtil;\nimport cn.hutool.core.lang.tree.Tree;\nimport cn.hutool.core.lang.tree.TreeNode;\nimport cn.hutool.core.lang.tree.TreeUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport jakarta.validation.constraints.NotNull;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.stream.Collectors;\n\n/**\n * ${tableComment} Service实现类\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n @Override\n public List<Tree<${pk.attrType}>> buildTree(LambdaQueryWrapper<${ClassName}Entity> wrapper) {\n // 查询所有数据\n List<${ClassName}Entity> allList = list(wrapper);\n \n if (CollUtil.isEmpty(allList)) {\n return new ArrayList<>();\n }\n\n // 转换为TreeNode\n List<TreeNode<${pk.attrType}>> collect = allList.stream().map(getNodeFunction()).toList();\n\n // 使用TreeUtil构建树形结构,根节点ID为0\n#if($pk.attrType == \'Long\')\n return TreeUtil.build(collect, 0L);\n#else\n return TreeUtil.build(collect, 0);\n#end\n }\n\n /**\n * 获取TreeNode转换函数\n * @return TreeNode转换函数\n */\n @NotNull\n private Function<${ClassName}Entity, TreeNode<${pk.attrType}>> getNodeFunction() {\n return entity -> {\n TreeNode<${pk.attrType}> node = new TreeNode<>();\n node.setId(entity.$str.getProperty($pk.attrName)());\n node.setName(entity.$str.getProperty($nameField)());\n node.setParentId(entity.$str.getProperty($parentField)() != null ? entity.$str.getProperty($parentField)() : 0L);\n\n // 扩展属性\n Map<String, Object> extra = new HashMap<>();\n#foreach($field in $fieldList)\n extra.put(${ClassName}Entity.Fields.${field.attrName}, entity.$str.getProperty($field.attrName)());\n#end\n node.setExtra(extra);\n return node;\n };\n }\n\n /**\n * 递归删除节点及其子节点\n * @param ids 要删除的节点ID列表\n * @return 删除结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public boolean removeBatchByIds(List<${pk.attrType}> ids) {\n if (CollUtil.isEmpty(ids)) {\n return true;\n }\n\n // 获取所有要删除的ID(包括子节点)\n List<${pk.attrType}> allDeleteIds = new ArrayList<>(ids);\n \n for (${pk.attrType} id : ids) {\n List<${pk.attrType}> childIds = getChildIdsRecursive(id);\n allDeleteIds.addAll(childIds);\n }\n\n // 去重\n allDeleteIds = allDeleteIds.stream().distinct().collect(Collectors.toList());\n\n // 批量删除\n return super.removeBatchByIds(allDeleteIds);\n }\n\n /**\n * 递归获取所有子节点ID\n * @param parentId 父节点ID\n * @return 子节点ID列表\n */\n private List<${pk.attrType}> getChildIdsRecursive(${pk.attrType} parentId) {\n List<${pk.attrType}> childIds = new ArrayList<>();\n \n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n wrapper.eq(${ClassName}Entity::$str.getProperty($parentField), parentId);\n wrapper.select(${ClassName}Entity::$str.getProperty($pk.attrName));\n \n List<${ClassName}Entity> children = list(wrapper);\n \n for (${ClassName}Entity child : children) {\n ${pk.attrType} childId = child.$str.getProperty($pk.attrName)();\n childIds.add(childId);\n // 递归获取子节点的子节点\n childIds.addAll(getChildIdsRecursive(childId));\n }\n \n return childIds;\n }\n} ','2026-04-08 17:38Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (26,'树形实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','树形实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\nimport lombok.experimental.FieldNameConstants;\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@FieldNameConstants\n@TableName(\"${tableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (27,'MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV2026001','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (28,'Mapper.xmlV2026001','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV2026001','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (29,'权限菜单V2026001','${backendPath}/menu/${functionName}_menu.sql','权限菜单V2026001','-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (30,'树形api.tsV2026001','${frontendPath}/src/api/${moduleName}/${functionName}.ts','树形api.tsV2026001','import request from \"/@/utils/request\"\n\n// ========== 树形表格CRUD接口 ==========\n\n/**\n * 获取树形列表数据\n * @param query - 查询参数对象\n * @returns Promise<树形数据>\n */\nexport function fetchTreeList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据(递归删除子节点)\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (31,'树形表格V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','树形表格V2026001','<template>\n <div class=\"layout-padding\">\n <div class=\"layout-padding-auto layout-padding-view\">\n#if($queryList)\n <!-- 查询表单区域 -->\n <el-row v-show=\"showSearch\">\n <el-form :model=\"state.queryForm\" ref=\"queryRef\" :inline=\"true\" @keyup.enter=\"getDataList\">\n#foreach($field in $queryList)\n#if($field.queryFormType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"state.queryForm.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option \n :label=\"item.label\" \n :value=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n :key=\"index\"\n />\n#else\n <el-option label=\"请选择\" value=\"0\" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker \n type=\"date\" \n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" \n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"datetime\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"daterange\"\n range-separator=\"至\"\n start-placeholder=\"开始日期\"\n end-placeholder=\"结束日期\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"datetimerange\"\n range-separator=\"至\"\n start-placeholder=\"开始时间\"\n end-placeholder=\"结束时间\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"state.queryForm.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio \n :label=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n border \n :key=\"index\"\n >\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>\n ${field.fieldComment}\n </el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input \n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" \n v-model=\"state.queryForm.${field.attrName}\" \n />\n </el-form-item>\n#end\n#end\n <el-form-item>\n <el-button icon=\"search\" type=\"primary\" @click=\"getDataList\">\n 查询\n </el-button>\n <el-button icon=\"Refresh\" @click=\"resetQuery\">重置</el-button>\n </el-form-item>\n </el-form>\n </el-row>\n#end\n\n <!-- 操作按钮区域 -->\n <el-row>\n <div class=\"mb8\" stLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (32,'树形表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','树形表单V2026001','<template>\n <el-dialog :title=\"form.${pk.attrName} ? \'编辑\' : \'新增\'\" v-model=\"visible\"\n :close-on-click-modal=\"false\" draggable>\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" formDialogRef label-width=\"90px\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n <!-- 父级节点选择 -->\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n <el-form-item label=\"父级节点\" prop=\"${parentField}\">\n <el-tree-select\n v-model=\"form.${parentField}\"\n :data=\"parentNodes\"\n :props=\"treeSelectProps\"\n check-strictly\n :render-after-expand=\"false\"\n placeholder=\"请选择父级节点\"\n style=\"width: 100%\"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${parentField})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetime\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${fieLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (33,'ControllerV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','ControllerV2026001','package ${package}.${moduleName}.controller;\n\nimport cn.hutool.core.util.StrUtil;\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($childFieldGetter = $str.getProperty($childField))\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"分页查询\" , description = \"分页查询\" )\n @GetMapping(\"/page\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#foreach ($field in $queryList)\n#set($getAttrName=$str.getProperty($field.attrName))\n#set($var=\"${className}.$getAttrName()\")\n#if($field.attrType == \'String\')\n#set($expression=\"StrUtil.isNotBlank\")\n#else\n#set($expression=\"Objects.nonNull\")\n#end\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n if (ArrayUtil.isNotEmpty(${className}.${getAttrName}Range())) {\n wrapper.between(${ClassName}Entity::$getAttrName, ${className}.${getAttrName}Range()[0], ${className}.${getAttrName}Range()[1]);\n }\n#elseif($field.queryType == \'=\')\n wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'like\' )\n wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'!-\' )\n wrapper.ne($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>\' )\n wrapper.gt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<\' )\n wrapper.lt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>=\' )\n wrapper.ge($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<=\' )\n wrapper.le($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'left like\' )\n wrapper.likeLeft($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'right like\' )\n wrapper.likeRight($expression($var),${ClassName}Entity::$getAttrName,$var);\n#end\n#end\n#if($childField)\n if (Objects.nonNull(${className}.$childFieldGetter())) {\n wrapper.eq(${ClassName}Entity::$str.getProperty($childField), ${className}.$childFieldGetter());\n }\n#end\n return R.ok(${className}Service.pLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (34,'ServiceV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','ServiceV2026001','package ${package}.${moduleName}.service;\n\nimport cn.hutool.core.lang.tree.Tree;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.extension.service.IService;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\n\nimport java.util.List;\n\n/**\n * ${tableComment} Service接口\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n List<Tree<${childPkField.attrType}>> buildTree(LambdaQueryWrapper<${ChildClassName}Entity> wrapper);\n\n /**\n * 获取树节点详情\n * @param ${childClassName} 树节点查询对象\n * @return 树节点详情列表\n */\n List<${ChildClassName}Entity> getTreeDetails(${ChildClassName}Entity ${childClassName});\n\n /**\n * 保存树节点\n * @param ${childClassName} 树节点对象\n * @return 保存结果\n */\n Boolean saveTree(${ChildClassName}Entity ${childClassName});\n\n /**\n * 更新树节点\n * @param ${childClassName} 树节点对象\n * @return 更新结果\n */\n Boolean updateTree(${ChildClassName}Entity ${childClassName});\n\n /**\n * 批量删除树节点\n * @param ids 树节点ID列表\n * @return 删除结果\n */\n Boolean removeTreeByIds(${childPkField.attrType}[] ids);\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (35,'ServiceImplV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','ServiceImplV2026001','package ${package}.${moduleName}.service.impl;\n\nimport cn.hutool.core.collection.CollUtil;\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.lang.tree.Tree;\nimport cn.hutool.core.lang.tree.TreeNode;\nimport cn.hutool.core.lang.tree.TreeUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ChildClassName}Mapper;\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\nimport java.util.function.Function;\n\n/**\n * ${tableComment} Service实现类\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#set($childPkGetter = $str.getProperty($childPkField.attrName))\n#break\n#end\n#end\n#set($parentGetter = $str.getProperty($parentField))\n#set($childFieldGetter = $str.getProperty($childField))\n#if($childPkField.attrType == \'Long\')\n#set($treeRootId = \'0L\')\n#elseif($childPkField.attrType == \'String\')\n#set($treeRootId = \'\"0\"\')\n#else\n#set($treeRootId = \'0\')\n#end\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n private final ${ChildClassName}Mapper ${childClassName}Mapper;\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n @Override\n public List<Tree<${childPkField.attrType}>> buildTree(LambdaQueryWrapper<${ChildClassName}Entity> wrapper) {\n List<${ChildClassName}Entity> allList = ${childClassName}Mapper.selectList(wrapper);\n\n if (CollUtil.isEmpty(allList)) {\n return new ArrayList<>();\n }\n\n List<TreeNode<${childPkField.attrType}>> collect = allList.stream().map(getNodeFunction()).toList();\n return TreeUtil.build(collect, ${treeRootId});\n }\n\n /**\n * 获取树节点详情\n * @param ${childClassName} 树节点查询对象\n * @return 树节点详情列表\n */\n @Override\n public List<${ChildClassName}Entity> getTreeDetails(${ChildClassName}Entity ${childClassName}) {\n return ${childClassName}Mapper.selectList(Wrappers.query(${childClassName}));\n }\n\n /**\n * 保存树节点\n * @param ${childClassName} 树节点对象\n * @return 保存结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean saveTree(${ChildClassName}Entity ${childClassName}) {\n ${childClassName}.$str.setProperty($parentField)(validateParentRelation(null, ${childClassName}.$str.getProperty($parentField)()));\n return ${childClassName}Mapper.insert(${childClassName}) > 0;\n }\n\n /**\n * 更新树节点\n * @param ${childClassName} 树节点对象\n * @return 更新结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean updateTree(${ChildClassName}Entity ${childClassName}) {\n ${childClassName}.$str.setProperty($parentField)(validateParentRelation(${childClassName}.$str.getProperty($childPkField.attrName)(), ${childClassName}.$str.getProperty($parentField)()));\n return ${childClassName}Mapper.updateById(${childClassName}) > 0;\n }\n\n /**\n * 批量删除树节点\n * @param ids 树节点ID列表\n * @return 删除结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeTreeByIds(${childPkField.attrType}[] ids) {\n if (ArrayUtil.isEmpty(ids)) {\n return Boolean.TRUE;\n }\n\n for (${childPkField.attrType} id : ids) {\n if (hasChildNodes(id)) {\n throw new RuntimeException(\"当前节点存在子节点,不能删除\");\n }\n if (hasMainRecords(id)) {\n throw new RuntimeException(\"当前节点已关联主表数据,不能删除\");\n }\n }\n\n return ${childClassName}Mapper.deleteBatchLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (36,'实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(\"${tableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (37,'MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV2026001','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (38,'Mapper.xmlV2026001','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV2026001','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (39,'子实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ChildClassName}Entity.java','子实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\n#if($isChildTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isChildTenant)\n@TenantTable\n#end\n@TableName(\"${childTableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${childTableName}\")\npublic class ${ChildClassName}Entity extends Model<${ChildClassName}Entity> {\n\n#foreach ($field in $childFieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end \n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (40,'子MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ChildClassName}Mapper.java','子MapperV2026001','package ${package}.${moduleName}.mapper;\n\nimport ${package}.common.data.datascope.PigxBaseMapper;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ChildClassName}Mapper extends PigxBaseMapper<${ChildClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (41,'权限菜单V2026001','${backendPath}/menu/${functionName}_menu.sql','权限菜单V2026001','-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (42,'api.tsV2026001','${frontendPath}/src/api/${moduleName}/${functionName}.ts','api.tsV2026001','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 树形CRUD接口 ==========\n\n/**\n * 获取树形列表数据\n * @param query - 查询参数对象\n * @returns Promise<树形数据>\n */\nexport function fetchTreeList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 获取树节点详情\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<树节点详情>\n */\nexport function getTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 新增树节点\n * @param obj - 要新增的树节点对象\n * @returns Promise<操作结果>\n */\nexport function addTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 更新树节点\n * @param obj - 要更新的树节点对象\n * @returns Promise<操作结果>\n */\nexport function putTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'put\',\n data: obj\n })\n}\n\n/**\n * 删除树节点\n * @param ids - 要删除的树节点ID数组\n * @returns Promise<操作结果>\n */\nexport function delTreeObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'delete\',\n data: ids\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n *\n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (43,'表格V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','表格V2026001','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n<template>\n <div class=\"layout-padding\">\n <splitpanes>\n <pane size=\"15\">\n <div class=\"layout-padding-auto layout-padding-view\">\n <el-scrollbar>\n <div class=\"mb8\" style=\"display: flex; align-items: center; justify-content: space-between;\">\n <span style=\"font-weight: 500;\">左侧节点</span>\n <div>\n <el-tooltip :content=\"currentTreeId ? \'新增子节点\' : \'新增根节点\'\" placement=\"top\">\n <el-button link type=\"primary\" icon=\"FolderAdd\" @click=\"handleAddTree\" />\n </el-tooltip>\n </div>\n </div>\n <el-tree\n ref=\"treeRef\"\n :data=\"treeData\"\n :props=\"treeProps\"\n node-key=\"${childPkField.attrName}\"\n highlight-current\n default-expand-all\n :expand-on-click-node=\"false\"\n @node-click=\"handleTreeNodeClick\"\n >\n <template #default=\"{ node, data }\">\n <span style=\"flex: 1; display: flex; align-items: center; justify-content: space-between;\">\n <span>{{ node.label }}</span>\n <span v-if=\"currentTreeId === data.${childPkField.attrName}\" style=\"margin-left: 8px;\">\n <el-tooltip content=\"编辑\" placement=\"top\">\n <el-button link type=\"primary\" icon=\"Edit\" size=\"small\" @click.stop=\"handleEditTree\" />\n </el-tooltip>\n <el-tooltip content=\"删除\" placement=\"top\">\n <el-button link type=\"danger\" icon=\"Delete\" size=\"small\" @click.stop=\"handleDeleteTree\" />\n </el-tooltip>\n </span>\n </span>\n </template>\n </el-tree>\n </el-scrollbar>\n </div>\n </pane>\n <pane class=\"ml8\">\n <div class=\"layout-padding-auto layout-padding-view\">\n#if($queryList)\n <el-row v-show=\"showSearch\">\n <el-form :model=\"state.queryForm\" ref=\"queryRef\" :inline=\"true\" @keyup.enter=\"getDataList\">\n#foreach($field in $queryList)\n#if($field.attrName != ${childField})\n#if($field.queryFormType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"state.queryForm.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option \n :label=\"item.label\" \n :value=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n :key=\"index\"\n />\n#else\n <el-option label=\"请选择\" value=\"0\" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"date\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"daterange\"\n range-separator=\"至\"\n start-placeholder=\"开始日期\"\n end-placeholder=\"结束日期\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"datetime\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (44,'树表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/tree-form.vue','树表单V2026001','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($fieldDict=[])\n#foreach($field in $childFieldList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n<template>\n <el-dialog :title=\"form.${childPkField.attrName} ? \'编辑\' : \'新增\'\" v-model=\"visible\"\n :close-on-click-modal=\"false\" draggable>\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" label-width=\"90px\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n <el-form-item label=\"父级节点\" prop=\"${parentField}\">\n <el-tree-select\n v-model=\"form.${parentField}\"\n :data=\"parentNodes\"\n :props=\"treeSelectProps\"\n check-strictly\n :render-after-expand=\"false\"\n placeholder=\"请选择父级节点\"\n style=\"width: 100%\"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $childFieldList)\n#if($field.attrName != ${childPkField.attrName} && $field.attrName != ${parentField})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetime\')\n <el-form-item label=\Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (45,'主表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','主表单V2026001','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($relationFieldLabel = $childField)\n#foreach($field in $fieldList)\n#if($field.attrName == $childField)\n#if($field.fieldComment)\n#set($relationFieldLabel = $field.fieldComment)\n#else\n#set($relationFieldLabel = $field.attrName)\n#end\n#break\n#end\n#end\n#set($fieldDict=[])\n#foreach($field in $formList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n<template>\n <el-dialog :title=\"form.${pk.attrName} ? \'编辑\' : \'新增\'\" v-model=\"visible\"\n :close-on-click-modal=\"false\" draggable>\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" label-width=\"90px\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n <el-form-item label=\"${relationFieldLabel}\" prop=\"${childField}\">\n <el-tree-select\n v-model=\"form.${childField}\"\n :data=\"treeNodes\"\n :props=\"treeSelectProps\"\n check-strictly\n :render-after-expand=\"false\"\n placeholder=\"请选择${relationFieldLabel}\"\n style=\"width: 100%\"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${childField})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fiLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (1,'ControllerV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','ControllerV202611','## 查询条件按需导入:字符串字段和组织关键字用 StrUtil,其余类型用 Objects;复选框与日期范围两者都不用\n#set($needStrUtil = false)\n#set($needObjects = false)\n#foreach($field in $queryList)\n#if($field.formType == \'checkbox\' || $field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#elseif($field.formType.startsWith(\'org-\') || $field.attrType == \'String\')\n#set($needStrUtil = true)\n#else\n#set($needObjects = true)\n#end\n#end\n#set($hasOrgQuery = false)\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrgQuery = true)\n#end\n#end\n## 组织字段以 [{id,name}] JSON 存储,按 ${attrName}Keyword 对整列模糊查询,分页和导出共用\n#macro(orgKeywordParams)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), @RequestParam(required = false) String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordDecl)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordArgs)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordFilters)\n#if($hasOrgQuery)\n // 组织字段对整列 JSON 做 LIKE:关键字为数字或 id/name 时会误命中,需精确匹配时改用数据库 JSON 函数\n#end\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n wrapper.like(StrUtil.isNotBlank(${field.attrName}Keyword), ${ClassName}Entity::$str.getProperty($field.attrName), ${field.attrName}Keyword);\n#end\n#end\n#end\n#set($permissionPrefix = \"${moduleName}_${functionName}\")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\npackage ${package}.${moduleName}.controller;\n\n#if($needStrUtil)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n#if($needObjects)\nimport java.util.Objects;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"分页查询\" , description = \"分页查询\" )\n @GetMapping(\"/page\" )\n #if($isSpringBoot3)\n @HasPermission(\"${permissionPrefix}_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'${permissionPrefix}_view\')\" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}#orgKeywordParams()) {\n return R.ok(${className}Service.page(page, buildQueryWrapper(${className}#orgKeywordArgs())));\n }\n\n /**\n * 列表与导出共用的查询条件,保证导出结果与列表一致\n */\n private LambdaQueryWrapper<${ClassName}Entity> buildQueryWrapper(${ClassName}Entity ${className}#orgKeywordDecl()) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (2,'ServiceV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','ServiceV202611','package ${package}.${moduleName}.service;\n\nimport com.baomidou.mybatisplus.spring.service.IService;\nimport ${entityClassName};\n\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (3,'ServiceImplV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','ServiceImplV202611','package ${package}.${moduleName}.service.impl;\n\nimport com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport org.springframework.stereotype.Service;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (4,'实体V202611','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','实体V202611','#set($hasOrg = false)\n#foreach($field in $fieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\npackage ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.spring.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($hasOrg)\nimport com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;\nimport ${package}.common.core.util.OrgRef;\nimport org.apache.fesod.sheet.annotation.ExcelIgnore;\nimport java.util.List;\n#end\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\n#if(!$import.startsWith(\'java.lang.\'))\nimport $import;\n#end\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(value = \"${tableName}\"#if($hasOrg), autoResultMap = true#end)\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.formType.startsWith(\'org-\'))\n @TableField(typeHandler = JacksonTypeHandler.class#if($field.autoFill == \'INSERT\' || $field.autoFill == \'INSERT_UPDATE\' || $field.autoFill == \'UPDATE\'), fill = FieldFill.${field.autoFill}#end)\n @ExcelIgnore\n#elseif($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType.startsWith(\'org-\'))\n private List<OrgRef> $field.attrName;\n#elseif($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (5,'MapperV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV202611','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (6,'Mapper.xmlV202611','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV202611','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"#if($field.formType.startsWith(\'org-\')) typeHandler=\"com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler\"#end/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (7,'权限菜单V202611','${backendPath}/menu/${functionName}_menu.sql','权限菜单V202611','#set($permissionPrefix = \"${moduleName}_${functionName}\")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'${permissionPrefix}_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'${permissionPrefix}_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'${permissionPrefix}_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'${permissionPrefix}_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'${permissionPrefix}_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (8,'api.tsV202611','${frontendPath}/src/api/${moduleName}/${functionName}.ts','api.tsV202611','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n\n#if($ChildClassName)\n// ========== 子表相关接口 ==========\n\n/**\n * 删除子表数据\n * @param ids - 要删除的子表数据ID数组\n * @returns Promise<操作结果>\n */\nexport function delChildObj(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/child\',\n method: \'delete\',\n data: ids\n })\n}\n#end\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (9,'表格V202611','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','表格V202611','## 有字典字段时才导入 useDict\n#set($hasDictField = false)\n#foreach($field in $queryList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($permissionPrefix = "${moduleName}_${functionName}")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n<template>\n <div class="layout-padding">\n <div class="layout-padding-auto layout-padding-view">\n#if($queryList)\n <!-- 查询表单区域 -->\n <el-row v-show="showSearch">\n <el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))#set($queryKey = "${field.attrName}Keyword")#else#set($queryKey = $field.attrName)#end\n#if($field.queryFormType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-select v-model="state.queryForm.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option \n :label="item.label" \n :value="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n :key="index"\n />\n#else\n <el-option label="请选择" value="0" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-date-picker\n type="date"\n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"\n v-model="state.queryForm.${field.attrName}"\n :value-format="dateStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-picker\n type="daterange"\n range-separator="至"\n start-placeholder="开始日期"\n end-placeholder="结束日期"\n v-model="state.queryForm.${field.attrName}Range"\n :value-format="dateStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-date-picker\n type="datetime"\n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"\n v-model="state.queryForm.${field.attrName}"\n :value-format="dateTimeStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-picker\n type="datetimerange"\n range-separator="至"\n start-placeholder="开始时间"\n end-placeholder="结束时间"\n v-model="state.queryForm.${field.attrName}Range"\n :value-format="dateTimeStr"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-radio-group v-model="state.queryForm.${field.attrName}">\n#if($field.fieldDict)\n <el-radio \n :label="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n border \n :key="index"\n >\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label="${field.fieldComment}" border>\n ${field.fieldComment}\n </el-radio>\n#end\n </el-rLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (10,'表单V202611','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','表单V202611','## 有字典字段时才导入 useDict\n#set($hasDictField = false)\n#foreach($field in $formList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#set($hasDuplicate = false)\n#foreach($field in $formList)\n#if($field.formValidator == \'duplicate\')\n#set($hasDuplicate = true)\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($hasOrg = false)\n#foreach($field in $formList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\n<template>\n <el-dialog :title="form.${pk.attrName} ? \'编辑\' : \'新增\'" v-model="visible"\n :close-on-click-modal="false" draggable>\n <el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading">\n <el-row :gutter="24">\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName})\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n#if($field.formType.startsWith(\'org-\'))\n#set($orgType = $field.formType.replace(\'org-\', \'\').replace(\'-multiple\', \'\'))\n <el-form-item label="${field.fieldComment}" prop="${field.attrName}">\n <OrgSelect v-model="form.${field.attrName}" value-type="item" type="${orgType}" :multiple="#if($field.formType.endsWith(\'-multiple\'))true#else false#end" label="${field.fieldComment}" :disabled="loading" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'switch\')\n#switchValues($field)\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-switch :model-value="String(form.${field.attrName}) === String($switchOn)" @change="(checked) => (form.${field.attrName} = checked ? $switchOn : $switchOff)" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'text\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input type="textarea" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-select v-model="form.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option :value="item.value" :label="item.label" v-for="(item, index) in ${field.fieldDict}" :key="index"></el-option>\n#else\n <el-option label="请选择" value="0"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-radio-group v-model="form.${field.attrName}">\n#if($field.fieldDict)\n <el-radio :label="item.value" v-for="(item, index) in ${field.fieldDict}" border :key="index">{{ item.label }}</el-radio>\n#else\n <el-radio label="${field.fieldComment}" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-checkbox-group v-model="form.${field.attrName}">\n#if($field.fieldDict)\n <el-checkbox :label="item.value" v-for="(item, index) in ${field.fieldDict}" :key="index">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label="启用"Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (11,'主子ServiceV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','主子ServiceV202611','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPk = $field)\n#end\n#end\npackage ${package}.${moduleName}.service;\n\nimport com.github.yulichang.extension.mapping.base.MPJDeepService;\nimport ${entityClassName};\n\npublic interface ${ClassName}Service extends MPJDeepService<${ClassName}Entity> {\n Boolean saveDeep(${ClassName}Entity ${className});\n\n Boolean updateDeep(${ClassName}Entity ${className});\n\n Boolean removeDeep(${pk.attrType}[] ids);\n\n Boolean removeChild(${childPk.attrType}[] ids);\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (12,'主子ServiceImplV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','主子ServiceImplV202611','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPk = $field)\n#end\n#end\npackage ${package}.${moduleName}.service.impl;\n\nimport com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport org.springframework.stereotype.Service;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${package}.${moduleName}.mapper.${ChildClassName}Mapper;\nimport org.springframework.transaction.annotation.Transactional;\nimport lombok.RequiredArgsConstructor;\nimport java.util.Objects;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n private final ${ChildClassName}Mapper ${childClassName}Mapper;\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean saveDeep(${ClassName}Entity ${className}) {\n baseMapper.insert(${className});\n for (${ChildClassName}Entity ${childClassName} : ${className}.get${ChildClassName}List()) {\n ${childClassName}.$str.setProperty($childField)(${className}.$str.getProperty($mainField)());\n ${childClassName}Mapper.insert( ${childClassName});\n }\n\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean updateDeep(${ClassName}Entity ${className}) {\n baseMapper.updateById(${className});\n for (${ChildClassName}Entity ${childClassName} : ${className}.get${ChildClassName}List()) {\n#set($getChildPkName=$str.getProperty(${childPk.attrName}))\n if (Objects.isNull(${childClassName}.$getChildPkName())) {\n ${childClassName}.$str.setProperty($childField)(${className}.$str.getProperty($mainField)());\n ${childClassName}Mapper.insert(${childClassName});\n } else {\n ${childClassName}Mapper.updateById(${childClassName});\n }\n }\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeDeep(${pk.attrType}[] ids) {\n List<${ClassName}Entity> records = baseMapper.selectBatchIds(CollUtil.toList(ids));\n if (CollUtil.isEmpty(records)) {\n return Boolean.TRUE;\n }\n ${childClassName}Mapper.delete(Wrappers.<${ChildClassName}Entity>lambdaQuery()\n .in(${ChildClassName}Entity::$str.getProperty($childField), records.stream()\n .map(${ClassName}Entity::$str.getProperty($mainField)).collect(Collectors.toList())));\n baseMapper.deleteBatchIds(CollUtil.toList(ids));\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeChild(${childPk.attrType}[] ids) {\n ${childClassName}Mapper.deleteBatchIds(CollUtil.toList(ids));\n return Boolean.TRUE;\n }\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (13,'主实体V202611','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','主实体V202611','#set($hasOrg = false)\n#foreach($field in $fieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\npackage ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.spring.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($hasOrg)\nimport com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;\nimport ${package}.common.core.util.OrgRef;\n#end\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\n#if(!$import.startsWith(\'java.lang.\'))\nimport $import;\n#end\n#end\nimport org.apache.fesod.sheet.annotation.ExcelIgnore;\nimport com.github.yulichang.annotation.EntityMapping;\nimport java.util.List;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(value = \"${tableName}\"#if($hasOrg), autoResultMap = true#end)\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.formType.startsWith(\'org-\'))\n @TableField(typeHandler = JacksonTypeHandler.class#if($field.autoFill == \'INSERT\' || $field.autoFill == \'INSERT_UPDATE\' || $field.autoFill == \'UPDATE\'), fill = FieldFill.${field.autoFill}#end)\n @ExcelIgnore\n#elseif($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType.startsWith(\'org-\'))\n private List<OrgRef> $field.attrName;\n#elseif($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n @TableField(typeHandler = JacksonTypeHandler.class)\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n @ExcelIgnore\n @TableField(exist = false)\n @EntityMapping(thisField = \"$mainField\", joinField = \"$childField\")\n private List<${ChildClassName}Entity> ${childClassName}List;\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (14,'MapperV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV202611','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (15,'Mapper.xmlV202611','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV202611','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"#if($field.formType.startsWith(\'org-\')) typeHandler=\"com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler\"#end/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (16,'权限菜单V202611','${backendPath}/menu/${functionName}_menu.sql','权限菜单V202611','#set($permissionPrefix = \"${moduleName}_${functionName}\")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'${permissionPrefix}_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'${permissionPrefix}_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'${permissionPrefix}_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'${permissionPrefix}_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'${permissionPrefix}_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (17,'api.tsV202611','${frontendPath}/src/api/${moduleName}/${functionName}.ts','api.tsV202611','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n\n#if($ChildClassName)\n// ========== 子表相关接口 ==========\n\n/**\n * 删除子表数据\n * @param ids - 要删除的子表数据ID数组\n * @returns Promise<操作结果>\n */\nexport function delChildObj(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/child\',\n method: \'delete\',\n data: ids\n })\n}\n#end\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (18,'子实体V202611','${entityPath}/src/main/java/${entityPackagePath}/${ChildClassName}Entity.java','子实体V202611','#set($hasOrg = false)\n#foreach($field in $childFieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\npackage ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.spring.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\n#if($isChildTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($hasOrg)\nimport com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;\nimport ${package}.common.core.util.OrgRef;\nimport java.util.List;\n#end\n#set($childImports = [])\n#foreach($field in $childFieldList)\n#if($field.packageName && !$field.packageName.startsWith(\'java.lang.\') && !$childImports.contains($field.packageName))\n#set($void = $childImports.add($field.packageName))\n#end\n#end\n#foreach($import in $childImports)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isChildTenant)\n@TenantTable\n#end\n@TableName(value = \"${childTableName}\"#if($hasOrg), autoResultMap = true#end)\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${childTableName}\")\npublic class ${ChildClassName}Entity extends Model<${ChildClassName}Entity> {\n\n#foreach ($field in $childFieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.formType.startsWith(\'org-\'))\n @TableField(typeHandler = JacksonTypeHandler.class#if($field.autoFill == \'INSERT\' || $field.autoFill == \'INSERT_UPDATE\' || $field.autoFill == \'UPDATE\'), fill = FieldFill.${field.autoFill}#end)\n#elseif($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType.startsWith(\'org-\'))\n private List<OrgRef> $field.attrName;\n#elseif($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end \n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (19,'主子ControllerV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','主子ControllerV202611','## 查询条件按需导入:字符串字段和组织关键字用 StrUtil,其余类型用 Objects;复选框与日期范围两者都不用\n#set($needStrUtil = false)\n#set($needObjects = false)\n#foreach($field in $queryList)\n#if($field.formType == \'checkbox\' || $field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#elseif($field.formType.startsWith(\'org-\') || $field.attrType == \'String\')\n#set($needStrUtil = true)\n#else\n#set($needObjects = true)\n#end\n#end\n#set($hasOrgQuery = false)\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrgQuery = true)\n#end\n#end\n## 组织字段以 [{id,name}] JSON 存储,按 ${attrName}Keyword 对整列模糊查询,分页和导出共用\n#macro(orgKeywordParams)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), @RequestParam(required = false) String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordDecl)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordArgs)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordFilters)\n#if($hasOrgQuery)\n // 组织字段对整列 JSON 做 LIKE:关键字为数字或 id/name 时会误命中,需精确匹配时改用数据库 JSON 函数\n#end\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n wrapper.like(StrUtil.isNotBlank(${field.attrName}Keyword), ${ClassName}Entity::$str.getProperty($field.attrName), ${field.attrName}Keyword);\n#end\n#end\n#end\n#set($permissionPrefix = \"${moduleName}_${functionName}\")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPk = $field)\n#end\n#end\npackage ${package}.${moduleName}.controller;\n\n#if($needStrUtil)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n#if($needObjects)\nimport java.util.Objects;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"分页查询\" , description = \"分页查询\" )\n @GetMapping(\"/page\" )\n #if($isSpringBoot3)\n @HasPermission(\"${permissionPrefix}_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'${permissionPrefix}_view\')\" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}#orgKeywordParams()) {\n return R.ok(${className}Service.page(page, buildQueryWrapper(${className}#orgKeywordArgs())));\n }\n\n /**\n * 列表与导出共用的查询条件,保证导出结果与列表一致\n */\n private LambdaQueryWrapper<${ClassName}Entity> buildQueryWrapper(${ClassName}Entity ${className}#orgKeywordDecl()) {\Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (20,'主子表单V202611','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','主子表单V202611','## 有字典字段时才导入 useDict\n#set($hasDictField = false)\n#foreach($field in $formList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#set($hasDuplicate = false)\n#foreach($field in $formList)\n#if($field.formValidator == \'duplicate\')\n#set($hasDuplicate = true)\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($hasOrg = false)\n#foreach($field in $formList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\n#foreach($field in $childFieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\n<template>\n <el-drawer :title="form.${pk.attrName} ? (detail ? \'详情\' : \'编辑\') : \'添加\'" v-model="visible" size="50%">\n <el-form ref="dataFormRef" :model="form" :rules="dataRules" :disabled="detail" v-loading="loading">\n <el-row :gutter="24">\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName})\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n#if($field.formType.startsWith(\'org-\'))\n#set($orgType = $field.formType.replace(\'org-\', \'\').replace(\'-multiple\', \'\'))\n <el-form-item label="${field.fieldComment}" prop="${field.attrName}">\n <OrgSelect v-model="form.${field.attrName}" value-type="item" type="${orgType}" :multiple="#if($field.formType.endsWith(\'-multiple\'))true#else false#end" label="${field.fieldComment}" :disabled="loading || detail" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'switch\')\n#switchValues($field)\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-switch :model-value="String(form.${field.attrName}) === String($switchOn)" @change="(checked) => (form.${field.attrName} = checked ? $switchOn : $switchOff)" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'text\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">\n <el-input v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">\n <el-input type="textarea" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">\n <el-select v-model="form.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end">\n#if($field.fieldDict)\n <el-option :value="item.value" :label="item.label" v-for="(item, index) in ${field.fieldDict}" :key="index"></el-option>\n#else\n <el-option label="请选择" value="0"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">\n <el-radio-group v-model="form.${field.attrName}">\n#if($field.fieldDict)\n <el-radio :label="item.value" v-for="(item, index) in ${field.fieldDict}" border :key="index">{{ item.label }}</el-radio>\n#else\n <el-radio label="${field.fieldComment}" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">\n <el-checkbox-group v-model="form.${field.attrName}">\n#if($field.fieldDict)\n <el-checkbox :label="item.value" v-fLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (21,'主子表格V202611','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','主子表格V202611','## 有字典字段时才导入 useDict\n#set($hasDictField = false)\n#foreach($field in $queryList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($permissionPrefix = "${moduleName}_${functionName}")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n<template>\n <div class="layout-padding">\n <div class="layout-padding-auto layout-padding-view">\n#if($queryList)\n <el-row v-show="showSearch">\n <el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))#set($queryKey = "${field.attrName}Keyword")#else#set($queryKey = $field.attrName)#end\n#if($field.queryFormType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-select v-model="state.queryForm.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option \n :label="item.label" \n :value="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n :key="index">\n </el-option>\n#else\n <el-option label="请选择">0</el-option>\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-date-picker\n type="date"\n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"\n :value-format="dateStr"\n v-model="state.queryForm.${field.attrName}"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-picker\n type="daterange"\n range-separator="至"\n start-placeholder="开始日期"\n end-placeholder="结束日期"\n v-model="state.queryForm.${field.attrName}Range"\n :value-format="dateStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-date-picker\n type="datetime"\n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"\n :value-format="dateTimeStr"\n v-model="state.queryForm.${field.attrName}"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-picker\n type="datetimerange"\n range-separator="至"\n start-placeholder="开始时间"\n end-placeholder="结束时间"\n v-model="state.queryForm.${field.attrName}Range"\n :value-format="dateTimeStr"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-radio-group v-model="state.queryForm.${field.attrName}">\n#if($field.fieldDict)\n <el-radio \n :label="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n border \n :key="index">\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label="${field.fieldComment}" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <elLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (22,'子MapperV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ChildClassName}Mapper.java','子MapperV202611','package ${package}.${moduleName}.mapper;\n\nimport ${package}.common.data.datascope.PigxBaseMapper;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ChildClassName}Mapper extends PigxBaseMapper<${ChildClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (23,'树形ControllerV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','树形ControllerV202611','## 查询条件按需导入:字符串字段用 StrUtil,其余类型用 Objects;复选框与日期范围两者都不用\n#set($needStrUtil = false)\n#set($needObjects = false)\n#foreach($field in $queryList)\n#if($field.formType == \'checkbox\' || $field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#elseif($field.formType.startsWith(\'org-\') || $field.attrType == \'String\')\n#set($needStrUtil = true)\n#else\n#set($needObjects = true)\n#end\n#end\n#set($hasOrgQuery = false)\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrgQuery = true)\n#end\n#end\n## 组织字段以 [{id,name}] JSON 存储,按 ${attrName}Keyword 对整列模糊查询,分页和导出共用\n#macro(orgKeywordParams)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), @RequestParam(required = false) String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordDecl)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordArgs)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordFilters)\n#if($hasOrgQuery)\n // 组织字段对整列 JSON 做 LIKE:关键字为数字或 id/name 时会误命中,需精确匹配时改用数据库 JSON 函数\n#end\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n wrapper.like(StrUtil.isNotBlank(${field.attrName}Keyword), ${ClassName}Entity::$str.getProperty($field.attrName), ${field.attrName}Keyword);\n#end\n#end\n#end\npackage ${package}.${moduleName}.controller;\n\n#if($queryList)\n#if($needStrUtil)\nimport cn.hutool.core.util.StrUtil;\n#end\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n#if($needObjects)\nimport java.util.Objects;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping("/${functionName}" )\n@Tag(description = "${functionName}" , name = "${tableComment}管理" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 获取树形列表\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = "获取树形列表" , description = "获取树形列表" )\n @GetMapping("/tree" )\n #if($isSpringBoot3)\n @HasPermission("$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view")\n #else\n @PreAuthorize("@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')" )\n #end\n public R get${ClassName}Tree(@ParameterObject ${ClassName}Entity ${className}#orgKeywordParams()) {\n return R.ok(${className}Service.buildTree(buildQueryWrapper(${className}#orgKeywordArgs())));\n }\n\n /**\n * 列表与导出共用的查询条件,保证导出结果与列表一致\n */\n private LambdaQueryWrapper<${ClassName}Entity> buildQueryWrapper(${ClassName}Entity ${className}#orgKeywordDecl()) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#orgKeywordFilters()\n#foreach ($field in $queryList)\n#if(!$field.formType.startsWith(\'org-\'))\n#set($getAttrName=$str.getProperty($field.attLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (24,'树形ServiceV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','树形ServiceV202611','package ${package}.${moduleName}.service;\n\nimport cn.hutool.core.lang.tree.Tree;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.spring.service.IService;\nimport ${entityClassName};\n\nimport java.util.List;\n\n/**\n * ${tableComment} Service接口\n *\n * @author ${author}\n * @date ${datetime}\n */\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n List<Tree<${pk.attrType}>> buildTree(LambdaQueryWrapper<${ClassName}Entity> wrapper);\n\n /**\n * 递归删除节点及其子节点\n * @param ids 要删除的节点ID列表\n * @return 删除结果\n */\n boolean removeBatchByIds(List<${pk.attrType}> ids);\n} ','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (25,'树形ServiceImplV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','树形ServiceImplV202611','## 根节点 ID 按主键类型生成,与 Tree<${pk.attrType}> 类型一致\n#if($pk.attrType == \'Long\')\n#set($treeRootId = \'0L\')\n#elseif($pk.attrType == \'String\')\n#set($treeRootId = \'"0"\')\n#else\n#set($treeRootId = \'0\')\n#end\npackage ${package}.${moduleName}.service.impl;\n\nimport cn.hutool.core.collection.CollUtil;\nimport cn.hutool.core.lang.tree.Tree;\nimport cn.hutool.core.lang.tree.TreeNode;\nimport cn.hutool.core.lang.tree.TreeUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport jakarta.validation.constraints.NotNull;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.function.Function;\nimport java.util.stream.Collectors;\n\n/**\n * ${tableComment} Service实现类\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n @Override\n public List<Tree<${pk.attrType}>> buildTree(LambdaQueryWrapper<${ClassName}Entity> wrapper) {\n // 查询命中节点,再按层补齐祖先,保留完整树路径\n List<${ClassName}Entity> allList = list(wrapper);\n \n if (CollUtil.isEmpty(allList)) {\n return new ArrayList<>();\n }\n\n Map<${pk.attrType}, ${ClassName}Entity> nodes = new LinkedHashMap<>();\n allList.forEach(entity -> nodes.put(entity.$str.getProperty($pk.attrName)(), entity));\n List<${ClassName}Entity> level = allList;\n while (!level.isEmpty()) {\n List<${pk.attrType}> parentIds = level.stream()\n .map(${ClassName}Entity::$str.getProperty($parentField))\n .filter(id -> id != null && !Objects.equals(id, ${treeRootId}) && !nodes.containsKey(id))\n .distinct()\n .toList();\n if (parentIds.isEmpty()) {\n break;\n }\n level = listByIds(parentIds);\n level.forEach(entity -> nodes.put(entity.$str.getProperty($pk.attrName)(), entity));\n }\n\n // 转换为TreeNode,仅包含命中节点及其祖先\n List<TreeNode<${pk.attrType}>> collect = nodes.values().stream().map(getNodeFunction()).toList();\n\n // 使用TreeUtil构建树形结构,根节点ID为0\n return TreeUtil.build(collect, ${treeRootId});\n }\n\n /**\n * 获取TreeNode转换函数\n * @return TreeNode转换函数\n */\n @NotNull\n private Function<${ClassName}Entity, TreeNode<${pk.attrType}>> getNodeFunction() {\n return entity -> {\n TreeNode<${pk.attrType}> node = new TreeNode<>();\n node.setId(entity.$str.getProperty($pk.attrName)());\n node.setName(entity.$str.getProperty($nameField)());\n node.setParentId(entity.$str.getProperty($parentField)() != null ? entity.$str.getProperty($parentField)() : ${treeRootId});\n\n // 扩展属性\n Map<String, Object> extra = new HashMap<>();\n#foreach($field in $fieldList)\n extra.put(${ClassName}Entity.Fields.${field.attrName}, entity.$str.getProperty($field.attrName)());\n#end\n node.setExtra(extra);\n return node;\n };\n }\n\n /**\n * 递归删除节点及其子节点\n * @param ids 要删除的节点ID列表\n * @return 删除结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public boolean removeBatchByIds(List<${pk.attrType}> ids) {\n if (CollUtil.isEmpty(ids)) {\n return true;\n }\n\n // 获取所有要删除的ID(包括子节点)\n List<${pk.attrType}> allDeleteIds = new ArrayList<>(ids);\n \n for (${pk.attrType} id : ids) {\n List<${pk.attrType}> childIds = getChildIdsRecursive(id);\n allDeleteIds.addAll(childIds);\n }\n\n // 去重\n allLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (26,'树形实体V202611','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','树形实体V202611','#set($hasOrg = false)\n#foreach($field in $fieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\npackage ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.spring.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\nimport lombok.experimental.FieldNameConstants;\n#if($hasOrg)\nimport com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;\nimport ${package}.common.core.util.OrgRef;\nimport org.apache.fesod.sheet.annotation.ExcelIgnore;\nimport java.util.List;\n#end\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\n#if(!$import.startsWith(\'java.lang.\'))\nimport $import;\n#end\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n@FieldNameConstants\n#if($isTenant)\n@TenantTable\n#end\n@TableName(value = "${tableName}"#if($hasOrg), autoResultMap = true#end)\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = "${tableComment}")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.formType.startsWith(\'org-\'))\n @TableField(typeHandler = JacksonTypeHandler.class#if($field.autoFill == \'INSERT\' || $field.autoFill == \'INSERT_UPDATE\' || $field.autoFill == \'UPDATE\'), fill = FieldFill.${field.autoFill}#end)\n @ExcelIgnore\n#elseif($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description="$comment"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType.startsWith(\'org-\'))\n private List<OrgRef> $field.attrName;\n#elseif($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description="$comment 查询范围",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (27,'MapperV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV202611','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (28,'Mapper.xmlV202611','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV202611','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"#if($field.formType.startsWith(\'org-\')) typeHandler=\"com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler\"#end/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (29,'权限菜单V202611','${backendPath}/menu/${functionName}_menu.sql','权限菜单V202611','#set($permissionPrefix = \"${moduleName}_${functionName}\")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'${permissionPrefix}_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'${permissionPrefix}_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'${permissionPrefix}_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'${permissionPrefix}_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'${permissionPrefix}_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (30,'树形api.tsV202611','${frontendPath}/src/api/${moduleName}/${functionName}.ts','树形api.tsV202611','import request from \"/@/utils/request\"\n\n// ========== 树形表格CRUD接口 ==========\n\n/**\n * 获取树形列表数据\n * @param query - 查询参数对象\n * @returns Promise<树形数据>\n */\nexport function fetchTreeList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据(递归删除子节点)\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (31,'树形表格V202611','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','树形表格V202611','## 有字典字段时才导入 useDict\n#set($hasDictField = false)\n#foreach($field in $queryList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n<template>\n <div class="layout-padding">\n <div class="layout-padding-auto layout-padding-view">\n#if($queryList)\n <!-- 查询表单区域 -->\n <el-row v-show="showSearch">\n <el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))#set($queryKey = "${field.attrName}Keyword")#else#set($queryKey = $field.attrName)#end\n#if($field.queryFormType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${queryKey}">\n <el-select v-model="state.queryForm.${queryKey}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option \n :label="item.label" \n :value="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n :key="index"\n />\n#else\n <el-option label="请选择" value="0" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${queryKey}">\n <el-date-picker \n type="date" \n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" \n v-model="state.queryForm.${queryKey}"\n :value-format="dateStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${queryKey}">\n <el-date-picker\n type="datetime"\n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"\n v-model="state.queryForm.${queryKey}"\n :value-format="dateTimeStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-picker\n type="daterange"\n range-separator="至"\n start-placeholder="开始日期"\n end-placeholder="结束日期"\n v-model="state.queryForm.${field.attrName}Range"\n :value-format="dateStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-picker\n type="datetimerange"\n range-separator="至"\n start-placeholder="开始时间"\n end-placeholder="结束时间"\n v-model="state.queryForm.${field.attrName}Range"\n :value-format="dateTimeStr"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${queryKey}">\n <el-radio-group v-model="state.queryForm.${queryKey}">\n#if($field.fieldDict)\n <el-radio \n :label="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n border \n :key="index"\n >\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label="${field.fieldComment}" border>\n ${field.fieldComment}\n </el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#enLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (32,'树形表单V202611','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','树形表单V202611','#set($hasDuplicate = false)\n#foreach($field in $formList)\n#if($field.formValidator == \'duplicate\')\n#set($hasDuplicate = true)\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($hasOrg = false)\n#foreach($field in $formList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\n<template>\n <el-dialog :title="form.${pk.attrName} ? \'编辑\' : \'新增\'" v-model="visible"\n :close-on-click-modal="false" draggable>\n <el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">\n <el-row :gutter="24">\n <!-- 父级节点选择 -->\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n <el-form-item label="父级节点" prop="${parentField}">\n <el-tree-select\n v-model="form.${parentField}"\n :data="parentNodes"\n :props="treeSelectProps"\n check-strictly\n :render-after-expand="false"\n placeholder="请选择父级节点"\n style="width: 100%"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${parentField})\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n#if($field.formType.startsWith(\'org-\'))\n#set($orgType = $field.formType.replace(\'org-\', \'\').replace(\'-multiple\', \'\'))\n <el-form-item label="${field.fieldComment}" prop="${field.attrName}">\n <OrgSelect v-model="form.${field.attrName}" value-type="item" type="${orgType}" :multiple="#if($field.formType.endsWith(\'-multiple\'))true#else false#end" label="${field.fieldComment}" :disabled="loading" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'switch\')\n#switchValues($field)\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-switch :model-value="String(form.${field.attrName}) === String($switchOn)" @change="(checked) => (form.${field.attrName} = checked ? $switchOn : $switchOff)" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'text\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input type="textarea" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-select v-model="form.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option :value="item.value" :label="item.label" v-for="(item, index) in ${field.fieldDict}" :key="index"></el-option>\n#else\n <el-option label="请选择" value="0"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-radio-group v-model="form.${field.attrName}">\n#if($field.fieldDict)\n <el-radio :label="item.value" v-for="(item, index) in ${field.fieldDict}" border :key="index">{{ item.label }}</el-radio>\n#else\n <el-radio label="${field.fieldComment}" bordLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (33,'左树右表ControllerV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','左树右表ControllerV202611','## 查询条件按需导入 StrUtil(字符串字段);Objects 用于树节点筛选,始终导入\n#set($needStrUtil = false)\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\') || ($field.formType != \'checkbox\' && $field.queryFormType != \'daterange\' && $field.queryFormType != \'datetimerange\' && $field.attrType == \'String\'))\n#set($needStrUtil = true)\n#end\n#end\n#set($hasOrgQuery = false)\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrgQuery = true)\n#end\n#end\n## 组织字段以 [{id,name}] JSON 存储,按 ${attrName}Keyword 对整列模糊查询,分页和导出共用\n#macro(orgKeywordParams)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), @RequestParam(required = false) String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordDecl)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordArgs)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordFilters)\n#if($hasOrgQuery)\n // 组织字段对整列 JSON 做 LIKE:关键字为数字或 id/name 时会误命中,需精确匹配时改用数据库 JSON 函数\n#end\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n wrapper.like(StrUtil.isNotBlank(${field.attrName}Keyword), ${ClassName}Entity::$str.getProperty($field.attrName), ${field.attrName}Keyword);\n#end\n#end\n#end\npackage ${package}.${moduleName}.controller;\n\n#if($needStrUtil)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($childFieldGetter = $str.getProperty($childField))\n@RestController\n@RequiredArgsConstructor\n@RequestMapping("/${functionName}" )\n@Tag(description = "${functionName}" , name = "${tableComment}管理" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = "分页查询" , description = "分页查询" )\n @GetMapping("/page" )\n #if($isSpringBoot3)\n @HasPermission("$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view")\n #else\n @PreAuthorize("@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}#orgKeywordParams()) {\n return R.ok(${className}Service.page(page, buildQueryWrapper(${className}#orgKeywordArgs())));\n }\n\n /**\n * 列表与导出共用的查询条件,保证导出结果与列表一致\n */\n private LambdaQueryWrapper<${ClassName}Entity> buildQueryWrapper(${ClassName}Entity ${className}#orgKeywordDecl()) {\n LambLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (34,'左树右表ServiceV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','左树右表ServiceV202611','package ${package}.${moduleName}.service;\n\nimport cn.hutool.core.lang.tree.Tree;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.spring.service.IService;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\n\nimport java.util.List;\n\n/**\n * ${tableComment} Service接口\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n List<Tree<${childPkField.attrType}>> buildTree(LambdaQueryWrapper<${ChildClassName}Entity> wrapper);\n\n /**\n * 获取树节点详情\n * @param ${childClassName} 树节点查询对象\n * @return 树节点详情列表\n */\n List<${ChildClassName}Entity> getTreeDetails(${ChildClassName}Entity ${childClassName});\n\n /**\n * 保存树节点\n * @param ${childClassName} 树节点对象\n * @return 保存结果\n */\n Boolean saveTree(${ChildClassName}Entity ${childClassName});\n\n /**\n * 更新树节点\n * @param ${childClassName} 树节点对象\n * @return 更新结果\n */\n Boolean updateTree(${ChildClassName}Entity ${childClassName});\n\n /**\n * 批量删除树节点\n * @param ids 树节点ID列表\n * @return 删除结果\n */\n Boolean removeTreeByIds(${childPkField.attrType}[] ids);\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (35,'左树右表ServiceImplV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','左树右表ServiceImplV202611','package ${package}.${moduleName}.service.impl;\n\nimport cn.hutool.core.collection.CollUtil;\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.lang.tree.Tree;\nimport cn.hutool.core.lang.tree.TreeNode;\nimport cn.hutool.core.lang.tree.TreeUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ChildClassName}Mapper;\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\nimport java.util.function.Function;\n\n/**\n * ${tableComment} Service实现类\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#set($childPkGetter = $str.getProperty($childPkField.attrName))\n#break\n#end\n#end\n#set($parentGetter = $str.getProperty($parentField))\n#set($childFieldGetter = $str.getProperty($childField))\n#if($childPkField.attrType == \'Long\')\n#set($treeRootId = \'0L\')\n#elseif($childPkField.attrType == \'String\')\n#set($treeRootId = \'\"0\"\')\n#else\n#set($treeRootId = \'0\')\n#end\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n private final ${ChildClassName}Mapper ${childClassName}Mapper;\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n @Override\n public List<Tree<${childPkField.attrType}>> buildTree(LambdaQueryWrapper<${ChildClassName}Entity> wrapper) {\n List<${ChildClassName}Entity> allList = ${childClassName}Mapper.selectList(wrapper);\n\n if (CollUtil.isEmpty(allList)) {\n return new ArrayList<>();\n }\n\n List<TreeNode<${childPkField.attrType}>> collect = allList.stream().map(getNodeFunction()).toList();\n return TreeUtil.build(collect, ${treeRootId});\n }\n\n /**\n * 获取树节点详情\n * @param ${childClassName} 树节点查询对象\n * @return 树节点详情列表\n */\n @Override\n public List<${ChildClassName}Entity> getTreeDetails(${ChildClassName}Entity ${childClassName}) {\n return ${childClassName}Mapper.selectList(Wrappers.query(${childClassName}));\n }\n\n /**\n * 保存树节点\n * @param ${childClassName} 树节点对象\n * @return 保存结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean saveTree(${ChildClassName}Entity ${childClassName}) {\n ${childClassName}.$str.setProperty($parentField)(validateParentRelation(null, ${childClassName}.$str.getProperty($parentField)()));\n return ${childClassName}Mapper.insert(${childClassName}) > 0;\n }\n\n /**\n * 更新树节点\n * @param ${childClassName} 树节点对象\n * @return 更新结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean updateTree(${ChildClassName}Entity ${childClassName}) {\n ${childClassName}.$str.setProperty($parentField)(validateParentRelation(${childClassName}.$str.getProperty($childPkField.attrName)(), ${childClassName}.$str.getProperty($parentField)()));\n return ${childClassName}Mapper.updateById(${childClassName}) > 0;\n }\n\n /**\n * 批量删除树节点\n * @param ids 树节点ID列表\n * @return 删除结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeTreeByIds(${childPkField.attrType}[] ids) {\n if (ArrayUtil.isEmpty(ids)) {\n return Boolean.TRUE;\n }\n\n for (${childPkField.attrType} id : ids) {\n if (hasChildNodes(id)) {\n throw new RuntimeException(\"当前节点存在子节点,不能删除\");\n }\n if (hasMainRecords(id)) {\n throw new RuntimeException(\"当前节点已关联主表数据,不能删除\");\n }\n }\n\n return ${childClassNameLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (36,'实体V202611','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','实体V202611','#set($hasOrg = false)\n#foreach($field in $fieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\npackage ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.spring.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($hasOrg)\nimport com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;\nimport ${package}.common.core.util.OrgRef;\nimport org.apache.fesod.sheet.annotation.ExcelIgnore;\nimport java.util.List;\n#end\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\n#if(!$import.startsWith(\'java.lang.\'))\nimport $import;\n#end\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(value = \"${tableName}\"#if($hasOrg), autoResultMap = true#end)\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.formType.startsWith(\'org-\'))\n @TableField(typeHandler = JacksonTypeHandler.class#if($field.autoFill == \'INSERT\' || $field.autoFill == \'INSERT_UPDATE\' || $field.autoFill == \'UPDATE\'), fill = FieldFill.${field.autoFill}#end)\n @ExcelIgnore\n#elseif($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType.startsWith(\'org-\'))\n private List<OrgRef> $field.attrName;\n#elseif($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (37,'MapperV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV202611','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (38,'Mapper.xmlV202611','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV202611','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"#if($field.formType.startsWith(\'org-\')) typeHandler=\"com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler\"#end/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (39,'子实体V202611','${entityPath}/src/main/java/${entityPackagePath}/${ChildClassName}Entity.java','子实体V202611','#set($hasOrg = false)\n#foreach($field in $childFieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\npackage ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.spring.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\n#if($isChildTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($hasOrg)\nimport com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;\nimport ${package}.common.core.util.OrgRef;\nimport java.util.List;\n#end\n#set($childImports = [])\n#foreach($field in $childFieldList)\n#if($field.packageName && !$field.packageName.startsWith(\'java.lang.\') && !$childImports.contains($field.packageName))\n#set($void = $childImports.add($field.packageName))\n#end\n#end\n#foreach($import in $childImports)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isChildTenant)\n@TenantTable\n#end\n@TableName(value = \"${childTableName}\"#if($hasOrg), autoResultMap = true#end)\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${childTableName}\")\npublic class ${ChildClassName}Entity extends Model<${ChildClassName}Entity> {\n\n#foreach ($field in $childFieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.formType.startsWith(\'org-\'))\n @TableField(typeHandler = JacksonTypeHandler.class#if($field.autoFill == \'INSERT\' || $field.autoFill == \'INSERT_UPDATE\' || $field.autoFill == \'UPDATE\'), fill = FieldFill.${field.autoFill}#end)\n#elseif($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType.startsWith(\'org-\'))\n private List<OrgRef> $field.attrName;\n#elseif($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end \n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (40,'子MapperV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ChildClassName}Mapper.java','子MapperV202611','package ${package}.${moduleName}.mapper;\n\nimport ${package}.common.data.datascope.PigxBaseMapper;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ChildClassName}Mapper extends PigxBaseMapper<${ChildClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (41,'权限菜单V202611','${backendPath}/menu/${functionName}_menu.sql','权限菜单V202611','#set($permissionPrefix = \"${moduleName}_${functionName}\")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'${permissionPrefix}_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'${permissionPrefix}_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'${permissionPrefix}_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'${permissionPrefix}_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'${permissionPrefix}_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (42,'左树右表api.tsV202611','${frontendPath}/src/api/${moduleName}/${functionName}.ts','左树右表api.tsV202611','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 树形CRUD接口 ==========\n\n/**\n * 获取树形列表数据\n * @param query - 查询参数对象\n * @returns Promise<树形数据>\n */\nexport function fetchTreeList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 获取树节点详情\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<树节点详情>\n */\nexport function getTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 新增树节点\n * @param obj - 要新增的树节点对象\n * @returns Promise<操作结果>\n */\nexport function addTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 更新树节点\n * @param obj - 要更新的树节点对象\n * @returns Promise<操作结果>\n */\nexport function putTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'put\',\n data: obj\n })\n}\n\n/**\n * 删除树节点\n * @param ids - 要删除的树节点ID数组\n * @returns Promise<操作结果>\n */\nexport function delTreeObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'delete\',\n data: ids\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n *\n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (43,'左树右表表格V202611','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','左树右表表格V202611','## 有字典字段时才导入 useDict\n#set($hasDictField = false)\n#foreach($field in $queryList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n<template>\n <div class="layout-padding">\n <splitpanes>\n <pane size="15">\n <div class="layout-padding-auto layout-padding-view">\n <el-scrollbar>\n <div class="mb8" style="display: flex; align-items: center; justify-content: space-between;">\n <span style="font-weight: 500;">左侧节点</span>\n <div>\n <el-tooltip :content="currentTreeId ? \'新增子节点\' : \'新增根节点\'" placement="top">\n <el-button link type="primary" icon="FolderAdd" @click="handleAddTree" />\n </el-tooltip>\n </div>\n </div>\n <el-tree\n ref="treeRef"\n :data="treeData"\n :props="treeProps"\n node-key="${childPkField.attrName}"\n highlight-current\n default-expand-all\n :expand-on-click-node="false"\n @node-click="handleTreeNodeClick"\n >\n <template #default="{ node, data }">\n <span style="flex: 1; display: flex; align-items: center; justify-content: space-between;">\n <span>{{ node.label }}</span>\n <span v-if="currentTreeId === data.${childPkField.attrName}" style="margin-left: 8px;">\n <el-tooltip content="编辑" placement="top">\n <el-button link type="primary" icon="Edit" size="small" @click.stop="handleEditTree" />\n </el-tooltip>\n <el-tooltip content="删除" placement="top">\n <el-button link type="danger" icon="Delete" size="small" @click.stop="handleDeleteTree" />\n </el-tooltip>\n </span>\n </span>\n </template>\n </el-tree>\n </el-scrollbar>\n </div>\n </pane>\n <pane class="ml8">\n <div class="layout-padding-auto layout-padding-view">\n#if($queryList)\n <el-row v-show="showSearch">\n <el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))#set($queryKey = "${field.attrName}Keyword")#else#set($queryKey = $field.attrName)#end\n#if($field.attrName != ${childField})\n#if($field.queryFormType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${queryKey}">\n <el-select v-model="state.queryForm.${queryKey}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option \n :label="item.label" \n :value="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n :key="index"\n />\n#else\n <el-option label="请选择" value="0" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${queryKey}">\n <el-date-picker\n type="date"\n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"\n v-model="state.queryForm.${queryKey}"\n :value-format="dateStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-pickerLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (44,'左树右表树表单V202611','${frontendPath}/src/views/${moduleName}/${functionName}/tree-form.vue','左树右表树表单V202611','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($fieldDict=[])\n#foreach($field in $childFieldList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($hasOrg = false)\n#foreach($field in $childFieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\n<template>\n <el-dialog :title="form.${childPkField.attrName} ? \'编辑\' : \'新增\'" v-model="visible"\n :close-on-click-modal="false" draggable>\n <el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading">\n <el-row :gutter="24">\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n <el-form-item label="父级节点" prop="${parentField}">\n <el-tree-select\n v-model="form.${parentField}"\n :data="parentNodes"\n :props="treeSelectProps"\n check-strictly\n :render-after-expand="false"\n placeholder="请选择父级节点"\n style="width: 100%"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $childFieldList)\n#if($field.attrName != ${childPkField.attrName} && $field.attrName != ${parentField})\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n#if($field.formType.startsWith(\'org-\'))\n#set($orgType = $field.formType.replace(\'org-\', \'\').replace(\'-multiple\', \'\'))\n <el-form-item label="${field.fieldComment}" prop="${field.attrName}">\n <OrgSelect v-model="form.${field.attrName}" value-type="item" type="${orgType}" :multiple="#if($field.formType.endsWith(\'-multiple\'))true#else false#end" label="${field.fieldComment}" :disabled="loading" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'switch\')\n#switchValues($field)\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-switch :model-value="String(form.${field.attrName}) === String($switchOn)" @change="(checked) => (form.${field.attrName} = checked ? $switchOn : $switchOff)" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'text\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input type="textarea" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-select v-model="form.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option :value="item.value" :label="item.label" v-for="(item, index) in ${field.fieldDict}" :key="index"></el-option>\n#else\n <el-option label="请选择" value="0"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-radio-group v-model="form.${field.attrName}">\n#if($field.fieldDict)\n <el-radio :label="item.value" v-for="(item, index) in ${field.fieldDicLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (45,'左树右表主表单V202611','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','左树右表主表单V202611','#set($hasDuplicate = false)\n#foreach($field in $formList)\n#if($field.attrName != ${childField} && $field.formValidator == \'duplicate\')\n#set($hasDuplicate = true)\n#end\n#end\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($relationFieldLabel = $childField)\n#foreach($field in $fieldList)\n#if($field.attrName == $childField)\n#if($field.fieldComment)\n#set($relationFieldLabel = $field.fieldComment)\n#else\n#set($relationFieldLabel = $field.attrName)\n#end\n#break\n#end\n#end\n#set($fieldDict=[])\n#foreach($field in $formList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($hasOrg = false)\n#foreach($field in $formList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\n<template>\n <el-dialog :title="form.${pk.attrName} ? \'编辑\' : \'新增\'" v-model="visible"\n :close-on-click-modal="false" draggable>\n <el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading">\n <el-row :gutter="24">\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n <el-form-item label="${relationFieldLabel}" prop="${childField}">\n <el-tree-select\n v-model="form.${childField}"\n :data="treeNodes"\n :props="treeSelectProps"\n check-strictly\n :render-after-expand="false"\n placeholder="请选择${relationFieldLabel}"\n style="width: 100%"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${childField})\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n#if($field.formType.startsWith(\'org-\'))\n#set($orgType = $field.formType.replace(\'org-\', \'\').replace(\'-multiple\', \'\'))\n <el-form-item label="${field.fieldComment}" prop="${field.attrName}">\n <OrgSelect v-model="form.${field.attrName}" value-type="item" type="${orgType}" :multiple="#if($field.formType.endsWith(\'-multiple\'))true#else false#end" label="${field.fieldComment}" :disabled="loading" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'switch\')\n#switchValues($field)\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-switch :model-value="String(form.${field.attrName}) === String($switchOn)" @change="(checked) => (form.${field.attrName} = checked ? $switchOn : $switchOff)" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'text\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input type="textarea" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-select v-model="form.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option :value="item.value" :label="item.label" v-for="(item, index) in ${field.fieldDict}" :key="index"></el-option>\n#else\n <el-option label="请选择" value="0"></el-option>\n#end\n Line truncated
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
|
||||
+131
-116
@@ -112,8 +112,8 @@ CREATE TABLE `sys_dept` (
|
||||
`dept_id` bigint(20) NOT NULL COMMENT '部门ID',
|
||||
`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '部门名称',
|
||||
`sort_order` int(11) NOT NULL DEFAULT '0' COMMENT '排序',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标志',
|
||||
@@ -150,8 +150,8 @@ CREATE TABLE `sys_dict` (
|
||||
`id` bigint(20) NOT NULL COMMENT '编号',
|
||||
`dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字典类型',
|
||||
`description` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '描述',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注信息',
|
||||
@@ -209,8 +209,8 @@ CREATE TABLE `sys_dict_item` (
|
||||
`description` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字典项描述',
|
||||
`list_class` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '标签类型',
|
||||
`sort_order` int(11) NOT NULL DEFAULT '0' COMMENT '排序(升序)',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注信息',
|
||||
@@ -262,8 +262,6 @@ INSERT INTO `sys_dict_item` VALUES (33, 11, '0', '正常', 'status_type', '状
|
||||
INSERT INTO `sys_dict_item` VALUES (34, 11, '9', '冻结', 'status_type', '状态冻结', NULL, 1, ' ', ' ', '2019-05-15 16:31:56', '2019-05-16 22:30:50', '状态冻结', '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (35, 12, '1', '系统类', 'dict_type', '系统类字典', NULL, 0, ' ', ' ', '2019-05-16 14:20:40', '2019-05-16 14:20:40', '不能修改删除', '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (36, 12, '0', '业务类', 'dict_type', '业务类字典', NULL, 0, ' ', ' ', '2019-05-16 14:20:59', '2019-05-16 14:20:59', '可以修改', '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (37, 2, 'GITEE', '码云', 'social_type', '码云', NULL, 2, ' ', ' ', '2019-06-28 09:59:12', '2019-06-28 09:59:12', '码云', '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (38, 2, 'OSC', '开源中国', 'social_type', '开源中国登录', NULL, 2, ' ', ' ', '2019-06-28 10:04:32', '2019-06-28 10:04:32', '', '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (39, 14, 'password', '密码模式', 'grant_types', '支持oauth密码模式', NULL, 0, ' ', ' ', '2019-08-13 07:35:28', '2019-08-13 07:35:28', NULL, '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (40, 14, 'authorization_code', '授权码模式', 'grant_types', 'oauth2 授权码模式', NULL, 1, ' ', ' ', '2019-08-13 07:36:07', '2019-08-13 07:36:07', NULL, '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (41, 14, 'client_credentials', '客户端模式', 'grant_types', 'oauth2 客户端模式', NULL, 2, ' ', ' ', '2019-08-13 07:36:30', '2019-08-13 07:36:30', NULL, '0', 1);
|
||||
@@ -322,6 +320,7 @@ INSERT INTO `sys_dict_item` VALUES (95, 29, '0', '黑名单', 'sensitive_type',
|
||||
INSERT INTO `sys_dict_item` VALUES (96, 29, '1', '白名单', 'sensitive_type', '失败', NULL, 3, 'admin', ' ', '2023-10-27 10:30:47', NULL, NULL, '0', 1);
|
||||
INSERT INTO `sys_dict_item` VALUES (97,2,'MINI','小程序登录','social_type','小程序登录',NULL,3,' ',' ','2022-02-18 13:56:25','2022-02-18 13:56:28',NULL,'0',1);
|
||||
INSERT INTO `sys_dict_item` VALUES (98,2,'clarity','clarity','social_type','clarity',NULL,3,' ',' ','2022-02-18 13:56:25','2022-02-18 13:56:28',NULL,'0',1);
|
||||
INSERT INTO `sys_dict_item` VALUES (100,2,'FEISHU','企业飞书','social_type','企业飞书扫码登录',NULL,5,' ',' ','2026-09-18 00:00:00','2026-09-18 00:00:00',NULL,'0',1);
|
||||
INSERT INTO `sys_dict_item` VALUES (99,2,'umami','umami','social_type','umami',NULL,4,' ',' ','2026-06-23 00:00:00','2026-06-23 00:00:00',NULL,'0',1);
|
||||
COMMIT;
|
||||
|
||||
@@ -339,8 +338,8 @@ CREATE TABLE `sys_file` (
|
||||
`type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '文件类型',
|
||||
`hash` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '文件hash',
|
||||
`file_size` bigint(20) DEFAULT NULL COMMENT '文件大小',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '上传时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标志',
|
||||
@@ -387,9 +386,9 @@ CREATE TABLE `sys_i18n` (
|
||||
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'name',
|
||||
`zh_cn` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '中文',
|
||||
`en` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '英文',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
|
||||
PRIMARY KEY (`id`)
|
||||
@@ -399,80 +398,83 @@ CREATE TABLE `sys_i18n` (
|
||||
-- Records of sys_i18n
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_i18n` VALUES (1, 'router.permissionManagement', '权限管理', 'Permission Management', '', '2023-02-14 02:03:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (2, 'router.userManagement', '用户管理', 'User Management', 'admin', '2023-02-14 10:39:08', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (3, 'router.menuManagement', '菜单管理', 'Menu Management', 'admin', '2023-02-15 23:14:39', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (4, 'router.roleManagement', '角色管理', 'Role Management', 'admin', '2023-02-15 23:15:51', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (5, 'router.departmentManagement', '部门管理', 'Department Management', 'admin', '2023-02-15 23:16:52', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (6, 'router.tenantManagement', '租户管理', 'Tenant Management', 'admin', '2023-02-24 10:08:29', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (7, 'router.postManagement', '岗位管理', 'Post Management', 'admin', '2023-02-24 10:12:58', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (8, 'router.systemManagement', '系统管理', 'System Management', 'admin', '2023-02-24 10:13:34', 'admin', '2023-02-24 10:58:30', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (9, 'router.operationLog', '操作日志', 'Operation Log', 'admin', '2023-02-24 10:14:47', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (10, 'router.dictManagement', '字典管理', 'Dictionary Management', 'admin', '2023-02-24 10:16:21', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (11, 'router.parameterManagement', '参数管理', 'Parameter Management', 'admin', '2023-02-24 10:17:04', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (12, 'router.codeGeneration', '代码生成', 'Code Generation', 'admin', '2023-02-24 10:19:16', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (13, 'router.terminalManagement', '终端管理', 'Terminal Management', 'admin', '2023-02-24 10:21:45', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (14, 'router.keyManagement', '密钥管理', 'Key Management', 'admin', '2023-02-24 10:22:52', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (15, 'router.tokenManagement', '令牌管理', 'Token Management', 'admin', '2023-02-24 10:23:22', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (16, 'router.quartzManagement', 'Quartz管理', 'Quartz Management', 'admin', '2023-02-24 10:24:32', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (17, 'router.metadataManagement', '元数据管理', 'Metadata Management', 'admin', '2023-02-24 10:25:11', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (1, 'router.permissionManagement', '权限管理', 'Permissions', '', '2023-02-14 02:03:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (2, 'router.userManagement', '用户管理', 'Users', 'admin', '2023-02-14 10:39:08', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (3, 'router.menuManagement', '菜单管理', 'Menus', 'admin', '2023-02-15 23:14:39', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (4, 'router.roleManagement', '角色管理', 'Roles', 'admin', '2023-02-15 23:15:51', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (5, 'router.departmentManagement', '部门管理', 'Departments', 'admin', '2023-02-15 23:16:52', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (6, 'router.tenantManagement', '租户管理', 'Tenants', 'admin', '2023-02-24 10:08:29', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (7, 'router.postManagement', '岗位管理', 'Positions', 'admin', '2023-02-24 10:12:58', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (8, 'router.systemManagement', '系统管理', 'System', 'admin', '2023-02-24 10:13:34', 'admin', '2023-02-24 10:58:30', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (9, 'router.operationLog', '操作日志', 'Operation Logs', 'admin', '2023-02-24 10:14:47', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (10, 'router.dictManagement', '字典管理', 'Dictionaries', 'admin', '2023-02-24 10:16:21', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (11, 'router.parameterManagement', '参数管理', 'Parameters', 'admin', '2023-02-24 10:17:04', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (12, 'router.codeGeneration', '代码生成', 'Code Generator', 'admin', '2023-02-24 10:19:16', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (13, 'router.terminalManagement', '终端管理', 'OAuth Clients', 'admin', '2023-02-24 10:21:45', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (14, 'router.keyManagement', '密钥管理', 'Keys', 'admin', '2023-02-24 10:22:52', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (15, 'router.tokenManagement', '令牌管理', 'Tokens', 'admin', '2023-02-24 10:23:22', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (16, 'router.quartzManagement', 'Quartz管理', 'Quartz Jobs', 'admin', '2023-02-24 10:24:32', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (17, 'router.metadataManagement', '元数据管理', 'Metadata', 'admin', '2023-02-24 10:25:11', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (18, 'router.documentExtension', '文档扩展', 'Document Extension', 'admin', '2023-02-24 10:27:23', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (19, 'router.fileManagement', '文件管理', 'File Management', 'admin', '2023-02-24 10:28:44', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (20, 'router.platformDevelopment', '开发平台', 'Platform Development', 'admin', '2023-02-24 10:29:28', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (21, 'router.dataSourceManagement', '数据源管理', 'Data Source Management', 'admin', '2023-02-24 10:30:33', 'admin', '2023-03-06 14:33:20', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (22, 'router.formDesign', '表单设计', 'Form Design', 'admin', '2023-02-24 10:31:33', 'admin', '2023-03-06 14:33:28', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (23, 'router.appManagement', 'APP管理', 'App Management', 'admin', '2023-02-24 10:33:22', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (24, 'router.customerManagement', '客户管理', 'Customer Management', 'admin', '2023-02-24 10:35:30', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (19, 'router.fileManagement', '文件管理', 'Files', 'admin', '2023-02-24 10:28:44', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (20, 'router.platformDevelopment', '开发平台', 'Development', 'admin', '2023-02-24 10:29:28', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (21, 'router.dataSourceManagement', '数据源管理', 'Data Sources', 'admin', '2023-02-24 10:30:33', 'admin', '2023-03-06 14:33:20', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (23, 'router.appManagement', 'APP管理', 'Apps', 'admin', '2023-02-24 10:33:22', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (24, 'router.customerManagement', '客户管理', 'Customers', 'admin', '2023-02-24 10:35:30', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (25, 'router.appRole', 'APP角色', 'App Role', 'admin', '2023-02-24 10:36:17', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (26, 'router.appPermission', 'APP权限', 'App Permission', 'admin', '2023-02-24 10:36:59', 'admin', '2023-02-24 10:37:47', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (27, 'router.appKey', 'APP秘钥', 'App Key', 'admin', '2023-02-24 10:36:59', 'admin', '2023-02-24 10:40:27', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (28, 'router.internationalizationManagement', '国际化管理', 'Internationalization Management', 'admin', '2023-02-24 10:36:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (29, 'router.auditLog', '审计日志', 'Audit Log', 'admin', '2023-02-24 10:36:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (27, 'router.appKey', 'APP秘钥', 'App Keys', 'admin', '2023-02-24 10:36:59', 'admin', '2023-02-24 10:40:27', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (28, 'router.internationalizationManagement', '国际化管理', 'Translations', 'admin', '2023-02-24 10:36:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (29, 'router.auditLog', '审计日志', 'Audit Logs', 'admin', '2023-02-24 10:36:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (30, 'router.systemMonitoring', '系统监控', 'System Monitoring', 'admin', '2023-02-24 10:36:59', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (31, 'router.generatePages', '生成页面', 'Generate Pages', 'admin', '2023-02-24 10:44:04', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (32, 'router.templateManagement', '模板管理', 'Template Management', 'admin', '2023-02-24 10:44:31', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (33, 'router.templateGroup', '模板分组', 'Template Group', 'admin', '2023-02-24 10:45:10', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (34, 'router.fieldManagement', '字段管理', 'Field Management', 'admin', '2023-02-24 10:46:04', 'admin', '2023-03-07 14:27:48', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (35, 'router.wechatPlatform', '公众号平台', 'WeChat Platform', 'admin', '2023-02-24 10:48:51', 'admin', '2023-02-24 11:03:41', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (36, 'router.accountManagement', '账号管理', 'Account Management', 'admin', '2023-02-24 10:13:34', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (37, 'router.menuSettings', '菜单设置', 'Menu Settings', 'admin', '2023-02-24 14:02:22', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (38, 'router.fanManagement', '粉丝管理', 'Fan Management', 'admin', '2023-02-24 14:03:44', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (39, 'router.messageManagement', '消息管理', 'Message Management', 'admin', '2023-02-24 14:03:45', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (40, 'router.paymentSystem', '支付系统', 'Payment System', 'admin', '2023-02-24 14:03:46', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (41, 'router.checkoutCounter', '收银台', 'Checkout Counter', 'admin', '2023-02-24 14:03:47', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (42, 'router.mediaManagement', '素材管理', 'Media Management', 'admin', '2023-02-24 14:03:48', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (43, 'router.paymentChannel', '支付渠道', 'Payment Channel', 'admin', '2023-02-24 14:03:49', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (44, 'router.productOrder', '商品订单', 'Product Order', 'admin', '2023-02-24 14:03:50', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (45, 'router.notificationRecord', '通知记录', 'Notification Record', 'admin', '2023-02-24 14:03:51', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (46, 'router.refundOrder', '退款订单', 'Refund Order', 'admin', '2023-02-24 14:03:52', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (47, 'router.paymentOrder', '支付订单', 'Payment Order', 'admin', '2023-02-24 14:03:53', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (48, 'router.autoReply', '自动回复', 'Auto Reply', 'admin', '2023-02-24 14:03:54', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (49, 'router.operationalData', '运营数据', 'Operational Data', 'admin', '2023-02-24 14:03:55', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (50, 'router.logManagement', '日志管理', 'Log Management', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (51, 'router.collaborativeOffice', '协同办公', 'Collaborative Office', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (32, 'router.templateManagement', '模板管理', 'Templates', 'admin', '2023-02-24 10:44:31', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (33, 'router.templateGroup', '模板分组', 'Template Groups', 'admin', '2023-02-24 10:45:10', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (34, 'router.fieldManagement', '字段管理', 'Fields', 'admin', '2023-02-24 10:46:04', 'admin', '2023-03-07 14:27:48', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (35, 'router.wechatPlatform', '公众号平台', 'WeChat', 'admin', '2023-02-24 10:48:51', 'admin', '2023-02-24 11:03:41', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (36, 'router.accountManagement', '账号管理', 'Accounts', 'admin', '2023-02-24 10:13:34', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (37, 'router.menuSettings', '菜单设置', 'Menus', 'admin', '2023-02-24 14:02:22', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (38, 'router.fanManagement', '粉丝管理', 'Followers', 'admin', '2023-02-24 14:03:44', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (39, 'router.messageManagement', '消息管理', 'Messages', 'admin', '2023-02-24 14:03:45', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (40, 'router.paymentSystem', '支付系统', 'Payments', 'admin', '2023-02-24 14:03:46', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (41, 'router.checkoutCounter', '收银台', 'Checkout', 'admin', '2023-02-24 14:03:47', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (42, 'router.mediaManagement', '素材管理', 'Media', 'admin', '2023-02-24 14:03:48', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (43, 'router.paymentChannel', '支付渠道', 'Channels', 'admin', '2023-02-24 14:03:49', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (44, 'router.productOrder', '商品订单', 'Product Orders', 'admin', '2023-02-24 14:03:50', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (45, 'router.notificationRecord', '通知记录', 'Notifications', 'admin', '2023-02-24 14:03:51', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (46, 'router.refundOrder', '退款订单', 'Refunds', 'admin', '2023-02-24 14:03:52', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (47, 'router.paymentOrder', '支付订单', 'Payment Orders', 'admin', '2023-02-24 14:03:53', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (48, 'router.autoReply', '自动回复', 'Auto Replies', 'admin', '2023-02-24 14:03:54', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (49, 'router.operationalData', '运营数据', 'Analytics', 'admin', '2023-02-24 14:03:55', '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (50, 'router.logManagement', '日志管理', 'Logs', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (51, 'router.collaborativeOffice', '协同办公', 'Office', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (52, 'router.modelManagement', '模型管理', 'Model Management', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (53, 'router.modelDiagramView', '模型图查看', 'Model Diagram View', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (54, 'router.processManagement', '流程管理', 'Process Management', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (54, 'router.processManagement', '流程管理', 'Workflows', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (55, 'router.leaveWorkOrder', '请假工单', 'Leave Work Order', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (56, 'router.todoTask', '我的待办', 'Todo Task', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (57, 'router.tagManagement', '标签管理', 'Tag Management', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (58, 'router.articleInformation', '文章资讯', 'Article Information', ' ', '2023-08-10 13:40:09', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (59, 'router.articleCategory', '文章分类', 'Article Category', ' ', '2023-08-10 13:40:48', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (60, 'router.interfaceSettings', '界面设置', 'Interface Settings', ' ', '2023-08-10 13:41:21', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (62, 'router.cacheMonitoring', '缓存监控', 'Cache Monitoring', ' ', '2023-08-10 13:42:35', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (63, 'rotuer. initiateProcess', '发起流程', 'Initiate Process', ' ', '2023-08-10 13:44:23', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (64, 'router.taskManagement', '任务管理', 'Task Management', ' ', '2023-08-10 13:44:53', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (65, 'router.myInitiations', '我的发起', 'My Initiations', ' ', '2023-08-10 13:45:17', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (56, 'router.todoTask', '待办任务', 'Pending Tasks', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (57, 'router.tagManagement', '标签管理', 'Tags', 'admin', NULL, '', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (58, 'router.articleInformation', '文章资讯', 'Articles', ' ', '2023-08-10 13:40:09', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (59, 'router.articleCategory', '文章分类', 'Categories', ' ', '2023-08-10 13:40:48', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (60, 'router.interfaceSettings', '界面设置', 'Page Settings', ' ', '2023-08-10 13:41:21', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (62, 'router.cacheMonitoring', '缓存监控', 'Cache Monitor', ' ', '2023-08-10 13:42:35', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (63, 'rotuer. initiateProcess', '发起流程', 'Start Workflow', ' ', '2023-08-10 13:44:23', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (64, 'router.taskManagement', '任务管理', 'Tasks', ' ', '2023-08-10 13:44:53', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (65, 'router.myInitiations', '我的发起', 'My Requests', ' ', '2023-08-10 13:45:17', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (66, 'router.copiedtoMe', '抄送给我', 'Copied to Me', ' ', '2023-08-10 13:45:46', ' ', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (67, 'router.completedTasks', '我的已办', 'Completed Tasks', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (68, 'router.bizPlatform', '业务平台', 'Biz Platform', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (69, 'router.baseTools', '基础工具', 'Base Tools', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (70, 'router.route', '路由管理', 'Route Management', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (71, 'router.datav', '大屏看板', 'Data Visual', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (72, 'router.bi', '数据报表', 'Bi Report', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (67, 'router.completedTasks', '我的已办', 'Handled Tasks', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (68, 'router.bizPlatform', '业务平台', 'Business', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (69, 'router.baseTools', '基础工具', 'Tools', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (70, 'router.route', '路由管理', 'Routes', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (71, 'router.datav', '大屏看板', 'Dashboards', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (72, 'router.bi', '数据报表', 'Reports', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (73, 'router.message', '信息推送', 'Message Push', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (74, 'router.sensitiveWords', '敏感词管理', 'Sensitive words', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (74, 'router.sensitiveWords', '敏感词管理', 'Sensitive Words', ' ', '2023-08-10 13:46:37', ' ', '2023-08-10 13:47:09', '0');
|
||||
INSERT INTO `sys_i18n` VALUES (75, 'router.clarityMonitoring', '站点统计', 'Site Analytics', 'admin', '2026-03-26 00:00:00', 'admin', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (128, 'router.siteConfig', '网站配置', 'Site Settings', 'admin', '2026-11-03 00:00:00', 'admin', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (129, 'router.sysArea', '行政区划', 'Admin Divisions', 'admin', '2026-11-03 00:00:00', 'admin', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (130, 'router.businessForm', '业务表单', 'Business Forms', 'admin', '2026-11-03 00:00:00', 'admin', NULL, '0');
|
||||
INSERT INTO `sys_i18n` VALUES (131, 'router.databaseTables', '数据表管理', 'Database Tables', 'admin', '2026-11-03 00:00:00', 'admin', NULL, '0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
@@ -484,12 +486,12 @@ CREATE TABLE `sys_log` (
|
||||
`log_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '日志类型',
|
||||
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '日志标题',
|
||||
`service_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '服务ID',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remote_addr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '远程地址',
|
||||
`user_agent` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户代理',
|
||||
`user_agent` text COLLATE utf8mb4_general_ci COMMENT '浏览器标识',
|
||||
`request_uri` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '请求URI',
|
||||
`method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '请求方法',
|
||||
`params` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '请求参数',
|
||||
@@ -526,9 +528,9 @@ CREATE TABLE `sys_menu` (
|
||||
`keep_alive` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '是否缓存,0否,1是',
|
||||
`embedded` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否内嵌,0否,1是',
|
||||
`menu_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '菜单类型,0:菜单 1:按钮',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标志,0未删除,1已删除',
|
||||
`tenant_id` bigint(20) unsigned DEFAULT NULL COMMENT '租户ID',
|
||||
@@ -686,6 +688,7 @@ INSERT INTO `sys_menu` VALUES (4011,'信息推送查看','sys_message_view',NULL
|
||||
INSERT INTO `sys_menu` VALUES (4012,'信息推送新增','sys_message_add',NULL,NULL,4010,'1','1',1,'0',NULL,'1','',NULL,'admin','2023-10-25 14:52:00','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (4013,'信息推送修改','sys_message_edit',NULL,NULL,4010,'1','1',2,'0',NULL,'1','',NULL,'admin','2023-10-25 14:52:04','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (4014,'信息推送删除','sys_message_del',NULL,NULL,4010,'1','1',3,'0',NULL,'1','',NULL,'admin','2023-10-25 14:52:09','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (4015, '信息推送导出', 'sys_message_export', NULL, NULL, 4010, NULL, '1', 10, '0', '0', '1', 'admin', NOW(), 'admin', NOW(), '0', 1);
|
||||
INSERT INTO `sys_menu` VALUES (5000,'支付系统',NULL,'/pay',NULL,9900,'iconfont icon-duoqudaozhifuxitongguanli','1',1,'0','0','0','admin','2023-02-27 10:57:14','admin','2023-11-27 14:52:11','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (5001,'收银台',NULL,'/biz/pay/cd/index',NULL,5000,'iconfont icon-shouyintai','1',0,'0','0','0','admin','2023-02-27 10:58:13','admin','2023-11-01 17:28:57','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (5002,'支付渠道',NULL,'/biz/pay/channel/index',NULL,5000,'iconfont icon-zhifuqudao','1',1,'0','0','0','admin','2023-02-27 19:36:55','admin','2023-11-01 17:29:01','0',1);
|
||||
@@ -759,7 +762,6 @@ INSERT INTO `sys_menu` VALUES (7804,'删除','app_appContacts_del',NULL,NULL,780
|
||||
INSERT INTO `sys_menu` VALUES (7805,'导入导出','app_appContacts_export',NULL,NULL,7800,NULL,'1',1,'0',NULL,'1','admin','2025-05-29 17:30:31',' ',NULL,'0',1);
|
||||
INSERT INTO `sys_menu` VALUES (9000,'开发平台',NULL,'/gen',NULL,-1,'iconfont icon-DevOps','1',9,'0','0','0','','2019-08-12 09:35:16','admin','2025-01-26 22:38:09','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (9005,'数据源管理',NULL,'/gen/datasource/index',NULL,9000,'iconfont icon-shujuyuanguanli','1',0,'0',NULL,'0','','2019-08-12 09:42:11','admin','2025-01-26 22:26:51','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (9006,'表单设计',NULL,'/gen/design/index',NULL,9000,'iconfont icon-AIshiyanshi','0',2,'0','0','0','','2019-08-16 10:08:56','admin','2023-02-23 14:06:50','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (9007,'生成页面',NULL,'/gen/gener/index',NULL,9000,'iconfont icon-tongzhi4','0',1,'0','0','0','admin','2023-02-20 09:58:23','admin','2023-02-20 14:41:43','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (9050,'元数据管理',NULL,'/gen/metadata',NULL,9000,'iconfont icon-yuanshujuguanli','1',9,'0','0','0','','2018-07-27 01:13:21','admin','2023-02-23 19:55:10','0',1);
|
||||
INSERT INTO `sys_menu` VALUES (9051,'模板管理',NULL,'/gen/template/index',NULL,9050,'iconfont icon-mti-mobanguanli','1',5,'0','0','0','admin','2023-02-21 11:22:54','admin','2023-02-23 19:56:03','0',1);
|
||||
@@ -806,8 +808,8 @@ CREATE TABLE `sys_oauth_client_details` (
|
||||
`additional_information` varchar(4096) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '附加信息',
|
||||
`autoapprove` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '自动授权',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记,0未删除,1已删除',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '所属租户ID',
|
||||
@@ -818,11 +820,11 @@ CREATE TABLE `sys_oauth_client_details` (
|
||||
-- Records of sys_oauth_client_details
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (1, 'app', NULL, 'app', 'server', 'password,refresh_token,authorization_code,client_credentials,mobile', 'http://localhost:4040/sso1/login,http://localhost:4041/sso1/login,http://localhost:8080/renren-admin/sys/oauth2-sso,http://localhost:8090/sys/oauth2-sso', NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\",\"online_quantity\":\"1\"}', 'true', '0', '', 'admin', NULL, '2023-02-09 13:54:54', 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (1, 'app', NULL, 'app', 'server', 'password,refresh_token,authorization_code,mobile', 'http://localhost:4040/sso1/login,http://localhost:4041/sso1/login,http://localhost:8080/renren-admin/sys/oauth2-sso,http://localhost:8090/sys/oauth2-sso', NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\",\"online_quantity\":\"1\"}', 'true', '0', '', 'admin', NULL, '2023-02-09 13:54:54', 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (2, 'daemon', NULL, 'daemon', 'server', 'password,refresh_token', NULL, NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\"}', 'true', '0', ' ', ' ', NULL, NULL, 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (3, 'gen', NULL, 'gen', 'server', 'password,refresh_token', NULL, NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\"}', 'true', '0', ' ', ' ', NULL, NULL, 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (4, 'mp', NULL, 'mp', 'server', 'password,refresh_token', NULL, NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\"}', 'true', '0', ' ', ' ', NULL, NULL, 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (5, 'pig', NULL, 'pig', 'server', 'password,refresh_token,authorization_code,client_credentials,mobile', 'http://localhost:4040/sso1/login,http://localhost:4041/sso1/login,http://localhost:8080/renren-admin/sys/oauth2-sso,http://localhost:8090/sys/oauth2-sso', NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\",\"online_quantity\":\"1\"}', 'false', '0', '', 'admin', NULL, '2023-03-08 11:32:41', 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (5, 'pig', NULL, 'pig', 'server', 'password,refresh_token,authorization_code,mobile', 'http://localhost:4040/sso1/login,http://localhost:4041/sso1/login,http://localhost:8080/renren-admin/sys/oauth2-sso,http://localhost:8090/sys/oauth2-sso', NULL, 43200, 2592001, '{\"enc_flag\":\"1\",\"captcha_flag\":\"1\",\"online_quantity\":\"1\"}', 'false', '0', '', 'admin', NULL, '2023-03-08 11:32:41', 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (6, 'test', NULL, 'test', 'server', 'password,refresh_token', NULL, NULL, 43200, 2592001, '{ \"enc_flag\":\"1\",\"captcha_flag\":\"0\"}', 'true', '0', ' ', ' ', NULL, NULL, 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (7, 'social', NULL, 'social', 'server', 'password,refresh_token,mobile', NULL, NULL, 43200, 2592001, '{ \"enc_flag\":\"0\",\"captcha_flag\":\"0\"}', 'true', '0', ' ', ' ', NULL, NULL, 1);
|
||||
INSERT INTO `sys_oauth_client_details` VALUES (8, 'mini', NULL, 'mini', 'server', 'password,mobile', NULL, NULL, 160000000, 160000000, '{\"captcha_flag\":\"0\",\"enc_flag\":\"0\",\"online_quantity\":\"1\"}', 'true', '0', 'admin', 'admin', '2023-01-29 16:38:06', '2023-01-29 17:21:56', 1);
|
||||
@@ -865,8 +867,8 @@ CREATE TABLE `sys_public_param` (
|
||||
`public_value` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '值',
|
||||
`status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '状态,0禁用,1启用',
|
||||
`validate_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '校验码',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`public_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '类型,0未知,1系统,2业务',
|
||||
@@ -895,8 +897,8 @@ INSERT INTO `sys_public_param` VALUES (12, '强制重置密码', 'SITE_FORCE_RES
|
||||
INSERT INTO `sys_public_param` VALUES (13, '强制退出', 'SITE_FORCE_LOGOUT', '0', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (14, '短信登录开关', 'SITE_SMS_LOGIN_ENABLE', '1', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (15, '社交登录开关', 'SITE_SOCIAL_LOGIN_ENABLE', '1', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (16, '前端注册开关', 'SITE_REGISTER_ENABLE', '1', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (17, '找回/重置密码开关', 'SITE_RESET_PASSWORD', '1', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (16, '前端注册开关', 'SITE_REGISTER_ENABLE', '0', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (17, '找回/重置密码开关', 'SITE_RESET_PASSWORD', '0', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (18, '国际化切换开关', 'SITE_I18N_ENABLE', '1', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (19, '亮暗模式切换开关', 'SITE_DARK_MODE_ENABLE', '1', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
INSERT INTO `sys_public_param` VALUES (20, '反调试保护', 'SITE_ANTI_DEBUG_ENABLE', '0', '0', NULL, 'admin', 'admin', '2026-03-28 00:00:00', NULL, '2', '1', '0', 1);
|
||||
@@ -925,8 +927,8 @@ CREATE TABLE `sys_role` (
|
||||
`role_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '角色描述',
|
||||
`ds_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '2' COMMENT '数据权限类型,0全部,1自定义,2本部门及以下,3本部门,4仅本人',
|
||||
`ds_scope` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据权限范围',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记,0未删除,1已删除',
|
||||
@@ -1107,6 +1109,7 @@ INSERT INTO `sys_role_menu` VALUES (1, 4011);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 4012);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 4013);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 4014);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 4015);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 5000);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 5001);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 5002);
|
||||
@@ -1180,7 +1183,6 @@ INSERT INTO `sys_role_menu` VALUES (1, 7804);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 7805);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 9000);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 9005);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 9006);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 9007);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 9050);
|
||||
INSERT INTO `sys_role_menu` VALUES (1, 9051);
|
||||
@@ -1234,18 +1236,18 @@ CREATE TABLE `sys_role_widget` (
|
||||
DROP TABLE IF EXISTS `sys_route_conf`;
|
||||
CREATE TABLE `sys_route_conf` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键',
|
||||
`route_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
|
||||
`route_id` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
|
||||
`route_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`route_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`predicates` json DEFAULT NULL COMMENT '断言',
|
||||
`filters` json DEFAULT NULL COMMENT '过滤器',
|
||||
`uri` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
|
||||
`uri` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`sort_order` int(11) DEFAULT '0' COMMENT '排序',
|
||||
`metadata` json DEFAULT NULL COMMENT '路由元信息',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '0',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='路由配置表';
|
||||
|
||||
@@ -1281,9 +1283,9 @@ CREATE TABLE `sys_schedule` (
|
||||
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '内容',
|
||||
`schedule_time` time DEFAULT NULL COMMENT '时间',
|
||||
`schedule_date` date DEFAULT NULL COMMENT '日期',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
|
||||
`tenant_id` bigint(20) unsigned DEFAULT NULL COMMENT '租户ID',
|
||||
@@ -1308,8 +1310,8 @@ CREATE TABLE `sys_social_details` (
|
||||
`app_secret` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '应用密钥',
|
||||
`redirect_url` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '回调地址',
|
||||
`ext` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '拓展字段',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记,0未删除,1已删除',
|
||||
@@ -1398,22 +1400,15 @@ CREATE TABLE `sys_user` (
|
||||
`nickname` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '昵称',
|
||||
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名',
|
||||
`email` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '邮箱地址',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
`lock_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '锁定标记,0未锁定,9已锁定',
|
||||
`password_expire_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '密码是否过期,0未过期,9已过期',
|
||||
`password_modify_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记,0未删除,1已删除',
|
||||
`wx_openid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '微信登录openId',
|
||||
`mini_openid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '小程序openId',
|
||||
`qq_openid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'QQ openId',
|
||||
`gitee_login` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '码云标识',
|
||||
`osc_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '开源中国标识',
|
||||
`wx_cp_userid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '企业微信唯一ID',
|
||||
`wx_ding_userid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '钉钉唯一ID',
|
||||
`dept_id` bigint(20) DEFAULT NULL COMMENT '主部门ID',
|
||||
`dept_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '主部门ID',
|
||||
`tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '所属租户ID',
|
||||
PRIMARY KEY (`user_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户表';
|
||||
@@ -1422,9 +1417,24 @@ CREATE TABLE `sys_user` (
|
||||
-- Records of sys_user
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_user` VALUES (1, 'admin', '$2a$10$c/Ae0pRjJtMZg3BnvVpO.eIK6WYWVbKTzqgdy3afR7w.vd.xi3Mgy', '', '17338122125', '/admin/sys-file/local/2a14ae08150e483c93e12ac8934173e2.png', '管理员666777', '管理员', 'sw@mail.pigxl.vip', ' ', 'admin', '2018-04-20 07:15:18', '2023-04-03 14:00:06', '0', '0', NULL, '0', NULL, 'oBxPy5E-v82xWGsfzZVzkD3wEX64', NULL, 'log4j', NULL, NULL,NULL,1,1);
|
||||
INSERT INTO `sys_user` (`user_id`, `username`, `password`, `salt`, `phone`, `avatar`, `nickname`, `name`, `email`, `create_by`, `update_by`, `create_time`, `update_time`, `lock_flag`, `password_expire_flag`, `password_modify_time`, `del_flag`, `dept_id`, `tenant_id`) VALUES (1, 'admin', '$2a$10$c/Ae0pRjJtMZg3BnvVpO.eIK6WYWVbKTzqgdy3afR7w.vd.xi3Mgy', '', '17338122125', '/admin/sys-file/local/2a14ae08150e483c93e12ac8934173e2.png', '管理员666777', '管理员', 'sw@mail.pigxl.vip', ' ', 'admin', '2018-04-20 07:15:18', '2023-04-03 14:00:06', '0', '0', NULL, '0', 1, 1);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_user_social
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_user_social`;
|
||||
CREATE TABLE `sys_user_social` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
|
||||
`type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '社交平台类型',
|
||||
`identifier` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '唯一凭据',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE KEY `uk_social_identifier` (`type`,`identifier`) USING BTREE,
|
||||
UNIQUE KEY `uk_user_social_type` (`user_id`,`type`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户社交登录身份表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_user_post
|
||||
-- ----------------------------
|
||||
@@ -1480,8 +1490,12 @@ CREATE TABLE `sys_message` (
|
||||
`update_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除时间',
|
||||
`tenant_id` bigint DEFAULT NULL COMMENT '租户',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='站内信';
|
||||
`business_type` varchar(32) DEFAULT NULL COMMENT '业务类型',
|
||||
`business_id` varchar(64) DEFAULT NULL COMMENT '业务记录ID',
|
||||
`request_key` varchar(100) DEFAULT NULL COMMENT '调用方事件标识',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_message_request` (`tenant_id`,`request_key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='站内信息';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of sys_message
|
||||
@@ -1505,7 +1519,8 @@ CREATE TABLE `sys_message_relation` (
|
||||
`update_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除时间',
|
||||
`tenant_id` bigint DEFAULT NULL COMMENT '租户',
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_relation_msg_user` (`msg_id`,`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='系统消息推送记录';
|
||||
|
||||
DROP TABLE IF EXISTS `sys_system_config`;
|
||||
|
||||
+67
-8
@@ -1,3 +1,4 @@
|
||||
-- 本文件仅用于初始化,不用于升级已有数据库。
|
||||
USE pigxx_flow;
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
@@ -137,11 +138,13 @@ CREATE TABLE `process_node_data` (
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标志',
|
||||
`create_time` datetime COMMENT '创建时间',
|
||||
`update_time` datetime COMMENT '更新时间',
|
||||
`process_definition_id` varchar(64) DEFAULT NULL COMMENT '引擎流程定义ID,发布版本快照',
|
||||
`flow_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '流程id',
|
||||
`data` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '表单数据',
|
||||
`node_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '所属租户id',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE KEY `uk_node_definition` (`tenant_id`,`process_definition_id`,`node_id`),
|
||||
KEY `data_idx_id` (`id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1195 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='流程节点数据';
|
||||
|
||||
@@ -202,9 +205,21 @@ CREATE TABLE `process_node_record_assign_user` (
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE KEY `uk_node_record_user` (`tenant_id`,`node_record_id`,`user_id`) USING BTREE,
|
||||
KEY `user_idx_id` (`id`) USING BTREE,
|
||||
KEY `idx_add_sign_record_id` (`add_sign_record_id`) USING BTREE
|
||||
KEY `idx_add_sign_record_id` (`add_sign_record_id`) USING BTREE,
|
||||
KEY `idx_assign_tenant_instance_del` (`tenant_id`,`process_instance_id`,`del_flag`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=597 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='流程节点记录-执行人';
|
||||
|
||||
-- Flowable 列表查询索引:act_* 表由引擎初始化,不在本脚本中创建。
|
||||
-- 首次启动完成后,在业务库手动执行以下 SQL 一次;已有同名索引时不要重复执行。
|
||||
-- 待办:按审批人筛选、创建时间排序。
|
||||
-- ALTER TABLE `act_ru_task`
|
||||
-- ADD INDEX `idx_task_assignee_create` (`ASSIGNEE_`, `CREATE_TIME_`),
|
||||
-- ALGORITHM=INPLACE, LOCK=NONE;
|
||||
-- 已办:按审批人及结束时间查询、统计。
|
||||
-- ALTER TABLE `act_hi_actinst`
|
||||
-- ADD INDEX `idx_act_assignee_end` (`ASSIGNEE_`, `END_TIME_`),
|
||||
-- ALGORITHM=INPLACE, LOCK=NONE;
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for process_task_add_sign_record
|
||||
@@ -255,21 +270,65 @@ CREATE TABLE `process_starter` (
|
||||
DROP TABLE IF EXISTS `bmp_oa_leave`;
|
||||
CREATE TABLE `bmp_oa_leave` (
|
||||
`id` bigint NOT NULL COMMENT '请假表单主键',
|
||||
`username` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '申请人',
|
||||
`username` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '申请人',
|
||||
`leave_type` int NOT NULL COMMENT '请假类型',
|
||||
`leave_reason` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '请假原因',
|
||||
`leave_reason` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '请假原因',
|
||||
`start_time` datetime NOT NULL COMMENT '开始时间',
|
||||
`end_time` datetime NOT NULL COMMENT '结束时间',
|
||||
`leave_day` int NOT NULL COMMENT '请假天数',
|
||||
`leave_status` int DEFAULT NULL COMMENT '请假结果',
|
||||
`process_instance_id` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '流程实例的编号',
|
||||
`create_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',
|
||||
`process_instance_id` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '流程实例的编号',
|
||||
`create_by` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
|
||||
`update_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者',
|
||||
`update_by` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
|
||||
`del_flag` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '是否删除',
|
||||
`del_flag` char(1) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='请假表单';
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='请假表单';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for flow_draft
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `flow_draft`;
|
||||
CREATE TABLE `flow_draft` (
|
||||
`id` varchar(36) COLLATE utf8mb4_general_ci NOT NULL COMMENT '草稿ID',
|
||||
`tenant_id` bigint NOT NULL COMMENT '所属租户ID',
|
||||
`user_id` bigint NOT NULL COMMENT '草稿所属用户ID',
|
||||
`kind` varchar(16) COLLATE utf8mb4_general_ci NOT NULL COMMENT '草稿类型:DESIGN 流程设计,APPLICATION 申请',
|
||||
`flow_id` varchar(64) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '关联流程ID,未建立流程时为空串',
|
||||
`title` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT '草稿标题',
|
||||
`payload` longtext COLLATE utf8mb4_general_ci NOT NULL COMMENT '草稿内容 JSON,最多 1 MB',
|
||||
`revision` bigint NOT NULL COMMENT '乐观锁版本号',
|
||||
`updated_at` timestamp(3) NOT NULL COMMENT '最后保存时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_draft_owner` (`tenant_id`,`user_id`,`kind`,`updated_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='个人流程草稿';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for flow_notice
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `flow_notice`;
|
||||
CREATE TABLE `flow_notice` (
|
||||
`id` varchar(36) COLLATE utf8mb4_general_ci NOT NULL COMMENT '通知事件ID',
|
||||
`tenant_id` bigint NOT NULL COMMENT '所属租户ID',
|
||||
`user_id` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '接收人ID,超时提醒到期前为空串',
|
||||
`event_key` varchar(180) COLLATE utf8mb4_general_ci NOT NULL COMMENT '事件去重键',
|
||||
`kind` varchar(16) COLLATE utf8mb4_general_ci NOT NULL COMMENT '通知类型:TODO 待办,URGE 催办,OVERDUE 超时提醒',
|
||||
`title` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT '通知标题',
|
||||
`task_id` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '引擎任务ID',
|
||||
`instance_id` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '引擎流程实例ID',
|
||||
`created_at` timestamp(3) NOT NULL COMMENT '创建时间',
|
||||
`status` varchar(16) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'SENT' COMMENT '状态:PENDING 待到期,READY 待投递,SENT 已投递,REMOVING 待撤销,CANCELLED 已取消,DISABLED 已停用',
|
||||
`scheduled_at` timestamp(3) NULL DEFAULT NULL COMMENT '计划投递或到期时间',
|
||||
`sent_at` timestamp(3) NULL DEFAULT NULL COMMENT '投递到统一站内信的时间',
|
||||
`reminder_key` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '超时提醒任务ID,每个任务最多一条',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_notice_event` (`tenant_id`,`user_id`,`event_key`),
|
||||
UNIQUE KEY `uk_notice_reminder` (`tenant_id`,`reminder_key`),
|
||||
KEY `idx_notice_owner` (`tenant_id`,`user_id`,`created_at`),
|
||||
KEY `idx_notice_due` (`status`,`scheduled_at`),
|
||||
KEY `idx_notice_task` (`tenant_id`,`task_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='流程通知事件';
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
+70
-70
@@ -8,9 +8,9 @@ SET FOREIGN_KEY_CHECKS = 0;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_blob_triggers`;
|
||||
CREATE TABLE `qrtz_blob_triggers` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`blob_data` blob,
|
||||
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`) USING BTREE,
|
||||
CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
|
||||
@@ -27,8 +27,8 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_calendars`;
|
||||
CREATE TABLE `qrtz_calendars` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`calendar_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`calendar_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`calendar` blob NOT NULL,
|
||||
PRIMARY KEY (`sched_name`,`calendar_name`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
@@ -44,11 +44,11 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_cron_triggers`;
|
||||
CREATE TABLE `qrtz_cron_triggers` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`cron_expression` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`time_zone_id` varchar(80) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`cron_expression` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`time_zone_id` varchar(80) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`) USING BTREE,
|
||||
CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
@@ -64,19 +64,19 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_fired_triggers`;
|
||||
CREATE TABLE `qrtz_fired_triggers` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`entry_id` varchar(95) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`instance_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`entry_id` varchar(95) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`instance_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`fired_time` bigint NOT NULL,
|
||||
`sched_time` bigint NOT NULL,
|
||||
`priority` int NOT NULL,
|
||||
`state` varchar(16) CHARACTER SET utf8 NOT NULL,
|
||||
`job_name` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`job_group` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`is_nonconcurrent` varchar(1) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`requests_recovery` varchar(1) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`state` varchar(16) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`job_name` varchar(200) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`job_group` varchar(200) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`is_nonconcurrent` varchar(1) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`requests_recovery` varchar(1) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
PRIMARY KEY (`sched_name`,`entry_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
@@ -91,15 +91,15 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_job_details`;
|
||||
CREATE TABLE `qrtz_job_details` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`job_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`job_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`description` varchar(250) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`job_class_name` varchar(250) CHARACTER SET utf8 NOT NULL,
|
||||
`is_durable` varchar(1) CHARACTER SET utf8 NOT NULL,
|
||||
`is_nonconcurrent` varchar(1) CHARACTER SET utf8 NOT NULL,
|
||||
`is_update_data` varchar(1) CHARACTER SET utf8 NOT NULL,
|
||||
`requests_recovery` varchar(1) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`job_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`job_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`description` varchar(250) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`job_class_name` varchar(250) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`is_durable` varchar(1) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`is_nonconcurrent` varchar(1) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`is_update_data` varchar(1) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`requests_recovery` varchar(1) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`job_data` blob,
|
||||
PRIMARY KEY (`sched_name`,`job_name`,`job_group`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
@@ -115,8 +115,8 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_locks`;
|
||||
CREATE TABLE `qrtz_locks` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`lock_name` varchar(40) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`lock_name` varchar(40) CHARACTER SET utf8mb4 NOT NULL,
|
||||
PRIMARY KEY (`sched_name`,`lock_name`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
@@ -131,8 +131,8 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_paused_trigger_grps`;
|
||||
CREATE TABLE `qrtz_paused_trigger_grps` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
PRIMARY KEY (`sched_name`,`trigger_group`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
@@ -147,8 +147,8 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_scheduler_state`;
|
||||
CREATE TABLE `qrtz_scheduler_state` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`instance_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`instance_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`last_checkin_time` bigint NOT NULL,
|
||||
`checkin_interval` bigint NOT NULL,
|
||||
PRIMARY KEY (`sched_name`,`instance_name`) USING BTREE
|
||||
@@ -165,9 +165,9 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_simple_triggers`;
|
||||
CREATE TABLE `qrtz_simple_triggers` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`repeat_count` bigint NOT NULL,
|
||||
`repeat_interval` bigint NOT NULL,
|
||||
`times_triggered` bigint NOT NULL,
|
||||
@@ -186,20 +186,20 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_simprop_triggers`;
|
||||
CREATE TABLE `qrtz_simprop_triggers` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`str_prop_1` varchar(512) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`str_prop_2` varchar(512) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`str_prop_3` varchar(512) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`str_prop_1` varchar(512) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`str_prop_2` varchar(512) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`str_prop_3` varchar(512) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`int_prop_1` int DEFAULT NULL,
|
||||
`int_prop_2` int DEFAULT NULL,
|
||||
`long_prop_1` bigint DEFAULT NULL,
|
||||
`long_prop_2` bigint DEFAULT NULL,
|
||||
`dec_prop_1` decimal(13,4) DEFAULT NULL,
|
||||
`dec_prop_2` decimal(13,4) DEFAULT NULL,
|
||||
`bool_prop_1` varchar(1) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`bool_prop_2` varchar(1) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`bool_prop_1` varchar(1) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`bool_prop_2` varchar(1) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`) USING BTREE,
|
||||
CONSTRAINT `QRTZ_SIMPROP_TRIGGERS_IBFK_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
@@ -215,20 +215,20 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `qrtz_triggers`;
|
||||
CREATE TABLE `qrtz_triggers` (
|
||||
`sched_name` varchar(120) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`job_name` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`job_group` varchar(200) CHARACTER SET utf8 NOT NULL,
|
||||
`description` varchar(250) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`sched_name` varchar(120) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`job_name` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`job_group` varchar(200) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`description` varchar(250) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`next_fire_time` bigint DEFAULT NULL,
|
||||
`prev_fire_time` bigint DEFAULT NULL,
|
||||
`priority` int DEFAULT NULL,
|
||||
`trigger_state` varchar(16) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_type` varchar(8) CHARACTER SET utf8 NOT NULL,
|
||||
`trigger_state` varchar(16) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`trigger_type` varchar(8) CHARACTER SET utf8mb4 NOT NULL,
|
||||
`start_time` bigint NOT NULL,
|
||||
`end_time` bigint DEFAULT NULL,
|
||||
`calendar_name` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`calendar_name` varchar(200) CHARACTER SET utf8mb4 DEFAULT NULL,
|
||||
`misfire_instr` smallint DEFAULT NULL,
|
||||
`job_data` blob,
|
||||
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`) USING BTREE,
|
||||
@@ -286,22 +286,22 @@ DROP TABLE IF EXISTS `sys_job_log`;
|
||||
CREATE TABLE `sys_job_log` (
|
||||
`job_log_id` bigint NOT NULL COMMENT '任务日志ID',
|
||||
`job_id` bigint NOT NULL COMMENT '任务id',
|
||||
`job_name` varchar(64) CHARACTER SET utf8 DEFAULT NULL COMMENT '任务名称',
|
||||
`job_group` varchar(64) CHARACTER SET utf8 DEFAULT NULL COMMENT '任务组名',
|
||||
`job_order` char(1) CHARACTER SET utf8 DEFAULT NULL COMMENT '组内执行顺利,值越大执行优先级越高,最大值9,最小值1',
|
||||
`job_type` char(1) CHARACTER SET utf8 NOT NULL DEFAULT '1' COMMENT '1、java类;2、spring bean名称;3、rest调用;4、jar调用;9其他',
|
||||
`execute_path` varchar(500) CHARACTER SET utf8 DEFAULT NULL COMMENT 'job_type=3时,rest调用地址,仅支持post协议;job_type=4时,jar路径;其它值为空',
|
||||
`class_name` varchar(500) CHARACTER SET utf8 DEFAULT NULL COMMENT 'job_type=1时,类完整路径;job_type=2时,spring bean名称;其它值为空',
|
||||
`method_name` varchar(500) CHARACTER SET utf8 DEFAULT NULL COMMENT '任务方法',
|
||||
`method_params_value` varchar(2000) CHARACTER SET utf8 DEFAULT NULL COMMENT '参数值',
|
||||
`cron_expression` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT 'cron执行表达式',
|
||||
`job_message` varchar(500) CHARACTER SET utf8 DEFAULT NULL COMMENT '日志信息',
|
||||
`job_log_status` char(1) CHARACTER SET utf8 DEFAULT '0' COMMENT '执行状态(0正常 1失败)',
|
||||
`execute_time` varchar(30) CHARACTER SET utf8 DEFAULT NULL COMMENT '执行时间',
|
||||
`exception_info` varchar(2000) CHARACTER SET utf8 DEFAULT '' COMMENT '异常信息',
|
||||
`job_name` varchar(64) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '任务名称',
|
||||
`job_group` varchar(64) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '任务组名',
|
||||
`job_order` char(1) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '组内执行顺利,值越大执行优先级越高,最大值9,最小值1',
|
||||
`job_type` char(1) CHARACTER SET utf8mb4 NOT NULL DEFAULT '1' COMMENT '1、java类;2、spring bean名称;3、rest调用;4、jar调用;9其他',
|
||||
`execute_path` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'job_type=3时,rest调用地址,仅支持post协议;job_type=4时,jar路径;其它值为空',
|
||||
`class_name` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'job_type=1时,类完整路径;job_type=2时,spring bean名称;其它值为空',
|
||||
`method_name` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '任务方法',
|
||||
`method_params_value` varchar(2000) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '参数值',
|
||||
`cron_expression` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'cron执行表达式',
|
||||
`job_message` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '日志信息',
|
||||
`job_log_status` char(1) CHARACTER SET utf8mb4 DEFAULT '0' COMMENT '执行状态(0正常 1失败)',
|
||||
`execute_time` varchar(30) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '执行时间',
|
||||
`exception_info` varchar(2000) CHARACTER SET utf8mb4 DEFAULT '' COMMENT '异常信息',
|
||||
`scheduled_fire_time` datetime DEFAULT NULL COMMENT '计划触发时间',
|
||||
`fire_instance_id` varchar(128) CHARACTER SET utf8 DEFAULT NULL COMMENT 'Quartz触发实例ID',
|
||||
`dedup_status` char(1) CHARACTER SET utf8 DEFAULT '0' COMMENT '去重状态(0正常执行 1同一触发点重复 2任务运行中跳过)',
|
||||
`fire_instance_id` varchar(128) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'Quartz触发实例ID',
|
||||
`dedup_status` char(1) CHARACTER SET utf8mb4 DEFAULT '0' COMMENT '去重状态(0正常执行 1同一触发点重复 2任务运行中跳过)',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`tenant_id` bigint NOT NULL DEFAULT '1' COMMENT '租户id',
|
||||
PRIMARY KEY (`job_log_id`) USING BTREE
|
||||
|
||||
+6
-6
@@ -113,8 +113,8 @@ CREATE TABLE `wx_auto_reply` (
|
||||
`rep_thumb_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '缩略图url',
|
||||
`content` json DEFAULT NULL COMMENT '图文消息的内容',
|
||||
`app_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '公众号ID',
|
||||
`remark` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '备注',
|
||||
`del_flag` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '0' COMMENT '逻辑删除标记(0:显示;1:隐藏)',
|
||||
`remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '逻辑删除标记(0:显示;1:隐藏)',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`tenant_id` bigint(20) DEFAULT NULL COMMENT '租户ID',
|
||||
@@ -159,7 +159,7 @@ CREATE TABLE `wx_msg` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键',
|
||||
`app_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '公众号名称',
|
||||
`app_logo` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '公众号logo',
|
||||
`wx_user_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '微信用户ID',
|
||||
`wx_user_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '微信用户ID',
|
||||
`nick_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '微信用户昵称',
|
||||
`headimg_url` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '微信用户头像',
|
||||
`type` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '消息分类(1、用户发给公众号;2、公众号发给用户;)',
|
||||
@@ -177,11 +177,11 @@ CREATE TABLE `wx_msg` (
|
||||
`rep_location_x` double DEFAULT NULL COMMENT '地理位置维度',
|
||||
`rep_location_y` double DEFAULT NULL COMMENT '地理位置经度',
|
||||
`rep_scale` double DEFAULT NULL COMMENT '地图缩放大小',
|
||||
`read_flag` char(2) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '1' COMMENT '已读标记(1:是;0:否)',
|
||||
`read_flag` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '1' COMMENT '已读标记(1:是;0:否)',
|
||||
`app_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '公众号ID',
|
||||
`open_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '微信唯一标识',
|
||||
`remark` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '备注',
|
||||
`del_flag` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '0' COMMENT '逻辑删除标记(0:显示;1:隐藏)',
|
||||
`remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '逻辑删除标记(0:显示;1:隐藏)',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`tenant_id` bigint(20) DEFAULT NULL COMMENT '租户ID',
|
||||
|
||||
@@ -40,17 +40,17 @@ VALUES (1, 'application-dev.yml', 'DEFAULT_GROUP',
|
||||
'0dc3faa0d9871245282f6b7d4f2249c0', '2022-12-16 10:44:25', '2023-08-14 11:44:19', 'nacos', '127.0.0.1', '',
|
||||
'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (2, 'pigx-auth-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n freemarker:\n allow-request-override: false\n allow-session-override: false\n cache: true\n charset: UTF-8\n check-template-location: true\n content-type: text/html\n enabled: true\n expose-request-attributes: false\n expose-session-attributes: false\n expose-spring-macro-helpers: true\n prefer-file-system-access: true\n suffix: .ftl\n template-loader-path: classpath:/templates/\n\n# 前端登录验证码\nsecurity:\n encodeKey: \'pigxpigxpigxpigx\'\n# 验证码相关配置参考: http://t.cn/A647jEdu\naj:\n captcha:\n cache-type: redis\n water-mark: pig4cloud', 'bb6bd9b9e21afdec3d6c88636387df96', '2022-12-16 10:44:25', '2024-04-20 22:47:21', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (3, 'pigx-codegen-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_codegen}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/\n', 'ed6de06e34e2634c28a24e8a1db99b06', '2022-12-16 10:44:25', '2024-02-22 15:08:09', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (3, 'pigx-codegen-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_codegen}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n', 'e9ca4622d920568cb5daf08145b63b1e', '2022-12-16 10:44:25', '2024-02-22 15:08:09', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (4, 'pigx-daemon-elastic-job-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n\n# XXL-Job 配置\nxxl:\n job:\n accessToken: default_token', 'ac1b92ceacc451eac15942131e04c6dd', '2022-12-16 10:44:25', '2023-04-07 14:14:50', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (5, 'pigx-gateway-dev.yml', 'DEFAULT_GROUP', '# 固定路由转发配置 无修改\nspring:\n cloud:\n gateway:\n server:\n webflux:\n routes:\n - id: openapi\n uri: lb://pigx-gateway\n predicates:\n - Path=/v3/api-docs/**\n filters:\n - RewritePath=/v3/api-docs/(?<path>.*), /$\\{path}/$\\{path}/v3/api-docs\n\n# gateway 刷新端点\nmanagement:\n endpoint:\n gateway:\n access: unrestricted\n', 'd9454d877ff3d8bd3fd0d5be99810195', '2022-12-16 10:44:25', '2024-04-20 22:47:02', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (6, 'pigx-monitor-dev.yml', 'DEFAULT_GROUP', 'spring:\n # 安全配置\n security:\n user:\n name: ENC(rZHA4LW5hHmhLAAzJoFNag==) # pigx\n password: ENC(bjeyh+Aeii3kHXkoo00ZUw==) # pigx\n autoconfigure:\n exclude: com.pig4cloud.pigx.common.core.config.JacksonConfiguration\n boot:\n admin:\n ui:\n title: \'pigx 服务状态监控\'\n brand: \'pigx 服务状态监控\'\n external-views:\n - label: \"SQL监控\"\n url: /druid/sql.html\n order: 2000\n iframe: true\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n endpoint:\n health:\n show-details: ALWAYS #显示详细信息\n\n\n# druid 监控的服务\nmonitor:\n applications:\n - pigx-upms-biz\n', '2bb39e4dee3f90d4186d1e42aa666d2a', '2022-12-16 10:44:25', '2023-04-07 14:12:09', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (7, 'pigx-upms-biz-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n ignore-urls:\n - /druid/**\n\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n stat-view-servlet:\n enabled: true\n allow: \"\"\n url-pattern: /druid/*\n #login-username: admin\n #login-password: admin\n filter:\n stat:\n enabled: true\n log-slow-sql: true\n slow-sql-millis: 10000\n merge-sql: false\n wall:\n config:\n multi-statement-allow: true\n\n# 本地文件系统\nfile:\n type: local\n local:\n basePath: /Users/lengleng/Downloads/files', '31570b7a880625228335b7f7e5aaa312', '2022-12-16 10:44:25', '2024-02-22 15:08:36', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (8, 'pigx-daemon-quartz-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/', '79619124a30cdb6e8bc1046aaa18d91c', '2022-12-16 10:44:25', '2024-04-19 21:49:00', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (8, 'pigx-daemon-quartz-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n', 'caa1a7ea301239a18e9a43699e43707e', '2022-12-16 10:44:25', '2024-04-19 21:49:00', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (9, 'pigx-pay-platform-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_pay}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n freemarker:\n allow-request-override: false\n allow-session-override: false\n cache: true\n charset: UTF-8\n check-template-location: true\n content-type: text/html\n enabled: true\n expose-request-attributes: false\n expose-session-attributes: false\n expose-spring-macro-helpers: true\n prefer-file-system-access: true\n suffix: .ftl\n template-loader-path: classpath:/templates/\n# 租户表维护\npigx:\n pay:\n test: lengleng\n aliPayConfig:\n expire-time: 30\n return-url: http://pig4cloud.com\n notify-url: http://payx.yunjihuitong.com/pay/notify/ali/callbak\n wxPayConfig:\n notify-url: https://admin.pig4cloud.com/pay/notify/wx/callbak\n mergePayConfig:\n return-url: http://pig4cloud.com\n notify-url: http://wechat.pigx.top/pay/notify/merge/callbak\n xsequence: #发号器相关配置\n db:\n retry-times: 3\n table-name: pay_sequence', 'f4e5734a99f3c1f059071deac081b33d', '2022-12-16 10:44:25', '2024-02-22 15:09:08', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (11, 'pigx-mp-platform-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_mp}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/', 'd5936e0c352fb1fbe1d05f054f14c98a', '2022-12-16 10:44:25', '2024-02-22 15:09:20', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (11, 'pigx-mp-platform-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_mp}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n', 'ae40865200e414d06d63d96f257f372e', '2022-12-16 10:44:25', '2024-02-22 15:09:20', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (12, 'pigx-xxl-job-admin-dev.yml', 'DEFAULT_GROUP', '# XXL-Job Admin 微服务配置\n# Actuator 监控配置\nmanagement:\n endpoints:\n web:\n base-path: /actuator\n health:\n mail:\n enabled: false\n\n# Spring 配置\nspring:\n # MVC 配置\n mvc:\n servlet:\n load-on-startup: 0\n static-path-pattern: /static/**\n\n # 静态资源配置\n web:\n resources:\n static-locations: classpath:/static/\n\n # Freemarker 模板引擎配置\n freemarker:\n template-loader-path: classpath:/templates/\n suffix: .ftl\n charset: UTF-8\n request-context-attribute: request\n settings:\n number_format: 0.##########\n new_builtin_class_resolver: safer\n\n # 数据源配置\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n\n # 邮件服务配置\n mail:\n host: smtp.qq.com\n port: 25\n username: xxx@qq.com\n from: xxx@qq.com\n password: xxx\n properties:\n mail:\n smtp:\n auth: true\n starttls:\n enable: true\n required: true\n socketFactory:\n class: javax.net.ssl.SSLSocketFactory\n\n# MyBatis 配置\nmybatis:\n mapper-locations: classpath:/mapper/**/*Mapper.xml\n\n# XXL-Job 配置\nxxl:\n job:\n # 访问令牌\n accessToken: default_token\n # 超时时间(秒)\n timeout: 3\n # 国际化 (zh_CN, zh_TC, en)\n i18n: zh_CN\n # 触发器线程池最大线程数\n triggerpool:\n fast:\n max: 300\n slow:\n max: 200\n # 调度批次大小\n schedule:\n batchsize: 100\n # 日志保留天数\n logretentiondays: 30\n\n# XXL-SSO 单点登录配置\nxxl-sso:\n token:\n key: xxl_job_login_token\n timeout: 604800000\n client:\n excluded:\n paths:\n login:\n path: /auth/login', 'e4e88bd4e91599ae03854a8dfe491786', '2022-12-16 10:44:25', '2026-05-01 23:02:41', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (13, 'pigx-report-platform-dev.yml', 'DEFAULT_GROUP', 'spring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_report}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n jpa:\n database-platform: org.hibernate.dialect.MySQLDialect\n\nsecurity:\n oauth2:\n client:\n ignore-urls:\n - /\n - /api/project/getData\n - /static/**\n - /api/project/get-file/*\n\n# 文件上传路径\ngv:\n img-path: /Users/lengleng/Downloads/img/\n', 'ce3fde4b4592cdd61feb2e443b2ddfe5', '2022-12-16 10:44:25', '2023-04-07 12:56:57', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (14, 'pigx-jimu-platform-dev.yml', 'DEFAULT_GROUP', 'spring:\n #配置静态资源\n mvc:\n static-path-pattern: /**\n resource:\n static-locations: classpath:/static/\n #配置数据库\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_bi}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n \n#JimuReport[minidao配置]\nminidao :\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\n db-type: mysql\n#JimuReport[上传配置]\njeecg :\n jmreport:\n customPrePath: /api/jimu\n # 自动保存\n autoSave: true\n # 单位毫秒 默认5*60*1000 \n interval: 10000\n # local|minio|alioss\n uploadType: local\n # local\n path :\n #文件路径A\n upload: ~/jimu/data\n # alioss\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n staticDomain: ??\n bucketName: ??\n # minio\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: ??\n#输出sql日志\nlogging:\n level:\n org.jeecg.modules.jmreport : debug', '608f41b13df1e7f5556fe7b8db0ff8be', '2022-12-16 10:44:25', '2024-01-30 20:44:36', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (14, 'pigx-jimu-platform-dev.yml', 'DEFAULT_GROUP', 'spring:\n #配置静态资源\n mvc:\n static-path-pattern: /**\n #配置数据库\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_bi}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n \n#JimuReport[minidao配置]\nminidao :\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\n db-type: mysql\n#JimuReport[上传配置]\njeecg :\n jmreport:\n customPrePath: /api/jimu\n # 自动保存\n autoSave: true\n # 单位毫秒 默认5*60*1000 \n interval: 10000\n # local|minio|alioss\n uploadType: local\n # local\n path :\n #文件路径A\n upload: ~/jimu/data\n # alioss\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n staticDomain: ??\n bucketName: ??\n # minio\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: ??\n#输出sql日志\nlogging:\n level:\n org.jeecg.modules.jmreport : debug', '898d86e9ae9110a0081f7d346487fe6a', '2022-12-16 10:44:25', '2024-01-30 20:44:36', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (15, 'pigx-app-server-biz-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_app}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true', 'e4668a1854e92a5a666e83479ef7d26a', '2022-12-19 10:30:07', '2024-02-22 15:09:50', 'nacos', '127.0.0.1', '', 'public', '', '', '', 'yaml', '', '');
|
||||
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (16, 'pigx-flow-biz-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_flow}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true\n\n# flowable 配置\nflowable:\n variable-json-mapper: jackson2', '233121e20445609e1ba378c3686ea7d5', '2023-07-28 13:41:32', '2023-07-28 13:43:36', 'nacos', '127.0.0.1', '', 'public', 'flowable 工作引擎', '', '', 'yaml', '', '');
|
||||
COMMIT;
|
||||
|
||||
+53
-76
@@ -107,29 +107,6 @@ INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`,
|
||||
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (49,'bytea','String',NULL,'textarea','text','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for gen_form_conf
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `gen_form_conf`;
|
||||
CREATE TABLE `gen_form_conf` (
|
||||
`id` bigint NOT NULL COMMENT 'ID',
|
||||
`ds_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据库名称',
|
||||
`table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '表名称',
|
||||
`form_info` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '表单信息',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0',
|
||||
`tenant_id` bigint DEFAULT NULL COMMENT '所属租户',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `table_name` (`table_name`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='表单配置';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of gen_form_conf
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for gen_group
|
||||
-- ----------------------------
|
||||
@@ -139,8 +116,8 @@ CREATE TABLE `gen_group` (
|
||||
`group_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '分组名称',
|
||||
`group_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '分组描述',
|
||||
`tenant_id` bigint NOT NULL COMMENT '租户ID',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建人',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '修改人',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
|
||||
@@ -151,10 +128,10 @@ CREATE TABLE `gen_group` (
|
||||
-- Records of gen_group
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (1,'单表增删改查V2026001',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (2,'主子表增删改查V2026001',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (3,'树形表格增删改查V2026001',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (4,'左树右表增删改查V2026001',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (1,'单表增删改查V202611',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (2,'主子表增删改查V202611',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (3,'树形表格增删改查V202611',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (4,'左树右表增删改查V202611',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
@@ -250,8 +227,8 @@ CREATE TABLE `gen_template` (
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '删除标记',
|
||||
`tenant_id` bigint NOT NULL COMMENT '租户ID',
|
||||
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='模板';
|
||||
|
||||
@@ -259,51 +236,51 @@ CREATE TABLE `gen_template` (
|
||||
-- Records of gen_template
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (1,'ControllerV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','ControllerV2026001','package ${package}.${moduleName}.controller;\n\n#if($queryList)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"分页查询\" , description = \"分页查询\" )\n @GetMapping(\"/page\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#foreach ($field in $queryList)\n#set($getAttrName=$str.getProperty($field.attrName))\n#set($var=\"${className}.$getAttrName()\")\n#if($field.attrType == \'String\')\n#set($expression=\"StrUtil.isNotBlank\")\n#else\n#set($expression=\"Objects.nonNull\")\n#end\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n if (ArrayUtil.isNotEmpty(${className}.${getAttrName}Range())) {\n wrapper.between(${ClassName}Entity::$getAttrName, ${className}.${getAttrName}Range()[0], ${className}.${getAttrName}Range()[1]);\n }\n#elseif($field.queryType == \'=\')\n wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'like\' )\n wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'!-\' )\n wrapper.ne($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>\' )\n wrapper.gt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<\' )\n wrapper.lt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>=\' )\n wrapper.ge($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<=\' )\n wrapper.le($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'left like\' )\n wrapper.likeLeft($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'right like\' )\n wrapper.likeRight($expression($var),${ClassName}Entity::$getAttrName,$var);\n#end\n#end\n return R.ok(${className}Service.page(page, wrapper));\n }\n\n\n /**\n * 通过条件查询${tableComment}\n * @param ${className} 查询条件\n * @return R 对象列表\n */\n @Operation(summary = \"通过条件查询\" , description = \"通过条件查询对象\" )\n @GetMapping(\"/details\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #elsLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (2,'ServiceV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','ServiceV2026001','package ${package}.${moduleName}.service;\n\nimport com.baomidou.mybatisplus.extension.service.IService;\nimport ${entityClassName};\n\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (3,'ServiceImplV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','ServiceImplV2026001','package ${package}.${moduleName}.service.impl;\n\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport org.springframework.stereotype.Service;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (4,'实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(\"${tableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (5,'MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV2026001','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (6,'Mapper.xmlV2026001','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV2026001','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (7,'权限菜单V2026001','${backendPath}/menu/${functionName}_menu.sql','权限菜单V2026001','-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (8,'api.tsV2026001','${frontendPath}/src/api/${moduleName}/${functionName}.ts','api.tsV2026001','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n\n#if($ChildClassName)\n// ========== 子表相关接口 ==========\n\n/**\n * 删除子表数据\n * @param ids - 要删除的子表数据ID数组\n * @returns Promise<操作结果>\n */\nexport function delChildObj(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/child\',\n method: \'delete\',\n data: ids\n })\n}\n#end\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (9,'表格V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','表格V2026001','<template>\n <div class=\"layout-padding\">\n <div class=\"layout-padding-auto layout-padding-view\">\n#if($queryList)\n <!-- 查询表单区域 -->\n <el-row v-show=\"showSearch\">\n <el-form :model=\"state.queryForm\" ref=\"queryRef\" :inline=\"true\" @keyup.enter=\"getDataList\">\n#foreach($field in $queryList)\n#if($field.queryFormType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"state.queryForm.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option \n :label=\"item.label\" \n :value=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n :key=\"index\"\n />\n#else\n <el-option label=\"请选择\" value=\"0\" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"date\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"daterange\"\n range-separator=\"至\"\n start-placeholder=\"开始日期\"\n end-placeholder=\"结束日期\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"datetime\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"datetimerange\"\n range-separator=\"至\"\n start-placeholder=\"开始时间\"\n end-placeholder=\"结束时间\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"state.queryForm.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio \n :label=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n border \n :key=\"index\"\n >\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>\n ${field.fieldComment}\n </el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input \n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" \n v-model=\"state.queryForm.${field.attrName}\" \n />\n </el-form-item>\n#end\n#end\n <el-form-item>\n <el-button icon=\"search\" type=\"primary\" @click=\"getDataList\">\n 查询\n </el-button>\n <el-button icon=\"Refresh\" @click=\"resetQuery\">重置</el-button>\n </el-form-item>\n </el-form>\n </el-row>\n#end\n\n <!-- 操作按钮区域 -->\n <el-row>\n <div class=\"mb8\" style=\"width: 100Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (10,'表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','表单V2026001','<template>\n <el-dialog :title=\"form.${pk.attrName} ? \'编辑\' : \'新增\'\" v-model=\"visible\"\n :close-on-click-modal=\"false\" draggable>\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" label-width=\"90px\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetime\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"daterange\" range-separator=\"至\" start-placeholder=\"开始日期\" end-placeholder=\"结束日期\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (11,'主子ServiceV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','主子ServiceV2026001','package ${package}.${moduleName}.service;\n\nimport com.github.yulichang.extension.mapping.base.MPJDeepService;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\n\npublic interface ${ClassName}Service extends MPJDeepService<${ClassName}Entity> {\n Boolean saveDeep(${ClassName}Entity ${className});\n\n Boolean updateDeep(${ClassName}Entity ${className});\n\n Boolean removeDeep(Long[] ids);\n\n Boolean removeChild(Long[] ids);\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (12,'主子ServiceImplV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','主子ServiceImplV2026001','package ${package}.${moduleName}.service.impl;\n\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport org.springframework.stereotype.Service;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${package}.${moduleName}.mapper.${ChildClassName}Mapper;\nimport org.springframework.transaction.annotation.Transactional;\nimport lombok.RequiredArgsConstructor;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n private final ${ChildClassName}Mapper ${childClassName}Mapper;\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean saveDeep(${ClassName}Entity ${className}) {\n baseMapper.insert(${className});\n for (${ChildClassName}Entity ${childClassName} : ${className}.get${ChildClassName}List()) {\n ${childClassName}.$str.setProperty($childField)(${className}.$str.getProperty($mainField)());\n ${childClassName}Mapper.insert( ${childClassName});\n }\n\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean updateDeep(${ClassName}Entity ${className}) {\n baseMapper.updateById(${className});\n for (${ChildClassName}Entity ${childClassName} : ${className}.get${ChildClassName}List()) {\n#set($getChildPkName=$str.getProperty(${pk.attrName}))\n if (Objects.isNull(${childClassName}.$getChildPkName())) {\n ${childClassName}.$str.setProperty($childField)(${className}.$str.getProperty($mainField)());\n ${childClassName}Mapper.insert(${childClassName});\n } else {\n ${childClassName}Mapper.updateById(${childClassName});\n }\n }\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeDeep(Long[] ids) {\n baseMapper.deleteBatchIds(CollUtil.toList(ids));\n ${childClassName}Mapper.delete(Wrappers.<${ChildClassName}Entity>lambdaQuery().in(${ChildClassName}Entity::$str.getProperty($childField), ids));\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeChild(Long[] ids) {\n ${childClassName}Mapper.deleteBatchIds(CollUtil.toList(ids));\n return Boolean.TRUE;\n }\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (13,'主实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','主实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\nimport $import;\n#end\nimport org.apache.fesod.sheet.annotation.ExcelIgnore;\nimport com.github.yulichang.annotation.EntityMapping;\nimport java.util.List;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(\"${tableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n @TableField(typeHandler = JacksonTypeHandler.class)\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n @ExcelIgnore\n @TableField(exist = false)\n @EntityMapping(thisField = \"$mainField\", joinField = \"$childField\")\n private List<${ChildClassName}Entity> ${childClassName}List;\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (14,'MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV2026001','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (15,'Mapper.xmlV2026001','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV2026001','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (16,'权限菜单V2026001','${backendPath}/menu/${functionName}_menu.sql','权限菜单V2026001','-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (17,'api.tsV2026001','${frontendPath}/src/api/${moduleName}/${functionName}.ts','api.tsV2026001','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n\n#if($ChildClassName)\n// ========== 子表相关接口 ==========\n\n/**\n * 删除子表数据\n * @param ids - 要删除的子表数据ID数组\n * @returns Promise<操作结果>\n */\nexport function delChildObj(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/child\',\n method: \'delete\',\n data: ids\n })\n}\n#end\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (18,'子实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ChildClassName}Entity.java','子实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\n#if($isChildTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isChildTenant)\n@TenantTable\n#end\n@TableName(\"${childTableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${childTableName}\")\npublic class ${ChildClassName}Entity extends Model<${ChildClassName}Entity> {\n\n#foreach ($field in $childFieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end \n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (19,'主子ControllerV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','主子ControllerV2026001','package ${package}.${moduleName}.controller;\n\n#if($queryList)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"分页查询\" , description = \"分页查询\" )\n @GetMapping(\"/page\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#foreach ($field in $queryList)\n#set($getAttrName=$str.getProperty($field.attrName))\n#set($var=\"${className}.$getAttrName()\")\n#if($field.attrType == \'String\')\n#set($expression=\"StrUtil.isNotBlank\")\n#else\n#set($expression=\"Objects.nonNull\")\n#end\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n if (ArrayUtil.isNotEmpty(${className}.${getAttrName}Range())) {\n wrapper.between(${ClassName}Entity::$getAttrName, ${className}.${getAttrName}Range()[0], ${className}.${getAttrName}Range()[1]);\n }\n#elseif($field.queryType == \'=\')\n wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'like\' )\n wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'!-\' )\n wrapper.ne($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>\' )\n wrapper.gt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<\' )\n wrapper.lt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>=\' )\n wrapper.ge($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<=\' )\n wrapper.le($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'left like\' )\n wrapper.likeLeft($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'right like\' )\n wrapper.likeRight($expression($var),${ClassName}Entity::$getAttrName,$var);\n#end\n#end\n return R.ok(${className}Service.page(page, wrapper));\n }\n\n\n /**\n * 通过条件查询${tableComment}\n * @param ${className} 查询条件\n * @return R 对象列表\n */\n @Operation(summary = \"通过条件查询\" , description = \"通过条件查询对象\" )\n @GetMapping(\"/details\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (20,'主子表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','主子表单V2026001','<template>\n <el-drawer :title=\"form.${pk.attrName} ? (detail ? \'详情\' : \'编辑\') : \'添加\'\" v-model=\"visible\" size=\"50%\">\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" :disabled=\"detail\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetime\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"daterange\" range-separator=\"至\" start-placeholder=\"开始日期\" end-placeholder=\"结束日期\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldNaLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (21,'主子表格V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','主子表格V2026001','<template>\n <div class=\"layout-padding\">\n <div class=\"layout-padding-auto layout-padding-view\">\n#if($queryList)\n <el-row v-show=\"showSearch\">\n <el-form :model=\"state.queryForm\" ref=\"queryRef\" :inline=\"true\" @keyup.enter=\"getDataList\">\n#foreach($field in $queryList)\n#if($field.queryFormType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"state.queryForm.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option \n :label=\"item.label\" \n :value=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n :key=\"index\">\n </el-option>\n#else\n <el-option label=\"请选择\">0</el-option>\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"date\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n :value-format=\"dateStr\"\n v-model=\"state.queryForm.${field.attrName}\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"daterange\"\n range-separator=\"至\"\n start-placeholder=\"开始日期\"\n end-placeholder=\"结束日期\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"datetime\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n :value-format=\"dateTimeStr\"\n v-model=\"state.queryForm.${field.attrName}\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"datetimerange\"\n range-separator=\"至\"\n start-placeholder=\"开始时间\"\n end-placeholder=\"结束时间\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"state.queryForm.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio \n :label=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n border \n :key=\"index\">\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input \n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" \n v-model=\"state.queryForm.${field.attrName}\"\n style=\"max-width: 180px\" \n />\n </el-form-item>\n#end\n#end\n <el-form-item>\n <el-button icon=\"search\" type=\"primary\" @click=\"getDataList\">\n 查询\n </el-button>\n <el-button icon=\"Refresh\" @click=\"resetQuery\">重置</el-button>\n </el-form-item>\n </el-form>\n </el-row>\n#end\n <el-row>\n <div class=\"mb8\" style=\"width: 100%\">\n <el-button \n icon=\"folder-adLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (22,'子MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ChildClassName}Mapper.java','子MapperV2026001','package ${package}.${moduleName}.mapper;\n\nimport ${package}.common.data.datascope.PigxBaseMapper;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ChildClassName}Mapper extends PigxBaseMapper<${ChildClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (23,'树形ControllerV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','树形ControllerV2026001','package ${package}.${moduleName}.controller;\n\n#if($queryList)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 获取树形列表\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"获取树形列表\" , description = \"获取树形列表\" )\n @GetMapping(\"/tree\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R get${ClassName}Tree(@ParameterObject ${ClassName}Entity ${className}) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#foreach ($field in $queryList)\n#set($getAttrName=$str.getProperty($field.attrName))\n#set($var=\"${className}.$getAttrName()\")\n#if($field.attrType == \'String\')\n#set($expression=\"StrUtil.isNotBlank\")\n#else\n#set($expression=\"Objects.nonNull\")\n#end\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n if (ArrayUtil.isNotEmpty(${className}.${getAttrName}Range())) {\n wrapper.between(${ClassName}Entity::$getAttrName, ${className}.${getAttrName}Range()[0], ${className}.${getAttrName}Range()[1]);\n }\n#elseif($field.queryType == \'=\')\n wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'like\' )\n wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'!-\' )\n wrapper.ne($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>\' )\n wrapper.gt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<\' )\n wrapper.lt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>=\' )\n wrapper.ge($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<=\' )\n wrapper.le($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'left like\' )\n wrapper.likeLeft($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'right like\' )\n wrapper.likeRight($expression($var),${ClassName}Entity::$getAttrName,$var);\n#end\n#end\n return R.ok(${className}Service.buildTree(wrapper));\n }\n\n /**\n * 通过条件查询${tableComment}\n * @param ${className} 查询条件\n * @return R 对象列表\n */\n @Operation(summary = \"通过条件查询\" , description = \"通过条件查询对象\" )\n @GetMapping(\"/details\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (24,'树形ServiceV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','树形ServiceV2026001','package ${package}.${moduleName}.service;\n\nimport cn.hutool.core.lang.tree.Tree;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.extension.service.IService;\nimport ${entityClassName};\n\nimport java.util.List;\n\n/**\n * ${tableComment} Service接口\n *\n * @author ${author}\n * @date ${datetime}\n */\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n List<Tree<${pk.attrType}>> buildTree(LambdaQueryWrapper<${ClassName}Entity> wrapper);\n\n /**\n * 递归删除节点及其子节点\n * @param ids 要删除的节点ID列表\n * @return 删除结果\n */\n boolean removeBatchByIds(List<${pk.attrType}> ids);\n} ','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (25,'树形ServiceImplV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','树形ServiceImplV2026001','package ${package}.${moduleName}.service.impl;\n\nimport cn.hutool.core.collection.CollUtil;\nimport cn.hutool.core.lang.tree.Tree;\nimport cn.hutool.core.lang.tree.TreeNode;\nimport cn.hutool.core.lang.tree.TreeUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport jakarta.validation.constraints.NotNull;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.stream.Collectors;\n\n/**\n * ${tableComment} Service实现类\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n @Override\n public List<Tree<${pk.attrType}>> buildTree(LambdaQueryWrapper<${ClassName}Entity> wrapper) {\n // 查询所有数据\n List<${ClassName}Entity> allList = list(wrapper);\n \n if (CollUtil.isEmpty(allList)) {\n return new ArrayList<>();\n }\n\n // 转换为TreeNode\n List<TreeNode<${pk.attrType}>> collect = allList.stream().map(getNodeFunction()).toList();\n\n // 使用TreeUtil构建树形结构,根节点ID为0\n#if($pk.attrType == \'Long\')\n return TreeUtil.build(collect, 0L);\n#else\n return TreeUtil.build(collect, 0);\n#end\n }\n\n /**\n * 获取TreeNode转换函数\n * @return TreeNode转换函数\n */\n @NotNull\n private Function<${ClassName}Entity, TreeNode<${pk.attrType}>> getNodeFunction() {\n return entity -> {\n TreeNode<${pk.attrType}> node = new TreeNode<>();\n node.setId(entity.$str.getProperty($pk.attrName)());\n node.setName(entity.$str.getProperty($nameField)());\n node.setParentId(entity.$str.getProperty($parentField)() != null ? entity.$str.getProperty($parentField)() : 0L);\n\n // 扩展属性\n Map<String, Object> extra = new HashMap<>();\n#foreach($field in $fieldList)\n extra.put(${ClassName}Entity.Fields.${field.attrName}, entity.$str.getProperty($field.attrName)());\n#end\n node.setExtra(extra);\n return node;\n };\n }\n\n /**\n * 递归删除节点及其子节点\n * @param ids 要删除的节点ID列表\n * @return 删除结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public boolean removeBatchByIds(List<${pk.attrType}> ids) {\n if (CollUtil.isEmpty(ids)) {\n return true;\n }\n\n // 获取所有要删除的ID(包括子节点)\n List<${pk.attrType}> allDeleteIds = new ArrayList<>(ids);\n \n for (${pk.attrType} id : ids) {\n List<${pk.attrType}> childIds = getChildIdsRecursive(id);\n allDeleteIds.addAll(childIds);\n }\n\n // 去重\n allDeleteIds = allDeleteIds.stream().distinct().collect(Collectors.toList());\n\n // 批量删除\n return super.removeBatchByIds(allDeleteIds);\n }\n\n /**\n * 递归获取所有子节点ID\n * @param parentId 父节点ID\n * @return 子节点ID列表\n */\n private List<${pk.attrType}> getChildIdsRecursive(${pk.attrType} parentId) {\n List<${pk.attrType}> childIds = new ArrayList<>();\n \n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n wrapper.eq(${ClassName}Entity::$str.getProperty($parentField), parentId);\n wrapper.select(${ClassName}Entity::$str.getProperty($pk.attrName));\n \n List<${ClassName}Entity> children = list(wrapper);\n \n for (${ClassName}Entity child : children) {\n ${pk.attrType} childId = child.$str.getProperty($pk.attrName)();\n childIds.add(childId);\n // 递归获取子节点的子节点\n childIds.addAll(getChildIdsRecursive(childId));\n }\n \n return childIds;\n }\n} ','2026-04-08 17:38Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (26,'树形实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','树形实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\nimport lombok.experimental.FieldNameConstants;\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@FieldNameConstants\n@TableName(\"${tableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (27,'MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV2026001','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (28,'Mapper.xmlV2026001','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV2026001','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (29,'权限菜单V2026001','${backendPath}/menu/${functionName}_menu.sql','权限菜单V2026001','-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (30,'树形api.tsV2026001','${frontendPath}/src/api/${moduleName}/${functionName}.ts','树形api.tsV2026001','import request from \"/@/utils/request\"\n\n// ========== 树形表格CRUD接口 ==========\n\n/**\n * 获取树形列表数据\n * @param query - 查询参数对象\n * @returns Promise<树形数据>\n */\nexport function fetchTreeList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据(递归删除子节点)\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (31,'树形表格V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','树形表格V2026001','<template>\n <div class=\"layout-padding\">\n <div class=\"layout-padding-auto layout-padding-view\">\n#if($queryList)\n <!-- 查询表单区域 -->\n <el-row v-show=\"showSearch\">\n <el-form :model=\"state.queryForm\" ref=\"queryRef\" :inline=\"true\" @keyup.enter=\"getDataList\">\n#foreach($field in $queryList)\n#if($field.queryFormType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"state.queryForm.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option \n :label=\"item.label\" \n :value=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n :key=\"index\"\n />\n#else\n <el-option label=\"请选择\" value=\"0\" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker \n type=\"date\" \n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" \n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"datetime\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"daterange\"\n range-separator=\"至\"\n start-placeholder=\"开始日期\"\n end-placeholder=\"结束日期\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"datetimerange\"\n range-separator=\"至\"\n start-placeholder=\"开始时间\"\n end-placeholder=\"结束时间\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"state.queryForm.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio \n :label=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n border \n :key=\"index\"\n >\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>\n ${field.fieldComment}\n </el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input \n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" \n v-model=\"state.queryForm.${field.attrName}\" \n />\n </el-form-item>\n#end\n#end\n <el-form-item>\n <el-button icon=\"search\" type=\"primary\" @click=\"getDataList\">\n 查询\n </el-button>\n <el-button icon=\"Refresh\" @click=\"resetQuery\">重置</el-button>\n </el-form-item>\n </el-form>\n </el-row>\n#end\n\n <!-- 操作按钮区域 -->\n <el-row>\n <div class=\"mb8\" stLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (32,'树形表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','树形表单V2026001','<template>\n <el-dialog :title=\"form.${pk.attrName} ? \'编辑\' : \'新增\'\" v-model=\"visible\"\n :close-on-click-modal=\"false\" draggable>\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" formDialogRef label-width=\"90px\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n <!-- 父级节点选择 -->\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n <el-form-item label=\"父级节点\" prop=\"${parentField}\">\n <el-tree-select\n v-model=\"form.${parentField}\"\n :data=\"parentNodes\"\n :props=\"treeSelectProps\"\n check-strictly\n :render-after-expand=\"false\"\n placeholder=\"请选择父级节点\"\n style=\"width: 100%\"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${parentField})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetime\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${fieLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (33,'ControllerV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','ControllerV2026001','package ${package}.${moduleName}.controller;\n\nimport cn.hutool.core.util.StrUtil;\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($childFieldGetter = $str.getProperty($childField))\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"分页查询\" , description = \"分页查询\" )\n @GetMapping(\"/page\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#foreach ($field in $queryList)\n#set($getAttrName=$str.getProperty($field.attrName))\n#set($var=\"${className}.$getAttrName()\")\n#if($field.attrType == \'String\')\n#set($expression=\"StrUtil.isNotBlank\")\n#else\n#set($expression=\"Objects.nonNull\")\n#end\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n if (ArrayUtil.isNotEmpty(${className}.${getAttrName}Range())) {\n wrapper.between(${ClassName}Entity::$getAttrName, ${className}.${getAttrName}Range()[0], ${className}.${getAttrName}Range()[1]);\n }\n#elseif($field.queryType == \'=\')\n wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'like\' )\n wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'!-\' )\n wrapper.ne($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>\' )\n wrapper.gt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<\' )\n wrapper.lt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>=\' )\n wrapper.ge($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<=\' )\n wrapper.le($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'left like\' )\n wrapper.likeLeft($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'right like\' )\n wrapper.likeRight($expression($var),${ClassName}Entity::$getAttrName,$var);\n#end\n#end\n#if($childField)\n if (Objects.nonNull(${className}.$childFieldGetter())) {\n wrapper.eq(${ClassName}Entity::$str.getProperty($childField), ${className}.$childFieldGetter());\n }\n#end\n return R.ok(${className}Service.pLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (34,'ServiceV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','ServiceV2026001','package ${package}.${moduleName}.service;\n\nimport cn.hutool.core.lang.tree.Tree;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.extension.service.IService;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\n\nimport java.util.List;\n\n/**\n * ${tableComment} Service接口\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n List<Tree<${childPkField.attrType}>> buildTree(LambdaQueryWrapper<${ChildClassName}Entity> wrapper);\n\n /**\n * 获取树节点详情\n * @param ${childClassName} 树节点查询对象\n * @return 树节点详情列表\n */\n List<${ChildClassName}Entity> getTreeDetails(${ChildClassName}Entity ${childClassName});\n\n /**\n * 保存树节点\n * @param ${childClassName} 树节点对象\n * @return 保存结果\n */\n Boolean saveTree(${ChildClassName}Entity ${childClassName});\n\n /**\n * 更新树节点\n * @param ${childClassName} 树节点对象\n * @return 更新结果\n */\n Boolean updateTree(${ChildClassName}Entity ${childClassName});\n\n /**\n * 批量删除树节点\n * @param ids 树节点ID列表\n * @return 删除结果\n */\n Boolean removeTreeByIds(${childPkField.attrType}[] ids);\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (35,'ServiceImplV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','ServiceImplV2026001','package ${package}.${moduleName}.service.impl;\n\nimport cn.hutool.core.collection.CollUtil;\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.lang.tree.Tree;\nimport cn.hutool.core.lang.tree.TreeNode;\nimport cn.hutool.core.lang.tree.TreeUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ChildClassName}Mapper;\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\nimport java.util.function.Function;\n\n/**\n * ${tableComment} Service实现类\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#set($childPkGetter = $str.getProperty($childPkField.attrName))\n#break\n#end\n#end\n#set($parentGetter = $str.getProperty($parentField))\n#set($childFieldGetter = $str.getProperty($childField))\n#if($childPkField.attrType == \'Long\')\n#set($treeRootId = \'0L\')\n#elseif($childPkField.attrType == \'String\')\n#set($treeRootId = \'\"0\"\')\n#else\n#set($treeRootId = \'0\')\n#end\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n private final ${ChildClassName}Mapper ${childClassName}Mapper;\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n @Override\n public List<Tree<${childPkField.attrType}>> buildTree(LambdaQueryWrapper<${ChildClassName}Entity> wrapper) {\n List<${ChildClassName}Entity> allList = ${childClassName}Mapper.selectList(wrapper);\n\n if (CollUtil.isEmpty(allList)) {\n return new ArrayList<>();\n }\n\n List<TreeNode<${childPkField.attrType}>> collect = allList.stream().map(getNodeFunction()).toList();\n return TreeUtil.build(collect, ${treeRootId});\n }\n\n /**\n * 获取树节点详情\n * @param ${childClassName} 树节点查询对象\n * @return 树节点详情列表\n */\n @Override\n public List<${ChildClassName}Entity> getTreeDetails(${ChildClassName}Entity ${childClassName}) {\n return ${childClassName}Mapper.selectList(Wrappers.query(${childClassName}));\n }\n\n /**\n * 保存树节点\n * @param ${childClassName} 树节点对象\n * @return 保存结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean saveTree(${ChildClassName}Entity ${childClassName}) {\n ${childClassName}.$str.setProperty($parentField)(validateParentRelation(null, ${childClassName}.$str.getProperty($parentField)()));\n return ${childClassName}Mapper.insert(${childClassName}) > 0;\n }\n\n /**\n * 更新树节点\n * @param ${childClassName} 树节点对象\n * @return 更新结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean updateTree(${ChildClassName}Entity ${childClassName}) {\n ${childClassName}.$str.setProperty($parentField)(validateParentRelation(${childClassName}.$str.getProperty($childPkField.attrName)(), ${childClassName}.$str.getProperty($parentField)()));\n return ${childClassName}Mapper.updateById(${childClassName}) > 0;\n }\n\n /**\n * 批量删除树节点\n * @param ids 树节点ID列表\n * @return 删除结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeTreeByIds(${childPkField.attrType}[] ids) {\n if (ArrayUtil.isEmpty(ids)) {\n return Boolean.TRUE;\n }\n\n for (${childPkField.attrType} id : ids) {\n if (hasChildNodes(id)) {\n throw new RuntimeException(\"当前节点存在子节点,不能删除\");\n }\n if (hasMainRecords(id)) {\n throw new RuntimeException(\"当前节点已关联主表数据,不能删除\");\n }\n }\n\n return ${childClassName}Mapper.deleteBatchLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (36,'实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(\"${tableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (37,'MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV2026001','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (38,'Mapper.xmlV2026001','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV2026001','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (39,'子实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ChildClassName}Entity.java','子实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\n#if($isChildTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isChildTenant)\n@TenantTable\n#end\n@TableName(\"${childTableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${childTableName}\")\npublic class ${ChildClassName}Entity extends Model<${ChildClassName}Entity> {\n\n#foreach ($field in $childFieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end \n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (40,'子MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ChildClassName}Mapper.java','子MapperV2026001','package ${package}.${moduleName}.mapper;\n\nimport ${package}.common.data.datascope.PigxBaseMapper;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ChildClassName}Mapper extends PigxBaseMapper<${ChildClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (41,'权限菜单V2026001','${backendPath}/menu/${functionName}_menu.sql','权限菜单V2026001','-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (42,'api.tsV2026001','${frontendPath}/src/api/${moduleName}/${functionName}.ts','api.tsV2026001','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 树形CRUD接口 ==========\n\n/**\n * 获取树形列表数据\n * @param query - 查询参数对象\n * @returns Promise<树形数据>\n */\nexport function fetchTreeList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 获取树节点详情\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<树节点详情>\n */\nexport function getTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 新增树节点\n * @param obj - 要新增的树节点对象\n * @returns Promise<操作结果>\n */\nexport function addTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 更新树节点\n * @param obj - 要更新的树节点对象\n * @returns Promise<操作结果>\n */\nexport function putTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'put\',\n data: obj\n })\n}\n\n/**\n * 删除树节点\n * @param ids - 要删除的树节点ID数组\n * @returns Promise<操作结果>\n */\nexport function delTreeObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'delete\',\n data: ids\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n *\n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (43,'表格V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','表格V2026001','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n<template>\n <div class=\"layout-padding\">\n <splitpanes>\n <pane size=\"15\">\n <div class=\"layout-padding-auto layout-padding-view\">\n <el-scrollbar>\n <div class=\"mb8\" style=\"display: flex; align-items: center; justify-content: space-between;\">\n <span style=\"font-weight: 500;\">左侧节点</span>\n <div>\n <el-tooltip :content=\"currentTreeId ? \'新增子节点\' : \'新增根节点\'\" placement=\"top\">\n <el-button link type=\"primary\" icon=\"FolderAdd\" @click=\"handleAddTree\" />\n </el-tooltip>\n </div>\n </div>\n <el-tree\n ref=\"treeRef\"\n :data=\"treeData\"\n :props=\"treeProps\"\n node-key=\"${childPkField.attrName}\"\n highlight-current\n default-expand-all\n :expand-on-click-node=\"false\"\n @node-click=\"handleTreeNodeClick\"\n >\n <template #default=\"{ node, data }\">\n <span style=\"flex: 1; display: flex; align-items: center; justify-content: space-between;\">\n <span>{{ node.label }}</span>\n <span v-if=\"currentTreeId === data.${childPkField.attrName}\" style=\"margin-left: 8px;\">\n <el-tooltip content=\"编辑\" placement=\"top\">\n <el-button link type=\"primary\" icon=\"Edit\" size=\"small\" @click.stop=\"handleEditTree\" />\n </el-tooltip>\n <el-tooltip content=\"删除\" placement=\"top\">\n <el-button link type=\"danger\" icon=\"Delete\" size=\"small\" @click.stop=\"handleDeleteTree\" />\n </el-tooltip>\n </span>\n </span>\n </template>\n </el-tree>\n </el-scrollbar>\n </div>\n </pane>\n <pane class=\"ml8\">\n <div class=\"layout-padding-auto layout-padding-view\">\n#if($queryList)\n <el-row v-show=\"showSearch\">\n <el-form :model=\"state.queryForm\" ref=\"queryRef\" :inline=\"true\" @keyup.enter=\"getDataList\">\n#foreach($field in $queryList)\n#if($field.attrName != ${childField})\n#if($field.queryFormType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"state.queryForm.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option \n :label=\"item.label\" \n :value=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n :key=\"index\"\n />\n#else\n <el-option label=\"请选择\" value=\"0\" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"date\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"daterange\"\n range-separator=\"至\"\n start-placeholder=\"开始日期\"\n end-placeholder=\"结束日期\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"datetime\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (44,'树表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/tree-form.vue','树表单V2026001','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($fieldDict=[])\n#foreach($field in $childFieldList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n<template>\n <el-dialog :title=\"form.${childPkField.attrName} ? \'编辑\' : \'新增\'\" v-model=\"visible\"\n :close-on-click-modal=\"false\" draggable>\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" label-width=\"90px\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n <el-form-item label=\"父级节点\" prop=\"${parentField}\">\n <el-tree-select\n v-model=\"form.${parentField}\"\n :data=\"parentNodes\"\n :props=\"treeSelectProps\"\n check-strictly\n :render-after-expand=\"false\"\n placeholder=\"请选择父级节点\"\n style=\"width: 100%\"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $childFieldList)\n#if($field.attrName != ${childPkField.attrName} && $field.attrName != ${parentField})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetime\')\n <el-form-item label=\Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (45,'主表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','主表单V2026001','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($relationFieldLabel = $childField)\n#foreach($field in $fieldList)\n#if($field.attrName == $childField)\n#if($field.fieldComment)\n#set($relationFieldLabel = $field.fieldComment)\n#else\n#set($relationFieldLabel = $field.attrName)\n#end\n#break\n#end\n#end\n#set($fieldDict=[])\n#foreach($field in $formList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n<template>\n <el-dialog :title=\"form.${pk.attrName} ? \'编辑\' : \'新增\'\" v-model=\"visible\"\n :close-on-click-modal=\"false\" draggable>\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" label-width=\"90px\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n <el-form-item label=\"${relationFieldLabel}\" prop=\"${childField}\">\n <el-tree-select\n v-model=\"form.${childField}\"\n :data=\"treeNodes\"\n :props=\"treeSelectProps\"\n check-strictly\n :render-after-expand=\"false\"\n placeholder=\"请选择${relationFieldLabel}\"\n style=\"width: 100%\"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${childField})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fiLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (1,'ControllerV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','ControllerV202611','## 查询条件按需导入:字符串字段和组织关键字用 StrUtil,其余类型用 Objects;复选框与日期范围两者都不用\n#set($needStrUtil = false)\n#set($needObjects = false)\n#foreach($field in $queryList)\n#if($field.formType == \'checkbox\' || $field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#elseif($field.formType.startsWith(\'org-\') || $field.attrType == \'String\')\n#set($needStrUtil = true)\n#else\n#set($needObjects = true)\n#end\n#end\n#set($hasOrgQuery = false)\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrgQuery = true)\n#end\n#end\n## 组织字段以 [{id,name}] JSON 存储,按 ${attrName}Keyword 对整列模糊查询,分页和导出共用\n#macro(orgKeywordParams)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), @RequestParam(required = false) String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordDecl)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordArgs)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordFilters)\n#if($hasOrgQuery)\n // 组织字段对整列 JSON 做 LIKE:关键字为数字或 id/name 时会误命中,需精确匹配时改用数据库 JSON 函数\n#end\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n wrapper.like(StrUtil.isNotBlank(${field.attrName}Keyword), ${ClassName}Entity::$str.getProperty($field.attrName), ${field.attrName}Keyword);\n#end\n#end\n#end\n#set($permissionPrefix = \"${moduleName}_${functionName}\")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\npackage ${package}.${moduleName}.controller;\n\n#if($needStrUtil)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n#if($needObjects)\nimport java.util.Objects;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"分页查询\" , description = \"分页查询\" )\n @GetMapping(\"/page\" )\n #if($isSpringBoot3)\n @HasPermission(\"${permissionPrefix}_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'${permissionPrefix}_view\')\" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}#orgKeywordParams()) {\n return R.ok(${className}Service.page(page, buildQueryWrapper(${className}#orgKeywordArgs())));\n }\n\n /**\n * 列表与导出共用的查询条件,保证导出结果与列表一致\n */\n private LambdaQueryWrapper<${ClassName}Entity> buildQueryWrapper(${ClassName}Entity ${className}#orgKeywordDecl()) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (2,'ServiceV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','ServiceV202611','package ${package}.${moduleName}.service;\n\nimport com.baomidou.mybatisplus.spring.service.IService;\nimport ${entityClassName};\n\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (3,'ServiceImplV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','ServiceImplV202611','package ${package}.${moduleName}.service.impl;\n\nimport com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport org.springframework.stereotype.Service;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (4,'实体V202611','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','实体V202611','#set($hasOrg = false)\n#foreach($field in $fieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\npackage ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.spring.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($hasOrg)\nimport com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;\nimport ${package}.common.core.util.OrgRef;\nimport org.apache.fesod.sheet.annotation.ExcelIgnore;\nimport java.util.List;\n#end\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\n#if(!$import.startsWith(\'java.lang.\'))\nimport $import;\n#end\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(value = \"${tableName}\"#if($hasOrg), autoResultMap = true#end)\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.formType.startsWith(\'org-\'))\n @TableField(typeHandler = JacksonTypeHandler.class#if($field.autoFill == \'INSERT\' || $field.autoFill == \'INSERT_UPDATE\' || $field.autoFill == \'UPDATE\'), fill = FieldFill.${field.autoFill}#end)\n @ExcelIgnore\n#elseif($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType.startsWith(\'org-\'))\n private List<OrgRef> $field.attrName;\n#elseif($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (5,'MapperV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV202611','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (6,'Mapper.xmlV202611','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV202611','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"#if($field.formType.startsWith(\'org-\')) typeHandler=\"com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler\"#end/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (7,'权限菜单V202611','${backendPath}/menu/${functionName}_menu.sql','权限菜单V202611','#set($permissionPrefix = \"${moduleName}_${functionName}\")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'${permissionPrefix}_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'${permissionPrefix}_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'${permissionPrefix}_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'${permissionPrefix}_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'${permissionPrefix}_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (8,'api.tsV202611','${frontendPath}/src/api/${moduleName}/${functionName}.ts','api.tsV202611','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n\n#if($ChildClassName)\n// ========== 子表相关接口 ==========\n\n/**\n * 删除子表数据\n * @param ids - 要删除的子表数据ID数组\n * @returns Promise<操作结果>\n */\nexport function delChildObj(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/child\',\n method: \'delete\',\n data: ids\n })\n}\n#end\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (9,'表格V202611','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','表格V202611','## 有字典字段时才导入 useDict\n#set($hasDictField = false)\n#foreach($field in $queryList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($permissionPrefix = "${moduleName}_${functionName}")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n<template>\n <div class="layout-padding">\n <div class="layout-padding-auto layout-padding-view">\n#if($queryList)\n <!-- 查询表单区域 -->\n <el-row v-show="showSearch">\n <el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))#set($queryKey = "${field.attrName}Keyword")#else#set($queryKey = $field.attrName)#end\n#if($field.queryFormType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-select v-model="state.queryForm.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option \n :label="item.label" \n :value="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n :key="index"\n />\n#else\n <el-option label="请选择" value="0" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-date-picker\n type="date"\n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"\n v-model="state.queryForm.${field.attrName}"\n :value-format="dateStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-picker\n type="daterange"\n range-separator="至"\n start-placeholder="开始日期"\n end-placeholder="结束日期"\n v-model="state.queryForm.${field.attrName}Range"\n :value-format="dateStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-date-picker\n type="datetime"\n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"\n v-model="state.queryForm.${field.attrName}"\n :value-format="dateTimeStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-picker\n type="datetimerange"\n range-separator="至"\n start-placeholder="开始时间"\n end-placeholder="结束时间"\n v-model="state.queryForm.${field.attrName}Range"\n :value-format="dateTimeStr"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-radio-group v-model="state.queryForm.${field.attrName}">\n#if($field.fieldDict)\n <el-radio \n :label="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n border \n :key="index"\n >\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label="${field.fieldComment}" border>\n ${field.fieldComment}\n </el-radio>\n#end\n </el-rLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (10,'表单V202611','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','表单V202611','## 有字典字段时才导入 useDict\n#set($hasDictField = false)\n#foreach($field in $formList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#set($hasDuplicate = false)\n#foreach($field in $formList)\n#if($field.formValidator == \'duplicate\')\n#set($hasDuplicate = true)\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($hasOrg = false)\n#foreach($field in $formList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\n<template>\n <el-dialog :title="form.${pk.attrName} ? \'编辑\' : \'新增\'" v-model="visible"\n :close-on-click-modal="false" draggable>\n <el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading">\n <el-row :gutter="24">\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName})\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n#if($field.formType.startsWith(\'org-\'))\n#set($orgType = $field.formType.replace(\'org-\', \'\').replace(\'-multiple\', \'\'))\n <el-form-item label="${field.fieldComment}" prop="${field.attrName}">\n <OrgSelect v-model="form.${field.attrName}" value-type="item" type="${orgType}" :multiple="#if($field.formType.endsWith(\'-multiple\'))true#else false#end" label="${field.fieldComment}" :disabled="loading" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'switch\')\n#switchValues($field)\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-switch :model-value="String(form.${field.attrName}) === String($switchOn)" @change="(checked) => (form.${field.attrName} = checked ? $switchOn : $switchOff)" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'text\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input type="textarea" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-select v-model="form.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option :value="item.value" :label="item.label" v-for="(item, index) in ${field.fieldDict}" :key="index"></el-option>\n#else\n <el-option label="请选择" value="0"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-radio-group v-model="form.${field.attrName}">\n#if($field.fieldDict)\n <el-radio :label="item.value" v-for="(item, index) in ${field.fieldDict}" border :key="index">{{ item.label }}</el-radio>\n#else\n <el-radio label="${field.fieldComment}" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-checkbox-group v-model="form.${field.attrName}">\n#if($field.fieldDict)\n <el-checkbox :label="item.value" v-for="(item, index) in ${field.fieldDict}" :key="index">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label="启用"Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (11,'主子ServiceV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','主子ServiceV202611','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPk = $field)\n#end\n#end\npackage ${package}.${moduleName}.service;\n\nimport com.github.yulichang.extension.mapping.base.MPJDeepService;\nimport ${entityClassName};\n\npublic interface ${ClassName}Service extends MPJDeepService<${ClassName}Entity> {\n Boolean saveDeep(${ClassName}Entity ${className});\n\n Boolean updateDeep(${ClassName}Entity ${className});\n\n Boolean removeDeep(${pk.attrType}[] ids);\n\n Boolean removeChild(${childPk.attrType}[] ids);\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (12,'主子ServiceImplV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','主子ServiceImplV202611','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPk = $field)\n#end\n#end\npackage ${package}.${moduleName}.service.impl;\n\nimport com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport org.springframework.stereotype.Service;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${package}.${moduleName}.mapper.${ChildClassName}Mapper;\nimport org.springframework.transaction.annotation.Transactional;\nimport lombok.RequiredArgsConstructor;\nimport java.util.Objects;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n private final ${ChildClassName}Mapper ${childClassName}Mapper;\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean saveDeep(${ClassName}Entity ${className}) {\n baseMapper.insert(${className});\n for (${ChildClassName}Entity ${childClassName} : ${className}.get${ChildClassName}List()) {\n ${childClassName}.$str.setProperty($childField)(${className}.$str.getProperty($mainField)());\n ${childClassName}Mapper.insert( ${childClassName});\n }\n\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean updateDeep(${ClassName}Entity ${className}) {\n baseMapper.updateById(${className});\n for (${ChildClassName}Entity ${childClassName} : ${className}.get${ChildClassName}List()) {\n#set($getChildPkName=$str.getProperty(${childPk.attrName}))\n if (Objects.isNull(${childClassName}.$getChildPkName())) {\n ${childClassName}.$str.setProperty($childField)(${className}.$str.getProperty($mainField)());\n ${childClassName}Mapper.insert(${childClassName});\n } else {\n ${childClassName}Mapper.updateById(${childClassName});\n }\n }\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeDeep(${pk.attrType}[] ids) {\n List<${ClassName}Entity> records = baseMapper.selectBatchIds(CollUtil.toList(ids));\n if (CollUtil.isEmpty(records)) {\n return Boolean.TRUE;\n }\n ${childClassName}Mapper.delete(Wrappers.<${ChildClassName}Entity>lambdaQuery()\n .in(${ChildClassName}Entity::$str.getProperty($childField), records.stream()\n .map(${ClassName}Entity::$str.getProperty($mainField)).collect(Collectors.toList())));\n baseMapper.deleteBatchIds(CollUtil.toList(ids));\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeChild(${childPk.attrType}[] ids) {\n ${childClassName}Mapper.deleteBatchIds(CollUtil.toList(ids));\n return Boolean.TRUE;\n }\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (13,'主实体V202611','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','主实体V202611','#set($hasOrg = false)\n#foreach($field in $fieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\npackage ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.spring.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($hasOrg)\nimport com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;\nimport ${package}.common.core.util.OrgRef;\n#end\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\n#if(!$import.startsWith(\'java.lang.\'))\nimport $import;\n#end\n#end\nimport org.apache.fesod.sheet.annotation.ExcelIgnore;\nimport com.github.yulichang.annotation.EntityMapping;\nimport java.util.List;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(value = \"${tableName}\"#if($hasOrg), autoResultMap = true#end)\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.formType.startsWith(\'org-\'))\n @TableField(typeHandler = JacksonTypeHandler.class#if($field.autoFill == \'INSERT\' || $field.autoFill == \'INSERT_UPDATE\' || $field.autoFill == \'UPDATE\'), fill = FieldFill.${field.autoFill}#end)\n @ExcelIgnore\n#elseif($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType.startsWith(\'org-\'))\n private List<OrgRef> $field.attrName;\n#elseif($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n @TableField(typeHandler = JacksonTypeHandler.class)\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n @ExcelIgnore\n @TableField(exist = false)\n @EntityMapping(thisField = \"$mainField\", joinField = \"$childField\")\n private List<${ChildClassName}Entity> ${childClassName}List;\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (14,'MapperV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV202611','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (15,'Mapper.xmlV202611','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV202611','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"#if($field.formType.startsWith(\'org-\')) typeHandler=\"com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler\"#end/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (16,'权限菜单V202611','${backendPath}/menu/${functionName}_menu.sql','权限菜单V202611','#set($permissionPrefix = \"${moduleName}_${functionName}\")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'${permissionPrefix}_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'${permissionPrefix}_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'${permissionPrefix}_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'${permissionPrefix}_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'${permissionPrefix}_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (17,'api.tsV202611','${frontendPath}/src/api/${moduleName}/${functionName}.ts','api.tsV202611','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n\n#if($ChildClassName)\n// ========== 子表相关接口 ==========\n\n/**\n * 删除子表数据\n * @param ids - 要删除的子表数据ID数组\n * @returns Promise<操作结果>\n */\nexport function delChildObj(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/child\',\n method: \'delete\',\n data: ids\n })\n}\n#end\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (18,'子实体V202611','${entityPath}/src/main/java/${entityPackagePath}/${ChildClassName}Entity.java','子实体V202611','#set($hasOrg = false)\n#foreach($field in $childFieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\npackage ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.spring.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\n#if($isChildTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($hasOrg)\nimport com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;\nimport ${package}.common.core.util.OrgRef;\nimport java.util.List;\n#end\n#set($childImports = [])\n#foreach($field in $childFieldList)\n#if($field.packageName && !$field.packageName.startsWith(\'java.lang.\') && !$childImports.contains($field.packageName))\n#set($void = $childImports.add($field.packageName))\n#end\n#end\n#foreach($import in $childImports)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isChildTenant)\n@TenantTable\n#end\n@TableName(value = \"${childTableName}\"#if($hasOrg), autoResultMap = true#end)\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${childTableName}\")\npublic class ${ChildClassName}Entity extends Model<${ChildClassName}Entity> {\n\n#foreach ($field in $childFieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.formType.startsWith(\'org-\'))\n @TableField(typeHandler = JacksonTypeHandler.class#if($field.autoFill == \'INSERT\' || $field.autoFill == \'INSERT_UPDATE\' || $field.autoFill == \'UPDATE\'), fill = FieldFill.${field.autoFill}#end)\n#elseif($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType.startsWith(\'org-\'))\n private List<OrgRef> $field.attrName;\n#elseif($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end \n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (19,'主子ControllerV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','主子ControllerV202611','## 查询条件按需导入:字符串字段和组织关键字用 StrUtil,其余类型用 Objects;复选框与日期范围两者都不用\n#set($needStrUtil = false)\n#set($needObjects = false)\n#foreach($field in $queryList)\n#if($field.formType == \'checkbox\' || $field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#elseif($field.formType.startsWith(\'org-\') || $field.attrType == \'String\')\n#set($needStrUtil = true)\n#else\n#set($needObjects = true)\n#end\n#end\n#set($hasOrgQuery = false)\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrgQuery = true)\n#end\n#end\n## 组织字段以 [{id,name}] JSON 存储,按 ${attrName}Keyword 对整列模糊查询,分页和导出共用\n#macro(orgKeywordParams)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), @RequestParam(required = false) String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordDecl)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordArgs)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordFilters)\n#if($hasOrgQuery)\n // 组织字段对整列 JSON 做 LIKE:关键字为数字或 id/name 时会误命中,需精确匹配时改用数据库 JSON 函数\n#end\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n wrapper.like(StrUtil.isNotBlank(${field.attrName}Keyword), ${ClassName}Entity::$str.getProperty($field.attrName), ${field.attrName}Keyword);\n#end\n#end\n#end\n#set($permissionPrefix = \"${moduleName}_${functionName}\")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPk = $field)\n#end\n#end\npackage ${package}.${moduleName}.controller;\n\n#if($needStrUtil)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n#if($needObjects)\nimport java.util.Objects;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"分页查询\" , description = \"分页查询\" )\n @GetMapping(\"/page\" )\n #if($isSpringBoot3)\n @HasPermission(\"${permissionPrefix}_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'${permissionPrefix}_view\')\" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}#orgKeywordParams()) {\n return R.ok(${className}Service.page(page, buildQueryWrapper(${className}#orgKeywordArgs())));\n }\n\n /**\n * 列表与导出共用的查询条件,保证导出结果与列表一致\n */\n private LambdaQueryWrapper<${ClassName}Entity> buildQueryWrapper(${ClassName}Entity ${className}#orgKeywordDecl()) {\Line truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (20,'主子表单V202611','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','主子表单V202611','## 有字典字段时才导入 useDict\n#set($hasDictField = false)\n#foreach($field in $formList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#set($hasDuplicate = false)\n#foreach($field in $formList)\n#if($field.formValidator == \'duplicate\')\n#set($hasDuplicate = true)\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($hasOrg = false)\n#foreach($field in $formList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\n#foreach($field in $childFieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\n<template>\n <el-drawer :title="form.${pk.attrName} ? (detail ? \'详情\' : \'编辑\') : \'添加\'" v-model="visible" size="50%">\n <el-form ref="dataFormRef" :model="form" :rules="dataRules" :disabled="detail" v-loading="loading">\n <el-row :gutter="24">\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName})\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n#if($field.formType.startsWith(\'org-\'))\n#set($orgType = $field.formType.replace(\'org-\', \'\').replace(\'-multiple\', \'\'))\n <el-form-item label="${field.fieldComment}" prop="${field.attrName}">\n <OrgSelect v-model="form.${field.attrName}" value-type="item" type="${orgType}" :multiple="#if($field.formType.endsWith(\'-multiple\'))true#else false#end" label="${field.fieldComment}" :disabled="loading || detail" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'switch\')\n#switchValues($field)\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-switch :model-value="String(form.${field.attrName}) === String($switchOn)" @change="(checked) => (form.${field.attrName} = checked ? $switchOn : $switchOff)" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'text\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">\n <el-input v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">\n <el-input type="textarea" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">\n <el-select v-model="form.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end">\n#if($field.fieldDict)\n <el-option :value="item.value" :label="item.label" v-for="(item, index) in ${field.fieldDict}" :key="index"></el-option>\n#else\n <el-option label="请选择" value="0"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">\n <el-radio-group v-model="form.${field.attrName}">\n#if($field.fieldDict)\n <el-radio :label="item.value" v-for="(item, index) in ${field.fieldDict}" border :key="index">{{ item.label }}</el-radio>\n#else\n <el-radio label="${field.fieldComment}" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">\n <el-checkbox-group v-model="form.${field.attrName}">\n#if($field.fieldDict)\n <el-checkbox :label="item.value" v-fLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (21,'主子表格V202611','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','主子表格V202611','## 有字典字段时才导入 useDict\n#set($hasDictField = false)\n#foreach($field in $queryList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($permissionPrefix = "${moduleName}_${functionName}")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n<template>\n <div class="layout-padding">\n <div class="layout-padding-auto layout-padding-view">\n#if($queryList)\n <el-row v-show="showSearch">\n <el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))#set($queryKey = "${field.attrName}Keyword")#else#set($queryKey = $field.attrName)#end\n#if($field.queryFormType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-select v-model="state.queryForm.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option \n :label="item.label" \n :value="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n :key="index">\n </el-option>\n#else\n <el-option label="请选择">0</el-option>\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-date-picker\n type="date"\n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"\n :value-format="dateStr"\n v-model="state.queryForm.${field.attrName}"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-picker\n type="daterange"\n range-separator="至"\n start-placeholder="开始日期"\n end-placeholder="结束日期"\n v-model="state.queryForm.${field.attrName}Range"\n :value-format="dateStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-date-picker\n type="datetime"\n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"\n :value-format="dateTimeStr"\n v-model="state.queryForm.${field.attrName}"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-picker\n type="datetimerange"\n range-separator="至"\n start-placeholder="开始时间"\n end-placeholder="结束时间"\n v-model="state.queryForm.${field.attrName}Range"\n :value-format="dateTimeStr"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-radio-group v-model="state.queryForm.${field.attrName}">\n#if($field.fieldDict)\n <el-radio \n :label="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n border \n :key="index">\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label="${field.fieldComment}" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <elLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (22,'子MapperV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ChildClassName}Mapper.java','子MapperV202611','package ${package}.${moduleName}.mapper;\n\nimport ${package}.common.data.datascope.PigxBaseMapper;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ChildClassName}Mapper extends PigxBaseMapper<${ChildClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (23,'树形ControllerV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','树形ControllerV202611','## 查询条件按需导入:字符串字段用 StrUtil,其余类型用 Objects;复选框与日期范围两者都不用\n#set($needStrUtil = false)\n#set($needObjects = false)\n#foreach($field in $queryList)\n#if($field.formType == \'checkbox\' || $field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#elseif($field.formType.startsWith(\'org-\') || $field.attrType == \'String\')\n#set($needStrUtil = true)\n#else\n#set($needObjects = true)\n#end\n#end\n#set($hasOrgQuery = false)\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrgQuery = true)\n#end\n#end\n## 组织字段以 [{id,name}] JSON 存储,按 ${attrName}Keyword 对整列模糊查询,分页和导出共用\n#macro(orgKeywordParams)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), @RequestParam(required = false) String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordDecl)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordArgs)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordFilters)\n#if($hasOrgQuery)\n // 组织字段对整列 JSON 做 LIKE:关键字为数字或 id/name 时会误命中,需精确匹配时改用数据库 JSON 函数\n#end\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n wrapper.like(StrUtil.isNotBlank(${field.attrName}Keyword), ${ClassName}Entity::$str.getProperty($field.attrName), ${field.attrName}Keyword);\n#end\n#end\n#end\npackage ${package}.${moduleName}.controller;\n\n#if($queryList)\n#if($needStrUtil)\nimport cn.hutool.core.util.StrUtil;\n#end\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n#if($needObjects)\nimport java.util.Objects;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping("/${functionName}" )\n@Tag(description = "${functionName}" , name = "${tableComment}管理" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 获取树形列表\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = "获取树形列表" , description = "获取树形列表" )\n @GetMapping("/tree" )\n #if($isSpringBoot3)\n @HasPermission("$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view")\n #else\n @PreAuthorize("@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')" )\n #end\n public R get${ClassName}Tree(@ParameterObject ${ClassName}Entity ${className}#orgKeywordParams()) {\n return R.ok(${className}Service.buildTree(buildQueryWrapper(${className}#orgKeywordArgs())));\n }\n\n /**\n * 列表与导出共用的查询条件,保证导出结果与列表一致\n */\n private LambdaQueryWrapper<${ClassName}Entity> buildQueryWrapper(${ClassName}Entity ${className}#orgKeywordDecl()) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#orgKeywordFilters()\n#foreach ($field in $queryList)\n#if(!$field.formType.startsWith(\'org-\'))\n#set($getAttrName=$str.getProperty($field.attLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (24,'树形ServiceV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','树形ServiceV202611','package ${package}.${moduleName}.service;\n\nimport cn.hutool.core.lang.tree.Tree;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.spring.service.IService;\nimport ${entityClassName};\n\nimport java.util.List;\n\n/**\n * ${tableComment} Service接口\n *\n * @author ${author}\n * @date ${datetime}\n */\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n List<Tree<${pk.attrType}>> buildTree(LambdaQueryWrapper<${ClassName}Entity> wrapper);\n\n /**\n * 递归删除节点及其子节点\n * @param ids 要删除的节点ID列表\n * @return 删除结果\n */\n boolean removeBatchByIds(List<${pk.attrType}> ids);\n} ','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (25,'树形ServiceImplV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','树形ServiceImplV202611','## 根节点 ID 按主键类型生成,与 Tree<${pk.attrType}> 类型一致\n#if($pk.attrType == \'Long\')\n#set($treeRootId = \'0L\')\n#elseif($pk.attrType == \'String\')\n#set($treeRootId = \'"0"\')\n#else\n#set($treeRootId = \'0\')\n#end\npackage ${package}.${moduleName}.service.impl;\n\nimport cn.hutool.core.collection.CollUtil;\nimport cn.hutool.core.lang.tree.Tree;\nimport cn.hutool.core.lang.tree.TreeNode;\nimport cn.hutool.core.lang.tree.TreeUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport jakarta.validation.constraints.NotNull;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.function.Function;\nimport java.util.stream.Collectors;\n\n/**\n * ${tableComment} Service实现类\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n @Override\n public List<Tree<${pk.attrType}>> buildTree(LambdaQueryWrapper<${ClassName}Entity> wrapper) {\n // 查询命中节点,再按层补齐祖先,保留完整树路径\n List<${ClassName}Entity> allList = list(wrapper);\n \n if (CollUtil.isEmpty(allList)) {\n return new ArrayList<>();\n }\n\n Map<${pk.attrType}, ${ClassName}Entity> nodes = new LinkedHashMap<>();\n allList.forEach(entity -> nodes.put(entity.$str.getProperty($pk.attrName)(), entity));\n List<${ClassName}Entity> level = allList;\n while (!level.isEmpty()) {\n List<${pk.attrType}> parentIds = level.stream()\n .map(${ClassName}Entity::$str.getProperty($parentField))\n .filter(id -> id != null && !Objects.equals(id, ${treeRootId}) && !nodes.containsKey(id))\n .distinct()\n .toList();\n if (parentIds.isEmpty()) {\n break;\n }\n level = listByIds(parentIds);\n level.forEach(entity -> nodes.put(entity.$str.getProperty($pk.attrName)(), entity));\n }\n\n // 转换为TreeNode,仅包含命中节点及其祖先\n List<TreeNode<${pk.attrType}>> collect = nodes.values().stream().map(getNodeFunction()).toList();\n\n // 使用TreeUtil构建树形结构,根节点ID为0\n return TreeUtil.build(collect, ${treeRootId});\n }\n\n /**\n * 获取TreeNode转换函数\n * @return TreeNode转换函数\n */\n @NotNull\n private Function<${ClassName}Entity, TreeNode<${pk.attrType}>> getNodeFunction() {\n return entity -> {\n TreeNode<${pk.attrType}> node = new TreeNode<>();\n node.setId(entity.$str.getProperty($pk.attrName)());\n node.setName(entity.$str.getProperty($nameField)());\n node.setParentId(entity.$str.getProperty($parentField)() != null ? entity.$str.getProperty($parentField)() : ${treeRootId});\n\n // 扩展属性\n Map<String, Object> extra = new HashMap<>();\n#foreach($field in $fieldList)\n extra.put(${ClassName}Entity.Fields.${field.attrName}, entity.$str.getProperty($field.attrName)());\n#end\n node.setExtra(extra);\n return node;\n };\n }\n\n /**\n * 递归删除节点及其子节点\n * @param ids 要删除的节点ID列表\n * @return 删除结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public boolean removeBatchByIds(List<${pk.attrType}> ids) {\n if (CollUtil.isEmpty(ids)) {\n return true;\n }\n\n // 获取所有要删除的ID(包括子节点)\n List<${pk.attrType}> allDeleteIds = new ArrayList<>(ids);\n \n for (${pk.attrType} id : ids) {\n List<${pk.attrType}> childIds = getChildIdsRecursive(id);\n allDeleteIds.addAll(childIds);\n }\n\n // 去重\n allLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (26,'树形实体V202611','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','树形实体V202611','#set($hasOrg = false)\n#foreach($field in $fieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\npackage ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.spring.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\nimport lombok.experimental.FieldNameConstants;\n#if($hasOrg)\nimport com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;\nimport ${package}.common.core.util.OrgRef;\nimport org.apache.fesod.sheet.annotation.ExcelIgnore;\nimport java.util.List;\n#end\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\n#if(!$import.startsWith(\'java.lang.\'))\nimport $import;\n#end\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n@FieldNameConstants\n#if($isTenant)\n@TenantTable\n#end\n@TableName(value = "${tableName}"#if($hasOrg), autoResultMap = true#end)\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = "${tableComment}")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.formType.startsWith(\'org-\'))\n @TableField(typeHandler = JacksonTypeHandler.class#if($field.autoFill == \'INSERT\' || $field.autoFill == \'INSERT_UPDATE\' || $field.autoFill == \'UPDATE\'), fill = FieldFill.${field.autoFill}#end)\n @ExcelIgnore\n#elseif($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description="$comment"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType.startsWith(\'org-\'))\n private List<OrgRef> $field.attrName;\n#elseif($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description="$comment 查询范围",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (27,'MapperV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV202611','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (28,'Mapper.xmlV202611','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV202611','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"#if($field.formType.startsWith(\'org-\')) typeHandler=\"com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler\"#end/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (29,'权限菜单V202611','${backendPath}/menu/${functionName}_menu.sql','权限菜单V202611','#set($permissionPrefix = \"${moduleName}_${functionName}\")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'${permissionPrefix}_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'${permissionPrefix}_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'${permissionPrefix}_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'${permissionPrefix}_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'${permissionPrefix}_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (30,'树形api.tsV202611','${frontendPath}/src/api/${moduleName}/${functionName}.ts','树形api.tsV202611','import request from \"/@/utils/request\"\n\n// ========== 树形表格CRUD接口 ==========\n\n/**\n * 获取树形列表数据\n * @param query - 查询参数对象\n * @returns Promise<树形数据>\n */\nexport function fetchTreeList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据(递归删除子节点)\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (31,'树形表格V202611','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','树形表格V202611','## 有字典字段时才导入 useDict\n#set($hasDictField = false)\n#foreach($field in $queryList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n<template>\n <div class="layout-padding">\n <div class="layout-padding-auto layout-padding-view">\n#if($queryList)\n <!-- 查询表单区域 -->\n <el-row v-show="showSearch">\n <el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))#set($queryKey = "${field.attrName}Keyword")#else#set($queryKey = $field.attrName)#end\n#if($field.queryFormType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${queryKey}">\n <el-select v-model="state.queryForm.${queryKey}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option \n :label="item.label" \n :value="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n :key="index"\n />\n#else\n <el-option label="请选择" value="0" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${queryKey}">\n <el-date-picker \n type="date" \n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" \n v-model="state.queryForm.${queryKey}"\n :value-format="dateStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${queryKey}">\n <el-date-picker\n type="datetime"\n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"\n v-model="state.queryForm.${queryKey}"\n :value-format="dateTimeStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-picker\n type="daterange"\n range-separator="至"\n start-placeholder="开始日期"\n end-placeholder="结束日期"\n v-model="state.queryForm.${field.attrName}Range"\n :value-format="dateStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-picker\n type="datetimerange"\n range-separator="至"\n start-placeholder="开始时间"\n end-placeholder="结束时间"\n v-model="state.queryForm.${field.attrName}Range"\n :value-format="dateTimeStr"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${queryKey}">\n <el-radio-group v-model="state.queryForm.${queryKey}">\n#if($field.fieldDict)\n <el-radio \n :label="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n border \n :key="index"\n >\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label="${field.fieldComment}" border>\n ${field.fieldComment}\n </el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#enLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (32,'树形表单V202611','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','树形表单V202611','#set($hasDuplicate = false)\n#foreach($field in $formList)\n#if($field.formValidator == \'duplicate\')\n#set($hasDuplicate = true)\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($hasOrg = false)\n#foreach($field in $formList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\n<template>\n <el-dialog :title="form.${pk.attrName} ? \'编辑\' : \'新增\'" v-model="visible"\n :close-on-click-modal="false" draggable>\n <el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">\n <el-row :gutter="24">\n <!-- 父级节点选择 -->\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n <el-form-item label="父级节点" prop="${parentField}">\n <el-tree-select\n v-model="form.${parentField}"\n :data="parentNodes"\n :props="treeSelectProps"\n check-strictly\n :render-after-expand="false"\n placeholder="请选择父级节点"\n style="width: 100%"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${parentField})\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n#if($field.formType.startsWith(\'org-\'))\n#set($orgType = $field.formType.replace(\'org-\', \'\').replace(\'-multiple\', \'\'))\n <el-form-item label="${field.fieldComment}" prop="${field.attrName}">\n <OrgSelect v-model="form.${field.attrName}" value-type="item" type="${orgType}" :multiple="#if($field.formType.endsWith(\'-multiple\'))true#else false#end" label="${field.fieldComment}" :disabled="loading" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'switch\')\n#switchValues($field)\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-switch :model-value="String(form.${field.attrName}) === String($switchOn)" @change="(checked) => (form.${field.attrName} = checked ? $switchOn : $switchOff)" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'text\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input type="textarea" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-select v-model="form.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option :value="item.value" :label="item.label" v-for="(item, index) in ${field.fieldDict}" :key="index"></el-option>\n#else\n <el-option label="请选择" value="0"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-radio-group v-model="form.${field.attrName}">\n#if($field.fieldDict)\n <el-radio :label="item.value" v-for="(item, index) in ${field.fieldDict}" border :key="index">{{ item.label }}</el-radio>\n#else\n <el-radio label="${field.fieldComment}" bordLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (33,'左树右表ControllerV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','左树右表ControllerV202611','## 查询条件按需导入 StrUtil(字符串字段);Objects 用于树节点筛选,始终导入\n#set($needStrUtil = false)\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\') || ($field.formType != \'checkbox\' && $field.queryFormType != \'daterange\' && $field.queryFormType != \'datetimerange\' && $field.attrType == \'String\'))\n#set($needStrUtil = true)\n#end\n#end\n#set($hasOrgQuery = false)\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrgQuery = true)\n#end\n#end\n## 组织字段以 [{id,name}] JSON 存储,按 ${attrName}Keyword 对整列模糊查询,分页和导出共用\n#macro(orgKeywordParams)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), @RequestParam(required = false) String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordDecl)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), String ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordArgs)#foreach($field in $queryList)#if($field.formType.startsWith(\'org-\')), ${field.attrName}Keyword#end#end#end\n#macro(orgKeywordFilters)\n#if($hasOrgQuery)\n // 组织字段对整列 JSON 做 LIKE:关键字为数字或 id/name 时会误命中,需精确匹配时改用数据库 JSON 函数\n#end\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))\n wrapper.like(StrUtil.isNotBlank(${field.attrName}Keyword), ${ClassName}Entity::$str.getProperty($field.attrName), ${field.attrName}Keyword);\n#end\n#end\n#end\npackage ${package}.${moduleName}.controller;\n\n#if($needStrUtil)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($childFieldGetter = $str.getProperty($childField))\n@RestController\n@RequiredArgsConstructor\n@RequestMapping("/${functionName}" )\n@Tag(description = "${functionName}" , name = "${tableComment}管理" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = "分页查询" , description = "分页查询" )\n @GetMapping("/page" )\n #if($isSpringBoot3)\n @HasPermission("$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view")\n #else\n @PreAuthorize("@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}#orgKeywordParams()) {\n return R.ok(${className}Service.page(page, buildQueryWrapper(${className}#orgKeywordArgs())));\n }\n\n /**\n * 列表与导出共用的查询条件,保证导出结果与列表一致\n */\n private LambdaQueryWrapper<${ClassName}Entity> buildQueryWrapper(${ClassName}Entity ${className}#orgKeywordDecl()) {\n LambLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (34,'左树右表ServiceV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','左树右表ServiceV202611','package ${package}.${moduleName}.service;\n\nimport cn.hutool.core.lang.tree.Tree;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.spring.service.IService;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\n\nimport java.util.List;\n\n/**\n * ${tableComment} Service接口\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n List<Tree<${childPkField.attrType}>> buildTree(LambdaQueryWrapper<${ChildClassName}Entity> wrapper);\n\n /**\n * 获取树节点详情\n * @param ${childClassName} 树节点查询对象\n * @return 树节点详情列表\n */\n List<${ChildClassName}Entity> getTreeDetails(${ChildClassName}Entity ${childClassName});\n\n /**\n * 保存树节点\n * @param ${childClassName} 树节点对象\n * @return 保存结果\n */\n Boolean saveTree(${ChildClassName}Entity ${childClassName});\n\n /**\n * 更新树节点\n * @param ${childClassName} 树节点对象\n * @return 更新结果\n */\n Boolean updateTree(${ChildClassName}Entity ${childClassName});\n\n /**\n * 批量删除树节点\n * @param ids 树节点ID列表\n * @return 删除结果\n */\n Boolean removeTreeByIds(${childPkField.attrType}[] ids);\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (35,'左树右表ServiceImplV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','左树右表ServiceImplV202611','package ${package}.${moduleName}.service.impl;\n\nimport cn.hutool.core.collection.CollUtil;\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.lang.tree.Tree;\nimport cn.hutool.core.lang.tree.TreeNode;\nimport cn.hutool.core.lang.tree.TreeUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ChildClassName}Mapper;\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\nimport java.util.function.Function;\n\n/**\n * ${tableComment} Service实现类\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#set($childPkGetter = $str.getProperty($childPkField.attrName))\n#break\n#end\n#end\n#set($parentGetter = $str.getProperty($parentField))\n#set($childFieldGetter = $str.getProperty($childField))\n#if($childPkField.attrType == \'Long\')\n#set($treeRootId = \'0L\')\n#elseif($childPkField.attrType == \'String\')\n#set($treeRootId = \'\"0\"\')\n#else\n#set($treeRootId = \'0\')\n#end\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n private final ${ChildClassName}Mapper ${childClassName}Mapper;\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n @Override\n public List<Tree<${childPkField.attrType}>> buildTree(LambdaQueryWrapper<${ChildClassName}Entity> wrapper) {\n List<${ChildClassName}Entity> allList = ${childClassName}Mapper.selectList(wrapper);\n\n if (CollUtil.isEmpty(allList)) {\n return new ArrayList<>();\n }\n\n List<TreeNode<${childPkField.attrType}>> collect = allList.stream().map(getNodeFunction()).toList();\n return TreeUtil.build(collect, ${treeRootId});\n }\n\n /**\n * 获取树节点详情\n * @param ${childClassName} 树节点查询对象\n * @return 树节点详情列表\n */\n @Override\n public List<${ChildClassName}Entity> getTreeDetails(${ChildClassName}Entity ${childClassName}) {\n return ${childClassName}Mapper.selectList(Wrappers.query(${childClassName}));\n }\n\n /**\n * 保存树节点\n * @param ${childClassName} 树节点对象\n * @return 保存结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean saveTree(${ChildClassName}Entity ${childClassName}) {\n ${childClassName}.$str.setProperty($parentField)(validateParentRelation(null, ${childClassName}.$str.getProperty($parentField)()));\n return ${childClassName}Mapper.insert(${childClassName}) > 0;\n }\n\n /**\n * 更新树节点\n * @param ${childClassName} 树节点对象\n * @return 更新结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean updateTree(${ChildClassName}Entity ${childClassName}) {\n ${childClassName}.$str.setProperty($parentField)(validateParentRelation(${childClassName}.$str.getProperty($childPkField.attrName)(), ${childClassName}.$str.getProperty($parentField)()));\n return ${childClassName}Mapper.updateById(${childClassName}) > 0;\n }\n\n /**\n * 批量删除树节点\n * @param ids 树节点ID列表\n * @return 删除结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeTreeByIds(${childPkField.attrType}[] ids) {\n if (ArrayUtil.isEmpty(ids)) {\n return Boolean.TRUE;\n }\n\n for (${childPkField.attrType} id : ids) {\n if (hasChildNodes(id)) {\n throw new RuntimeException(\"当前节点存在子节点,不能删除\");\n }\n if (hasMainRecords(id)) {\n throw new RuntimeException(\"当前节点已关联主表数据,不能删除\");\n }\n }\n\n return ${childClassNameLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (36,'实体V202611','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','实体V202611','#set($hasOrg = false)\n#foreach($field in $fieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\npackage ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.spring.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($hasOrg)\nimport com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;\nimport ${package}.common.core.util.OrgRef;\nimport org.apache.fesod.sheet.annotation.ExcelIgnore;\nimport java.util.List;\n#end\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\n#if(!$import.startsWith(\'java.lang.\'))\nimport $import;\n#end\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(value = \"${tableName}\"#if($hasOrg), autoResultMap = true#end)\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.formType.startsWith(\'org-\'))\n @TableField(typeHandler = JacksonTypeHandler.class#if($field.autoFill == \'INSERT\' || $field.autoFill == \'INSERT_UPDATE\' || $field.autoFill == \'UPDATE\'), fill = FieldFill.${field.autoFill}#end)\n @ExcelIgnore\n#elseif($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType.startsWith(\'org-\'))\n private List<OrgRef> $field.attrName;\n#elseif($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (37,'MapperV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV202611','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (38,'Mapper.xmlV202611','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV202611','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"#if($field.formType.startsWith(\'org-\')) typeHandler=\"com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler\"#end/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (39,'子实体V202611','${entityPath}/src/main/java/${entityPackagePath}/${ChildClassName}Entity.java','子实体V202611','#set($hasOrg = false)\n#foreach($field in $childFieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\npackage ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.spring.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\n#if($isChildTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($hasOrg)\nimport com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;\nimport ${package}.common.core.util.OrgRef;\nimport java.util.List;\n#end\n#set($childImports = [])\n#foreach($field in $childFieldList)\n#if($field.packageName && !$field.packageName.startsWith(\'java.lang.\') && !$childImports.contains($field.packageName))\n#set($void = $childImports.add($field.packageName))\n#end\n#end\n#foreach($import in $childImports)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isChildTenant)\n@TenantTable\n#end\n@TableName(value = \"${childTableName}\"#if($hasOrg), autoResultMap = true#end)\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${childTableName}\")\npublic class ${ChildClassName}Entity extends Model<${ChildClassName}Entity> {\n\n#foreach ($field in $childFieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.formType.startsWith(\'org-\'))\n @TableField(typeHandler = JacksonTypeHandler.class#if($field.autoFill == \'INSERT\' || $field.autoFill == \'INSERT_UPDATE\' || $field.autoFill == \'UPDATE\'), fill = FieldFill.${field.autoFill}#end)\n#elseif($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType.startsWith(\'org-\'))\n private List<OrgRef> $field.attrName;\n#elseif($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end \n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (40,'子MapperV202611','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ChildClassName}Mapper.java','子MapperV202611','package ${package}.${moduleName}.mapper;\n\nimport ${package}.common.data.datascope.PigxBaseMapper;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ChildClassName}Mapper extends PigxBaseMapper<${ChildClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (41,'权限菜单V202611','${backendPath}/menu/${functionName}_menu.sql','权限菜单V202611','#set($permissionPrefix = \"${moduleName}_${functionName}\")\n#set($permissionPrefix = $permissionPrefix.toLowerCase())\n-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'${permissionPrefix}_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'${permissionPrefix}_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'${permissionPrefix}_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'${permissionPrefix}_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'${permissionPrefix}_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (42,'左树右表api.tsV202611','${frontendPath}/src/api/${moduleName}/${functionName}.ts','左树右表api.tsV202611','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 树形CRUD接口 ==========\n\n/**\n * 获取树形列表数据\n * @param query - 查询参数对象\n * @returns Promise<树形数据>\n */\nexport function fetchTreeList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 获取树节点详情\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<树节点详情>\n */\nexport function getTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 新增树节点\n * @param obj - 要新增的树节点对象\n * @returns Promise<操作结果>\n */\nexport function addTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 更新树节点\n * @param obj - 要更新的树节点对象\n * @returns Promise<操作结果>\n */\nexport function putTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'put\',\n data: obj\n })\n}\n\n/**\n * 删除树节点\n * @param ids - 要删除的树节点ID数组\n * @returns Promise<操作结果>\n */\nexport function delTreeObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'delete\',\n data: ids\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n *\n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (43,'左树右表表格V202611','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','左树右表表格V202611','## 有字典字段时才导入 useDict\n#set($hasDictField = false)\n#foreach($field in $queryList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($hasDictField = true)\n#end\n#end\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n<template>\n <div class="layout-padding">\n <splitpanes>\n <pane size="15">\n <div class="layout-padding-auto layout-padding-view">\n <el-scrollbar>\n <div class="mb8" style="display: flex; align-items: center; justify-content: space-between;">\n <span style="font-weight: 500;">左侧节点</span>\n <div>\n <el-tooltip :content="currentTreeId ? \'新增子节点\' : \'新增根节点\'" placement="top">\n <el-button link type="primary" icon="FolderAdd" @click="handleAddTree" />\n </el-tooltip>\n </div>\n </div>\n <el-tree\n ref="treeRef"\n :data="treeData"\n :props="treeProps"\n node-key="${childPkField.attrName}"\n highlight-current\n default-expand-all\n :expand-on-click-node="false"\n @node-click="handleTreeNodeClick"\n >\n <template #default="{ node, data }">\n <span style="flex: 1; display: flex; align-items: center; justify-content: space-between;">\n <span>{{ node.label }}</span>\n <span v-if="currentTreeId === data.${childPkField.attrName}" style="margin-left: 8px;">\n <el-tooltip content="编辑" placement="top">\n <el-button link type="primary" icon="Edit" size="small" @click.stop="handleEditTree" />\n </el-tooltip>\n <el-tooltip content="删除" placement="top">\n <el-button link type="danger" icon="Delete" size="small" @click.stop="handleDeleteTree" />\n </el-tooltip>\n </span>\n </span>\n </template>\n </el-tree>\n </el-scrollbar>\n </div>\n </pane>\n <pane class="ml8">\n <div class="layout-padding-auto layout-padding-view">\n#if($queryList)\n <el-row v-show="showSearch">\n <el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">\n#foreach($field in $queryList)\n#if($field.formType.startsWith(\'org-\'))#set($queryKey = "${field.attrName}Keyword")#else#set($queryKey = $field.attrName)#end\n#if($field.attrName != ${childField})\n#if($field.queryFormType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${queryKey}">\n <el-select v-model="state.queryForm.${queryKey}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option \n :label="item.label" \n :value="item.value" \n v-for="(item, index) in ${field.fieldDict}" \n :key="index"\n />\n#else\n <el-option label="请选择" value="0" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${queryKey}">\n <el-date-picker\n type="date"\n placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"\n v-model="state.queryForm.${queryKey}"\n :value-format="dateStr"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">\n <el-date-pickerLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (44,'左树右表树表单V202611','${frontendPath}/src/views/${moduleName}/${functionName}/tree-form.vue','左树右表树表单V202611','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($fieldDict=[])\n#foreach($field in $childFieldList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($hasOrg = false)\n#foreach($field in $childFieldList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\n<template>\n <el-dialog :title="form.${childPkField.attrName} ? \'编辑\' : \'新增\'" v-model="visible"\n :close-on-click-modal="false" draggable>\n <el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading">\n <el-row :gutter="24">\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n <el-form-item label="父级节点" prop="${parentField}">\n <el-tree-select\n v-model="form.${parentField}"\n :data="parentNodes"\n :props="treeSelectProps"\n check-strictly\n :render-after-expand="false"\n placeholder="请选择父级节点"\n style="width: 100%"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $childFieldList)\n#if($field.attrName != ${childPkField.attrName} && $field.attrName != ${parentField})\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n#if($field.formType.startsWith(\'org-\'))\n#set($orgType = $field.formType.replace(\'org-\', \'\').replace(\'-multiple\', \'\'))\n <el-form-item label="${field.fieldComment}" prop="${field.attrName}">\n <OrgSelect v-model="form.${field.attrName}" value-type="item" type="${orgType}" :multiple="#if($field.formType.endsWith(\'-multiple\'))true#else false#end" label="${field.fieldComment}" :disabled="loading" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'switch\')\n#switchValues($field)\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-switch :model-value="String(form.${field.attrName}) === String($switchOn)" @change="(checked) => (form.${field.attrName} = checked ? $switchOn : $switchOff)" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'text\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input type="textarea" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-select v-model="form.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option :value="item.value" :label="item.label" v-for="(item, index) in ${field.fieldDict}" :key="index"></el-option>\n#else\n <el-option label="请选择" value="0"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-radio-group v-model="form.${field.attrName}">\n#if($field.fieldDict)\n <el-radio :label="item.value" v-for="(item, index) in ${field.fieldDicLine truncated
|
||||
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (45,'左树右表主表单V202611','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','左树右表主表单V202611','#set($hasDuplicate = false)\n#foreach($field in $formList)\n#if($field.attrName != ${childField} && $field.formValidator == \'duplicate\')\n#set($hasDuplicate = true)\n#end\n#end\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($relationFieldLabel = $childField)\n#foreach($field in $fieldList)\n#if($field.attrName == $childField)\n#if($field.fieldComment)\n#set($relationFieldLabel = $field.fieldComment)\n#else\n#set($relationFieldLabel = $field.attrName)\n#end\n#break\n#end\n#end\n#set($fieldDict=[])\n#foreach($field in $formList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n## 开关:按属性类型决定开/关的值,Boolean 用 true/false,整型用 1/0,其余用 \'1\'/\'0\'\n#macro(switchValues $f)\n#if($f.attrType == \'Boolean\')\n#set($switchOn = \'true\')\n#set($switchOff = \'false\')\n#elseif($f.attrType == \'Integer\' || $f.attrType == \'Long\' || $f.attrType == \'Short\')\n#set($switchOn = \'1\')\n#set($switchOff = \'0\')\n#else\n#set($switchOn = "\'1\'")\n#set($switchOff = "\'0\'")\n#end\n#end\n#set($hasOrg = false)\n#foreach($field in $formList)\n#if($field.formType.startsWith(\'org-\'))\n#set($hasOrg = true)\n#end\n#end\n<template>\n <el-dialog :title="form.${pk.attrName} ? \'编辑\' : \'新增\'" v-model="visible"\n :close-on-click-modal="false" draggable>\n <el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading">\n <el-row :gutter="24">\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n <el-form-item label="${relationFieldLabel}" prop="${childField}">\n <el-tree-select\n v-model="form.${childField}"\n :data="treeNodes"\n :props="treeSelectProps"\n check-strictly\n :render-after-expand="false"\n placeholder="请选择${relationFieldLabel}"\n style="width: 100%"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${childField})\n#if($formLayout == 1)\n <el-col :span="24" class="mb20">\n#elseif($formLayout == 2)\n <el-col :span="12" class="mb20">\n#end\n#if($field.formType.startsWith(\'org-\'))\n#set($orgType = $field.formType.replace(\'org-\', \'\').replace(\'-multiple\', \'\'))\n <el-form-item label="${field.fieldComment}" prop="${field.attrName}">\n <OrgSelect v-model="form.${field.attrName}" value-type="item" type="${orgType}" :multiple="#if($field.formType.endsWith(\'-multiple\'))true#else false#end" label="${field.fieldComment}" :disabled="loading" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'switch\')\n#switchValues($field)\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-switch :model-value="String(form.${field.attrName}) === String($switchOn)" @change="(checked) => (form.${field.attrName} = checked ? $switchOn : $switchOff)" />\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'text\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-input type="textarea" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">\n <el-select v-model="form.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">\n#if($field.fieldDict)\n <el-option :value="item.value" :label="item.label" v-for="(item, index) in ${field.fieldDict}" :key="index"></el-option>\n#else\n <el-option label="请选择" value="0"></el-option>\n#end\n Line truncated
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
|
||||
@@ -3,6 +3,35 @@ USE pigxx_bi;
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for chat2bi_table_meta
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `chat2bi_table_meta`;
|
||||
CREATE TABLE `chat2bi_table_meta` (
|
||||
`id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键',
|
||||
`db_source_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '数据源来源表标识, 如: db_source / api_source / file_source / system_source',
|
||||
`db_source_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '对应来源表的主键ID',
|
||||
`schema_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Schema名',
|
||||
`table_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '表名',
|
||||
`source_comment` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '表注释-源(同步写入, 每次同步覆盖)',
|
||||
`table_comment` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '表注释-用户(用户手动填写, 同步不覆盖)',
|
||||
`columns_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '列定义[{name,type,source_comment,comment,is_primary,sample_values,nulltable}]',
|
||||
`relations_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '关联关系[{column,ref_table,ref_column,type}]',
|
||||
`is_enabled` tinyint(4) NOT NULL DEFAULT 1 COMMENT '对LLM可见: 0=否 1=是',
|
||||
`synced_time` datetime NULL DEFAULT NULL COMMENT '最近同步时间',
|
||||
`create_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人',
|
||||
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新人',
|
||||
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
|
||||
`tenant_id` int(11) NULL DEFAULT NULL COMMENT '多租户标识',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_source_table`(`db_source_type`, `db_source_id`, `schema_name`, `table_name`) USING BTREE,
|
||||
INDEX `idx_source`(`db_source_type`, `db_source_id`) USING BTREE,
|
||||
INDEX `idx_table_name`(`table_name`) USING BTREE,
|
||||
INDEX `idx_table_name_comment`(`table_name`, `source_comment`(320), `table_comment`(320)) USING BTREE,
|
||||
INDEX `idx_table_comment`(`table_comment`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '表元数据(同步+手动维护, 支持多数据源表)' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for huiyuan_age
|
||||
-- ----------------------------
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-app-server</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-app-server-api</artifactId>
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.pig4cloud.pigx.app.api.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import com.baomidou.mybatisplus.spring.activerecord.Model;
|
||||
import com.pig4cloud.pigx.common.core.util.TenantTable;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.pig4cloud.pigx.app.api.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import com.baomidou.mybatisplus.spring.activerecord.Model;
|
||||
import com.pig4cloud.pigx.common.core.util.TenantTable;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.pig4cloud.pigx.app.api.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import com.baomidou.mybatisplus.spring.activerecord.Model;
|
||||
import com.pig4cloud.pigx.common.core.util.TenantTable;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.pig4cloud.pigx.app.api.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import com.baomidou.mybatisplus.spring.activerecord.Model;
|
||||
import com.pig4cloud.pigx.common.core.util.TenantTable;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.pig4cloud.pigx.app.api.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import com.baomidou.mybatisplus.spring.activerecord.Model;
|
||||
import com.pig4cloud.pigx.common.core.util.TenantTable;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.pig4cloud.pigx.app.api.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import com.baomidou.mybatisplus.spring.activerecord.Model;
|
||||
import com.pig4cloud.pigx.common.core.util.TenantTable;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.pig4cloud.pigx.app.api.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import com.baomidou.mybatisplus.spring.activerecord.Model;
|
||||
import com.fasterxml.jackson.annotation.JsonRawValue;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.pig4cloud.pigx.common.core.util.TenantTable;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-app-server</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-app-server-biz</artifactId>
|
||||
|
||||
+21
-1
@@ -51,6 +51,7 @@ public class AppArticleCategoryController {
|
||||
LambdaQueryWrapper<AppArticleCategoryEntity> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.like(StrUtil.isNotBlank(appArticleCategory.getName()), AppArticleCategoryEntity::getName,
|
||||
appArticleCategory.getName());
|
||||
wrapper.orderByAsc(AppArticleCategoryEntity::getSort, AppArticleCategoryEntity::getId);
|
||||
return R.ok(appArticleCategoryService.page(page, wrapper));
|
||||
}
|
||||
|
||||
@@ -74,7 +75,8 @@ public class AppArticleCategoryController {
|
||||
@Inner(value = false)
|
||||
@GetMapping("/list")
|
||||
public R list() {
|
||||
return R.ok(appArticleCategoryService.list());
|
||||
return R.ok(appArticleCategoryService.list(Wrappers.<AppArticleCategoryEntity>lambdaQuery()
|
||||
.orderByAsc(AppArticleCategoryEntity::getSort, AppArticleCategoryEntity::getId)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,6 +105,24 @@ public class AppArticleCategoryController {
|
||||
return R.ok(appArticleCategoryService.updateById(appArticleCategory));
|
||||
}
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整文章分类,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的文章分类 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @return 排序保存成功的响应;校验或更新失败时抛出异常,由统一异常处理器转换响应
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
@Operation(summary = "拖拽排序", description = "按当前列表顺序保存排序")
|
||||
@SysLog("文章分类排序")
|
||||
@PutMapping("/sort")
|
||||
@HasPermission("app_appArticleCategory_edit")
|
||||
public R sort(@RequestBody List<Long> ids) {
|
||||
appArticleCategoryService.sort(ids);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除文章分类表
|
||||
* @param ids id列表
|
||||
|
||||
+28
-12
@@ -36,13 +36,12 @@ public class AppArticleController {
|
||||
private final AppArticleService appArticleService;
|
||||
|
||||
/**
|
||||
* 分页查询文章资讯。
|
||||
* <p>
|
||||
* 返回文章列表时会关联分类名称,供 App 资讯列表和后台管理复用。
|
||||
*
|
||||
* 分页查询文章资讯。
|
||||
* <p>
|
||||
* 返回文章列表时会关联分类名称,供 App 资讯列表和后台管理复用。
|
||||
* @param page 分页对象
|
||||
* @param appArticle 文章资讯
|
||||
* @return 文章分页结果
|
||||
* @return 文章分页结果
|
||||
*/
|
||||
@Operation(summary = "分页查询", description = "分页查询")
|
||||
@Inner(value = false)
|
||||
@@ -52,13 +51,12 @@ public class AppArticleController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询文章详情。
|
||||
* <p>
|
||||
* 会递增访问次数;如果传入 userId,则额外返回该用户是否收藏当前文章。
|
||||
*
|
||||
* @param id 文章 ID
|
||||
* @param userId 用户 ID,可为空
|
||||
* @return 文章详情
|
||||
* 查询文章详情。
|
||||
* <p>
|
||||
* 会递增访问次数;如果传入 userId,则额外返回该用户是否收藏当前文章。
|
||||
* @param id 文章 ID
|
||||
* @param userId 用户 ID,可为空
|
||||
* @return 文章详情
|
||||
*/
|
||||
@Inner(value = false)
|
||||
@Operation(summary = "通过id查询", description = "通过id查询")
|
||||
@@ -93,6 +91,24 @@ public class AppArticleController {
|
||||
return R.ok(appArticleService.updateById(appArticle));
|
||||
}
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整文章,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的文章 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @return 排序保存成功的响应;校验或更新失败时抛出异常,由统一异常处理器转换响应
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
@Operation(summary = "拖拽排序", description = "按当前列表顺序保存排序")
|
||||
@SysLog("文章资讯排序")
|
||||
@PutMapping("/sort")
|
||||
@HasPermission("app_appArticle_edit")
|
||||
public R sort(@RequestBody List<Long> ids) {
|
||||
appArticleService.sort(ids);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除文章资讯
|
||||
* @param ids id列表
|
||||
|
||||
+13
-1
@@ -1,11 +1,23 @@
|
||||
package com.pig4cloud.pigx.app.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.baomidou.mybatisplus.spring.service.IService;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppArticleCategoryEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 文章分类基础服务。
|
||||
*/
|
||||
public interface AppArticleCategoryService extends IService<AppArticleCategoryEntity> {
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整文章分类,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的文章分类 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
void sort(List<Long> ids);
|
||||
|
||||
}
|
||||
+16
-1
@@ -1,11 +1,26 @@
|
||||
package com.pig4cloud.pigx.app.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.baomidou.mybatisplus.spring.service.IService;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppArticleEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 文章查询与排序服务,供管理端和 App 文章接口调用。
|
||||
*/
|
||||
public interface AppArticleService extends IService<AppArticleEntity> {
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整文章,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的文章 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
void sort(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 获取文章并使阅读数+1
|
||||
* @param id id
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.pig4cloud.pigx.app.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.baomidou.mybatisplus.spring.service.IService;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppContactsEntity;
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package com.pig4cloud.pigx.app.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.baomidou.mybatisplus.spring.service.IService;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppPageEntity;
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package com.pig4cloud.pigx.app.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.baomidou.mybatisplus.spring.service.IService;
|
||||
import com.pig4cloud.pigx.app.api.dto.AppRoleTabbarDTO;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppRoleTabbar;
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package com.pig4cloud.pigx.app.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.baomidou.mybatisplus.spring.service.IService;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppTabbarEntity;
|
||||
|
||||
/**
|
||||
|
||||
+42
-1
@@ -1,10 +1,18 @@
|
||||
package com.pig4cloud.pigx.app.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppArticleCategoryEntity;
|
||||
import com.pig4cloud.pigx.app.mapper.AppArticleCategoryMapper;
|
||||
import com.pig4cloud.pigx.app.service.AppArticleCategoryService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 文章分类表
|
||||
@@ -16,4 +24,37 @@ import org.springframework.stereotype.Service;
|
||||
public class AppArticleCategoryServiceImpl extends ServiceImpl<AppArticleCategoryMapper, AppArticleCategoryEntity>
|
||||
implements AppArticleCategoryService {
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整文章分类,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的文章分类 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void sort(List<Long> ids) {
|
||||
Assert.notEmpty(ids, "排序记录不能为空");
|
||||
Set<Long> selected = new HashSet<>(ids);
|
||||
Assert.isTrue(!selected.contains(null) && selected.size() == ids.size(), "排序记录无效");
|
||||
// 锁定统一顺序,避免重复排序值和分页边界导致拖动后顺序丢失。
|
||||
List<AppArticleCategoryEntity> records = list(Wrappers.<AppArticleCategoryEntity>lambdaQuery()
|
||||
.orderByAsc(AppArticleCategoryEntity::getSort, AppArticleCategoryEntity::getId)
|
||||
.last("FOR UPDATE"));
|
||||
long matched = records.stream().filter(row -> selected.contains(row.getId())).count();
|
||||
Assert.isTrue(matched == ids.size(), "记录已变更,请刷新后重试");
|
||||
List<AppArticleCategoryEntity> updates = new ArrayList<>();
|
||||
int next = 0;
|
||||
for (int i = 0; i < records.size(); i++) {
|
||||
AppArticleCategoryEntity current = records.get(i);
|
||||
Long id = selected.contains(current.getId()) ? ids.get(next++) : current.getId();
|
||||
AppArticleCategoryEntity update = new AppArticleCategoryEntity();
|
||||
update.setId(id);
|
||||
update.setSort(i + 1);
|
||||
updates.add(update);
|
||||
}
|
||||
Assert.state(updateBatchById(updates), "排序保存失败");
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.pig4cloud.pigx.app.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppArticleCollectEntity;
|
||||
import com.pig4cloud.pigx.app.mapper.AppArticleCollectMapper;
|
||||
import com.pig4cloud.pigx.app.service.AppArticleCollectService;
|
||||
|
||||
+53
-15
@@ -3,7 +3,7 @@ package com.pig4cloud.pigx.app.service.impl;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppArticleCategoryEntity;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppArticleCollectEntity;
|
||||
@@ -13,6 +13,13 @@ import com.pig4cloud.pigx.app.mapper.AppArticleMapper;
|
||||
import com.pig4cloud.pigx.app.service.AppArticleService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -32,19 +39,17 @@ public class AppArticleServiceImpl extends ServiceImpl<AppArticleMapper, AppArti
|
||||
private final AppArticleCollectMapper collectMapper;
|
||||
|
||||
/**
|
||||
* 获取文章详情,并尝试将阅读数加 1。
|
||||
* <p>
|
||||
* 如果传入用户 ID,会额外查询该用户是否已收藏当前文章。
|
||||
* 阅读数更新使用当前 visit 值作为条件,降低并发覆盖风险。
|
||||
*
|
||||
* @param id 文章 ID
|
||||
* @param userId 当前用户 ID,可为空
|
||||
* @return 文章详情
|
||||
* 获取文章详情,并尝试将阅读数加 1。
|
||||
* <p>
|
||||
* 如果传入用户 ID,会额外查询该用户是否已收藏当前文章。 阅读数更新使用当前 visit 值作为条件,降低并发覆盖风险。
|
||||
* @param id 文章 ID
|
||||
* @param userId 当前用户 ID,可为空
|
||||
* @return 文章详情
|
||||
*/
|
||||
@Override
|
||||
public AppArticleEntity getArticleAndIncrById(Long id, Long userId) {
|
||||
AppArticleEntity appArticleEntity = baseMapper.selectById(id);
|
||||
// 登录用户访问详情时,补充当前用户是否已收藏该文章。
|
||||
// 登录用户访问详情时,补充当前用户是否已收藏该文章。
|
||||
if (Objects.nonNull(userId)) {
|
||||
boolean exists = collectMapper.exists(Wrappers.<AppArticleCollectEntity>lambdaQuery()//
|
||||
.eq(AppArticleCollectEntity::getArticleId, appArticleEntity.getId())//
|
||||
@@ -54,7 +59,7 @@ public class AppArticleServiceImpl extends ServiceImpl<AppArticleMapper, AppArti
|
||||
|
||||
Integer nowVisit = appArticleEntity.getVisit();
|
||||
appArticleEntity.setVisit(nowVisit + 1);
|
||||
// 使用旧 visit 值作为更新条件,避免并发访问时直接覆盖最新阅读数。
|
||||
// 使用旧 visit 值作为更新条件,避免并发访问时直接覆盖最新阅读数。
|
||||
baseMapper.update(appArticleEntity,
|
||||
Wrappers.<AppArticleEntity>lambdaQuery()
|
||||
.eq(AppArticleEntity::getId, id)
|
||||
@@ -63,11 +68,10 @@ public class AppArticleServiceImpl extends ServiceImpl<AppArticleMapper, AppArti
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询文章列表,并关联分类名称。
|
||||
*
|
||||
* 分页查询文章列表,并关联分类名称。
|
||||
* @param page 分页参数
|
||||
* @param appArticle 文章查询条件
|
||||
* @return 文章分页结果,包含分类名称 cname
|
||||
* @return 文章分页结果,包含分类名称 cname
|
||||
*/
|
||||
@Override
|
||||
public Page pageAndCname(Page page, AppArticleEntity appArticle) {
|
||||
@@ -77,8 +81,42 @@ public class AppArticleServiceImpl extends ServiceImpl<AppArticleMapper, AppArti
|
||||
.leftJoin(AppArticleCategoryEntity.class, AppArticleCategoryEntity::getId, AppArticleEntity::getCid)
|
||||
.like(StrUtil.isNotBlank(appArticle.getAuthor()), AppArticleEntity::getAuthor, appArticle.getAuthor())
|
||||
.like(StrUtil.isNotBlank(appArticle.getTitle()), AppArticleEntity::getTitle, appArticle.getTitle())
|
||||
.eq(Objects.nonNull(appArticle.getCid()), AppArticleEntity::getCid, appArticle.getCid());
|
||||
.eq(Objects.nonNull(appArticle.getCid()), AppArticleEntity::getCid, appArticle.getCid())
|
||||
.orderByAsc(AppArticleEntity::getSort, AppArticleEntity::getId);
|
||||
return this.page(page, wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整文章,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的文章 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void sort(List<Long> ids) {
|
||||
Assert.notEmpty(ids, "排序记录不能为空");
|
||||
Set<Long> selected = new HashSet<>(ids);
|
||||
Assert.isTrue(!selected.contains(null) && selected.size() == ids.size(), "排序记录无效");
|
||||
// 锁定统一顺序,避免重复排序值和分页边界导致拖动后顺序丢失。
|
||||
List<AppArticleEntity> records = list(Wrappers.<AppArticleEntity>lambdaQuery()
|
||||
.orderByAsc(AppArticleEntity::getSort, AppArticleEntity::getId)
|
||||
.last("FOR UPDATE"));
|
||||
long matched = records.stream().filter(row -> selected.contains(row.getId())).count();
|
||||
Assert.isTrue(matched == ids.size(), "记录已变更,请刷新后重试");
|
||||
List<AppArticleEntity> updates = new ArrayList<>();
|
||||
int next = 0;
|
||||
for (int i = 0; i < records.size(); i++) {
|
||||
AppArticleEntity current = records.get(i);
|
||||
Long id = selected.contains(current.getId()) ? ids.get(next++) : current.getId();
|
||||
AppArticleEntity update = new AppArticleEntity();
|
||||
update.setId(id);
|
||||
update.setSort(i + 1);
|
||||
updates.add(update);
|
||||
}
|
||||
Assert.state(updateBatchById(updates), "排序保存失败");
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppContactsEntity;
|
||||
import com.pig4cloud.pigx.app.mapper.AppContactsMapper;
|
||||
import com.pig4cloud.pigx.app.service.AppContactsService;
|
||||
|
||||
+2
-2
@@ -59,7 +59,7 @@ public class AppMobileServiceImpl implements AppMobileService {
|
||||
*/
|
||||
@Override
|
||||
public R<Boolean> sendSmsCode(String mobile) {
|
||||
String codeObj = RedisUtils.get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile);
|
||||
String codeObj = RedisUtils.get(CacheConstants.SMS_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile);
|
||||
|
||||
if (StrUtil.isNotBlank(codeObj)) {
|
||||
log.info("手机号验证码未过期:{},{}", mobile, codeObj);
|
||||
@@ -68,7 +68,7 @@ public class AppMobileServiceImpl implements AppMobileService {
|
||||
|
||||
String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE));
|
||||
log.debug("手机号生成验证码成功:{},{}", mobile, code);
|
||||
RedisUtils.set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile, code, SecurityConstants.CODE_TIME);
|
||||
RedisUtils.set(CacheConstants.SMS_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile, code, SecurityConstants.CODE_TIME);
|
||||
return R.ok(Boolean.TRUE);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package com.pig4cloud.pigx.app.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppPageEntity;
|
||||
import com.pig4cloud.pigx.app.mapper.AppPageMapper;
|
||||
import com.pig4cloud.pigx.app.service.AppPageService;
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.pig4cloud.pigx.app.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.app.api.dto.AppRoleTabbarDTO;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppRoleTabbar;
|
||||
import com.pig4cloud.pigx.app.mapper.AppRoleTabbarMapper;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package com.pig4cloud.pigx.app.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppTabbarEntity;
|
||||
import com.pig4cloud.pigx.app.mapper.AppTabbarMapper;
|
||||
import com.pig4cloud.pigx.app.service.AppTabbarService;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-app-server</artifactId>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-auth</artifactId>
|
||||
|
||||
@@ -18,6 +18,8 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
* 验证码相关的接口
|
||||
*
|
||||
@@ -39,7 +41,7 @@ public class ImageCodeEndpoint {
|
||||
@SneakyThrows
|
||||
@GetMapping("/image")
|
||||
public void image(String randomStr, HttpServletResponse response) {
|
||||
ArithmeticCaptcha captcha = new ArithmeticCaptcha(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT);
|
||||
ArithmeticCaptcha captcha = createCaptcha();
|
||||
|
||||
String result = captcha.text();
|
||||
|
||||
@@ -48,11 +50,20 @@ public class ImageCodeEndpoint {
|
||||
return;
|
||||
}
|
||||
|
||||
RedisUtils.set(CacheConstants.DEFAULT_CODE_KEY + randomStr, result, SecurityConstants.CODE_TIME);
|
||||
RedisUtils.set(CacheConstants.IMAGE_CODE_KEY + randomStr, result, SecurityConstants.CODE_TIME);
|
||||
// 转换流信息写出
|
||||
captcha.out(response.getOutputStream());
|
||||
}
|
||||
|
||||
static ArithmeticCaptcha createCaptcha() {
|
||||
return new ArithmeticCaptcha(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT) {
|
||||
@Override
|
||||
protected Color color() {
|
||||
return Color.BLACK;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 行为 创建滑块图形验证码
|
||||
*/
|
||||
|
||||
+32
-7
@@ -6,6 +6,7 @@ import cn.hutool.json.JSONUtil;
|
||||
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.enums.CaptchaFlagTypeEnum;
|
||||
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
|
||||
import com.pig4cloud.pigx.common.core.exception.ValidateCodeException;
|
||||
import com.pig4cloud.pigx.common.core.util.MsgUtils;
|
||||
import com.pig4cloud.pigx.common.data.cache.RedisUtils;
|
||||
@@ -75,7 +76,7 @@ public class AuthCaptchaSupport {
|
||||
*/
|
||||
public boolean isCaptchaEnabled(String tenantId, String clientId) {
|
||||
if (StrUtil.isBlank(clientId)) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
String finalTenantId = StrUtil.isBlank(tenantId) ? CommonConstants.TENANT_ID_1.toString() : tenantId;
|
||||
@@ -103,12 +104,6 @@ public class AuthCaptchaSupport {
|
||||
}
|
||||
|
||||
String randomStr = request.getParameter("randomStr");
|
||||
// https://gitee.com/log4j/pig/issues/IWA0D 手机号场景以 mobile 作为缓存键
|
||||
String mobile = request.getParameter("mobile");
|
||||
if (StrUtil.isNotBlank(mobile)) {
|
||||
randomStr = mobile;
|
||||
}
|
||||
|
||||
boolean isBehavior = StrUtil.equalsAnyIgnoreCase(randomStr, CommonConstants.IMAGE_CODE_BLOCK_PUZZLE,
|
||||
CommonConstants.IMAGE_CODE_CLICK_WORD);
|
||||
String captchaType = isBehavior ? randomStr : CommonConstants.IMAGE_CODE_MATH;
|
||||
@@ -122,6 +117,36 @@ public class AuthCaptchaSupport {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按完整类型前缀判断是否使用短信登录,不校验手机号格式或验证码。
|
||||
*
|
||||
* @param mobile 登录标识,格式为 {@code SMS@手机号} 或 {@code APP-SMS@手机号};允许为 null
|
||||
* @return 匹配短信类型前缀时为 true;null、空串或其他类型返回 false
|
||||
*/
|
||||
public boolean isSmsLogin(String mobile) {
|
||||
return StrUtil.startWith(mobile, LoginTypeEnum.SMS.getType() + StrUtil.AT)
|
||||
|| StrUtil.startWith(mobile, LoginTypeEnum.APPSMS.getType() + StrUtil.AT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验请求中的短信身份凭据,不接受图形或行为验证码作为替代。
|
||||
* 类型合法且验证码非空时委托缓存校验;读取缓存后无论匹配与否均消费该验证码。
|
||||
*
|
||||
* @param request 非 null 请求,mobile 参数为 {@code SMS@手机号} 或
|
||||
* {@code APP-SMS@手机号},code 参数为短信验证码
|
||||
* @throws ValidateCodeException 验证码为空、登录类型不合法,或验证码不存在、过期、不匹配
|
||||
*/
|
||||
public void validateSmsCode(HttpServletRequest request) {
|
||||
String mobile = request.getParameter("mobile");
|
||||
String code = request.getParameter("code");
|
||||
if (StrUtil.isBlank(code)) {
|
||||
throw new ValidateCodeException(MsgUtils.getMessage(AuthErrorCodes.AUTH_CAPTCHA_EMPTY));
|
||||
}
|
||||
if (!isSmsLogin(mobile) || !captchaValidator.validateSms(mobile, code).isOk()) {
|
||||
throw new ValidateCodeException(MsgUtils.getMessage(AuthErrorCodes.AUTH_CAPTCHA_INVALID));
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveAuthorizationParameter(HttpServletRequest request, HttpServletResponse response,
|
||||
String parameterName, boolean includeCurrentRequestId) {
|
||||
if (includeCurrentRequestId) {
|
||||
|
||||
+11
-1
@@ -1,8 +1,9 @@
|
||||
package com.pig4cloud.pigx.auth.support.filter;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.pig4cloud.pigx.auth.support.core.AuthCaptchaSupport;
|
||||
import com.pig4cloud.pigx.auth.support.handler.FormAuthenticationFailureHandler;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.exception.ValidateCodeException;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
@@ -11,6 +12,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
@@ -45,6 +47,14 @@ public class FormLoginValidateCodeFilter extends OncePerRequestFilter {
|
||||
return;
|
||||
}
|
||||
|
||||
// 表单登录只允许密码认证,防止切换到 APP 模式的免密码校验分支。
|
||||
String[] grantTypes = request.getParameterValues(OAuth2ParameterNames.GRANT_TYPE);
|
||||
if (ArrayUtil.length(grantTypes) != 1 || !ArrayUtil.contains(grantTypes, SecurityConstants.PASSWORD)) {
|
||||
failureHandler.onAuthenticationFailure(request, response,
|
||||
new AuthenticationServiceException("Form login only supports password grant"));
|
||||
return;
|
||||
}
|
||||
|
||||
String authClientId = authCaptchaSupport.resolveAuthorizationClientId(request, response, true);
|
||||
String tenantId = authCaptchaSupport.resolveAuthorizationTenantId(request, response, true);
|
||||
|
||||
|
||||
+23
-32
@@ -12,20 +12,22 @@ import com.pig4cloud.pigx.auth.support.core.AuthCaptchaSupport;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.exception.ValidateCodeException;
|
||||
import com.pig4cloud.pigx.common.core.util.WebUtils;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author lbw
|
||||
@@ -54,45 +56,30 @@ public class ValidateCodeFilter extends OncePerRequestFilter {
|
||||
|
||||
// 如果登录URL 但是刷新token的请求,直接向下执行
|
||||
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
|
||||
if (StrUtil.containsAny(grantType, SecurityConstants.REFRESH_TOKEN)) {
|
||||
if (StrUtil.equals(grantType, SecurityConstants.REFRESH_TOKEN)) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// mobile模式, 如果请求不包含mobile 参数直接
|
||||
String mobile = request.getParameter(SecurityConstants.GRANT_MOBILE);
|
||||
if (StrUtil.equals(SecurityConstants.GRANT_MOBILE, grantType) && StrUtil.isBlank(mobile)) {
|
||||
throw new OAuth2AuthenticationException(SecurityConstants.GRANT_MOBILE);
|
||||
}
|
||||
|
||||
// mobile模式, 社交登录模式不校验验证码直接跳过
|
||||
if (StrUtil.equals(SecurityConstants.GRANT_MOBILE, grantType) && !StrUtil.contains(mobile, "SMS")) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// 判断客户端是否跳过检验
|
||||
if (!isCheckCaptchaClient(request)) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// 校验验证码 1. 客户端开启验证码 2. 短信模式
|
||||
try {
|
||||
checkCode();
|
||||
if (StrUtil.equals(SecurityConstants.GRANT_MOBILE, grantType)) {
|
||||
String mobile = request.getParameter(SecurityConstants.GRANT_MOBILE);
|
||||
if (StrUtil.isBlank(mobile)) {
|
||||
throw new OAuth2AuthenticationException(SecurityConstants.GRANT_MOBILE);
|
||||
}
|
||||
// 短信是身份凭据,不能随客户端图形验证码开关关闭。
|
||||
if (authCaptchaSupport.isSmsLogin(mobile)) {
|
||||
authCaptchaSupport.validateSmsCode(request);
|
||||
}
|
||||
} else if (isCheckCaptchaClient(request)) {
|
||||
authCaptchaSupport.validateCode(request);
|
||||
}
|
||||
filterChain.doFilter(request, response);
|
||||
} catch (ValidateCodeException validateCodeException) {
|
||||
throw new OAuth2AuthenticationException(validateCodeException.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验验证码
|
||||
*/
|
||||
private void checkCode() throws ValidateCodeException {
|
||||
authCaptchaSupport.validateCode(WebUtils.getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要校验客户端,根据client 查询客户端配置
|
||||
*
|
||||
@@ -100,8 +87,12 @@ public class ValidateCodeFilter extends OncePerRequestFilter {
|
||||
* @return true 需要校验, false 不需要校验
|
||||
*/
|
||||
private boolean isCheckCaptchaClient(HttpServletRequest request) {
|
||||
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
String clientId = WebUtils.extractClientId(header).orElse(null);
|
||||
// 客户端认证过滤器在本过滤器之前执行,兼容 Basic 和 client_secret_post,
|
||||
// 不信任额外传入的 client_id 来决定验证码策略。
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
String clientId = authentication instanceof OAuth2ClientAuthenticationToken client
|
||||
&& client.isAuthenticated() && Objects.nonNull(client.getRegisteredClient())
|
||||
? client.getRegisteredClient().getClientId() : null;
|
||||
// 获取租户拼接区分租户的key
|
||||
String tenantId = request.getHeader(CommonConstants.TENANT_ID);
|
||||
return authCaptchaSupport.isCaptchaEnabled(tenantId, clientId);
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package com.pig4cloud.pigx.auth.support.filter;
|
||||
|
||||
import com.pig4cloud.pigx.auth.support.core.AuthCaptchaSupport;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class FormLoginValidateCodeFilterTests {
|
||||
|
||||
private final AuthCaptchaSupport captchaSupport = mock(AuthCaptchaSupport.class);
|
||||
|
||||
private final FormLoginValidateCodeFilter filter = new FormLoginValidateCodeFilter(captchaSupport);
|
||||
|
||||
private final FilterChain chain = mock(FilterChain.class);
|
||||
|
||||
private final MockHttpServletRequest request = new MockHttpServletRequest("POST", "/oauth2/form");
|
||||
|
||||
private final MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RequestContextHolder.resetRequestAttributes();
|
||||
}
|
||||
|
||||
static Stream<Arguments> invalidGrants() {
|
||||
return Stream.of(null, new String[] { "" }, new String[] { "app" }, new String[] { "mobile" },
|
||||
new String[] { "client_credentials" }, new String[] { "authorization_code" },
|
||||
new String[] { "refresh_token" }, new String[] { "password", "app" },
|
||||
new String[] { "app", "password" }, new String[] { "password", "password" }).map(values -> Arguments.of((Object) values));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidGrants")
|
||||
void rejectsInvalidGrantsBeforeCaptchaOrAuthentication(String[] grantTypes) throws Exception {
|
||||
if (grantTypes != null) {
|
||||
request.setParameter("grant_type", grantTypes);
|
||||
}
|
||||
applyFilter();
|
||||
assertThat(response.getStatus()).isEqualTo(302);
|
||||
assertThat(response.getRedirectedUrl()).contains("/token/login?error=");
|
||||
verifyNoInteractions(captchaSupport, chain);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = { false, true })
|
||||
void allowsPasswordWithExistingTenantCaptchaPolicy(boolean captchaEnabled) throws Exception {
|
||||
request.setParameter("grant_type", "password");
|
||||
when(captchaSupport.resolveAuthorizationClientId(request, response, true)).thenReturn("client");
|
||||
when(captchaSupport.resolveAuthorizationTenantId(request, response, true)).thenReturn("2");
|
||||
when(captchaSupport.isCaptchaEnabled("2", "client")).thenReturn(captchaEnabled);
|
||||
applyFilter();
|
||||
verify(captchaSupport).isCaptchaEnabled("2", "client");
|
||||
verify(captchaSupport, times(captchaEnabled ? 1 : 0)).validateCode(request);
|
||||
verify(chain).doFilter(request, response);
|
||||
}
|
||||
|
||||
private void applyFilter() throws Exception {
|
||||
request.setServletPath("/oauth2/form");
|
||||
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request, response));
|
||||
filter.doFilter(request, response, chain);
|
||||
}
|
||||
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
package com.pig4cloud.pigx.auth.support.filter;
|
||||
|
||||
import com.pig4cloud.pigx.auth.endpoint.ImageCodeEndpoint;
|
||||
import com.pig4cloud.pigx.auth.support.core.AuthCaptchaSupport;
|
||||
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
|
||||
import com.pig4cloud.pigx.common.security.captcha.CaptchaValidator;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.support.StaticMessageSource;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ValueOperations;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class LoginCaptchaSecurityTests {
|
||||
|
||||
private final Map<String, Object> cache = new HashMap<>();
|
||||
private final RedisTemplate<String, Object> redis = mock(RedisTemplate.class);
|
||||
private final ValueOperations<String, Object> values = mock(ValueOperations.class);
|
||||
private final ValidateCodeFilter filter = new ValidateCodeFilter(
|
||||
new AuthCaptchaSupport(new CaptchaValidator(null, redis)));
|
||||
private final MockHttpServletRequest request = new MockHttpServletRequest("POST", "/oauth2/token");
|
||||
private final MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
private final FilterChain chain = mock(FilterChain.class);
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
when(redis.opsForValue()).thenReturn(values);
|
||||
when(values.get(anyString())).thenAnswer(invocation -> cache.get(invocation.getArgument(0)));
|
||||
when(values.getAndDelete(anyString())).thenAnswer(invocation -> cache.remove(invocation.getArgument(0)));
|
||||
doAnswer(invocation -> {
|
||||
cache.put(invocation.getArgument(0), invocation.getArgument(1));
|
||||
return null;
|
||||
}).when(values).set(anyString(), any(), anyLong(), any(TimeUnit.class));
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
factory.registerSingleton("redisTemplate", redis);
|
||||
StaticMessageSource messages = new StaticMessageSource();
|
||||
messages.setUseCodeAsDefaultMessage(true);
|
||||
factory.registerSingleton("pigxMessageSource", messages);
|
||||
new SpringContextHolder().postProcessBeanFactory(factory);
|
||||
request.setServletPath("/oauth2/token");
|
||||
request.addHeader("TENANT-ID", "1");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
SecurityContextHolder.clearContext();
|
||||
new SpringContextHolder().postProcessBeanFactory(null);
|
||||
SpringContextHolder.clearHolder();
|
||||
}
|
||||
|
||||
static Stream<Arguments> validCases() {
|
||||
return Stream.of(Arguments.of("SMS", false, false), Arguments.of("SMS", true, false),
|
||||
Arguments.of("SMS", false, true), Arguments.of("SMS", true, true),
|
||||
Arguments.of("APP-SMS", true, true), Arguments.of("image", false, true),
|
||||
Arguments.of("image", true, true));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("validCases")
|
||||
void acceptsOnlyTheExpectedCaptchaAndConsumesIt(String type, boolean post, boolean enabled) throws Exception {
|
||||
configureClient(post, enabled);
|
||||
String key;
|
||||
if (type.equals("image")) {
|
||||
request.setParameter("grant_type", "password");
|
||||
request.setParameter("randomStr", "image-test");
|
||||
new ImageCodeEndpoint().image("image-test", response);
|
||||
key = CacheConstants.IMAGE_CODE_KEY + "image-test";
|
||||
} else {
|
||||
request.setParameter("grant_type", "mobile");
|
||||
request.setParameter("mobile", type + "@13800138000");
|
||||
key = CacheConstants.SMS_CODE_KEY + type + "@13800138000";
|
||||
cache.put(key, "654321");
|
||||
}
|
||||
request.setParameter("code", cache.get(key).toString());
|
||||
filter.doFilter(request, response, chain);
|
||||
verify(chain).doFilter(request, response);
|
||||
assertThat(cache).doesNotContainKey(key);
|
||||
}
|
||||
|
||||
static Stream<Arguments> invalidCases() {
|
||||
Stream<Arguments> smsCases = Stream.of(false, true).flatMap(post -> Stream.of(false, true).flatMap(enabled ->
|
||||
Stream.of("missing", "image", "legacy").map(kind -> Arguments.of(post, enabled, kind))));
|
||||
return Stream.concat(smsCases, Stream.of(Arguments.of(false, true, "password"),
|
||||
Arguments.of(true, true, "password")));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidCases")
|
||||
void rejectsMissingOrSubstitutedIdentityProof(boolean post, boolean enabled, String kind) throws Exception {
|
||||
configureClient(post, enabled);
|
||||
String mobile = "SMS@13800138000";
|
||||
request.setParameter("grant_type", kind.equals("password") ? "password" : "mobile");
|
||||
request.setParameter("mobile", mobile);
|
||||
if (kind.equals("image")) {
|
||||
new ImageCodeEndpoint().image(mobile, response);
|
||||
assertThat(cache).doesNotContainKey(CacheConstants.SMS_CODE_KEY + mobile);
|
||||
request.setParameter("code", cache.get(CacheConstants.IMAGE_CODE_KEY + mobile).toString());
|
||||
} else if (kind.equals("legacy")) {
|
||||
cache.put(CacheConstants.DEFAULT_CODE_KEY + mobile, "123456");
|
||||
request.setParameter("code", "123456");
|
||||
}
|
||||
assertThatThrownBy(() -> filter.doFilter(request, response, chain))
|
||||
.isInstanceOf(OAuth2AuthenticationException.class);
|
||||
verifyNoInteractions(chain);
|
||||
}
|
||||
|
||||
private void configureClient(boolean post, boolean enabled) {
|
||||
RegisteredClient client = RegisteredClient.withId("test-client").clientId("test-client")
|
||||
.authorizationGrantType(new AuthorizationGrantType("password")).build();
|
||||
SecurityContextHolder.getContext().setAuthentication(new OAuth2ClientAuthenticationToken(client,
|
||||
post ? ClientAuthenticationMethod.CLIENT_SECRET_POST : ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
|
||||
"test-secret"));
|
||||
// 策略只取已认证客户端,不使用请求额外指定的客户端。
|
||||
request.setParameter("client_id", "untrusted-client");
|
||||
cache.put("1:client_config_flag:test-client", "{\"captcha_flag\":\"" + (enabled ? "1" : "0") + "\"}");
|
||||
cache.put("1:client_config_flag:untrusted-client", "{\"captcha_flag\":\"0\"}");
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-boot</artifactId>
|
||||
|
||||
@@ -26,6 +26,7 @@ spring:
|
||||
redis.enabled: false
|
||||
sentinel.enabled: false
|
||||
openfeign.okhttp.enabled: true
|
||||
openfeign.compression.request.min-request-size: 5120
|
||||
freemarker: # freemarker 配置,授权码模式页面渲染使用
|
||||
suffix: .ftl
|
||||
template-loader-path: classpath:/templates/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-audit</artifactId>
|
||||
|
||||
@@ -7,18 +7,18 @@
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-bom</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>${pigx.version}</version>
|
||||
<version>6.2.0</version>
|
||||
<description>pigx 公共版本控制,在此pom定义的依赖,全局业务微服务不需要指定版本。</description>
|
||||
|
||||
<properties>
|
||||
<pigx.version>6.1.0</pigx.version>
|
||||
<mybatis-plus.version>3.5.16</mybatis-plus.version>
|
||||
<pigx.version>6.2.0</pigx.version>
|
||||
<mybatis-plus.version>3.5.18.1</mybatis-plus.version>
|
||||
<mybatis-spring-boot.version>4.0.1</mybatis-spring-boot.version>
|
||||
<mybatis-plus-join.version>1.5.7</mybatis-plus-join.version>
|
||||
<dynamic-ds.version>4.5.0</dynamic-ds.version>
|
||||
<nacos.client.version>3.2.3</nacos.client.version>
|
||||
<mybatis-plus-join.version>1.5.9</mybatis-plus-join.version>
|
||||
<dynamic-ds.version>4.6.0</dynamic-ds.version>
|
||||
<nacos.client.version>3.3.0</nacos.client.version>
|
||||
<druid.version>1.2.28</druid.version>
|
||||
<hutool.version>5.8.47</hutool.version>
|
||||
<hutool.version>5.8.48</hutool.version>
|
||||
<mysql.connector.version>9.5.0</mysql.connector.version>
|
||||
<oracle.version>21.3.0.0</oracle.version>
|
||||
<sqlserver.version>12.10.2.jre8</sqlserver.version>
|
||||
@@ -30,13 +30,13 @@
|
||||
<mp.weixin.version>4.7.9-20260103.233048</mp.weixin.version>
|
||||
<ijpay.version>2.9.12.1-17</ijpay.version>
|
||||
<groovy.version>3.0.25</groovy.version>
|
||||
<jsoup.version>1.15.4</jsoup.version>
|
||||
<jsoup.version>1.23.2</jsoup.version>
|
||||
<aviator.version>5.4.4</aviator.version>
|
||||
<flowable.version>8.0.0</flowable.version>
|
||||
<fastjson.version>1.2.84</fastjson.version>
|
||||
<xxl.job.version>3.4.2</xxl.job.version>
|
||||
<aliyun.version>3.0.52.ALL</aliyun.version>
|
||||
<aws.sdk.version>2.44.14</aws.sdk.version>
|
||||
<aws.sdk.version>2.55.3</aws.sdk.version>
|
||||
<javers.version>7.8.6</javers.version>
|
||||
<seata.version>2.5.0</seata.version>
|
||||
<asm.version>7.1</asm.version>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
|
||||
+6
@@ -20,6 +20,12 @@ public interface CacheConstants {
|
||||
*/
|
||||
String DEFAULT_CODE_KEY = "DEFAULT_CODE_KEY:";
|
||||
|
||||
/** 图形验证码独立命名空间,不能写入短信验证码缓存。 */
|
||||
String IMAGE_CODE_KEY = "IMAGE_CODE_KEY:";
|
||||
|
||||
/** 短信验证码独立命名空间,后接登录类型与手机号。 */
|
||||
String SMS_CODE_KEY = "SMS_CODE_KEY:";
|
||||
|
||||
/**
|
||||
* 菜单信息缓存
|
||||
*/
|
||||
|
||||
-21
@@ -137,32 +137,11 @@ public interface SecurityConstants {
|
||||
*/
|
||||
String MINI_APP_PHONE_NUMBER_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s";
|
||||
|
||||
/**
|
||||
* 码云获取token
|
||||
*/
|
||||
String GITEE_AUTHORIZATION_CODE_URL = "https://gitee.com/oauth/token?grant_type="
|
||||
+ "authorization_code&code=%S&client_id=%s&redirect_uri=" + "%s&client_secret=%s";
|
||||
|
||||
/**
|
||||
* 开源中国获取token
|
||||
*/
|
||||
String OSC_AUTHORIZATION_CODE_URL = "https://www.oschina.net/action/openapi/token";
|
||||
|
||||
/**
|
||||
* QQ获取用户信息
|
||||
*/
|
||||
String QQ_USER_INFO_URL = "https://graph.qq.com/oauth2.0/me?access_token=%s";
|
||||
|
||||
/**
|
||||
* 码云获取用户信息
|
||||
*/
|
||||
String GITEE_USER_INFO_URL = "https://gitee.com/api/v5/user?access_token=%s";
|
||||
|
||||
/**
|
||||
* 开源中国用户信息
|
||||
*/
|
||||
String OSC_USER_INFO_URL = "https://www.oschina.net/action/openapi/user?access_token=%s&dataType=json";
|
||||
|
||||
/**
|
||||
* 钉钉获取 token
|
||||
*/
|
||||
|
||||
+3
-10
@@ -55,21 +55,14 @@ public enum LoginTypeEnum {
|
||||
*/
|
||||
MINI_APP("MINI", "微信小程序"),
|
||||
|
||||
/**
|
||||
* 码云登录
|
||||
*/
|
||||
GITEE("GITEE", "码云登录"),
|
||||
|
||||
/**
|
||||
* 开源中国登录
|
||||
*/
|
||||
OSC("OSC", "开源中国登录"),
|
||||
|
||||
/**
|
||||
* 钉钉
|
||||
*/
|
||||
DINGTALK("DINGTALK", "钉钉"),
|
||||
|
||||
/** 企业飞书 */
|
||||
FEISHU("FEISHU", "企业飞书"),
|
||||
|
||||
/**
|
||||
* 企业微信
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-data</artifactId>
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
package com.pig4cloud.pigx.common.data.datascope;
|
||||
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.github.yulichang.injector.MPJSqlInjector;
|
||||
import org.apache.ibatis.session.Configuration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -16,8 +16,8 @@ import java.util.List;
|
||||
public class DataScopeSqlInjector extends MPJSqlInjector {
|
||||
|
||||
@Override
|
||||
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
|
||||
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
|
||||
public List<AbstractMethod> getMethodList(Configuration configuration, Class<?> mapperClass, TableInfo tableInfo) {
|
||||
List<AbstractMethod> methodList = super.getMethodList(configuration, mapperClass, tableInfo);
|
||||
methodList.add(new SelectListByScope());
|
||||
methodList.add(new SelectPageByScope());
|
||||
methodList.add(new SelectCountByScope());
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ public class SelectCountByScope extends AbstractMethod {
|
||||
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
|
||||
SqlMethod sqlMethod = SqlMethod.SELECT_LIST;
|
||||
|
||||
String sql = String.format(sqlMethod.getSql(), this.sqlFirst(), this.sqlSelectColumns(tableInfo, true),
|
||||
String sql = sqlMethod.format(this.sqlFirst(), this.sqlSelectColumns(tableInfo, true),
|
||||
tableInfo.getTableName(), this.sqlWhereEntityWrapper(true, tableInfo), this.sqlOrderBy(tableInfo),
|
||||
this.sqlComment());
|
||||
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ public class SelectListByScope extends AbstractMethod {
|
||||
@Override
|
||||
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
|
||||
SqlMethod sqlMethod = SqlMethod.SELECT_LIST;
|
||||
String sql = String.format(sqlMethod.getSql(), this.sqlFirst(), this.sqlSelectColumns(tableInfo, true),
|
||||
String sql = sqlMethod.format(this.sqlFirst(), this.sqlSelectColumns(tableInfo, true),
|
||||
tableInfo.getTableName(), this.sqlWhereEntityWrapper(true, tableInfo), this.sqlOrderBy(tableInfo),
|
||||
this.sqlComment());
|
||||
SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ public class SelectPageByScope extends AbstractMethod {
|
||||
@Override
|
||||
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
|
||||
SqlMethod sqlMethod = SqlMethod.SELECT_PAGE;
|
||||
String sql = String.format(sqlMethod.getSql(), this.sqlFirst(), this.sqlSelectColumns(tableInfo, true),
|
||||
String sql = sqlMethod.format(this.sqlFirst(), this.sqlSelectColumns(tableInfo, true),
|
||||
tableInfo.getTableName(), this.sqlWhereEntityWrapper(true, tableInfo), this.sqlOrderBy(tableInfo),
|
||||
this.sqlComment());
|
||||
SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
|
||||
|
||||
+7
-5
@@ -20,9 +20,9 @@ package com.pig4cloud.pigx.common.data.resolver;
|
||||
import cn.hutool.core.comparator.CompareUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.baomidou.mybatisplus.core.toolkit.sql.SqlInjectionUtils;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.pig4cloud.pigx.common.core.exception.CheckedException;
|
||||
import com.pig4cloud.pigx.common.data.util.SqlSortUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.MethodParameter;
|
||||
@@ -92,14 +92,16 @@ public class SqlFilterArgumentResolver implements HandlerMethodArgumentResolver
|
||||
List<OrderItem> orderItemList = new ArrayList<>();
|
||||
Optional.ofNullable(ascs)
|
||||
.ifPresent(s -> orderItemList.addAll(Arrays.stream(s.split(StrUtil.COMMA))
|
||||
.filter(asc -> !SqlInjectionUtils.check(asc))
|
||||
.map(String::trim)
|
||||
.filter(SqlSortUtils::isValidColumn)
|
||||
.map(OrderItem::asc)
|
||||
.toList()));
|
||||
.toList()));
|
||||
Optional.ofNullable(descs)
|
||||
.ifPresent(s -> orderItemList.addAll(Arrays.stream(s.split(StrUtil.COMMA))
|
||||
.filter(desc -> !SqlInjectionUtils.check(desc))
|
||||
.map(String::trim)
|
||||
.filter(SqlSortUtils::isValidColumn)
|
||||
.map(OrderItem::desc)
|
||||
.toList()));
|
||||
.toList()));
|
||||
page.addOrder(orderItemList);
|
||||
|
||||
return page;
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.data.util;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 前端排序字段校验。仅接受字段名或表别名限定的字段名,不接受 SQL 表达式。
|
||||
* <p>
|
||||
* 本工具只校验字段格式,业务层仍需限制允许排序的字段。
|
||||
*/
|
||||
public final class SqlSortUtils {
|
||||
|
||||
private static final Pattern SORT_COLUMN = Pattern.compile("[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)?");
|
||||
|
||||
private SqlSortUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验单个排序字段。调用方应先拆分多个字段并去除首尾空白。
|
||||
* @param column 前端传入的排序字段
|
||||
* @return 是否为合法的字段名或别名限定字段名
|
||||
*/
|
||||
public static boolean isValidColumn(String column) {
|
||||
return column != null && SORT_COLUMN.matcher(column).matches();
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.pig4cloud.pigx.common.data.datascope;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.config.GlobalConfig;
|
||||
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class DataScopeSqlInjectorTests {
|
||||
|
||||
@Test
|
||||
void registersDataScopeAndJoinStatementsTogether() {
|
||||
MybatisConfiguration configuration = new MybatisConfiguration();
|
||||
GlobalConfig globalConfig = new GlobalConfig();
|
||||
globalConfig.setDbConfig(new GlobalConfig.DbConfig());
|
||||
globalConfig.setSqlInjector(new DataScopeSqlInjector());
|
||||
GlobalConfigUtils.setGlobalConfig(configuration, globalConfig);
|
||||
|
||||
configuration.addMapper(TestMapper.class);
|
||||
|
||||
String namespace = TestMapper.class.getName() + ".";
|
||||
assertThat(configuration.getMappedStatementNames()).contains(namespace + "selectListByScope",
|
||||
namespace + "selectPageByScope", namespace + "selectCountByScope", namespace + "selectJoinList",
|
||||
namespace + "selectJoinPage", namespace + "selectJoinCount", namespace + "selectById");
|
||||
}
|
||||
|
||||
interface TestMapper extends PigxBaseMapper<TestEntity> {
|
||||
}
|
||||
|
||||
@TableName("injector_test")
|
||||
static class TestEntity {
|
||||
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-encrypt-api</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-excel</artifactId>
|
||||
|
||||
+23
-24
@@ -13,32 +13,31 @@ import java.util.List;
|
||||
*/
|
||||
public final class BuiltinConverters {
|
||||
|
||||
private BuiltinConverters() {
|
||||
}
|
||||
private BuiltinConverters() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 读写 Excel 时默认启用的转换器列表。
|
||||
*/
|
||||
private static final List<Converter<?>> INSTANCES = List.of(LocalDateStringConverter.INSTANCE,
|
||||
LocalTimeStringConverter.INSTANCE, LocalDateTimeStringConverter.INSTANCE, LongStringConverter.INSTANCE,
|
||||
StringArrayConverter.INSTANCE);
|
||||
/**
|
||||
* 读写 Excel 时默认启用的转换器列表。
|
||||
*/
|
||||
private static final List<Converter<?>> INSTANCES = List.of(LocalDateStringConverter.INSTANCE,
|
||||
LocalTimeStringConverter.INSTANCE, LocalDateTimeStringConverter.INSTANCE, LongStringConverter.INSTANCE,
|
||||
StringArrayConverter.INSTANCE);
|
||||
|
||||
/**
|
||||
* 注册内置转换器到 Excel 写构造器。
|
||||
*
|
||||
* @param builder Excel 写构造器
|
||||
*/
|
||||
public static void registerTo(ExcelWriterBuilder builder) {
|
||||
INSTANCES.forEach(builder::registerConverter);
|
||||
}
|
||||
/**
|
||||
* 注册内置转换器到 Excel 写构造器。
|
||||
* @param builder Excel 写构造器
|
||||
*/
|
||||
public static void registerTo(ExcelWriterBuilder builder) {
|
||||
INSTANCES.forEach(builder::registerConverter);
|
||||
builder.registerConverter(StringArrayConverter.WRITE_INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册内置转换器到 Excel 读构造器。
|
||||
*
|
||||
* @param builder Excel 读构造器
|
||||
*/
|
||||
public static void registerTo(ExcelReaderBuilder builder) {
|
||||
INSTANCES.forEach(builder::registerConverter);
|
||||
}
|
||||
/**
|
||||
* 注册内置转换器到 Excel 读构造器。
|
||||
* @param builder Excel 读构造器
|
||||
*/
|
||||
public static void registerTo(ExcelReaderBuilder builder) {
|
||||
INSTANCES.forEach(builder::registerConverter);
|
||||
}
|
||||
|
||||
}
|
||||
+20
-6
@@ -18,10 +18,24 @@ public enum StringArrayConverter implements Converter<String[]> {
|
||||
/**
|
||||
* 实例
|
||||
*/
|
||||
INSTANCE;
|
||||
INSTANCE,
|
||||
|
||||
/**
|
||||
* 未指定目标单元格类型时,FESOD 使用 null 作为导出转换器的类型键。
|
||||
*/
|
||||
WRITE_INSTANCE {
|
||||
/**
|
||||
* 提供未指定目标单元格类型时使用的导出转换器查找键。
|
||||
* @return null,与 FESOD 默认导出时的目标单元格类型匹配
|
||||
*/
|
||||
@Override
|
||||
public CellDataTypeEnum supportExcelTypeKey() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Class<?> supportJavaTypeKey() {
|
||||
public Class<?> supportJavaTypeKey() {
|
||||
return String[].class;
|
||||
}
|
||||
|
||||
@@ -31,15 +45,15 @@ public enum StringArrayConverter implements Converter<String[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
|
||||
GlobalConfiguration globalConfiguration) {
|
||||
return StrUtil.splitToArray(cellData.getStringValue(), StrUtil.COMMA);
|
||||
public String[] convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
|
||||
GlobalConfiguration globalConfiguration) {
|
||||
return StrUtil.splitToArray(cellData.getStringValue(), StrUtil.COMMA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WriteCellData<String> convertToExcelData(String[] value, ExcelContentProperty contentProperty,
|
||||
GlobalConfiguration globalConfiguration) {
|
||||
return new WriteCellData<>(String.join(StrUtil.COMMA, value));
|
||||
return new WriteCellData<>(String.join(StrUtil.COMMA, value));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-gateway</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-gray</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-idempotent</artifactId>
|
||||
|
||||
+68
-44
@@ -5,8 +5,10 @@ import com.pig4cloud.pigx.common.idempotent.expression.ExpressionResolver;
|
||||
import com.pig4cloud.pigx.common.idempotent.expression.KeyResolver;
|
||||
import org.redisson.Redisson;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.config.BaseConfig;
|
||||
import org.redisson.config.ClusterServersConfig;
|
||||
import org.redisson.config.Config;
|
||||
import org.redisson.config.SingleServerConfig;
|
||||
import org.redisson.config.SentinelServersConfig;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
@@ -27,52 +29,74 @@ import org.springframework.util.StringUtils;
|
||||
@EnableConfigurationProperties(DataRedisProperties.class)
|
||||
public class IdempotentAutoConfiguration {
|
||||
|
||||
/**
|
||||
* KEY解析器
|
||||
* @return {@link KeyResolver }
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(KeyResolver.class)
|
||||
public KeyResolver keyResolver() {
|
||||
return new ExpressionResolver();
|
||||
}
|
||||
|
||||
/**
|
||||
* KEY解析器
|
||||
*
|
||||
* @return {@link KeyResolver }
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(KeyResolver.class)
|
||||
public KeyResolver keyResolver() {
|
||||
return new ExpressionResolver();
|
||||
}
|
||||
/**
|
||||
* 幂等 Redis 客户端
|
||||
* @param redisProperties Redis 连接配置
|
||||
* @return Redisson 客户端
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(RedissonClient.class)
|
||||
public RedissonClient redissonClient(DataRedisProperties redisProperties) {
|
||||
Config config = new Config();
|
||||
BaseConfig<?> serverConfig;
|
||||
if (redisProperties.getSentinel() != null) {
|
||||
DataRedisProperties.Sentinel sentinel = redisProperties.getSentinel();
|
||||
SentinelServersConfig sentinelConfig = config.useSentinelServers()
|
||||
.setMasterName(sentinel.getMaster())
|
||||
.setDatabase(redisProperties.getDatabase());
|
||||
for (String node : sentinel.getNodes()) {
|
||||
sentinelConfig.addSentinelAddress("redis://" + node);
|
||||
}
|
||||
if (StringUtils.hasText(sentinel.getUsername())) {
|
||||
sentinelConfig.setSentinelUsername(sentinel.getUsername());
|
||||
}
|
||||
if (StringUtils.hasText(sentinel.getPassword())) {
|
||||
sentinelConfig.setSentinelPassword(sentinel.getPassword());
|
||||
}
|
||||
serverConfig = sentinelConfig;
|
||||
}
|
||||
else if (redisProperties.getCluster() != null) {
|
||||
ClusterServersConfig clusterConfig = config.useClusterServers();
|
||||
for (String node : redisProperties.getCluster().getNodes()) {
|
||||
clusterConfig.addNodeAddress("redis://" + node);
|
||||
}
|
||||
serverConfig = clusterConfig;
|
||||
}
|
||||
else {
|
||||
serverConfig = config.useSingleServer()
|
||||
.setAddress("redis://" + redisProperties.getHost() + ":" + redisProperties.getPort())
|
||||
.setDatabase(redisProperties.getDatabase());
|
||||
}
|
||||
|
||||
/**
|
||||
* 幂等方面
|
||||
*
|
||||
* @param redisson redisson 客户端
|
||||
* @param keyResolver KEY解析器
|
||||
* @return {@link IdempotentAspect }
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(RedissonClient.class)
|
||||
public RedissonClient redissonClient(DataRedisProperties redisProperties) {
|
||||
Config config = new Config();
|
||||
SingleServerConfig singleServerConfig = config.useSingleServer()
|
||||
.setAddress("redis://" + redisProperties.getHost() + ":" + redisProperties.getPort())
|
||||
.setDatabase(redisProperties.getDatabase());
|
||||
if (StringUtils.hasText(redisProperties.getUsername())) {
|
||||
serverConfig.setUsername(redisProperties.getUsername());
|
||||
}
|
||||
if (StringUtils.hasText(redisProperties.getPassword())) {
|
||||
serverConfig.setPassword(redisProperties.getPassword());
|
||||
}
|
||||
if (redisProperties.getConnectTimeout() != null) {
|
||||
serverConfig.setConnectTimeout((int) redisProperties.getConnectTimeout().toMillis());
|
||||
}
|
||||
if (redisProperties.getTimeout() != null) {
|
||||
serverConfig.setTimeout((int) redisProperties.getTimeout().toMillis());
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(redisProperties.getUsername())) {
|
||||
singleServerConfig.setUsername(redisProperties.getUsername());
|
||||
}
|
||||
if (StringUtils.hasText(redisProperties.getPassword())) {
|
||||
singleServerConfig.setPassword(redisProperties.getPassword());
|
||||
}
|
||||
if (redisProperties.getConnectTimeout() != null) {
|
||||
singleServerConfig.setConnectTimeout((int) redisProperties.getConnectTimeout().toMillis());
|
||||
}
|
||||
if (redisProperties.getTimeout() != null) {
|
||||
singleServerConfig.setTimeout((int) redisProperties.getTimeout().toMillis());
|
||||
}
|
||||
return Redisson.create(config);
|
||||
}
|
||||
|
||||
return Redisson.create(config);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IdempotentAspect idempotentAspect(RedissonClient redisson, KeyResolver keyResolver) {
|
||||
return new IdempotentAspect(redisson, keyResolver);
|
||||
}
|
||||
@Bean
|
||||
public IdempotentAspect idempotentAspect(RedissonClient redisson, KeyResolver keyResolver) {
|
||||
return new IdempotentAspect(redisson, keyResolver);
|
||||
}
|
||||
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
package com.pig4cloud.pigx.common.idempotent;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.redisson.Redisson;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.config.ClusterServersConfig;
|
||||
import org.redisson.config.Config;
|
||||
import org.redisson.config.SentinelServersConfig;
|
||||
import org.springframework.boot.data.redis.autoconfigure.DataRedisProperties;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.withSettings;
|
||||
|
||||
class IdempotentAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
void usesClusterNodesInsteadOfDefaultSingleServer() {
|
||||
DataRedisProperties properties = new DataRedisProperties();
|
||||
properties.setUsername("cluster-user");
|
||||
properties.setPassword("cluster-password");
|
||||
properties.setConnectTimeout(Duration.ofSeconds(2));
|
||||
properties.setTimeout(Duration.ofSeconds(3));
|
||||
DataRedisProperties.Cluster cluster = new DataRedisProperties.Cluster();
|
||||
cluster.setNodes(List.of("redis-1:7000", "redis-2:7001", "redis-3:7002"));
|
||||
properties.setCluster(cluster);
|
||||
|
||||
RedissonClient client = mock(RedissonClient.class);
|
||||
try (MockedStatic<Redisson> redisson = mockStatic(Redisson.class,
|
||||
withSettings().mockMaker("mock-maker-inline"))) {
|
||||
redisson.when(() -> Redisson.create(any(Config.class))).thenAnswer(invocation -> {
|
||||
Config config = invocation.getArgument(0);
|
||||
assertThat(config.isClusterConfig()).as("必须使用集群模式连接").isTrue();
|
||||
ClusterServersConfig servers = config.useClusterServers();
|
||||
assertThat(servers.getNodeAddresses()).containsExactly("redis://redis-1:7000", "redis://redis-2:7001",
|
||||
"redis://redis-3:7002");
|
||||
assertThat(servers.getUsername()).isEqualTo("cluster-user");
|
||||
assertThat(servers.getPassword()).isEqualTo("cluster-password");
|
||||
assertThat(servers.getConnectTimeout()).isEqualTo(2000);
|
||||
assertThat(servers.getTimeout()).isEqualTo(3000);
|
||||
return client;
|
||||
});
|
||||
assertThat(new IdempotentAutoConfiguration().redissonClient(properties)).isSameAs(client);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void usesSentinelConfigurationInsteadOfDefaultSingleServer() {
|
||||
DataRedisProperties properties = new DataRedisProperties();
|
||||
properties.setDatabase(2);
|
||||
properties.setUsername("data-user");
|
||||
properties.setPassword("data-password");
|
||||
properties.setConnectTimeout(Duration.ofSeconds(2));
|
||||
properties.setTimeout(Duration.ofSeconds(3));
|
||||
DataRedisProperties.Sentinel sentinel = new DataRedisProperties.Sentinel();
|
||||
sentinel.setMaster("mymaster");
|
||||
sentinel.setNodes(List.of("sentinel-1:26379", "sentinel-2:26379"));
|
||||
sentinel.setUsername("sentinel-user");
|
||||
sentinel.setPassword("sentinel-password");
|
||||
properties.setSentinel(sentinel);
|
||||
|
||||
RedissonClient client = mock(RedissonClient.class);
|
||||
try (MockedStatic<Redisson> redisson = mockStatic(Redisson.class,
|
||||
withSettings().mockMaker("mock-maker-inline"))) {
|
||||
redisson.when(() -> Redisson.create(any(Config.class))).thenAnswer(invocation -> {
|
||||
Config config = invocation.getArgument(0);
|
||||
assertThat(config.isSentinelConfig()).as("必须使用哨兵模式连接").isTrue();
|
||||
SentinelServersConfig servers = config.useSentinelServers();
|
||||
assertThat(servers.getMasterName()).isEqualTo("mymaster");
|
||||
assertThat(servers.getSentinelAddresses()).containsExactly("redis://sentinel-1:26379",
|
||||
"redis://sentinel-2:26379");
|
||||
assertThat(servers.getSentinelUsername()).isEqualTo("sentinel-user");
|
||||
assertThat(servers.getSentinelPassword()).isEqualTo("sentinel-password");
|
||||
assertThat(servers.getUsername()).isEqualTo("data-user");
|
||||
assertThat(servers.getPassword()).isEqualTo("data-password");
|
||||
assertThat(servers.getDatabase()).isEqualTo(2);
|
||||
assertThat(servers.getConnectTimeout()).isEqualTo(2000);
|
||||
assertThat(servers.getTimeout()).isEqualTo(3000);
|
||||
return client;
|
||||
});
|
||||
assertThat(new IdempotentAutoConfiguration().redissonClient(properties)).isSameAs(client);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-job</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-log</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-oss</artifactId>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-seata</artifactId>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-security</artifactId>
|
||||
|
||||
+21
-4
@@ -68,14 +68,31 @@ public class CaptchaValidator {
|
||||
return CaptchaResult.failed("验证码参数不能为空");
|
||||
}
|
||||
|
||||
String key = CacheConstants.DEFAULT_CODE_KEY + randomStr;
|
||||
Object codeObj = redisTemplate.opsForValue().get(key);
|
||||
return validateCachedCode(CacheConstants.IMAGE_CODE_KEY + randomStr, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从短信专用缓存校验身份凭据,不读取图形或行为验证码缓存。
|
||||
* 非空参数触发原子读取并删除,无论匹配与否均消费该缓存中的验证码。
|
||||
*
|
||||
* @param mobile 短信登录标识,格式为类型@手机号;调用方负责校验允许的登录类型
|
||||
* @param code 待校验的短信验证码
|
||||
* @return 匹配时返回成功;任一参数为 null、空白,或验证码不存在、过期、不匹配时返回失败;
|
||||
* 参数为空时不访问缓存
|
||||
*/
|
||||
public CaptchaResult validateSms(String mobile, String code) {
|
||||
if (StrUtil.hasBlank(mobile, code)) {
|
||||
return CaptchaResult.failed("验证码参数不能为空");
|
||||
}
|
||||
return validateCachedCode(CacheConstants.SMS_CODE_KEY + mobile, code);
|
||||
}
|
||||
|
||||
private CaptchaResult validateCachedCode(String key, String code) {
|
||||
Object codeObj = redisTemplate.opsForValue().getAndDelete(key);
|
||||
if (codeObj == null || StrUtil.isBlank(codeObj.toString()) || !StrUtil.equals(codeObj.toString(), code)) {
|
||||
redisTemplate.delete(key);
|
||||
return CaptchaResult.failed("验证码错误或已过期");
|
||||
}
|
||||
|
||||
redisTemplate.delete(key);
|
||||
return CaptchaResult.ok();
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -2,13 +2,13 @@ package com.pig4cloud.pigx.common.security.component;
|
||||
|
||||
import cn.hutool.core.net.Ipv4Util;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.JakartaServletUtil;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.tomcat.util.net.IPv6Utils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -39,23 +39,23 @@ public class PigxInnerHeaderRemoveFilter extends OncePerRequestFilter {
|
||||
*/
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException {
|
||||
// 获取客户端IP地址
|
||||
String clientIP = JakartaServletUtil.getClientIP(request);
|
||||
// 使用容器提供的连接地址,不从调用者可填写的转发头提取 IP。
|
||||
String clientIP = request.getRemoteAddr();
|
||||
|
||||
// 允许 127.0.0.1 请求直接通过
|
||||
if (Ipv4Util.LOCAL_IP.equals(clientIP)) {
|
||||
// 兼容 IPv4 回环不解析主机名。
|
||||
if (StrUtil.equalsAny(clientIP, Ipv4Util.LOCAL_IP)) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
String fromHeader = request.getHeader(SecurityConstants.FROM);
|
||||
// 非 127.0.0.1 请求,没有配置 from header ,直接跳过
|
||||
// 普通请求不携带内部标记,交给后续认证与权限检查。
|
||||
if (StrUtil.isBlank(fromHeader)) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// 非 127.0.0.1,配置了 from header ,直接拒绝访问
|
||||
// 外部连接或经过代理的请求,不允许自行声明为内部调用。
|
||||
log.warn("请求 IP {},疑似进行系统注入操作,请注意", clientIP);
|
||||
response.setStatus(HttpStatus.FORBIDDEN.value());
|
||||
}
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ public class PigxResourceServerConfiguration {
|
||||
private final PigxBootCorsProperties corsProperties;
|
||||
|
||||
@Bean
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE + 1)
|
||||
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
PathPatternRequestMatcher[] permitMatchers = permitAllUrl.getIgnoreUrls()
|
||||
.stream()
|
||||
|
||||
+2
-2
@@ -22,7 +22,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Getter;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.SpringSecurityCoreVersion;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
|
||||
|
||||
@@ -40,7 +39,8 @@ import java.util.Map;
|
||||
public class PigxUser extends User implements OAuth2AuthenticatedPrincipal {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
|
||||
// 保留原序列化版本,兼容已有授权缓存。
|
||||
private static final long serialVersionUID = 620L;
|
||||
|
||||
/**
|
||||
* 扩展属性,方便存放oauth 上下文相关信息
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-sensitive</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -55,5 +55,15 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-jackson2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+14
@@ -28,6 +28,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.MessageSourceResolvable;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
@@ -108,6 +109,19 @@ public class GlobalBizExceptionHandler {
|
||||
return R.failed("数据库调用异常,请联系管理员处理");
|
||||
}
|
||||
|
||||
/**
|
||||
* Spring 包装的数据访问异常,避免向客户端回显 SQL 和数据库结构
|
||||
* @param exception 数据访问异常
|
||||
* @return 统一失败响应,不向客户端暴露底层 SQL 细节
|
||||
*/
|
||||
@ExceptionHandler(DataAccessException.class)
|
||||
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
public R handleDataAccessException(DataAccessException exception) {
|
||||
log.error("数据库调用异常 ex={}", exception.getMessage(), exception);
|
||||
Tracer.trace(exception);
|
||||
return R.failed("数据库调用异常,请联系管理员处理");
|
||||
}
|
||||
|
||||
/**
|
||||
* Feign 远程调用异常,透传远端 R 响应体
|
||||
* @param e Feign 调用异常
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.pig4cloud.pigx.common.sentinel.handle;
|
||||
|
||||
import com.alibaba.csp.sentinel.Entry;
|
||||
import com.alibaba.csp.sentinel.SphU;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.method.annotation.ExceptionHandlerMethodResolver;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class GlobalBizExceptionHandlerTests {
|
||||
|
||||
@Test
|
||||
void dataAccessExceptionMustNotExposeSql() throws Exception {
|
||||
String sql = "select password, salt from sys_user where username = 'admin'";
|
||||
BadSqlGrammarException exception = new BadSqlGrammarException("query", sql, new SQLException("syntax error"));
|
||||
ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(GlobalBizExceptionHandler.class);
|
||||
Method method = resolver.resolveMethodByThrowable(exception);
|
||||
|
||||
assertThat(method).isNotNull();
|
||||
try (Entry entry = SphU.entry("dataAccessExceptionMustNotExposeSql")) {
|
||||
R<?> result = (R<?>) method.invoke(new GlobalBizExceptionHandler(), exception);
|
||||
|
||||
assertThat(result.getCode()).isEqualTo(CommonConstants.FAIL);
|
||||
assertThat(result.getMsg()).isEqualTo("数据库调用异常,请联系管理员处理");
|
||||
assertThat(result.getData()).isNull();
|
||||
assertThat(method.getAnnotation(ResponseStatus.class).value()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
assertThat(entry.getError()).isSameAs(exception);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-sequence</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-sse</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-swagger</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-websocket</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-xss</artifactId>
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ public class XssUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSafeAttribute(String tagName, Element el, Attribute attr) {
|
||||
public boolean isSafeAttribute(String tagName, Element el, Attribute attr) {
|
||||
// 不允许 javascript 开头的 src 和 href
|
||||
if ("src".equalsIgnoreCase(attr.getKey()) || "href".equalsIgnoreCase(attr.getKey())) {
|
||||
String value = attr.getValue();
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common</artifactId>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-flow</artifactId>
|
||||
<version>6.1.0</version>
|
||||
<version>6.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-flow-api</artifactId>
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.pig4cloud.pigx.flow.constant;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/** 流程通知事件类型;编码与 flow_notice.kind 保持兼容,标签用于统一站内信标题。 */
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum FlowNoticeKindEnum {
|
||||
|
||||
/** 新分配的待办任务。 */
|
||||
TODO("TODO", "待办"),
|
||||
|
||||
/** 发起人手动催办。 */
|
||||
URGE("URGE", "催办"),
|
||||
|
||||
/** 审批节点超时提醒。 */
|
||||
OVERDUE("OVERDUE", "超时提醒");
|
||||
|
||||
/** 持久化编码,不能随枚举重命名改变。 */
|
||||
private final String code;
|
||||
|
||||
/** 站内信标题前缀。 */
|
||||
private final String label;
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.pig4cloud.pigx.flow.constant;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* 流程通知事件状态;READY 经统一信息推送发送后转为 SENT,待触发提醒随任务结束取消。
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum FlowNoticeStatusEnum {
|
||||
|
||||
/** 等待截止时间,到期后确定当前审批人。 */
|
||||
PENDING("PENDING"),
|
||||
|
||||
/** 等待投递到统一站内信。 */
|
||||
READY("READY"),
|
||||
|
||||
/** 已投递到统一站内信,已读状态由 sys_message_relation 维护。 */
|
||||
SENT("SENT"),
|
||||
|
||||
/** 任务结束或接收人变更,等待删除统一站内信的接收记录。 */
|
||||
REMOVING("REMOVING"),
|
||||
|
||||
/** 任务已经结束,提醒已取消或接收记录已删除。 */
|
||||
CANCELLED("CANCELLED"),
|
||||
|
||||
/** 旧监听没有截止时间,迁移后保留但不参与扫描。 */
|
||||
DISABLED("DISABLED");
|
||||
|
||||
/** 数据库状态值,保持与已发布的三表结构兼容。 */
|
||||
private final String code;
|
||||
|
||||
}
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
package com.pig4cloud.pigx.flow.constant;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 枚举通用接口
|
||||
* <p>
|
||||
* 为所有业务枚举提供统一的接口规范,实现枚举值和标签的标准化管理。
|
||||
* 提供了根据值获取枚举、根据值获取标签、根据标签获取值等通用方法。
|
||||
* 所有业务枚举类都应实现此接口,以保证枚举使用的一致性。
|
||||
* </p>
|
||||
*
|
||||
* @param <T> 枚举值的类型,通常为Integer或String
|
||||
* @author haoxr
|
||||
* @since 2022/3/27 12:06
|
||||
*/
|
||||
public interface IBaseEnum<T> {
|
||||
|
||||
/**
|
||||
* 获取枚举值
|
||||
* <p>
|
||||
* 返回枚举对应的实际值,通常用于数据库存储或接口传输
|
||||
* </p>
|
||||
*
|
||||
* @return 枚举对应的值
|
||||
*/
|
||||
T getValue();
|
||||
|
||||
/**
|
||||
* 获取枚举标签
|
||||
* <p>
|
||||
* 返回枚举对应的显示标签,通常用于界面展示
|
||||
* </p>
|
||||
*
|
||||
* @return 枚举对应的中文标签
|
||||
*/
|
||||
String getLabel();
|
||||
|
||||
/**
|
||||
* 根据值获取对应的枚举实例
|
||||
* <p>
|
||||
* 通过枚举值查找对应的枚举实例,常用于数据库查询结果的转换。
|
||||
* 如果找不到匹配的枚举,返回null。
|
||||
* </p>
|
||||
*
|
||||
* @param value 枚举值
|
||||
* @param clazz 枚举类的Class对象
|
||||
* @param <E> 枚举类型,必须实现IBaseEnum接口
|
||||
* @return 匹配的枚举实例,如果没有找到返回null
|
||||
*/
|
||||
static <E extends Enum<E> & IBaseEnum> E getEnumByValue(Object value, Class<E> clazz) {
|
||||
Objects.requireNonNull(value);
|
||||
EnumSet<E> allEnums = EnumSet.allOf(clazz); // 获取类型下的所有枚举
|
||||
E matchEnum = allEnums.stream().filter(e -> ObjectUtil.equal(e.getValue(), value)).findFirst().orElse(null);
|
||||
return matchEnum;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据值获取对应的标签
|
||||
* <p>
|
||||
* 通过枚举值直接获取对应的显示标签,常用于列表展示时的值转换。
|
||||
* 如果找不到匹配的枚举,返回null。
|
||||
* </p>
|
||||
*
|
||||
* @param value 枚举值
|
||||
* @param clazz 枚举类的Class对象
|
||||
* @param <E> 枚举类型,必须实现IBaseEnum接口
|
||||
* @return 枚举对应的标签,如果没有找到返回null
|
||||
*/
|
||||
static <E extends Enum<E> & IBaseEnum> String getLabelByValue(Object value, Class<E> clazz) {
|
||||
Objects.requireNonNull(value);
|
||||
EnumSet<E> allEnums = EnumSet.allOf(clazz); // 获取类型下的所有枚举
|
||||
E matchEnum = allEnums.stream().filter(e -> ObjectUtil.equal(e.getValue(), value)).findFirst().orElse(null);
|
||||
|
||||
String label = null;
|
||||
if (matchEnum != null) {
|
||||
label = matchEnum.getLabel();
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据标签获取对应的值
|
||||
* <p>
|
||||
* 通过枚举标签反向查找对应的枚举值,常用于表单提交时的数据转换。
|
||||
* 如果找不到匹配的枚举,返回null。
|
||||
* </p>
|
||||
*
|
||||
* @param label 枚举标签
|
||||
* @param clazz 枚举类的Class对象
|
||||
* @param <E> 枚举类型,必须实现IBaseEnum接口
|
||||
* @return 枚举对应的值,如果没有找到返回null
|
||||
*/
|
||||
static <E extends Enum<E> & IBaseEnum> Object getValueByLabel(String label, Class<E> clazz) {
|
||||
Objects.requireNonNull(label);
|
||||
EnumSet<E> allEnums = EnumSet.allOf(clazz); // 获取类型下的所有枚举
|
||||
String finalLabel = label;
|
||||
E matchEnum = allEnums.stream()
|
||||
.filter(e -> ObjectUtil.equal(e.getLabel(), finalLabel))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
Object value = null;
|
||||
if (matchEnum != null) {
|
||||
value = matchEnum.getValue();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
+5
@@ -60,6 +60,11 @@ public class ProcessInstanceConstant {
|
||||
*/
|
||||
public static final String REJECT_TO_STARTER_VAR = "rejectToStarter";
|
||||
|
||||
/**
|
||||
* 流程变量:明确的流程结束原因
|
||||
*/
|
||||
public static final String FINISH_REASON_VAR = "_pigx_finish_reason";
|
||||
|
||||
/**
|
||||
* 流程结束原因:拒绝
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.pig4cloud.pigx.flow.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 个人流程草稿保存请求;租户和用户只能由认证上下文提供。标题和内容仅反序列化,避免操作日志记录个人表单。
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "个人流程草稿保存请求")
|
||||
public class FlowDraftDTO {
|
||||
|
||||
/** 首次保存为空;更新时为已有草稿 ID。 */
|
||||
@Schema(description = "首次保存为空,更新使用已有草稿 ID")
|
||||
private String id;
|
||||
|
||||
/** 草稿类型:DESIGN 流程设计,APPLICATION 动态表单申请。 */
|
||||
@NotBlank
|
||||
@Pattern(regexp = "DESIGN|APPLICATION", message = "草稿类型无效")
|
||||
@Schema(description = "草稿类型", allowableValues = { "DESIGN", "APPLICATION" })
|
||||
private String kind;
|
||||
|
||||
/** 关联流程 ID;尚未建立流程的设计草稿为空串。 */
|
||||
@NotNull
|
||||
@Size(max = 64)
|
||||
@Schema(description = "关联流程 ID,尚未建立流程的设计草稿可为空串")
|
||||
private String flowId;
|
||||
|
||||
/** 草稿标题,最多 200 字符。 */
|
||||
@NotBlank
|
||||
@Size(max = 200)
|
||||
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
|
||||
@Schema(description = "非空标题,最多 200 字符")
|
||||
private String title;
|
||||
|
||||
/** 与 kind 对应的 JSON 对象字符串,最多 1 MB UTF-8;字节数和 JSON 结构由服务端校验。 */
|
||||
@NotBlank
|
||||
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
|
||||
@Schema(description = "与 kind 对应的 JSON 对象字符串,最多 1 MB UTF-8")
|
||||
private String payload;
|
||||
|
||||
/** 首次保存为 0;更新时为读取到的版本号,冲突时拒绝覆盖。 */
|
||||
@Schema(description = "首次保存为 0,更新为读取时的版本号")
|
||||
private long revision;
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.pig4cloud.pigx.flow.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/** 打开动态表单时查询字段权限的 REST 配置。 */
|
||||
@Data
|
||||
public class FormPermissionConfig {
|
||||
|
||||
/** 是否启用 REST 权限查询;null 或 false 表示使用静态权限。 */
|
||||
private Boolean enabled;
|
||||
|
||||
/** 已启用时必填的完整 HTTP(S) 地址,不能包含账号或片段。 */
|
||||
private String url;
|
||||
|
||||
}
|
||||
@@ -70,6 +70,9 @@ public class Node {
|
||||
*/
|
||||
private String eventConfig;
|
||||
|
||||
/** 超时提醒分钟数;空或 0 表示关闭,按任务创建时间计算自然时长。 */
|
||||
private Integer reminderMinutes;
|
||||
|
||||
/**
|
||||
* 执行人分配类型 对应AssignedTypeClass中的常量(指定用户、部门主管、角色等)
|
||||
*/
|
||||
@@ -121,11 +124,19 @@ public class Node {
|
||||
*/
|
||||
private List<Node> conditionNodes;
|
||||
|
||||
/**
|
||||
* 条件分支是否允许同时命中多条 true=包容网关,满足条件的分支都执行;空或 false=排他网关,只走一条
|
||||
*/
|
||||
private Boolean multiMatch;
|
||||
|
||||
/**
|
||||
* 表单字段权限配置 key=表单字段ID,value=权限类型(H=隐藏,R=只读,E=编辑)
|
||||
*/
|
||||
private Map<String, String> formPerms;
|
||||
|
||||
/** REST 返回值按字段覆盖静态权限;未启用时沿用 formPerms。 */
|
||||
private FormPermissionConfig formPermissionConfig;
|
||||
|
||||
/**
|
||||
* 无执行人处理配置 定义当节点找不到执行人时的处理策略
|
||||
*/
|
||||
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
package com.pig4cloud.pigx.flow.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 节点HTTP请求结果数据传输对象
|
||||
* <p>
|
||||
* 该DTO用于封装流程节点执行HTTP请求后的返回结果。
|
||||
* 在流程执行过程中,某些节点可能需要调用外部系统的接口(如获取审批人、
|
||||
* 验证业务数据等),此对象用于统一封装这些HTTP请求的响应结果。
|
||||
* </p>
|
||||
*
|
||||
* @author pigx
|
||||
*/
|
||||
@Data
|
||||
public class NodeHttpResultVO {
|
||||
|
||||
/**
|
||||
* 请求是否成功
|
||||
* <p>
|
||||
* 标识HTTP请求是否执行成功:
|
||||
* - true: 请求成功,data字段包含返回的业务数据
|
||||
* - false: 请求失败,data字段可能包含错误信息
|
||||
* </p>
|
||||
*/
|
||||
private Boolean ok;
|
||||
|
||||
/**
|
||||
* 返回的数据内容
|
||||
* <p>
|
||||
* HTTP请求返回的业务数据,以Map形式存储,便于灵活处理各种数据结构。
|
||||
* 成功时包含业务数据,失败时可能包含错误码、错误信息等。
|
||||
* 具体内容取决于调用的接口定义。
|
||||
* </p>
|
||||
*/
|
||||
private Map<String, Object> data;
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.pig4cloud.pigx.flow.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/** 打开发起表单;initialData 为草稿与业务入口合并后的初始数据。 */
|
||||
@Data
|
||||
public class OpenProcessFormDto {
|
||||
|
||||
/** 待发起流程的业务标识,必填。 */
|
||||
@NotBlank
|
||||
private String flowId;
|
||||
|
||||
/** 可选初始数据,由调用方按草稿低于入口参数的优先级合并,覆盖表单默认值。 */
|
||||
private Map<String, Object> initialData;
|
||||
|
||||
/** 恢复草稿时校验发布版本,防止将旧稿数据送给新版本的权限接口。 */
|
||||
private String draftVersion;
|
||||
|
||||
}
|
||||
Loaded 100 of 397 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user