Compare commits
47 Commits
develop
...
update-2.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcde5acba8 | ||
|
|
ff462a9a40 | ||
|
|
cc8e320fd5 | ||
|
|
5417c1d311 | ||
|
|
3f28749c31 | ||
|
|
93f4db6c2a | ||
|
|
45a10786bc | ||
|
|
12466eb63a | ||
|
|
59029ac68b | ||
|
|
a7a2c464e0 | ||
|
|
556597a126 | ||
|
|
027d5e9327 | ||
|
|
d86cd66715 | ||
|
|
dae1ad9dd5 | ||
|
|
174ceb6041 | ||
|
|
1d6b24607a | ||
|
|
42197d8d7b | ||
|
|
e8fb661398 | ||
|
|
27427be842 | ||
|
|
5d5b715b55 | ||
|
|
d881cce65b | ||
|
|
5a881bdb6e | ||
|
|
a0ae26253f | ||
|
|
4a079d7e9d | ||
|
|
150439ad1b | ||
|
|
6d7ea72c1e | ||
|
|
03747a0a8b | ||
|
|
91de213790 | ||
|
|
627f13d707 | ||
|
|
dc5dfc8f7b | ||
|
|
dbce51193b | ||
|
|
4f758d35c5 | ||
|
|
130c2f21ff | ||
|
|
0a46549dd0 | ||
|
|
2bcd06235e | ||
|
|
45013f520a | ||
|
|
2b96854e2a | ||
|
|
07f5328b27 | ||
|
|
f767728884 | ||
|
|
c1efb38526 | ||
|
|
fde0867dd8 | ||
|
|
2aabbcc7ca | ||
|
|
2b1e431b1e | ||
|
|
ea65b82505 | ||
|
|
e6b24fbbe1 | ||
|
|
ede6f72fbf | ||
|
|
8bea769556 |
@ -1,6 +1,6 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://img.shields.io/badge/Spring%20Cloud-2024-blue.svg" alt="Coverage Status">
|
<img src="https://img.shields.io/badge/Spring%20Cloud-2024-blue.svg" alt="Coverage Status">
|
||||||
<img src="https://img.shields.io/badge/Spring%20Boot-3.4.1-blue.svg" alt="Downloads">
|
<img src="https://img.shields.io/badge/Spring%20Boot-3.4.5-blue.svg" alt="Downloads">
|
||||||
<img src="https://img.shields.io/badge/Vue-3.2-blue.svg" alt="Downloads">
|
<img src="https://img.shields.io/badge/Vue-3.2-blue.svg" alt="Downloads">
|
||||||
<img src="https://img.shields.io/github/license/YunaiV/yudao-cloud" alt="Downloads" />
|
<img src="https://img.shields.io/github/license/YunaiV/yudao-cloud" alt="Downloads" />
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
6
pom.xml
6
pom.xml
@ -11,6 +11,8 @@
|
|||||||
<module>yudao-dependencies</module>
|
<module>yudao-dependencies</module>
|
||||||
<module>yudao-gateway</module>
|
<module>yudao-gateway</module>
|
||||||
<module>yudao-framework</module>
|
<module>yudao-framework</module>
|
||||||
|
<!-- Server 主项目 -->
|
||||||
|
<module>yudao-server</module>
|
||||||
<!-- 各种 module 拓展 -->
|
<!-- 各种 module 拓展 -->
|
||||||
<module>yudao-module-system</module>
|
<module>yudao-module-system</module>
|
||||||
<module>yudao-module-infra</module>
|
<module>yudao-module-infra</module>
|
||||||
@ -31,7 +33,7 @@
|
|||||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<yudao-revision>2.4.2-SNAPSHOT</yudao-revision>
|
<yudao-revision>2.5.0-SNAPSHOT</yudao-revision>
|
||||||
<revision>1.0.0-SNAPSHOT</revision>
|
<revision>1.0.0-SNAPSHOT</revision>
|
||||||
<!-- Maven 相关 -->
|
<!-- Maven 相关 -->
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
@ -42,7 +44,7 @@
|
|||||||
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
|
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
|
||||||
<!-- 看看咋放到 bom 里 -->
|
<!-- 看看咋放到 bom 里 -->
|
||||||
<lombok.version>1.18.36</lombok.version>
|
<lombok.version>1.18.36</lombok.version>
|
||||||
<spring.boot.version>3.4.1</spring.boot.version>
|
<spring.boot.version>3.4.5</spring.boot.version>
|
||||||
<mapstruct.version>1.6.3</mapstruct.version>
|
<mapstruct.version>1.6.3</mapstruct.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
Target Server Version : 80200 (8.2.0)
|
Target Server Version : 80200 (8.2.0)
|
||||||
File Encoding : 65001
|
File Encoding : 65001
|
||||||
|
|
||||||
Date: 17/03/2025 13:14:16
|
Date: 12/05/2025 09:09:45
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SET NAMES utf8mb4;
|
SET NAMES utf8mb4;
|
||||||
@ -49,7 +49,7 @@ CREATE TABLE `infra_api_access_log` (
|
|||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 35942 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 35953 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_api_access_log
|
-- Records of infra_api_access_log
|
||||||
@ -91,7 +91,7 @@ CREATE TABLE `infra_api_error_log` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 21482 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
|
) ENGINE = InnoDB AUTO_INCREMENT = 22175 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_api_error_log
|
-- Records of infra_api_error_log
|
||||||
@ -193,7 +193,7 @@ CREATE TABLE `infra_config` (
|
|||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '参数配置表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '参数配置表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_config
|
-- Records of infra_config
|
||||||
@ -205,7 +205,8 @@ INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `val
|
|||||||
INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (9, 'url', 2, 'Spring Boot Admin 监控的地址', 'url.spring-boot-admin', '', b'1', '', '1', '2023-04-07 13:41:16', '1', '2023-04-07 14:52:07', b'0');
|
INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (9, 'url', 2, 'Spring Boot Admin 监控的地址', 'url.spring-boot-admin', '', b'1', '', '1', '2023-04-07 13:41:16', '1', '2023-04-07 14:52:07', b'0');
|
||||||
INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (10, 'url', 2, 'Swagger 接口文档的地址', 'url.swagger', '', b'1', '', '1', '2023-04-07 13:41:16', '1', '2023-04-07 14:59:00', b'0');
|
INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (10, 'url', 2, 'Swagger 接口文档的地址', 'url.swagger', '', b'1', '', '1', '2023-04-07 13:41:16', '1', '2023-04-07 14:59:00', b'0');
|
||||||
INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (11, 'ui', 2, '腾讯地图 key', 'tencent.lbs.key', 'TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E', b'1', '腾讯地图 key', '1', '2023-06-03 19:16:27', '1', '2023-06-03 19:16:27', b'0');
|
INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (11, 'ui', 2, '腾讯地图 key', 'tencent.lbs.key', 'TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E', b'1', '腾讯地图 key', '1', '2023-06-03 19:16:27', '1', '2023-06-03 19:16:27', b'0');
|
||||||
INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (12, 'test2', 2, 'test3', 'test4', 'test5', b'1', 'test6', '1', '2023-12-03 09:55:16', '1', '2023-12-03 09:55:27', b'0');
|
INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (12, 'test2', 2, 'test3', 'test4', 'test5', b'1', 'test6', '1', '2023-12-03 09:55:16', '1', '2025-04-06 21:00:09', b'0');
|
||||||
|
INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (13, '用户管理-账号初始密码', 2, '用户管理-注册开关', 'system.user.register-enabled', 'true', b'0', '', '1', '2025-04-26 17:23:41', '1', '2025-04-26 17:23:41', b'0');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -224,7 +225,7 @@ CREATE TABLE `infra_data_source_config` (
|
|||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '数据源配置表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '数据源配置表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_data_source_config
|
-- Records of infra_data_source_config
|
||||||
@ -250,7 +251,7 @@ CREATE TABLE `infra_file` (
|
|||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 1657 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 1898 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_file
|
-- Records of infra_file
|
||||||
@ -275,19 +276,21 @@ CREATE TABLE `infra_file_config` (
|
|||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 29 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件配置表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 31 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件配置表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_file_config
|
-- Records of infra_file_config
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '数据库(示例)', 1, '我是数据库', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClientConfig\",\"domain\":\"http://127.0.0.1:48080\"}', '1', '2022-03-15 23:56:24', '1', '2024-11-09 18:09:28', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '数据库(示例)', 1, '我是数据库', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClientConfig\",\"domain\":\"http://127.0.0.1:48080\"}', '1', '2022-03-15 23:56:24', '1', '2025-05-02 18:30:28', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (22, '七牛存储器(示例)', 20, '请换成你自己的密钥!!!', b'1', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3.cn-south-1.qiniucs.com\",\"domain\":\"http://test.yudao.iocoder.cn\",\"bucket\":\"ruoyi-vue-pro\",\"accessKey\":\"3TvrJ70gl2Gt6IBe7_IZT1F6i_k0iMuRtyEv4EyS\",\"accessSecret\":\"wd0tbVBYlp0S-ihA8Qg2hPLncoP83wyrIq24OZuY\"}', '1', '2024-01-13 22:11:12', '1', '2024-11-09 18:09:28', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (22, '七牛存储器(示例)', 20, '请换成你自己的密钥!!!', b'1', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3.cn-south-1.qiniucs.com\",\"domain\":\"http://test.yudao.iocoder.cn\",\"bucket\":\"ruoyi-vue-pro\",\"accessKey\":\"3TvrJ70gl2Gt6IBe7_IZT1F6i_k0iMuRtyEv4EyS\",\"accessSecret\":\"wd0tbVBYlp0S-ihA8Qg2hPLncoP83wyrIq24OZuY\",\"enablePathStyleAccess\":false}', '1', '2024-01-13 22:11:12', '1', '2025-05-02 18:30:28', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (24, '腾讯云存储(示例)', 20, '请换成你的密钥!!!', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"https://cos.ap-shanghai.myqcloud.com\",\"domain\":\"http://tengxun-oss.iocoder.cn\",\"bucket\":\"aoteman-1255880240\",\"accessKey\":\"AKIDAF6WSh1uiIjwqtrOsGSN3WryqTM6cTMt\",\"accessSecret\":\"X\"}', '1', '2024-11-09 16:03:22', '1', '2024-11-09 18:15:39', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (24, '腾讯云存储(示例)', 20, '请换成你的密钥!!!', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"https://cos.ap-shanghai.myqcloud.com\",\"domain\":\"http://tengxun-oss.iocoder.cn\",\"bucket\":\"aoteman-1255880240\",\"accessKey\":\"AKIDAF6WSh1uiIjwqtrOsGSN3WryqTM6cTMt\",\"accessSecret\":\"X\"}', '1', '2024-11-09 16:03:22', '1', '2025-05-02 18:30:28', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (25, '阿里云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"oss-cn-beijing.aliyuncs.com\",\"domain\":\"http://ali-oss.iocoder.cn\",\"bucket\":\"yunai-aoteman\",\"accessKey\":\"LTAI5tEQLgnDyjh3WpNcdMKA\",\"accessSecret\":\"X\"}', '1', '2024-11-09 16:47:08', '1', '2024-11-09 18:15:43', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (25, '阿里云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"oss-cn-beijing.aliyuncs.com\",\"domain\":\"http://ali-oss.iocoder.cn\",\"bucket\":\"yunai-aoteman\",\"accessKey\":\"LTAI5tEQLgnDyjh3WpNcdMKA\",\"accessSecret\":\"X\",\"enablePathStyleAccess\":false}', '1', '2024-11-09 16:47:08', '1', '2025-05-02 18:30:28', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (26, '火山云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"tos-s3-cn-beijing.volces.com\",\"domain\":null,\"bucket\":\"yunai\",\"accessKey\":\"AKLTZjc3Zjc4MzZmMjU3NDk0ZTgxYmIyMmFkNTIwMDI1ZGE\",\"accessSecret\":\"X==\"}', '1', '2024-11-09 16:56:42', '1', '2024-11-09 18:15:46', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (26, '火山云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"tos-s3-cn-beijing.volces.com\",\"domain\":null,\"bucket\":\"yunai\",\"accessKey\":\"AKLTZjc3Zjc4MzZmMjU3NDk0ZTgxYmIyMmFkNTIwMDI1ZGE\",\"accessSecret\":\"X==\",\"enablePathStyleAccess\":false}', '1', '2024-11-09 16:56:42', '1', '2025-05-02 18:30:28', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (27, '华为云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"obs.cn-east-3.myhuaweicloud.com\",\"domain\":\"\",\"bucket\":\"yudao\",\"accessKey\":\"PVDONDEIOTW88LF8DC4U\",\"accessSecret\":\"X\"}', '1', '2024-11-09 17:18:41', '1', '2024-11-09 18:15:49', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (27, '华为云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"obs.cn-east-3.myhuaweicloud.com\",\"domain\":\"\",\"bucket\":\"yudao\",\"accessKey\":\"PVDONDEIOTW88LF8DC4U\",\"accessSecret\":\"X\",\"enablePathStyleAccess\":false}', '1', '2024-11-09 17:18:41', '1', '2025-05-02 18:30:28', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (28, 'MinIO 存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"http://127.0.0.1:9000\",\"domain\":\"http://127.0.0.1:9000/yudao\",\"bucket\":\"yudao\",\"accessKey\":\"admin\",\"accessSecret\":\"password\"}', '1', '2024-11-09 17:43:10', '1', '2024-11-09 18:15:52', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (28, 'MinIO 存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"http://127.0.0.1:9000\",\"domain\":\"http://127.0.0.1:9000/yudao\",\"bucket\":\"yudao\",\"accessKey\":\"admin\",\"accessSecret\":\"password\",\"enablePathStyleAccess\":false}', '1', '2024-11-09 17:43:10', '1', '2025-05-02 18:30:28', b'0');
|
||||||
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (29, '本地存储(示例)', 10, '仅适合 mac 或 windows', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.local.LocalFileClientConfig\",\"basePath\":\"/Users/yunai/tmp/file\",\"domain\":\"http://127.0.0.1:48080\"}', '1', '2025-05-02 11:25:45', '1', '2025-05-02 18:30:28', b'0');
|
||||||
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (30, 'SFTP 存储(示例)', 12, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.sftp.SftpFileClientConfig\",\"basePath\":\"/upload\",\"domain\":\"http://127.0.0.1:48080\",\"host\":\"127.0.0.1\",\"port\":2222,\"username\":\"foo\",\"password\":\"pass\"}', '1', '2025-05-02 16:34:10', '1', '2025-05-02 18:30:28', b'0');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -305,7 +308,7 @@ CREATE TABLE `infra_file_content` (
|
|||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 283 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 286 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_file_content
|
-- Records of infra_file_content
|
||||||
@ -333,7 +336,7 @@ CREATE TABLE `infra_job` (
|
|||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 34 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 36 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_job
|
-- Records of infra_job
|
||||||
@ -350,7 +353,8 @@ INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`
|
|||||||
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (25, '访问日志清理 Job', 2, 'accessLogCleanJob', '', '0 0 0 * * ?', 3, 0, 0, '1', '2023-10-03 10:59:41', '1', '2023-10-03 11:01:10', b'0');
|
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (25, '访问日志清理 Job', 2, 'accessLogCleanJob', '', '0 0 0 * * ?', 3, 0, 0, '1', '2023-10-03 10:59:41', '1', '2023-10-03 11:01:10', b'0');
|
||||||
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (26, '错误日志清理 Job', 2, 'errorLogCleanJob', '', '0 0 0 * * ?', 3, 0, 0, '1', '2023-10-03 11:00:43', '1', '2023-10-03 11:01:12', b'0');
|
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (26, '错误日志清理 Job', 2, 'errorLogCleanJob', '', '0 0 0 * * ?', 3, 0, 0, '1', '2023-10-03 11:00:43', '1', '2023-10-03 11:01:12', b'0');
|
||||||
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (27, '任务日志清理 Job', 2, 'jobLogCleanJob', '', '0 0 0 * * ?', 3, 0, 0, '1', '2023-10-03 11:01:33', '1', '2024-09-12 13:40:34', b'0');
|
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (27, '任务日志清理 Job', 2, 'jobLogCleanJob', '', '0 0 0 * * ?', 3, 0, 0, '1', '2023-10-03 11:01:33', '1', '2024-09-12 13:40:34', b'0');
|
||||||
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (33, 'demoJob', 2, 'demoJob', '', '0 * * * * ?', 1, 1, 0, '1', '2024-10-27 19:38:46', '1', '2024-10-27 19:40:23', b'0');
|
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (33, 'demoJob', 2, 'demoJob', '', '0 * * * * ?', 1, 1, 0, '1', '2024-10-27 19:38:46', '1', '2025-05-10 18:13:54', b'0');
|
||||||
|
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (35, '转账订单的同步 Job', 2, 'payTransferSyncJob', '', '0 * * * * ?', 0, 0, 0, '1', '2025-05-10 17:35:54', '1', '2025-05-10 18:13:52', b'0');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -374,7 +378,7 @@ CREATE TABLE `infra_job_log` (
|
|||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 638 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 972 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_job_log
|
-- Records of infra_job_log
|
||||||
@ -408,8 +412,8 @@ CREATE TABLE `system_dept` (
|
|||||||
-- Records of system_dept
|
-- Records of system_dept
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, '芋道源码', 0, 0, 1, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2023-11-14 23:30:36', b'0', 1);
|
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, '芋道源码', 0, 0, 1, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2025-03-29 15:47:53', b'0', 1);
|
||||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (101, '深圳总公司', 100, 1, 104, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2023-12-02 09:53:35', b'0', 1);
|
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (101, '深圳总公司', 100, 1, 104, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2025-03-29 15:49:55', b'0', 1);
|
||||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (102, '长沙分公司', 100, 2, NULL, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-12-15 05:01:40', b'0', 1);
|
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (102, '长沙分公司', 100, 2, NULL, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-12-15 05:01:40', b'0', 1);
|
||||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, '研发部门', 101, 1, 1, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2024-10-02 10:22:03', b'0', 1);
|
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, '研发部门', 101, 1, 1, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2024-10-02 10:22:03', b'0', 1);
|
||||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, '市场部门', 101, 2, NULL, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-12-15 05:01:38', b'0', 1);
|
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, '市场部门', 101, 2, NULL, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-12-15 05:01:38', b'0', 1);
|
||||||
@ -421,7 +425,7 @@ INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`,
|
|||||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (110, '新部门', 0, 1, NULL, NULL, NULL, 0, '110', '2022-02-23 20:46:30', '110', '2022-02-23 20:46:30', b'0', 121);
|
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (110, '新部门', 0, 1, NULL, NULL, NULL, 0, '110', '2022-02-23 20:46:30', '110', '2022-02-23 20:46:30', b'0', 121);
|
||||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, '顶级部门', 0, 1, NULL, NULL, NULL, 0, '113', '2022-03-07 21:44:50', '113', '2022-03-07 21:44:50', b'0', 122);
|
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, '顶级部门', 0, 1, NULL, NULL, NULL, 0, '113', '2022-03-07 21:44:50', '113', '2022-03-07 21:44:50', b'0', 122);
|
||||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (112, '产品部门', 101, 100, 1, NULL, NULL, 1, '1', '2023-12-02 09:45:13', '1', '2023-12-02 09:45:31', b'0', 1);
|
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (112, '产品部门', 101, 100, 1, NULL, NULL, 1, '1', '2023-12-02 09:45:13', '1', '2023-12-02 09:45:31', b'0', 1);
|
||||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, '支持部门', 102, 3, 104, NULL, NULL, 1, '1', '2023-12-02 09:47:38', '1', '2023-12-02 09:47:38', b'0', 1);
|
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, '支持部门', 102, 3, 104, NULL, NULL, 1, '1', '2023-12-02 09:47:38', '1', '2025-03-29 15:00:56', b'0', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -444,7 +448,7 @@ CREATE TABLE `system_dict_data` (
|
|||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 3000 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 3003 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_dict_data
|
-- Records of system_dict_data
|
||||||
@ -492,7 +496,7 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
|
|||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (58, 1, '成功', '1', 'infra_job_log_status', 0, 'success', '', NULL, '', '2021-02-08 10:06:57', '1', '2022-02-16 19:07:52', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (58, 1, '成功', '1', 'infra_job_log_status', 0, 'success', '', NULL, '', '2021-02-08 10:06:57', '1', '2022-02-16 19:07:52', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (59, 2, '失败', '2', 'infra_job_log_status', 0, 'warning', '', '失败', '', '2021-02-08 10:07:38', '1', '2022-02-16 19:07:56', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (59, 2, '失败', '2', 'infra_job_log_status', 0, 'warning', '', '失败', '', '2021-02-08 10:07:38', '1', '2022-02-16 19:07:56', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (60, 1, '会员', '1', 'user_type', 0, 'primary', '', NULL, '', '2021-02-26 00:16:27', '1', '2022-02-16 10:22:19', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (60, 1, '会员', '1', 'user_type', 0, 'primary', '', NULL, '', '2021-02-26 00:16:27', '1', '2022-02-16 10:22:19', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (61, 2, '管理员', '2', 'user_type', 0, 'success', '', NULL, '', '2021-02-26 00:16:34', '1', '2022-02-16 10:22:22', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (61, 2, '管理员', '2', 'user_type', 0, 'success', '', NULL, '', '2021-02-26 00:16:34', '1', '2025-04-06 18:37:43', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (62, 0, '未处理', '0', 'infra_api_error_log_process_status', 0, 'primary', '', NULL, '', '2021-02-26 07:07:19', '1', '2022-02-16 20:14:17', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (62, 0, '未处理', '0', 'infra_api_error_log_process_status', 0, 'primary', '', NULL, '', '2021-02-26 07:07:19', '1', '2022-02-16 20:14:17', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (63, 1, '已处理', '1', 'infra_api_error_log_process_status', 0, 'success', '', NULL, '', '2021-02-26 07:07:26', '1', '2022-02-16 20:14:08', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (63, 1, '已处理', '1', 'infra_api_error_log_process_status', 0, 'success', '', NULL, '', '2021-02-26 07:07:26', '1', '2022-02-16 20:14:08', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (64, 2, '已忽略', '2', 'infra_api_error_log_process_status', 0, 'danger', '', NULL, '', '2021-02-26 07:07:34', '1', '2022-02-16 20:14:14', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (64, 2, '已忽略', '2', 'infra_api_error_log_process_status', 0, 'danger', '', NULL, '', '2021-02-26 07:07:34', '1', '2022-02-16 20:14:14', b'0');
|
||||||
@ -635,7 +639,7 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
|
|||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1230, 13, '支付宝条码支付', 'alipay_bar', 'pay_channel_code', 0, 'primary', '', '支付宝条码支付', '1', '2023-02-18 23:32:24', '1', '2023-07-19 20:09:23', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1230, 13, '支付宝条码支付', 'alipay_bar', 'pay_channel_code', 0, 'primary', '', '支付宝条码支付', '1', '2023-02-18 23:32:24', '1', '2023-07-19 20:09:23', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1231, 10, 'Vue2 Element UI 标准模版', '10', 'infra_codegen_front_type', 0, '', '', '', '1', '2023-04-13 00:03:55', '1', '2023-04-13 00:03:55', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1231, 10, 'Vue2 Element UI 标准模版', '10', 'infra_codegen_front_type', 0, '', '', '', '1', '2023-04-13 00:03:55', '1', '2023-04-13 00:03:55', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1232, 20, 'Vue3 Element Plus 标准模版', '20', 'infra_codegen_front_type', 0, '', '', '', '1', '2023-04-13 00:04:08', '1', '2023-04-13 00:04:08', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1232, 20, 'Vue3 Element Plus 标准模版', '20', 'infra_codegen_front_type', 0, '', '', '', '1', '2023-04-13 00:04:08', '1', '2023-04-13 00:04:08', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1234, 30, 'Vue3 vben 模版', '30', 'infra_codegen_front_type', 0, '', '', '', '1', '2023-04-13 00:04:26', '1', '2023-04-13 00:04:26', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1234, 30, 'Vben2.0 Ant Design Schema 模版', '30', 'infra_codegen_front_type', 0, '', '', '', '1', '2023-04-13 00:04:26', '1', '2025-04-23 21:27:34', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1244, 0, '按件', '1', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:40', '1', '2023-05-21 22:46:40', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1244, 0, '按件', '1', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:40', '1', '2023-05-21 22:46:40', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1245, 1, '按重量', '2', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:58', '1', '2023-05-21 22:46:58', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1245, 1, '按重量', '2', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:58', '1', '2023-05-21 22:46:58', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1246, 2, '按体积', '3', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:47:18', '1', '2023-05-21 22:47:18', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1246, 2, '按体积', '3', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:47:18', '1', '2023-05-21 22:47:18', b'0');
|
||||||
@ -666,8 +670,8 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
|
|||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1363, 3, '覆盖绑定', '3', 'brokerage_bind_mode', 0, '', '', '如果用户已经有推广人,推广人会被变更', '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1363, 3, '覆盖绑定', '3', 'brokerage_bind_mode', 0, '', '', '如果用户已经有推广人,推广人会被变更', '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1364, 1, '钱包', '1', 'brokerage_withdraw_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1364, 1, '钱包', '1', 'brokerage_withdraw_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1365, 2, '银行卡', '2', 'brokerage_withdraw_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1365, 2, '银行卡', '2', 'brokerage_withdraw_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1366, 3, '微信', '3', 'brokerage_withdraw_type', 0, '', '', '手动打款', '', '2023-09-28 02:46:05', '1', '2024-10-13 11:06:54', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1366, 3, '微信收款码', '3', 'brokerage_withdraw_type', 0, '', '', '手动打款', '', '2023-09-28 02:46:05', '1', '2025-05-10 08:24:25', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1367, 4, '支付宝', '4', 'brokerage_withdraw_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1367, 4, '支付宝收款码', '4', 'brokerage_withdraw_type', 0, '', '', '手动打款', '', '2023-09-28 02:46:05', '1', '2025-05-10 08:24:37', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1368, 1, '订单返佣', '1', 'brokerage_record_biz_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1368, 1, '订单返佣', '1', 'brokerage_record_biz_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1369, 2, '申请提现', '2', 'brokerage_record_biz_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1369, 2, '申请提现', '2', 'brokerage_record_biz_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1370, 3, '申请提现驳回', '3', 'brokerage_record_biz_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1370, 3, '申请提现驳回', '3', 'brokerage_record_biz_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0');
|
||||||
@ -764,13 +768,9 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
|
|||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1475, 2, '发短信', '2', 'crm_follow_up_type', 0, '', '', '', '1', '2024-01-15 20:48:31', '1', '2024-01-15 20:48:31', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1475, 2, '发短信', '2', 'crm_follow_up_type', 0, '', '', '', '1', '2024-01-15 20:48:31', '1', '2024-01-15 20:48:31', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1476, 3, '上门拜访', '3', 'crm_follow_up_type', 0, '', '', '', '1', '2024-01-15 20:49:07', '1', '2024-01-15 20:49:07', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1476, 3, '上门拜访', '3', 'crm_follow_up_type', 0, '', '', '', '1', '2024-01-15 20:49:07', '1', '2024-01-15 20:49:07', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1477, 4, '微信沟通', '4', 'crm_follow_up_type', 0, '', '', '', '1', '2024-01-15 20:49:15', '1', '2024-01-15 20:49:15', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1477, 4, '微信沟通', '4', 'crm_follow_up_type', 0, '', '', '', '1', '2024-01-15 20:49:15', '1', '2024-01-15 20:49:15', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1478, 4, '钱包余额', '4', 'pay_transfer_type', 0, 'info', '', '', '1', '2023-10-28 16:28:37', '1', '2023-10-28 16:28:37', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1482, 4, '转账失败', '20', 'pay_transfer_status', 0, 'warning', '', '', '1', '2023-10-28 16:24:16', '1', '2025-05-08 12:59:01', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1479, 3, '银行卡', '3', 'pay_transfer_type', 0, 'default', '', '', '1', '2023-10-28 16:28:21', '1', '2023-10-28 16:28:21', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1483, 3, '转账成功', '10', 'pay_transfer_status', 0, 'success', '', '', '1', '2023-10-28 16:23:50', '1', '2025-05-08 12:58:58', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1480, 2, '微信余额', '2', 'pay_transfer_type', 0, 'info', '', '', '1', '2023-10-28 16:28:07', '1', '2023-10-28 16:28:07', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1484, 2, '转账进行中', '5', 'pay_transfer_status', 0, 'info', '', '', '1', '2023-10-28 16:23:12', '1', '2025-05-08 12:58:54', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1481, 1, '支付宝余额', '1', 'pay_transfer_type', 0, 'default', '', '', '1', '2023-10-28 16:27:44', '1', '2023-10-28 16:27:44', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1482, 4, '转账失败', '30', 'pay_transfer_status', 0, 'warning', '', '', '1', '2023-10-28 16:24:16', '1', '2023-10-28 16:24:16', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1483, 3, '转账成功', '20', 'pay_transfer_status', 0, 'success', '', '', '1', '2023-10-28 16:23:50', '1', '2023-10-28 16:23:50', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1484, 2, '转账进行中', '10', 'pay_transfer_status', 0, 'info', '', '', '1', '2023-10-28 16:23:12', '1', '2023-10-28 16:23:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1485, 1, '等待转账', '0', 'pay_transfer_status', 0, 'default', '', '', '1', '2023-10-28 16:21:43', '1', '2023-10-28 16:23:22', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1485, 1, '等待转账', '0', 'pay_transfer_status', 0, 'default', '', '', '1', '2023-10-28 16:21:43', '1', '2023-10-28 16:23:22', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1486, 10, '其它入库', '10', 'erp_stock_record_biz_type', 0, '', '', '', '1', '2024-02-05 18:07:25', '1', '2024-02-05 18:07:43', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1486, 10, '其它入库', '10', 'erp_stock_record_biz_type', 0, '', '', '', '1', '2024-02-05 18:07:25', '1', '2024-02-05 18:07:43', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1487, 11, '其它入库(作废)', '11', 'erp_stock_record_biz_type', 0, 'danger', '', '', '1', '2024-02-05 18:08:07', '1', '2024-02-05 19:20:16', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1487, 11, '其它入库(作废)', '11', 'erp_stock_record_biz_type', 0, 'danger', '', '', '1', '2024-02-05 18:08:07', '1', '2024-02-05 19:20:16', b'0');
|
||||||
@ -869,7 +869,7 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
|
|||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1590, 20, 'SIMPLE 设计器', '20', 'bpm_model_type', 0, 'success', '', '', '1', '2024-08-26 15:22:27', '1', '2024-08-26 16:45:58', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1590, 20, 'SIMPLE 设计器', '20', 'bpm_model_type', 0, 'success', '', '', '1', '2024-08-26 15:22:27', '1', '2024-08-26 16:45:58', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1591, 4, '七牛云', 'QINIU', 'system_sms_channel_code', 0, '', '', '', '1', '2024-08-31 08:45:03', '1', '2024-08-31 08:45:24', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1591, 4, '七牛云', 'QINIU', 'system_sms_channel_code', 0, '', '', '', '1', '2024-08-31 08:45:03', '1', '2024-08-31 08:45:24', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1592, 3, '新人券', '3', 'promotion_coupon_take_type', 0, 'info', '', '新人注册后,自动发放', '1', '2024-09-03 11:57:16', '1', '2024-09-03 11:57:28', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1592, 3, '新人券', '3', 'promotion_coupon_take_type', 0, 'info', '', '新人注册后,自动发放', '1', '2024-09-03 11:57:16', '1', '2024-09-03 11:57:28', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1593, 5, '微信零钱', '5', 'brokerage_withdraw_type', 0, '', '', '自动打款', '1', '2024-10-13 11:06:48', '1', '2024-10-13 11:06:59', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1593, 5, '微信零钱', '5', 'brokerage_withdraw_type', 0, '', '', 'API 打款', '1', '2024-10-13 11:06:48', '1', '2025-05-10 08:24:55', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1683, 10, '字节豆包', 'DouBao', 'ai_platform', 0, '', '', '', '1', '2025-02-23 19:51:40', '1', '2025-02-23 19:52:02', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1683, 10, '字节豆包', 'DouBao', 'ai_platform', 0, '', '', '', '1', '2025-02-23 19:51:40', '1', '2025-02-23 19:52:02', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1684, 11, '腾讯混元', 'HunYuan', 'ai_platform', 0, '', '', '', '1', '2025-02-23 20:58:04', '1', '2025-02-23 20:58:04', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1684, 11, '腾讯混元', 'HunYuan', 'ai_platform', 0, '', '', '', '1', '2025-02-23 20:58:04', '1', '2025-02-23 20:58:04', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1685, 12, '硅基流动', 'SiliconFlow', 'ai_platform', 0, '', '', '', '1', '2025-02-24 20:19:09', '1', '2025-02-24 20:19:09', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1685, 12, '硅基流动', 'SiliconFlow', 'ai_platform', 0, '', '', '', '1', '2025-02-24 20:19:09', '1', '2025-02-24 20:19:09', b'0');
|
||||||
@ -1054,6 +1054,9 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
|
|||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2171, 30, 'ROCKETMQ', '30', 'iot_data_bridge_type_enum', 0, 'primary', '', '', '1', '2025-03-09 12:41:30', '1', '2025-03-17 09:40:46', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2171, 30, 'ROCKETMQ', '30', 'iot_data_bridge_type_enum', 0, 'primary', '', '', '1', '2025-03-09 12:41:30', '1', '2025-03-17 09:40:46', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2172, 31, 'RABBITMQ', '31', 'iot_data_bridge_type_enum', 0, 'primary', '', '', '1', '2025-03-09 12:41:47', '1', '2025-03-17 09:40:46', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2172, 31, 'RABBITMQ', '31', 'iot_data_bridge_type_enum', 0, 'primary', '', '', '1', '2025-03-09 12:41:47', '1', '2025-03-17 09:40:46', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2173, 32, 'KAFKA', '32', 'iot_data_bridge_type_enum', 0, 'primary', '', '', '1', '2025-03-09 12:41:59', '1', '2025-03-17 09:40:46', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2173, 32, 'KAFKA', '32', 'iot_data_bridge_type_enum', 0, 'primary', '', '', '1', '2025-03-09 12:41:59', '1', '2025-03-17 09:40:46', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3000, 16, '百川智能', 'BaiChuan', 'ai_platform', 0, '', '', '', '1', '2025-03-23 12:15:46', '1', '2025-03-23 12:15:46', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3001, 50, 'Vben5.0 Ant Design Schema 模版', '40', 'infra_codegen_front_type', 0, '', '', NULL, '1', '2025-04-23 21:47:47', '1', '2025-05-02 12:01:15', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3002, 6, '支付宝余额', '6', 'brokerage_withdraw_type', 0, '', '', 'API 打款', '1', '2025-05-10 08:24:49', '1', '2025-05-10 08:24:49', b'0');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -1154,7 +1157,6 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
|
|||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (606, 'CRM 审批状态', 'crm_audit_status', 0, '', '1', '2023-11-30 18:56:23', '1', '2023-11-30 18:56:23', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (606, 'CRM 审批状态', 'crm_audit_status', 0, '', '1', '2023-11-30 18:56:23', '1', '2023-11-30 18:56:23', b'0', '1970-01-01 00:00:00');
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (607, 'CRM 产品单位', 'crm_product_unit', 0, '', '1', '2023-12-05 23:01:51', '1', '2023-12-05 23:01:51', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (607, 'CRM 产品单位', 'crm_product_unit', 0, '', '1', '2023-12-05 23:01:51', '1', '2023-12-05 23:01:51', b'0', '1970-01-01 00:00:00');
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (608, 'CRM 跟进方式', 'crm_follow_up_type', 0, '', '1', '2024-01-15 20:48:05', '1', '2024-01-15 20:48:05', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (608, 'CRM 跟进方式', 'crm_follow_up_type', 0, '', '1', '2024-01-15 20:48:05', '1', '2024-01-15 20:48:05', b'0', '1970-01-01 00:00:00');
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (609, '支付转账类型', 'pay_transfer_type', 0, '', '1', '2023-10-28 16:27:18', '1', '2023-10-28 16:27:18', b'0', '1970-01-01 00:00:00');
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (610, '转账订单状态', 'pay_transfer_status', 0, '', '1', '2023-10-28 16:18:32', '1', '2023-10-28 16:18:32', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (610, '转账订单状态', 'pay_transfer_status', 0, '', '1', '2023-10-28 16:18:32', '1', '2023-10-28 16:18:32', b'0', '1970-01-01 00:00:00');
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (611, 'ERP 库存明细的业务类型', 'erp_stock_record_biz_type', 0, 'ERP 库存明细的业务类型', '1', '2024-02-05 18:07:02', '1', '2024-02-05 18:07:02', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (611, 'ERP 库存明细的业务类型', 'erp_stock_record_biz_type', 0, 'ERP 库存明细的业务类型', '1', '2024-02-05 18:07:02', '1', '2024-02-05 18:07:02', b'0', '1970-01-01 00:00:00');
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (612, 'ERP 审批状态', 'erp_audit_status', 0, '', '1', '2024-02-06 00:00:07', '1', '2024-02-06 00:00:07', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (612, 'ERP 审批状态', 'erp_audit_status', 0, '', '1', '2024-02-06 00:00:07', '1', '2024-02-06 00:00:07', b'0', '1970-01-01 00:00:00');
|
||||||
@ -1186,7 +1188,7 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
|
|||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1010, 'IoT 插件类型', 'iot_plugin_type', 0, '', '1', '2024-12-13 11:08:19', '1', '2025-03-17 09:25:32', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1010, 'IoT 插件类型', 'iot_plugin_type', 0, '', '1', '2024-12-13 11:08:19', '1', '2025-03-17 09:25:32', b'0', '1970-01-01 00:00:00');
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1011, 'IoT 物模型单位', 'iot_thing_model_unit', 0, '', '1', '2024-12-25 17:36:46', '1', '2025-03-17 09:25:35', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1011, 'IoT 物模型单位', 'iot_thing_model_unit', 0, '', '1', '2024-12-25 17:36:46', '1', '2025-03-17 09:25:35', b'0', '1970-01-01 00:00:00');
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1012, 'IoT 数据桥接的方向枚举', 'iot_data_bridge_direction_enum', 0, '', '1', '2025-03-09 12:37:40', '1', '2025-03-17 09:25:39', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1012, 'IoT 数据桥接的方向枚举', 'iot_data_bridge_direction_enum', 0, '', '1', '2025-03-09 12:37:40', '1', '2025-03-17 09:25:39', b'0', '1970-01-01 00:00:00');
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1013, 'IoT 数据桥梁的类型枚举', 'iot_data_bridge_type_enum', 0, '', '1', '2025-03-09 12:39:36', '1', '2025-03-17 09:25:43', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1013, 'IoT 数据桥梁的类型枚举', 'iot_data_bridge_type_enum', 0, '', '1', '2025-03-09 12:39:36', '1', '2025-04-06 17:09:46', b'0', '1970-01-01 00:00:00');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -1210,7 +1212,7 @@ CREATE TABLE `system_login_log` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 3446 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
|
) ENGINE = InnoDB AUTO_INCREMENT = 3822 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_login_log
|
-- Records of system_login_log
|
||||||
@ -1243,7 +1245,7 @@ CREATE TABLE `system_mail_account` (
|
|||||||
-- Records of system_mail_account
|
-- Records of system_mail_account
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `starttls_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '7684413@qq.com', '7684413@qq.com', '1234576', '127.0.0.1', 8080, b'0', b'0', '1', '2023-01-25 17:39:52', '1', '2024-07-27 22:39:12', b'0');
|
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `starttls_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '7684413@qq.com', '7684413@qq.com', '1234576', '127.0.0.1', 8080, b'0', b'0', '1', '2023-01-25 17:39:52', '1', '2025-04-04 16:34:40', b'0');
|
||||||
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `starttls_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2, 'ydym_test@163.com', 'ydym_test@163.com', 'WBZTEINMIFVRYSOE', 'smtp.163.com', 465, b'1', b'0', '1', '2023-01-26 01:26:03', '1', '2023-04-12 22:39:38', b'0');
|
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `starttls_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2, 'ydym_test@163.com', 'ydym_test@163.com', 'WBZTEINMIFVRYSOE', 'smtp.163.com', 465, b'1', b'0', '1', '2023-01-26 01:26:03', '1', '2023-04-12 22:39:38', b'0');
|
||||||
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `starttls_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3, '76854114@qq.com', '3335', '11234', 'yunai1.cn', 466, b'0', b'0', '1', '2023-01-27 15:06:38', '1', '2023-01-27 07:08:36', b'1');
|
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `starttls_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3, '76854114@qq.com', '3335', '11234', 'yunai1.cn', 466, b'0', b'0', '1', '2023-01-27 15:06:38', '1', '2023-01-27 07:08:36', b'1');
|
||||||
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `starttls_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '7685413x@qq.com', '2', '3', '4', 5, b'1', b'0', '1', '2023-04-12 23:05:06', '1', '2023-04-12 15:05:11', b'1');
|
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `starttls_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '7685413x@qq.com', '2', '3', '4', 5, b'1', b'0', '1', '2023-04-12 23:05:06', '1', '2023-04-12 15:05:11', b'1');
|
||||||
@ -1276,7 +1278,7 @@ CREATE TABLE `system_mail_log` (
|
|||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 359 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '邮件日志表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 360 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '邮件日志表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_mail_log
|
-- Records of system_mail_log
|
||||||
@ -1341,7 +1343,7 @@ CREATE TABLE `system_menu` (
|
|||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 5000 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 5013 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_menu
|
-- Records of system_menu
|
||||||
@ -1484,15 +1486,9 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1150, '秘钥解析', '', 3, 6, 1129, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2021-11-08 15:15:47', '1', '2022-04-20 17:03:10', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1150, '秘钥解析', '', 3, 6, 1129, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2021-11-08 15:15:47', '1', '2022-04-20 17:03:10', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1161, '退款订单', '', 2, 3, 1117, 'refund', 'fa:registered', 'pay/refund/index', 'PayRefund', 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '1', '2024-02-29 08:59:20', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1161, '退款订单', '', 2, 3, 1117, 'refund', 'fa:registered', 'pay/refund/index', 'PayRefund', 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '1', '2024-02-29 08:59:20', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1162, '退款订单查询', 'pay:refund:query', 3, 1, 1161, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '', '2022-04-20 17:03:10', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1162, '退款订单查询', 'pay:refund:query', 3, 1, 1161, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '', '2022-04-20 17:03:10', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1163, '退款订单创建', 'pay:refund:create', 3, 2, 1161, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '', '2022-04-20 17:03:10', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1164, '退款订单更新', 'pay:refund:update', 3, 3, 1161, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '', '2022-04-20 17:03:10', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1165, '退款订单删除', 'pay:refund:delete', 3, 4, 1161, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '', '2022-04-20 17:03:10', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1166, '退款订单导出', 'pay:refund:export', 3, 5, 1161, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '', '2022-04-20 17:03:10', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1166, '退款订单导出', 'pay:refund:export', 3, 5, 1161, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '', '2022-04-20 17:03:10', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1173, '支付订单', '', 2, 2, 1117, 'order', 'fa:cc-paypal', 'pay/order/index', 'PayOrder', 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '1', '2024-02-29 08:59:43', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1173, '支付订单', '', 2, 2, 1117, 'order', 'fa:cc-paypal', 'pay/order/index', 'PayOrder', 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '1', '2024-02-29 08:59:43', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1174, '支付订单查询', 'pay:order:query', 3, 1, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1174, '支付订单查询', 'pay:order:query', 3, 1, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1175, '支付订单创建', 'pay:order:create', 3, 2, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1176, '支付订单更新', 'pay:order:update', 3, 3, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1177, '支付订单删除', 'pay:order:delete', 3, 4, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1178, '支付订单导出', 'pay:order:export', 3, 5, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1178, '支付订单导出', 'pay:order:export', 3, 5, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1185, '工作流程', '', 1, 50, 0, '/bpm', 'fa:medium', NULL, NULL, 0, b'1', b'1', b'1', '1', '2021-12-30 20:26:36', '1', '2024-02-29 12:43:43', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1185, '工作流程', '', 1, 50, 0, '/bpm', 'fa:medium', NULL, NULL, 0, b'1', b'1', b'1', '1', '2021-12-30 20:26:36', '1', '2024-02-29 12:43:43', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1186, '流程管理', '', 1, 10, 1185, 'manager', 'fa:dedent', NULL, NULL, 0, b'1', b'1', b'1', '1', '2021-12-30 20:28:30', '1', '2024-02-29 12:36:02', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1186, '流程管理', '', 1, 10, 1185, 'manager', 'fa:dedent', NULL, NULL, 0, b'1', b'1', b'1', '1', '2021-12-30 20:28:30', '1', '2024-02-29 12:36:02', b'0');
|
||||||
@ -1539,7 +1535,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1241, '文件配置删除', 'infra:file-config:delete', 3, 4, 1237, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-03-15 14:35:28', '', '2022-04-20 17:03:10', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1241, '文件配置删除', 'infra:file-config:delete', 3, 4, 1237, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-03-15 14:35:28', '', '2022-04-20 17:03:10', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1242, '文件配置导出', 'infra:file-config:export', 3, 5, 1237, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-03-15 14:35:28', '', '2022-04-20 17:03:10', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1242, '文件配置导出', 'infra:file-config:export', 3, 5, 1237, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-03-15 14:35:28', '', '2022-04-20 17:03:10', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1243, '文件管理', '', 2, 6, 2, 'file', 'ep:files', NULL, '', 0, b'1', b'1', b'1', '1', '2022-03-16 23:47:40', '1', '2024-04-23 00:02:11', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1243, '文件管理', '', 2, 6, 2, 'file', 'ep:files', NULL, '', 0, b'1', b'1', b'1', '1', '2022-03-16 23:47:40', '1', '2024-04-23 00:02:11', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1254, '作者动态', '', 1, 0, 0, 'https://www.iocoder.cn', 'ep:avatar', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-04-23 01:03:15', '104', '2025-01-04 10:59:37', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1254, '作者动态', '', 1, 0, 0, 'https://www.iocoder.cn', 'ep:avatar', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-04-23 01:03:15', '1', '2025-04-29 17:45:38', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1255, '数据源配置', '', 2, 1, 2, 'data-source-config', 'ep:data-analysis', 'infra/dataSourceConfig/index', 'InfraDataSourceConfig', 0, b'1', b'1', b'1', '', '2022-04-27 14:37:32', '1', '2024-02-29 08:51:25', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1255, '数据源配置', '', 2, 1, 2, 'data-source-config', 'ep:data-analysis', 'infra/dataSourceConfig/index', 'InfraDataSourceConfig', 0, b'1', b'1', b'1', '', '2022-04-27 14:37:32', '1', '2024-02-29 08:51:25', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1256, '数据源配置查询', 'infra:data-source-config:query', 3, 1, 1255, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-04-27 14:37:32', '', '2022-04-27 14:37:32', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1256, '数据源配置查询', 'infra:data-source-config:query', 3, 1, 1255, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-04-27 14:37:32', '', '2022-04-27 14:37:32', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1257, '数据源配置创建', 'infra:data-source-config:create', 3, 2, 1255, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-04-27 14:37:32', '', '2022-04-27 14:37:32', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1257, '数据源配置创建', 'infra:data-source-config:create', 3, 2, 1255, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-04-27 14:37:32', '', '2022-04-27 14:37:32', b'0');
|
||||||
@ -1553,7 +1549,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1266, '客户端更新', 'system:oauth2-client:update', 3, 3, 1263, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:28', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1266, '客户端更新', 'system:oauth2-client:update', 3, 3, 1263, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:28', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1267, '客户端删除', 'system:oauth2-client:delete', 3, 4, 1263, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:33', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1267, '客户端删除', 'system:oauth2-client:delete', 3, 4, 1263, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:33', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1281, '报表管理', '', 2, 40, 0, '/report', 'ep:pie-chart', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-07-10 20:22:15', '1', '2024-02-29 12:33:03', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1281, '报表管理', '', 2, 40, 0, '/report', 'ep:pie-chart', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-07-10 20:22:15', '1', '2024-02-29 12:33:03', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1282, '报表设计器', '', 2, 1, 1281, 'jimu-report', 'ep:trend-charts', 'report/jmreport/index', 'GoView', 0, b'1', b'1', b'1', '1', '2022-07-10 20:26:36', '1', '2024-02-29 12:33:54', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1282, '报表设计器', '', 2, 1, 1281, 'jimu-report', 'ep:trend-charts', 'report/jmreport/index', 'JimuReport', 0, b'1', b'1', b'1', '1', '2022-07-10 20:26:36', '1', '2025-05-03 09:57:07', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2000, '商品中心', '', 1, 60, 2362, 'product', 'fa:product-hunt', NULL, NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '1', '2023-09-30 11:52:36', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2000, '商品中心', '', 1, 60, 2362, 'product', 'fa:product-hunt', NULL, NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '1', '2023-09-30 11:52:36', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2002, '商品分类', '', 2, 2, 2000, 'category', 'ep:cellphone', 'mall/product/category/index', 'ProductCategory', 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '1', '2023-08-21 10:27:15', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2002, '商品分类', '', 2, 2, 2000, 'category', 'ep:cellphone', 'mall/product/category/index', 'ProductCategory', 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '1', '2023-08-21 10:27:15', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2003, '分类查询', 'product:category:query', 3, 1, 2002, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2003, '分类查询', 'product:category:query', 3, 1, 2002, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0');
|
||||||
@ -1652,7 +1648,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2116, '删除素材', 'mp:material:delete', 3, 3, 2113, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-14 15:35:37', '1', '2023-01-14 15:35:37', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2116, '删除素材', 'mp:material:delete', 3, 3, 2113, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-14 15:35:37', '1', '2023-01-14 15:35:37', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2117, '上传图文图片', 'mp:material:upload-news-image', 3, 4, 2113, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-14 15:36:31', '1', '2023-01-14 15:36:31', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2117, '上传图文图片', 'mp:material:upload-news-image', 3, 4, 2113, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-14 15:36:31', '1', '2023-01-14 15:36:31', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2118, '查询素材', 'mp:material:query', 3, 5, 2113, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-14 15:39:22', '1', '2023-01-14 15:39:22', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2118, '查询素材', 'mp:material:query', 3, 5, 2113, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-14 15:39:22', '1', '2023-01-14 15:39:22', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2119, '菜单管理', '', 2, 6, 2084, 'menu', 'ep:menu', 'mp/menu/index', 'MpMenu', 0, b'1', b'1', b'1', '1', '2023-01-14 17:43:54', '1', '2024-02-29 12:42:56', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2119, '菜单管理', '', 2, 6, 2084, 'menu', 'ep:menu', 'mp/menu/index', 'MpMenu', 0, b'1', b'1', b'1', '1', '2023-01-14 17:43:54', '1', '2025-04-01 20:21:02', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2120, '自动回复', '', 2, 7, 2084, 'auto-reply', 'fa-solid:republican', 'mp/autoReply/index', 'MpAutoReply', 0, b'1', b'1', b'1', '1', '2023-01-15 22:13:09', '1', '2024-02-29 12:43:10', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2120, '自动回复', '', 2, 7, 2084, 'auto-reply', 'fa-solid:republican', 'mp/autoReply/index', 'MpAutoReply', 0, b'1', b'1', b'1', '1', '2023-01-15 22:13:09', '1', '2024-02-29 12:43:10', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2121, '查询回复', 'mp:auto-reply:query', 3, 0, 2120, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-16 22:28:41', '1', '2023-01-16 22:28:41', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2121, '查询回复', 'mp:auto-reply:query', 3, 0, 2120, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-16 22:28:41', '1', '2023-01-16 22:28:41', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2122, '新增回复', 'mp:auto-reply:create', 3, 1, 2120, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-16 22:28:54', '1', '2023-01-16 22:28:54', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2122, '新增回复', 'mp:auto-reply:create', 3, 1, 2120, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-16 22:28:54', '1', '2023-01-16 22:28:54', b'0');
|
||||||
@ -1686,7 +1682,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2150, '发送测试站内信', 'system:notify-template:send-notify', 3, 5, 2145, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-28 10:54:43', '1', '2023-01-28 10:54:43', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2150, '发送测试站内信', 'system:notify-template:send-notify', 3, 5, 2145, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-28 10:54:43', '1', '2023-01-28 10:54:43', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2151, '消息记录', '', 2, 0, 2144, 'notify-message', 'fa:edit', 'system/notify/message/index', 'SystemNotifyMessage', 0, b'1', b'1', b'1', '', '2023-01-28 04:28:22', '1', '2024-02-29 08:49:22', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2151, '消息记录', '', 2, 0, 2144, 'notify-message', 'fa:edit', 'system/notify/message/index', 'SystemNotifyMessage', 0, b'1', b'1', b'1', '', '2023-01-28 04:28:22', '1', '2024-02-29 08:49:22', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2152, '站内信消息查询', 'system:notify-message:query', 3, 1, 2151, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-01-28 04:28:22', '', '2023-01-28 04:28:22', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2152, '站内信消息查询', 'system:notify-message:query', 3, 1, 2151, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-01-28 04:28:22', '', '2023-01-28 04:28:22', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2153, '大屏设计器', '', 2, 2, 1281, 'go-view', 'fa:area-chart', 'report/goview/index', 'JimuReport', 0, b'1', b'1', b'1', '1', '2023-02-07 00:03:19', '1', '2024-02-29 12:34:02', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2153, '大屏设计器', '', 2, 2, 1281, 'go-view', 'fa:area-chart', 'report/goview/index', 'GoView', 0, b'1', b'1', b'1', '1', '2023-02-07 00:03:19', '1', '2025-05-03 09:57:03', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2154, '创建项目', 'report:go-view-project:create', 3, 1, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:14', '1', '2023-02-07 19:25:14', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2154, '创建项目', 'report:go-view-project:create', 3, 1, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:14', '1', '2023-02-07 19:25:14', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2155, '更新项目', 'report:go-view-project:update', 3, 2, 2153, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:34', '1', '2024-04-24 20:01:18', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2155, '更新项目', 'report:go-view-project:update', 3, 2, 2153, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:34', '1', '2024-04-24 20:01:18', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2156, '查询项目', 'report:go-view-project:query', 3, 0, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:53', '1', '2023-02-07 19:25:53', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2156, '查询项目', 'report:go-view-project:query', 3, 0, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:53', '1', '2023-02-07 19:25:53', b'0');
|
||||||
@ -1825,7 +1821,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2394, '客户更新', 'crm:customer:update', 3, 3, 2391, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 09:04:21', '', '2023-10-29 09:04:21', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2394, '客户更新', 'crm:customer:update', 3, 3, 2391, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 09:04:21', '', '2023-10-29 09:04:21', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2395, '客户删除', 'crm:customer:delete', 3, 4, 2391, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 09:04:21', '', '2023-10-29 09:04:21', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2395, '客户删除', 'crm:customer:delete', 3, 4, 2391, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 09:04:21', '', '2023-10-29 09:04:21', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2396, '客户导出', 'crm:customer:export', 3, 5, 2391, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 09:04:21', '', '2023-10-29 09:04:21', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2396, '客户导出', 'crm:customer:export', 3, 5, 2391, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 09:04:21', '', '2023-10-29 09:04:21', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2397, 'CRM 系统', '', 1, 200, 0, '/crm', 'ep:avatar', '', '', 0, b'1', b'1', b'1', '1', '2023-10-29 17:08:30', '1', '2024-02-04 15:37:31', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2397, 'CRM 系统', '', 1, 200, 0, '/crm', 'simple-icons:civicrm', '', '', 0, b'1', b'1', b'1', '1', '2023-10-29 17:08:30', '1', '2025-04-19 18:56:38', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2398, '合同管理', '', 2, 50, 2397, 'contract', 'ep:notebook', 'crm/contract/index', 'CrmContract', 0, b'1', b'1', b'1', '', '2023-10-29 10:50:41', '1', '2024-02-17 17:15:09', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2398, '合同管理', '', 2, 50, 2397, 'contract', 'ep:notebook', 'crm/contract/index', 'CrmContract', 0, b'1', b'1', b'1', '', '2023-10-29 10:50:41', '1', '2024-02-17 17:15:09', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2399, '合同查询', 'crm:contract:query', 3, 1, 2398, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 10:50:41', '', '2023-10-29 10:50:41', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2399, '合同查询', 'crm:contract:query', 3, 1, 2398, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 10:50:41', '', '2023-10-29 10:50:41', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2400, '合同创建', 'crm:contract:create', 3, 2, 2398, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 10:50:41', '', '2023-10-29 10:50:41', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2400, '合同创建', 'crm:contract:create', 3, 2, 2398, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 10:50:41', '', '2023-10-29 10:50:41', b'0');
|
||||||
@ -1929,7 +1925,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2547, '订单查询', 'trade:order:query', 3, 1, 2076, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-01-16 08:52:00', '1', '2024-01-16 08:52:00', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2547, '订单查询', 'trade:order:query', 3, 1, 2076, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-01-16 08:52:00', '1', '2024-01-16 08:52:00', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2548, '订单更新', 'trade:order:update', 3, 2, 2076, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-01-16 08:52:21', '1', '2024-01-16 08:52:21', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2548, '订单更新', 'trade:order:update', 3, 2, 2076, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-01-16 08:52:21', '1', '2024-01-16 08:52:21', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2549, '支付&退款案例', '', 2, 1, 2161, 'order', 'fa:paypal', 'pay/demo/order/index', '', 0, b'1', b'1', b'1', '1', '2024-01-18 23:45:00', '1', '2024-01-18 23:47:21', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2549, '支付&退款案例', '', 2, 1, 2161, 'order', 'fa:paypal', 'pay/demo/order/index', '', 0, b'1', b'1', b'1', '1', '2024-01-18 23:45:00', '1', '2024-01-18 23:47:21', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2550, '转账案例', '', 2, 2, 2161, 'transfer', 'fa:transgender-alt', 'pay/demo/transfer/index', '', 0, b'1', b'1', b'1', '1', '2024-01-18 23:51:16', '1', '2024-01-18 23:51:16', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2550, '提现转账案例', '', 2, 2, 2161, 'transfer', 'fa:transgender-alt', 'pay/demo/withdraw/index', '', 0, b'1', b'1', b'1', '1', '2024-01-18 23:51:16', '1', '2025-05-08 13:04:36', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2551, '钱包管理', '', 1, 4, 1117, 'wallet', 'ep:wallet', '', '', 0, b'1', b'1', b'1', '', '2023-12-29 02:32:54', '1', '2024-02-29 08:58:54', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2551, '钱包管理', '', 1, 4, 1117, 'wallet', 'ep:wallet', '', '', 0, b'1', b'1', b'1', '', '2023-12-29 02:32:54', '1', '2024-02-29 08:58:54', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2552, '充值套餐', '', 2, 2, 2551, 'wallet-recharge-package', 'fa:leaf', 'pay/wallet/rechargePackage/index', 'WalletRechargePackage', 0, b'1', b'1', b'1', '', '2023-12-29 02:32:54', '', '2023-12-29 02:32:54', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2552, '充值套餐', '', 2, 2, 2551, 'wallet-recharge-package', 'fa:leaf', 'pay/wallet/rechargePackage/index', 'WalletRechargePackage', 0, b'1', b'1', b'1', '', '2023-12-29 02:32:54', '', '2023-12-29 02:32:54', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2553, '钱包充值套餐查询', 'pay:wallet-recharge-package:query', 3, 1, 2552, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-12-29 02:32:54', '', '2023-12-29 02:32:54', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2553, '钱包充值套餐查询', 'pay:wallet-recharge-package:query', 3, 1, 2552, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-12-29 02:32:54', '', '2023-12-29 02:32:54', b'0');
|
||||||
@ -1942,7 +1938,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2560, '数据统计', '', 1, 200, 2397, 'statistics', 'ep:data-line', '', '', 0, b'1', b'1', b'1', '1', '2024-01-26 22:50:35', '1', '2024-02-24 20:10:07', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2560, '数据统计', '', 1, 200, 2397, 'statistics', 'ep:data-line', '', '', 0, b'1', b'1', b'1', '1', '2024-01-26 22:50:35', '1', '2024-02-24 20:10:07', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2561, '排行榜', 'crm:statistics-rank:query', 2, 1, 2560, 'ranking', 'fa:area-chart', 'crm/statistics/rank/index', 'CrmStatisticsRank', 0, b'1', b'1', b'1', '1', '2024-01-26 22:52:09', '1', '2024-04-24 19:39:11', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2561, '排行榜', 'crm:statistics-rank:query', 2, 1, 2560, 'ranking', 'fa:area-chart', 'crm/statistics/rank/index', 'CrmStatisticsRank', 0, b'1', b'1', b'1', '1', '2024-01-26 22:52:09', '1', '2024-04-24 19:39:11', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2562, '客户导入', 'crm:customer:import', 3, 6, 2391, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-02-01 13:09:00', '1', '2024-02-01 13:09:05', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2562, '客户导入', 'crm:customer:import', 3, 6, 2391, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-02-01 13:09:00', '1', '2024-02-01 13:09:05', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2563, 'ERP 系统', '', 1, 300, 0, '/erp', 'fa-solid:store', '', '', 0, b'1', b'1', b'1', '1', '2024-02-04 15:37:25', '1', '2024-02-04 15:37:25', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2563, 'ERP 系统', '', 1, 300, 0, '/erp', 'simple-icons:erpnext', '', '', 0, b'1', b'1', b'1', '1', '2024-02-04 15:37:25', '1', '2025-04-19 18:56:15', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2564, '产品管理', '', 1, 40, 2563, 'product', 'fa:product-hunt', '', '', 0, b'1', b'1', b'1', '1', '2024-02-04 15:38:43', '1', '2024-02-04 15:38:43', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2564, '产品管理', '', 1, 40, 2563, 'product', 'fa:product-hunt', '', '', 0, b'1', b'1', b'1', '1', '2024-02-04 15:38:43', '1', '2024-02-04 15:38:43', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2565, '产品信息', '', 2, 0, 2564, 'product', 'fa-solid:apple-alt', 'erp/product/product/index', 'ErpProduct', 0, b'1', b'1', b'1', '', '2024-02-04 07:52:15', '1', '2024-02-05 14:42:11', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2565, '产品信息', '', 2, 0, 2564, 'product', 'fa-solid:apple-alt', 'erp/product/product/index', 'ErpProduct', 0, b'1', b'1', b'1', '', '2024-02-04 07:52:15', '1', '2024-02-05 14:42:11', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2566, '产品查询', 'erp:product:query', 3, 1, 2565, '', '', '', '', 0, b'1', b'1', b'1', '', '2024-02-04 07:52:15', '1', '2024-02-04 17:21:57', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2566, '产品查询', 'erp:product:query', 3, 1, 2565, '', '', '', '', 0, b'1', b'1', b'1', '', '2024-02-04 07:52:15', '1', '2024-02-04 17:21:57', b'0');
|
||||||
@ -2136,7 +2132,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2755, '删除项目', 'report:go-view-project:delete', 3, 2, 2153, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 20:01:37', '1', '2024-04-24 20:01:37', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2755, '删除项目', 'report:go-view-project:delete', 3, 2, 2153, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 20:01:37', '1', '2024-04-24 20:01:37', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2756, '会员等级记录查询', 'member:level-record:query', 3, 10, 2325, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 20:02:32', '1', '2024-04-24 20:02:32', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2756, '会员等级记录查询', 'member:level-record:query', 3, 10, 2325, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 20:02:32', '1', '2024-04-24 20:02:32', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2757, '会员经验记录查询', 'member:experience-record:query', 3, 11, 2325, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 20:02:51', '1', '2024-04-24 20:02:51', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2757, '会员经验记录查询', 'member:experience-record:query', 3, 11, 2325, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 20:02:51', '1', '2024-04-24 20:02:51', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2758, 'AI 大模型', '', 1, 400, 0, '/ai', 'fa:apple', '', '', 0, b'1', b'1', b'1', '1', '2024-05-07 15:07:56', '1', '2024-05-25 12:36:12', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2758, 'AI 大模型', '', 1, 400, 0, '/ai', 'tabler:ai', '', '', 0, b'1', b'1', b'1', '1', '2024-05-07 15:07:56', '1', '2025-04-19 18:57:05', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2759, 'AI 对话', '', 2, 1, 2758, 'chat', 'ep:message', 'ai/chat/index/index.vue', 'AiChat', 0, b'1', b'1', b'1', '1', '2024-05-07 15:09:14', '1', '2024-07-07 17:15:36', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2759, 'AI 对话', '', 2, 1, 2758, 'chat', 'ep:message', 'ai/chat/index/index.vue', 'AiChat', 0, b'1', b'1', b'1', '1', '2024-05-07 15:09:14', '1', '2024-07-07 17:15:36', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2760, '控制台', '', 1, 100, 2758, 'console', 'ep:setting', '', '', 0, b'1', b'1', b'1', '1', '2024-05-09 22:39:09', '1', '2024-05-24 23:34:21', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2760, '控制台', '', 1, 100, 2758, 'console', 'ep:setting', '', '', 0, b'1', b'1', b'1', '1', '2024-05-09 22:39:09', '1', '2024-05-24 23:34:21', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2761, 'API 密钥', '', 2, 0, 2760, 'api-key', 'ep:key', 'ai/model/apiKey/index.vue', 'AiApiKey', 0, b'1', b'1', b'1', '', '2024-05-09 14:52:56', '1', '2024-05-10 22:44:08', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2761, 'API 密钥', '', 2, 0, 2760, 'api-key', 'ep:key', 'ai/model/apiKey/index.vue', 'AiApiKey', 0, b'1', b'1', b'1', '', '2024-05-09 14:52:56', '1', '2024-05-10 22:44:08', b'0');
|
||||||
@ -2254,6 +2250,16 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4054, 'IoT 数据桥梁更新', 'iot:data-bridge:update', 3, 3, 4051, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2025-03-09 13:47:11', '', '2025-03-09 13:47:11', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4054, 'IoT 数据桥梁更新', 'iot:data-bridge:update', 3, 3, 4051, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2025-03-09 13:47:11', '', '2025-03-09 13:47:11', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4055, 'IoT 数据桥梁删除', 'iot:data-bridge:delete', 3, 4, 4051, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2025-03-09 13:47:12', '', '2025-03-09 13:47:12', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4055, 'IoT 数据桥梁删除', 'iot:data-bridge:delete', 3, 4, 4051, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2025-03-09 13:47:12', '', '2025-03-09 13:47:12', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4056, 'IoT 数据桥梁导出', 'iot:data-bridge:export', 3, 5, 4051, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2025-03-09 13:47:12', '', '2025-03-09 13:47:12', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4056, 'IoT 数据桥梁导出', 'iot:data-bridge:export', 3, 5, 4051, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2025-03-09 13:47:12', '', '2025-03-09 13:47:12', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5000, 'AI 工作流', '', 2, 5, 2758, 'workflow', 'fa:hand-grab-o', 'ai/workflow/index.vue', 'AiWorkflow', 0, b'1', b'1', b'1', '1', '2025-03-25 09:50:27', '1', '2025-05-03 18:55:12', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5001, 'AI 工作流查询', 'ai:workflow:query', 3, 1, 5000, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-03-25 09:51:11', '1', '2025-03-25 09:51:11', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5002, 'AI 工作流创建', 'ai:workflow:create', 3, 2, 5000, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-03-25 09:51:28', '1', '2025-03-25 09:51:28', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5003, 'AI 工作流更新', 'ai:workflow:update', 3, 3, 5000, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-03-25 09:51:42', '1', '2025-03-25 09:51:42', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5004, 'AI 工作流删除', 'ai:workflow:delete', 3, 4, 5000, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-03-25 09:51:55', '1', '2025-03-25 09:52:03', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5005, 'AI 工作流测试', 'ai:workflow:test', 3, 5, 5000, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-03-30 10:29:41', '1', '2025-03-30 10:29:41', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5009, '仪表盘设计器', '', 2, 1, 1281, 'jimu-bi', 'fa:y-combinator', 'report/jmreport/bi', 'JimuBI', 0, b'1', b'1', b'1', '1', '2025-05-03 09:57:15', '1', '2025-05-03 10:02:05', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5010, '租户切换', 'system:tenant:visit', 3, 999, 1138, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-05-05 15:25:32', '1', '2025-05-05 15:25:32', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5011, '转账订单查询', 'pay:transfer:query', 3, 1, 2559, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-05-08 12:46:53', '1', '2025-05-08 12:46:53', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5012, '转账订单导出', 'pay:transfer:export', 3, 2, 2559, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-05-10 17:00:28', '1', '2025-05-10 17:00:28', b'0');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -2280,7 +2286,7 @@ CREATE TABLE `system_notice` (
|
|||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '芋道的公众', '<p>新版本内容133</p>', 1, 0, 'admin', '2021-01-05 17:03:48', '1', '2022-05-04 21:00:20', b'0', 1);
|
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '芋道的公众', '<p>新版本内容133</p>', 1, 0, 'admin', '2021-01-05 17:03:48', '1', '2022-05-04 21:00:20', b'0', 1);
|
||||||
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '维护通知:2018-07-01 系统凌晨维护', '<p><img src=\"http://test.yudao.iocoder.cn/b7cb3cf49b4b3258bf7309a09dd2f4e5.jpg\" alt=\"\" data-href=\"\" style=\"\"/>11112222<img src=\"http://test.yudao.iocoder.cn/fe44fc7bdb82ca421184b2eebbaee9e2148d4a1827479a4eb4521e11d2a062ba.png\" alt=\"image\" data-href=\"http://test.yudao.iocoder.cn/fe44fc7bdb82ca421184b2eebbaee9e2148d4a1827479a4eb4521e11d2a062ba.png\" style=\"\"/></p>', 2, 1, 'admin', '2021-01-05 17:03:48', '1', '2024-09-24 20:48:09', b'0', 1);
|
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '维护通知:2018-07-01 系统凌晨维护', '<p><img src=\"http://test.yudao.iocoder.cn/b7cb3cf49b4b3258bf7309a09dd2f4e5.jpg\" alt=\"\" data-href=\"\">11112222<img src=\"http://test.yudao.iocoder.cn/fe44fc7bdb82ca421184b2eebbaee9e2148d4a1827479a4eb4521e11d2a062ba.png\" alt=\"image\" data-href=\"http://test.yudao.iocoder.cn/fe44fc7bdb82ca421184b2eebbaee9e2148d4a1827479a4eb4521e11d2a062ba.png\">3333</p>', 2, 1, 'admin', '2021-01-05 17:03:48', '1', '2025-04-18 23:56:40', b'0', 1);
|
||||||
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, '我是测试标题', '<p>哈哈哈哈123</p>', 1, 0, '110', '2022-02-22 01:01:25', '110', '2022-02-22 01:01:46', b'0', 121);
|
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, '我是测试标题', '<p>哈哈哈哈123</p>', 1, 0, '110', '2022-02-22 01:01:25', '110', '2022-02-22 01:01:46', b'0', 121);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
@ -2313,13 +2319,13 @@ CREATE TABLE `system_notify_message` (
|
|||||||
-- Records of system_notify_message
|
-- Records of system_notify_message
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, 1, 2, 1, 'test', '123', '我是 1,我开始 2 了', 1, '{\"name\":\"1\",\"what\":\"2\"}', b'1', '2023-02-10 00:47:04', '1', '2023-01-28 11:44:08', '1', '2023-02-10 00:47:04', b'0', 1);
|
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, 1, 2, 1, 'test', '123', '我是 1,我开始 2 了', 1, '{\"name\":\"1\",\"what\":\"2\"}', b'1', '2025-04-21 14:59:37', '1', '2023-01-28 11:44:08', '1', '2025-04-21 14:59:37', b'0', 1);
|
||||||
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, 1, 2, 1, 'test', '123', '我是 1,我开始 2 了', 1, '{\"name\":\"1\",\"what\":\"2\"}', b'1', '2023-02-10 00:47:04', '1', '2023-01-28 11:45:04', '1', '2023-02-10 00:47:04', b'0', 1);
|
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, 1, 2, 1, 'test', '123', '我是 1,我开始 2 了', 1, '{\"name\":\"1\",\"what\":\"2\"}', b'1', '2025-04-21 14:59:37', '1', '2023-01-28 11:45:04', '1', '2025-04-21 14:59:37', b'0', 1);
|
||||||
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, 103, 2, 2, 'register', '系统消息', '你好,欢迎 哈哈 加入大家庭!', 2, '{\"name\":\"哈哈\"}', b'0', NULL, '1', '2023-01-28 21:02:20', '1', '2023-01-28 21:02:20', b'0', 1);
|
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, 103, 2, 2, 'register', '系统消息', '你好,欢迎 哈哈 加入大家庭!', 2, '{\"name\":\"哈哈\"}', b'0', NULL, '1', '2023-01-28 21:02:20', '1', '2023-01-28 21:02:20', b'0', 1);
|
||||||
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, 1, 2, 1, 'test', '123', '我是 芋艿,我开始 写代码 了', 1, '{\"name\":\"芋艿\",\"what\":\"写代码\"}', b'1', '2023-02-10 00:47:04', '1', '2023-01-28 22:21:42', '1', '2023-02-10 00:47:04', b'0', 1);
|
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, 1, 2, 1, 'test', '123', '我是 芋艿,我开始 写代码 了', 1, '{\"name\":\"芋艿\",\"what\":\"写代码\"}', b'1', '2025-04-21 14:59:37', '1', '2023-01-28 22:21:42', '1', '2025-04-21 14:59:37', b'0', 1);
|
||||||
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6, 1, 2, 1, 'test', '123', '我是 芋艿,我开始 写代码 了', 1, '{\"name\":\"芋艿\",\"what\":\"写代码\"}', b'1', '2023-01-29 10:52:06', '1', '2023-01-28 22:22:07', '1', '2023-01-29 10:52:06', b'0', 1);
|
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6, 1, 2, 1, 'test', '123', '我是 芋艿,我开始 写代码 了', 1, '{\"name\":\"芋艿\",\"what\":\"写代码\"}', b'1', '2025-04-21 14:59:36', '1', '2023-01-28 22:22:07', '1', '2025-04-21 14:59:36', b'0', 1);
|
||||||
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 1, 2, 1, 'test', '123', '我是 2,我开始 3 了', 1, '{\"name\":\"2\",\"what\":\"3\"}', b'1', '2023-01-29 10:52:06', '1', '2023-01-28 23:45:21', '1', '2023-01-29 10:52:06', b'0', 1);
|
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 1, 2, 1, 'test', '123', '我是 2,我开始 3 了', 1, '{\"name\":\"2\",\"what\":\"3\"}', b'1', '2025-04-21 14:59:35', '1', '2023-01-28 23:45:21', '1', '2025-04-21 14:59:35', b'0', 1);
|
||||||
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (8, 1, 2, 2, 'register', '系统消息', '你好,欢迎 123 加入大家庭!', 2, '{\"name\":\"123\"}', b'1', '2023-01-29 10:52:06', '1', '2023-01-28 23:50:21', '1', '2023-01-29 10:52:06', b'0', 1);
|
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (8, 1, 2, 2, 'register', '系统消息', '你好,欢迎 123 加入大家庭!', 2, '{\"name\":\"123\"}', b'1', '2025-04-21 14:59:35', '1', '2023-01-28 23:50:21', '1', '2025-04-21 14:59:35', b'0', 1);
|
||||||
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, 247, 1, 4, 'brokerage_withdraw_audit_approve', 'system', '您在2023-09-28 08:35:46提现¥0.09元的申请已通过审核', 2, '{\"reason\":null,\"createTime\":\"2023-09-28 08:35:46\",\"price\":\"0.09\"}', b'0', NULL, '1', '2023-09-28 16:36:22', '1', '2023-09-28 16:36:22', b'0', 1);
|
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, 247, 1, 4, 'brokerage_withdraw_audit_approve', 'system', '您在2023-09-28 08:35:46提现¥0.09元的申请已通过审核', 2, '{\"reason\":null,\"createTime\":\"2023-09-28 08:35:46\",\"price\":\"0.09\"}', b'0', NULL, '1', '2023-09-28 16:36:22', '1', '2023-09-28 16:36:22', b'0', 1);
|
||||||
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (10, 247, 1, 4, 'brokerage_withdraw_audit_approve', 'system', '您在2023-09-30 20:59:40提现¥1.00元的申请已通过审核', 2, '{\"reason\":null,\"createTime\":\"2023-09-30 20:59:40\",\"price\":\"1.00\"}', b'0', NULL, '1', '2023-10-03 12:11:34', '1', '2023-10-03 12:11:34', b'0', 1);
|
INSERT INTO `system_notify_message` (`id`, `user_id`, `user_type`, `template_id`, `template_code`, `template_nickname`, `template_content`, `template_type`, `template_params`, `read_status`, `read_time`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (10, 247, 1, 4, 'brokerage_withdraw_audit_approve', 'system', '您在2023-09-30 20:59:40提现¥1.00元的申请已通过审核', 2, '{\"reason\":null,\"createTime\":\"2023-09-30 20:59:40\",\"price\":\"1.00\"}', b'0', NULL, '1', '2023-10-03 12:11:34', '1', '2023-10-03 12:11:34', b'0', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
@ -2375,7 +2381,7 @@ CREATE TABLE `system_oauth2_access_token` (
|
|||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_access_token`(`access_token` ASC) USING BTREE,
|
INDEX `idx_access_token`(`access_token` ASC) USING BTREE,
|
||||||
INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE
|
INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 13787 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
|
) ENGINE = InnoDB AUTO_INCREMENT = 16697 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_oauth2_access_token
|
-- Records of system_oauth2_access_token
|
||||||
@ -2402,7 +2408,7 @@ CREATE TABLE `system_oauth2_approve` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 82 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 批准表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 84 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 批准表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_oauth2_approve
|
-- Records of system_oauth2_approve
|
||||||
@ -2443,10 +2449,10 @@ CREATE TABLE `system_oauth2_client` (
|
|||||||
-- Records of system_oauth2_client
|
-- Records of system_oauth2_client
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, 'default', 'admin123', '芋道源码', 'http://test.yudao.iocoder.cn/a5e2e244368878a366b516805a4aabf1.png', '我是描述', 0, 1800, 2592000, '[\"https://www.iocoder.cn\",\"https://doc.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[\"user.read\",\"user.write\"]', '[]', '{}', '1', '2022-05-11 21:47:12', '1', '2024-02-22 16:31:52', b'0');
|
INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, 'default', 'admin123', '芋道源码', 'http://test.yudao.iocoder.cn/20250502/sort2_1746189740718.png', '我是描述', 0, 1800, 2592000, '[\"https://www.iocoder.cn\",\"https://doc.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[\"user.read\",\"user.write\"]', '[]', '{}', '1', '2022-05-11 21:47:12', '1', '2025-05-02 20:42:22', b'0');
|
||||||
INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (40, 'test', 'test2', 'biubiu', 'http://test.yudao.iocoder.cn/277a899d573723f1fcdfb57340f00379.png', '啦啦啦啦', 0, 1800, 43200, '[\"https://www.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\"]', '[\"user_info\",\"projects\"]', '[\"user_info\"]', '[]', '[]', '{}', '1', '2022-05-12 00:28:20', '1', '2023-12-02 21:01:01', b'0');
|
INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (40, 'test', 'test2', 'biubiu', 'http://test.yudao.iocoder.cn/xx/20250502/ed07110a37464b5299f8bd7c67ad65c7_1746187077009.jpg', '啦啦啦啦', 0, 1800, 43200, '[\"https://www.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\"]', '[\"user_info\",\"projects\"]', '[\"user_info\"]', '[]', '[]', '{}', '1', '2022-05-12 00:28:20', '1', '2025-05-02 19:58:08', b'0');
|
||||||
INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (41, 'yudao-sso-demo-by-code', 'test', '基于授权码模式,如何实现 SSO 单点登录?', 'http://test.yudao.iocoder.cn/fe4ed36596adad5120036ef61a6d0153654544d44af8dd4ad3ffe8f759933d6f.png', NULL, 0, 1800, 43200, '[\"http://127.0.0.1:18080\"]', '[\"authorization_code\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[]', '[]', NULL, '1', '2022-09-29 13:28:31', '1', '2022-09-29 13:28:31', b'0');
|
INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (41, 'yudao-sso-demo-by-code', 'test', '基于授权码模式,如何实现 SSO 单点登录?', 'http://test.yudao.iocoder.cn/it/20250502/sign_1746181948685.png', NULL, 0, 1800, 43200, '[\"http://127.0.0.1:18080\"]', '[\"authorization_code\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[]', '[]', NULL, '1', '2022-09-29 13:28:31', '1', '2025-05-02 18:32:30', b'0');
|
||||||
INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (42, 'yudao-sso-demo-by-password', 'test', '基于密码模式,如何实现 SSO 单点登录?', 'http://test.yudao.iocoder.cn/604bdc695e13b3b22745be704d1f2aa8ee05c5f26f9fead6d1ca49005afbc857.jpeg', NULL, 0, 1800, 43200, '[\"http://127.0.0.1:18080\"]', '[\"password\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[]', '[]', NULL, '1', '2022-10-04 17:40:16', '1', '2022-10-04 20:31:21', b'0');
|
INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (42, 'yudao-sso-demo-by-password', 'test', '基于密码模式,如何实现 SSO 单点登录?', 'http://test.yudao.iocoder.cn/604bdc695e13b3b22745be704d1f2aa8ee05c5f26f9fead6d1ca49005afbc857.jpeg', NULL, 0, 1800, 43200, '[\"http://127.0.0.1:18080\"]', '[\"password\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[]', '[]', NULL, '1', '2022-10-04 17:40:16', '1', '2025-05-04 16:00:46', b'0');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -2470,7 +2476,7 @@ CREATE TABLE `system_oauth2_code` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 147 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 授权码表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 155 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 授权码表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_oauth2_code
|
-- Records of system_oauth2_code
|
||||||
@ -2497,7 +2503,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 1735 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
|
) ENGINE = InnoDB AUTO_INCREMENT = 2036 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_oauth2_refresh_token
|
-- Records of system_oauth2_refresh_token
|
||||||
@ -2531,7 +2537,7 @@ CREATE TABLE `system_operate_log` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 9065 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录 V2 版本';
|
) ENGINE = InnoDB AUTO_INCREMENT = 9090 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录 V2 版本';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_operate_log
|
-- Records of system_operate_log
|
||||||
@ -2557,7 +2563,7 @@ CREATE TABLE `system_post` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '岗位信息表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '岗位信息表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_post
|
-- Records of system_post
|
||||||
@ -2565,8 +2571,8 @@ CREATE TABLE `system_post` (
|
|||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `system_post` (`id`, `code`, `name`, `sort`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'ceo', '董事长', 1, 0, '', 'admin', '2021-01-06 17:03:48', '1', '2023-02-11 15:19:04', b'0', 1);
|
INSERT INTO `system_post` (`id`, `code`, `name`, `sort`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'ceo', '董事长', 1, 0, '', 'admin', '2021-01-06 17:03:48', '1', '2023-02-11 15:19:04', b'0', 1);
|
||||||
INSERT INTO `system_post` (`id`, `code`, `name`, `sort`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, 'se', '项目经理', 2, 0, '', 'admin', '2021-01-05 17:03:48', '1', '2023-11-15 09:18:20', b'0', 1);
|
INSERT INTO `system_post` (`id`, `code`, `name`, `sort`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, 'se', '项目经理', 2, 0, '', 'admin', '2021-01-05 17:03:48', '1', '2023-11-15 09:18:20', b'0', 1);
|
||||||
INSERT INTO `system_post` (`id`, `code`, `name`, `sort`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, 'user', '普通员工', 4, 0, '111', 'admin', '2021-01-05 17:03:48', '1', '2023-12-02 10:04:37', b'0', 1);
|
INSERT INTO `system_post` (`id`, `code`, `name`, `sort`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, 'user', '普通员工', 4, 0, '111222', 'admin', '2021-01-05 17:03:48', '1', '2025-03-24 21:32:40', b'0', 1);
|
||||||
INSERT INTO `system_post` (`id`, `code`, `name`, `sort`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, 'HR', '人力资源', 5, 0, '', '1', '2024-03-24 20:45:40', '1', '2024-03-24 20:45:40', b'0', 1);
|
INSERT INTO `system_post` (`id`, `code`, `name`, `sort`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, 'HR', '人力资源', 5, 0, '`', '1', '2024-03-24 20:45:40', '1', '2025-03-29 19:08:10', b'0', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -2590,7 +2596,7 @@ CREATE TABLE `system_role` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 154 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色信息表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 159 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色信息表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_role
|
-- Records of system_role
|
||||||
@ -2599,10 +2605,11 @@ BEGIN;
|
|||||||
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '超级管理员', 'super_admin', 1, 1, '', 0, 1, '超级管理员', 'admin', '2021-01-05 17:03:48', '', '2022-02-22 05:08:21', b'0', 1);
|
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '超级管理员', 'super_admin', 1, 1, '', 0, 1, '超级管理员', 'admin', '2021-01-05 17:03:48', '', '2022-02-22 05:08:21', b'0', 1);
|
||||||
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '普通角色', 'common', 2, 2, '', 0, 1, '普通角色', 'admin', '2021-01-05 17:03:48', '', '2022-02-22 05:08:20', b'0', 1);
|
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '普通角色', 'common', 2, 2, '', 0, 1, '普通角色', 'admin', '2021-01-05 17:03:48', '', '2022-02-22 05:08:20', b'0', 1);
|
||||||
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, 'CRM 管理员', 'crm_admin', 2, 1, '', 0, 1, 'CRM 专属角色', '1', '2024-02-24 10:51:13', '1', '2024-02-24 02:51:32', b'0', 1);
|
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, 'CRM 管理员', 'crm_admin', 2, 1, '', 0, 1, 'CRM 专属角色', '1', '2024-02-24 10:51:13', '1', '2024-02-24 02:51:32', b'0', 1);
|
||||||
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (101, '测试账号', 'test', 0, 1, '[]', 0, 2, '', '', '2021-01-06 13:49:35', '1', '2024-08-11 10:41:10', b'0', 1);
|
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (101, '测试账号', 'test', 0, 1, '[]', 0, 2, '123', '', '2021-01-06 13:49:35', '1', '2025-04-30 17:38:28', b'0', 1);
|
||||||
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-02-22 00:56:14', '1', '2022-02-22 00:56:14', b'0', 121);
|
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-02-22 00:56:14', '1', '2022-02-22 00:56:14', b'0', 121);
|
||||||
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-03-07 21:37:58', '1', '2022-03-07 21:37:58', b'0', 122);
|
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-03-07 21:37:58', '1', '2022-03-07 21:37:58', b'0', 122);
|
||||||
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (153, '某角色', 'tt', 4, 1, '', 0, 2, '', '1', '2024-08-17 14:09:35', '1', '2024-08-17 14:09:35', b'0', 1);
|
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (155, '测试数据权限', 'test-dp', 3, 2, '[100,102,103,104,105,108]', 0, 2, '', '1', '2025-03-31 14:58:06', '1', '2025-04-17 23:07:44', b'0', 1);
|
||||||
|
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (158, '2', '3', 4, 1, '', 0, 2, NULL, '1', '2025-04-17 20:08:08', '1', '2025-04-17 23:05:31', b'0', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -2620,7 +2627,7 @@ CREATE TABLE `system_role_menu` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 5793 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色和菜单关联表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 6139 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色和菜单关联表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_role_menu
|
-- Records of system_role_menu
|
||||||
@ -2945,15 +2952,9 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2080, 2, 1150, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2080, 2, 1150, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2081, 2, 1161, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2081, 2, 1161, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2082, 2, 1162, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2082, 2, 1162, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2083, 2, 1163, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2084, 2, 1164, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2085, 2, 1165, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2086, 2, 1166, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2086, 2, 1166, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2087, 2, 1173, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2087, 2, 1173, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2088, 2, 1174, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2088, 2, 1174, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2089, 2, 1175, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2090, 2, 1176, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2091, 2, 1177, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2092, 2, 1178, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2092, 2, 1178, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2099, 2, 1226, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2099, 2, 1226, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2100, 2, 1227, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2100, 2, 1227, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||||
@ -3458,6 +3459,43 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5790, 109, 2740, '1', '2024-07-13 22:37:24', '1', '2024-07-13 22:37:24', b'0', 121);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5790, 109, 2740, '1', '2024-07-13 22:37:24', '1', '2024-07-13 22:37:24', b'0', 121);
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5791, 111, 2739, '1', '2024-07-13 22:37:24', '1', '2024-07-13 22:37:24', b'0', 122);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5791, 111, 2739, '1', '2024-07-13 22:37:24', '1', '2024-07-13 22:37:24', b'0', 122);
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5792, 111, 2740, '1', '2024-07-13 22:37:24', '1', '2024-07-13 22:37:24', b'0', 122);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5792, 111, 2740, '1', '2024-07-13 22:37:24', '1', '2024-07-13 22:37:24', b'0', 122);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6053, 155, 4000, '1', '2025-04-01 13:48:26', '1', '2025-04-01 13:48:26', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6097, 155, 4050, '1', '2025-04-01 13:48:26', '1', '2025-04-01 13:48:26', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6104, 155, 4032, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6105, 155, 4033, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6106, 155, 4034, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6107, 155, 4035, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6108, 155, 4036, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6109, 155, 4037, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6110, 155, 4038, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6111, 155, 4039, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6112, 155, 4040, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6113, 155, 4041, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6114, 155, 4042, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6115, 155, 4043, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6116, 155, 4044, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6117, 155, 4045, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6118, 155, 4046, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6119, 155, 4001, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6120, 155, 4002, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6121, 155, 4003, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6122, 155, 4004, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6123, 155, 4005, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6124, 155, 4006, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6125, 155, 4007, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6126, 155, 4008, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6127, 155, 4009, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6128, 155, 4010, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6129, 155, 4011, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6130, 155, 4012, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6131, 155, 4013, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6132, 155, 4014, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6133, 155, 4015, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6134, 155, 4016, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6135, 155, 4017, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6136, 155, 4018, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6137, 155, 4031, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1);
|
||||||
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6138, 101, 5010, '1', '2025-05-05 17:49:17', '1', '2025-05-05 17:49:17', b'0', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -3512,7 +3550,7 @@ CREATE TABLE `system_sms_code` (
|
|||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号'
|
INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号'
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 649 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
|
) ENGINE = InnoDB AUTO_INCREMENT = 666 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_sms_code
|
-- Records of system_sms_code
|
||||||
@ -3553,7 +3591,7 @@ CREATE TABLE `system_sms_log` (
|
|||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 1279 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
|
) ENGINE = InnoDB AUTO_INCREMENT = 1290 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_sms_log
|
-- Records of system_sms_log
|
||||||
@ -3583,7 +3621,7 @@ CREATE TABLE `system_sms_template` (
|
|||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 19 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信模板';
|
) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信模板';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_sms_template
|
-- Records of system_sms_template
|
||||||
@ -3603,6 +3641,7 @@ INSERT INTO `system_sms_template` (`id`, `type`, `status`, `code`, `name`, `cont
|
|||||||
INSERT INTO `system_sms_template` (`id`, `type`, `status`, `code`, `name`, `content`, `params`, `remark`, `api_template_id`, `channel_id`, `channel_code`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (16, 1, 0, 'user-reset-password', '会员用户 - 重置密码', '您的验证码{code},该验证码 5 分钟内有效,请勿泄漏于他人!', '[\"code\"]', '', 'null', 4, 'DEBUG_DING_TALK', '1', '2023-08-19 18:58:01', '1', '2023-12-02 22:35:27', b'0');
|
INSERT INTO `system_sms_template` (`id`, `type`, `status`, `code`, `name`, `content`, `params`, `remark`, `api_template_id`, `channel_id`, `channel_code`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (16, 1, 0, 'user-reset-password', '会员用户 - 重置密码', '您的验证码{code},该验证码 5 分钟内有效,请勿泄漏于他人!', '[\"code\"]', '', 'null', 4, 'DEBUG_DING_TALK', '1', '2023-08-19 18:58:01', '1', '2023-12-02 22:35:27', b'0');
|
||||||
INSERT INTO `system_sms_template` (`id`, `type`, `status`, `code`, `name`, `content`, `params`, `remark`, `api_template_id`, `channel_id`, `channel_code`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (17, 2, 0, 'bpm_task_timeout', '【工作流】任务审批超时', '您收到了一条超时的待办任务:{processInstanceName}-{taskName},处理链接:{detailUrl}', '[\"processInstanceName\",\"taskName\",\"detailUrl\"]', '', 'X', 4, 'DEBUG_DING_TALK', '1', '2024-08-16 21:59:15', '1', '2024-08-16 21:59:34', b'0');
|
INSERT INTO `system_sms_template` (`id`, `type`, `status`, `code`, `name`, `content`, `params`, `remark`, `api_template_id`, `channel_id`, `channel_code`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (17, 2, 0, 'bpm_task_timeout', '【工作流】任务审批超时', '您收到了一条超时的待办任务:{processInstanceName}-{taskName},处理链接:{detailUrl}', '[\"processInstanceName\",\"taskName\",\"detailUrl\"]', '', 'X', 4, 'DEBUG_DING_TALK', '1', '2024-08-16 21:59:15', '1', '2024-08-16 21:59:34', b'0');
|
||||||
INSERT INTO `system_sms_template` (`id`, `type`, `status`, `code`, `name`, `content`, `params`, `remark`, `api_template_id`, `channel_id`, `channel_code`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (18, 1, 0, 'admin-reset-password', '后台用户 - 忘记密码', '您的验证码{code},该验证码 5 分钟内有效,请勿泄漏于他人!', '[\"code\"]', '', 'null', 4, 'DEBUG_DING_TALK', '1', '2025-03-16 14:19:34', '1', '2025-03-16 14:19:45', b'0');
|
INSERT INTO `system_sms_template` (`id`, `type`, `status`, `code`, `name`, `content`, `params`, `remark`, `api_template_id`, `channel_id`, `channel_code`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (18, 1, 0, 'admin-reset-password', '后台用户 - 忘记密码', '您的验证码{code},该验证码 5 分钟内有效,请勿泄漏于他人!', '[\"code\"]', '', 'null', 4, 'DEBUG_DING_TALK', '1', '2025-03-16 14:19:34', '1', '2025-03-16 14:19:45', b'0');
|
||||||
|
INSERT INTO `system_sms_template` (`id`, `type`, `status`, `code`, `name`, `content`, `params`, `remark`, `api_template_id`, `channel_id`, `channel_code`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (19, 1, 0, 'admin-sms-login', '后台用户短信登录', '您的验证码是{code}', '[\"code\"]', '', '4372216', 4, 'DEBUG_DING_TALK', '1', '2025-04-08 09:36:03', '1', '2025-04-08 09:36:17', b'0');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -3625,7 +3664,7 @@ CREATE TABLE `system_social_client` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 44 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交客户端表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 45 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交客户端表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_social_client
|
-- Records of system_social_client
|
||||||
@ -3635,6 +3674,7 @@ INSERT INTO `system_social_client` (`id`, `name`, `social_type`, `user_type`, `c
|
|||||||
INSERT INTO `system_social_client` (`id`, `name`, `social_type`, `user_type`, `client_id`, `client_secret`, `agent_id`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '钉钉(王土豆)', 20, 2, 'dingtsu9hpepjkbmthhw', 'FP_bnSq_HAHKCSncmJjw5hxhnzs6vaVDSZZn3egj6rdqTQ_hu5tQVJyLMpgCakdP', NULL, 0, '', '2023-10-18 11:21:18', '', '2023-12-20 21:28:26', b'1', 121);
|
INSERT INTO `system_social_client` (`id`, `name`, `social_type`, `user_type`, `client_id`, `client_secret`, `agent_id`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '钉钉(王土豆)', 20, 2, 'dingtsu9hpepjkbmthhw', 'FP_bnSq_HAHKCSncmJjw5hxhnzs6vaVDSZZn3egj6rdqTQ_hu5tQVJyLMpgCakdP', NULL, 0, '', '2023-10-18 11:21:18', '', '2023-12-20 21:28:26', b'1', 121);
|
||||||
INSERT INTO `system_social_client` (`id`, `name`, `social_type`, `user_type`, `client_id`, `client_secret`, `agent_id`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, '微信公众号', 31, 1, 'wx5b23ba7a5589ecbb', '2a7b3b20c537e52e74afd395eb85f61f', NULL, 0, '', '2023-10-18 16:07:46', '1', '2023-12-20 21:28:23', b'1', 1);
|
INSERT INTO `system_social_client` (`id`, `name`, `social_type`, `user_type`, `client_id`, `client_secret`, `agent_id`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, '微信公众号', 31, 1, 'wx5b23ba7a5589ecbb', '2a7b3b20c537e52e74afd395eb85f61f', NULL, 0, '', '2023-10-18 16:07:46', '1', '2023-12-20 21:28:23', b'1', 1);
|
||||||
INSERT INTO `system_social_client` (`id`, `name`, `social_type`, `user_type`, `client_id`, `client_secret`, `agent_id`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (43, '微信小程序', 34, 1, 'wx63c280fe3248a3e7', '6f270509224a7ae1296bbf1c8cb97aed', NULL, 0, '', '2023-10-19 13:37:41', '1', '2023-12-20 21:28:25', b'1', 1);
|
INSERT INTO `system_social_client` (`id`, `name`, `social_type`, `user_type`, `client_id`, `client_secret`, `agent_id`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (43, '微信小程序', 34, 1, 'wx63c280fe3248a3e7', '6f270509224a7ae1296bbf1c8cb97aed', NULL, 0, '', '2023-10-19 13:37:41', '1', '2023-12-20 21:28:25', b'1', 1);
|
||||||
|
INSERT INTO `system_social_client` (`id`, `name`, `social_type`, `user_type`, `client_id`, `client_secret`, `agent_id`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (44, '1', 10, 1, '2', '3', NULL, 0, '1', '2025-04-06 20:36:28', '1', '2025-04-06 20:43:12', b'1', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -3659,7 +3699,7 @@ CREATE TABLE `system_social_user` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 38 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 40 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_social_user
|
-- Records of system_social_user
|
||||||
@ -3684,7 +3724,7 @@ CREATE TABLE `system_social_user_bind` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 121 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 164 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_social_user_bind
|
-- Records of system_social_user_bind
|
||||||
@ -3720,7 +3760,7 @@ CREATE TABLE `system_tenant` (
|
|||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '芋道源码', NULL, '芋艿', '17321315478', 0, 'www.iocoder.cn', 0, '2099-02-19 17:14:16', 9999, '1', '2021-01-05 17:03:47', '1', '2023-11-06 11:41:41', b'0');
|
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '芋道源码', NULL, '芋艿', '17321315478', 0, 'www.iocoder.cn', 0, '2099-02-19 17:14:16', 9999, '1', '2021-01-05 17:03:47', '1', '2023-11-06 11:41:41', b'0');
|
||||||
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (121, '小租户', 110, '小王2', '15601691300', 0, 'zsxq.iocoder.cn', 111, '2025-03-11 00:00:00', 20, '1', '2022-02-22 00:56:14', '1', '2024-07-20 22:21:53', b'0');
|
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (121, '小租户', 110, '小王2', '15601691300', 0, 'zsxq.iocoder.cn', 111, '2026-07-10 00:00:00', 30, '1', '2022-02-22 00:56:14', '1', '2025-04-03 21:33:01', b'0');
|
||||||
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (122, '测试租户', 113, '芋道', '15601691300', 0, 'test.iocoder.cn', 111, '2022-04-29 00:00:00', 50, '1', '2022-03-07 21:37:58', '1', '2024-09-22 12:10:50', b'0');
|
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (122, '测试租户', 113, '芋道', '15601691300', 0, 'test.iocoder.cn', 111, '2022-04-29 00:00:00', 50, '1', '2022-03-07 21:37:58', '1', '2024-09-22 12:10:50', b'0');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
@ -3740,13 +3780,14 @@ CREATE TABLE `system_tenant_package` (
|
|||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 112 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '租户套餐表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 113 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '租户套餐表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_tenant_package
|
-- Records of system_tenant_package
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `system_tenant_package` (`id`, `name`, `status`, `remark`, `menu_ids`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (111, '普通套餐', 0, '小功能', '[1,2,5,1031,1032,1033,1034,1035,1036,1037,1038,1039,1050,1051,1052,1053,1054,1056,1057,1058,1059,1060,1063,1064,1065,1066,1067,1070,1075,1077,1078,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1118,1119,1120,100,101,102,103,106,107,110,111,112,113,1138,114,1139,115,1140,116,1141,1142,1143,2713,2714,2715,2716,2717,2718,2720,1185,2721,1186,2722,1187,2723,1188,2724,1189,2725,1190,2726,1191,2727,2472,1192,2728,1193,2729,1194,2730,1195,2731,1196,2732,1197,2733,2478,1198,2734,2479,1199,2735,2480,1200,2481,1201,2482,1202,2483,2739,2484,2740,2485,2486,2487,1207,2488,1208,2489,1209,2490,1210,2491,1211,2492,1212,2493,1213,2494,2495,1215,1216,2497,1217,1218,1219,1220,1221,1222,1224,1225,1226,1227,1228,1229,1237,1238,1239,1240,1241,1242,1243,2525,1255,1256,1001,1257,1002,1258,1003,1259,1004,1260,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020]', '1', '2022-02-22 00:54:00', '1', '2024-07-13 22:37:24', b'0');
|
INSERT INTO `system_tenant_package` (`id`, `name`, `status`, `remark`, `menu_ids`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (111, '普通套餐', 0, '小功能', '[1,2,5,1031,1032,1033,1034,1035,1036,1037,1038,1039,1050,1051,1052,1053,1054,1056,1057,1058,1059,1060,1063,1064,1065,1066,1067,1070,1075,1077,1078,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1118,1119,1120,100,101,102,103,106,107,110,111,112,113,1138,114,1139,115,1140,116,1141,1142,1143,2713,2714,2715,2716,2717,2718,2720,1185,2721,1186,2722,1187,2723,1188,2724,1189,2725,1190,2726,1191,2727,2472,1192,2728,1193,2729,1194,2730,1195,2731,1196,2732,1197,2733,2478,1198,2734,2479,1199,2735,2480,1200,2481,1201,2482,1202,2483,2739,2484,2740,2485,2486,2487,1207,2488,1208,2489,1209,2490,1210,2491,1211,2492,1212,2493,1213,2494,2495,1215,1216,2497,1217,1218,1219,1220,1221,1222,1224,1225,1226,1227,1228,1229,1237,1238,1239,1240,1241,1242,1243,2525,1255,1256,1001,1257,1002,1258,1003,1259,1004,1260,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020]', '1', '2022-02-22 00:54:00', '1', '2024-07-13 22:37:24', b'0');
|
||||||
|
INSERT INTO `system_tenant_package` (`id`, `name`, `status`, `remark`, `menu_ids`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (112, '再来一个套餐', 0, '1234', '[1024,1,1025,1026,2,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1042,1043,1045,1046,1048,1050,1051,1052,1053,1054,1056,1057,1058,2083,1059,1060,1063,1064,1065,1066,1067,1070,1075,1077,1078,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1100,1101,1102,1103,1104,1105,1106,2130,1107,2131,1108,2132,1109,2133,2134,2135,2136,2137,2138,2139,2140,2141,2142,2143,2144,2145,2146,2147,100,2148,101,2149,102,2150,103,2151,104,2152,105,106,107,108,109,110,111,112,113,1138,114,1139,115,1140,116,1141,1142,1143,2739,2740,1224,1225,1226,1227,1228,1229,1237,1238,1239,1240,1241,1242,1243,1255,1256,1257,1258,1259,1260,1261,1263,1264,1265,1266,1267,2447,2448,2449,2450,2451,2452,2453,2472,2478,2479,2480,2481,2482,2483,2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495,2497,2525,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,500,1013,501,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023]', '1', '2025-04-04 08:15:02', '1', '2025-04-04 08:15:21', b'0');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -3764,7 +3805,7 @@ CREATE TABLE `system_user_post` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 126 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户岗位表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 128 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户岗位表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_user_post
|
-- Records of system_user_post
|
||||||
@ -3796,7 +3837,7 @@ CREATE TABLE `system_user_role` (
|
|||||||
`deleted` bit(1) NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 48 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户和角色关联表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 49 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户和角色关联表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_user_role
|
-- Records of system_user_role
|
||||||
@ -3818,6 +3859,7 @@ INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_t
|
|||||||
INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (38, 114, 101, '1', '2024-03-24 22:23:03', '1', '2024-03-24 22:23:03', b'0', 1);
|
INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (38, 114, 101, '1', '2024-03-24 22:23:03', '1', '2024-03-24 22:23:03', b'0', 1);
|
||||||
INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (46, 117, 1, '1', '2024-10-02 10:16:11', '1', '2024-10-02 10:16:11', b'0', 1);
|
INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (46, 117, 1, '1', '2024-10-02 10:16:11', '1', '2024-10-02 10:16:11', b'0', 1);
|
||||||
INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (47, 104, 2, '1', '2025-01-04 10:40:33', '1', '2025-01-04 10:40:33', b'0', 1);
|
INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (47, 104, 2, '1', '2025-01-04 10:40:33', '1', '2025-01-04 10:40:33', b'0', 1);
|
||||||
|
INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (48, 100, 155, '1', '2025-04-04 10:41:14', '1', '2025-04-04 10:41:14', b'0', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -3846,29 +3888,30 @@ CREATE TABLE `system_users` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 140 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户信息表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 142 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户信息表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_users
|
-- Records of system_users
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$04$Q3WCEQJbSZ0zT/7ryYTb3OgtrhwIZXu4ah5RQ5/YQDQ7DpW7N7oNa', '芋道源码', '管理员', 103, '[1,2]', 'aoteman@126.com', '18818260277', 2, 'http://test.yudao.iocoder.cn/bf2002b38950c904243be7c825d3f82e29f25a44526583c3fde2ebdff3a87f75.png', 0, '0:0:0:0:0:0:0:1', '2025-03-16 14:20:16', 'admin', '2021-01-05 17:03:47', NULL, '2025-03-16 14:20:16', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$04$KljJDa/LK7QfDm0lF5OhuePhlPfjRH3tB2Wu351Uidz.oQGJXevPi', '芋道源码', '管理员', 103, '[1,2]', '11aoteman@126.com', '18818260277', 2, 'http://test.yudao.iocoder.cn/test/20250502/avatar_1746154660449.png', 0, '0:0:0:0:0:0:0:1', '2025-05-10 18:03:15', 'admin', '2021-01-05 17:03:47', NULL, '2025-05-10 18:03:15', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$04$IgUse/ibRzAZ3rngCThmtemJeoh15Ux1TQ2hIMe4iwt/K3LcFHEda', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 0, '0:0:0:0:0:0:0:1', '2024-11-02 14:00:46', '', '2021-01-07 09:07:17', NULL, '2024-11-02 14:00:46', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$04$h.aaPKgO.odHepnk5PCsWeEwKdojFWdTItxGKfx1r0e1CSeBzsTJ6', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2025-04-08 09:36:40', '', '2021-01-07 09:07:17', NULL, '2025-04-21 14:23:08', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$04$fUBSmjKCPYAUmnMzOb6qE.eZCGPhHi1JmAKclODbfS/O7fHOl2bH6', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '0:0:0:0:0:0:0:1', '2024-08-11 17:48:12', '', '2021-01-13 23:50:35', NULL, '2024-08-11 17:48:12', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$04$fUBSmjKCPYAUmnMzOb6qE.eZCGPhHi1JmAKclODbfS/O7fHOl2bH6', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2024-08-11 17:48:12', '', '2021-01-13 23:50:35', NULL, '2025-04-21 14:23:08', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$04$BrwaYn303hjA/6TnXqdGoOLhyHOAA0bVrAFu6.1dJKycqKUnIoRz2', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, '', 0, '0:0:0:0:0:0:0:1', '2025-01-04 10:40:49', '', '2021-01-21 02:13:53', NULL, '2025-01-04 10:40:49', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$04$BrwaYn303hjA/6TnXqdGoOLhyHOAA0bVrAFu6.1dJKycqKUnIoRz2', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2025-03-28 20:01:16', '', '2021-01-21 02:13:53', NULL, '2025-04-21 14:23:08', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (107, 'admin107', '$2a$10$dYOOBKMO93v/.ReCqzyFg.o67Tqk.bbc2bhrpyBGkIw9aypCtr2pm', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 22:59:33', '1', '2022-02-27 08:26:51', b'0', 118);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (107, 'admin107', '$2a$10$dYOOBKMO93v/.ReCqzyFg.o67Tqk.bbc2bhrpyBGkIw9aypCtr2pm', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 22:59:33', '1', '2025-04-21 14:23:08', b'0', 118);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (108, 'admin108', '$2a$10$y6mfvKoNYL1GXWak8nYwVOH.kCWqjactkzdoIDgiKl93WN3Ejg.Lu', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:00:50', '1', '2022-02-27 08:26:53', b'0', 119);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (108, 'admin108', '$2a$10$y6mfvKoNYL1GXWak8nYwVOH.kCWqjactkzdoIDgiKl93WN3Ejg.Lu', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 23:00:50', '1', '2025-04-21 14:23:08', b'0', 119);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, 'admin109', '$2a$10$JAqvH0tEc0I7dfDVBI7zyuB4E3j.uH6daIjV53.vUS6PknFkDJkuK', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:11:50', '1', '2022-02-27 08:26:56', b'0', 120);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, 'admin109', '$2a$10$JAqvH0tEc0I7dfDVBI7zyuB4E3j.uH6daIjV53.vUS6PknFkDJkuK', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 23:11:50', '1', '2025-04-21 14:23:08', b'0', 120);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (110, 'admin110', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '小王', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '0:0:0:0:0:0:0:1', '2024-07-20 22:23:17', '1', '2022-02-22 00:56:14', NULL, '2024-07-20 22:23:17', b'0', 121);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (110, 'admin110', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '小王', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2024-07-20 22:23:17', '1', '2022-02-22 00:56:14', NULL, '2025-04-21 14:23:08', b'0', 121);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, 'test', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '测试用户', NULL, NULL, '[]', '', '', 0, '', 0, '0:0:0:0:0:0:0:1', '2023-12-30 11:42:17', '110', '2022-02-23 13:14:33', NULL, '2023-12-30 11:42:17', b'0', 121);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, 'test', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '测试用户', NULL, NULL, '[]', '', '', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2023-12-30 11:42:17', '110', '2022-02-23 13:14:33', NULL, '2025-04-21 14:23:08', b'0', 121);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (112, 'newobject', '$2a$04$dB0z8Q819fJWz0hbaLe6B.VfHCjYgWx6LFfET5lyz3JwcqlyCkQ4C', '新对象', NULL, 100, '[]', '', '15601691235', 1, '', 0, '0:0:0:0:0:0:0:1', '2024-03-16 23:11:38', '1', '2022-02-23 19:08:03', NULL, '2024-03-16 23:11:38', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (112, 'newobject', '$2a$04$dB0z8Q819fJWz0hbaLe6B.VfHCjYgWx6LFfET5lyz3JwcqlyCkQ4C', '新对象', NULL, 100, '[]', '', '15601691235', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2024-03-16 23:11:38', '1', '2022-02-23 19:08:03', NULL, '2025-04-21 14:23:08', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, 'aoteman', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '127.0.0.1', '2022-03-19 18:38:51', '1', '2022-03-07 21:37:58', NULL, '2022-03-19 18:38:51', b'0', 122);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, 'aoteman', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道1', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '127.0.0.1', '2022-03-19 18:38:51', '1', '2022-03-07 21:37:58', '1', '2025-05-05 15:30:53', b'0', 122);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (114, 'hrmgr', '$2a$10$TR4eybBioGRhBmDBWkqWLO6NIh3mzYa8KBKDDB5woiGYFVlRAi.fu', 'hr 小姐姐', NULL, NULL, '[5]', '', '15601691236', 1, '', 0, '0:0:0:0:0:0:0:1', '2024-03-24 22:21:05', '1', '2022-03-19 21:50:58', NULL, '2024-03-24 22:21:05', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (114, 'hrmgr', '$2a$10$TR4eybBioGRhBmDBWkqWLO6NIh3mzYa8KBKDDB5woiGYFVlRAi.fu', 'hr 小姐姐', NULL, NULL, '[5]', '', '15601691236', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2024-03-24 22:21:05', '1', '2022-03-19 21:50:58', NULL, '2025-04-21 14:23:08', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (115, 'aotemane', '$2a$04$GcyP0Vyzb2F2Yni5PuIK9ueGxM0tkZGMtDwVRwrNbtMvorzbpNsV2', '阿呆', '11222', 102, '[1,2]', '7648@qq.com', '15601691229', 2, '', 0, '', NULL, '1', '2022-04-30 02:55:43', '1', '2024-04-04 09:37:14', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (115, 'aotemane', '$2a$04$GcyP0Vyzb2F2Yni5PuIK9ueGxM0tkZGMtDwVRwrNbtMvorzbpNsV2', '阿呆', '11222', 102, '[1,2]', '7648@qq.com', '15601691229', 2, NULL, 0, '', NULL, '1', '2022-04-30 02:55:43', '1', '2025-04-21 14:23:08', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (117, 'admin123', '$2a$04$sEtimsHu9YCkYY4/oqElHem2Ijc9ld20eYO6lN.g/21NfLUTDLB9W', '测试号02', '1111', 100, '[2]', '', '15601691234', 1, '', 0, '0:0:0:0:0:0:0:1', '2024-10-02 10:16:20', '1', '2022-07-09 17:40:26', NULL, '2024-10-02 10:16:20', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (117, 'admin123', '$2a$04$sEtimsHu9YCkYY4/oqElHem2Ijc9ld20eYO6lN.g/21NfLUTDLB9W', '测试号02', '1111', 100, '[2]', '', '15601691234', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2024-10-02 10:16:20', '1', '2022-07-09 17:40:26', NULL, '2025-04-21 14:23:08', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (118, 'goudan', '$2a$04$OB1SuphCdiLVRpiYRKeqH.8NYS7UIp5vmIv1W7U4w6toiFeOAATVK', '狗蛋', NULL, 103, '[1]', '', '15601691239', 1, '', 0, '0:0:0:0:0:0:0:1', '2024-03-17 09:10:27', '1', '2022-07-09 17:44:43', '1', '2024-09-06 21:40:43', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (118, 'goudan', '$2a$04$jth0yOj8cSJq84D6vrzusOHDwW/LpBfgBnQ6bfFlD8zNZfM632Ta2', '狗蛋', NULL, 103, '[1]', '', '15601691239', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2024-03-17 09:10:27', '1', '2022-07-09 17:44:43', '1', '2025-04-21 14:23:08', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (131, 'hh', '$2a$04$jyH9h6.gaw8mpOjPfHIpx.8as2Rzfcmdlj5rlJFwgCw4rsv/MTb2K', '呵呵', NULL, 100, '[]', '777@qq.com', '15601882312', 1, '', 0, '', NULL, '1', '2024-04-27 08:45:56', '1', '2024-04-27 08:45:56', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (131, 'hh', '$2a$04$jyH9h6.gaw8mpOjPfHIpx.8as2Rzfcmdlj5rlJFwgCw4rsv/MTb2K', '呵呵', NULL, 100, '[]', '777@qq.com', '15601882312', 1, NULL, 0, '', NULL, '1', '2024-04-27 08:45:56', '1', '2025-04-21 14:23:08', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (139, 'wwbwwb', '$2a$04$aOHoFbQU6zfBk/1Z9raF/ugTdhjNdx7culC1HhO0zvoczAnahCiMq', '小秃头', NULL, NULL, NULL, '', '', 0, '', 0, '0:0:0:0:0:0:0:1', '2024-09-10 21:03:58', NULL, '2024-09-10 21:03:58', NULL, '2024-09-10 21:03:58', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (139, 'wwbwwb', '$2a$04$aOHoFbQU6zfBk/1Z9raF/ugTdhjNdx7culC1HhO0zvoczAnahCiMq', '小秃头', NULL, NULL, NULL, '', '', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2024-09-10 21:03:58', NULL, '2024-09-10 21:03:58', NULL, '2025-04-21 14:23:08', b'0', 1);
|
||||||
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (141, 'admin1', '$2a$04$oj6F6d7HrZ70kYVD3TNzEu.m3TPUzajOVuC66zdKna8KRerK1FmVa', '新用户', NULL, NULL, NULL, '', '', 0, '', 0, '0:0:0:0:0:0:0:1', '2025-04-08 13:09:07', '1', '2025-04-08 13:09:07', '1', '2025-04-08 13:09:07', b'0', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -3943,7 +3986,7 @@ CREATE TABLE `yudao_demo03_course` (
|
|||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '学生课程表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 22 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '学生课程表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of yudao_demo03_course
|
-- Records of yudao_demo03_course
|
||||||
@ -3964,7 +4007,8 @@ INSERT INTO `yudao_demo03_course` (`id`, `student_id`, `name`, `score`, `creator
|
|||||||
INSERT INTO `yudao_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (16, 5, '计算机', 11, '1', '2023-11-16 23:22:46', '1', '2024-09-17 18:55:29', b'0', 1);
|
INSERT INTO `yudao_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (16, 5, '计算机', 11, '1', '2023-11-16 23:22:46', '1', '2024-09-17 18:55:29', b'0', 1);
|
||||||
INSERT INTO `yudao_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (17, 2, '语文', 66, '1', '2023-11-16 23:21:49', '1', '2024-09-17 18:55:31', b'0', 1);
|
INSERT INTO `yudao_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (17, 2, '语文', 66, '1', '2023-11-16 23:21:49', '1', '2024-09-17 18:55:31', b'0', 1);
|
||||||
INSERT INTO `yudao_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (18, 2, '数学', 22, '1', '2023-11-16 23:21:49', '1', '2024-09-17 18:55:31', b'0', 1);
|
INSERT INTO `yudao_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (18, 2, '数学', 22, '1', '2023-11-16 23:21:49', '1', '2024-09-17 18:55:31', b'0', 1);
|
||||||
INSERT INTO `yudao_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (19, 9, '滑雪', 12, '1', '2023-11-17 13:13:20', '1', '2024-09-17 18:55:50', b'0', 1);
|
INSERT INTO `yudao_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (19, 9, '滑雪', 12, '1', '2023-11-17 13:13:20', '1', '2025-04-19 02:49:03', b'1', 1);
|
||||||
|
INSERT INTO `yudao_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (20, 9, '滑雪', 12, '1', '2023-11-17 13:13:20', '1', '2025-04-19 10:49:04', b'0', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -3991,7 +4035,7 @@ CREATE TABLE `yudao_demo03_grade` (
|
|||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `yudao_demo03_grade` (`id`, `student_id`, `name`, `teacher`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 2, '三年 2 班', '周杰伦', '1', '2023-11-16 23:21:49', '1', '2024-09-17 18:55:31', b'0', 1);
|
INSERT INTO `yudao_demo03_grade` (`id`, `student_id`, `name`, `teacher`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 2, '三年 2 班', '周杰伦', '1', '2023-11-16 23:21:49', '1', '2024-09-17 18:55:31', b'0', 1);
|
||||||
INSERT INTO `yudao_demo03_grade` (`id`, `student_id`, `name`, `teacher`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (8, 5, '华为', '遥遥领先', '1', '2023-11-16 23:22:46', '1', '2024-09-17 18:55:29', b'0', 1);
|
INSERT INTO `yudao_demo03_grade` (`id`, `student_id`, `name`, `teacher`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (8, 5, '华为', '遥遥领先', '1', '2023-11-16 23:22:46', '1', '2024-09-17 18:55:29', b'0', 1);
|
||||||
INSERT INTO `yudao_demo03_grade` (`id`, `student_id`, `name`, `teacher`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, 9, '小图', '小娃111', '1', '2023-11-17 13:10:23', '1', '2024-09-17 18:55:50', b'0', 1);
|
INSERT INTO `yudao_demo03_grade` (`id`, `student_id`, `name`, `teacher`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, 9, '小图', '小娃111', '1', '2023-11-17 13:10:23', '1', '2025-04-19 10:49:04', b'0', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -4019,7 +4063,7 @@ CREATE TABLE `yudao_demo03_student` (
|
|||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `yudao_demo03_student` (`id`, `name`, `sex`, `birthday`, `description`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '小白', 1, '2023-11-16 00:00:00', '<p>厉害</p>', '1', '2023-11-16 23:21:49', '1', '2024-09-17 18:55:31', b'0', 1);
|
INSERT INTO `yudao_demo03_student` (`id`, `name`, `sex`, `birthday`, `description`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '小白', 1, '2023-11-16 00:00:00', '<p>厉害</p>', '1', '2023-11-16 23:21:49', '1', '2024-09-17 18:55:31', b'0', 1);
|
||||||
INSERT INTO `yudao_demo03_student` (`id`, `name`, `sex`, `birthday`, `description`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, '大黑', 2, '2023-11-13 00:00:00', '<p>你在教我做事?</p>', '1', '2023-11-16 23:22:46', '1', '2024-09-17 18:55:29', b'0', 1);
|
INSERT INTO `yudao_demo03_student` (`id`, `name`, `sex`, `birthday`, `description`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, '大黑', 2, '2023-11-13 00:00:00', '<p>你在教我做事?</p>', '1', '2023-11-16 23:22:46', '1', '2024-09-17 18:55:29', b'0', 1);
|
||||||
INSERT INTO `yudao_demo03_student` (`id`, `name`, `sex`, `birthday`, `description`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, '小花', 1, '2023-11-07 00:00:00', '<p>哈哈哈</p>', '1', '2023-11-17 00:04:47', '1', '2024-09-17 18:55:50', b'0', 1);
|
INSERT INTO `yudao_demo03_student` (`id`, `name`, `sex`, `birthday`, `description`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, '小花', 1, '2023-11-07 00:00:00', '<p>哈哈哈</p>', '1', '2023-11-17 00:04:47', '1', '2025-04-19 10:49:04', b'0', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
|
|||||||
@ -16,16 +16,16 @@
|
|||||||
<revision>1.0.0-SNAPSHOT</revision>
|
<revision>1.0.0-SNAPSHOT</revision>
|
||||||
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
|
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
|
||||||
<!-- 统一依赖管理 -->
|
<!-- 统一依赖管理 -->
|
||||||
<spring.boot.version>3.4.1</spring.boot.version>
|
<spring.boot.version>3.4.5</spring.boot.version>
|
||||||
<spring.cloud.version>2024.0.0</spring.cloud.version>
|
<spring.cloud.version>2024.0.1</spring.cloud.version>
|
||||||
<spring.cloud.alibaba.version>2023.0.3.2</spring.cloud.alibaba.version>
|
<spring.cloud.alibaba.version>2023.0.3.2</spring.cloud.alibaba.version>
|
||||||
<!-- Web 相关 -->
|
<!-- Web 相关 -->
|
||||||
<springdoc.version>2.7.0</springdoc.version>
|
<springdoc.version>2.8.3</springdoc.version>
|
||||||
<knife4j.version>4.6.0</knife4j.version>
|
<knife4j.version>4.6.0</knife4j.version>
|
||||||
<!-- DB 相关 -->
|
<!-- DB 相关 -->
|
||||||
<druid.version>1.2.24</druid.version>
|
<druid.version>1.2.24</druid.version>
|
||||||
<mybatis.version>3.5.17</mybatis.version>
|
<mybatis.version>3.5.19</mybatis.version>
|
||||||
<mybatis-plus.version>3.5.9</mybatis-plus.version>
|
<mybatis-plus.version>3.5.10.1</mybatis-plus.version>
|
||||||
<dynamic-datasource.version>4.3.1</dynamic-datasource.version>
|
<dynamic-datasource.version>4.3.1</dynamic-datasource.version>
|
||||||
<mybatis-plus-join.version>1.4.13</mybatis-plus-join.version>
|
<mybatis-plus-join.version>1.4.13</mybatis-plus-join.version>
|
||||||
<easy-trans.version>3.0.6</easy-trans.version>
|
<easy-trans.version>3.0.6</easy-trans.version>
|
||||||
@ -35,7 +35,7 @@
|
|||||||
<opengauss.jdbc.version>5.1.0</opengauss.jdbc.version>
|
<opengauss.jdbc.version>5.1.0</opengauss.jdbc.version>
|
||||||
<taos.version>3.3.3</taos.version>
|
<taos.version>3.3.3</taos.version>
|
||||||
<!-- 消息队列 -->
|
<!-- 消息队列 -->
|
||||||
<rocketmq-spring.version>2.3.1</rocketmq-spring.version>
|
<rocketmq-spring.version>2.3.2</rocketmq-spring.version>
|
||||||
<!-- RPC 相关 -->
|
<!-- RPC 相关 -->
|
||||||
<!-- Config 配置中心相关 -->
|
<!-- Config 配置中心相关 -->
|
||||||
<!-- Job 定时任务相关 -->
|
<!-- Job 定时任务相关 -->
|
||||||
@ -44,7 +44,7 @@
|
|||||||
<lock4j.version>2.2.7</lock4j.version>
|
<lock4j.version>2.2.7</lock4j.version>
|
||||||
<!-- 监控相关 -->
|
<!-- 监控相关 -->
|
||||||
<skywalking.version>9.0.0</skywalking.version>
|
<skywalking.version>9.0.0</skywalking.version>
|
||||||
<spring-boot-admin.version>3.4.1</spring-boot-admin.version>
|
<spring-boot-admin.version>3.4.5</spring-boot-admin.version>
|
||||||
<opentracing.version>0.33.0</opentracing.version>
|
<opentracing.version>0.33.0</opentracing.version>
|
||||||
<!-- Test 测试相关 -->
|
<!-- Test 测试相关 -->
|
||||||
<podam.version>8.0.2.RELEASE</podam.version>
|
<podam.version>8.0.2.RELEASE</podam.version>
|
||||||
@ -53,7 +53,7 @@
|
|||||||
<!-- Bpm 工作流相关 -->
|
<!-- Bpm 工作流相关 -->
|
||||||
<flowable.version>7.0.1</flowable.version>
|
<flowable.version>7.0.1</flowable.version>
|
||||||
<!-- 工具类相关 -->
|
<!-- 工具类相关 -->
|
||||||
<captcha-plus.version>2.0.3</captcha-plus.version>
|
<anji-plus-captcha.version>1.4.0</anji-plus-captcha.version>
|
||||||
<jsoup.version>1.18.1</jsoup.version>
|
<jsoup.version>1.18.1</jsoup.version>
|
||||||
<lombok.version>1.18.36</lombok.version>
|
<lombok.version>1.18.36</lombok.version>
|
||||||
<mapstruct.version>1.6.3</mapstruct.version>
|
<mapstruct.version>1.6.3</mapstruct.version>
|
||||||
@ -62,7 +62,7 @@
|
|||||||
<easyexcel.version>4.0.3</easyexcel.version>
|
<easyexcel.version>4.0.3</easyexcel.version>
|
||||||
<velocity.version>2.4.1</velocity.version>
|
<velocity.version>2.4.1</velocity.version>
|
||||||
<fastjson.version>1.2.83</fastjson.version>
|
<fastjson.version>1.2.83</fastjson.version>
|
||||||
<guava.version>33.4.0-jre</guava.version>
|
<guava.version>33.4.8-jre</guava.version>
|
||||||
<transmittable-thread-local.version>2.14.5</transmittable-thread-local.version>
|
<transmittable-thread-local.version>2.14.5</transmittable-thread-local.version>
|
||||||
<commons-net.version>3.11.1</commons-net.version>
|
<commons-net.version>3.11.1</commons-net.version>
|
||||||
<jsch.version>0.1.55</jsch.version>
|
<jsch.version>0.1.55</jsch.version>
|
||||||
@ -77,10 +77,11 @@
|
|||||||
<!-- 三方云服务相关 -->
|
<!-- 三方云服务相关 -->
|
||||||
<commons-io.version>2.17.0</commons-io.version>
|
<commons-io.version>2.17.0</commons-io.version>
|
||||||
<commons-compress.version>1.27.1</commons-compress.version>
|
<commons-compress.version>1.27.1</commons-compress.version>
|
||||||
<aws-java-sdk-s3.version>1.12.777</aws-java-sdk-s3.version>
|
<awssdk.version>2.30.14</awssdk.version>
|
||||||
<justauth.version>2.0.5</justauth.version>
|
<justauth.version>1.16.7</justauth.version>
|
||||||
<jimureport.version>1.8.1</jimureport.version>
|
<justauth-starter.version>1.4.0</justauth-starter.version>
|
||||||
<weixin-java.version>4.7.2.B</weixin-java.version>
|
<jimureport.version>1.9.4</jimureport.version>
|
||||||
|
<weixin-java.version>4.7.5.B</weixin-java.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
@ -205,6 +206,7 @@
|
|||||||
<version>${druid.version}</version>
|
<version>${druid.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
<!-- 注意:必须声明,避免 flowable 和 mybatis-plus 引入的 mybatis 版本不一致!!! -->
|
||||||
<groupId>org.mybatis</groupId>
|
<groupId>org.mybatis</groupId>
|
||||||
<artifactId>mybatis</artifactId>
|
<artifactId>mybatis</artifactId>
|
||||||
<version>${mybatis.version}</version>
|
<version>${mybatis.version}</version>
|
||||||
@ -571,9 +573,9 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.xingyuv</groupId>
|
<groupId>com.anji-plus</groupId>
|
||||||
<artifactId>spring-boot-starter-captcha-plus</artifactId>
|
<artifactId>captcha-spring-boot-starter</artifactId> <!-- 验证码,一般用于登录使用 -->
|
||||||
<version>${captcha-plus.version}</version>
|
<version>${anji-plus-captcha.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -596,9 +598,9 @@
|
|||||||
|
|
||||||
<!-- 三方云服务相关 -->
|
<!-- 三方云服务相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.amazonaws</groupId>
|
<groupId>software.amazon.awssdk</groupId>
|
||||||
<artifactId>aws-java-sdk-s3</artifactId>
|
<artifactId>s3</artifactId>
|
||||||
<version>${aws-java-sdk-s3.version}</version>
|
<version>${awssdk.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -618,15 +620,14 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.xingyuv</groupId>
|
<groupId>me.zhyd.oauth</groupId>
|
||||||
<artifactId>spring-boot-starter-justauth</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
|
<artifactId>JustAuth</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
|
||||||
<version>${justauth.version}</version>
|
<version>${justauth.version}</version>
|
||||||
<exclusions>
|
</dependency>
|
||||||
<exclusion>
|
<dependency>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>com.xkcoding.justauth</groupId>
|
||||||
<artifactId>hutool-core</artifactId>
|
<artifactId>justauth-spring-boot-starter</artifactId>
|
||||||
</exclusion>
|
<version>${justauth-starter.version}</version>
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 积木报表-->
|
<!-- 积木报表-->
|
||||||
@ -634,10 +635,15 @@
|
|||||||
<groupId>org.jeecgframework.jimureport</groupId>
|
<groupId>org.jeecgframework.jimureport</groupId>
|
||||||
<artifactId>jimureport-spring-boot3-starter-fastjson2</artifactId>
|
<artifactId>jimureport-spring-boot3-starter-fastjson2</artifactId>
|
||||||
<version>${jimureport.version}</version>
|
<version>${jimureport.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jeecgframework.jimureport</groupId>
|
||||||
|
<artifactId>jimubi-spring-boot3-starter</artifactId>
|
||||||
|
<version>${jimureport.version}</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>com.alibaba</groupId>
|
<groupId>com.github.jsqlparser</groupId>
|
||||||
<artifactId>druid</artifactId>
|
<artifactId>jsqlparser</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import java.util.function.*;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static cn.hutool.core.convert.Convert.toCollection;
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -335,4 +336,17 @@ public class CollectionUtils {
|
|||||||
return list.stream().filter(Objects::nonNull).flatMap(Collection::stream).collect(Collectors.toList());
|
return list.stream().filter(Objects::nonNull).flatMap(Collection::stream).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为 LinkedHashSet
|
||||||
|
*
|
||||||
|
* @param <T> 元素类型
|
||||||
|
* @param elementType 集合中元素类型
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return {@link LinkedHashSet}
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> LinkedHashSet<T> toLinkedHashSet(Class<T> elementType, Object value) {
|
||||||
|
return (LinkedHashSet<T>) toCollection(LinkedHashSet.class, elementType, value);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -8,12 +8,16 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import cn.iocoder.yudao.framework.common.enums.DateIntervalEnum;
|
import cn.iocoder.yudao.framework.common.enums.DateIntervalEnum;
|
||||||
|
|
||||||
import java.time.*;
|
import java.time.*;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.DateTimeParseException;
|
import java.time.format.DateTimeParseException;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.time.temporal.TemporalAdjusters;
|
import java.time.temporal.TemporalAdjusters;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.hutool.core.date.DatePattern.UTC_MS_WITH_XXX_OFFSET_PATTERN;
|
||||||
|
import static cn.hutool.core.date.DatePattern.createFormatter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 时间工具类,用于 {@link java.time.LocalDateTime}
|
* 时间工具类,用于 {@link java.time.LocalDateTime}
|
||||||
*
|
*
|
||||||
@ -26,6 +30,8 @@ public class LocalDateTimeUtils {
|
|||||||
*/
|
*/
|
||||||
public static LocalDateTime EMPTY = buildTime(1970, 1, 1);
|
public static LocalDateTime EMPTY = buildTime(1970, 1, 1);
|
||||||
|
|
||||||
|
public static DateTimeFormatter UTC_MS_WITH_XXX_OFFSET_FORMATTER = createFormatter(UTC_MS_WITH_XXX_OFFSET_PATTERN);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析时间
|
* 解析时间
|
||||||
*
|
*
|
||||||
|
|||||||
@ -1,14 +1,9 @@
|
|||||||
package cn.iocoder.yudao.framework.common.util.io;
|
package cn.iocoder.yudao.framework.common.util.io;
|
||||||
|
|
||||||
import cn.hutool.core.io.FileTypeUtil;
|
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.core.io.file.FileNameUtil;
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.hutool.crypto.digest.DigestUtil;
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,22 +58,4 @@ public class FileUtils {
|
|||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成文件路径
|
|
||||||
*
|
|
||||||
* @param content 文件内容
|
|
||||||
* @param originalName 原始文件名
|
|
||||||
* @return path,唯一不可重复
|
|
||||||
*/
|
|
||||||
public static String generatePath(byte[] content, String originalName) {
|
|
||||||
String sha256Hex = DigestUtil.sha256Hex(content);
|
|
||||||
// 情况一:如果存在 name,则优先使用 name 的后缀
|
|
||||||
if (StrUtil.isNotBlank(originalName)) {
|
|
||||||
String extName = FileNameUtil.extName(originalName);
|
|
||||||
return StrUtil.isBlank(extName) ? sha256Hex : sha256Hex + "." + extName;
|
|
||||||
}
|
|
||||||
// 情况二:基于 content 计算
|
|
||||||
return sha256Hex + '.' + FileTypeUtil.getType(new ByteArrayInputStream(content));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.common.util.string;
|
|||||||
import cn.hutool.core.text.StrPool;
|
import cn.hutool.core.text.StrPool;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -77,4 +78,30 @@ public class StrUtils {
|
|||||||
.collect(Collectors.joining("\n"));
|
.collect(Collectors.joining("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拼接方法的参数
|
||||||
|
*
|
||||||
|
* 特殊:排除一些无法序列化的参数,如 ServletRequest、ServletResponse、MultipartFile
|
||||||
|
*
|
||||||
|
* @param joinPoint 连接点
|
||||||
|
* @return 拼接后的参数
|
||||||
|
*/
|
||||||
|
public static String joinMethodArgs(JoinPoint joinPoint) {
|
||||||
|
Object[] args = joinPoint.getArgs();
|
||||||
|
if (ArrayUtil.isEmpty(args)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return ArrayUtil.join(args, ",", item -> {
|
||||||
|
if (item == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// 讨论可见:https://t.zsxq.com/XUJVk、https://t.zsxq.com/MnKcL
|
||||||
|
String clazzName = item.getClass().getName();
|
||||||
|
if (StrUtil.startWithAny(clazzName, "javax.servlet", "jakarta.servlet", "org.springframework.web")) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,8 @@ import net.sf.jsqlparser.schema.Table;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.skipPermissionCheck;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于 {@link DataPermissionRule} 的数据权限处理器
|
* 基于 {@link DataPermissionRule} 的数据权限处理器
|
||||||
*
|
*
|
||||||
@ -27,6 +29,11 @@ public class DataPermissionRuleHandler implements MultiDataPermissionHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Expression getSqlSegment(Table table, Expression where, String mappedStatementId) {
|
public Expression getSqlSegment(Table table, Expression where, String mappedStatementId) {
|
||||||
|
// 特殊:跨租户访问
|
||||||
|
if (skipPermissionCheck()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// 获得 Mapper 对应的数据权限的规则
|
// 获得 Mapper 对应的数据权限的规则
|
||||||
List<DataPermissionRule> rules = ruleFactory.getDataPermissionRule(mappedStatementId);
|
List<DataPermissionRule> rules = ruleFactory.getDataPermissionRule(mappedStatementId);
|
||||||
if (CollUtil.isEmpty(rules)) {
|
if (CollUtil.isEmpty(rules)) {
|
||||||
|
|||||||
@ -32,13 +32,12 @@ public class DataPermissionUtils {
|
|||||||
* @param runnable 逻辑
|
* @param runnable 逻辑
|
||||||
*/
|
*/
|
||||||
public static void executeIgnore(Runnable runnable) {
|
public static void executeIgnore(Runnable runnable) {
|
||||||
DataPermission dataPermission = getDisableDataPermissionDisable();
|
addDisableDataPermission();
|
||||||
DataPermissionContextHolder.add(dataPermission);
|
|
||||||
try {
|
try {
|
||||||
// 执行 runnable
|
// 执行 runnable
|
||||||
runnable.run();
|
runnable.run();
|
||||||
} finally {
|
} finally {
|
||||||
DataPermissionContextHolder.remove();
|
removeDataPermission();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,14 +49,25 @@ public class DataPermissionUtils {
|
|||||||
*/
|
*/
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public static <T> T executeIgnore(Callable<T> callable) {
|
public static <T> T executeIgnore(Callable<T> callable) {
|
||||||
DataPermission dataPermission = getDisableDataPermissionDisable();
|
addDisableDataPermission();
|
||||||
DataPermissionContextHolder.add(dataPermission);
|
|
||||||
try {
|
try {
|
||||||
// 执行 callable
|
// 执行 callable
|
||||||
return callable.call();
|
return callable.call();
|
||||||
} finally {
|
} finally {
|
||||||
DataPermissionContextHolder.remove();
|
removeDataPermission();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加忽略数据权限
|
||||||
|
*/
|
||||||
|
public static void addDisableDataPermission(){
|
||||||
|
DataPermission dataPermission = getDisableDataPermissionDisable();
|
||||||
|
DataPermissionContextHolder.add(dataPermission);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeDataPermission(){
|
||||||
|
DataPermissionContextHolder.remove();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import lombok.Data;
|
|||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,7 +31,14 @@ public class TenantProperties {
|
|||||||
*
|
*
|
||||||
* 默认情况下,每个请求需要带上 tenant-id 的请求头。但是,部分请求是无需带上的,例如说短信回调、支付回调等 Open API!
|
* 默认情况下,每个请求需要带上 tenant-id 的请求头。但是,部分请求是无需带上的,例如说短信回调、支付回调等 Open API!
|
||||||
*/
|
*/
|
||||||
private Set<String> ignoreUrls = Collections.emptySet();
|
private Set<String> ignoreUrls = new HashSet<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 需要忽略跨(切换)租户访问的请求
|
||||||
|
*
|
||||||
|
* 原因是:某些接口,访问的是个人信息,在跨租户是获取不到的!
|
||||||
|
*/
|
||||||
|
private Set<String> ignoreVisitUrls = Collections.emptySet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 需要忽略多租户的表
|
* 需要忽略多租户的表
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
package cn.iocoder.yudao.framework.tenant.config;
|
package cn.iocoder.yudao.framework.tenant.config;
|
||||||
|
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
|
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
|
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
|
||||||
import cn.iocoder.yudao.framework.redis.config.YudaoCacheProperties;
|
import cn.iocoder.yudao.framework.redis.config.YudaoCacheProperties;
|
||||||
|
import cn.iocoder.yudao.framework.security.core.service.SecurityFrameworkService;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnoreAspect;
|
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnoreAspect;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor;
|
import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.job.TenantJobAspect;
|
import cn.iocoder.yudao.framework.tenant.core.job.TenantJobAspect;
|
||||||
@ -14,16 +17,19 @@ import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter;
|
|||||||
import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
|
import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkServiceImpl;
|
import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkServiceImpl;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.web.TenantContextWebFilter;
|
import cn.iocoder.yudao.framework.tenant.core.web.TenantContextWebFilter;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.web.TenantVisitContextInterceptor;
|
||||||
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
||||||
import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
|
import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
|
||||||
import cn.iocoder.yudao.module.system.api.tenant.TenantApi;
|
import cn.iocoder.yudao.module.system.api.tenant.TenantApi;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
@ -33,16 +39,35 @@ import org.springframework.data.redis.cache.RedisCacheManager;
|
|||||||
import org.springframework.data.redis.cache.RedisCacheWriter;
|
import org.springframework.data.redis.cache.RedisCacheWriter;
|
||||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.web.method.HandlerMethod;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||||
|
import org.springframework.web.util.pattern.PathPattern;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||||
|
|
||||||
@AutoConfiguration
|
@AutoConfiguration
|
||||||
@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) // 允许使用 yudao.tenant.enable=false 禁用多租户
|
@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) // 允许使用 yudao.tenant.enable=false 禁用多租户
|
||||||
@EnableConfigurationProperties(TenantProperties.class)
|
@EnableConfigurationProperties(TenantProperties.class)
|
||||||
public class YudaoTenantAutoConfiguration {
|
public class YudaoTenantAutoConfiguration {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public TenantFrameworkService tenantFrameworkService(TenantApi tenantApi) {
|
public TenantFrameworkService tenantFrameworkService(TenantApi tenantApi) {
|
||||||
|
// 参见 https://gitee.com/zhijiantianya/yudao-cloud/issues/IC6YZF
|
||||||
|
try {
|
||||||
|
TenantApi tenantApiImpl = SpringUtil.getBean("tenantApiImpl", TenantApi.class);
|
||||||
|
if (tenantApiImpl != null) {
|
||||||
|
tenantApi = tenantApiImpl;
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {}
|
||||||
return new TenantFrameworkServiceImpl(tenantApi);
|
return new TenantFrameworkServiceImpl(tenantApi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,13 +93,60 @@ public class YudaoTenantAutoConfiguration {
|
|||||||
// ========== WEB ==========
|
// ========== WEB ==========
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public FilterRegistrationBean<TenantContextWebFilter> tenantContextWebFilter() {
|
public FilterRegistrationBean<TenantContextWebFilter> tenantContextWebFilter(TenantProperties tenantProperties) {
|
||||||
FilterRegistrationBean<TenantContextWebFilter> registrationBean = new FilterRegistrationBean<>();
|
FilterRegistrationBean<TenantContextWebFilter> registrationBean = new FilterRegistrationBean<>();
|
||||||
registrationBean.setFilter(new TenantContextWebFilter());
|
registrationBean.setFilter(new TenantContextWebFilter());
|
||||||
registrationBean.setOrder(WebFilterOrderEnum.TENANT_CONTEXT_FILTER);
|
registrationBean.setOrder(WebFilterOrderEnum.TENANT_CONTEXT_FILTER);
|
||||||
|
addIgnoreUrls(tenantProperties);
|
||||||
return registrationBean;
|
return registrationBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果 Controller 接口上,有 {@link TenantIgnore} 注解,那么添加到忽略的 URL 中
|
||||||
|
*
|
||||||
|
* @param tenantProperties 租户配置
|
||||||
|
*/
|
||||||
|
private void addIgnoreUrls(TenantProperties tenantProperties) {
|
||||||
|
// 获得接口对应的 HandlerMethod 集合
|
||||||
|
RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping)
|
||||||
|
applicationContext.getBean("requestMappingHandlerMapping");
|
||||||
|
Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods();
|
||||||
|
// 获得有 @TenantIgnore 注解的接口
|
||||||
|
for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethodMap.entrySet()) {
|
||||||
|
HandlerMethod handlerMethod = entry.getValue();
|
||||||
|
if (!handlerMethod.hasMethodAnnotation(TenantIgnore.class)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 添加到忽略的 URL 中
|
||||||
|
if (entry.getKey().getPatternsCondition() != null) {
|
||||||
|
tenantProperties.getIgnoreUrls().addAll(entry.getKey().getPatternsCondition().getPatterns());
|
||||||
|
}
|
||||||
|
if (entry.getKey().getPathPatternsCondition() != null) {
|
||||||
|
tenantProperties.getIgnoreUrls().addAll(
|
||||||
|
convertList(entry.getKey().getPathPatternsCondition().getPatterns(), PathPattern::getPatternString));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TenantVisitContextInterceptor tenantVisitContextInterceptor(TenantProperties tenantProperties,
|
||||||
|
SecurityFrameworkService securityFrameworkService) {
|
||||||
|
return new TenantVisitContextInterceptor(tenantProperties, securityFrameworkService);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public WebMvcConfigurer tenantWebMvcConfigurer(TenantProperties tenantProperties,
|
||||||
|
TenantVisitContextInterceptor tenantVisitContextInterceptor) {
|
||||||
|
return new WebMvcConfigurer() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
|
registry.addInterceptor(tenantVisitContextInterceptor)
|
||||||
|
.excludePathPatterns(tenantProperties.getIgnoreVisitUrls().toArray(new String[0]));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// ========== Security ==========
|
// ========== Security ==========
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ -142,4 +214,5 @@ public class YudaoTenantAutoConfiguration {
|
|||||||
// 创建 TenantRedisCacheManager 对象
|
// 创建 TenantRedisCacheManager 对象
|
||||||
return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration, tenantProperties.getIgnoreCaches());
|
return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration, tenantProperties.getIgnoreCaches());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
package cn.iocoder.yudao.framework.tenant.core.aop;
|
package cn.iocoder.yudao.framework.tenant.core.aop;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,10 +11,22 @@ import java.lang.annotation.*;
|
|||||||
* 1、Redis 场景:因为是基于 Key 实现多租户的能力,所以忽略没有意义,不像 DB 是一个 column 实现的
|
* 1、Redis 场景:因为是基于 Key 实现多租户的能力,所以忽略没有意义,不像 DB 是一个 column 实现的
|
||||||
* 2、MQ 场景:有点难以抉择,目前可以通过 Consumer 手动在消费的方法上,添加 @TenantIgnore 进行忽略
|
* 2、MQ 场景:有点难以抉择,目前可以通过 Consumer 手动在消费的方法上,添加 @TenantIgnore 进行忽略
|
||||||
*
|
*
|
||||||
|
* 特殊:
|
||||||
|
* 1、如果添加到 Controller 类上,则该 URL 自动添加到 {@link TenantProperties#getIgnoreUrls()} 中
|
||||||
|
* 2、如果添加到 DO 实体类上,则它对应的表名“相当于”自动添加到 {@link TenantProperties#getIgnoreTables()} 中
|
||||||
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.METHOD})
|
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Inherited
|
@Inherited
|
||||||
public @interface TenantIgnore {
|
public @interface TenantIgnore {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否开启忽略租户,默认为 true 开启
|
||||||
|
*
|
||||||
|
* 支持 Spring EL 表达式,如果返回 true 则满足条件,进行租户的忽略
|
||||||
|
*/
|
||||||
|
String enable() default "true";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.framework.tenant.core.aop;
|
package cn.iocoder.yudao.framework.tenant.core.aop;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.util.spring.SpringExpressionUtils;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -24,7 +25,12 @@ public class TenantIgnoreAspect {
|
|||||||
public Object around(ProceedingJoinPoint joinPoint, TenantIgnore tenantIgnore) throws Throwable {
|
public Object around(ProceedingJoinPoint joinPoint, TenantIgnore tenantIgnore) throws Throwable {
|
||||||
Boolean oldIgnore = TenantContextHolder.isIgnore();
|
Boolean oldIgnore = TenantContextHolder.isIgnore();
|
||||||
try {
|
try {
|
||||||
|
// 计算条件,满足的情况下,才进行忽略
|
||||||
|
Object enable = SpringExpressionUtils.parseExpression(tenantIgnore.enable());
|
||||||
|
if (Boolean.TRUE.equals(enable)) {
|
||||||
TenantContextHolder.setIgnore(true);
|
TenantContextHolder.setIgnore(true);
|
||||||
|
}
|
||||||
|
|
||||||
// 执行逻辑
|
// 执行逻辑
|
||||||
return joinPoint.proceed();
|
return joinPoint.proceed();
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
package cn.iocoder.yudao.framework.tenant.core.db;
|
package cn.iocoder.yudao.framework.tenant.core.db;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
|
import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
|
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
|
||||||
import com.baomidou.mybatisplus.extension.toolkit.SqlParserUtils;
|
import com.baomidou.mybatisplus.extension.toolkit.SqlParserUtils;
|
||||||
import net.sf.jsqlparser.expression.Expression;
|
import net.sf.jsqlparser.expression.Expression;
|
||||||
import net.sf.jsqlparser.expression.LongValue;
|
import net.sf.jsqlparser.expression.LongValue;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashMap;
|
||||||
import java.util.Set;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于 MyBatis Plus 多租户的功能,实现 DB 层面的多租户的功能
|
* 基于 MyBatis Plus 多租户的功能,实现 DB 层面的多租户的功能
|
||||||
@ -18,16 +20,21 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
public class TenantDatabaseInterceptor implements TenantLineHandler {
|
public class TenantDatabaseInterceptor implements TenantLineHandler {
|
||||||
|
|
||||||
private final Set<String> ignoreTables = new HashSet<>();
|
/**
|
||||||
|
* 忽略的表
|
||||||
|
*
|
||||||
|
* KEY:表名
|
||||||
|
* VALUE:是否忽略
|
||||||
|
*/
|
||||||
|
private final Map<String, Boolean> ignoreTables = new HashMap<>();
|
||||||
|
|
||||||
public TenantDatabaseInterceptor(TenantProperties properties) {
|
public TenantDatabaseInterceptor(TenantProperties properties) {
|
||||||
// 不同 DB 下,大小写的习惯不同,所以需要都添加进去
|
// 不同 DB 下,大小写的习惯不同,所以需要都添加进去
|
||||||
properties.getIgnoreTables().forEach(table -> {
|
properties.getIgnoreTables().forEach(table -> {
|
||||||
ignoreTables.add(table.toLowerCase());
|
addIgnoreTable(table, true);
|
||||||
ignoreTables.add(table.toUpperCase());
|
|
||||||
});
|
});
|
||||||
// 在 OracleKeyGenerator 中,生成主键时,会查询这个表,查询这个表后,会自动拼接 TENANT_ID 导致报错
|
// 在 OracleKeyGenerator 中,生成主键时,会查询这个表,查询这个表后,会自动拼接 TENANT_ID 导致报错
|
||||||
ignoreTables.add("DUAL");
|
addIgnoreTable("DUAL", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -37,8 +44,40 @@ public class TenantDatabaseInterceptor implements TenantLineHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean ignoreTable(String tableName) {
|
public boolean ignoreTable(String tableName) {
|
||||||
return TenantContextHolder.isIgnore() // 情况一,全局忽略多租户
|
// 情况一,全局忽略多租户
|
||||||
|| CollUtil.contains(ignoreTables, SqlParserUtils.removeWrapperSymbol(tableName)); // 情况二,忽略多租户的表
|
if (TenantContextHolder.isIgnore()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 情况二,忽略多租户的表
|
||||||
|
tableName = SqlParserUtils.removeWrapperSymbol(tableName);
|
||||||
|
Boolean ignore = ignoreTables.get(tableName.toLowerCase());
|
||||||
|
if (ignore == null) {
|
||||||
|
ignore = computeIgnoreTable(tableName);
|
||||||
|
synchronized (ignoreTables) {
|
||||||
|
addIgnoreTable(tableName, ignore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ignore;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addIgnoreTable(String tableName, boolean ignore) {
|
||||||
|
ignoreTables.put(tableName.toLowerCase(), ignore);
|
||||||
|
ignoreTables.put(tableName.toUpperCase(), ignore);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean computeIgnoreTable(String tableName) {
|
||||||
|
// 找不到的表,说明不是 yudao 项目里的,不进行拦截(忽略租户)
|
||||||
|
TableInfo tableInfo = TableInfoHelper.getTableInfo(tableName);
|
||||||
|
if (tableInfo == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 如果继承了 TenantBaseDO 基类,显然不忽略租户
|
||||||
|
if (TenantBaseDO.class.isAssignableFrom(tableInfo.getEntityType())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 如果添加了 @TenantIgnore 注解,显然也不忽略租户
|
||||||
|
TenantIgnore tenantIgnore = tableInfo.getEntityType().getAnnotation(TenantIgnore.class);
|
||||||
|
return tenantIgnore != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,65 @@
|
|||||||
|
package cn.iocoder.yudao.framework.tenant.core.web;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||||
|
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||||
|
import cn.iocoder.yudao.framework.security.core.service.SecurityFrameworkService;
|
||||||
|
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||||
|
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class TenantVisitContextInterceptor implements HandlerInterceptor {
|
||||||
|
|
||||||
|
private static final String PERMISSION = "system:tenant:visit";
|
||||||
|
|
||||||
|
private final TenantProperties tenantProperties;
|
||||||
|
|
||||||
|
private final SecurityFrameworkService securityFrameworkService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||||
|
// 如果和当前租户编号一致,则直接跳过
|
||||||
|
Long visitTenantId = WebFrameworkUtils.getVisitTenantId(request);
|
||||||
|
if (visitTenantId == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ObjUtil.equal(visitTenantId, TenantContextHolder.getTenantId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 必须是登录用户
|
||||||
|
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||||
|
if (loginUser == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验用户是否可切换租户
|
||||||
|
if (!securityFrameworkService.hasAnyPermissions(PERMISSION)) {
|
||||||
|
throw exception0(GlobalErrorCodeConstants.FORBIDDEN.getCode(), "您无权切换租户");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 【重点】切换租户编号
|
||||||
|
loginUser.setVisitTenantId(visitTenantId);
|
||||||
|
TenantContextHolder.setTenantId(visitTenantId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
|
||||||
|
// 【重点】清理切换,换回原租户编号
|
||||||
|
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||||
|
if (loginUser != null && loginUser.getTenantId() != null) {
|
||||||
|
TenantContextHolder.setTenantId(loginUser.getTenantId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@ import cn.hutool.system.SystemUtil;
|
|||||||
import cn.iocoder.yudao.framework.common.enums.DocumentEnum;
|
import cn.iocoder.yudao.framework.common.enums.DocumentEnum;
|
||||||
import cn.iocoder.yudao.framework.mq.redis.core.RedisMQTemplate;
|
import cn.iocoder.yudao.framework.mq.redis.core.RedisMQTemplate;
|
||||||
import cn.iocoder.yudao.framework.mq.redis.core.job.RedisPendingMessageResendJob;
|
import cn.iocoder.yudao.framework.mq.redis.core.job.RedisPendingMessageResendJob;
|
||||||
|
import cn.iocoder.yudao.framework.mq.redis.core.job.RedisStreamMessageCleanupJob;
|
||||||
import cn.iocoder.yudao.framework.mq.redis.core.pubsub.AbstractRedisChannelMessageListener;
|
import cn.iocoder.yudao.framework.mq.redis.core.pubsub.AbstractRedisChannelMessageListener;
|
||||||
import cn.iocoder.yudao.framework.mq.redis.core.stream.AbstractRedisStreamMessageListener;
|
import cn.iocoder.yudao.framework.mq.redis.core.stream.AbstractRedisStreamMessageListener;
|
||||||
import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
|
import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
|
||||||
@ -73,6 +74,17 @@ public class YudaoRedisMQConsumerAutoConfiguration {
|
|||||||
return new RedisPendingMessageResendJob(listeners, redisTemplate, groupName, redissonClient);
|
return new RedisPendingMessageResendJob(listeners, redisTemplate, groupName, redissonClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建 Redis Stream 消息清理任务
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnBean(AbstractRedisStreamMessageListener.class)
|
||||||
|
public RedisStreamMessageCleanupJob redisStreamMessageCleanupJob(List<AbstractRedisStreamMessageListener<?>> listeners,
|
||||||
|
RedisMQTemplate redisTemplate,
|
||||||
|
RedissonClient redissonClient) {
|
||||||
|
return new RedisStreamMessageCleanupJob(listeners, redisTemplate, redissonClient);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建 Redis Stream 集群消费的容器
|
* 创建 Redis Stream 集群消费的容器
|
||||||
*
|
*
|
||||||
|
|||||||
@ -23,13 +23,13 @@ import java.util.Objects;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class RedisPendingMessageResendJob {
|
public class RedisPendingMessageResendJob {
|
||||||
|
|
||||||
private static final String LOCK_KEY = "redis:pending:msg:lock";
|
private static final String LOCK_KEY = "redis:stream:pending-message-resend:lock";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息超时时间,默认 5 分钟
|
* 消息超时时间,默认 5 分钟
|
||||||
*
|
*
|
||||||
* 1. 超时的消息才会被重新投递
|
* 1. 超时的消息才会被重新投递
|
||||||
* 2. 由于定时任务 1 分钟一次,消息超时后不会被立即重投,极端情况下消息5分钟过期后,再等 1 分钟才会被扫瞄到
|
* 2. 由于定时任务 1 分钟一次,消息超时后不会被立即重投,极端情况下消息 5 分钟过期后,再等 1 分钟才会被扫瞄到
|
||||||
*/
|
*/
|
||||||
private static final int EXPIRE_TIME = 5 * 60;
|
private static final int EXPIRE_TIME = 5 * 60;
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ public class RedisPendingMessageResendJob {
|
|||||||
private final RedissonClient redissonClient;
|
private final RedissonClient redissonClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一分钟执行一次,这里选择每分钟的35秒执行,是为了避免整点任务过多的问题
|
* 一分钟执行一次,这里选择每分钟的 35 秒执行,是为了避免整点任务过多的问题
|
||||||
*/
|
*/
|
||||||
@Scheduled(cron = "35 * * * * ?")
|
@Scheduled(cron = "35 * * * * ?")
|
||||||
public void messageResend() {
|
public void messageResend() {
|
||||||
|
|||||||
@ -0,0 +1,72 @@
|
|||||||
|
package cn.iocoder.yudao.framework.mq.redis.core.job;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mq.redis.core.RedisMQTemplate;
|
||||||
|
import cn.iocoder.yudao.framework.mq.redis.core.stream.AbstractRedisStreamMessageListener;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.redisson.api.RLock;
|
||||||
|
import org.redisson.api.RedissonClient;
|
||||||
|
import org.springframework.data.redis.core.StreamOperations;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis Stream 消息清理任务
|
||||||
|
* 用于定期清理已消费的消息,防止内存占用过大
|
||||||
|
*
|
||||||
|
* @see <a href="https://www.cnblogs.com/nanxiang/p/16179519.html">记一次 redis stream 数据类型内存不释放问题</a>
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class RedisStreamMessageCleanupJob {
|
||||||
|
|
||||||
|
private static final String LOCK_KEY = "redis:stream:message-cleanup:lock";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保留的消息数量,默认保留最近 10000 条消息
|
||||||
|
*/
|
||||||
|
private static final long MAX_COUNT = 10000;
|
||||||
|
|
||||||
|
private final List<AbstractRedisStreamMessageListener<?>> listeners;
|
||||||
|
private final RedisMQTemplate redisTemplate;
|
||||||
|
private final RedissonClient redissonClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每小时执行一次清理任务
|
||||||
|
*/
|
||||||
|
@Scheduled(cron = "0 0 * * * ?")
|
||||||
|
public void cleanup() {
|
||||||
|
RLock lock = redissonClient.getLock(LOCK_KEY);
|
||||||
|
// 尝试加锁
|
||||||
|
if (lock.tryLock()) {
|
||||||
|
try {
|
||||||
|
execute();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("[cleanup][执行异常]", ex);
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行清理逻辑
|
||||||
|
*/
|
||||||
|
private void execute() {
|
||||||
|
StreamOperations<String, Object, Object> ops = redisTemplate.getRedisTemplate().opsForStream();
|
||||||
|
listeners.forEach(listener -> {
|
||||||
|
try {
|
||||||
|
// 使用 XTRIM 命令清理消息,只保留最近的 MAX_LEN 条消息
|
||||||
|
Long trimCount = ops.trim(listener.getStreamKey(), MAX_COUNT, true);
|
||||||
|
if (trimCount != null && trimCount > 0) {
|
||||||
|
log.info("[execute][Stream({}) 清理消息数量({})]", listener.getStreamKey(), trimCount);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("[execute][Stream({}) 清理异常]", listener.getStreamKey(), ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,7 +4,6 @@ import cn.hutool.core.util.ArrayUtil;
|
|||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||||
import com.github.yulichang.toolkit.MPJWrappers;
|
|
||||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
@ -15,94 +14,94 @@ import java.util.function.Consumer;
|
|||||||
* 拓展 MyBatis Plus Join QueryWrapper 类,主要增加如下功能:
|
* 拓展 MyBatis Plus Join QueryWrapper 类,主要增加如下功能:
|
||||||
* <p>
|
* <p>
|
||||||
* 1. 拼接条件的方法,增加 xxxIfPresent 方法,用于判断值不存在的时候,不要拼接到条件中。
|
* 1. 拼接条件的方法,增加 xxxIfPresent 方法,用于判断值不存在的时候,不要拼接到条件中。
|
||||||
*
|
* 2. SFunction<S, ?> column + <S> 泛型:支持任意类字段(主表、子表、三表),推荐写法, 让编译器自动推断 S 类型
|
||||||
* @param <T> 数据类型
|
* @param <T> 数据类型
|
||||||
*/
|
*/
|
||||||
public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
|
public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
|
||||||
|
|
||||||
public <R> MPJLambdaWrapperX<T> likeIfPresent(SFunction<R, ?> column, String val) {
|
public <S> MPJLambdaWrapperX<T> likeIfPresent(SFunction<S, ?> column, String val) {
|
||||||
MPJWrappers.lambdaJoin().like(column, val);
|
|
||||||
if (StringUtils.hasText(val)) {
|
if (StringUtils.hasText(val)) {
|
||||||
return (MPJLambdaWrapperX<T>) super.like(column, val);
|
return (MPJLambdaWrapperX<T>) super.like(column, val);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <R> MPJLambdaWrapperX<T> inIfPresent(SFunction<R, ?> column, Collection<?> values) {
|
public <S> MPJLambdaWrapperX<T> inIfPresent(SFunction<S, ?> column, Collection<?> values) {
|
||||||
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
|
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
|
||||||
return (MPJLambdaWrapperX<T>) super.in(column, values);
|
return (MPJLambdaWrapperX<T>) super.in(column, values);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <R> MPJLambdaWrapperX<T> inIfPresent(SFunction<R, ?> column, Object... values) {
|
public <S> MPJLambdaWrapperX<T> inIfPresent(SFunction<S, ?> column, Object... values) {
|
||||||
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
|
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
|
||||||
return (MPJLambdaWrapperX<T>) super.in(column, values);
|
return (MPJLambdaWrapperX<T>) super.in(column, values);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <R> MPJLambdaWrapperX<T> eqIfPresent(SFunction<R, ?> column, Object val) {
|
public <S> MPJLambdaWrapperX<T> eqIfPresent(SFunction<S, ?> column, Object val) {
|
||||||
if (ObjectUtil.isNotEmpty(val)) {
|
if (ObjectUtil.isNotEmpty(val)) {
|
||||||
return (MPJLambdaWrapperX<T>) super.eq(column, val);
|
return (MPJLambdaWrapperX<T>) super.eq(column, val);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <R> MPJLambdaWrapperX<T> neIfPresent(SFunction<R, ?> column, Object val) {
|
public <S> MPJLambdaWrapperX<T> neIfPresent(SFunction<S, ?> column, Object val) {
|
||||||
if (ObjectUtil.isNotEmpty(val)) {
|
if (ObjectUtil.isNotEmpty(val)) {
|
||||||
return (MPJLambdaWrapperX<T>) super.ne(column, val);
|
return (MPJLambdaWrapperX<T>) super.ne(column, val);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <R> MPJLambdaWrapperX<T> gtIfPresent(SFunction<R, ?> column, Object val) {
|
public <S> MPJLambdaWrapperX<T> gtIfPresent(SFunction<S, ?> column, Object val) {
|
||||||
if (val != null) {
|
if (val != null) {
|
||||||
return (MPJLambdaWrapperX<T>) super.gt(column, val);
|
return (MPJLambdaWrapperX<T>) super.gt(column, val);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <R> MPJLambdaWrapperX<T> geIfPresent(SFunction<R, ?> column, Object val) {
|
public <S> MPJLambdaWrapperX<T> geIfPresent(SFunction<S, ?> column, Object val) {
|
||||||
if (val != null) {
|
if (val != null) {
|
||||||
return (MPJLambdaWrapperX<T>) super.ge(column, val);
|
return (MPJLambdaWrapperX<T>) super.ge(column, val);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <R> MPJLambdaWrapperX<T> ltIfPresent(SFunction<R, ?> column, Object val) {
|
public <S> MPJLambdaWrapperX<T> ltIfPresent(SFunction<S, ?> column, Object val) {
|
||||||
if (val != null) {
|
if (val != null) {
|
||||||
return (MPJLambdaWrapperX<T>) super.lt(column, val);
|
return (MPJLambdaWrapperX<T>) super.lt(column, val);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <R> MPJLambdaWrapperX<T> leIfPresent(SFunction<R, ?> column, Object val) {
|
public <S> MPJLambdaWrapperX<T> leIfPresent(SFunction<S, ?> column, Object val) {
|
||||||
if (val != null) {
|
if (val != null) {
|
||||||
return (MPJLambdaWrapperX<T>) super.le(column, val);
|
return (MPJLambdaWrapperX<T>) super.le(column, val);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <R> MPJLambdaWrapperX<T> betweenIfPresent(SFunction<R, ?> column, Object val1, Object val2) {
|
public <S> MPJLambdaWrapperX<T> betweenIfPresent(SFunction<S, ?> column, Object[] values) {
|
||||||
if (val1 != null && val2 != null) {
|
|
||||||
return (MPJLambdaWrapperX<T>) super.between(column, val1, val2);
|
|
||||||
}
|
|
||||||
if (val1 != null) {
|
|
||||||
return (MPJLambdaWrapperX<T>) ge(column, val1);
|
|
||||||
}
|
|
||||||
if (val2 != null) {
|
|
||||||
return (MPJLambdaWrapperX<T>) le(column, val2);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <R> MPJLambdaWrapperX<T> betweenIfPresent(SFunction<R, ?> column, Object[] values) {
|
|
||||||
Object val1 = ArrayUtils.get(values, 0);
|
Object val1 = ArrayUtils.get(values, 0);
|
||||||
Object val2 = ArrayUtils.get(values, 1);
|
Object val2 = ArrayUtils.get(values, 1);
|
||||||
return betweenIfPresent(column, val1, val2);
|
return betweenIfPresent(column, val1, val2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <S> MPJLambdaWrapperX<T> betweenIfPresent(SFunction<S, ?> column, Object val1, Object val2) {
|
||||||
|
if (val1 != null && val2 != null) {
|
||||||
|
return (MPJLambdaWrapperX<T>) super.between(column, val1, val2);
|
||||||
|
}
|
||||||
|
if (val1 != null) {
|
||||||
|
return (MPJLambdaWrapperX<T>) super.ge(column, val1);
|
||||||
|
}
|
||||||
|
if (val2 != null) {
|
||||||
|
return (MPJLambdaWrapperX<T>) super.le(column, val2);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ========== 重写父类方法,方便链式调用 ==========
|
// ========== 重写父类方法,方便链式调用 ==========
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -310,4 +309,41 @@ public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== 关键重写:使 leftJoin 返回当前类型 this ==========
|
||||||
|
@Override
|
||||||
|
public <A, B> MPJLambdaWrapperX<T> leftJoin(Class<A> clazz, SFunction<A, ?> left, SFunction<B, ?> right) {
|
||||||
|
super.leftJoin(clazz, left, right);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <A, B> MPJLambdaWrapperX<T> rightJoin(Class<A> clazz, SFunction<A, ?> left, SFunction<B, ?> right) {
|
||||||
|
super.rightJoin(clazz, left, right);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <A, B> MPJLambdaWrapperX<T> innerJoin(Class<A> clazz, SFunction<A, ?> left, SFunction<B, ?> right) {
|
||||||
|
super.innerJoin(clazz, left, right);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 添加扩展 Join 支持 ext 函数式参数 ==========
|
||||||
|
public <A, B> MPJLambdaWrapperX<T> leftJoin(Class<A> clazz, SFunction<A, ?> left, SFunction<B, ?> right, Consumer<MPJLambdaWrapperX<T>> ext) {
|
||||||
|
super.leftJoin(clazz, left, right);
|
||||||
|
if (ext != null) ext.accept(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <A, B> MPJLambdaWrapperX<T> rightJoin(Class<A> clazz, SFunction<A, ?> left, SFunction<B, ?> right, Consumer<MPJLambdaWrapperX<T>> ext) {
|
||||||
|
super.rightJoin(clazz, left, right);
|
||||||
|
if (ext != null) ext.accept(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <A, B> MPJLambdaWrapperX<T> innerJoin(Class<A> clazz, SFunction<A, ?> left, SFunction<B, ?> right, Consumer<MPJLambdaWrapperX<T>> ext) {
|
||||||
|
super.innerJoin(clazz, left, right);
|
||||||
|
if (ext != null) ext.accept(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -56,6 +56,10 @@ public class LoginUser {
|
|||||||
*/
|
*/
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private Map<String, Object> context;
|
private Map<String, Object> context;
|
||||||
|
/**
|
||||||
|
* 访问的租户编号
|
||||||
|
*/
|
||||||
|
private Long visitTenantId;
|
||||||
|
|
||||||
public void setContext(String key, Object value) {
|
public void setContext(String key, Object value) {
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
|
|||||||
@ -135,7 +135,17 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
loginUserStr = URLDecoder.decode(loginUserStr, StandardCharsets.UTF_8); // 解码,解决中文乱码问题
|
loginUserStr = URLDecoder.decode(loginUserStr, StandardCharsets.UTF_8); // 解码,解决中文乱码问题
|
||||||
return JsonUtils.parseObject(loginUserStr, LoginUser.class);
|
LoginUser loginUser = JsonUtils.parseObject(loginUserStr, LoginUser.class);
|
||||||
|
// 用户类型不匹配,无权限
|
||||||
|
// 注意:只有 /admin-api/* 和 /app-api/* 有 userType,才需要比对用户类型
|
||||||
|
// 类似 WebSocket 的 /ws/* 连接地址,是不需要比对用户类型的
|
||||||
|
Integer userType = WebFrameworkUtils.getLoginUserType(request);
|
||||||
|
if (userType != null
|
||||||
|
&& loginUser != null
|
||||||
|
&& ObjectUtil.notEqual(loginUser.getUserType(), userType)) {
|
||||||
|
throw new AccessDeniedException("错误的用户类型");
|
||||||
|
}
|
||||||
|
return loginUser;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
log.error("[buildLoginUserByHeader][解析 LoginUser({}) 发生异常]", loginUserStr, ex); ;
|
log.error("[buildLoginUserByHeader][解析 LoginUser({}) 发生异常]", loginUserStr, ex); ;
|
||||||
throw ex;
|
throw ex;
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildCache;
|
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildCache;
|
||||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||||
|
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.skipPermissionCheck;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认的 {@link SecurityFrameworkService} 实现类
|
* 默认的 {@link SecurityFrameworkService} 实现类
|
||||||
@ -63,6 +64,12 @@ public class SecurityFrameworkServiceImpl implements SecurityFrameworkService {
|
|||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public boolean hasAnyPermissions(String... permissions) {
|
public boolean hasAnyPermissions(String... permissions) {
|
||||||
|
// 特殊:跨租户访问
|
||||||
|
if (skipPermissionCheck()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 权限校验
|
||||||
Long userId = getLoginUserId();
|
Long userId = getLoginUserId();
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
return false;
|
return false;
|
||||||
@ -78,6 +85,12 @@ public class SecurityFrameworkServiceImpl implements SecurityFrameworkService {
|
|||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public boolean hasAnyRoles(String... roles) {
|
public boolean hasAnyRoles(String... roles) {
|
||||||
|
// 特殊:跨租户访问
|
||||||
|
if (skipPermissionCheck()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 权限校验
|
||||||
Long userId = getLoginUserId();
|
Long userId = getLoginUserId();
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
return false;
|
return false;
|
||||||
@ -92,6 +105,12 @@ public class SecurityFrameworkServiceImpl implements SecurityFrameworkService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasAnyScopes(String... scope) {
|
public boolean hasAnyScopes(String... scope) {
|
||||||
|
// 特殊:跨租户访问
|
||||||
|
if (skipPermissionCheck()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 权限校验
|
||||||
LoginUser user = SecurityFrameworkUtils.getLoginUser();
|
LoginUser user = SecurityFrameworkUtils.getLoginUser();
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package cn.iocoder.yudao.framework.security.core.util;
|
package cn.iocoder.yudao.framework.security.core.util;
|
||||||
|
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||||
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||||
@ -139,4 +140,21 @@ public class SecurityFrameworkUtils {
|
|||||||
return authenticationToken;
|
return authenticationToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否条件跳过权限校验,包括数据权限、功能权限
|
||||||
|
*
|
||||||
|
* @return 是否跳过
|
||||||
|
*/
|
||||||
|
public static boolean skipPermissionCheck() {
|
||||||
|
LoginUser loginUser = getLoginUser();
|
||||||
|
if (loginUser == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (loginUser.getVisitTenantId() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 重点:跨租户访问时,无法进行权限校验
|
||||||
|
return ObjUtil.notEqual(loginUser.getVisitTenantId(), loginUser.getTenantId());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,7 @@ public class WebFrameworkUtils {
|
|||||||
private static final String REQUEST_ATTRIBUTE_COMMON_RESULT = "common_result";
|
private static final String REQUEST_ATTRIBUTE_COMMON_RESULT = "common_result";
|
||||||
|
|
||||||
public static final String HEADER_TENANT_ID = "tenant-id";
|
public static final String HEADER_TENANT_ID = "tenant-id";
|
||||||
|
public static final String HEADER_VISIT_TENANT_ID = "visit-tenant-id";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 终端的 Header
|
* 终端的 Header
|
||||||
@ -54,6 +55,18 @@ public class WebFrameworkUtils {
|
|||||||
return NumberUtil.isNumber(tenantId) ? Long.valueOf(tenantId) : null;
|
return NumberUtil.isNumber(tenantId) ? Long.valueOf(tenantId) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得访问的租户编号,从 header 中
|
||||||
|
* 考虑到其它 framework 组件也会使用到租户编号,所以不得不放在 WebFrameworkUtils 统一提供
|
||||||
|
*
|
||||||
|
* @param request 请求
|
||||||
|
* @return 租户编号
|
||||||
|
*/
|
||||||
|
public static Long getVisitTenantId(HttpServletRequest request) {
|
||||||
|
String tenantId = request.getHeader(HEADER_VISIT_TENANT_ID);
|
||||||
|
return NumberUtil.isNumber(tenantId)? Long.valueOf(tenantId) : null;
|
||||||
|
}
|
||||||
|
|
||||||
public static void setLoginUserId(ServletRequest request, Long userId) {
|
public static void setLoginUserId(ServletRequest request, Long userId) {
|
||||||
request.setAttribute(REQUEST_ATTRIBUTE_LOGIN_USER_ID, userId);
|
request.setAttribute(REQUEST_ATTRIBUTE_LOGIN_USER_ID, userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,10 @@ import org.springframework.stereotype.Component;
|
|||||||
import org.springframework.web.server.ServerWebExchange;
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解决 Spring Cloud Gateway 2.x 跨域时,出现重复 Origin 的 BUG
|
* 解决 Spring Cloud Gateway 2.x 跨域时,出现重复 Origin 的 BUG
|
||||||
@ -31,13 +34,19 @@ public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {
|
|||||||
@Override
|
@Override
|
||||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
return chain.filter(exchange).then(Mono.defer(() -> {
|
return chain.filter(exchange).then(Mono.defer(() -> {
|
||||||
exchange.getResponse().getHeaders().entrySet().stream()
|
// https://gitee.com/zhijiantianya/yudao-cloud/pulls/177/
|
||||||
|
List<String> keysToModify = exchange.getResponse().getHeaders().entrySet().stream()
|
||||||
.filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
|
.filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
|
||||||
.filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
|
.filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||||
|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)))
|
|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)))
|
||||||
.forEach(kv -> kv.setValue(new ArrayList<String>() {{
|
.map(Map.Entry::getKey)
|
||||||
add(kv.getValue().get(0));
|
.collect(Collectors.toList());
|
||||||
}}));
|
keysToModify.forEach(key->{
|
||||||
|
List<String> values = exchange.getResponse().getHeaders().get(key);
|
||||||
|
if (values != null && !values.isEmpty()) {
|
||||||
|
exchange.getResponse().getHeaders().put(key, Collections.singletonList(values.get(0)));
|
||||||
|
}
|
||||||
|
});
|
||||||
return chain.filter(exchange);
|
return chain.filter(exchange);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,7 +47,8 @@ public class GrayReactiveLoadBalancerClientFilter implements GlobalFilter, Order
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOrder() {
|
public int getOrder() {
|
||||||
return ReactiveLoadBalancerClientFilter.LOAD_BALANCER_CLIENT_FILTER_ORDER;
|
// https://github.com/YunaiV/yudao-cloud/pull/213
|
||||||
|
return ReactiveLoadBalancerClientFilter.LOAD_BALANCER_CLIENT_FILTER_ORDER - 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -81,9 +81,9 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> filter(final ServerWebExchange exchange, GatewayFilterChain chain) {
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
// 移除 login-user 的请求头,避免伪造模拟
|
// 移除 login-user 的请求头,避免伪造模拟
|
||||||
SecurityFrameworkUtils.removeLoginUser(exchange);
|
exchange = SecurityFrameworkUtils.removeLoginUser(exchange);
|
||||||
|
|
||||||
// 情况一,如果没有 Token 令牌,则直接继续 filter
|
// 情况一,如果没有 Token 令牌,则直接继续 filter
|
||||||
String token = SecurityFrameworkUtils.obtainAuthorization(exchange);
|
String token = SecurityFrameworkUtils.obtainAuthorization(exchange);
|
||||||
@ -93,17 +93,18 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered {
|
|||||||
|
|
||||||
// 情况二,如果有 Token 令牌,则解析对应 userId、userType、tenantId 等字段,并通过 通过 Header 转发给服务
|
// 情况二,如果有 Token 令牌,则解析对应 userId、userType、tenantId 等字段,并通过 通过 Header 转发给服务
|
||||||
// 重要说明:defaultIfEmpty 作用,保证 Mono.empty() 情况,可以继续执行 `flatMap 的 chain.filter(exchange)` 逻辑,避免返回给前端空的 Response!!
|
// 重要说明:defaultIfEmpty 作用,保证 Mono.empty() 情况,可以继续执行 `flatMap 的 chain.filter(exchange)` 逻辑,避免返回给前端空的 Response!!
|
||||||
|
ServerWebExchange finalExchange = exchange;
|
||||||
return getLoginUser(exchange, token).defaultIfEmpty(LOGIN_USER_EMPTY).flatMap(user -> {
|
return getLoginUser(exchange, token).defaultIfEmpty(LOGIN_USER_EMPTY).flatMap(user -> {
|
||||||
// 1. 无用户,直接 filter 继续请求
|
// 1. 无用户,直接 filter 继续请求
|
||||||
if (user == LOGIN_USER_EMPTY || // 下面 expiresTime 的判断,为了解决 token 实际已经过期的情况
|
if (user == LOGIN_USER_EMPTY || // 下面 expiresTime 的判断,为了解决 token 实际已经过期的情况
|
||||||
user.getExpiresTime() == null || LocalDateTimeUtils.beforeNow(user.getExpiresTime())) {
|
user.getExpiresTime() == null || LocalDateTimeUtils.beforeNow(user.getExpiresTime())) {
|
||||||
return chain.filter(exchange);
|
return chain.filter(finalExchange);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.1 有用户,则设置登录用户
|
// 2.1 有用户,则设置登录用户
|
||||||
SecurityFrameworkUtils.setLoginUser(exchange, user);
|
SecurityFrameworkUtils.setLoginUser(finalExchange, user);
|
||||||
// 2.2 将 user 并设置到 login-user 的请求头,使用 json 存储值
|
// 2.2 将 user 并设置到 login-user 的请求头,使用 json 存储值
|
||||||
ServerWebExchange newExchange = exchange.mutate()
|
ServerWebExchange newExchange = finalExchange.mutate()
|
||||||
.request(builder -> SecurityFrameworkUtils.setLoginUserHeader(builder, user)).build();
|
.request(builder -> SecurityFrameworkUtils.setLoginUserHeader(builder, user)).build();
|
||||||
return chain.filter(newExchange);
|
return chain.filter(newExchange);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -12,8 +12,8 @@ spring:
|
|||||||
config:
|
config:
|
||||||
group: ${DEPLOY_ENV}
|
group: ${DEPLOY_ENV}
|
||||||
namespace: ${DEPLOY_ENV}
|
namespace: ${DEPLOY_ENV}
|
||||||
file-extension: yml
|
file-extension: yaml
|
||||||
config:
|
config:
|
||||||
import:
|
import:
|
||||||
- optional:nacos:zoe-gateway.yml?group=DEFAULT_GROUP
|
- optional:nacos:zoe-gateway.yaml?group=DEFAULT_GROUP
|
||||||
- optional:classpath:application.yml
|
- optional:classpath:application.yaml
|
||||||
@ -64,6 +64,15 @@ public class AiKnowledgeController {
|
|||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/delete")
|
||||||
|
@Operation(summary = "删除知识库")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||||
|
@PreAuthorize("@ss.hasPermission('ai:knowledge:delete')")
|
||||||
|
public CommonResult<Boolean> deleteKnowledge(@RequestParam("id") Long id) {
|
||||||
|
knowledgeService.deleteKnowledge(id);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/simple-list")
|
@GetMapping("/simple-list")
|
||||||
@Operation(summary = "获得知识库的精简列表")
|
@Operation(summary = "获得知识库的精简列表")
|
||||||
public CommonResult<List<AiKnowledgeRespVO>> getKnowledgeSimpleList() {
|
public CommonResult<List<AiKnowledgeRespVO>> getKnowledgeSimpleList() {
|
||||||
|
|||||||
@ -0,0 +1,12 @@
|
|||||||
|
### 测试 AI 工作流
|
||||||
|
POST {{baseUrl}}/ai/workflow/test
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: {{token}}
|
||||||
|
tenant-id: {{adminTenantId}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"params": {
|
||||||
|
"message": "1 + 1 = ?"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,8 @@
|
|||||||
package cn.iocoder.yudao.module.ai.controller.admin.workflow.vo;
|
package cn.iocoder.yudao.module.ai.controller.admin.workflow.vo;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
import jakarta.validation.constraints.AssertTrue;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -10,11 +11,18 @@ import java.util.Map;
|
|||||||
@Data
|
@Data
|
||||||
public class AiWorkflowTestReqVO {
|
public class AiWorkflowTestReqVO {
|
||||||
|
|
||||||
@Schema(description = "工作流模型", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}")
|
@Schema(description = "工作流编号", example = "1024")
|
||||||
@NotEmpty(message = "工作流模型不能为空")
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "工作流模型", example = "{}")
|
||||||
private String graph;
|
private String graph;
|
||||||
|
|
||||||
@Schema(description = "参数", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}")
|
@Schema(description = "参数", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}")
|
||||||
private Map<String, Object> params;
|
private Map<String, Object> params;
|
||||||
|
|
||||||
|
@AssertTrue(message = "工作流或模型,必须传递一个")
|
||||||
|
public boolean isGraphValid() {
|
||||||
|
return id != null || StrUtil.isNotEmpty(graph);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,4 +36,8 @@ public interface AiKnowledgeDocumentMapper extends BaseMapperX<AiKnowledgeDocume
|
|||||||
return selectList(AiKnowledgeDocumentDO::getStatus, status);
|
return selectList(AiKnowledgeDocumentDO::getStatus, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default List<AiKnowledgeDocumentDO> selectListByKnowledgeId(Long knowledgeId) {
|
||||||
|
return selectList(AiKnowledgeDocumentDO::getKnowledgeId, knowledgeId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,9 +30,9 @@ public interface AiKnowledgeSegmentMapper extends BaseMapperX<AiKnowledgeSegment
|
|||||||
.orderByDesc(AiKnowledgeSegmentDO::getId));
|
.orderByDesc(AiKnowledgeSegmentDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<AiKnowledgeSegmentDO> selectListByVectorIds(List<String> vectorIdList) {
|
default List<AiKnowledgeSegmentDO> selectListByVectorIds(List<String> vectorIds) {
|
||||||
return selectList(new LambdaQueryWrapperX<AiKnowledgeSegmentDO>()
|
return selectList(new LambdaQueryWrapperX<AiKnowledgeSegmentDO>()
|
||||||
.in(AiKnowledgeSegmentDO::getVectorId, vectorIdList)
|
.in(AiKnowledgeSegmentDO::getVectorId, vectorIds)
|
||||||
.orderByDesc(AiKnowledgeSegmentDO::getId));
|
.orderByDesc(AiKnowledgeSegmentDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,10 +2,11 @@ package cn.iocoder.yudao.module.ai.framework.rpc.config;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
||||||
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
|
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
|
||||||
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(value = "aiRpcConfiguration", proxyBeanMethods = false)
|
||||||
@EnableFeignClients(clients = {DictDataApi.class, FileApi.class})
|
@EnableFeignClients(clients = {DictDataApi.class, FileApi.class, AdminUserApi.class})
|
||||||
public class RpcConfiguration {
|
public class RpcConfiguration {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,8 +101,7 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
|
|||||||
ChatModel chatModel = modalService.getChatModel(model.getId());
|
ChatModel chatModel = modalService.getChatModel(model.getId());
|
||||||
|
|
||||||
// 2. 知识库找回
|
// 2. 知识库找回
|
||||||
List<AiKnowledgeSegmentSearchRespBO> knowledgeSegments = recallKnowledgeSegment(sendReqVO.getContent(),
|
List<AiKnowledgeSegmentSearchRespBO> knowledgeSegments = recallKnowledgeSegment(sendReqVO.getContent(), conversation);
|
||||||
conversation);
|
|
||||||
|
|
||||||
// 3. 插入 user 发送消息
|
// 3. 插入 user 发送消息
|
||||||
AiChatMessageDO userMessage = createChatMessage(conversation.getId(), null, model,
|
AiChatMessageDO userMessage = createChatMessage(conversation.getId(), null, model,
|
||||||
@ -122,11 +121,11 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
|
|||||||
String newContent = chatResponse.getResult().getOutput().getText();
|
String newContent = chatResponse.getResult().getOutput().getText();
|
||||||
chatMessageMapper.updateById(new AiChatMessageDO().setId(assistantMessage.getId()).setContent(newContent));
|
chatMessageMapper.updateById(new AiChatMessageDO().setId(assistantMessage.getId()).setContent(newContent));
|
||||||
// 3.4 响应结果
|
// 3.4 响应结果
|
||||||
|
Map<Long, AiKnowledgeDocumentDO> documentMap = knowledgeDocumentService.getKnowledgeDocumentMap(
|
||||||
|
convertSet(knowledgeSegments, AiKnowledgeSegmentSearchRespBO::getDocumentId));
|
||||||
List<AiChatMessageRespVO.KnowledgeSegment> segments = BeanUtils.toBean(knowledgeSegments,
|
List<AiChatMessageRespVO.KnowledgeSegment> segments = BeanUtils.toBean(knowledgeSegments,
|
||||||
AiChatMessageRespVO.KnowledgeSegment.class,
|
AiChatMessageRespVO.KnowledgeSegment.class, segment -> {
|
||||||
segment -> {
|
AiKnowledgeDocumentDO document = documentMap.get(segment.getDocumentId());
|
||||||
AiKnowledgeDocumentDO document = knowledgeDocumentService
|
|
||||||
.getKnowledgeDocument(segment.getDocumentId());
|
|
||||||
segment.setDocumentName(document != null ? document.getName() : null);
|
segment.setDocumentName(document != null ? document.getName() : null);
|
||||||
});
|
});
|
||||||
return new AiChatMessageSendRespVO()
|
return new AiChatMessageSendRespVO()
|
||||||
@ -173,12 +172,13 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
|
|||||||
// 处理知识库的返回,只有首次才有
|
// 处理知识库的返回,只有首次才有
|
||||||
List<AiChatMessageRespVO.KnowledgeSegment> segments = null;
|
List<AiChatMessageRespVO.KnowledgeSegment> segments = null;
|
||||||
if (StrUtil.isEmpty(contentBuffer)) {
|
if (StrUtil.isEmpty(contentBuffer)) {
|
||||||
segments = BeanUtils.toBean(knowledgeSegments, AiChatMessageRespVO.KnowledgeSegment.class,
|
Map<Long, AiKnowledgeDocumentDO> documentMap = TenantUtils.executeIgnore(() ->
|
||||||
segment -> TenantUtils.executeIgnore(() -> {
|
knowledgeDocumentService.getKnowledgeDocumentMap(
|
||||||
AiKnowledgeDocumentDO document = knowledgeDocumentService
|
convertSet(knowledgeSegments, AiKnowledgeSegmentSearchRespBO::getDocumentId)));
|
||||||
.getKnowledgeDocument(segment.getDocumentId());
|
segments = BeanUtils.toBean(knowledgeSegments, AiChatMessageRespVO.KnowledgeSegment.class, segment -> {
|
||||||
|
AiKnowledgeDocumentDO document = documentMap.get(segment.getDocumentId());
|
||||||
segment.setDocumentName(document != null ? document.getName() : null);
|
segment.setDocumentName(document != null ? document.getName() : null);
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
// 响应结果
|
// 响应结果
|
||||||
String newContent = chunk.getResult() != null ? chunk.getResult().getOutput().getText() : null;
|
String newContent = chunk.getResult() != null ? chunk.getResult().getOutput().getText() : null;
|
||||||
@ -247,16 +247,18 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
|
|||||||
|
|
||||||
// 2.1 查询 tool 工具
|
// 2.1 查询 tool 工具
|
||||||
Set<String> toolNames = null;
|
Set<String> toolNames = null;
|
||||||
|
Map<String,Object> toolContext = Map.of();
|
||||||
if (conversation.getRoleId() != null) {
|
if (conversation.getRoleId() != null) {
|
||||||
AiChatRoleDO chatRole = chatRoleService.getChatRole(conversation.getRoleId());
|
AiChatRoleDO chatRole = chatRoleService.getChatRole(conversation.getRoleId());
|
||||||
if (chatRole != null && CollUtil.isNotEmpty(chatRole.getToolIds())) {
|
if (chatRole != null && CollUtil.isNotEmpty(chatRole.getToolIds())) {
|
||||||
toolNames = convertSet(toolService.getToolList(chatRole.getToolIds()), AiToolDO::getName);
|
toolNames = convertSet(toolService.getToolList(chatRole.getToolIds()), AiToolDO::getName);
|
||||||
|
toolContext = AiUtils.buildCommonToolContext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 2.2 构建 ChatOptions 对象
|
// 2.2 构建 ChatOptions 对象
|
||||||
AiPlatformEnum platform = AiPlatformEnum.validatePlatform(model.getPlatform());
|
AiPlatformEnum platform = AiPlatformEnum.validatePlatform(model.getPlatform());
|
||||||
ChatOptions chatOptions = AiUtils.buildChatOptions(platform, model.getModel(),
|
ChatOptions chatOptions = AiUtils.buildChatOptions(platform, model.getModel(),
|
||||||
conversation.getTemperature(), conversation.getMaxTokens(), toolNames);
|
conversation.getTemperature(), conversation.getMaxTokens(), toolNames, toolContext);
|
||||||
return new Prompt(chatMessages, chatOptions);
|
return new Prompt(chatMessages, chatOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -67,13 +67,6 @@ public interface AiKnowledgeDocumentService {
|
|||||||
*/
|
*/
|
||||||
void updateKnowledgeDocumentStatus(AiKnowledgeDocumentUpdateStatusReqVO reqVO);
|
void updateKnowledgeDocumentStatus(AiKnowledgeDocumentUpdateStatusReqVO reqVO);
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新文档检索次数(增加 +1)
|
|
||||||
*
|
|
||||||
* @param ids 文档编号列表
|
|
||||||
*/
|
|
||||||
void updateKnowledgeDocumentRetrievalCountIncr(Collection<Long> ids);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除文档
|
* 删除文档
|
||||||
*
|
*
|
||||||
@ -81,6 +74,13 @@ public interface AiKnowledgeDocumentService {
|
|||||||
*/
|
*/
|
||||||
void deleteKnowledgeDocument(Long id);
|
void deleteKnowledgeDocument(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据知识库编号,批量删除文档
|
||||||
|
*
|
||||||
|
* @param knowledgeId 知识库编号
|
||||||
|
*/
|
||||||
|
void deleteKnowledgeDocumentByKnowledgeId(Long knowledgeId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验文档是否存在
|
* 校验文档是否存在
|
||||||
*
|
*
|
||||||
@ -105,6 +105,14 @@ public interface AiKnowledgeDocumentService {
|
|||||||
*/
|
*/
|
||||||
List<AiKnowledgeDocumentDO> getKnowledgeDocumentList(Collection<Long> ids);
|
List<AiKnowledgeDocumentDO> getKnowledgeDocumentList(Collection<Long> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据知识库编号获取文档列表
|
||||||
|
*
|
||||||
|
* @param knowledgeId 知识库编号
|
||||||
|
* @return 文档列表
|
||||||
|
*/
|
||||||
|
List<AiKnowledgeDocumentDO> getKnowledgeDocumentListByKnowledgeId(Long knowledgeId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文档 Map
|
* 获取文档 Map
|
||||||
*
|
*
|
||||||
|
|||||||
@ -161,14 +161,6 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic
|
|||||||
knowledgeSegmentService.deleteKnowledgeSegmentByDocumentId(id);
|
knowledgeSegmentService.deleteKnowledgeSegmentByDocumentId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateKnowledgeDocumentRetrievalCountIncr(Collection<Long> ids) {
|
|
||||||
if (CollUtil.isEmpty(ids)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
knowledgeDocumentMapper.updateRetrievalCountIncr(ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AiKnowledgeDocumentDO validateKnowledgeDocumentExists(Long id) {
|
public AiKnowledgeDocumentDO validateKnowledgeDocumentExists(Long id) {
|
||||||
AiKnowledgeDocumentDO knowledgeDocument = knowledgeDocumentMapper.selectById(id);
|
AiKnowledgeDocumentDO knowledgeDocument = knowledgeDocumentMapper.selectById(id);
|
||||||
@ -211,4 +203,24 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic
|
|||||||
return knowledgeDocumentMapper.selectBatchIds(ids);
|
return knowledgeDocumentMapper.selectBatchIds(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AiKnowledgeDocumentDO> getKnowledgeDocumentListByKnowledgeId(Long knowledgeId) {
|
||||||
|
return knowledgeDocumentMapper.selectListByKnowledgeId(knowledgeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void deleteKnowledgeDocumentByKnowledgeId(Long knowledgeId) {
|
||||||
|
// 1. 获取该知识库下的所有文档
|
||||||
|
List<AiKnowledgeDocumentDO> documents = knowledgeDocumentMapper.selectListByKnowledgeId(knowledgeId);
|
||||||
|
if (CollUtil.isEmpty(documents)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 逐个删除文档及其对应的段落
|
||||||
|
for (AiKnowledgeDocumentDO document : documents) {
|
||||||
|
deleteKnowledgeDocument(document.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,13 @@ public interface AiKnowledgeService {
|
|||||||
*/
|
*/
|
||||||
void updateKnowledge(AiKnowledgeSaveReqVO updateReqVO);
|
void updateKnowledge(AiKnowledgeSaveReqVO updateReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除知识库
|
||||||
|
*
|
||||||
|
* @param id 知识库编号
|
||||||
|
*/
|
||||||
|
void deleteKnowledge(Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得知识库
|
* 获得知识库
|
||||||
*
|
*
|
||||||
|
|||||||
@ -1,19 +1,18 @@
|
|||||||
package cn.iocoder.yudao.module.ai.service.knowledge;
|
package cn.iocoder.yudao.module.ai.service.knowledge;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgePageReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgePageReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeSaveReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDO;
|
import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDO;
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDocumentDO;
|
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiModelDO;
|
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiModelDO;
|
||||||
import cn.iocoder.yudao.module.ai.dal.mysql.knowledge.AiKnowledgeMapper;
|
import cn.iocoder.yudao.module.ai.dal.mysql.knowledge.AiKnowledgeMapper;
|
||||||
import cn.iocoder.yudao.module.ai.service.model.AiModelService;
|
import cn.iocoder.yudao.module.ai.service.model.AiModelService;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -36,6 +35,8 @@ public class AiKnowledgeServiceImpl implements AiKnowledgeService {
|
|||||||
private AiModelService modelService;
|
private AiModelService modelService;
|
||||||
@Resource
|
@Resource
|
||||||
private AiKnowledgeSegmentService knowledgeSegmentService;
|
private AiKnowledgeSegmentService knowledgeSegmentService;
|
||||||
|
@Resource
|
||||||
|
private AiKnowledgeDocumentService knowledgeDocumentService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createKnowledge(AiKnowledgeSaveReqVO createReqVO) {
|
public Long createKnowledge(AiKnowledgeSaveReqVO createReqVO) {
|
||||||
@ -67,6 +68,20 @@ public class AiKnowledgeServiceImpl implements AiKnowledgeService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void deleteKnowledge(Long id) {
|
||||||
|
// 1. 校验存在
|
||||||
|
validateKnowledgeExists(id);
|
||||||
|
|
||||||
|
// 2. 删除知识库下的所有文档及段落
|
||||||
|
knowledgeDocumentService.deleteKnowledgeDocumentByKnowledgeId(id);
|
||||||
|
|
||||||
|
// 3. 删除知识库
|
||||||
|
// 特殊:知识库需要最后删除,不然相关的配置会找不到
|
||||||
|
knowledgeMapper.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AiKnowledgeDO getKnowledge(Long id) {
|
public AiKnowledgeDO getKnowledge(Long id) {
|
||||||
return knowledgeMapper.selectById(id);
|
return knowledgeMapper.selectById(id);
|
||||||
@ -74,11 +89,11 @@ public class AiKnowledgeServiceImpl implements AiKnowledgeService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AiKnowledgeDO validateKnowledgeExists(Long id) {
|
public AiKnowledgeDO validateKnowledgeExists(Long id) {
|
||||||
AiKnowledgeDO knowledgeBase = knowledgeMapper.selectById(id);
|
AiKnowledgeDO knowledge = knowledgeMapper.selectById(id);
|
||||||
if (knowledgeBase == null) {
|
if (knowledge == null) {
|
||||||
throw exception(KNOWLEDGE_NOT_EXISTS);
|
throw exception(KNOWLEDGE_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
return knowledgeBase;
|
return knowledge;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|||||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiModelPageReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiModelPageReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiModelSaveReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiModelSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiModelDO;
|
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiModelDO;
|
||||||
|
import dev.tinyflow.core.Tinyflow;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.springframework.ai.chat.model.ChatModel;
|
import org.springframework.ai.chat.model.ChatModel;
|
||||||
import org.springframework.ai.image.ImageModel;
|
import org.springframework.ai.image.ImageModel;
|
||||||
@ -131,4 +132,12 @@ public interface AiModelService {
|
|||||||
*/
|
*/
|
||||||
VectorStore getOrCreateVectorStore(Long id, Map<String, Class<?>> metadataFields);
|
VectorStore getOrCreateVectorStore(Long id, Map<String, Class<?>> metadataFields);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 TinyFlow 所需 LLm Provider
|
||||||
|
*
|
||||||
|
* @param tinyflow tinyflow
|
||||||
|
* @param modelId AI 模型 ID
|
||||||
|
*/
|
||||||
|
void getLLmProvider4Tinyflow(Tinyflow tinyflow, Long modelId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,11 @@ import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiModelSaveReq
|
|||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
|
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiModelDO;
|
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiModelDO;
|
||||||
import cn.iocoder.yudao.module.ai.dal.mysql.model.AiChatMapper;
|
import cn.iocoder.yudao.module.ai.dal.mysql.model.AiChatMapper;
|
||||||
|
import com.agentsflex.llm.ollama.OllamaLlm;
|
||||||
|
import com.agentsflex.llm.ollama.OllamaLlmConfig;
|
||||||
|
import com.agentsflex.llm.qwen.QwenLlm;
|
||||||
|
import com.agentsflex.llm.qwen.QwenLlmConfig;
|
||||||
|
import dev.tinyflow.core.Tinyflow;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.ai.chat.model.ChatModel;
|
import org.springframework.ai.chat.model.ChatModel;
|
||||||
import org.springframework.ai.embedding.EmbeddingModel;
|
import org.springframework.ai.embedding.EmbeddingModel;
|
||||||
@ -168,4 +173,29 @@ public class AiModelServiceImpl implements AiModelService {
|
|||||||
// return modelFactory.getOrCreateVectorStore(MilvusVectorStore.class, embeddingModel, metadataFields);
|
// return modelFactory.getOrCreateVectorStore(MilvusVectorStore.class, embeddingModel, metadataFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO @lesan:是不是返回 Llm 对象会好点哈?
|
||||||
|
@Override
|
||||||
|
public void getLLmProvider4Tinyflow(Tinyflow tinyflow, Long modelId) {
|
||||||
|
AiModelDO model = validateModel(modelId);
|
||||||
|
AiApiKeyDO apiKey = apiKeyService.validateApiKey(model.getKeyId());
|
||||||
|
AiPlatformEnum platform = AiPlatformEnum.validatePlatform(apiKey.getPlatform());
|
||||||
|
switch (platform) {
|
||||||
|
// TODO @lesan 考虑到未来不需要使用agents-flex 现在仅测试通义千问
|
||||||
|
// TODO @lesan:【重要】是不是可以实现一个 SpringAiLlm,这样的话,内部全部用它就好了。只实现 chat 部分;这样,就把 flex 作为一个 agent 框架,内部调用,还是 spring ai 相关的。成本可能低一点?!
|
||||||
|
case TONG_YI:
|
||||||
|
QwenLlmConfig qwenLlmConfig = new QwenLlmConfig();
|
||||||
|
qwenLlmConfig.setApiKey(apiKey.getApiKey());
|
||||||
|
qwenLlmConfig.setModel(model.getModel());
|
||||||
|
// TODO @lesan:这个有点奇怪。。。如果一个链式里,有多个模型,咋整呀。。。
|
||||||
|
tinyflow.setLlmProvider(id -> new QwenLlm(qwenLlmConfig));
|
||||||
|
break;
|
||||||
|
case OLLAMA:
|
||||||
|
OllamaLlmConfig ollamaLlmConfig = new OllamaLlmConfig();
|
||||||
|
ollamaLlmConfig.setEndpoint(apiKey.getUrl());
|
||||||
|
ollamaLlmConfig.setModel(model.getModel());
|
||||||
|
tinyflow.setLlmProvider(id -> new OllamaLlm(ollamaLlmConfig));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
package cn.iocoder.yudao.module.ai.service.model.tool;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.ai.core.util.AiUtils;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||||
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
|
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonClassDescription;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.springframework.ai.chat.model.ToolContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工具:当前用户信息查询
|
||||||
|
*
|
||||||
|
* 同时,也是展示 ToolContext 上下文的使用
|
||||||
|
*
|
||||||
|
* @author Ren
|
||||||
|
*/
|
||||||
|
@Component("user_profile_query")
|
||||||
|
public class UserProfileQueryToolFunction
|
||||||
|
implements BiFunction<UserProfileQueryToolFunction.Request, ToolContext, UserProfileQueryToolFunction.Response> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AdminUserApi adminUserApi;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@JsonClassDescription("当前用户信息查询")
|
||||||
|
public static class Request { }
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public static class Response {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 用户昵称
|
||||||
|
*/
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号码
|
||||||
|
*/
|
||||||
|
private String mobile;
|
||||||
|
/**
|
||||||
|
* 用户头像
|
||||||
|
*/
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserProfileQueryToolFunction.Response apply(UserProfileQueryToolFunction.Request request, ToolContext toolContext) {
|
||||||
|
LoginUser loginUser = (LoginUser) toolContext.getContext().get(AiUtils.TOOL_CONTEXT_LOGIN_USER);
|
||||||
|
Long tenantId = (Long) toolContext.getContext().get(AiUtils.TOOL_CONTEXT_TENANT_ID);
|
||||||
|
if (loginUser == null | tenantId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return TenantUtils.execute(tenantId, () -> {
|
||||||
|
AdminUserRespDTO user = adminUserApi.getUser(loginUser.getId()).getCheckedData();
|
||||||
|
return BeanUtils.toBean(user, Response.class);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -7,10 +7,9 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
|||||||
import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowPageReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowPageReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowSaveReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowTestReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowTestReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
|
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.workflow.AiWorkflowDO;
|
import cn.iocoder.yudao.module.ai.dal.dataobject.workflow.AiWorkflowDO;
|
||||||
import cn.iocoder.yudao.module.ai.dal.mysql.workflow.AiWorkflowMapper;
|
import cn.iocoder.yudao.module.ai.dal.mysql.workflow.AiWorkflowMapper;
|
||||||
import cn.iocoder.yudao.module.ai.service.model.AiApiKeyService;
|
import cn.iocoder.yudao.module.ai.service.model.AiModelService;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import dev.tinyflow.core.Tinyflow;
|
import dev.tinyflow.core.Tinyflow;
|
||||||
@ -37,11 +36,14 @@ public class AiWorkflowServiceImpl implements AiWorkflowService {
|
|||||||
private AiWorkflowMapper workflowMapper;
|
private AiWorkflowMapper workflowMapper;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private AiApiKeyService apiKeyService;
|
private AiModelService apiModelService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createWorkflow(AiWorkflowSaveReqVO createReqVO) {
|
public Long createWorkflow(AiWorkflowSaveReqVO createReqVO) {
|
||||||
validateWorkflowForCreateOrUpdate(null, createReqVO.getCode());
|
// 1. 参数校验
|
||||||
|
validateCodeUnique(null, createReqVO.getCode());
|
||||||
|
|
||||||
|
// 2. 插入工作流配置
|
||||||
AiWorkflowDO workflow = BeanUtils.toBean(createReqVO, AiWorkflowDO.class);
|
AiWorkflowDO workflow = BeanUtils.toBean(createReqVO, AiWorkflowDO.class);
|
||||||
workflowMapper.insert(workflow);
|
workflowMapper.insert(workflow);
|
||||||
return workflow.getId();
|
return workflow.getId();
|
||||||
@ -49,47 +51,33 @@ public class AiWorkflowServiceImpl implements AiWorkflowService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateWorkflow(AiWorkflowSaveReqVO updateReqVO) {
|
public void updateWorkflow(AiWorkflowSaveReqVO updateReqVO) {
|
||||||
validateWorkflowForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getCode());
|
// 1. 参数校验
|
||||||
|
validateWorkflowExists(updateReqVO.getId());
|
||||||
|
validateCodeUnique(updateReqVO.getId(), updateReqVO.getCode());
|
||||||
|
|
||||||
|
// 2. 更新工作流配置
|
||||||
AiWorkflowDO workflow = BeanUtils.toBean(updateReqVO, AiWorkflowDO.class);
|
AiWorkflowDO workflow = BeanUtils.toBean(updateReqVO, AiWorkflowDO.class);
|
||||||
workflowMapper.updateById(workflow);
|
workflowMapper.updateById(workflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteWorkflow(Long id) {
|
public void deleteWorkflow(Long id) {
|
||||||
|
// 1. 校验存在
|
||||||
validateWorkflowExists(id);
|
validateWorkflowExists(id);
|
||||||
|
|
||||||
|
// 2. 删除工作流配置
|
||||||
workflowMapper.deleteById(id);
|
workflowMapper.deleteById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private AiWorkflowDO validateWorkflowExists(Long id) {
|
||||||
public AiWorkflowDO getWorkflow(Long id) {
|
|
||||||
return workflowMapper.selectById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PageResult<AiWorkflowDO> getWorkflowPage(AiWorkflowPageReqVO pageReqVO) {
|
|
||||||
return workflowMapper.selectPage(pageReqVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object testWorkflow(AiWorkflowTestReqVO testReqVO) {
|
|
||||||
Map<String, Object> variables = testReqVO.getParams();
|
|
||||||
Tinyflow tinyflow = parseFlowParam(testReqVO.getGraph());
|
|
||||||
return tinyflow.toChain().executeForResult(variables);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateWorkflowForCreateOrUpdate(Long id, String code) {
|
|
||||||
validateWorkflowExists(id);
|
|
||||||
validateCodeUnique(id, code);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateWorkflowExists(Long id) {
|
|
||||||
if (ObjUtil.isNull(id)) {
|
if (ObjUtil.isNull(id)) {
|
||||||
return;
|
throw exception(WORKFLOW_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
AiWorkflowDO workflow = workflowMapper.selectById(id);
|
AiWorkflowDO workflow = workflowMapper.selectById(id);
|
||||||
if (ObjUtil.isNull(workflow)) {
|
if (ObjUtil.isNull(workflow)) {
|
||||||
throw exception(WORKFLOW_NOT_EXISTS);
|
throw exception(WORKFLOW_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
|
return workflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateCodeUnique(Long id, String code) {
|
private void validateCodeUnique(Long id, String code) {
|
||||||
@ -108,6 +96,30 @@ public class AiWorkflowServiceImpl implements AiWorkflowService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AiWorkflowDO getWorkflow(Long id) {
|
||||||
|
return workflowMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<AiWorkflowDO> getWorkflowPage(AiWorkflowPageReqVO pageReqVO) {
|
||||||
|
return workflowMapper.selectPage(pageReqVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object testWorkflow(AiWorkflowTestReqVO testReqVO) {
|
||||||
|
// 加载 graph
|
||||||
|
String graph = testReqVO.getGraph() != null ? testReqVO.getGraph()
|
||||||
|
: validateWorkflowExists(testReqVO.getId()).getGraph();
|
||||||
|
|
||||||
|
// 构建 TinyFlow 执行链
|
||||||
|
Tinyflow tinyflow = parseFlowParam(graph);
|
||||||
|
|
||||||
|
// 执行
|
||||||
|
Map<String, Object> variables = testReqVO.getParams();
|
||||||
|
return tinyflow.toChain().executeForResult(variables);
|
||||||
|
}
|
||||||
|
|
||||||
private Tinyflow parseFlowParam(String graph) {
|
private Tinyflow parseFlowParam(String graph) {
|
||||||
// TODO @lesan:可以使用 jackson 哇?
|
// TODO @lesan:可以使用 jackson 哇?
|
||||||
JSONObject json = JSONObject.parseObject(graph);
|
JSONObject json = JSONObject.parseObject(graph);
|
||||||
@ -118,25 +130,7 @@ public class AiWorkflowServiceImpl implements AiWorkflowService {
|
|||||||
switch (node.getString("type")) {
|
switch (node.getString("type")) {
|
||||||
case "llmNode":
|
case "llmNode":
|
||||||
JSONObject data = node.getJSONObject("data");
|
JSONObject data = node.getJSONObject("data");
|
||||||
AiApiKeyDO apiKey = apiKeyService.getApiKey(data.getLong("llmId"));
|
apiModelService.getLLmProvider4Tinyflow(tinyflow, data.getLong("llmId"));
|
||||||
switch (apiKey.getPlatform()) {
|
|
||||||
// TODO @lesan 需要讨论一下这里怎么弄
|
|
||||||
// TODO @lesan llmId 对应 model 的编号如何?这样的话,就是 apiModelService 提供一个获取 LLM 的方法。然后,创建的方法,也在 AiModelFactory 提供。可以先接个 deepseek 先。deepseek yyds!
|
|
||||||
case "OpenAI":
|
|
||||||
break;
|
|
||||||
case "Ollama":
|
|
||||||
break;
|
|
||||||
case "YiYan":
|
|
||||||
break;
|
|
||||||
case "XingHuo":
|
|
||||||
break;
|
|
||||||
case "TongYi":
|
|
||||||
break;
|
|
||||||
case "DeepSeek":
|
|
||||||
break;
|
|
||||||
case "ZhiPu":
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case "internalNode":
|
case "internalNode":
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -76,7 +76,7 @@ public class AiWriteServiceImpl implements AiWriteService {
|
|||||||
? writeRole.getSystemMessage() : AiChatRoleEnum.AI_WRITE_ROLE.getSystemMessage();
|
? writeRole.getSystemMessage() : AiChatRoleEnum.AI_WRITE_ROLE.getSystemMessage();
|
||||||
// 1.3 校验平台
|
// 1.3 校验平台
|
||||||
AiPlatformEnum platform = AiPlatformEnum.validatePlatform(model.getPlatform());
|
AiPlatformEnum platform = AiPlatformEnum.validatePlatform(model.getPlatform());
|
||||||
StreamingChatModel chatModel = modalService.getChatModel(model.getKeyId());
|
StreamingChatModel chatModel = modalService.getChatModel(model.getId());
|
||||||
|
|
||||||
// 2. 插入写作信息
|
// 2. 插入写作信息
|
||||||
AiWriteDO writeDO = BeanUtils.toBean(generateReqVO, AiWriteDO.class, write -> write.setUserId(userId)
|
AiWriteDO writeDO = BeanUtils.toBean(generateReqVO, AiWriteDO.class, write -> write.setUserId(userId)
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
<description>AI 大模型拓展,接入国内外大模型</description>
|
<description>AI 大模型拓展,接入国内外大模型</description>
|
||||||
<properties>
|
<properties>
|
||||||
<spring-ai.version>1.0.0-M6</spring-ai.version>
|
<spring-ai.version>1.0.0-M6</spring-ai.version>
|
||||||
<tinyflow.version>1.0.0-rc.3</tinyflow.version>
|
<tinyflow.version>1.0.2</tinyflow.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -24,6 +24,18 @@
|
|||||||
<artifactId>yudao-common</artifactId>
|
<artifactId>yudao-common</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 业务组件 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.qqchen.cloud</groupId>
|
||||||
|
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Web 相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.qqchen.cloud</groupId>
|
||||||
|
<artifactId>yudao-spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Spring AI Model 模型接入 -->
|
<!-- Spring AI Model 模型接入 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.ai</groupId>
|
<groupId>org.springframework.ai</groupId>
|
||||||
@ -98,6 +110,13 @@
|
|||||||
<groupId>org.springframework.ai</groupId>
|
<groupId>org.springframework.ai</groupId>
|
||||||
<artifactId>spring-ai-milvus-store</artifactId>
|
<artifactId>spring-ai-milvus-store</artifactId>
|
||||||
<version>${spring-ai.version}</version>
|
<version>${spring-ai.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<!-- 解决和 logback 的日志冲突 -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-reload4j</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -113,6 +132,10 @@
|
|||||||
<artifactId>tinyflow-java-core</artifactId>
|
<artifactId>tinyflow-java-core</artifactId>
|
||||||
<version>${tinyflow.version}</version>
|
<version>${tinyflow.version}</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>com.jfinal</groupId>
|
||||||
|
<artifactId>enjoy</artifactId>
|
||||||
|
</exclusion>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<!-- 解决 https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1318/ 问题 -->
|
<!-- 解决 https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1318/ 问题 -->
|
||||||
<groupId>com.agentsflex</groupId>
|
<groupId>com.agentsflex</groupId>
|
||||||
@ -123,6 +146,19 @@
|
|||||||
<groupId>org.codehaus.groovy</groupId>
|
<groupId>org.codehaus.groovy</groupId>
|
||||||
<artifactId>groovy-all</artifactId>
|
<artifactId>groovy-all</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
|
<!-- 解决和 logback 的日志冲突 -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-simple</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-slf4j-impl</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-reload4j</artifactId>
|
||||||
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,8 @@ package cn.iocoder.yudao.framework.ai.core.util;
|
|||||||
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum;
|
import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum;
|
||||||
|
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||||
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
|
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
|
||||||
import org.springframework.ai.azure.openai.AzureOpenAiChatOptions;
|
import org.springframework.ai.azure.openai.AzureOpenAiChatOptions;
|
||||||
import org.springframework.ai.chat.messages.*;
|
import org.springframework.ai.chat.messages.*;
|
||||||
@ -15,6 +17,8 @@ import org.springframework.ai.qianfan.QianFanChatOptions;
|
|||||||
import org.springframework.ai.zhipuai.ZhiPuAiChatOptions;
|
import org.springframework.ai.zhipuai.ZhiPuAiChatOptions;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,29 +28,32 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
public class AiUtils {
|
public class AiUtils {
|
||||||
|
|
||||||
|
public static final String TOOL_CONTEXT_LOGIN_USER = "LOGIN_USER";
|
||||||
|
public static final String TOOL_CONTEXT_TENANT_ID = "TENANT_ID";
|
||||||
|
|
||||||
public static ChatOptions buildChatOptions(AiPlatformEnum platform, String model, Double temperature, Integer maxTokens) {
|
public static ChatOptions buildChatOptions(AiPlatformEnum platform, String model, Double temperature, Integer maxTokens) {
|
||||||
return buildChatOptions(platform, model, temperature, maxTokens, null);
|
return buildChatOptions(platform, model, temperature, maxTokens, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChatOptions buildChatOptions(AiPlatformEnum platform, String model, Double temperature, Integer maxTokens,
|
public static ChatOptions buildChatOptions(AiPlatformEnum platform, String model, Double temperature, Integer maxTokens,
|
||||||
Set<String> toolNames) {
|
Set<String> toolNames, Map<String, Object> toolContext) {
|
||||||
toolNames = ObjUtil.defaultIfNull(toolNames, Collections.emptySet());
|
toolNames = ObjUtil.defaultIfNull(toolNames, Collections.emptySet());
|
||||||
// noinspection EnhancedSwitchMigration
|
// noinspection EnhancedSwitchMigration
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
case TONG_YI:
|
case TONG_YI:
|
||||||
return DashScopeChatOptions.builder().withModel(model).withTemperature(temperature).withMaxToken(maxTokens)
|
return DashScopeChatOptions.builder().withModel(model).withTemperature(temperature).withMaxToken(maxTokens)
|
||||||
.withFunctions(toolNames).build();
|
.withFunctions(toolNames).withToolContext(toolContext).build();
|
||||||
case YI_YAN:
|
case YI_YAN:
|
||||||
return QianFanChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build();
|
return QianFanChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build();
|
||||||
case ZHI_PU:
|
case ZHI_PU:
|
||||||
return ZhiPuAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
|
return ZhiPuAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
|
||||||
.functions(toolNames).build();
|
.functions(toolNames).toolContext(toolContext).build();
|
||||||
case MINI_MAX:
|
case MINI_MAX:
|
||||||
return MiniMaxChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
|
return MiniMaxChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
|
||||||
.functions(toolNames).build();
|
.functions(toolNames).toolContext(toolContext).build();
|
||||||
case MOONSHOT:
|
case MOONSHOT:
|
||||||
return MoonshotChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
|
return MoonshotChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
|
||||||
.functions(toolNames).build();
|
.functions(toolNames).toolContext(toolContext).build();
|
||||||
case OPENAI:
|
case OPENAI:
|
||||||
case DEEP_SEEK: // 复用 OpenAI 客户端
|
case DEEP_SEEK: // 复用 OpenAI 客户端
|
||||||
case DOU_BAO: // 复用 OpenAI 客户端
|
case DOU_BAO: // 复用 OpenAI 客户端
|
||||||
@ -55,14 +62,13 @@ public class AiUtils {
|
|||||||
case SILICON_FLOW: // 复用 OpenAI 客户端
|
case SILICON_FLOW: // 复用 OpenAI 客户端
|
||||||
case BAI_CHUAN: // 复用 OpenAI 客户端
|
case BAI_CHUAN: // 复用 OpenAI 客户端
|
||||||
return OpenAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
|
return OpenAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
|
||||||
.toolNames(toolNames).build();
|
.toolNames(toolNames).toolContext(toolContext).build();
|
||||||
case AZURE_OPENAI:
|
case AZURE_OPENAI:
|
||||||
// TODO 芋艿:貌似没 model 字段???!
|
|
||||||
return AzureOpenAiChatOptions.builder().deploymentName(model).temperature(temperature).maxTokens(maxTokens)
|
return AzureOpenAiChatOptions.builder().deploymentName(model).temperature(temperature).maxTokens(maxTokens)
|
||||||
.toolNames(toolNames).build();
|
.toolNames(toolNames).toolContext(toolContext).build();
|
||||||
case OLLAMA:
|
case OLLAMA:
|
||||||
return OllamaOptions.builder().model(model).temperature(temperature).numPredict(maxTokens)
|
return OllamaOptions.builder().model(model).temperature(temperature).numPredict(maxTokens)
|
||||||
.toolNames(toolNames).build();
|
.toolNames(toolNames).toolContext(toolContext).build();
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform));
|
throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform));
|
||||||
}
|
}
|
||||||
@ -84,4 +90,11 @@ public class AiUtils {
|
|||||||
throw new IllegalArgumentException(StrUtil.format("未知消息类型({})", type));
|
throw new IllegalArgumentException(StrUtil.format("未知消息类型({})", type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> buildCommonToolContext() {
|
||||||
|
Map<String, Object> context = new HashMap<>();
|
||||||
|
context.put(TOOL_CONTEXT_LOGIN_USER, SecurityFrameworkUtils.getLoginUser());
|
||||||
|
context.put(TOOL_CONTEXT_TENANT_ID, TenantContextHolder.getTenantId());
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
package cn.iocoder.yudao.framework.ai.chat;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.ai.chat.messages.Message;
|
||||||
|
import org.springframework.ai.chat.messages.SystemMessage;
|
||||||
|
import org.springframework.ai.chat.messages.UserMessage;
|
||||||
|
import org.springframework.ai.chat.model.ChatResponse;
|
||||||
|
import org.springframework.ai.chat.prompt.Prompt;
|
||||||
|
import org.springframework.ai.openai.OpenAiChatModel;
|
||||||
|
import org.springframework.ai.openai.api.OpenAiApi;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基于 {@link OpenAiChatModel} 集成 Coze 测试
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public class CozeChatModelTests {
|
||||||
|
|
||||||
|
private final OpenAiChatModel chatModel = OpenAiChatModel.builder()
|
||||||
|
.openAiApi(OpenAiApi.builder()
|
||||||
|
.baseUrl("http://127.0.0.1:3000")
|
||||||
|
.apiKey("app-4hy2d7fJauSbrKbzTKX1afuP") // apiKey
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Disabled
|
||||||
|
public void testCall() {
|
||||||
|
// 准备参数
|
||||||
|
List<Message> messages = new ArrayList<>();
|
||||||
|
messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
|
||||||
|
messages.add(new UserMessage("1 + 1 = ?"));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
ChatResponse response = chatModel.call(new Prompt(messages));
|
||||||
|
// 打印结果
|
||||||
|
System.out.println(response);
|
||||||
|
System.out.println(response.getResult().getOutput());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Disabled
|
||||||
|
public void testStream() {
|
||||||
|
// 准备参数
|
||||||
|
List<Message> messages = new ArrayList<>();
|
||||||
|
messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
|
||||||
|
messages.add(new UserMessage("1 + 1 = ?"));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages));
|
||||||
|
// 打印结果
|
||||||
|
flux.doOnNext(response -> {
|
||||||
|
// System.out.println(response);
|
||||||
|
System.out.println(response.getResult().getOutput());
|
||||||
|
}).then().block();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ import cn.hutool.core.map.MapUtil;
|
|||||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
|
import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
|
||||||
@ -53,6 +54,7 @@ public interface BpmTaskConvert {
|
|||||||
taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class));
|
taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class));
|
||||||
AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
|
AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
|
||||||
taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class));
|
taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class));
|
||||||
|
taskVO.getProcessInstance().setCreateTime(DateUtils.of(processInstance.getStartTime()));
|
||||||
// 摘要
|
// 摘要
|
||||||
taskVO.getProcessInstance().setSummary(FlowableUtils.getSummary(processDefinitionInfoMap.get(processInstance.getProcessDefinitionId()),
|
taskVO.getProcessInstance().setSummary(FlowableUtils.getSummary(processDefinitionInfoMap.get(processInstance.getProcessDefinitionId()),
|
||||||
processInstance.getProcessVariables()));
|
processInstance.getProcessVariables()));
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import org.flowable.bpmn.model.UserTask;
|
|||||||
import org.flowable.engine.delegate.DelegateExecution;
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
|
import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
|
||||||
import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
|
import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
|
||||||
|
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -82,4 +83,13 @@ public class BpmSequentialMultiInstanceBehavior extends SequentialMultiInstanceB
|
|||||||
return super.resolveNrOfInstances(execution);
|
return super.resolveNrOfInstances(execution);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void executeOriginalBehavior(DelegateExecution execution, ExecutionEntity multiInstanceRootExecution, int loopCounter) {
|
||||||
|
// 参见 https://gitee.com/zhijiantianya/yudao-cloud/issues/IC239F
|
||||||
|
super.collectionExpression = null;
|
||||||
|
super.collectionVariable = FlowableUtils.formatExecutionCollectionVariable(execution.getCurrentActivityId());
|
||||||
|
super.collectionElementVariable = FlowableUtils.formatExecutionCollectionElementVariable(execution.getCurrentActivityId());
|
||||||
|
super.executeOriginalBehavior(execution, multiInstanceRootExecution, loopCounter);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.form;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.form;
|
||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user.BpmTaskCandidateUserStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user.BpmTaskCandidateUserStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
@ -33,7 +33,7 @@ public class BpmTaskCandidateFormUserStrategy implements BpmTaskCandidateStrateg
|
|||||||
@Override
|
@Override
|
||||||
public Set<Long> calculateUsersByTask(DelegateExecution execution, String param) {
|
public Set<Long> calculateUsersByTask(DelegateExecution execution, String param) {
|
||||||
Object result = execution.getVariable(param);
|
Object result = execution.getVariable(param);
|
||||||
return Convert.toSet(Long.class, result);
|
return CollectionUtils.toLinkedHashSet(Long.class, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -41,7 +41,7 @@ public class BpmTaskCandidateFormUserStrategy implements BpmTaskCandidateStrateg
|
|||||||
String param, Long startUserId, String processDefinitionId,
|
String param, Long startUserId, String processDefinitionId,
|
||||||
Map<String, Object> processVariables) {
|
Map<String, Object> processVariables) {
|
||||||
Object result = processVariables == null ? null : processVariables.get(param);
|
Object result = processVariables == null ? null : processVariables.get(param);
|
||||||
return Convert.toSet(Long.class, result);
|
return CollectionUtils.toLinkedHashSet(Long.class, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.other;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.other;
|
||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||||
@ -37,7 +37,7 @@ public class BpmTaskCandidateExpressionStrategy implements BpmTaskCandidateStrat
|
|||||||
@Override
|
@Override
|
||||||
public Set<Long> calculateUsersByTask(DelegateExecution execution, String param) {
|
public Set<Long> calculateUsersByTask(DelegateExecution execution, String param) {
|
||||||
Object result = FlowableUtils.getExpressionValue(execution, param);
|
Object result = FlowableUtils.getExpressionValue(execution, param);
|
||||||
return Convert.toSet(Long.class, result);
|
return CollectionUtils.toLinkedHashSet(Long.class, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -46,7 +46,7 @@ public class BpmTaskCandidateExpressionStrategy implements BpmTaskCandidateStrat
|
|||||||
Map<String, Object> variables = processVariables == null ? new HashMap<>() : processVariables;
|
Map<String, Object> variables = processVariables == null ? new HashMap<>() : processVariables;
|
||||||
try {
|
try {
|
||||||
Object result = FlowableUtils.getExpressionValue(variables, param);
|
Object result = FlowableUtils.getExpressionValue(variables, param);
|
||||||
return Convert.toSet(Long.class, result);
|
return CollectionUtils.toLinkedHashSet(Long.class, result);
|
||||||
} catch (FlowableException ex) {
|
} catch (FlowableException ex) {
|
||||||
// 预测未运行的节点时候,表达式如果包含 execution 或者不存在的流程变量会抛异常,
|
// 预测未运行的节点时候,表达式如果包含 execution 或者不存在的流程变量会抛异常,
|
||||||
log.warn("[calculateUsersByActivity][表达式({}) 变量({}) 解析报错", param, variables, ex);
|
log.warn("[calculateUsersByActivity][表达式({}) 变量({}) 解析报错", param, variables, ex);
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|||||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(value = "bpmRpcConfiguration", proxyBeanMethods = false)
|
||||||
@EnableFeignClients(clients = {RoleApi.class, DeptApi.class, PostApi.class, AdminUserApi.class, SmsSendApi.class, DictDataApi.class})
|
@EnableFeignClients(clients = {RoleApi.class, DeptApi.class, PostApi.class, AdminUserApi.class, SmsSendApi.class, DictDataApi.class})
|
||||||
public class RpcConfiguration {
|
public class RpcConfiguration {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -597,6 +597,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
* @param nextAssignees 下一个节点审批人集合(参数)
|
* @param nextAssignees 下一个节点审批人集合(参数)
|
||||||
* @param processInstance 流程实例
|
* @param processInstance 流程实例
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private Map<String, Object> validateAndSetNextAssignees(String taskDefinitionKey, Map<String, Object> variables, BpmnModel bpmnModel,
|
private Map<String, Object> validateAndSetNextAssignees(String taskDefinitionKey, Map<String, Object> variables, BpmnModel bpmnModel,
|
||||||
Map<String, List<Long>> nextAssignees, ProcessInstance processInstance) {
|
Map<String, List<Long>> nextAssignees, ProcessInstance processInstance) {
|
||||||
// simple 设计器第一个节点默认为发起人节点,不校验是否存在审批人
|
// simple 设计器第一个节点默认为发起人节点,不校验是否存在审批人
|
||||||
@ -646,6 +647,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
approveUserSelectAssignees = new HashMap<>();
|
approveUserSelectAssignees = new HashMap<>();
|
||||||
}
|
}
|
||||||
approveUserSelectAssignees.put(nextFlowNode.getId(), assignees);
|
approveUserSelectAssignees.put(nextFlowNode.getId(), assignees);
|
||||||
|
Map<String,List<Long>> existingApproveUserSelectAssignees = (Map<String,List<Long>>) variables.get(
|
||||||
|
BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES);
|
||||||
|
if (CollUtil.isNotEmpty(existingApproveUserSelectAssignees)) {
|
||||||
|
approveUserSelectAssignees.putAll(existingApproveUserSelectAssignees);
|
||||||
|
}
|
||||||
variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES, approveUserSelectAssignees);
|
variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES, approveUserSelectAssignees);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -873,12 +879,14 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
List<UserTask> returnUserTaskList = BpmnModelUtils.iteratorFindChildUserTasks(targetElement, runTaskKeyList, null, null);
|
List<UserTask> returnUserTaskList = BpmnModelUtils.iteratorFindChildUserTasks(targetElement, runTaskKeyList, null, null);
|
||||||
List<String> returnTaskKeyList = convertList(returnUserTaskList, UserTask::getId);
|
List<String> returnTaskKeyList = convertList(returnUserTaskList, UserTask::getId);
|
||||||
|
|
||||||
|
List<String> runExecutionIds = new ArrayList<>();
|
||||||
// 2. 给当前要被退回的 task 数组,设置退回意见
|
// 2. 给当前要被退回的 task 数组,设置退回意见
|
||||||
taskList.forEach(task -> {
|
taskList.forEach(task -> {
|
||||||
// 需要排除掉,不需要设置退回意见的任务
|
// 需要排除掉,不需要设置退回意见的任务
|
||||||
if (!returnTaskKeyList.contains(task.getTaskDefinitionKey())) {
|
if (!returnTaskKeyList.contains(task.getTaskDefinitionKey())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
runExecutionIds.add(task.getExecutionId());
|
||||||
|
|
||||||
// 判断是否分配给自己任务,因为会签任务,一个节点会有多个任务
|
// 判断是否分配给自己任务,因为会签任务,一个节点会有多个任务
|
||||||
if (isAssignUserTask(userId, task)) { // 情况一:自己的任务,进行 RETURN 标记
|
if (isAssignUserTask(userId, task)) { // 情况一:自己的任务,进行 RETURN 标记
|
||||||
@ -898,7 +906,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
// 4. 执行驳回
|
// 4. 执行驳回
|
||||||
// 使用 moveExecutionsToSingleActivityId 替换 moveActivityIdsToSingleActivityId 原因:
|
// 使用 moveExecutionsToSingleActivityId 替换 moveActivityIdsToSingleActivityId 原因:
|
||||||
// 当多实例任务回退的时候有问题。相关 issue: https://github.com/flowable/flowable-engine/issues/3944
|
// 当多实例任务回退的时候有问题。相关 issue: https://github.com/flowable/flowable-engine/issues/3944
|
||||||
List<String> runExecutionIds = convertList(taskList, Task::getExecutionId);
|
|
||||||
runtimeService.createChangeActivityStateBuilder()
|
runtimeService.createChangeActivityStateBuilder()
|
||||||
.processInstanceId(currentTask.getProcessInstanceId())
|
.processInstanceId(currentTask.getProcessInstanceId())
|
||||||
.moveExecutionsToSingleActivityId(runExecutionIds, reqVO.getTargetTaskDefinitionKey())
|
.moveExecutionsToSingleActivityId(runExecutionIds, reqVO.getTargetTaskDefinitionKey())
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|||||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(value = "crmRpcConfiguration", proxyBeanMethods = false)
|
||||||
@EnableFeignClients(clients = {AdminUserApi.class, DeptApi.class, PostApi.class,
|
@EnableFeignClients(clients = {AdminUserApi.class, DeptApi.class, PostApi.class,
|
||||||
BpmProcessInstanceApi.class})
|
BpmProcessInstanceApi.class})
|
||||||
public class RpcConfiguration {
|
public class RpcConfiguration {
|
||||||
|
|||||||
@ -214,7 +214,7 @@ public class CrmContactServiceImpl implements CrmContactService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_UPDATE_OWNER_USER_SUB_TYPE, bizNo = "{{#contact.id}",
|
@LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_UPDATE_OWNER_USER_SUB_TYPE, bizNo = "{{#contact.id}}",
|
||||||
success = CRM_CONTACT_UPDATE_OWNER_USER_SUCCESS)
|
success = CRM_CONTACT_UPDATE_OWNER_USER_SUCCESS)
|
||||||
public void receiveContactLog(CrmContactDO contact, Long ownerUserId) {
|
public void receiveContactLog(CrmContactDO contact, Long ownerUserId) {
|
||||||
// 记录操作日志上下文
|
// 记录操作日志上下文
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|||||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(value = "erpRpcConfiguration", proxyBeanMethods = false)
|
||||||
@EnableFeignClients(clients = AdminUserApi.class)
|
@EnableFeignClients(clients = AdminUserApi.class)
|
||||||
public class RpcConfiguration {
|
public class RpcConfiguration {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,14 +3,13 @@ package cn.iocoder.yudao.module.infra.api.file;
|
|||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.module.infra.api.file.dto.FileCreateReqDTO;
|
import cn.iocoder.yudao.module.infra.api.file.dto.FileCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.infra.enums.ApiConstants;
|
import cn.iocoder.yudao.module.infra.enums.ApiConstants;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
|
||||||
|
|
||||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||||
@Tag(name = "RPC 服务 - 文件")
|
@Tag(name = "RPC 服务 - 文件")
|
||||||
@ -25,32 +24,32 @@ public interface FileApi {
|
|||||||
* @return 文件路径
|
* @return 文件路径
|
||||||
*/
|
*/
|
||||||
default String createFile(byte[] content) {
|
default String createFile(byte[] content) {
|
||||||
return createFile(null, null, content);
|
return createFile(content, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存文件,并返回文件的访问路径
|
* 保存文件,并返回文件的访问路径
|
||||||
*
|
*
|
||||||
* @param path 文件路径
|
|
||||||
* @param content 文件内容
|
* @param content 文件内容
|
||||||
|
* @param name 文件名称,允许空
|
||||||
* @return 文件路径
|
* @return 文件路径
|
||||||
*/
|
*/
|
||||||
default String createFile(String path, byte[] content) {
|
default String createFile(byte[] content, String name) {
|
||||||
return createFile(null, path, content);
|
return createFile(content, name, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存文件,并返回文件的访问路径
|
* 保存文件,并返回文件的访问路径
|
||||||
*
|
*
|
||||||
* @param name 原文件名称
|
|
||||||
* @param path 文件路径
|
|
||||||
* @param content 文件内容
|
* @param content 文件内容
|
||||||
|
* @param name 文件名称,允许空
|
||||||
|
* @param directory 目录,允许空
|
||||||
|
* @param type 文件的 MIME 类型,允许空
|
||||||
* @return 文件路径
|
* @return 文件路径
|
||||||
*/
|
*/
|
||||||
default String createFile(@RequestParam("name") String name,
|
default String createFile(@NotEmpty(message = "文件内容不能为空") byte[] content,
|
||||||
@RequestParam("path") String path,
|
String name, String directory, String type) {
|
||||||
@RequestParam("content") byte[] content) {
|
return createFile(new FileCreateReqDTO().setName(name).setDirectory(directory).setType(type).setContent(content)).getCheckedData();
|
||||||
return createFile(new FileCreateReqDTO().setName(name).setPath(path).setContent(content)).getCheckedData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(PREFIX + "/create")
|
@PostMapping(PREFIX + "/create")
|
||||||
|
|||||||
@ -12,8 +12,11 @@ public class FileCreateReqDTO {
|
|||||||
@Schema(description = "原文件名称", example = "xxx.png")
|
@Schema(description = "原文件名称", example = "xxx.png")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Schema(description = "文件路径", example = "xxx.png")
|
@Schema(description = "文件目录", example = "xxx")
|
||||||
private String path;
|
private String directory;
|
||||||
|
|
||||||
|
@Schema(description = "文件的 MIME 类型", example = "image/png")
|
||||||
|
private String type;
|
||||||
|
|
||||||
@Schema(description = "文件内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "文件内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
@NotEmpty(message = "文件内容不能为空")
|
@NotEmpty(message = "文件内容不能为空")
|
||||||
|
|||||||
@ -138,8 +138,8 @@
|
|||||||
<artifactId>jsch</artifactId> <!-- 文件客户端:解决 sftp 连接 -->
|
<artifactId>jsch</artifactId> <!-- 文件客户端:解决 sftp 连接 -->
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.amazonaws</groupId>
|
<groupId>software.amazon.awssdk</groupId> <!-- 文件客户端:解决阿里云、腾讯云、minio 等 S3 连接 -->
|
||||||
<artifactId>aws-java-sdk-s3</artifactId><!-- 文件客户端:解决阿里云、腾讯云、minio 等 S3 连接 -->
|
<artifactId>s3</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@ -19,8 +19,8 @@ public class FileApiImpl implements FileApi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<String> createFile(FileCreateReqDTO createReqDTO) {
|
public CommonResult<String> createFile(FileCreateReqDTO createReqDTO) {
|
||||||
return success(fileService.createFile(createReqDTO.getName(), createReqDTO.getPath(),
|
return success(fileService.createFile(createReqDTO.getContent(), createReqDTO.getName(),
|
||||||
createReqDTO.getContent()));
|
createReqDTO.getDirectory(), createReqDTO.getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,11 +6,13 @@ import cn.hutool.core.util.URLUtil;
|
|||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.*;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.*;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
||||||
import cn.iocoder.yudao.module.infra.service.file.FileService;
|
import cn.iocoder.yudao.module.infra.service.file.FileService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameters;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.annotation.security.PermitAll;
|
import jakarta.annotation.security.PermitAll;
|
||||||
@ -41,14 +43,21 @@ public class FileController {
|
|||||||
@Operation(summary = "上传文件", description = "模式一:后端上传文件")
|
@Operation(summary = "上传文件", description = "模式一:后端上传文件")
|
||||||
public CommonResult<String> uploadFile(FileUploadReqVO uploadReqVO) throws Exception {
|
public CommonResult<String> uploadFile(FileUploadReqVO uploadReqVO) throws Exception {
|
||||||
MultipartFile file = uploadReqVO.getFile();
|
MultipartFile file = uploadReqVO.getFile();
|
||||||
String path = uploadReqVO.getPath();
|
byte[] content = IoUtil.readBytes(file.getInputStream());
|
||||||
return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
|
return success(fileService.createFile(content, file.getOriginalFilename(),
|
||||||
|
uploadReqVO.getDirectory(), file.getContentType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/presigned-url")
|
@GetMapping("/presigned-url")
|
||||||
@Operation(summary = "获取文件预签名地址", description = "模式二:前端上传文件:用于前端直接上传七牛、阿里云 OSS 等文件存储器")
|
@Operation(summary = "获取文件预签名地址", description = "模式二:前端上传文件:用于前端直接上传七牛、阿里云 OSS 等文件存储器")
|
||||||
public CommonResult<FilePresignedUrlRespVO> getFilePresignedUrl(@RequestParam("path") String path) throws Exception {
|
@Parameters({
|
||||||
return success(fileService.getFilePresignedUrl(path));
|
@Parameter(name = "name", description = "文件名称", required = true),
|
||||||
|
@Parameter(name = "directory", description = "文件目录")
|
||||||
|
})
|
||||||
|
public CommonResult<FilePresignedUrlRespVO> getFilePresignedUrl(
|
||||||
|
@RequestParam("name") String name,
|
||||||
|
@RequestParam(value = "directory", required = false) String directory) {
|
||||||
|
return success(fileService.getFilePresignedUrl(name, directory));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@ -68,6 +77,7 @@ public class FileController {
|
|||||||
|
|
||||||
@GetMapping("/{configId}/get/**")
|
@GetMapping("/{configId}/get/**")
|
||||||
@PermitAll
|
@PermitAll
|
||||||
|
@TenantIgnore
|
||||||
@Operation(summary = "下载文件")
|
@Operation(summary = "下载文件")
|
||||||
@Parameter(name = "configId", description = "配置编号", required = true)
|
@Parameter(name = "configId", description = "配置编号", required = true)
|
||||||
public void getFileContent(HttpServletRequest request,
|
public void getFileContent(HttpServletRequest request,
|
||||||
|
|||||||
@ -14,7 +14,8 @@ public class FilePresignedUrlRespVO {
|
|||||||
@Schema(description = "配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11")
|
@Schema(description = "配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11")
|
||||||
private Long configId;
|
private Long configId;
|
||||||
|
|
||||||
@Schema(description = "文件上传 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://s3.cn-south-1.qiniucs.com/ruoyi-vue-pro/758d3a5387507358c7236de4c8f96de1c7f5097ff6a7722b34772fb7b76b140f.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=3TvrJ70gl2Gt6IBe7_IZT1F6i_k0iMuRtyEv4EyS%2F20240217%2Fcn-south-1%2Fs3%2Faws4_request&X-Amz-Date=20240217T123222Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Signature=a29f33770ab79bf523ccd4034d0752ac545f3c2a3b17baa1eb4e280cfdccfda5")
|
@Schema(description = "文件上传 URL", requiredMode = Schema.RequiredMode.REQUIRED,
|
||||||
|
example = "https://s3.cn-south-1.qiniucs.com/ruoyi-vue-pro/758d3a5387507358c7236de4c8f96de1c7f5097ff6a7722b34772fb7b76b140f.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=3TvrJ70gl2Gt6IBe7_IZT1F6i_k0iMuRtyEv4EyS%2F20240217%2Fcn-south-1%2Fs3%2Faws4_request&X-Amz-Date=20240217T123222Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Signature=a29f33770ab79bf523ccd4034d0752ac545f3c2a3b17baa1eb4e280cfdccfda5")
|
||||||
private String uploadUrl;
|
private String uploadUrl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,4 +27,12 @@ public class FilePresignedUrlRespVO {
|
|||||||
example = "https://test.yudao.iocoder.cn/758d3a5387507358c7236de4c8f96de1c7f5097ff6a7722b34772fb7b76b140f.png")
|
example = "https://test.yudao.iocoder.cn/758d3a5387507358c7236de4c8f96de1c7f5097ff6a7722b34772fb7b76b140f.png")
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为什么要返回 path 字段?
|
||||||
|
*
|
||||||
|
* 前端上传完文件后,需要调用 createFile 记录下 path 路径
|
||||||
|
*/
|
||||||
|
@Schema(description = "文件路径", requiredMode = Schema.RequiredMode.REQUIRED, example = "xxx.png")
|
||||||
|
private String path;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ public class FileUploadReqVO {
|
|||||||
@NotNull(message = "文件附件不能为空")
|
@NotNull(message = "文件附件不能为空")
|
||||||
private MultipartFile file;
|
private MultipartFile file;
|
||||||
|
|
||||||
@Schema(description = "文件附件", example = "yudaoyuanma.png")
|
@Schema(description = "文件目录", example = "XXX/YYY")
|
||||||
private String path;
|
private String directory;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePresigned
|
|||||||
import cn.iocoder.yudao.module.infra.controller.app.file.vo.AppFileUploadReqVO;
|
import cn.iocoder.yudao.module.infra.controller.app.file.vo.AppFileUploadReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.service.file.FileService;
|
import cn.iocoder.yudao.module.infra.service.file.FileService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameters;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.annotation.security.PermitAll;
|
import jakarta.annotation.security.PermitAll;
|
||||||
@ -33,15 +35,21 @@ public class AppFileController {
|
|||||||
@PermitAll
|
@PermitAll
|
||||||
public CommonResult<String> uploadFile(AppFileUploadReqVO uploadReqVO) throws Exception {
|
public CommonResult<String> uploadFile(AppFileUploadReqVO uploadReqVO) throws Exception {
|
||||||
MultipartFile file = uploadReqVO.getFile();
|
MultipartFile file = uploadReqVO.getFile();
|
||||||
String path = uploadReqVO.getPath();
|
byte[] content = IoUtil.readBytes(file.getInputStream());
|
||||||
return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
|
return success(fileService.createFile(content, file.getOriginalFilename(),
|
||||||
|
uploadReqVO.getDirectory(), file.getContentType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/presigned-url")
|
@GetMapping("/presigned-url")
|
||||||
@Operation(summary = "获取文件预签名地址", description = "模式二:前端上传文件:用于前端直接上传七牛、阿里云 OSS 等文件存储器")
|
@Operation(summary = "获取文件预签名地址", description = "模式二:前端上传文件:用于前端直接上传七牛、阿里云 OSS 等文件存储器")
|
||||||
@PermitAll
|
@Parameters({
|
||||||
public CommonResult<FilePresignedUrlRespVO> getFilePresignedUrl(@RequestParam("path") String path) throws Exception {
|
@Parameter(name = "name", description = "文件名称", required = true),
|
||||||
return success(fileService.getFilePresignedUrl(path));
|
@Parameter(name = "directory", description = "文件目录")
|
||||||
|
})
|
||||||
|
public CommonResult<FilePresignedUrlRespVO> getFilePresignedUrl(
|
||||||
|
@RequestParam("name") String name,
|
||||||
|
@RequestParam(value = "directory", required = false) String directory) {
|
||||||
|
return success(fileService.getFilePresignedUrl(name, directory));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
|
|||||||
@ -14,7 +14,7 @@ public class AppFileUploadReqVO {
|
|||||||
@NotNull(message = "文件附件不能为空")
|
@NotNull(message = "文件附件不能为空")
|
||||||
private MultipartFile file;
|
private MultipartFile file;
|
||||||
|
|
||||||
@Schema(description = "文件附件", example = "yudaoyuanma.png")
|
@Schema(description = "文件目录", example = "XXX/YYY")
|
||||||
private String path;
|
private String directory;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.infra.dal.dataobject.codegen;
|
package cn.iocoder.yudao.module.infra.dal.dataobject.codegen;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnHtmlTypeEnum;
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnHtmlTypeEnum;
|
||||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnListConditionEnum;
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnListConditionEnum;
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
@ -21,6 +22,7 @@ import lombok.experimental.Accessors;
|
|||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TenantIgnore
|
||||||
public class CodegenColumnDO extends BaseDO {
|
public class CodegenColumnDO extends BaseDO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.infra.dal.dataobject.codegen;
|
package cn.iocoder.yudao.module.infra.dal.dataobject.codegen;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
|
||||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
||||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
||||||
@ -23,6 +24,7 @@ import lombok.experimental.Accessors;
|
|||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TenantIgnore
|
||||||
public class CodegenTableDO extends BaseDO {
|
public class CodegenTableDO extends BaseDO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.infra.dal.dataobject.config;
|
package cn.iocoder.yudao.module.infra.dal.dataobject.config;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||||
import cn.iocoder.yudao.module.infra.enums.config.ConfigTypeEnum;
|
import cn.iocoder.yudao.module.infra.enums.config.ConfigTypeEnum;
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
@ -19,6 +20,7 @@ import lombok.ToString;
|
|||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
|
@TenantIgnore
|
||||||
public class ConfigDO extends BaseDO {
|
public class ConfigDO extends BaseDO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.db;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.type.EncryptTypeHandler;
|
import cn.iocoder.yudao.framework.mybatis.core.type.EncryptTypeHandler;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
@ -15,6 +16,7 @@ import lombok.Data;
|
|||||||
@TableName(value = "infra_data_source_config", autoResultMap = true)
|
@TableName(value = "infra_data_source_config", autoResultMap = true)
|
||||||
@KeySequence("infra_data_source_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
@KeySequence("infra_data_source_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
@Data
|
@Data
|
||||||
|
@TenantIgnore
|
||||||
public class DataSourceConfigDO extends BaseDO {
|
public class DataSourceConfigDO extends BaseDO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.file;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||||
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig;
|
||||||
import cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClientConfig;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClientConfig;
|
||||||
import cn.iocoder.yudao.module.infra.framework.file.core.client.ftp.FtpFileClientConfig;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.ftp.FtpFileClientConfig;
|
||||||
@ -32,6 +33,7 @@ import java.lang.reflect.Field;
|
|||||||
@Builder
|
@Builder
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@TenantIgnore
|
||||||
public class FileConfigDO extends BaseDO {
|
public class FileConfigDO extends BaseDO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
package cn.iocoder.yudao.module.infra.dal.dataobject.file;
|
package cn.iocoder.yudao.module.infra.dal.dataobject.file;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||||
import cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClient;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClient;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
@ -23,6 +23,7 @@ import lombok.*;
|
|||||||
@Builder
|
@Builder
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@TenantIgnore
|
||||||
public class FileContentDO extends BaseDO {
|
public class FileContentDO extends BaseDO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.infra.dal.dataobject.file;
|
package cn.iocoder.yudao.module.infra.dal.dataobject.file;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
@ -19,6 +20,7 @@ import lombok.*;
|
|||||||
@Builder
|
@Builder
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@TenantIgnore
|
||||||
public class FileDO extends BaseDO {
|
public class FileDO extends BaseDO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -19,7 +19,8 @@ public interface ConfigMapper extends BaseMapperX<ConfigDO> {
|
|||||||
.likeIfPresent(ConfigDO::getName, reqVO.getName())
|
.likeIfPresent(ConfigDO::getName, reqVO.getName())
|
||||||
.likeIfPresent(ConfigDO::getConfigKey, reqVO.getKey())
|
.likeIfPresent(ConfigDO::getConfigKey, reqVO.getKey())
|
||||||
.eqIfPresent(ConfigDO::getType, reqVO.getType())
|
.eqIfPresent(ConfigDO::getType, reqVO.getType())
|
||||||
.betweenIfPresent(ConfigDO::getCreateTime, reqVO.getCreateTime()));
|
.betweenIfPresent(ConfigDO::getCreateTime, reqVO.getCreateTime())
|
||||||
|
.orderByDesc(ConfigDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,9 +13,14 @@ import lombok.Getter;
|
|||||||
public enum CodegenFrontTypeEnum {
|
public enum CodegenFrontTypeEnum {
|
||||||
|
|
||||||
VUE2_ELEMENT_UI(10), // Vue2 Element UI 标准模版
|
VUE2_ELEMENT_UI(10), // Vue2 Element UI 标准模版
|
||||||
|
|
||||||
VUE3_ELEMENT_PLUS(20), // Vue3 Element Plus 标准模版
|
VUE3_ELEMENT_PLUS(20), // Vue3 Element Plus 标准模版
|
||||||
|
|
||||||
VUE3_VBEN2_ANTD_SCHEMA(30), // Vue3 VBEN2 + ANTD + Schema 模版
|
VUE3_VBEN2_ANTD_SCHEMA(30), // Vue3 VBEN2 + ANTD + Schema 模版
|
||||||
|
|
||||||
VUE3_VBEN5_ANTD_SCHEMA(40), // Vue3 VBEN5 + ANTD + schema 模版
|
VUE3_VBEN5_ANTD_SCHEMA(40), // Vue3 VBEN5 + ANTD + schema 模版
|
||||||
|
|
||||||
|
VUE3_VBEN5_ANTD_GENERAL(41), // Vue3 VBEN5 + ANTD 标准模版
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -26,12 +26,6 @@ public class FtpFileClient extends AbstractFileClient<FtpFileClientConfig> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doInit() {
|
protected void doInit() {
|
||||||
// 把配置的 \ 替换成 /, 如果路径配置 \a\test, 替换成 /a/test, 替换方法已经处理 null 情况
|
|
||||||
config.setBasePath(StrUtil.replace(config.getBasePath(), StrUtil.BACKSLASH, StrUtil.SLASH));
|
|
||||||
// ftp的路径是 / 结尾
|
|
||||||
if (!config.getBasePath().endsWith(StrUtil.SLASH)) {
|
|
||||||
config.setBasePath(config.getBasePath() + StrUtil.SLASH);
|
|
||||||
}
|
|
||||||
// 初始化 Ftp 对象
|
// 初始化 Ftp 对象
|
||||||
this.ftp = new Ftp(config.getHost(), config.getPort(), config.getUsername(), config.getPassword(),
|
this.ftp = new Ftp(config.getHost(), config.getPort(), config.getUsername(), config.getPassword(),
|
||||||
CharsetUtil.CHARSET_UTF_8, null, null, FtpMode.valueOf(config.getMode()));
|
CharsetUtil.CHARSET_UTF_8, null, null, FtpMode.valueOf(config.getMode()));
|
||||||
@ -43,8 +37,8 @@ public class FtpFileClient extends AbstractFileClient<FtpFileClientConfig> {
|
|||||||
String filePath = getFilePath(path);
|
String filePath = getFilePath(path);
|
||||||
String fileName = FileUtil.getName(filePath);
|
String fileName = FileUtil.getName(filePath);
|
||||||
String dir = StrUtil.removeSuffix(filePath, fileName);
|
String dir = StrUtil.removeSuffix(filePath, fileName);
|
||||||
ftp.reconnectIfTimeout();
|
reconnectIfTimeout();
|
||||||
boolean success = ftp.upload(dir, fileName, new ByteArrayInputStream(content));
|
boolean success = ftp.upload(dir, fileName, new ByteArrayInputStream(content)); // 不需要主动创建目录,ftp 内部已经处理(见源码)
|
||||||
if (!success) {
|
if (!success) {
|
||||||
throw new FtpException(StrUtil.format("上传文件到目标目录 ({}) 失败", filePath));
|
throw new FtpException(StrUtil.format("上传文件到目标目录 ({}) 失败", filePath));
|
||||||
}
|
}
|
||||||
@ -55,7 +49,7 @@ public class FtpFileClient extends AbstractFileClient<FtpFileClientConfig> {
|
|||||||
@Override
|
@Override
|
||||||
public void delete(String path) {
|
public void delete(String path) {
|
||||||
String filePath = getFilePath(path);
|
String filePath = getFilePath(path);
|
||||||
ftp.reconnectIfTimeout();
|
reconnectIfTimeout();
|
||||||
ftp.delFile(filePath);
|
ftp.delFile(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,13 +59,17 @@ public class FtpFileClient extends AbstractFileClient<FtpFileClientConfig> {
|
|||||||
String fileName = FileUtil.getName(filePath);
|
String fileName = FileUtil.getName(filePath);
|
||||||
String dir = StrUtil.removeSuffix(filePath, fileName);
|
String dir = StrUtil.removeSuffix(filePath, fileName);
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
ftp.reconnectIfTimeout();
|
reconnectIfTimeout();
|
||||||
ftp.download(dir, fileName, out);
|
ftp.download(dir, fileName, out);
|
||||||
return out.toByteArray();
|
return out.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getFilePath(String path) {
|
private String getFilePath(String path) {
|
||||||
return config.getBasePath() + path;
|
return config.getBasePath() + StrUtil.SLASH + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void reconnectIfTimeout() {
|
||||||
|
ftp.reconnectIfTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -18,10 +18,6 @@ public class LocalFileClient extends AbstractFileClient<LocalFileClientConfig> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doInit() {
|
protected void doInit() {
|
||||||
// 补全风格。例如说 Linux 是 /,Windows 是 \
|
|
||||||
if (!config.getBasePath().endsWith(File.separator)) {
|
|
||||||
config.setBasePath(config.getBasePath() + File.separator);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -46,7 +42,7 @@ public class LocalFileClient extends AbstractFileClient<LocalFileClientConfig> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getFilePath(String path) {
|
private String getFilePath(String path) {
|
||||||
return config.getBasePath() + path;
|
return config.getBasePath() + File.separator + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,29 +4,31 @@ import cn.hutool.core.io.IoUtil;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.http.HttpUtil;
|
import cn.hutool.http.HttpUtil;
|
||||||
import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient;
|
||||||
import com.amazonaws.HttpMethod;
|
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
|
||||||
import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
|
||||||
import com.amazonaws.auth.BasicAWSCredentials;
|
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
|
||||||
import com.amazonaws.client.builder.AwsClientBuilder;
|
import software.amazon.awssdk.core.sync.RequestBody;
|
||||||
import com.amazonaws.services.s3.AmazonS3Client;
|
import software.amazon.awssdk.regions.Region;
|
||||||
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
import software.amazon.awssdk.services.s3.S3Client;
|
||||||
import com.amazonaws.services.s3.model.ObjectMetadata;
|
import software.amazon.awssdk.services.s3.S3Configuration;
|
||||||
import com.amazonaws.services.s3.model.S3Object;
|
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
|
||||||
|
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
|
||||||
|
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
|
||||||
|
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
|
||||||
|
import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.net.URI;
|
||||||
import java.util.Date;
|
import java.time.Duration;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于 S3 协议的文件客户端,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务
|
* 基于 S3 协议的文件客户端,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务
|
||||||
* <p>
|
|
||||||
* S3 协议的客户端,采用亚马逊提供的 software.amazon.awssdk.s3 库
|
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
||||||
|
|
||||||
private AmazonS3Client client;
|
private S3Client client;
|
||||||
|
private S3Presigner presigner;
|
||||||
|
|
||||||
public S3FileClient(Long id, S3FileClientConfig config) {
|
public S3FileClient(Long id, S3FileClientConfig config) {
|
||||||
super(id, config);
|
super(id, config);
|
||||||
@ -38,31 +40,80 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
|||||||
if (StrUtil.isEmpty(config.getDomain())) {
|
if (StrUtil.isEmpty(config.getDomain())) {
|
||||||
config.setDomain(buildDomain());
|
config.setDomain(buildDomain());
|
||||||
}
|
}
|
||||||
// 初始化客户端
|
// 初始化 S3 客户端
|
||||||
client = (AmazonS3Client)AmazonS3ClientBuilder.standard()
|
Region region = Region.of("us-east-1"); // 必须填,但填什么都行,常见的值有 "us-east-1",不填会报错
|
||||||
.withCredentials(buildCredentials())
|
AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
|
||||||
.withEndpointConfiguration(buildEndpointConfiguration())
|
AwsBasicCredentials.create(config.getAccessKey(), config.getAccessSecret()));
|
||||||
|
URI endpoint = URI.create(buildEndpoint());
|
||||||
|
S3Configuration serviceConfiguration = S3Configuration.builder() // Path-style 访问
|
||||||
|
.pathStyleAccessEnabled(Boolean.TRUE.equals(config.getEnablePathStyleAccess()))
|
||||||
|
.chunkedEncodingEnabled(false) // 禁用分块编码,参见 https://t.zsxq.com/kBy57
|
||||||
|
.build();
|
||||||
|
client = S3Client.builder()
|
||||||
|
.credentialsProvider(credentialsProvider)
|
||||||
|
.region(region)
|
||||||
|
.endpointOverride(endpoint)
|
||||||
|
.serviceConfiguration(serviceConfiguration)
|
||||||
|
.build();
|
||||||
|
presigner = S3Presigner.builder()
|
||||||
|
.credentialsProvider(credentialsProvider)
|
||||||
|
.region(region)
|
||||||
|
.endpointOverride(endpoint)
|
||||||
|
.serviceConfiguration(serviceConfiguration)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* 基于 config 秘钥,构建 S3 客户端的认证信息
|
public String upload(byte[] content, String path, String type) {
|
||||||
*
|
// 构造 PutObjectRequest
|
||||||
* @return S3 客户端的认证信息
|
PutObjectRequest putRequest = PutObjectRequest.builder()
|
||||||
*/
|
.bucket(config.getBucket())
|
||||||
private AWSStaticCredentialsProvider buildCredentials() {
|
.key(path)
|
||||||
return new AWSStaticCredentialsProvider(
|
.contentType(type)
|
||||||
new BasicAWSCredentials(config.getAccessKey(), config.getAccessSecret()));
|
.contentLength((long) content.length)
|
||||||
|
.build();
|
||||||
|
// 上传文件
|
||||||
|
client.putObject(putRequest, RequestBody.fromBytes(content));
|
||||||
|
// 拼接返回路径
|
||||||
|
return config.getDomain() + "/" + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(String path) {
|
||||||
|
DeleteObjectRequest deleteRequest = DeleteObjectRequest.builder()
|
||||||
|
.bucket(config.getBucket())
|
||||||
|
.key(path)
|
||||||
|
.build();
|
||||||
|
client.deleteObject(deleteRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getContent(String path) {
|
||||||
|
GetObjectRequest getRequest = GetObjectRequest.builder()
|
||||||
|
.bucket(config.getBucket())
|
||||||
|
.key(path)
|
||||||
|
.build();
|
||||||
|
return IoUtil.readBytes(client.getObject(getRequest));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FilePresignedUrlRespDTO getPresignedObjectUrl(String path) {
|
||||||
|
Duration expiration = Duration.ofHours(24);
|
||||||
|
return new FilePresignedUrlRespDTO(getPresignedUrl(path, expiration), config.getDomain() + "/" + path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建 S3 客户端的 Endpoint 配置,包括 region、endpoint
|
* 生成动态的预签名上传 URL
|
||||||
*
|
*
|
||||||
* @return S3 客户端的 EndpointConfiguration 配置
|
* @param path 相对路径
|
||||||
|
* @param expiration 过期时间
|
||||||
|
* @return 生成的上传 URL
|
||||||
*/
|
*/
|
||||||
private AwsClientBuilder.EndpointConfiguration buildEndpointConfiguration() {
|
private String getPresignedUrl(String path, Duration expiration) {
|
||||||
return new AwsClientBuilder.EndpointConfiguration(config.getEndpoint(),
|
return presigner.presignPutObject(PutObjectPresignRequest.builder()
|
||||||
null); // 无需设置 region
|
.signatureDuration(expiration)
|
||||||
|
.putObjectRequest(b -> b.bucket(config.getBucket()).key(path))
|
||||||
|
.build()).url().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,40 +130,17 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
|||||||
return StrUtil.format("https://{}.{}", config.getBucket(), config.getEndpoint());
|
return StrUtil.format("https://{}.{}", config.getBucket(), config.getEndpoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public String upload(byte[] content, String path, String type) throws Exception {
|
* 节点地址补全协议头
|
||||||
// 元数据,主要用于设置文件类型
|
*
|
||||||
ObjectMetadata objectMetadata = new ObjectMetadata();
|
* @return 节点地址
|
||||||
objectMetadata.setContentType(type);
|
*/
|
||||||
objectMetadata.setContentLength(content.length); // 如果不设置,会有 “ No content length specified for stream data” 警告日志
|
private String buildEndpoint() {
|
||||||
// 执行上传
|
// 如果已经是 http 或者 https,则不进行拼接
|
||||||
client.putObject(config.getBucket(),
|
if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) {
|
||||||
path, // 相对路径
|
return config.getEndpoint();
|
||||||
new ByteArrayInputStream(content), // 文件内容
|
|
||||||
objectMetadata);
|
|
||||||
|
|
||||||
// 拼接返回路径
|
|
||||||
return config.getDomain() + "/" + path;
|
|
||||||
}
|
}
|
||||||
|
return StrUtil.format("https://{}", config.getEndpoint());
|
||||||
@Override
|
|
||||||
public void delete(String path) throws Exception {
|
|
||||||
client.deleteObject(config.getBucket(), path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getContent(String path) throws Exception {
|
|
||||||
S3Object tempS3Object = client.getObject(config.getBucket(), path);
|
|
||||||
return IoUtil.readBytes(tempS3Object.getObjectContent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FilePresignedUrlRespDTO getPresignedObjectUrl(String path) throws Exception {
|
|
||||||
// 设定过期时间为 10 分钟。取值范围:1 秒 ~ 7 天
|
|
||||||
Date expiration = new Date(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(10));
|
|
||||||
// 生成上传 URL
|
|
||||||
String uploadUrl = String.valueOf(client.generatePresignedUrl(config.getBucket(), path, expiration , HttpMethod.PUT));
|
|
||||||
return new FilePresignedUrlRespDTO(uploadUrl, config.getDomain() + "/" + path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,6 +66,12 @@ public class S3FileClientConfig implements FileClientConfig {
|
|||||||
@NotNull(message = "accessSecret 不能为空")
|
@NotNull(message = "accessSecret 不能为空")
|
||||||
private String accessSecret;
|
private String accessSecret;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用 PathStyle 访问
|
||||||
|
*/
|
||||||
|
@NotNull(message = "enablePathStyleAccess 不能为空")
|
||||||
|
private Boolean enablePathStyleAccess;
|
||||||
|
|
||||||
@SuppressWarnings("RedundantIfStatement")
|
@SuppressWarnings("RedundantIfStatement")
|
||||||
@AssertTrue(message = "domain 不能为空")
|
@AssertTrue(message = "domain 不能为空")
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
|
|||||||
@ -22,10 +22,6 @@ public class SftpFileClient extends AbstractFileClient<SftpFileClientConfig> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doInit() {
|
protected void doInit() {
|
||||||
// 补全风格。例如说 Linux 是 /,Windows 是 \
|
|
||||||
if (!config.getBasePath().endsWith(File.separator)) {
|
|
||||||
config.setBasePath(config.getBasePath() + File.separator);
|
|
||||||
}
|
|
||||||
// 初始化 Ftp 对象
|
// 初始化 Ftp 对象
|
||||||
this.sftp = new Sftp(config.getHost(), config.getPort(), config.getUsername(), config.getPassword());
|
this.sftp = new Sftp(config.getHost(), config.getPort(), config.getUsername(), config.getPassword());
|
||||||
}
|
}
|
||||||
@ -35,6 +31,8 @@ public class SftpFileClient extends AbstractFileClient<SftpFileClientConfig> {
|
|||||||
// 执行写入
|
// 执行写入
|
||||||
String filePath = getFilePath(path);
|
String filePath = getFilePath(path);
|
||||||
File file = FileUtils.createTempFile(content);
|
File file = FileUtils.createTempFile(content);
|
||||||
|
reconnectIfTimeout();
|
||||||
|
sftp.mkDirs(FileUtil.getParent(filePath, 1)); // 需要创建父目录,不然会报错
|
||||||
sftp.upload(filePath, file);
|
sftp.upload(filePath, file);
|
||||||
// 拼接返回路径
|
// 拼接返回路径
|
||||||
return super.formatFileUrl(config.getDomain(), path);
|
return super.formatFileUrl(config.getDomain(), path);
|
||||||
@ -43,6 +41,7 @@ public class SftpFileClient extends AbstractFileClient<SftpFileClientConfig> {
|
|||||||
@Override
|
@Override
|
||||||
public void delete(String path) {
|
public void delete(String path) {
|
||||||
String filePath = getFilePath(path);
|
String filePath = getFilePath(path);
|
||||||
|
reconnectIfTimeout();
|
||||||
sftp.delFile(filePath);
|
sftp.delFile(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,12 +49,17 @@ public class SftpFileClient extends AbstractFileClient<SftpFileClientConfig> {
|
|||||||
public byte[] getContent(String path) {
|
public byte[] getContent(String path) {
|
||||||
String filePath = getFilePath(path);
|
String filePath = getFilePath(path);
|
||||||
File destFile = FileUtils.createTempFile();
|
File destFile = FileUtils.createTempFile();
|
||||||
|
reconnectIfTimeout();
|
||||||
sftp.download(filePath, destFile);
|
sftp.download(filePath, destFile);
|
||||||
return FileUtil.readBytes(destFile);
|
return FileUtil.readBytes(destFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getFilePath(String path) {
|
private String getFilePath(String path) {
|
||||||
return config.getBasePath() + path;
|
return config.getBasePath() + File.separator + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void reconnectIfTimeout() {
|
||||||
|
sftp.reconnectIfTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,10 @@ import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
|
|||||||
import com.alibaba.ttl.TransmittableThreadLocal;
|
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.tika.Tika;
|
import org.apache.tika.Tika;
|
||||||
|
import org.apache.tika.mime.MimeTypeException;
|
||||||
|
import org.apache.tika.mime.MimeTypes;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@ -15,12 +18,13 @@ import java.io.IOException;
|
|||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class FileTypeUtils {
|
public class FileTypeUtils {
|
||||||
|
|
||||||
private static final ThreadLocal<Tika> TIKA = TransmittableThreadLocal.withInitial(Tika::new);
|
private static final ThreadLocal<Tika> TIKA = TransmittableThreadLocal.withInitial(Tika::new);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得文件的 mineType,对于doc,jar等文件会有误差
|
* 获得文件的 mineType,对于 doc,jar 等文件会有误差
|
||||||
*
|
*
|
||||||
* @param data 文件内容
|
* @param data 文件内容
|
||||||
* @return mineType 无法识别时会返回“application/octet-stream”
|
* @return mineType 无法识别时会返回“application/octet-stream”
|
||||||
@ -31,7 +35,7 @@ public class FileTypeUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 已知文件名,获取文件类型,在某些情况下比通过字节数组准确,例如使用jar文件时,通过名字更为准确
|
* 已知文件名,获取文件类型,在某些情况下比通过字节数组准确,例如使用 jar 文件时,通过名字更为准确
|
||||||
*
|
*
|
||||||
* @param name 文件名
|
* @param name 文件名
|
||||||
* @return mineType 无法识别时会返回“application/octet-stream”
|
* @return mineType 无法识别时会返回“application/octet-stream”
|
||||||
@ -51,6 +55,23 @@ public class FileTypeUtils {
|
|||||||
return TIKA.get().detect(data, name);
|
return TIKA.get().detect(data, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 mineType 获得文件后缀
|
||||||
|
*
|
||||||
|
* 注意:如果获取不到,或者发生异常,都返回 null
|
||||||
|
*
|
||||||
|
* @param mineType 类型
|
||||||
|
* @return 后缀,例如说 .pdf
|
||||||
|
*/
|
||||||
|
public static String getExtension(String mineType) {
|
||||||
|
try {
|
||||||
|
return MimeTypes.getDefaultMimeTypes().forName(mineType).getExtension();
|
||||||
|
} catch (MimeTypeException e) {
|
||||||
|
log.warn("[getExtension][获取文件后缀({}) 失败]", mineType, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回附件
|
* 返回附件
|
||||||
*
|
*
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|||||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(value = "infraRpcConfiguration", proxyBeanMethods = false)
|
||||||
@EnableFeignClients(clients = AdminUserApi.class)
|
@EnableFeignClients(clients = AdminUserApi.class)
|
||||||
public class RpcConfiguration {
|
public class RpcConfiguration {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -145,24 +145,41 @@ public class CodegenEngine {
|
|||||||
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("api/api.ts"),
|
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("api/api.ts"),
|
||||||
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||||
// VUE3_VBEN5_ANTD_SCHEMA
|
// VUE3_VBEN5_ANTD_SCHEMA
|
||||||
// TODO @puhui999:目录改成 vue3_vben5_antd;然后里面有 schema(目前我们在写的)和 general(你微信里提的,原生的,感觉也要搞!)
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/data.ts"),
|
||||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3VbenNextSchemaTemplatePath("views/data.ts"),
|
|
||||||
vue3FilePath("views/${table.moduleName}/${table.businessName}/data.ts"))
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/data.ts"))
|
||||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3VbenNextSchemaTemplatePath("views/index.vue"),
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/index.vue"),
|
||||||
vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
||||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3VbenNextSchemaTemplatePath("views/form.vue"),
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/form.vue"),
|
||||||
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
|
||||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3VbenNextSchemaTemplatePath("api/api.ts"),
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("api/api.ts"),
|
||||||
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||||
// 主子表模板配置 - Vue3 vben5 schema 模版
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑
|
||||||
//.put(CodegenFrontTypeEnum.VUE3_VBEN_NEXT_SCHEMA.getType(), vue3VbenNextSchemaTemplatePath("views/master_slave_data.ts"),
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||||
// vue3FilePath("views/${table.moduleName}/${table.businessName}/data.ts"))
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||||
//.put(CodegenFrontTypeEnum.VUE3_VBEN_NEXT_SCHEMA.getType(), vue3VbenNextSchemaTemplatePath("views/master_slave_index.vue"),
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||||
// vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||||
//.put(CodegenFrontTypeEnum.VUE3_VBEN_NEXT_SCHEMA.getType(), vue3VbenNextSchemaTemplatePath("views/modules/master_slave_form.vue"),
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||||
// vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||||
//.put(CodegenFrontTypeEnum.VUE3_VBEN_NEXT_SCHEMA.getType(), vue3VbenNextSchemaTemplatePath("views/modules/sub_table.vue"),
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
|
||||||
// vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/sub_table.vue"))
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||||
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
|
||||||
|
// VUE3_VBEN5_ANTD
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/index.vue"),
|
||||||
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/form.vue"),
|
||||||
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("api/api.ts"),
|
||||||
|
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑
|
||||||
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||||
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||||
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||||
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||||
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@ -451,6 +468,8 @@ public class CodegenEngine {
|
|||||||
filePath = StrUtil.replace(filePath, "${subTable.className}", subTable.getClassName());
|
filePath = StrUtil.replace(filePath, "${subTable.className}", subTable.getClassName());
|
||||||
filePath = StrUtil.replace(filePath, "${subSimpleClassName}",
|
filePath = StrUtil.replace(filePath, "${subSimpleClassName}",
|
||||||
((List<String>) bindingMap.get("subSimpleClassNames")).get(subIndex));
|
((List<String>) bindingMap.get("subSimpleClassNames")).get(subIndex));
|
||||||
|
filePath = StrUtil.replace(filePath, "${subSimpleClassName_strikeCase}",
|
||||||
|
((List<String>) bindingMap.get("subSimpleClassName_strikeCases")).get(subIndex));
|
||||||
}
|
}
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
@ -515,8 +534,12 @@ public class CodegenEngine {
|
|||||||
return "codegen/vue3_vben/" + path + ".vm";
|
return "codegen/vue3_vben/" + path + ".vm";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String vue3VbenNextSchemaTemplatePath(String path) {
|
private static String vue3Vben5AntdSchemaTemplatePath(String path) {
|
||||||
return "codegen/vue3_vben_next/schema/" + path + ".vm";
|
return "codegen/vue3_vben5_antd/schema/" + path + ".vm";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String vue3Vben5AntdGeneralTemplatePath(String path) {
|
||||||
|
return "codegen/vue3_vben5_antd/general/" + path + ".vm";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSubTemplate(String path) {
|
private static boolean isSubTemplate(String path) {
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileCreateReq
|
|||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePresignedUrlRespVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePresignedUrlRespVO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件 Service 接口
|
* 文件 Service 接口
|
||||||
@ -24,12 +25,24 @@ public interface FileService {
|
|||||||
/**
|
/**
|
||||||
* 保存文件,并返回文件的访问路径
|
* 保存文件,并返回文件的访问路径
|
||||||
*
|
*
|
||||||
* @param name 文件名称
|
|
||||||
* @param path 文件路径
|
|
||||||
* @param content 文件内容
|
* @param content 文件内容
|
||||||
|
* @param name 文件名称,允许空
|
||||||
|
* @param directory 目录,允许空
|
||||||
|
* @param type 文件的 MIME 类型,允许空
|
||||||
* @return 文件路径
|
* @return 文件路径
|
||||||
*/
|
*/
|
||||||
String createFile(String name, String path, byte[] content);
|
String createFile(@NotEmpty(message = "文件内容不能为空") byte[] content,
|
||||||
|
String name, String directory, String type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成文件预签名地址信息
|
||||||
|
*
|
||||||
|
* @param name 文件名
|
||||||
|
* @param directory 目录
|
||||||
|
* @return 预签名地址信息
|
||||||
|
*/
|
||||||
|
FilePresignedUrlRespVO getFilePresignedUrl(@NotEmpty(message = "文件名不能为空") String name,
|
||||||
|
String directory);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建文件
|
* 创建文件
|
||||||
@ -55,12 +68,4 @@ public interface FileService {
|
|||||||
*/
|
*/
|
||||||
byte[] getFileContent(Long configId, String path) throws Exception;
|
byte[] getFileContent(Long configId, String path) throws Exception;
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成文件预签名地址信息
|
|
||||||
*
|
|
||||||
* @param path 文件路径
|
|
||||||
* @return 预签名地址信息
|
|
||||||
*/
|
|
||||||
FilePresignedUrlRespVO getFilePresignedUrl(String path) throws Exception;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
package cn.iocoder.yudao.module.infra.service.file;
|
package cn.iocoder.yudao.module.infra.service.file;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.crypto.digest.DigestUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileCreateReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
||||||
@ -13,10 +15,12 @@ import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
|
|||||||
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient;
|
||||||
import cn.iocoder.yudao.module.infra.framework.file.core.client.s3.FilePresignedUrlRespDTO;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.s3.FilePresignedUrlRespDTO;
|
||||||
import cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils;
|
import cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils;
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import static cn.hutool.core.date.DatePattern.PURE_DATE_PATTERN;
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
|
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
|
||||||
|
|
||||||
@ -28,6 +32,20 @@ import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EX
|
|||||||
@Service
|
@Service
|
||||||
public class FileServiceImpl implements FileService {
|
public class FileServiceImpl implements FileService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件的前缀,是否包含日期(yyyyMMdd)
|
||||||
|
*
|
||||||
|
* 目的:按照日期,进行分目录
|
||||||
|
*/
|
||||||
|
static boolean PATH_PREFIX_DATE_ENABLE = true;
|
||||||
|
/**
|
||||||
|
* 上传文件的后缀,是否包含时间戳
|
||||||
|
*
|
||||||
|
* 目的:保证文件的唯一性,避免覆盖
|
||||||
|
* 定制:可按需调整成 UUID、或者其他方式
|
||||||
|
*/
|
||||||
|
static boolean PATH_SUFFIX_TIMESTAMP_ENABLE = true;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private FileConfigService fileConfigService;
|
private FileConfigService fileConfigService;
|
||||||
|
|
||||||
@ -41,34 +59,82 @@ public class FileServiceImpl implements FileService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public String createFile(String name, String path, byte[] content) {
|
public String createFile(byte[] content, String name, String directory, String type) {
|
||||||
// 计算默认的 path 名
|
// 1.1 处理 type 为空的情况
|
||||||
String type = FileTypeUtils.getMineType(content, name);
|
if (StrUtil.isEmpty(type)) {
|
||||||
if (StrUtil.isEmpty(path)) {
|
type = FileTypeUtils.getMineType(content, name);
|
||||||
path = FileUtils.generatePath(content, name);
|
|
||||||
}
|
}
|
||||||
// 如果 name 为空,则使用 path 填充
|
// 1.2 处理 name 为空的情况
|
||||||
if (StrUtil.isEmpty(name)) {
|
if (StrUtil.isEmpty(name)) {
|
||||||
name = path;
|
name = DigestUtil.sha256Hex(content);
|
||||||
|
}
|
||||||
|
if (StrUtil.isEmpty(FileUtil.extName(name))) {
|
||||||
|
// 如果 name 没有后缀 type,则补充后缀
|
||||||
|
String extension = FileTypeUtils.getExtension(type);
|
||||||
|
if (StrUtil.isNotEmpty(extension)) {
|
||||||
|
name = name + extension;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上传到文件存储器
|
// 2.1 生成上传的 path,需要保证唯一
|
||||||
|
String path = generateUploadPath(name, directory);
|
||||||
|
// 2.2 上传到文件存储器
|
||||||
FileClient client = fileConfigService.getMasterFileClient();
|
FileClient client = fileConfigService.getMasterFileClient();
|
||||||
Assert.notNull(client, "客户端(master) 不能为空");
|
Assert.notNull(client, "客户端(master) 不能为空");
|
||||||
String url = client.upload(content, path, type);
|
String url = client.upload(content, path, type);
|
||||||
|
|
||||||
// 保存到数据库
|
// 3. 保存到数据库
|
||||||
FileDO file = new FileDO();
|
fileMapper.insert(new FileDO().setConfigId(client.getId())
|
||||||
file.setConfigId(client.getId());
|
.setName(name).setPath(path).setUrl(url)
|
||||||
file.setName(name);
|
.setType(type).setSize(content.length));
|
||||||
file.setPath(path);
|
|
||||||
file.setUrl(url);
|
|
||||||
file.setType(type);
|
|
||||||
file.setSize(content.length);
|
|
||||||
fileMapper.insert(file);
|
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
String generateUploadPath(String name, String directory) {
|
||||||
|
// 1. 生成前缀、后缀
|
||||||
|
String prefix = null;
|
||||||
|
if (PATH_PREFIX_DATE_ENABLE) {
|
||||||
|
prefix = LocalDateTimeUtil.format(LocalDateTimeUtil.now(), PURE_DATE_PATTERN);
|
||||||
|
}
|
||||||
|
String suffix = null;
|
||||||
|
if (PATH_SUFFIX_TIMESTAMP_ENABLE) {
|
||||||
|
suffix = String.valueOf(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.1 先拼接 suffix 后缀
|
||||||
|
if (StrUtil.isNotEmpty(suffix)) {
|
||||||
|
String ext = FileUtil.extName(name);
|
||||||
|
if (StrUtil.isNotEmpty(ext)) {
|
||||||
|
name = FileUtil.mainName(name) + StrUtil.C_UNDERLINE + suffix + StrUtil.DOT + ext;
|
||||||
|
} else {
|
||||||
|
name = name + StrUtil.C_UNDERLINE + suffix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 2.2 再拼接 prefix 前缀
|
||||||
|
if (StrUtil.isNotEmpty(prefix)) {
|
||||||
|
name = prefix + StrUtil.SLASH + name;
|
||||||
|
}
|
||||||
|
// 2.3 最后拼接 directory 目录
|
||||||
|
if (StrUtil.isNotEmpty(directory)) {
|
||||||
|
name = directory + StrUtil.SLASH + name;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public FilePresignedUrlRespVO getFilePresignedUrl(String name, String directory) {
|
||||||
|
// 1. 生成上传的 path,需要保证唯一
|
||||||
|
String path = generateUploadPath(name, directory);
|
||||||
|
|
||||||
|
// 2. 获取文件预签名地址
|
||||||
|
FileClient fileClient = fileConfigService.getMasterFileClient();
|
||||||
|
FilePresignedUrlRespDTO presignedObjectUrl = fileClient.getPresignedObjectUrl(path);
|
||||||
|
return BeanUtils.toBean(presignedObjectUrl, FilePresignedUrlRespVO.class,
|
||||||
|
object -> object.setConfigId(fileClient.getId()).setPath(path));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createFile(FileCreateReqVO createReqVO) {
|
public Long createFile(FileCreateReqVO createReqVO) {
|
||||||
FileDO file = BeanUtils.toBean(createReqVO, FileDO.class);
|
FileDO file = BeanUtils.toBean(createReqVO, FileDO.class);
|
||||||
@ -105,12 +171,4 @@ public class FileServiceImpl implements FileService {
|
|||||||
return client.getContent(path);
|
return client.getContent(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public FilePresignedUrlRespVO getFilePresignedUrl(String path) throws Exception {
|
|
||||||
FileClient fileClient = fileConfigService.getMasterFileClient();
|
|
||||||
FilePresignedUrlRespDTO presignedObjectUrl = fileClient.getPresignedObjectUrl(path);
|
|
||||||
return BeanUtils.toBean(presignedObjectUrl, FilePresignedUrlRespVO.class,
|
|
||||||
object -> object.setConfigId(fileClient.getId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -132,17 +132,6 @@ yudao:
|
|||||||
tenant: # 多租户相关配置项
|
tenant: # 多租户相关配置项
|
||||||
enable: true
|
enable: true
|
||||||
ignore-urls:
|
ignore-urls:
|
||||||
- /admin-api/infra/file/*/get/** # 获取图片,和租户无关
|
|
||||||
ignore-tables:
|
ignore-tables:
|
||||||
- infra_codegen_column
|
|
||||||
- infra_codegen_table
|
|
||||||
- infra_config
|
|
||||||
- infra_file_config
|
|
||||||
- infra_file
|
|
||||||
- infra_file_content
|
|
||||||
- infra_job
|
|
||||||
- infra_job_log
|
|
||||||
- infra_job_log
|
|
||||||
- infra_data_source_config
|
|
||||||
|
|
||||||
debug: false
|
debug: false
|
||||||
|
|||||||
@ -1,9 +1,31 @@
|
|||||||
import type { PageParam, PageResult } from '@vben/request';
|
import type { PageParam, PageResult } from '@vben/request';
|
||||||
|
import type { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
import { requestClient } from '#/api/request';
|
import { requestClient } from '#/api/request';
|
||||||
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||||
|
|
||||||
export namespace ${simpleClassName}Api {
|
export namespace ${simpleClassName}Api {
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#set ($subColumns = $subColumnsList.get($index))##当前字段数组
|
||||||
|
/** ${subTable.classComment}信息 */
|
||||||
|
export interface ${subSimpleClassName} {
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
|
||||||
|
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
|
||||||
|
#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
|
||||||
|
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
|
||||||
|
#else
|
||||||
|
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
|
||||||
|
#end
|
||||||
/** ${table.classComment}信息 */
|
/** ${table.classComment}信息 */
|
||||||
export interface ${simpleClassName} {
|
export interface ${simpleClassName} {
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
@ -11,7 +33,7 @@ export namespace ${simpleClassName}Api {
|
|||||||
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
|
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
|
||||||
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
|
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
|
||||||
#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
|
#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
|
||||||
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: Date; // ${column.columnComment}
|
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
|
||||||
#else
|
#else
|
||||||
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
|
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
|
||||||
#end
|
#end
|
||||||
@ -19,6 +41,18 @@ export namespace ${simpleClassName}Api {
|
|||||||
#end
|
#end
|
||||||
#if ( $table.templateType == 2 )
|
#if ( $table.templateType == 2 )
|
||||||
children?: ${simpleClassName}[];
|
children?: ${simpleClassName}[];
|
||||||
|
#end
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#if ( $subTable.subJoinMany )
|
||||||
|
${subSimpleClassName.toLowerCase()}s?: ${subSimpleClassName}[]
|
||||||
|
#else
|
||||||
|
${subSimpleClassName.toLowerCase()}?: ${subSimpleClassName}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,35 +106,36 @@ export function export${simpleClassName}(params: any) {
|
|||||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
|
||||||
// ==================== 子表($subTable.classComment) ====================
|
// ==================== 子表($subTable.classComment) ====================
|
||||||
|
|
||||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||||
#if ( $table.templateType == 11 )
|
#if ( $table.templateType == 11 )
|
||||||
/** 获得${subTable.classComment}分页 */
|
/** 获得${subTable.classComment}分页 */
|
||||||
export function get${subSimpleClassName}Page(params: PageParam) {
|
export function get${subSimpleClassName}Page(params: PageParam) {
|
||||||
return requestClient.get<PageResult<${simpleClassName}Api.${simpleClassName}>>(`${baseURL}/${subSimpleClassName_strikeCase}/page`, { params });
|
return requestClient.get<PageResult<${simpleClassName}Api.${subSimpleClassName}>>(`${baseURL}/${subSimpleClassName_strikeCase}/page`, { params });
|
||||||
}
|
}
|
||||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||||
#else
|
#else
|
||||||
#if ( $subTable.subJoinMany )
|
#if ( $subTable.subJoinMany )
|
||||||
/** 获得${subTable.classComment}列表 */
|
/** 获得${subTable.classComment}列表 */
|
||||||
export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
|
export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
|
||||||
return requestClient.get<${simpleClassName}Api.${simpleClassName}[]>(`${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
|
return requestClient.get<${simpleClassName}Api.${subSimpleClassName}[]>(`${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/** 获得${subTable.classComment} */
|
/** 获得${subTable.classComment} */
|
||||||
export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
|
export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
|
||||||
return requestClient.get<${simpleClassName}Api.${simpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
|
return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||||
#if ( $table.templateType == 11 )
|
#if ( $table.templateType == 11 )
|
||||||
/** 新增${subTable.classComment} */
|
/** 新增${subTable.classComment} */
|
||||||
export function create${subSimpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) {
|
export function create${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
|
||||||
return requestClient.post(`${baseURL}/${subSimpleClassName_strikeCase}/create`, data);
|
return requestClient.post(`${baseURL}/${subSimpleClassName_strikeCase}/create`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 修改${subTable.classComment} */
|
/** 修改${subTable.classComment} */
|
||||||
export function update${subSimpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) {
|
export function update${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
|
||||||
return requestClient.put(`${baseURL}/${subSimpleClassName_strikeCase}/update`, data);
|
return requestClient.put(`${baseURL}/${subSimpleClassName_strikeCase}/update`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +146,7 @@ export function delete${subSimpleClassName}(id: number) {
|
|||||||
|
|
||||||
/** 获得${subTable.classComment} */
|
/** 获得${subTable.classComment} */
|
||||||
export function get${subSimpleClassName}(id: number) {
|
export function get${subSimpleClassName}(id: number) {
|
||||||
return requestClient.get<${simpleClassName}Api.${simpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get?id=${id}`);
|
return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get?id=${id}`);
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
@ -0,0 +1,324 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
import type { Rule } from 'ant-design-vue/es/form';
|
||||||
|
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import { Tinymce as RichTextarea } from '#/components/tinymce';
|
||||||
|
import { ImageUpload, FileUpload } from "#/components/upload";
|
||||||
|
import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker, TreeSelect } from 'ant-design-vue';
|
||||||
|
import { DICT_TYPE, getDictOptions } from '#/utils';
|
||||||
|
#if($table.templateType == 2)## 树表需要导入这些
|
||||||
|
import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
import { handleTree } from '@vben/utils'
|
||||||
|
#end
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
|
||||||
|
import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { $t } from '#/locales';
|
||||||
|
import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
|
||||||
|
const emit = defineEmits(['success']);
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const formData = ref<Partial<${simpleClassName}Api.${simpleClassName}>>({
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if ($column.htmlType == "checkbox")
|
||||||
|
$column.javaField: [],
|
||||||
|
#else
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
});
|
||||||
|
const rules: Record<string, Rule[]> = {
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||||
|
#set($comment=$column.columnComment)
|
||||||
|
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
};
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
const ${classNameVar}Tree = ref<any[]>([]) // 树形结构
|
||||||
|
#end
|
||||||
|
const getTitle = computed(() => {
|
||||||
|
return formData.value?.id
|
||||||
|
? $t('ui.actionTitle.edit', ['${table.classComment}'])
|
||||||
|
: $t('ui.actionTitle.create', ['${table.classComment}']);
|
||||||
|
});
|
||||||
|
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
/** 子表的表单 */
|
||||||
|
const subTabsName = ref('$subClassNameVars.get(0)')
|
||||||
|
#foreach ($subClassNameVar in $subClassNameVars)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
const ${subClassNameVar}FormRef = ref<InstanceType<typeof ${subSimpleClassName}Form>>()
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if ($column.htmlType == "checkbox")
|
||||||
|
$column.javaField: [],
|
||||||
|
#else
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
};
|
||||||
|
formRef.value?.resetFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
/** 获得${table.classComment}树 */
|
||||||
|
const get${simpleClassName}Tree = async () => {
|
||||||
|
${classNameVar}Tree.value = []
|
||||||
|
const data = await get${simpleClassName}List({});
|
||||||
|
data.unshift({
|
||||||
|
id: 0,
|
||||||
|
name: '顶级${table.classComment}',
|
||||||
|
});
|
||||||
|
${classNameVar}Tree.value = handleTree(data);
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
|
const [Modal, modalApi] = useVbenModal({
|
||||||
|
async onConfirm() {
|
||||||
|
await formRef.value?.validate();
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
// 校验子表单
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
#if ($subTable.subJoinMany) ## 一对多
|
||||||
|
## TODO 列表值校验?
|
||||||
|
#else
|
||||||
|
try {
|
||||||
|
await ${subClassNameVar}FormRef.value?.validate()
|
||||||
|
} catch (e) {
|
||||||
|
subTabsName.value = '${subClassNameVar}'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
modalApi.lock();
|
||||||
|
// 提交表单
|
||||||
|
const data = formData.value as ${simpleClassName}Api.${simpleClassName};
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
// 拼接子表的数据
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
#if ($subTable.subJoinMany)
|
||||||
|
data.${subClassNameVar}s = ${subClassNameVar}FormRef.value?.getData();
|
||||||
|
#else
|
||||||
|
data.${subClassNameVar} = ${subClassNameVar}FormRef.value?.getValues();
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
try {
|
||||||
|
await (formData.value?.id ? update${simpleClassName}(data) : create${simpleClassName}(data));
|
||||||
|
// 关闭并提示
|
||||||
|
await modalApi.close();
|
||||||
|
emit('success');
|
||||||
|
message.success({
|
||||||
|
content: $t('ui.actionMessage.operationSuccess'),
|
||||||
|
key: 'action_process_msg',
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
modalApi.unlock();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async onOpenChange(isOpen: boolean) {
|
||||||
|
if (!isOpen) {
|
||||||
|
resetForm()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 加载数据
|
||||||
|
let data = modalApi.getData<${simpleClassName}Api.${simpleClassName}>();
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data.id) {
|
||||||
|
modalApi.lock();
|
||||||
|
try {
|
||||||
|
data = await get${simpleClassName}(data.id);
|
||||||
|
} finally {
|
||||||
|
modalApi.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
formData.value = data;
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
// 加载树数据
|
||||||
|
await get${simpleClassName}Tree()
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Modal :title="getTitle">
|
||||||
|
<Form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="rules"
|
||||||
|
:label-col="{ span: 5 }"
|
||||||
|
:wrapper-col="{ span: 18 }"
|
||||||
|
>
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "number")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "string")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "boolean")
|
||||||
|
#end
|
||||||
|
#if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<TreeSelect
|
||||||
|
v-model:value="formData.${javaField}"
|
||||||
|
:treeData="${classNameVar}Tree"
|
||||||
|
#if ($treeNameColumn.javaField == "name")
|
||||||
|
:fieldNames="{
|
||||||
|
label: 'name',
|
||||||
|
value: 'id',
|
||||||
|
children: 'children',
|
||||||
|
}"
|
||||||
|
#else
|
||||||
|
:fieldNames="{
|
||||||
|
label: '$treeNameColumn.javaField',
|
||||||
|
value: 'id',
|
||||||
|
children: 'children',
|
||||||
|
}"
|
||||||
|
#end
|
||||||
|
checkable
|
||||||
|
treeDefaultExpandAll
|
||||||
|
placeholder="请选择${comment}"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<Input v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<ImageUpload v-model:value="formData.${javaField}" />
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<FileUpload v-model:value="formData.${javaField}" />
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<RichTextarea v-model="formData.${javaField}" height="500px" />
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<Select v-model:value="formData.${javaField}" placeholder="请选择${comment}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<Select.Option
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Select.Option>
|
||||||
|
#else##没数据字典
|
||||||
|
<Select.Option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<CheckboxGroup v-model:value="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<Checkbox
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Checkbox>
|
||||||
|
#else##没数据字典
|
||||||
|
<Checkbox label="请选择字典生成" />
|
||||||
|
#end
|
||||||
|
</CheckboxGroup>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<RadioGroup v-model:value="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<Radio
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Radio>
|
||||||
|
#else##没数据字典
|
||||||
|
<Radio value="1">请选择字典生成</Radio>
|
||||||
|
#end
|
||||||
|
</RadioGroup>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<DatePicker
|
||||||
|
v-model:value="formData.${javaField}"
|
||||||
|
valueFormat="x"
|
||||||
|
placeholder="选择${comment}"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "textarea")## 文本框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<Textarea v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
|
||||||
|
</Form.Item>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
</Form>
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
<!-- 子表的表单 -->
|
||||||
|
<Tabs v-model:active-key="subTabsName">
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
|
<Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}" force-render>
|
||||||
|
<${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData?.id" />
|
||||||
|
</Tabs.TabPane>
|
||||||
|
#end
|
||||||
|
</Tabs>
|
||||||
|
#end
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,442 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
import type { VxeTableInstance } from '#/adapter/vxe-table';
|
||||||
|
|
||||||
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
import { cloneDeep, formatDateTime } from '@vben/utils';
|
||||||
|
import { Button, message,Tabs,Pagination,Form,RangePicker,DatePicker,Select,Input } from 'ant-design-vue';
|
||||||
|
import { DictTag } from '#/components/dict-tag';
|
||||||
|
import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
|
||||||
|
import ${simpleClassName}Form from './modules/form.vue';
|
||||||
|
import { Download, Plus, RefreshCw, Search } from '@vben/icons';
|
||||||
|
import { ContentWrap } from '#/components/content-wrap';
|
||||||
|
import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
|
||||||
|
import { TableToolbar } from '#/components/table-toolbar';
|
||||||
|
import { useTableToolbar } from '#/hooks';
|
||||||
|
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 11 || $table.templateType == 12 )
|
||||||
|
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
|
||||||
|
import ${subSimpleClassName}List from './modules/${subSimpleClassName_strikeCase}-list.vue'
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
|
import { ref, h, reactive,onMounted,nextTick } from 'vue';
|
||||||
|
import { $t } from '#/locales';
|
||||||
|
#if (${table.templateType} == 2)## 树表接口
|
||||||
|
import { handleTree,isEmpty } from '@vben/utils'
|
||||||
|
import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
#else## 标准表接口
|
||||||
|
import { get${simpleClassName}Page, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
#end
|
||||||
|
import { downloadFileFromBlobPart } from '@vben/utils';
|
||||||
|
|
||||||
|
#if ($table.templateType == 12 || $table.templateType == 11) ## 内嵌和erp情况
|
||||||
|
/** 子表的列表 */
|
||||||
|
const subTabsName = ref('$subClassNameVars.get(0)')
|
||||||
|
#if ($table.templateType == 11)
|
||||||
|
const select${simpleClassName} = ref<${simpleClassName}Api.${simpleClassName}>();
|
||||||
|
async function onCellClick({ row }: { row: ${simpleClassName}Api.${simpleClassName} }) {
|
||||||
|
select${simpleClassName}.value = row
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
const list = ref<any[]>([]) // 树列表的数据
|
||||||
|
#else
|
||||||
|
const list = ref<${simpleClassName}Api.${simpleClassName}[]>([]) // 列表的数据
|
||||||
|
#end
|
||||||
|
|
||||||
|
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||||
|
#if ( $table.templateType != 2 )
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
#end
|
||||||
|
const queryParams = reactive({
|
||||||
|
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||||
|
#if ( $table.templateType != 2 )
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
#end
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#if ($column.listOperationCondition != 'BETWEEN')
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const params = cloneDeep(queryParams) as any;
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
|
||||||
|
if (params.${column.javaField} && Array.isArray(params.${column.javaField})) {
|
||||||
|
params.${column.javaField} = (params.${column.javaField} as string[]).join(',');
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
list.value = await get${simpleClassName}List(params);
|
||||||
|
#else
|
||||||
|
const data = await get${simpleClassName}Page(params)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
#end
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
#if ( $table.templateType != 2 )
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
#end
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
const [FormModal, formModalApi] = useVbenModal({
|
||||||
|
connectedComponent: ${simpleClassName}Form,
|
||||||
|
destroyOnClose: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 创建${table.classComment} */
|
||||||
|
function onCreate() {
|
||||||
|
formModalApi.setData({}).open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 编辑${table.classComment} */
|
||||||
|
function onEdit(row: ${simpleClassName}Api.${simpleClassName}) {
|
||||||
|
formModalApi.setData(row).open();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (${table.templateType} == 2)## 树表特有:新增下级
|
||||||
|
/** 新增下级${table.classComment} */
|
||||||
|
function onAppend(row: ${simpleClassName}Api.${simpleClassName}) {
|
||||||
|
formModalApi.setData({ ${treeParentColumn.javaField}: row.id }).open();
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
|
/** 删除${table.classComment} */
|
||||||
|
async function onDelete(row: ${simpleClassName}Api.${simpleClassName}) {
|
||||||
|
const hideLoading = message.loading({
|
||||||
|
content: $t('ui.actionMessage.deleting', [row.id]),
|
||||||
|
duration: 0,
|
||||||
|
key: 'action_process_msg',
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
await delete${simpleClassName}(row.id as number);
|
||||||
|
message.success({
|
||||||
|
content: $t('ui.actionMessage.deleteSuccess', [row.id]),
|
||||||
|
key: 'action_process_msg',
|
||||||
|
});
|
||||||
|
await getList();
|
||||||
|
} catch {
|
||||||
|
hideLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出表格 */
|
||||||
|
async function onExport() {
|
||||||
|
try {
|
||||||
|
exportLoading.value = true;
|
||||||
|
const data = await export${simpleClassName}(queryParams);
|
||||||
|
downloadFileFromBlobPart({ fileName: '${table.classComment}.xls', source: data });
|
||||||
|
}finally {
|
||||||
|
exportLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (${table.templateType} == 2)
|
||||||
|
/** 切换树形展开/收缩状态 */
|
||||||
|
const isExpanded = ref(true);
|
||||||
|
function toggleExpand() {
|
||||||
|
isExpanded.value = !isExpanded.value;
|
||||||
|
tableRef.value?.setAllTreeExpand(isExpanded.value);
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
|
/** 初始化 */
|
||||||
|
const { hiddenSearchBar, tableToolbarRef, tableRef } = useTableToolbar();
|
||||||
|
onMounted(() => {
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Page auto-content-height>
|
||||||
|
<FormModal @success="getList" />
|
||||||
|
|
||||||
|
<ContentWrap v-if="!hiddenSearchBar">
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<Form
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
layout="inline"
|
||||||
|
>
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "number")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "string")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "boolean")
|
||||||
|
#end
|
||||||
|
#if ($column.htmlType == "input")
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<Input
|
||||||
|
v-model:value="queryParams.${javaField}"
|
||||||
|
placeholder="请输入${comment}"
|
||||||
|
allowClear
|
||||||
|
@pressEnter="handleQuery"
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif ($column.htmlType == "select" || $column.htmlType == "radio" || $column.htmlType == "checkbox")
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<Select
|
||||||
|
v-model:value="queryParams.${javaField}"
|
||||||
|
placeholder="请选择${comment}"
|
||||||
|
allowClear
|
||||||
|
class="w-full"
|
||||||
|
>
|
||||||
|
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||||
|
<Select.Option
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Select.Option>
|
||||||
|
#else## 未设置 dictType 数据字典的情况
|
||||||
|
<Select.Option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "datetime")
|
||||||
|
#if ($column.listOperationCondition != "BETWEEN")## 非范围
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<DatePicker
|
||||||
|
v-model:value="queryParams.${javaField}"
|
||||||
|
valueFormat="YYYY-MM-DD"
|
||||||
|
placeholder="选择${comment}"
|
||||||
|
allowClear
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
#else## 范围
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<RangePicker
|
||||||
|
v-model:value="queryParams.${javaField}"
|
||||||
|
v-bind="getRangePickerDefaultProps()"
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
<Form.Item>
|
||||||
|
<Button class="ml-2" @click="resetQuery"> 重置 </Button>
|
||||||
|
<Button class="ml-2" @click="handleQuery" type="primary">
|
||||||
|
搜索
|
||||||
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap title="${table.classComment}">
|
||||||
|
<template #extra>
|
||||||
|
<TableToolbar
|
||||||
|
ref="tableToolbarRef"
|
||||||
|
v-model:hidden-search="hiddenSearchBar"
|
||||||
|
>
|
||||||
|
#if (${table.templateType} == 2)
|
||||||
|
<Button @click="toggleExpand" class="mr-2">
|
||||||
|
{{ isExpanded ? '收缩' : '展开' }}
|
||||||
|
</Button>
|
||||||
|
#end
|
||||||
|
<Button
|
||||||
|
class="ml-2"
|
||||||
|
:icon="h(Plus)"
|
||||||
|
type="primary"
|
||||||
|
@click="onCreate"
|
||||||
|
v-access:code="['${permissionPrefix}:create']"
|
||||||
|
>
|
||||||
|
{{ $t('ui.actionTitle.create', ['${table.classComment}']) }}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
:icon="h(Download)"
|
||||||
|
type="primary"
|
||||||
|
class="ml-2"
|
||||||
|
:loading="exportLoading"
|
||||||
|
@click="onExport"
|
||||||
|
v-access:code="['${permissionPrefix}:export']"
|
||||||
|
>
|
||||||
|
{{ $t('ui.actionTitle.export') }}
|
||||||
|
</Button>
|
||||||
|
</TableToolbar>
|
||||||
|
</template>
|
||||||
|
<vxe-table
|
||||||
|
ref="tableRef"
|
||||||
|
:data="list"
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
:tree-config="{
|
||||||
|
parentField: '${treeParentColumn.javaField}',
|
||||||
|
rowField: 'id',
|
||||||
|
transform: true,
|
||||||
|
expandAll: true,
|
||||||
|
reserve: true,
|
||||||
|
}"
|
||||||
|
#end
|
||||||
|
#if ($table.templateType == 11) ## erp情况
|
||||||
|
@cell-click="onCellClick"
|
||||||
|
:row-config="{
|
||||||
|
keyField: 'id',
|
||||||
|
isHover: true,
|
||||||
|
isCurrent: true,
|
||||||
|
}"
|
||||||
|
#end
|
||||||
|
show-overflow
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
|
||||||
|
<!-- 子表的列表 -->
|
||||||
|
<vxe-column type="expand" width="60">
|
||||||
|
<template #content="{ row }">
|
||||||
|
<!-- 子表的表单 -->
|
||||||
|
<Tabs v-model:active-key="subTabsName" class="mx-8">
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
|
<Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}" force-render>
|
||||||
|
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="row?.id" />
|
||||||
|
</Tabs.TabPane>
|
||||||
|
#end
|
||||||
|
</Tabs>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#end
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperationResult)
|
||||||
|
#set ($dictType=$column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
#set ($comment=$column.columnComment)
|
||||||
|
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
{{formatDateTime(row.${javaField})}}
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#elseif($column.dictType && "" != $column.dictType)## 数据字典
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="row.${javaField}" />
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#elseif ($table.templateType == 2 && $javaField == $treeNameColumn.javaField)
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center" tree-node/>
|
||||||
|
#else
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center" />
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
<vxe-column field="operation" title="操作" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="link"
|
||||||
|
@click="onAppend(row as any)"
|
||||||
|
v-access:code="['${permissionPrefix}:create']"
|
||||||
|
>
|
||||||
|
新增下级
|
||||||
|
</Button>
|
||||||
|
#end
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="link"
|
||||||
|
@click="onEdit(row as any)"
|
||||||
|
v-access:code="['${permissionPrefix}:update']"
|
||||||
|
>
|
||||||
|
{{ $t('ui.actionTitle.edit') }}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="link"
|
||||||
|
danger
|
||||||
|
class="ml-2"
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
:disabled="!isEmpty(row?.children)"
|
||||||
|
#end
|
||||||
|
@click="onDelete(row as any)"
|
||||||
|
v-access:code="['${permissionPrefix}:delete']"
|
||||||
|
>
|
||||||
|
{{ $t('ui.actionTitle.delete') }}
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
</vxe-table>
|
||||||
|
#if ( $table.templateType != 2 )
|
||||||
|
<!-- 分页 -->
|
||||||
|
<div class="mt-2 flex justify-end">
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:current="queryParams.pageNo"
|
||||||
|
v-model:page-size="queryParams.pageSize"
|
||||||
|
show-size-changer
|
||||||
|
@change="getList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
#end
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
#if ($table.templateType == 11) ## erp情况
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 子表的表单 -->
|
||||||
|
<Tabs v-model:active-key="subTabsName">
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
|
<Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}" force-render>
|
||||||
|
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="select${simpleClassName}?.id" />
|
||||||
|
</Tabs.TabPane>
|
||||||
|
#end
|
||||||
|
</Tabs>
|
||||||
|
</ContentWrap>
|
||||||
|
#end
|
||||||
|
</Page>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,212 @@
|
|||||||
|
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||||
|
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||||
|
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
import type { Rule } from 'ant-design-vue/es/form';
|
||||||
|
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import { Tinymce as RichTextarea } from '#/components/tinymce';
|
||||||
|
import { ImageUpload, FileUpload } from "#/components/upload";
|
||||||
|
import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker, TreeSelect } from 'ant-design-vue';
|
||||||
|
import { DICT_TYPE, getDictOptions } from '#/utils';
|
||||||
|
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
|
import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
|
||||||
|
const emit = defineEmits(['success']);
|
||||||
|
const getTitle = computed(() => {
|
||||||
|
return formData.value?.id
|
||||||
|
? $t('ui.actionTitle.edit', ['${subTable.classComment}'])
|
||||||
|
: $t('ui.actionTitle.create', ['${subTable.classComment}']);
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const formData = ref<Partial<${simpleClassName}Api.${subSimpleClassName}>>({
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if ($column.htmlType == "checkbox")
|
||||||
|
$column.javaField: [],
|
||||||
|
#else
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
});
|
||||||
|
const rules: Record<string, Rule[]> = {
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||||
|
#set($comment=$column.columnComment)
|
||||||
|
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
};
|
||||||
|
|
||||||
|
const [Modal, modalApi] = useVbenModal({
|
||||||
|
async onConfirm() {
|
||||||
|
await formRef.value?.validate();
|
||||||
|
|
||||||
|
modalApi.lock();
|
||||||
|
// 提交表单
|
||||||
|
const data = formData.value as ${simpleClassName}Api.${subSimpleClassName};
|
||||||
|
try {
|
||||||
|
await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data));
|
||||||
|
// 关闭并提示
|
||||||
|
await modalApi.close();
|
||||||
|
emit('success');
|
||||||
|
message.success({
|
||||||
|
content: $t('ui.actionMessage.operationSuccess'),
|
||||||
|
key: 'action_process_msg',
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
modalApi.unlock();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async onOpenChange(isOpen: boolean) {
|
||||||
|
if (!isOpen) {
|
||||||
|
resetForm()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载数据
|
||||||
|
let data = modalApi.getData<${simpleClassName}Api.${subSimpleClassName}>();
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data.id) {
|
||||||
|
modalApi.lock();
|
||||||
|
try {
|
||||||
|
data = await get${subSimpleClassName}(data.id);
|
||||||
|
} finally {
|
||||||
|
modalApi.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 设置到 values
|
||||||
|
formData.value = data;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if ($column.htmlType == "checkbox")
|
||||||
|
$column.javaField: [],
|
||||||
|
#else
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
};
|
||||||
|
formRef.value?.resetFields();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Modal :title="getTitle">
|
||||||
|
<Form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="rules"
|
||||||
|
:label-col="{ span: 5 }"
|
||||||
|
:wrapper-col="{ span: 18 }"
|
||||||
|
>
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "number")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "string")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "boolean")
|
||||||
|
#end
|
||||||
|
#if ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<Input v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<ImageUpload v-model:value="formData.${javaField}" />
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<FileUpload v-model:value="formData.${javaField}" />
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<RichTextarea v-model="formData.${javaField}" height="500px" />
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<Select v-model:value="formData.${javaField}" placeholder="请选择${comment}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<Select.Option
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Select.Option>
|
||||||
|
#else##没数据字典
|
||||||
|
<Select.Option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<CheckboxGroup v-model:value="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<Checkbox
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Checkbox>
|
||||||
|
#else##没数据字典
|
||||||
|
<Checkbox label="请选择字典生成" />
|
||||||
|
#end
|
||||||
|
</CheckboxGroup>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<RadioGroup v-model:value="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<Radio
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Radio>
|
||||||
|
#else##没数据字典
|
||||||
|
<Radio value="1">请选择字典生成</Radio>
|
||||||
|
#end
|
||||||
|
</RadioGroup>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<DatePicker
|
||||||
|
v-model:value="formData.${javaField}"
|
||||||
|
valueFormat="x"
|
||||||
|
placeholder="选择${comment}"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "textarea")## 文本框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<Textarea v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
|
||||||
|
</Form.Item>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
## 主表的 normal 和 inner 使用相同的 form 表单
|
||||||
|
#parse("codegen/vue3_vben5_antd/general/views/modules/form_sub_normal.vue.vm")
|
||||||
@ -0,0 +1,338 @@
|
|||||||
|
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||||
|
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||||
|
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($subIndex))
|
||||||
|
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
|
||||||
|
import { message, Tabs, Form, Input, Textarea,Button, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker } from 'ant-design-vue';
|
||||||
|
import { computed, ref, h, onMounted,watch,nextTick } from 'vue';
|
||||||
|
import { $t } from '#/locales';
|
||||||
|
import { DICT_TYPE, getDictOptions } from '#/utils';
|
||||||
|
|
||||||
|
#if ($subTable.subJoinMany) ## 一对多
|
||||||
|
import type { VxeTableInstance } from '#/adapter/vxe-table';
|
||||||
|
import { Plus } from "@vben/icons";
|
||||||
|
import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
|
||||||
|
import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
#else
|
||||||
|
import type { Rule } from 'ant-design-vue/es/form';
|
||||||
|
import { Tinymce as RichTextarea } from '#/components/tinymce';
|
||||||
|
import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
#end
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
|
||||||
|
}>()
|
||||||
|
|
||||||
|
#if ($subTable.subJoinMany) ## 一对多
|
||||||
|
const list = ref<${simpleClassName}Api.${subSimpleClassName}[]>([]) // 列表的数据
|
||||||
|
const tableRef = ref<VxeTableInstance>();
|
||||||
|
/** 添加${subTable.classComment} */
|
||||||
|
const onAdd = async () => {
|
||||||
|
await tableRef.value?.insertAt({} as ${simpleClassName}Api.${subSimpleClassName}, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除${subTable.classComment} */
|
||||||
|
const onDelete = async (row: ${simpleClassName}Api.${subSimpleClassName}) => {
|
||||||
|
await tableRef.value?.remove(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 提供获取表格数据的方法供父组件调用 */
|
||||||
|
defineExpose({
|
||||||
|
getData: (): ${simpleClassName}Api.${subSimpleClassName}[] => {
|
||||||
|
const data = list.value as ${simpleClassName}Api.${subSimpleClassName}[];
|
||||||
|
const removeRecords = tableRef.value?.getRemoveRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
|
||||||
|
const insertRecords = tableRef.value?.getInsertRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
|
||||||
|
return data
|
||||||
|
.filter((row) => !removeRecords.some((removed) => removed.id === row.id))
|
||||||
|
?.concat(insertRecords.map((row: any) => ({ ...row, id: undefined })));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
watch(
|
||||||
|
() => props.${subJoinColumn.javaField},
|
||||||
|
async (val) => {
|
||||||
|
if (!val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
list.value = await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!);
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
const formRef = ref();
|
||||||
|
const formData = ref<Partial<${simpleClassName}Api.${subSimpleClassName}>>({
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if ($column.htmlType == "checkbox")
|
||||||
|
$column.javaField: [],
|
||||||
|
#else
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
});
|
||||||
|
const rules: Record<string, Rule[]> = {
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||||
|
#set($comment=$column.columnComment)
|
||||||
|
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
};
|
||||||
|
/** 暴露出表单校验方法和表单值获取方法 */
|
||||||
|
defineExpose({
|
||||||
|
validate: async () => await formRef.value?.validate(),
|
||||||
|
getValues: ()=> formData.value,
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
watch(
|
||||||
|
() => props.${subJoinColumn.javaField},
|
||||||
|
async (val) => {
|
||||||
|
if (!val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await nextTick();
|
||||||
|
formData.value = await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!);
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
#end
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
#if ($subTable.subJoinMany) ## 一对多
|
||||||
|
<vxe-table ref="tableRef" :data="list" show-overflow class="mx-4">
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "number")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "string")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "boolean")
|
||||||
|
#end
|
||||||
|
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||||
|
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
<Input v-model:value="row.${javaField}" />
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
<ImageUpload v-model:value="row.${javaField}" />
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
<FileUpload v-model:value="row.${javaField}" />
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
<Select v-model:value="row.${javaField}" placeholder="请选择${comment}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<Select.Option
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Select.Option>
|
||||||
|
#else##没数据字典
|
||||||
|
<Select.Option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</Select>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
<CheckboxGroup v-model:value="row.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<Checkbox
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Checkbox>
|
||||||
|
#else##没数据字典
|
||||||
|
<Checkbox label="请选择字典生成" />
|
||||||
|
#end
|
||||||
|
</CheckboxGroup>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
<RadioGroup v-model:value="row.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<Radio
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Radio>
|
||||||
|
#else##没数据字典
|
||||||
|
<Radio value="1">请选择字典生成</Radio>
|
||||||
|
#end
|
||||||
|
</RadioGroup>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
<DatePicker
|
||||||
|
v-model:value="row.${javaField}"
|
||||||
|
:showTime="true"
|
||||||
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
valueFormat='x'
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#elseif($column.htmlType == "textarea" || $column.htmlType == "editor")## 文本框
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
<Textarea v-model:value="row.${javaField}" />
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
<vxe-column field="operation" title="操作" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="link"
|
||||||
|
danger
|
||||||
|
@click="onDelete(row as any)"
|
||||||
|
v-access:code="['${permissionPrefix}:delete']"
|
||||||
|
>
|
||||||
|
{{ $t('ui.actionTitle.delete') }}
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
</vxe-table>
|
||||||
|
<div class="flex justify-center mt-4">
|
||||||
|
<Button :icon="h(Plus)" type="primary" ghost @click="onAdd" v-access:code="['${permissionPrefix}:create']">
|
||||||
|
{{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
#else
|
||||||
|
<Form
|
||||||
|
ref="formRef"
|
||||||
|
class="mx-4"
|
||||||
|
:model="formData"
|
||||||
|
:rules="rules"
|
||||||
|
:label-col="{ span: 5 }"
|
||||||
|
:wrapper-col="{ span: 18 }"
|
||||||
|
>
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "number")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "string")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "boolean")
|
||||||
|
#end
|
||||||
|
#if ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<Input v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<ImageUpload v-model:value="formData.${javaField}" />
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<FileUpload v-model:value="formData.${javaField}" />
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<RichTextarea v-model="formData.${javaField}" height="500px" />
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<Select v-model:value="formData.${javaField}" placeholder="请选择${comment}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<Select.Option
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Select.Option>
|
||||||
|
#else##没数据字典
|
||||||
|
<Select.Option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<CheckboxGroup v-model:value="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<Checkbox
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Checkbox>
|
||||||
|
#else##没数据字典
|
||||||
|
<Checkbox label="请选择字典生成" />
|
||||||
|
#end
|
||||||
|
</CheckboxGroup>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<RadioGroup v-model:value="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<Radio
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Radio>
|
||||||
|
#else##没数据字典
|
||||||
|
<Radio value="1">请选择字典生成</Radio>
|
||||||
|
#end
|
||||||
|
</RadioGroup>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<DatePicker
|
||||||
|
v-model:value="formData.${javaField}"
|
||||||
|
valueFormat="x"
|
||||||
|
placeholder="选择${comment}"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "textarea")## 文本框
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<Textarea v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
|
||||||
|
</Form.Item>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
</Form>
|
||||||
|
#end
|
||||||
|
</template>
|
||||||
@ -0,0 +1,379 @@
|
|||||||
|
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||||
|
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||||
|
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||||
|
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||||
|
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex))
|
||||||
|
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
import type { VxeTableInstance } from '#/adapter/vxe-table';
|
||||||
|
|
||||||
|
import { DictTag } from '#/components/dict-tag';
|
||||||
|
import { DICT_TYPE, getDictOptions } from '#/utils';
|
||||||
|
import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
|
||||||
|
import { reactive,ref, h, nextTick,watch,onMounted } from 'vue';
|
||||||
|
import { cloneDeep, formatDateTime } from '@vben/utils';
|
||||||
|
import { ContentWrap } from '#/components/content-wrap';
|
||||||
|
|
||||||
|
#if ($table.templateType == 11) ## erp
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
|
||||||
|
import { Tinymce as RichTextarea } from '#/components/tinymce';
|
||||||
|
import { ImageUpload, FileUpload } from "#/components/upload";
|
||||||
|
import { message,Button, Tabs,Pagination, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox,RangePicker, DatePicker, TreeSelect } from 'ant-design-vue';
|
||||||
|
import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
|
||||||
|
import { Plus } from '@vben/icons';
|
||||||
|
import { $t } from '#/locales';
|
||||||
|
import { TableToolbar } from '#/components/table-toolbar';
|
||||||
|
import { useTableToolbar } from '#/hooks';
|
||||||
|
#end
|
||||||
|
|
||||||
|
#if ($table.templateType == 11) ## erp
|
||||||
|
import { delete${subSimpleClassName}, get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
#else
|
||||||
|
#if ($subTable.subJoinMany) ## 一对多
|
||||||
|
import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
#else
|
||||||
|
import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
|
||||||
|
}>()
|
||||||
|
|
||||||
|
#if ($table.templateType == 11) ## erp
|
||||||
|
const [FormModal, formModalApi] = useVbenModal({
|
||||||
|
connectedComponent: ${subSimpleClassName}Form,
|
||||||
|
destroyOnClose: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 创建${subTable.classComment} */
|
||||||
|
function onCreate() {
|
||||||
|
if (!props.${subJoinColumn.javaField}){
|
||||||
|
message.warning("请先选择一个${table.classComment}!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
formModalApi.setData({${subJoinColumn.javaField}: props.${subJoinColumn.javaField}}).open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 编辑${subTable.classComment} */
|
||||||
|
function onEdit(row: ${simpleClassName}Api.${subSimpleClassName}) {
|
||||||
|
formModalApi.setData(row).open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除${subTable.classComment} */
|
||||||
|
async function onDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
|
||||||
|
const hideLoading = message.loading({
|
||||||
|
content: $t('ui.actionMessage.deleting', [row.id]),
|
||||||
|
duration: 0,
|
||||||
|
key: 'action_process_msg',
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
await delete${subSimpleClassName}(row.id as number);
|
||||||
|
message.success({
|
||||||
|
content: $t('ui.actionMessage.deleteSuccess', [row.id]),
|
||||||
|
key: 'action_process_msg',
|
||||||
|
});
|
||||||
|
getList();
|
||||||
|
} catch {
|
||||||
|
hideLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<${simpleClassName}Api.${subSimpleClassName}[]>([]) // 列表的数据
|
||||||
|
#if ($table.templateType == 11) ## erp
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
#end
|
||||||
|
#if ($table.templateType == 11) ## erp
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#if ($column.listOperationCondition != 'BETWEEN')
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
if (!props.${subJoinColumn.javaField}){
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||||
|
#if ($table.templateType == 11) ## erp
|
||||||
|
const params = cloneDeep(queryParams) as any;
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
|
||||||
|
if (params.${column.javaField} && Array.isArray(params.${column.javaField})) {
|
||||||
|
params.${column.javaField} = (params.${column.javaField} as string[]).join(',');
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
params.${subJoinColumn.javaField} = props.${subJoinColumn.javaField};
|
||||||
|
const data = await get${subSimpleClassName}Page(params)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
#else
|
||||||
|
#if ($subTable.subJoinMany) ## 一对多
|
||||||
|
list.value = await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!);
|
||||||
|
#else
|
||||||
|
list.value = [await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!)];
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
watch(
|
||||||
|
() => props.${subJoinColumn.javaField},
|
||||||
|
async (val) => {
|
||||||
|
if (!val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await nextTick();
|
||||||
|
await getList()
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
#if ($table.templateType == 11) ## erp
|
||||||
|
/** 初始化 */
|
||||||
|
const { hiddenSearchBar, tableToolbarRef, tableRef } = useTableToolbar();
|
||||||
|
onMounted(() => {
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
#end
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
#if ($table.templateType == 11) ## erp
|
||||||
|
<FormModal @success="getList" />
|
||||||
|
<div class="h-[600px]">
|
||||||
|
<ContentWrap v-if="!hiddenSearchBar">
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<Form
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
layout="inline"
|
||||||
|
>
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "number")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "string")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "boolean")
|
||||||
|
#end
|
||||||
|
#if ($column.htmlType == "input")
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<Input
|
||||||
|
v-model:value="queryParams.${javaField}"
|
||||||
|
placeholder="请输入${comment}"
|
||||||
|
allowClear
|
||||||
|
@pressEnter="handleQuery"
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif ($column.htmlType == "select" || $column.htmlType == "radio" || $column.htmlType == "checkbox")
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<Select
|
||||||
|
v-model:value="queryParams.${javaField}"
|
||||||
|
placeholder="请选择${comment}"
|
||||||
|
allowClear
|
||||||
|
class="w-full"
|
||||||
|
>
|
||||||
|
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||||
|
<Select.Option
|
||||||
|
v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</Select.Option>
|
||||||
|
#else## 未设置 dictType 数据字典的情况
|
||||||
|
<Select.Option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
#elseif($column.htmlType == "datetime")
|
||||||
|
#if ($column.listOperationCondition != "BETWEEN")## 非范围
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<DatePicker
|
||||||
|
v-model:value="queryParams.${javaField}"
|
||||||
|
valueFormat="YYYY-MM-DD"
|
||||||
|
placeholder="选择${comment}"
|
||||||
|
allowClear
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
#else## 范围
|
||||||
|
<Form.Item label="${comment}" name="${javaField}">
|
||||||
|
<RangePicker
|
||||||
|
v-model:value="queryParams.${javaField}"
|
||||||
|
v-bind="getRangePickerDefaultProps()"
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
<Form.Item>
|
||||||
|
<Button class="ml-2" @click="resetQuery"> 重置 </Button>
|
||||||
|
<Button class="ml-2" @click="handleQuery" type="primary">
|
||||||
|
搜索
|
||||||
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap title="${table.classComment}">
|
||||||
|
<template #extra>
|
||||||
|
<TableToolbar
|
||||||
|
ref="tableToolbarRef"
|
||||||
|
v-model:hidden-search="hiddenSearchBar"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
class="ml-2"
|
||||||
|
:icon="h(Plus)"
|
||||||
|
type="primary"
|
||||||
|
@click="onCreate"
|
||||||
|
v-access:code="['${permissionPrefix}:create']"
|
||||||
|
>
|
||||||
|
{{ $t('ui.actionTitle.create', ['${table.classComment}']) }}
|
||||||
|
</Button>
|
||||||
|
</TableToolbar>
|
||||||
|
</template>
|
||||||
|
<vxe-table
|
||||||
|
ref="tableRef"
|
||||||
|
:data="list"
|
||||||
|
show-overflow
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.listOperationResult)
|
||||||
|
#set ($dictType=$column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($comment=$column.columnComment)
|
||||||
|
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
{{formatDateTime(row.${javaField})}}
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#elseif($column.dictType && "" != $column.dictType)## 数据字典
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="row.${javaField}" />
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#elseif ($table.templateType == 2 && $javaField == $treeNameColumn.javaField)
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center" tree-node/>
|
||||||
|
#else
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center" />
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
<vxe-column field="operation" title="操作" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="link"
|
||||||
|
@click="onEdit(row as any)"
|
||||||
|
v-access:code="['${permissionPrefix}:update']"
|
||||||
|
>
|
||||||
|
{{ $t('ui.actionTitle.edit') }}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="link"
|
||||||
|
danger
|
||||||
|
class="ml-2"
|
||||||
|
@click="onDelete(row as any)"
|
||||||
|
v-access:code="['${permissionPrefix}:delete']"
|
||||||
|
>
|
||||||
|
{{ $t('ui.actionTitle.delete') }}
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
</vxe-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<div class="mt-2 flex justify-end">
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:current="queryParams.pageNo"
|
||||||
|
v-model:page-size="queryParams.pageSize"
|
||||||
|
show-size-changer
|
||||||
|
@change="getList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</ContentWrap>
|
||||||
|
</div>
|
||||||
|
#else
|
||||||
|
<ContentWrap title="${subTable.classComment}列表">
|
||||||
|
<vxe-table
|
||||||
|
:data="list"
|
||||||
|
show-overflow
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.listOperationResult)
|
||||||
|
#set ($dictType=$column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($comment=$column.columnComment)
|
||||||
|
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
{{formatDateTime(row.${javaField})}}
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#elseif($column.dictType && "" != $column.dictType)## 数据字典
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center">
|
||||||
|
<template #default="{row}">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="row.${javaField}" />
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
#else
|
||||||
|
<vxe-column field="${javaField}" title="${comment}" align="center" />
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
</vxe-table>
|
||||||
|
</ContentWrap>
|
||||||
|
#end
|
||||||
|
</template>
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
## 子表的 erp 和 inner 使用相似的 list 列表,差异主要两点:
|
||||||
|
## 1)inner 使用 list 不分页,erp 使用 page 分页
|
||||||
|
## 2)erp 支持单个子表的新增、修改、删除,inner 不支持
|
||||||
|
#parse("codegen/vue3_vben5_antd/general/views/modules/list_sub_erp.vue.vm")
|
||||||
@ -0,0 +1,153 @@
|
|||||||
|
import type { PageParam, PageResult } from '@vben/request';
|
||||||
|
import type { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
|
import { requestClient } from '#/api/request';
|
||||||
|
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||||
|
|
||||||
|
export namespace ${simpleClassName}Api {
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#set ($subColumns = $subColumnsList.get($index))##当前字段数组
|
||||||
|
/** ${subTable.classComment}信息 */
|
||||||
|
export interface ${subSimpleClassName} {
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
|
||||||
|
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
|
||||||
|
#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
|
||||||
|
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
|
||||||
|
#else
|
||||||
|
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
|
||||||
|
#end
|
||||||
|
/** ${table.classComment}信息 */
|
||||||
|
export interface ${simpleClassName} {
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
|
||||||
|
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
|
||||||
|
#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
|
||||||
|
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
|
||||||
|
#else
|
||||||
|
${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
children?: ${simpleClassName}[];
|
||||||
|
#end
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#if ( $subTable.subJoinMany )
|
||||||
|
${subSimpleClassName.toLowerCase()}s?: ${subSimpleClassName}[]
|
||||||
|
#else
|
||||||
|
${subSimpleClassName.toLowerCase()}?: ${subSimpleClassName}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ( $table.templateType != 2 )
|
||||||
|
/** 查询${table.classComment}分页 */
|
||||||
|
export function get${simpleClassName}Page(params: PageParam) {
|
||||||
|
return requestClient.get<PageResult<${simpleClassName}Api.${simpleClassName}>>('${baseURL}/page', { params });
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/** 查询${table.classComment}列表 */
|
||||||
|
export function get${simpleClassName}List(params: any) {
|
||||||
|
return requestClient.get<${simpleClassName}Api.${simpleClassName}[]>('${baseURL}/list', { params });
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
|
/** 查询${table.classComment}详情 */
|
||||||
|
export function get${simpleClassName}(id: number) {
|
||||||
|
return requestClient.get<${simpleClassName}Api.${simpleClassName}>(`${baseURL}/get?id=${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 新增${table.classComment} */
|
||||||
|
export function create${simpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) {
|
||||||
|
return requestClient.post('${baseURL}/create', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改${table.classComment} */
|
||||||
|
export function update${simpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) {
|
||||||
|
return requestClient.put('${baseURL}/update', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除${table.classComment} */
|
||||||
|
export function delete${simpleClassName}(id: number) {
|
||||||
|
return requestClient.delete(`${baseURL}/delete?id=${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出${table.classComment} */
|
||||||
|
export function export${simpleClassName}(params: any) {
|
||||||
|
return requestClient.download('${baseURL}/export-excel', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
|
||||||
|
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||||
|
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||||
|
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
|
||||||
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
|
||||||
|
// ==================== 子表($subTable.classComment) ====================
|
||||||
|
|
||||||
|
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||||
|
#if ( $table.templateType == 11 )
|
||||||
|
/** 获得${subTable.classComment}分页 */
|
||||||
|
export function get${subSimpleClassName}Page(params: PageParam) {
|
||||||
|
return requestClient.get<PageResult<${simpleClassName}Api.${subSimpleClassName}>>(`${baseURL}/${subSimpleClassName_strikeCase}/page`, { params });
|
||||||
|
}
|
||||||
|
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||||
|
#else
|
||||||
|
#if ( $subTable.subJoinMany )
|
||||||
|
/** 获得${subTable.classComment}列表 */
|
||||||
|
export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
|
||||||
|
return requestClient.get<${simpleClassName}Api.${subSimpleClassName}[]>(`${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/** 获得${subTable.classComment} */
|
||||||
|
export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
|
||||||
|
return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||||
|
#if ( $table.templateType == 11 )
|
||||||
|
/** 新增${subTable.classComment} */
|
||||||
|
export function create${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
|
||||||
|
return requestClient.post(`${baseURL}/${subSimpleClassName_strikeCase}/create`, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改${subTable.classComment} */
|
||||||
|
export function update${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
|
||||||
|
return requestClient.put(`${baseURL}/${subSimpleClassName_strikeCase}/update`, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除${subTable.classComment} */
|
||||||
|
export function delete${subSimpleClassName}(id: number) {
|
||||||
|
return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete?id=${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获得${subTable.classComment} */
|
||||||
|
export function get${subSimpleClassName}(id: number) {
|
||||||
|
return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get?id=${id}`);
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
@ -0,0 +1,676 @@
|
|||||||
|
import type { VbenFormSchema } from '#/adapter/form';
|
||||||
|
import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
|
||||||
|
import { z } from '#/adapter/form';
|
||||||
|
#if(${table.templateType} == 2)## 树表需要导入这些
|
||||||
|
import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
import { handleTree } from '@vben/utils';
|
||||||
|
#end
|
||||||
|
import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
|
||||||
|
import { useAccess } from '@vben/access';
|
||||||
|
|
||||||
|
const { hasAccessByCodes } = useAccess();
|
||||||
|
|
||||||
|
/** 新增/修改的表单 */
|
||||||
|
export function useFormSchema(): VbenFormSchema[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
fieldName: 'id',
|
||||||
|
component: 'Input',
|
||||||
|
dependencies: {
|
||||||
|
triggerFields: [''],
|
||||||
|
show: () => false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
#if(${table.templateType} == 2)## 树表特有字段:上级
|
||||||
|
{
|
||||||
|
fieldName: '${treeParentColumn.javaField}',
|
||||||
|
label: '上级${table.classComment}',
|
||||||
|
component: 'ApiTreeSelect',
|
||||||
|
componentProps: {
|
||||||
|
allowClear: true,
|
||||||
|
api: async () => {
|
||||||
|
const data = await get${simpleClassName}List({});
|
||||||
|
data.unshift({
|
||||||
|
id: 0,
|
||||||
|
${treeNameColumn.javaField}: '顶级${table.classComment}',
|
||||||
|
});
|
||||||
|
return handleTree(data);
|
||||||
|
},
|
||||||
|
labelField: '${treeNameColumn.javaField}',
|
||||||
|
valueField: 'id',
|
||||||
|
childrenField: 'children',
|
||||||
|
placeholder: '请选择上级${table.classComment}',
|
||||||
|
treeDefaultExpandAll: true,
|
||||||
|
},
|
||||||
|
rules: 'selectRequired',
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if (!$column.primaryKey && ($table.templateType != 2 || ($table.templateType == 2 && $column.id != $treeParentColumn.id)))## 树表中已经添加了父ID字段,这里排除
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "number")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "string")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "boolean")
|
||||||
|
#end
|
||||||
|
{
|
||||||
|
fieldName: '${javaField}',
|
||||||
|
label: '${comment}',
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||||
|
rules: 'required',
|
||||||
|
#end
|
||||||
|
#if ($column.htmlType == "input")
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入${comment}',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
component: 'ImageUpload',
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
component: 'FileUpload',
|
||||||
|
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||||
|
component: 'RichTextarea',
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||||
|
#else##没数据字典
|
||||||
|
options: [],
|
||||||
|
#end
|
||||||
|
placeholder: '请选择${comment}',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
component: 'Checkbox',
|
||||||
|
componentProps: {
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||||
|
#else##没数据字典
|
||||||
|
options: [],
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
component: 'RadioGroup',
|
||||||
|
componentProps: {
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||||
|
#else##没数据字典
|
||||||
|
options: [],
|
||||||
|
#end
|
||||||
|
buttonStyle: 'solid',
|
||||||
|
optionType: 'button',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime: true,
|
||||||
|
format: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
valueFormat: 'x',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "textarea")## 文本域
|
||||||
|
component: 'Textarea',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入${comment}',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "inputNumber")## 数字输入框
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
min: 0,
|
||||||
|
controlsPosition: 'right',
|
||||||
|
placeholder: '请输入${comment}',
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 列表的搜索表单 */
|
||||||
|
export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
|
return [
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "number")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "string")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "boolean")
|
||||||
|
#end
|
||||||
|
{
|
||||||
|
fieldName: '${javaField}',
|
||||||
|
label: '${comment}',
|
||||||
|
#if ($column.htmlType == "input" || $column.htmlType == "textarea" || $column.htmlType == "editor")
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
allowClear: true,
|
||||||
|
placeholder: '请输入${comment}',
|
||||||
|
},
|
||||||
|
#elseif ($column.htmlType == "select" || $column.htmlType == "radio")
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
allowClear: true,
|
||||||
|
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||||
|
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||||
|
#else## 未设置 dictType 数据字典的情况
|
||||||
|
options: [],
|
||||||
|
#end
|
||||||
|
placeholder: '请选择${comment}',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "datetime")
|
||||||
|
component: 'RangePicker',
|
||||||
|
componentProps: {
|
||||||
|
...getRangePickerDefaultProps(),
|
||||||
|
allowClear: true,
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 列表的字段 */
|
||||||
|
export function useGridColumns(
|
||||||
|
onActionClick?: OnActionClickFn<${simpleClassName}Api.${simpleClassName}>,
|
||||||
|
): VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>['columns'] {
|
||||||
|
return [
|
||||||
|
#if ($table.templateType == 12) ## 内嵌情况
|
||||||
|
{ type: 'expand', width: 80, slots: { content: 'expand_content' } },
|
||||||
|
#end
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperationResult)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
{
|
||||||
|
field: '${javaField}',
|
||||||
|
title: '${comment}',
|
||||||
|
minWidth: 120,
|
||||||
|
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||||
|
formatter: 'formatDateTime',
|
||||||
|
#elseif("" != $dictType)## 数据字典
|
||||||
|
cellRender: {
|
||||||
|
name: 'CellDict',
|
||||||
|
props: { type: DICT_TYPE.$dictType.toUpperCase() },
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#if (${table.templateType} == 2 && $column.id == $treeNameColumn.id)## 树表特有:标记树节点列
|
||||||
|
treeNode: true,
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
{
|
||||||
|
field: 'operation',
|
||||||
|
title: '操作',
|
||||||
|
minWidth: 200,
|
||||||
|
align: 'center',
|
||||||
|
fixed: 'right',
|
||||||
|
headerAlign: 'center',
|
||||||
|
showOverflow: false,
|
||||||
|
cellRender: {
|
||||||
|
attrs: {
|
||||||
|
nameField: '${columns[0].javaField}',
|
||||||
|
nameTitle: '${table.classComment}',
|
||||||
|
onClick: onActionClick,
|
||||||
|
},
|
||||||
|
name: 'CellOperation',
|
||||||
|
options: [
|
||||||
|
#if (${table.templateType} == 2)## 树表特有操作
|
||||||
|
{
|
||||||
|
code: 'append',
|
||||||
|
text: '新增下级',
|
||||||
|
show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:create']),
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
{
|
||||||
|
code: 'edit',
|
||||||
|
show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:update']),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'delete',
|
||||||
|
show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:delete']),
|
||||||
|
#if (${table.templateType} == 2)## 树表禁止删除带有子节点的数据
|
||||||
|
disabled: (row: ${simpleClassName}Api.${simpleClassName}) => {
|
||||||
|
return !!(row.children && row.children.length > 0);
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
## 标准模式和内嵌模式时,主子关系一对一则生成表单schema,一对多则生成列表schema(内嵌模式时表单schema也要生成)。erp 模式时都生成
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subColumns = $subColumnsList.get($index))##当前字段数组
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||||
|
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
|
||||||
|
// ==================== 子表($subTable.classComment) ====================
|
||||||
|
|
||||||
|
#if ($table.templateType == 11) ## erp 情况
|
||||||
|
/** 新增/修改的表单 */
|
||||||
|
export function use${subSimpleClassName}FormSchema(): VbenFormSchema[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
fieldName: 'id',
|
||||||
|
component: 'Input',
|
||||||
|
dependencies: {
|
||||||
|
triggerFields: [''],
|
||||||
|
show: () => false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if (!$column.primaryKey && ($table.templateType != 2 || ($table.templateType == 2 && $column.id != $treeParentColumn.id)))## 树表中已经添加了父ID字段,这里排除
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "number")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "string")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "boolean")
|
||||||
|
#end
|
||||||
|
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
fieldName: '${javaField}',
|
||||||
|
label: '${comment}',
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||||
|
rules: 'required',
|
||||||
|
#end
|
||||||
|
#if ($column.htmlType == "input")
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入${comment}',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
component: 'ImageUpload',
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
component: 'FileUpload',
|
||||||
|
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||||
|
component: 'RichTextarea',
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||||
|
#else##没数据字典
|
||||||
|
options: [],
|
||||||
|
#end
|
||||||
|
placeholder: '请选择${comment}',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
component: 'Checkbox',
|
||||||
|
componentProps: {
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||||
|
#else##没数据字典
|
||||||
|
options: [],
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
component: 'RadioGroup',
|
||||||
|
componentProps: {
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||||
|
#else##没数据字典
|
||||||
|
options: [],
|
||||||
|
#end
|
||||||
|
buttonStyle: 'solid',
|
||||||
|
optionType: 'button',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime: true,
|
||||||
|
format: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
valueFormat: 'x',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "textarea")## 文本域
|
||||||
|
component: 'Textarea',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入${comment}',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "inputNumber")## 数字输入框
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
min: 0,
|
||||||
|
controlsPosition: 'right',
|
||||||
|
placeholder: '请输入${comment}',
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 列表的搜索表单 */
|
||||||
|
export function use${subSimpleClassName}GridFormSchema(): VbenFormSchema[] {
|
||||||
|
return [
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "number")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "string")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "boolean")
|
||||||
|
#end
|
||||||
|
{
|
||||||
|
fieldName: '${javaField}',
|
||||||
|
label: '${comment}',
|
||||||
|
#if ($column.htmlType == "input" || $column.htmlType == "textarea" || $column.htmlType == "editor")
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
allowClear: true,
|
||||||
|
placeholder: '请输入${comment}',
|
||||||
|
},
|
||||||
|
#elseif ($column.htmlType == "select" || $column.htmlType == "radio")
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
allowClear: true,
|
||||||
|
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||||
|
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||||
|
#else## 未设置 dictType 数据字典的情况
|
||||||
|
options: [],
|
||||||
|
#end
|
||||||
|
placeholder: '请选择${comment}',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "datetime")
|
||||||
|
component: 'RangePicker',
|
||||||
|
componentProps: {
|
||||||
|
...getRangePickerDefaultProps(),
|
||||||
|
allowClear: true,
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 列表的字段 */
|
||||||
|
export function use${subSimpleClassName}GridColumns(
|
||||||
|
onActionClick?: OnActionClickFn<${simpleClassName}Api.${subSimpleClassName}>,
|
||||||
|
): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {
|
||||||
|
return [
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.listOperationResult)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
{
|
||||||
|
field: '${javaField}',
|
||||||
|
title: '${comment}',
|
||||||
|
minWidth: 120,
|
||||||
|
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||||
|
formatter: 'formatDateTime',
|
||||||
|
#elseif("" != $dictType)## 数据字典
|
||||||
|
cellRender: {
|
||||||
|
name: 'CellDict',
|
||||||
|
props: { type: DICT_TYPE.$dictType.toUpperCase() },
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
{
|
||||||
|
field: 'operation',
|
||||||
|
title: '操作',
|
||||||
|
minWidth: 200,
|
||||||
|
align: 'center',
|
||||||
|
fixed: 'right',
|
||||||
|
headerAlign: 'center',
|
||||||
|
showOverflow: false,
|
||||||
|
cellRender: {
|
||||||
|
attrs: {
|
||||||
|
nameField: '${columns[0].javaField}',
|
||||||
|
nameTitle: '${subTable.classComment}',
|
||||||
|
onClick: onActionClick,
|
||||||
|
},
|
||||||
|
name: 'CellOperation',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
code: 'edit',
|
||||||
|
show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:update']),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'delete',
|
||||||
|
show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:delete']),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#if ($subTable.subJoinMany) ## 一对多
|
||||||
|
/** 新增/修改列表的字段 */
|
||||||
|
export function use${subSimpleClassName}GridEditColumns(
|
||||||
|
onActionClick?: OnActionClickFn<${simpleClassName}Api.${subSimpleClassName}>,
|
||||||
|
): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {
|
||||||
|
return [
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if (!$column.primaryKey && $column.listOperationResult && $column.id != $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "number")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "string")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "boolean")
|
||||||
|
#end
|
||||||
|
{
|
||||||
|
field: '${javaField}',
|
||||||
|
title: '${comment}',
|
||||||
|
minWidth: 120,
|
||||||
|
slots: { default: '${javaField}' },
|
||||||
|
#if ($column.htmlType == "select" || $column.htmlType == "checkbox" || $column.htmlType == "radio")
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
params: {
|
||||||
|
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||||
|
},
|
||||||
|
#else
|
||||||
|
params: {
|
||||||
|
options: [],
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
{
|
||||||
|
field: 'operation',
|
||||||
|
title: '操作',
|
||||||
|
minWidth: 60,
|
||||||
|
align: 'center',
|
||||||
|
fixed: 'right',
|
||||||
|
headerAlign: 'center',
|
||||||
|
showOverflow: false,
|
||||||
|
cellRender: {
|
||||||
|
attrs: {
|
||||||
|
nameField: '${columns[0].javaField}',
|
||||||
|
nameTitle: '${table.classComment}',
|
||||||
|
onClick: onActionClick,
|
||||||
|
},
|
||||||
|
name: 'CellOperation',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
code: 'delete',
|
||||||
|
show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:delete']),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
/** 新增/修改的表单 */
|
||||||
|
export function use${subSimpleClassName}FormSchema(): VbenFormSchema[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
fieldName: 'id',
|
||||||
|
component: 'Input',
|
||||||
|
dependencies: {
|
||||||
|
triggerFields: [''],
|
||||||
|
show: () => false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if (!$column.primaryKey && ($table.templateType != 2 || ($table.templateType == 2 && $column.id != $treeParentColumn.id)))## 树表中已经添加了父ID字段,这里排除
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "number")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "string")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "boolean")
|
||||||
|
#end
|
||||||
|
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
fieldName: '${javaField}',
|
||||||
|
label: '${comment}',
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||||
|
rules: 'required',
|
||||||
|
#end
|
||||||
|
#if ($column.htmlType == "input")
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入${comment}',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
component: 'ImageUpload',
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
component: 'FileUpload',
|
||||||
|
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||||
|
component: 'RichTextarea',
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||||
|
#else##没数据字典
|
||||||
|
options: [],
|
||||||
|
#end
|
||||||
|
placeholder: '请选择${comment}',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
component: 'Checkbox',
|
||||||
|
componentProps: {
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||||
|
#else##没数据字典
|
||||||
|
options: [],
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
component: 'RadioGroup',
|
||||||
|
componentProps: {
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||||
|
#else##没数据字典
|
||||||
|
options: [],
|
||||||
|
#end
|
||||||
|
buttonStyle: 'solid',
|
||||||
|
optionType: 'button',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime: true,
|
||||||
|
format: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
valueFormat: 'x',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "textarea")## 文本域
|
||||||
|
component: 'Textarea',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入${comment}',
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "inputNumber")## 数字输入框
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
min: 0,
|
||||||
|
controlsPosition: 'right',
|
||||||
|
placeholder: '请输入${comment}',
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
#end
|
||||||
|
#if ($table.templateType == 12) ## 内嵌情况
|
||||||
|
/** 列表的字段 */
|
||||||
|
export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {
|
||||||
|
return [
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.listOperationResult)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
{
|
||||||
|
field: '${javaField}',
|
||||||
|
title: '${comment}',
|
||||||
|
minWidth: 120,
|
||||||
|
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||||
|
formatter: 'formatDateTime',
|
||||||
|
#elseif("" != $dictType)## 数据字典
|
||||||
|
cellRender: {
|
||||||
|
name: 'CellDict',
|
||||||
|
props: { type: DICT_TYPE.$dictType.toUpperCase() },
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
@ -0,0 +1,154 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import { message, Tabs, Checkbox, Input, Textarea, Select,RadioGroup,CheckboxGroup, DatePicker } from 'ant-design-vue';
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
|
||||||
|
import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { $t } from '#/locales';
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
|
||||||
|
import { useFormSchema } from '../data';
|
||||||
|
|
||||||
|
const emit = defineEmits(['success']);
|
||||||
|
const formData = ref<${simpleClassName}Api.${simpleClassName}>();
|
||||||
|
const getTitle = computed(() => {
|
||||||
|
return formData.value?.id
|
||||||
|
? $t('ui.actionTitle.edit', ['${table.classComment}'])
|
||||||
|
: $t('ui.actionTitle.create', ['${table.classComment}']);
|
||||||
|
});
|
||||||
|
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
|
||||||
|
/** 子表的表单 */
|
||||||
|
const subTabsName = ref('$subClassNameVars.get(0)')
|
||||||
|
#foreach ($subClassNameVar in $subClassNameVars)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
const ${subClassNameVar}FormRef = ref<InstanceType<typeof ${subSimpleClassName}Form>>()
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
|
const [Form, formApi] = useVbenForm({
|
||||||
|
commonConfig: {
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
},
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
labelWidth: 80,
|
||||||
|
},
|
||||||
|
layout: 'horizontal',
|
||||||
|
schema: useFormSchema(),
|
||||||
|
showDefaultActions: false
|
||||||
|
});
|
||||||
|
|
||||||
|
const [Modal, modalApi] = useVbenModal({
|
||||||
|
async onConfirm() {
|
||||||
|
const { valid } = await formApi.validate();
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
// 校验子表单
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
#if ($subTable.subJoinMany) ## 一对多
|
||||||
|
## TODO 列表值校验?
|
||||||
|
#else
|
||||||
|
const ${subClassNameVar}Valid = await ${subClassNameVar}FormRef.value?.validate();
|
||||||
|
if (!${subClassNameVar}Valid) {
|
||||||
|
subTabsName.value = '${subClassNameVar}';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
modalApi.lock();
|
||||||
|
// 提交表单
|
||||||
|
const data = (await formApi.getValues()) as ${simpleClassName}Api.${simpleClassName};
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
// 拼接子表的数据
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
#if ($subTable.subJoinMany)
|
||||||
|
data.${subClassNameVar}s = ${subClassNameVar}FormRef.value?.getData();
|
||||||
|
#else
|
||||||
|
data.${subClassNameVar} = await ${subClassNameVar}FormRef.value?.getValues();
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
try {
|
||||||
|
await (formData.value?.id ? update${simpleClassName}(data) : create${simpleClassName}(data));
|
||||||
|
// 关闭并提示
|
||||||
|
await modalApi.close();
|
||||||
|
emit('success');
|
||||||
|
message.success( $t('ui.actionMessage.operationSuccess') );
|
||||||
|
} finally {
|
||||||
|
modalApi.unlock();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async onOpenChange(isOpen: boolean) {
|
||||||
|
if (!isOpen) {
|
||||||
|
formData.value = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 加载数据
|
||||||
|
let data = modalApi.getData<${simpleClassName}Api.${simpleClassName}>();
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data.id) {
|
||||||
|
modalApi.lock();
|
||||||
|
try {
|
||||||
|
data = await get${simpleClassName}(data.id);
|
||||||
|
} finally {
|
||||||
|
modalApi.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 设置到 values
|
||||||
|
formData.value = data;
|
||||||
|
await formApi.setValues(formData.value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Modal :title="getTitle">
|
||||||
|
<Form class="mx-4" />
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
<!-- 子表的表单 -->
|
||||||
|
<Tabs v-model:active-key="subTabsName">
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
|
<Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}" force-render>
|
||||||
|
<${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData?.id" />
|
||||||
|
</Tabs.TabPane>
|
||||||
|
#end
|
||||||
|
</Tabs>
|
||||||
|
#end
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
@ -3,11 +3,20 @@ import type { OnActionClickParams, VxeTableGridOptions } from '#/adapter/vxe-tab
|
|||||||
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
import { Button, message } from 'ant-design-vue';
|
import { Button, message,Tabs } from 'ant-design-vue';
|
||||||
import { Download, Plus } from '@vben/icons';
|
import { Download, Plus } from '@vben/icons';
|
||||||
import Form from './modules/form.vue';
|
import Form from './modules/form.vue';
|
||||||
|
|
||||||
import { ref } from 'vue';
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 11 || $table.templateType == 12 )
|
||||||
|
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
|
||||||
|
import ${subSimpleClassName}List from './modules/${subSimpleClassName_strikeCase}-list.vue'
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
|
import { ref, h } from 'vue';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
#if (${table.templateType} == 2)## 树表接口
|
#if (${table.templateType} == 2)## 树表接口
|
||||||
@ -15,10 +24,18 @@ import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClas
|
|||||||
#else## 标准表接口
|
#else## 标准表接口
|
||||||
import { get${simpleClassName}Page, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
import { get${simpleClassName}Page, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
#end
|
#end
|
||||||
import { downloadByData } from '#/utils/download';
|
import { downloadFileFromBlobPart } from '@vben/utils';
|
||||||
|
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
|
|
||||||
|
#if ($table.templateType == 12 || $table.templateType == 11) ## 内嵌和erp情况
|
||||||
|
/** 子表的列表 */
|
||||||
|
const subTabsName = ref('$subClassNameVars.get(0)')
|
||||||
|
#if ($table.templateType == 11)
|
||||||
|
const select${simpleClassName} = ref<${simpleClassName}Api.${simpleClassName}>();
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
const [FormModal, formModalApi] = useVbenModal({
|
const [FormModal, formModalApi] = useVbenModal({
|
||||||
connectedComponent: Form,
|
connectedComponent: Form,
|
||||||
destroyOnClose: true,
|
destroyOnClose: true,
|
||||||
@ -35,18 +52,16 @@ function toggleExpand() {
|
|||||||
|
|
||||||
/** 刷新表格 */
|
/** 刷新表格 */
|
||||||
function onRefresh() {
|
function onRefresh() {
|
||||||
|
#if ($table.templateType == 12) ## 内嵌情况
|
||||||
|
gridApi.reload();
|
||||||
|
#else
|
||||||
gridApi.query();
|
gridApi.query();
|
||||||
}
|
#end
|
||||||
|
|
||||||
/** 导出表格 */
|
|
||||||
async function onExport() {
|
|
||||||
const data = await export${simpleClassName}(await gridApi.formApi.getValues());
|
|
||||||
downloadByData(data, '${table.classComment}.xls');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 创建${table.classComment} */
|
/** 创建${table.classComment} */
|
||||||
function onCreate() {
|
function onCreate() {
|
||||||
formModalApi.setData(null).open();
|
formModalApi.setData({}).open();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 编辑${table.classComment} */
|
/** 编辑${table.classComment} */
|
||||||
@ -56,7 +71,7 @@ function onEdit(row: ${simpleClassName}Api.${simpleClassName}) {
|
|||||||
|
|
||||||
#if (${table.templateType} == 2)## 树表特有:新增下级
|
#if (${table.templateType} == 2)## 树表特有:新增下级
|
||||||
/** 新增下级${table.classComment} */
|
/** 新增下级${table.classComment} */
|
||||||
function onAddChild(row: ${simpleClassName}Api.${simpleClassName}) {
|
function onAppend(row: ${simpleClassName}Api.${simpleClassName}) {
|
||||||
formModalApi.setData({ ${treeParentColumn.javaField}: row.id }).open();
|
formModalApi.setData({ ${treeParentColumn.javaField}: row.id }).open();
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
@ -70,22 +85,31 @@ async function onDelete(row: ${simpleClassName}Api.${simpleClassName}) {
|
|||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
await delete${simpleClassName}(row.id as number);
|
await delete${simpleClassName}(row.id as number);
|
||||||
message.success({
|
message.success( $t('ui.actionMessage.deleteSuccess', [row.id]) );
|
||||||
content: $t('ui.actionMessage.deleteSuccess', [row.id]),
|
|
||||||
key: 'action_process_msg',
|
|
||||||
});
|
|
||||||
onRefresh();
|
onRefresh();
|
||||||
} catch {
|
} catch {
|
||||||
hideLoading();
|
hideLoading();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 导出表格 */
|
||||||
|
async function onExport() {
|
||||||
|
const data = await export${simpleClassName}(await gridApi.formApi.getValues());
|
||||||
|
downloadFileFromBlobPart({ fileName: '${table.classComment}.xls', source: data });
|
||||||
|
}
|
||||||
|
|
||||||
/** 表格操作按钮的回调函数 */
|
/** 表格操作按钮的回调函数 */
|
||||||
function onActionClick({
|
function onActionClick({
|
||||||
code,
|
code,
|
||||||
row,
|
row,
|
||||||
}: OnActionClickParams<${simpleClassName}Api.${simpleClassName}>) {
|
}: OnActionClickParams<${simpleClassName}Api.${simpleClassName}>) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
|
#if (${table.templateType} == 2)## 树表特有:新增下级
|
||||||
|
case 'append': {
|
||||||
|
onAppend(row);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#end
|
||||||
case 'edit': {
|
case 'edit': {
|
||||||
onEdit(row);
|
onEdit(row);
|
||||||
break;
|
break;
|
||||||
@ -94,12 +118,6 @@ function onActionClick({
|
|||||||
onDelete(row);
|
onDelete(row);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if (${table.templateType} == 2)## 树表特有:新增下级
|
|
||||||
case 'add_child': {
|
|
||||||
onAddChild(row);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +127,11 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: useGridColumns(onActionClick),
|
columns: useGridColumns(onActionClick),
|
||||||
|
#if (${table.templateType} == 11)
|
||||||
|
height: '600px',
|
||||||
|
#else
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
|
#end
|
||||||
#if (${table.templateType} == 2)## 树表设置
|
#if (${table.templateType} == 2)## 树表设置
|
||||||
treeConfig: {
|
treeConfig: {
|
||||||
parentField: '${treeParentColumn.javaField}',
|
parentField: '${treeParentColumn.javaField}',
|
||||||
@ -134,12 +156,11 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
#else## 标准表数据加载
|
#else## 标准表数据加载
|
||||||
query: async ({ page }, formValues) => {
|
query: async ({ page }, formValues) => {
|
||||||
const { items, total } = await get${simpleClassName}Page({
|
return await get${simpleClassName}Page({
|
||||||
pageNo: page.currentPage,
|
pageNo: page.currentPage,
|
||||||
pageSize: page.pageSize,
|
pageSize: page.pageSize,
|
||||||
...formValues,
|
...formValues,
|
||||||
});
|
});
|
||||||
return { items, total };
|
|
||||||
},
|
},
|
||||||
#end
|
#end
|
||||||
},
|
},
|
||||||
@ -147,12 +168,22 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
rowConfig: {
|
rowConfig: {
|
||||||
keyField: 'id',
|
keyField: 'id',
|
||||||
isHover: true,
|
isHover: true,
|
||||||
|
#if (${table.templateType} == 11)
|
||||||
|
isCurrent: true,
|
||||||
|
#end
|
||||||
},
|
},
|
||||||
toolbarConfig: {
|
toolbarConfig: {
|
||||||
refresh: { code: 'query' },
|
refresh: { code: 'query' },
|
||||||
search: true,
|
search: true,
|
||||||
},
|
},
|
||||||
} as VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>,
|
} as VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>,
|
||||||
|
#if (${table.templateType} == 11)
|
||||||
|
gridEvents:{
|
||||||
|
cellClick: ({ row }: { row: ${simpleClassName}Api.${simpleClassName}}) => {
|
||||||
|
select${simpleClassName}.value = row;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
#end
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -160,22 +191,61 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
<FormModal @success="onRefresh" />
|
<FormModal @success="onRefresh" />
|
||||||
|
|
||||||
|
#if ($table.templateType == 11) ## erp情况
|
||||||
|
<div>
|
||||||
|
#end
|
||||||
<Grid table-title="${table.classComment}列表">
|
<Grid table-title="${table.classComment}列表">
|
||||||
|
#if ($table.templateType == 12) ## 内嵌情况
|
||||||
|
<template #expand_content="{ row }">
|
||||||
|
<!-- 子表的表单 -->
|
||||||
|
<Tabs v-model:active-key="subTabsName" class="mx-8">
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
|
<Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}" force-render>
|
||||||
|
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="row?.id" />
|
||||||
|
</Tabs.TabPane>
|
||||||
|
#end
|
||||||
|
</Tabs>
|
||||||
|
</template>
|
||||||
|
#end
|
||||||
<template #toolbar-tools>
|
<template #toolbar-tools>
|
||||||
#if (${table.templateType} == 2)## 树表特有:展开/收缩按钮
|
#if (${table.templateType} == 2)## 树表特有:展开/收缩按钮
|
||||||
<Button @click="toggleExpand" class="mr-2">
|
<Button @click="toggleExpand" class="mr-2">
|
||||||
{{ isExpanded ? '收缩' : '展开' }}
|
{{ isExpanded ? '收缩' : '展开' }}
|
||||||
</Button>
|
</Button>
|
||||||
#end
|
#end
|
||||||
<Button type="primary" @click="onCreate" v-access:code="['${table.moduleName}:${simpleClassName_strikeCase}:create']">
|
<Button :icon="h(Plus)" type="primary" @click="onCreate" v-access:code="['${table.moduleName}:${simpleClassName_strikeCase}:create']">
|
||||||
<Plus class="size-5" />
|
|
||||||
{{ $t('ui.actionTitle.create', ['${table.classComment}']) }}
|
{{ $t('ui.actionTitle.create', ['${table.classComment}']) }}
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="primary" class="ml-2" @click="onExport" v-access:code="['${table.moduleName}:${simpleClassName_strikeCase}:export']">
|
<Button
|
||||||
<Download class="size-5" />
|
:icon="h(Download)"
|
||||||
|
type="primary"
|
||||||
|
class="ml-2"
|
||||||
|
@click="onExport"
|
||||||
|
v-access:code="['${table.moduleName}:${simpleClassName_strikeCase}:export']"
|
||||||
|
>
|
||||||
{{ $t('ui.actionTitle.export') }}
|
{{ $t('ui.actionTitle.export') }}
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
#if ($table.templateType == 11) ## erp情况
|
||||||
|
<!-- 子表的表单 -->
|
||||||
|
<Tabs v-model:active-key="subTabsName" class="mt-2">
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
|
<Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}" force-render>
|
||||||
|
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="select${simpleClassName}?.id" />
|
||||||
|
</Tabs.TabPane>
|
||||||
|
#end
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
#end
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||||
|
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||||
|
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { $t } from '#/locales';
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
|
||||||
|
|
||||||
|
import { use${subSimpleClassName}FormSchema } from '../data';
|
||||||
|
|
||||||
|
const emit = defineEmits(['success']);
|
||||||
|
const formData = ref<${simpleClassName}Api.${subSimpleClassName}>();
|
||||||
|
const getTitle = computed(() => {
|
||||||
|
return formData.value?.id
|
||||||
|
? $t('ui.actionTitle.edit', ['${subTable.classComment}'])
|
||||||
|
: $t('ui.actionTitle.create', ['${subTable.classComment}']);
|
||||||
|
});
|
||||||
|
|
||||||
|
const [Form, formApi] = useVbenForm({
|
||||||
|
commonConfig: {
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
},
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
labelWidth: 80,
|
||||||
|
},
|
||||||
|
layout: 'horizontal',
|
||||||
|
schema: use${subSimpleClassName}FormSchema(),
|
||||||
|
showDefaultActions: false
|
||||||
|
});
|
||||||
|
|
||||||
|
const [Modal, modalApi] = useVbenModal({
|
||||||
|
async onConfirm() {
|
||||||
|
const { valid } = await formApi.validate();
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
modalApi.lock();
|
||||||
|
// 提交表单
|
||||||
|
const data = (await formApi.getValues()) as ${simpleClassName}Api.${subSimpleClassName};
|
||||||
|
data.${subJoinColumn.javaField} = formData.value?.${subJoinColumn.javaField};
|
||||||
|
try {
|
||||||
|
await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data));
|
||||||
|
// 关闭并提示
|
||||||
|
await modalApi.close();
|
||||||
|
emit('success');
|
||||||
|
message.success( $t('ui.actionMessage.operationSuccess') );
|
||||||
|
} finally {
|
||||||
|
modalApi.unlock();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async onOpenChange(isOpen: boolean) {
|
||||||
|
if (!isOpen) {
|
||||||
|
formData.value = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载数据
|
||||||
|
let data = modalApi.getData<${simpleClassName}Api.${subSimpleClassName}>();
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data.id) {
|
||||||
|
modalApi.lock();
|
||||||
|
try {
|
||||||
|
data = await get${subSimpleClassName}(data.id);
|
||||||
|
} finally {
|
||||||
|
modalApi.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 设置到 values
|
||||||
|
formData.value = data;
|
||||||
|
await formApi.setValues(formData.value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Modal :title="getTitle">
|
||||||
|
<Form class="mx-4" />
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
## 主表的 normal 和 inner 使用相同的 form 表单
|
||||||
|
#parse("codegen/vue3_vben5_antd/schema/views/modules/form_sub_normal.vue.vm")
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user