mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 04:39:00 +08:00
参考 ai-dev-next c0b8a966b 的非 AI 表定义,统一单体与分库结构及内置 OAuth 客户端默认授权。保留 AI 表、菜单与路由排除边界。
367 lines
259 KiB
PL/PgSQL
367 lines
259 KiB
PL/PgSQL
USE pigxx_codegen;
|
|
|
|
SET NAMES utf8mb4;
|
|
SET FOREIGN_KEY_CHECKS = 0;
|
|
|
|
-- ----------------------------
|
|
-- Table structure for gen_datasource_conf
|
|
-- ----------------------------
|
|
DROP TABLE IF EXISTS `gen_datasource_conf`;
|
|
CREATE TABLE `gen_datasource_conf` (
|
|
`id` bigint NOT NULL COMMENT '主键',
|
|
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '别名',
|
|
`url` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'jdbcurl',
|
|
`username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户名',
|
|
`password` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '密码',
|
|
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
|
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新',
|
|
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
|
|
`tenant_id` bigint DEFAULT NULL COMMENT '租户ID',
|
|
`ds_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据库类型',
|
|
`conf_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '配置类型',
|
|
`ds_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据库名称',
|
|
`instance` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '实例',
|
|
`port` int DEFAULT NULL COMMENT '端口',
|
|
`host` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '主机',
|
|
PRIMARY KEY (`id`) USING BTREE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='数据源表';
|
|
|
|
-- ----------------------------
|
|
-- Records of gen_datasource_conf
|
|
-- ----------------------------
|
|
BEGIN;
|
|
COMMIT;
|
|
|
|
-- ----------------------------
|
|
-- Table structure for gen_field_type
|
|
-- ----------------------------
|
|
DROP TABLE IF EXISTS `gen_field_type`;
|
|
CREATE TABLE `gen_field_type` (
|
|
`id` bigint NOT NULL COMMENT 'id',
|
|
`column_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字段类型',
|
|
`attr_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '属性类型',
|
|
`package_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '属性包名',
|
|
`default_form_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '默认表单类型',
|
|
`default_query_form_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '默认查询表单类型',
|
|
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
|
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人',
|
|
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
|
|
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '修改人',
|
|
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `column_type` (`column_type`)
|
|
) ENGINE=InnoDB AUTO_INCREMENT=1634915190321451010 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='字段类型管理';
|
|
|
|
-- ----------------------------
|
|
-- Records of gen_field_type
|
|
-- ----------------------------
|
|
BEGIN;
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (1,'datetime','LocalDateTime','java.time.LocalDateTime','datetime','datetimerange','2023-02-06 08:45:10',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (2,'date','LocalDate','java.time.LocalDate','date','daterange','2023-02-06 08:45:10',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (3,'tinyint','Integer',NULL,'number','number','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (4,'smallint','Integer',NULL,'number','number','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (5,'mediumint','Integer',NULL,'number','number','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (6,'int','Integer',NULL,'number','number','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (7,'integer','Integer',NULL,'number','number','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (8,'bigint','Long',NULL,'number','number','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (9,'float','Float',NULL,'number','number','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (10,'double','Double',NULL,'number','number','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (11,'decimal','BigDecimal','java.math.BigDecimal','number','number','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (12,'bit','Boolean',NULL,'radio','radio','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (13,'char','String',NULL,'radio','radio','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (14,'varchar','String',NULL,'text','text','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (15,'tinytext','String',NULL,'textarea','text','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (16,'text','String',NULL,'textarea','text','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (17,'mediumtext','String',NULL,'textarea','text','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (18,'longtext','String',NULL,'textarea','text','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (19,'timestamp','LocalDateTime','java.time.LocalDateTime','datetime','datetimerange','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (20,'NUMBER','Integer',NULL,'number','number','2023-02-06 08:45:11',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (21,'BINARY_INTEGER','Integer',NULL,'number','number','2023-02-06 08:45:12',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (22,'BINARY_FLOAT','Float',NULL,'number','number','2023-02-06 08:45:12',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (23,'BINARY_DOUBLE','Double',NULL,'number','number','2023-02-06 08:45:12',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (24,'VARCHAR2','String',NULL,'text','text','2023-02-06 08:45:12',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (25,'NVARCHAR','String',NULL,'text','text','2023-02-06 08:45:12',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (26,'NVARCHAR2','String',NULL,'text','text','2023-02-06 08:45:12',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (27,'CLOB','String',NULL,'textarea','text','2023-02-06 08:45:12',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (28,'int8','Long',NULL,'number','number','2023-02-06 08:45:12',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (29,'int4','Integer',NULL,'number','number','2023-02-06 08:45:12',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (30,'int2','Integer',NULL,'number','number','2023-02-06 08:45:12',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (31,'numeric','BigDecimal','java.math.BigDecimal','number','number','2023-02-06 08:45:12',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (32,'json','String',NULL,'textarea','text','2023-02-06 08:45:12',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (33,'BPCHAR','String',NULL,'text','text','2026-04-07 20:27:29',NULL,NULL,NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (34,'time','LocalTime','java.time.LocalTime','text','text','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (35,'year','Integer',NULL,'number','number','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (36,'enum','String',NULL,'text','text','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (37,'set','String',NULL,'text','text','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (38,'bool','Boolean',NULL,'radio','radio','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (39,'boolean','Boolean',NULL,'radio','radio','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (40,'float4','Float',NULL,'number','number','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (41,'float8','Double',NULL,'number','number','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (42,'jsonb','String',NULL,'textarea','text','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (43,'uuid','String',NULL,'text','text','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (44,'serial','Integer',NULL,'number','number','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (45,'bigserial','Long',NULL,'number','number','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (46,'smallserial','Integer',NULL,'number','number','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (47,'timestamptz','LocalDateTime','java.time.LocalDateTime','datetime','datetimerange','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (48,'timetz','String',NULL,'text','text','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
INSERT INTO `gen_field_type` (`id`, `column_type`, `attr_type`, `package_name`, `default_form_type`, `default_query_form_type`, `create_time`, `create_by`, `update_time`, `update_by`, `del_flag`) VALUES (49,'bytea','String',NULL,'textarea','text','2026-04-07 20:47:09',NULL,'2026-04-07 20:47:09',NULL,'0');
|
|
COMMIT;
|
|
|
|
-- ----------------------------
|
|
-- Table structure for gen_group
|
|
-- ----------------------------
|
|
DROP TABLE IF EXISTS `gen_group`;
|
|
CREATE TABLE `gen_group` (
|
|
`id` bigint NOT NULL,
|
|
`group_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '分组名称',
|
|
`group_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '分组描述',
|
|
`tenant_id` bigint NOT NULL COMMENT '租户ID',
|
|
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
|
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
|
`create_time` datetime DEFAULT NULL COMMENT '创建人',
|
|
`update_time` datetime DEFAULT NULL COMMENT '修改人',
|
|
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
|
|
PRIMARY KEY (`id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='模板分组';
|
|
|
|
-- ----------------------------
|
|
-- Records of gen_group
|
|
-- ----------------------------
|
|
BEGIN;
|
|
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (1,'单表增删改查V2026001',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
|
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (2,'主子表增删改查V2026001',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
|
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (3,'树形表格增删改查V2026001',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
|
INSERT INTO `gen_group` (`id`, `group_name`, `group_desc`, `tenant_id`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (4,'左树右表增删改查V2026001',NULL,1,'admin','admin','2026-04-08 17:38:24','2026-04-08 17:38:24','0');
|
|
COMMIT;
|
|
|
|
-- ----------------------------
|
|
-- Table structure for gen_table
|
|
-- ----------------------------
|
|
DROP TABLE IF EXISTS `gen_table`;
|
|
CREATE TABLE `gen_table` (
|
|
`id` bigint NOT NULL COMMENT 'id',
|
|
`table_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '表名',
|
|
`class_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '类名',
|
|
`db_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据库类型',
|
|
`table_comment` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '说明',
|
|
`author` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '作者',
|
|
`email` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '邮箱',
|
|
`package_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '项目包名',
|
|
`version` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '项目版本号',
|
|
`i18n` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '是否生成带有i18n 0 不带有 1带有',
|
|
`style` bigint DEFAULT NULL COMMENT '代码风格',
|
|
`sync_menu_id` bigint DEFAULT NULL COMMENT '所属菜单ID',
|
|
`sync_route` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '是否自动同步路由',
|
|
`child_table_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '子表名称',
|
|
`main_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '主表关联键',
|
|
`child_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '子表关联键',
|
|
`parent_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '父表关联键',
|
|
`name_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '名称字段',
|
|
`generator_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '生成方式 0:zip压缩包 1:自定义目录',
|
|
`backend_path` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '后端生成路径',
|
|
`frontend_path` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '前端生成路径',
|
|
`module_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '模块名',
|
|
`function_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '功能名',
|
|
`form_layout` tinyint DEFAULT NULL COMMENT '表单布局 1:一列 2:两列',
|
|
`ds_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据源ID',
|
|
`baseclass_id` bigint DEFAULT NULL COMMENT '基类ID',
|
|
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `table_name_idx` (`table_name`,`ds_name`) USING BTREE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代码生成表';
|
|
|
|
-- ----------------------------
|
|
-- Records of gen_table
|
|
-- ----------------------------
|
|
BEGIN;
|
|
COMMIT;
|
|
|
|
-- ----------------------------
|
|
-- Table structure for gen_table_column
|
|
-- ----------------------------
|
|
DROP TABLE IF EXISTS `gen_table_column`;
|
|
CREATE TABLE `gen_table_column` (
|
|
`id` bigint NOT NULL COMMENT 'id',
|
|
`ds_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据源名称',
|
|
`table_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '表名称',
|
|
`field_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字段名称',
|
|
`field_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字段类型',
|
|
`field_comment` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字段说明',
|
|
`attr_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '属性名',
|
|
`attr_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '属性类型',
|
|
`package_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '属性包名',
|
|
`sort` int DEFAULT NULL COMMENT '排序',
|
|
`auto_fill` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '自动填充 DEFAULT、INSERT、UPDATE、INSERT_UPDATE',
|
|
`primary_pk` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '主键 0:否 1:是',
|
|
`base_field` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '基类字段 0:否 1:是',
|
|
`form_item` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '表单项 0:否 1:是',
|
|
`form_required` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '表单必填 0:否 1:是',
|
|
`form_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '表单类型',
|
|
`form_validator` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '表单效验',
|
|
`grid_item` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '列表项 0:否 1:是',
|
|
`grid_sort` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '列表排序 0:否 1:是',
|
|
`query_item` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '查询项 0:否 1:是',
|
|
`query_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '查询方式',
|
|
`query_form_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '查询表单类型',
|
|
`field_dict` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字典类型',
|
|
PRIMARY KEY (`id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代码生成表字段';
|
|
|
|
-- ----------------------------
|
|
-- Records of gen_table_column
|
|
-- ----------------------------
|
|
BEGIN;
|
|
COMMIT;
|
|
|
|
-- ----------------------------
|
|
-- Table structure for gen_template
|
|
-- ----------------------------
|
|
DROP TABLE IF EXISTS `gen_template`;
|
|
CREATE TABLE `gen_template` (
|
|
`id` bigint NOT NULL COMMENT '主键',
|
|
`template_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模板名称',
|
|
`generator_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模板路径',
|
|
`template_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模板描述',
|
|
`template_code` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模板代码',
|
|
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
|
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新',
|
|
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '删除标记',
|
|
`tenant_id` bigint NOT NULL COMMENT '租户ID',
|
|
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人',
|
|
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人',
|
|
PRIMARY KEY (`id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='模板';
|
|
|
|
-- ----------------------------
|
|
-- Records of gen_template
|
|
-- ----------------------------
|
|
BEGIN;
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (1,'ControllerV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','ControllerV2026001','package ${package}.${moduleName}.controller;\n\n#if($queryList)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"分页查询\" , description = \"分页查询\" )\n @GetMapping(\"/page\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#foreach ($field in $queryList)\n#set($getAttrName=$str.getProperty($field.attrName))\n#set($var=\"${className}.$getAttrName()\")\n#if($field.attrType == \'String\')\n#set($expression=\"StrUtil.isNotBlank\")\n#else\n#set($expression=\"Objects.nonNull\")\n#end\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n if (ArrayUtil.isNotEmpty(${className}.${getAttrName}Range())) {\n wrapper.between(${ClassName}Entity::$getAttrName, ${className}.${getAttrName}Range()[0], ${className}.${getAttrName}Range()[1]);\n }\n#elseif($field.queryType == \'=\')\n wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'like\' )\n wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'!-\' )\n wrapper.ne($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>\' )\n wrapper.gt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<\' )\n wrapper.lt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>=\' )\n wrapper.ge($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<=\' )\n wrapper.le($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'left like\' )\n wrapper.likeLeft($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'right like\' )\n wrapper.likeRight($expression($var),${ClassName}Entity::$getAttrName,$var);\n#end\n#end\n return R.ok(${className}Service.page(page, wrapper));\n }\n\n\n /**\n * 通过条件查询${tableComment}\n * @param ${className} 查询条件\n * @return R 对象列表\n */\n @Operation(summary = \"通过条件查询\" , description = \"通过条件查询对象\" )\n @GetMapping(\"/details\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R getDetails(@ParameterObject ${ClassName}Entity ${className}) {\n return R.ok(${className}Service.list(Wrappers.query(${className})));\n }\n\n /**\n * 新增${tableComment}\n * @param ${className} ${tableComment}\n * @return R\n */\n @Operation(summary = \"新增${tableComment}\" , description = \"新增${tableComment}\" )\n @SysLog(\"新增${tableComment}\" )\n @PostMapping\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\')\" )\n #end\n public R save(@RequestBody ${ClassName}Entity ${className}) {\n return R.ok(${className}Service.save(${className}));\n }\n\n /**\n * 修改${tableComment}\n * @param ${className} ${tableComment}\n * @return R\n */\n @Operation(summary = \"修改${tableComment}\" , description = \"修改${tableComment}\" )\n @SysLog(\"修改${tableComment}\" )\n @PutMapping\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\')\" )\n #end\n public R updateById(@RequestBody ${ClassName}Entity ${className}) {\n return R.ok(${className}Service.updateById(${className}));\n }\n\n /**\n * 通过id删除${tableComment}\n * @param ids ${pk.attrName}列表\n * @return R\n */\n @Operation(summary = \"通过id删除${tableComment}\" , description = \"通过id删除${tableComment}\" )\n @SysLog(\"通过id删除${tableComment}\" )\n @DeleteMapping\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\')\" )\n #end\n public R removeById(@RequestBody ${pk.attrType}[] ids) {\n return R.ok(${className}Service.removeBatchByIds(CollUtil.toList(ids)));\n }\n\n\n /**\n * 导出excel 表格\n * @param ${className} 查询条件\n * @param ids 导出指定ID\n * @return excel 文件流\n */\n @ResponseExcel\n @GetMapping(\"/export\")\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\')\" )\n #end\n public List<${ClassName}Entity> exportExcel(${ClassName}Entity ${className},${pk.attrType}[] ids) {\n return ${className}Service.list(Wrappers.lambdaQuery(${className}).in(ArrayUtil.isNotEmpty(ids), ${ClassName}Entity::$str.getProperty($pk.attrName), ids));\n }\n\n /**\n * 导入excel 表\n * @param ${className}List 对象实体列表\n * @param bindingResult 错误信息列表\n * @return ok fail\n */\n @PostMapping(\"/import\")\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\')\" )\n #end\n public R importExcel(@RequestExcel List<${ClassName}Entity> ${className}List, BindingResult bindingResult) {\n return R.ok(${className}Service.saveBatch(${className}List));\n }\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (2,'ServiceV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','ServiceV2026001','package ${package}.${moduleName}.service;\n\nimport com.baomidou.mybatisplus.extension.service.IService;\nimport ${entityClassName};\n\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (3,'ServiceImplV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','ServiceImplV2026001','package ${package}.${moduleName}.service.impl;\n\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport org.springframework.stereotype.Service;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (4,'实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(\"${tableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (5,'MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV2026001','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (6,'Mapper.xmlV2026001','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV2026001','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (7,'权限菜单V2026001','${backendPath}/menu/${functionName}_menu.sql','权限菜单V2026001','-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (8,'api.tsV2026001','${frontendPath}/src/api/${moduleName}/${functionName}.ts','api.tsV2026001','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n\n#if($ChildClassName)\n// ========== 子表相关接口 ==========\n\n/**\n * 删除子表数据\n * @param ids - 要删除的子表数据ID数组\n * @returns Promise<操作结果>\n */\nexport function delChildObj(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/child\',\n method: \'delete\',\n data: ids\n })\n}\n#end\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (9,'表格V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','表格V2026001','<template>\n <div class=\"layout-padding\">\n <div class=\"layout-padding-auto layout-padding-view\">\n#if($queryList)\n <!-- 查询表单区域 -->\n <el-row v-show=\"showSearch\">\n <el-form :model=\"state.queryForm\" ref=\"queryRef\" :inline=\"true\" @keyup.enter=\"getDataList\">\n#foreach($field in $queryList)\n#if($field.queryFormType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"state.queryForm.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option \n :label=\"item.label\" \n :value=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n :key=\"index\"\n />\n#else\n <el-option label=\"请选择\" value=\"0\" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"date\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"daterange\"\n range-separator=\"至\"\n start-placeholder=\"开始日期\"\n end-placeholder=\"结束日期\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"datetime\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"datetimerange\"\n range-separator=\"至\"\n start-placeholder=\"开始时间\"\n end-placeholder=\"结束时间\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"state.queryForm.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio \n :label=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n border \n :key=\"index\"\n >\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>\n ${field.fieldComment}\n </el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input \n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" \n v-model=\"state.queryForm.${field.attrName}\" \n />\n </el-form-item>\n#end\n#end\n <el-form-item>\n <el-button icon=\"search\" type=\"primary\" @click=\"getDataList\">\n 查询\n </el-button>\n <el-button icon=\"Refresh\" @click=\"resetQuery\">重置</el-button>\n </el-form-item>\n </el-form>\n </el-row>\n#end\n\n <!-- 操作按钮区域 -->\n <el-row>\n <div class=\"mb8\" style=\"width: 100%\">\n <el-button \n icon=\"folder-add\" \n type=\"primary\" \n class=\"ml10\" \n @click=\"formDialogRef.openDialog()\"\n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\'\"\n >\n 新增\n </el-button>\n <el-button \n plain \n icon=\"upload-filled\" \n type=\"primary\" \n class=\"ml10\" \n @click=\"excelUploadRef.show()\" \n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\'\"\n >\n 导入\n </el-button>\n <el-button \n plain \n :disabled=\"multiple\" \n icon=\"Delete\" \n type=\"primary\"\n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\'\" \n @click=\"handleDelete(selectObjs.value)\"\n >\n 删除\n </el-button>\n <right-toolbar \n v-model:showSearch=\"showSearch\" \n :export=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\'\"\n @exportExcel=\"exportExcel\" \n class=\"ml10 mr20\" \n style=\"float: right;\"\n @queryTable=\"getDataList\"\n />\n </div>\n </el-row>\n\n <!-- 数据表格区域 -->\n <el-table \n :data=\"state.dataList\" \n v-loading=\"state.loading\" \n border \n :cell-style=\"tableStyle.cellStyle\" \n :header-cell-style=\"tableStyle.headerCellStyle\"\n @selection-change=\"selectionChangeHandle\"\n @sort-change=\"sortChangeHandle\"\n >\n <el-table-column type=\"selection\" width=\"40\" align=\"center\" />\n <el-table-column type=\"index\" label=\"#\" width=\"40\" />\n#foreach($field in $gridList)\n#if($field.fieldDict)\n <el-table-column prop=\"${field.attrName}\" label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" show-overflow-tooltip>\n <template #default=\"scope\">\n <dict-tag :options=\"$field.fieldDict\" :value=\"scope.row.${field.attrName}\" />\n </template>\n </el-table-column>\n#elseif(${field.formType} == \'upload-img\')\n <el-table-column prop=\"${field.attrName}\" label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n <template #default=\"{ row }\">\n <upload-img disabled v-model:imageUrl=\"row.${field.attrName}\"></upload-img>\n </template>\n </el-table-column>\n#else\n <el-table-column\n prop=\"${field.attrName}\"\n label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n#if(${field.gridSort} == \'1\')\n sortable=\"custom\"\n#end\n show-overflow-tooltip\n />\n#end\n#end\n <el-table-column label=\"操作\" width=\"150\">\n <template #default=\"scope\">\n <el-button \n icon=\"edit-pen\" \n text \n type=\"primary\" \n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\'\"\n @click=\"formDialogRef.openDialog(scope.row.${pk.attrName})\"\n >\n 编辑\n </el-button>\n <el-button \n icon=\"delete\" \n text \n type=\"primary\" \n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\'\" \n @click=\"handleDelete([scope.row.${pk.attrName}])\"\n >\n 删除\n </el-button>\n </template>\n </el-table-column>\n </el-table>\n\n <!-- 分页组件 -->\n <pagination \n @size-change=\"sizeChangeHandle\" \n @current-change=\"currentChangeHandle\" \n v-bind=\"state.pagination\" \n />\n </div>\n\n <!-- 编辑、新增弹窗 -->\n <form-dialog ref=\"formDialogRef\" @refresh=\"getDataList(false)\" />\n\n <!-- 导入excel弹窗 (需要在 upms-biz/resources/file 下维护模板) -->\n <upload-excel\n ref=\"excelUploadRef\"\n title=\"导入\"\n url=\"/${moduleName}/${functionName}/import\"\n temp-url=\"/admin/sys-file/local/file/${functionName}.xlsx\"\n @refreshDataList=\"getDataList\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\" name=\"system${ClassName}\">\n// ========== 导入声明 ==========\nimport { BasicTableProps, useTable } from \"/@/hooks/table\";\nimport { fetchList, delObjs } from \"/@/api/${moduleName}/${functionName}\";\nimport { useMessage, useMessageBox } from \"/@/hooks/message\";\nimport { useDict } from \'/@/hooks/dict\';\n\n// ========== 组件声明 ==========\n// 异步加载表单弹窗组件\nconst FormDialog = defineAsyncComponent(() => import(\'./form.vue\'));\n\n// ========== 字典数据 ==========\n#set($fieldDict=[])\n#foreach($field in $queryList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n#if($fieldDict)\n// 加载字典数据\nconst { $dict.format($fieldDict) } = useDict($dict.quotation($fieldDict));\n#end\n\n// ========== 组件引用 ==========\nconst formDialogRef = ref(); // 表单弹窗引用\nconst excelUploadRef = ref(); // Excel上传弹窗引用\nconst queryRef = ref(); // 查询表单引用\n\n// ========== 响应式数据 ==========\nconst showSearch = ref(true); // 是否显示搜索区域\nconst selectObjs = ref([]) as any; // 表格多选数据\nconst multiple = ref(true); // 是否多选\n\n// ========== 表格状态 ==========\nconst state: BasicTableProps = reactive<BasicTableProps>({\n queryForm: {}, // 查询参数\n pageList: fetchList // 分页查询方法\n});\n\n// ========== Hook引用 ==========\n// 表格相关Hook\nconst {\n getDataList,\n currentChangeHandle,\n sizeChangeHandle,\n sortChangeHandle,\n downBlobFile,\n tableStyle\n} = useTable(state);\n\n// ========== 方法定义 ==========\n/**\n * 重置查询条件\n */\nconst resetQuery = () => {\n // 清空搜索条件\n queryRef.value?.resetFields();\n // 清空多选\n selectObjs.value = [];\n // 重新查询\n getDataList();\n};\n\n/**\n * 导出Excel文件\n */\nconst exportExcel = () => {\n downBlobFile(\n \'/${moduleName}/${functionName}/export\',\n { ...state.queryForm, ids: selectObjs.value },\n \'${functionName}.xlsx\'\n );\n};\n\n/**\n * 表格多选事件处理\n * @param objs 选中的数据行\n */\nconst selectionChangeHandle = (objs: { $pk.attrName: string }[]) => {\n selectObjs.value = objs.map(({ $pk.attrName }) => $pk.attrName);\n multiple.value = !objs.length;\n};\n\n/**\n * 删除数据处理\n * @param ids 要删除的数据ID数组\n */\nconst handleDelete = async (ids: string[]) => {\n try {\n await useMessageBox().confirm(\'此操作将永久删除\');\n } catch {\n return;\n }\n\n try {\n await delObjs(ids);\n getDataList();\n useMessage().success(\'删除成功\');\n } catch (err: any) {\n useMessage().error(err.msg);\n }\n};\n</script>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (10,'表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','表单V2026001','<template>\n <el-dialog :title=\"form.${pk.attrName} ? \'编辑\' : \'新增\'\" v-model=\"visible\"\n :close-on-click-modal=\"false\" draggable>\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" label-width=\"90px\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetime\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"daterange\" range-separator=\"至\" start-placeholder=\"开始日期\" end-placeholder=\"结束日期\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetimerange\" range-separator=\"至\" start-placeholder=\"开始时间\" end-placeholder=\"结束时间\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'number\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input-number :min=\"1\" :max=\"1000\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"></el-input-number>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'upload-file\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <upload-file v-model=\"form.${field.attrName}\"></upload-file>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'upload-img\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <upload-img v-model:imageUrl=\"form.${field.attrName}\"></upload-img>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'editor\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <editor v-if=\"visible\" v-model:get-html=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"></editor>\n </el-form-item>\n </el-col>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#end\n#end\n#end\n </el-row>\n </el-form>\n <template #footer>\n <span class=\"dialog-footer\">\n <el-button @click=\"visible = false\">取 消</el-button>\n <el-button type=\"primary\" @click=\"onSubmit\" :disabled=\"loading\">确 认</el-button>\n </span>\n </template>\n </el-dialog>\n</template>\n\n<script setup lang=\"ts\" name=\"${ClassName}Dialog\">\n// ========== 1. 导入语句 ==========\nimport { useDict } from \'/@/hooks/dict\';\nimport { rule } from \'/@/utils/validate\';\nimport { useMessage } from \"/@/hooks/message\";\nimport { getObj, addObj, putObj, validateExist } from \'/@/api/${moduleName}/${functionName}\';\n\n// ========== 2. 组件定义 ==========\n// 定义组件事件\nconst emit = defineEmits([\'refresh\']);\n\n// ========== 3. 响应式数据定义 ==========\n// 基础响应式变量\nconst dataFormRef = ref(); // 表单引用\nconst visible = ref(false); // 弹窗显示状态\nconst loading = ref(false); // 加载状态\n\n// 表单数据对象\nconst form = reactive({\n#if(!$formList.contains(${pk.attrName}))\n ${pk.attrName}: \'\', // 主键\n#end\n#foreach($field in $formList)\n#if($field.formType == \'number\')\n ${field.attrName}: 0, // ${field.fieldComment}\n#elseif($field.formType == \'checkbox\' || $field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n ${field.attrName}: [], // ${field.fieldComment}\n#else\n ${field.attrName}: \'\', // ${field.fieldComment}\n#end\n#end\n});\n\n// ========== 4. 字典数据处理 ==========\n#set($fieldDict=[])\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n#if($fieldDict && $fieldDict.size() > 0)\n// 加载字典数据\nconst { $dict.format($fieldDict) } = useDict($dict.quotation($fieldDict));\n#end\n\n// ========== 5. 表单校验规则 ==========\nconst dataRules = ref({\n#foreach($field in $formList)\n#if($field.formRequired == \'1\' && $field.formValidator == \'duplicate\')\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' },\n {\n validator: (rule: any, value: any, callback: any) => {\n // 重复性校验(编辑时跳过)\n validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n },\n trigger: \'blur\',\n }\n ],\n#elseif($field.formRequired == \'1\' && $field.formValidator)\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' },\n { validator: rule.${field.formValidator}, trigger: \'blur\' }\n ],\n#elseif($field.formRequired == \'1\')\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' }\n ],\n#elseif($field.formValidator)\n ${field.attrName}: [\n { validator: rule.${field.formValidator}, trigger: \'blur\' }\n ],\n#end\n#end\n});\n\n// ========== 6. 方法定义 ==========\n// 获取详情数据\nconst get${ClassName}Data = async (id: string) => {\n try {\n loading.value = true;\n const { data } = await getObj({ ${pk.attrName}: id });\n // 直接将第一条数据赋值给表单\n Object.assign(form, data[0]);\n } catch (error) {\n useMessage().error(\'获取数据失败\');\n } finally {\n loading.value = false;\n }\n};\n\n// 打开弹窗方法\nconst openDialog = (id: string) => {\n visible.value = true;\n form.${pk.attrName} = \'\';\n\n // 重置表单数据\n nextTick(() => {\n dataFormRef.value?.resetFields();\n });\n\n // 获取${ClassName}信息\n if (id) {\n form.${pk.attrName} = id;\n get${ClassName}Data(id);\n }\n};\n\n// 提交表单方法\nconst onSubmit = async () => {\n loading.value = true; // 防止重复提交\n \n // 表单校验\n const valid = await dataFormRef.value.validate().catch(() => {});\n if (!valid) {\n loading.value = false;\n return false;\n }\n\n try {\n // 根据是否有ID判断是新增还是修改\n form.${pk.attrName} ? await putObj(form) : await addObj(form);\n useMessage().success(form.${pk.attrName} ? \'修改成功\' : \'添加成功\');\n visible.value = false;\n emit(\'refresh\'); // 通知父组件刷新列表\n } catch (err: any) {\n useMessage().error(err.msg);\n } finally {\n loading.value = false;\n }\n};\n\n// ========== 7. 对外暴露 ==========\n// 暴露方法给父组件\ndefineExpose({\n openDialog\n});\n</script> ','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (11,'主子ServiceV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','主子ServiceV2026001','package ${package}.${moduleName}.service;\n\nimport com.github.yulichang.extension.mapping.base.MPJDeepService;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\n\npublic interface ${ClassName}Service extends MPJDeepService<${ClassName}Entity> {\n Boolean saveDeep(${ClassName}Entity ${className});\n\n Boolean updateDeep(${ClassName}Entity ${className});\n\n Boolean removeDeep(Long[] ids);\n\n Boolean removeChild(Long[] ids);\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (12,'主子ServiceImplV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','主子ServiceImplV2026001','package ${package}.${moduleName}.service.impl;\n\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport org.springframework.stereotype.Service;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${package}.${moduleName}.mapper.${ChildClassName}Mapper;\nimport org.springframework.transaction.annotation.Transactional;\nimport lombok.RequiredArgsConstructor;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n private final ${ChildClassName}Mapper ${childClassName}Mapper;\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean saveDeep(${ClassName}Entity ${className}) {\n baseMapper.insert(${className});\n for (${ChildClassName}Entity ${childClassName} : ${className}.get${ChildClassName}List()) {\n ${childClassName}.$str.setProperty($childField)(${className}.$str.getProperty($mainField)());\n ${childClassName}Mapper.insert( ${childClassName});\n }\n\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean updateDeep(${ClassName}Entity ${className}) {\n baseMapper.updateById(${className});\n for (${ChildClassName}Entity ${childClassName} : ${className}.get${ChildClassName}List()) {\n#set($getChildPkName=$str.getProperty(${pk.attrName}))\n if (Objects.isNull(${childClassName}.$getChildPkName())) {\n ${childClassName}.$str.setProperty($childField)(${className}.$str.getProperty($mainField)());\n ${childClassName}Mapper.insert(${childClassName});\n } else {\n ${childClassName}Mapper.updateById(${childClassName});\n }\n }\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeDeep(Long[] ids) {\n baseMapper.deleteBatchIds(CollUtil.toList(ids));\n ${childClassName}Mapper.delete(Wrappers.<${ChildClassName}Entity>lambdaQuery().in(${ChildClassName}Entity::$str.getProperty($childField), ids));\n return Boolean.TRUE;\n }\n\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeChild(Long[] ids) {\n ${childClassName}Mapper.deleteBatchIds(CollUtil.toList(ids));\n return Boolean.TRUE;\n }\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (13,'主实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','主实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\nimport $import;\n#end\nimport org.apache.fesod.sheet.annotation.ExcelIgnore;\nimport com.github.yulichang.annotation.EntityMapping;\nimport java.util.List;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(\"${tableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n @TableField(typeHandler = JacksonTypeHandler.class)\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n @ExcelIgnore\n @TableField(exist = false)\n @EntityMapping(thisField = \"$mainField\", joinField = \"$childField\")\n private List<${ChildClassName}Entity> ${childClassName}List;\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (14,'MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV2026001','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (15,'Mapper.xmlV2026001','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV2026001','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (16,'权限菜单V2026001','${backendPath}/menu/${functionName}_menu.sql','权限菜单V2026001','-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (17,'api.tsV2026001','${frontendPath}/src/api/${moduleName}/${functionName}.ts','api.tsV2026001','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n\n#if($ChildClassName)\n// ========== 子表相关接口 ==========\n\n/**\n * 删除子表数据\n * @param ids - 要删除的子表数据ID数组\n * @returns Promise<操作结果>\n */\nexport function delChildObj(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/child\',\n method: \'delete\',\n data: ids\n })\n}\n#end\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (18,'子实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ChildClassName}Entity.java','子实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\n#if($isChildTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isChildTenant)\n@TenantTable\n#end\n@TableName(\"${childTableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${childTableName}\")\npublic class ${ChildClassName}Entity extends Model<${ChildClassName}Entity> {\n\n#foreach ($field in $childFieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end \n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (19,'主子ControllerV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','主子ControllerV2026001','package ${package}.${moduleName}.controller;\n\n#if($queryList)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"分页查询\" , description = \"分页查询\" )\n @GetMapping(\"/page\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#foreach ($field in $queryList)\n#set($getAttrName=$str.getProperty($field.attrName))\n#set($var=\"${className}.$getAttrName()\")\n#if($field.attrType == \'String\')\n#set($expression=\"StrUtil.isNotBlank\")\n#else\n#set($expression=\"Objects.nonNull\")\n#end\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n if (ArrayUtil.isNotEmpty(${className}.${getAttrName}Range())) {\n wrapper.between(${ClassName}Entity::$getAttrName, ${className}.${getAttrName}Range()[0], ${className}.${getAttrName}Range()[1]);\n }\n#elseif($field.queryType == \'=\')\n wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'like\' )\n wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'!-\' )\n wrapper.ne($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>\' )\n wrapper.gt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<\' )\n wrapper.lt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>=\' )\n wrapper.ge($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<=\' )\n wrapper.le($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'left like\' )\n wrapper.likeLeft($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'right like\' )\n wrapper.likeRight($expression($var),${ClassName}Entity::$getAttrName,$var);\n#end\n#end\n return R.ok(${className}Service.page(page, wrapper));\n }\n\n\n /**\n * 通过条件查询${tableComment}\n * @param ${className} 查询条件\n * @return R 对象列表\n */\n @Operation(summary = \"通过条件查询\" , description = \"通过条件查询对象\" )\n @GetMapping(\"/details\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R getDetails(@ParameterObject ${ClassName}Entity ${className}) {\n return R.ok(${className}Service.listDeep(Wrappers.query(${className})));\n }\n\n /**\n * 新增${tableComment}\n * @param ${className} ${tableComment}\n * @return R\n */\n @Operation(summary = \"新增${tableComment}\" , description = \"新增${tableComment}\" )\n @SysLog(\"新增${tableComment}\" )\n @PostMapping\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\')\" )\n #end\n public R save(@RequestBody ${ClassName}Entity ${className}) {\n return R.ok(${className}Service.saveDeep(${className}));\n }\n\n /**\n * 修改${tableComment}\n * @param ${className} ${tableComment}\n * @return R\n */\n @Operation(summary = \"修改${tableComment}\" , description = \"修改${tableComment}\" )\n @SysLog(\"修改${tableComment}\" )\n @PutMapping\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\')\" )\n #end\n public R updateById(@RequestBody ${ClassName}Entity ${className}) {\n return R.ok(${className}Service.updateDeep(${className}));\n }\n\n /**\n * 通过id删除${tableComment}\n * @param ids ${pk.attrName}列表\n * @return R\n */\n @Operation(summary = \"通过id删除${tableComment}\" , description = \"通过id删除${tableComment}\" )\n @SysLog(\"通过id删除${tableComment}\" )\n @DeleteMapping\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\')\" )\n #end\n public R removeById(@RequestBody ${pk.attrType}[] ids) {\n return R.ok(${className}Service.removeDeep(ids));\n }\n\n /**\n * 通过id删除${tableComment}子表数据\n * @param ids ${pk.attrName}列表\n * @return R\n */\n @Operation(summary = \"通过id删除${tableComment}子表数据\" , description = \"通过id删除${tableComment}子表数据\" )\n @SysLog(\"通过id删除${tableComment}子表数据\" )\n @DeleteMapping(\"/child\")\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\')\" )\n #end\n public R removeChild(@RequestBody ${pk.attrType}[] ids) {\n return R.ok(${className}Service.removeChild(ids));\n }\n\n /**\n * 导出excel 表格\n * @param ${className} 查询条件\n * @param ids 导出指定ID\n * @return excel 文件流\n */\n @ResponseExcel\n @GetMapping(\"/export\")\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\')\" )\n #end\n public List<${ClassName}Entity> exportExcel(${ClassName}Entity ${className},${pk.attrType}[] ids) {\n return ${className}Service.list(Wrappers.lambdaQuery(${className}).in(ArrayUtil.isNotEmpty(ids), ${ClassName}Entity::$str.getProperty($pk.attrName), ids));\n }\n\n /**\n * 导入excel 表\n * @param ${className}List 对象实体列表\n * @param bindingResult 错误信息列表\n * @return ok fail\n */\n @PostMapping(\"/import\")\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\')\" )\n #end\n public R importExcel(@RequestExcel List<${ClassName}Entity> ${className}List, BindingResult bindingResult) {\n return R.ok(${className}Service.saveBatch(${className}List));\n }\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (20,'主子表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','主子表单V2026001','<template>\n <el-drawer :title=\"form.${pk.attrName} ? (detail ? \'详情\' : \'编辑\') : \'添加\'\" v-model=\"visible\" size=\"50%\">\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" :disabled=\"detail\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetime\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"daterange\" range-separator=\"至\" start-placeholder=\"开始日期\" end-placeholder=\"结束日期\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetimerange\" range-separator=\"至\" start-placeholder=\"开始时间\" end-placeholder=\"结束时间\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'number\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-input-number :min=\"1\" :max=\"1000\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\"></el-input-number>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'upload-file\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <upload-file v-model=\"form.${field.attrName}\"></upload-file>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'upload-img\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <upload-img v-model:imageUrl=\"form.${field.attrName}\"></upload-img>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'editor\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <editor v-if=\"visible\" v-model:get-html=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\"></editor>\n </el-form-item>\n </el-col>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\"/>\n </el-form-item>\n </el-col>\n#end\n#end\n#end\n </el-row>\n <el-row :gutter=\"24\">\n <sc-form-table\n v-model=\"form.${childClassName}List\"\n :addTemplate=\"childTemp\"\n @delete=\"deleteChild\"\n placeholder=\"暂无数据\"\n >\n#set($ignoreColumnList = [\"create_by\",\"create_time\",\"update_by\",\"update_time\",\"del_flag\",\"tenant_id\"])\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#elseif($ignoreColumnList.contains(${field.fieldName}))\n#elseif($field.attrName == $childField)\n#else \n <el-table-column label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end\" prop=\"${field.attrName}\">\n <template #default=\"{ row, $index }\">\n <el-form-item :prop=\"`${childClassName}List.${$index}.${field.attrName}`\" :rules=\"[{ required: true, trigger: \'blur\' }]\">\n <el-input v-model=\"row.${field.attrName}\"/>\n </el-form-item>\n </template>\n </el-table-column>\n#end\n#end\n </sc-form-table>\n </el-row>\n </el-form>\n <template #footer>\n <span class=\"dialog-footer\">\n <el-button @click=\"visible = false\">取 消</el-button>\n <el-button type=\"primary\" @click=\"onSubmit\" :disabled=\"loading\">确 认</el-button>\n </span>\n </template>\n </el-drawer>\n</template>\n\n<script setup lang=\"ts\" name=\"${ClassName}Dialog\">\n// ========== 1. 导入语句 ==========\nimport { useDict } from \'/@/hooks/dict\';\nimport { rule } from \'/@/utils/validate\';\nimport { useMessage } from \"/@/hooks/message\";\nimport { getObj, addObj, putObj, delChildObj, validateExist } from \'/@/api/${moduleName}/${functionName}\';\n\n// ========== 2. 组件定义 ==========\n// 异步加载表格组件\nconst scFormTable = defineAsyncComponent(() => import(\'/@/components/FormTable/index.vue\'));\n\n// 定义组件事件\nconst emit = defineEmits([\'refresh\']);\n\n// ========== 3. 响应式数据定义 ==========\n// 基础响应式变量\nconst dataFormRef = ref(); // 表单引用\nconst visible = ref(false); // 抽屉显示状态\nconst loading = ref(false); // 加载状态\nconst detail = ref(false); // 是否为详情模式\n\n// 表单数据对象\nconst form = reactive({\n#if(!$formList.contains(${pk.attrName}))\n ${pk.attrName}: \'\', // 主键\n#end\n#foreach($field in $formList)\n#if($field.formType == \'number\')\n ${field.attrName}: 0, // ${field.fieldComment}\n#elseif($field.formType == \'checkbox\' || $field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n ${field.attrName}: [], // ${field.fieldComment}\n#else\n ${field.attrName}: \'\', // ${field.fieldComment}\n#end\n#end\n ${childClassName}List: [], // 子表数据列表\n});\n\n// 子表数据模板\nconst childTemp = reactive({\n#foreach($field in $childFieldList)\n ${field.attrName}: \'\', // ${field.fieldComment}\n#end\n});\n\n// ========== 4. 字典数据处理 ==========\n#set($fieldDict=[])\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n#if($fieldDict && $fieldDict.size() > 0)\n// 加载字典数据\nconst { $dict.format($fieldDict) } = useDict($dict.quotation($fieldDict));\n#end\n\n// ========== 5. 表单校验规则 ==========\nconst dataRules = ref({\n#foreach($field in $formList)\n#if($field.formRequired == \'1\' && $field.formValidator == \'duplicate\')\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' },\n {\n validator: (rule: any, value: any, callback: any) => {\n // 重复性校验(编辑时跳过)\n validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n },\n trigger: \'blur\',\n }\n ],\n#elseif($field.formRequired == \'1\' && $field.formValidator)\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' },\n { validator: rule.${field.formValidator}, trigger: \'blur\' }\n ],\n#elseif($field.formRequired == \'1\')\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' }\n ],\n#elseif($field.formValidator)\n ${field.attrName}: [\n { validator: rule.${field.formValidator}, trigger: \'blur\' }\n ],\n#end\n#end\n});\n\n// ========== 6. 方法定义 ==========\n// 获取主子表详情数据\nconst get${ClassName}Data = async (id: string) => {\n try {\n loading.value = true;\n const { data } = await getObj({ ${pk.attrName}: id });\n // 直接将第一条数据赋值给表单\n Object.assign(form, data[0]);\n } catch (error) {\n useMessage().error(\'获取数据失败\');\n } finally {\n loading.value = false;\n }\n};\n\n// 打开抽屉方法\nconst openDialog = (id: string, isDetail: boolean) => {\n visible.value = true;\n detail.value = isDetail;\n form.${pk.attrName} = \'\';\n\n // 重置表单数据\n nextTick(() => {\n dataFormRef.value?.resetFields();\n form.${childClassName}List = [];\n });\n\n // 获取${ClassName}信息\n if (id) {\n form.${pk.attrName} = id;\n get${ClassName}Data(id);\n }\n};\n\n// 提交表单方法\nconst onSubmit = async () => {\n loading.value = true; // 防止重复提交\n \n // 表单校验\n const valid = await dataFormRef.value.validate().catch(() => {});\n if (!valid) {\n loading.value = false;\n return false;\n }\n\n try {\n // 根据是否有ID判断是新增还是修改\n form.${pk.attrName} ? await putObj(form) : await addObj(form);\n useMessage().success(form.${pk.attrName} ? \'修改成功\' : \'添加成功\');\n visible.value = false;\n emit(\'refresh\'); // 通知父组件刷新列表\n } catch (err: any) {\n useMessage().error(err.msg);\n } finally {\n loading.value = false;\n }\n};\n\n#foreach ($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkName=$field.attrName)\n#end\n#end\n// 删除子表数据方法\nconst deleteChild = async (obj: { $childPkName: string }) => {\n if (obj.$childPkName) {\n try {\n await delChildObj([obj.$childPkName]);\n useMessage().success(\'删除成功\');\n } catch (err: any) {\n useMessage().error(err.msg);\n }\n }\n};\n\n// ========== 7. 对外暴露 ==========\n// 暴露方法给父组件\ndefineExpose({\n openDialog\n});\n</script>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (21,'主子表格V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','主子表格V2026001','<template>\n <div class=\"layout-padding\">\n <div class=\"layout-padding-auto layout-padding-view\">\n#if($queryList)\n <el-row v-show=\"showSearch\">\n <el-form :model=\"state.queryForm\" ref=\"queryRef\" :inline=\"true\" @keyup.enter=\"getDataList\">\n#foreach($field in $queryList)\n#if($field.queryFormType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"state.queryForm.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option \n :label=\"item.label\" \n :value=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n :key=\"index\">\n </el-option>\n#else\n <el-option label=\"请选择\">0</el-option>\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"date\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n :value-format=\"dateStr\"\n v-model=\"state.queryForm.${field.attrName}\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"daterange\"\n range-separator=\"至\"\n start-placeholder=\"开始日期\"\n end-placeholder=\"结束日期\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"datetime\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n :value-format=\"dateTimeStr\"\n v-model=\"state.queryForm.${field.attrName}\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"datetimerange\"\n range-separator=\"至\"\n start-placeholder=\"开始时间\"\n end-placeholder=\"结束时间\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"state.queryForm.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio \n :label=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n border \n :key=\"index\">\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input \n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" \n v-model=\"state.queryForm.${field.attrName}\"\n style=\"max-width: 180px\" \n />\n </el-form-item>\n#end\n#end\n <el-form-item>\n <el-button icon=\"search\" type=\"primary\" @click=\"getDataList\">\n 查询\n </el-button>\n <el-button icon=\"Refresh\" @click=\"resetQuery\">重置</el-button>\n </el-form-item>\n </el-form>\n </el-row>\n#end\n <el-row>\n <div class=\"mb8\" style=\"width: 100%\">\n <el-button \n icon=\"folder-add\" \n type=\"primary\" \n class=\"ml10\" \n @click=\"formDialogRef.openDialog()\"\n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\'\">\n 新增\n </el-button>\n <el-button \n plain \n :disabled=\"multiple\" \n icon=\"Delete\" \n type=\"primary\"\n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\'\" \n @click=\"handleDelete(selectObjs.value)\">\n 删除\n </el-button>\n <right-toolbar \n v-model:showSearch=\"showSearch\" \n :export=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\'\"\n @exportExcel=\"exportExcel\" \n class=\"ml10 mr20\" \n style=\"float: right;\"\n @queryTable=\"getDataList\">\n </right-toolbar>\n </div>\n </el-row>\n <el-table \n :data=\"state.dataList\" \n v-loading=\"state.loading\" \n border \n :cell-style=\"tableStyle.cellStyle\" \n :header-cell-style=\"tableStyle.headerCellStyle\"\n @selection-change=\"selectionChangeHandle\" \n @sort-change=\"sortChangeHandle\">\n <el-table-column type=\"selection\" width=\"40\" align=\"center\" />\n <el-table-column type=\"index\" label=\"#\" width=\"40\" />\n#foreach($field in $gridList)\n#if($field.fieldDict)\n <el-table-column prop=\"${field.attrName}\" label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" show-overflow-tooltip>\n <template #default=\"scope\">\n <dict-tag :options=\"$field.fieldDict\" :value=\"scope.row.${field.attrName}\"></dict-tag>\n </template>\n </el-table-column>\n#elseif(${field.formType} == \'upload-img\')\n <el-table-column prop=\"${field.attrName}\" label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n <template #default=\"{ row }\">\n <upload-img disabled v-model:imageUrl=\"row.${field.attrName}\"></upload-img>\n </template>\n </el-table-column>\n#else\n <el-table-column\n prop=\"${field.attrName}\"\n label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n#if(${field.gridSort} == \'1\')\n sortable=\"custom\"\n#end\n show-overflow-tooltip\n />\n#end\n#end\n <el-table-column label=\"操作\" width=\"200\">\n <template #default=\"scope\">\n#if($ChildClassName)\n <el-button \n text \n type=\"primary\" \n icon=\"view\" \n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\'\" \n @click=\"formDialogRef.openDialog(scope.row.${pk.attrName}, true)\">\n 详情\n </el-button>\n#end\n <el-button \n icon=\"edit-pen\" \n text \n type=\"primary\" \n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\'\"\n @click=\"formDialogRef.openDialog(scope.row.${pk.attrName})\">\n 编辑\n </el-button>\n <el-button \n icon=\"delete\" \n text \n type=\"primary\" \n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\'\" \n @click=\"handleDelete([scope.row.${pk.attrName}])\">\n 删除\n </el-button>\n </template>\n </el-table-column>\n </el-table>\n <pagination \n @size-change=\"sizeChangeHandle\" \n @current-change=\"currentChangeHandle\" \n v-bind=\"state.pagination\" \n />\n </div>\n\n <!-- 编辑、新增 -->\n <form-dialog ref=\"formDialogRef\" @refresh=\"getDataList(false)\" />\n </div>\n</template>\n\n<script setup lang=\"ts\" name=\"system${ClassName}\">\nimport { BasicTableProps, useTable } from \"/@/hooks/table\";\nimport { fetchList, delObjs } from \"/@/api/${moduleName}/${functionName}\";\nimport { useMessage, useMessageBox } from \"/@/hooks/message\";\nimport { useDict } from \'/@/hooks/dict\';\n\n// 引入组件\nconst FormDialog = defineAsyncComponent(() => import(\'./form.vue\'));\n\n// 定义查询字典\n#set($fieldDict=[])\n#foreach($field in $queryList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n#if($fieldDict)\nconst { $dict.format($fieldDict) } = useDict($dict.quotation($fieldDict));\n#end\n\n// 定义变量内容\nconst formDialogRef = ref();\n// 搜索变量\nconst queryRef = ref();\nconst showSearch = ref(true);\n// 多选变量\nconst selectObjs = ref([]) as any;\nconst multiple = ref(true);\n\nconst state: BasicTableProps = reactive<BasicTableProps>({\n queryForm: {},\n pageList: fetchList\n});\n\n// table hook\nconst {\n getDataList,\n currentChangeHandle,\n sizeChangeHandle,\n sortChangeHandle,\n downBlobFile,\n tableStyle\n} = useTable(state);\n\n// 清空搜索条件\nconst resetQuery = () => {\n // 清空搜索条件\n queryRef.value?.resetFields();\n // 清空多选\n selectObjs.value = [];\n getDataList();\n};\n\n// 导出excel\nconst exportExcel = () => {\n downBlobFile(\'/${moduleName}/${functionName}/export\', { ...state.queryForm, ids: selectObjs.value }, \'${functionName}.xlsx\');\n};\n\n// 多选事件\nconst selectionChangeHandle = (objs: { $pk.attrName: string }[]) => {\n selectObjs.value = objs.map(({ $pk.attrName }) => $pk.attrName);\n multiple.value = !objs.length;\n};\n\n// 删除操作\nconst handleDelete = async (ids: string[]) => {\n try {\n await useMessageBox().confirm(\'此操作将永久删除\');\n } catch {\n return;\n }\n\n try {\n await delObjs(ids);\n getDataList();\n useMessage().success(\'删除成功\');\n } catch (err: any) {\n useMessage().error(err.msg);\n }\n};\n</script>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (22,'子MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ChildClassName}Mapper.java','子MapperV2026001','package ${package}.${moduleName}.mapper;\n\nimport ${package}.common.data.datascope.PigxBaseMapper;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ChildClassName}Mapper extends PigxBaseMapper<${ChildClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (23,'树形ControllerV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','树形ControllerV2026001','package ${package}.${moduleName}.controller;\n\n#if($queryList)\nimport cn.hutool.core.util.StrUtil;\n#end\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 获取树形列表\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"获取树形列表\" , description = \"获取树形列表\" )\n @GetMapping(\"/tree\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R get${ClassName}Tree(@ParameterObject ${ClassName}Entity ${className}) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#foreach ($field in $queryList)\n#set($getAttrName=$str.getProperty($field.attrName))\n#set($var=\"${className}.$getAttrName()\")\n#if($field.attrType == \'String\')\n#set($expression=\"StrUtil.isNotBlank\")\n#else\n#set($expression=\"Objects.nonNull\")\n#end\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n if (ArrayUtil.isNotEmpty(${className}.${getAttrName}Range())) {\n wrapper.between(${ClassName}Entity::$getAttrName, ${className}.${getAttrName}Range()[0], ${className}.${getAttrName}Range()[1]);\n }\n#elseif($field.queryType == \'=\')\n wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'like\' )\n wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'!-\' )\n wrapper.ne($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>\' )\n wrapper.gt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<\' )\n wrapper.lt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>=\' )\n wrapper.ge($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<=\' )\n wrapper.le($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'left like\' )\n wrapper.likeLeft($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'right like\' )\n wrapper.likeRight($expression($var),${ClassName}Entity::$getAttrName,$var);\n#end\n#end\n return R.ok(${className}Service.buildTree(wrapper));\n }\n\n /**\n * 通过条件查询${tableComment}\n * @param ${className} 查询条件\n * @return R 对象列表\n */\n @Operation(summary = \"通过条件查询\" , description = \"通过条件查询对象\" )\n @GetMapping(\"/details\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R getDetails(@ParameterObject ${ClassName}Entity ${className}) {\n return R.ok(${className}Service.list(Wrappers.query(${className})));\n }\n\n /**\n * 新增${tableComment}\n * @param ${className} ${tableComment}\n * @return R\n */\n @Operation(summary = \"新增${tableComment}\" , description = \"新增${tableComment}\" )\n @SysLog(\"新增${tableComment}\" )\n @PostMapping\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\')\" )\n #end\n public R save(@RequestBody ${ClassName}Entity ${className}) {\n return R.ok(${className}Service.save(${className}));\n }\n\n /**\n * 修改${tableComment}\n * @param ${className} ${tableComment}\n * @return R\n */\n @Operation(summary = \"修改${tableComment}\" , description = \"修改${tableComment}\" )\n @SysLog(\"修改${tableComment}\" )\n @PutMapping\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\')\" )\n #end\n public R updateById(@RequestBody ${ClassName}Entity ${className}) {\n return R.ok(${className}Service.updateById(${className}));\n }\n\n /**\n * 通过id删除${tableComment}\n * @param ids ${pk.attrName}列表\n * @return R\n */\n @Operation(summary = \"通过id删除${tableComment}\" , description = \"通过id删除${tableComment}\" )\n @SysLog(\"通过id删除${tableComment}\" )\n @DeleteMapping\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\')\" )\n #end\n public R removeById(@RequestBody ${pk.attrType}[] ids) {\n return R.ok(${className}Service.removeBatchByIds(CollUtil.toList(ids)));\n }\n\n /**\n * 导出excel 表格\n * @param ${className} 查询条件\n * @param ids 导出指定ID\n * @return excel 文件流\n */\n @ResponseExcel\n @GetMapping(\"/export\")\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\')\" )\n #end\n public List<${ClassName}Entity> exportExcel(${ClassName}Entity ${className},${pk.attrType}[] ids) {\n return ${className}Service.list(Wrappers.lambdaQuery(${className}).in(ArrayUtil.isNotEmpty(ids), ${ClassName}Entity::$str.getProperty($pk.attrName), ids));\n }\n\n /**\n * 导入excel 表\n * @param ${className}List 对象实体列表\n * @param bindingResult 错误信息列表\n * @return ok fail\n */\n @PostMapping(\"/import\")\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\')\" )\n #end\n public R importExcel(@RequestExcel List<${ClassName}Entity> ${className}List, BindingResult bindingResult) {\n return R.ok(${className}Service.saveBatch(${className}List));\n }\n} \n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (24,'树形ServiceV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','树形ServiceV2026001','package ${package}.${moduleName}.service;\n\nimport cn.hutool.core.lang.tree.Tree;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.extension.service.IService;\nimport ${entityClassName};\n\nimport java.util.List;\n\n/**\n * ${tableComment} Service接口\n *\n * @author ${author}\n * @date ${datetime}\n */\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n List<Tree<${pk.attrType}>> buildTree(LambdaQueryWrapper<${ClassName}Entity> wrapper);\n\n /**\n * 递归删除节点及其子节点\n * @param ids 要删除的节点ID列表\n * @return 删除结果\n */\n boolean removeBatchByIds(List<${pk.attrType}> ids);\n} ','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (25,'树形ServiceImplV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','树形ServiceImplV2026001','package ${package}.${moduleName}.service.impl;\n\nimport cn.hutool.core.collection.CollUtil;\nimport cn.hutool.core.lang.tree.Tree;\nimport cn.hutool.core.lang.tree.TreeNode;\nimport cn.hutool.core.lang.tree.TreeUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport jakarta.validation.constraints.NotNull;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.stream.Collectors;\n\n/**\n * ${tableComment} Service实现类\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n @Override\n public List<Tree<${pk.attrType}>> buildTree(LambdaQueryWrapper<${ClassName}Entity> wrapper) {\n // 查询所有数据\n List<${ClassName}Entity> allList = list(wrapper);\n \n if (CollUtil.isEmpty(allList)) {\n return new ArrayList<>();\n }\n\n // 转换为TreeNode\n List<TreeNode<${pk.attrType}>> collect = allList.stream().map(getNodeFunction()).toList();\n\n // 使用TreeUtil构建树形结构,根节点ID为0\n#if($pk.attrType == \'Long\')\n return TreeUtil.build(collect, 0L);\n#else\n return TreeUtil.build(collect, 0);\n#end\n }\n\n /**\n * 获取TreeNode转换函数\n * @return TreeNode转换函数\n */\n @NotNull\n private Function<${ClassName}Entity, TreeNode<${pk.attrType}>> getNodeFunction() {\n return entity -> {\n TreeNode<${pk.attrType}> node = new TreeNode<>();\n node.setId(entity.$str.getProperty($pk.attrName)());\n node.setName(entity.$str.getProperty($nameField)());\n node.setParentId(entity.$str.getProperty($parentField)() != null ? entity.$str.getProperty($parentField)() : 0L);\n\n // 扩展属性\n Map<String, Object> extra = new HashMap<>();\n#foreach($field in $fieldList)\n extra.put(${ClassName}Entity.Fields.${field.attrName}, entity.$str.getProperty($field.attrName)());\n#end\n node.setExtra(extra);\n return node;\n };\n }\n\n /**\n * 递归删除节点及其子节点\n * @param ids 要删除的节点ID列表\n * @return 删除结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public boolean removeBatchByIds(List<${pk.attrType}> ids) {\n if (CollUtil.isEmpty(ids)) {\n return true;\n }\n\n // 获取所有要删除的ID(包括子节点)\n List<${pk.attrType}> allDeleteIds = new ArrayList<>(ids);\n \n for (${pk.attrType} id : ids) {\n List<${pk.attrType}> childIds = getChildIdsRecursive(id);\n allDeleteIds.addAll(childIds);\n }\n\n // 去重\n allDeleteIds = allDeleteIds.stream().distinct().collect(Collectors.toList());\n\n // 批量删除\n return super.removeBatchByIds(allDeleteIds);\n }\n\n /**\n * 递归获取所有子节点ID\n * @param parentId 父节点ID\n * @return 子节点ID列表\n */\n private List<${pk.attrType}> getChildIdsRecursive(${pk.attrType} parentId) {\n List<${pk.attrType}> childIds = new ArrayList<>();\n \n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n wrapper.eq(${ClassName}Entity::$str.getProperty($parentField), parentId);\n wrapper.select(${ClassName}Entity::$str.getProperty($pk.attrName));\n \n List<${ClassName}Entity> children = list(wrapper);\n \n for (${ClassName}Entity child : children) {\n ${pk.attrType} childId = child.$str.getProperty($pk.attrName)();\n childIds.add(childId);\n // 递归获取子节点的子节点\n childIds.addAll(getChildIdsRecursive(childId));\n }\n \n return childIds;\n }\n} ','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (26,'树形实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','树形实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\nimport lombok.experimental.FieldNameConstants;\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@FieldNameConstants\n@TableName(\"${tableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (27,'MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV2026001','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (28,'Mapper.xmlV2026001','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV2026001','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (29,'权限菜单V2026001','${backendPath}/menu/${functionName}_menu.sql','权限菜单V2026001','-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (30,'树形api.tsV2026001','${frontendPath}/src/api/${moduleName}/${functionName}.ts','树形api.tsV2026001','import request from \"/@/utils/request\"\n\n// ========== 树形表格CRUD接口 ==========\n\n/**\n * 获取树形列表数据\n * @param query - 查询参数对象\n * @returns Promise<树形数据>\n */\nexport function fetchTreeList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据(递归删除子节点)\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n * \n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (31,'树形表格V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','树形表格V2026001','<template>\n <div class=\"layout-padding\">\n <div class=\"layout-padding-auto layout-padding-view\">\n#if($queryList)\n <!-- 查询表单区域 -->\n <el-row v-show=\"showSearch\">\n <el-form :model=\"state.queryForm\" ref=\"queryRef\" :inline=\"true\" @keyup.enter=\"getDataList\">\n#foreach($field in $queryList)\n#if($field.queryFormType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"state.queryForm.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option \n :label=\"item.label\" \n :value=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n :key=\"index\"\n />\n#else\n <el-option label=\"请选择\" value=\"0\" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker \n type=\"date\" \n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" \n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"datetime\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"daterange\"\n range-separator=\"至\"\n start-placeholder=\"开始日期\"\n end-placeholder=\"结束日期\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"datetimerange\"\n range-separator=\"至\"\n start-placeholder=\"开始时间\"\n end-placeholder=\"结束时间\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"state.queryForm.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio \n :label=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n border \n :key=\"index\"\n >\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>\n ${field.fieldComment}\n </el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input \n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" \n v-model=\"state.queryForm.${field.attrName}\" \n />\n </el-form-item>\n#end\n#end\n <el-form-item>\n <el-button icon=\"search\" type=\"primary\" @click=\"getDataList\">\n 查询\n </el-button>\n <el-button icon=\"Refresh\" @click=\"resetQuery\">重置</el-button>\n </el-form-item>\n </el-form>\n </el-row>\n#end\n\n <!-- 操作按钮区域 -->\n <el-row>\n <div class=\"mb8\" style=\"width: 100%\">\n <el-button \n icon=\"folder-add\" \n type=\"primary\" \n class=\"ml10\" \n @click=\"formDialogRef.openDialog()\"\n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\'\"\n >\n 新增\n </el-button>\n\n <el-button \n plain \n :disabled=\"multiple\" \n icon=\"Delete\" \n type=\"primary\"\n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\'\" \n @click=\"handleDelete(selectObjs)\"\n >\n 删除\n </el-button>\n\n <el-button \n plain \n :icon=\"isExpand ? \'FolderOpened\' : \'Folder\'\" \n type=\"primary\"\n @click=\"handleExpand\"\n >\n {{ isExpand ? \'全部折叠\' : \'全部展开\' }}\n </el-button>\n\n <right-toolbar \n v-model:showSearch=\"showSearch\" \n class=\"ml10 mr20\" \n style=\"float: right;\"\n @queryTable=\"getDataList\"\n />\n </div>\n </el-row>\n\n <!-- 树形数据表格区域 -->\n <el-table \n ref=\"tableRef\"\n :data=\"state.dataList\" \n v-loading=\"state.loading\" \n border \n row-key=\"${pk.attrName}\"\n default-expand-all\n :tree-props=\"{ children: \'children\', hasChildren: \'hasChildren\' }\"\n :cell-style=\"tableStyle.cellStyle\" \n :header-cell-style=\"tableStyle.headerCellStyle\"\n @selection-change=\"selectionChangHandle\"\n @expand-change=\"onExpandChange\"\n >\n <el-table-column type=\"selection\" width=\"40\" align=\"center\" />\n <el-table-column type=\"index\" label=\"#\" width=\"40\" />\n#foreach($field in $gridList)\n#if($field.fieldDict)\n <el-table-column prop=\"${field.attrName}\" label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" show-overflow-tooltip>\n <template #default=\"scope\">\n <dict-tag :options=\"${field.fieldDict}\" :value=\"scope.row.${field.attrName}\" />\n </template>\n </el-table-column>\n#elseif(${field.formType} == \'upload-img\')\n <el-table-column prop=\"${field.attrName}\" label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n <template #default=\"{ row }\">\n <upload-img disabled v-model:imageUrl=\"row.${field.attrName}\"></upload-img>\n </template>\n </el-table-column>\n#else\n <el-table-column\n prop=\"${field.attrName}\"\n label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n show-overflow-tooltip\n#if($field == $gridList[0])\n width=\"200\"\n#end\n />\n#end\n#end\n <el-table-column label=\"操作\" width=\"200\" fixed=\"right\">\n <template #default=\"scope\">\n <el-button \n icon=\"plus\" \n text \n type=\"primary\" \n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\'\"\n @click=\"formDialogRef.openDialog(undefined, scope.row.${pk.attrName})\"\n >\n 新增\n </el-button>\n <el-button \n icon=\"edit-pen\" \n text \n type=\"primary\" \n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\'\"\n @click=\"formDialogRef.openDialog(scope.row.${pk.attrName})\"\n >\n 编辑\n </el-button>\n <el-button \n icon=\"delete\" \n text \n type=\"primary\" \n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\'\" \n @click=\"handleDelete([scope.row.${pk.attrName}])\"\n >\n 删除\n </el-button>\n </template>\n </el-table-column>\n </el-table>\n </div>\n\n <!-- 编辑、新增弹窗 -->\n <form-dialog ref=\"formDialogRef\" @refresh=\"getDataList(false)\" />\n </div>\n</template>\n\n<script setup lang=\"ts\" name=\"system${ClassName}Tree\">\n// ========== 导入声明 ==========\nimport { BasicTableProps, useTable } from \"/@/hooks/table\";\nimport { fetchTreeList, delObjs } from \"/@/api/${moduleName}/${functionName}\";\nimport { useMessage, useMessageBox } from \"/@/hooks/message\";\nimport { useDict } from \'/@/hooks/dict\';\n\n// ========== 组件声明 ==========\n// 异步加载表单弹窗组件\nconst FormDialog = defineAsyncComponent(() => import(\'./form.vue\'));\n\n// ========== 字典数据 ==========\n#set($fieldDict=[])\n#foreach($field in $queryList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n#if($fieldDict && $fieldDict.size() > 0)\n// 加载字典数据\nconst { $dict.format($fieldDict) } = useDict($dict.quotation($fieldDict));\n#end\n\n// ========== 组件引用 ==========\nconst formDialogRef = ref(); // 表单弹窗引用\nconst queryRef = ref(); // 查询表单引用\nconst tableRef = ref(); // 表格引用\n\n// ========== 响应式数据 ==========\nconst showSearch = ref(true); // 是否显示搜索区域\nconst selectObjs = ref([]) as any; // 表格多选数据\nconst multiple = ref(true); // 是否多选\nconst isExpand = ref(true); // 是否展开状态,默认展开\n\n// ========== 表格状态 ==========\nconst state: BasicTableProps = reactive<BasicTableProps>({\n isPage: false, // 是否分页\n queryForm: {}, // 查询参数\n pageList: fetchTreeList, // 树形数据查询方法(不分页)\n loading: false, // 加载状态\n dataList: [] // 数据列表\n});\n\n// ========== Hook引用 ==========\n// 表格相关Hook (树形表格不使用分页)\nconst {\n getDataList,\n tableStyle\n} = useTable(state);\n\n// ========== 方法定义 ==========\n/**\n * 重置查询条件\n */\nconst resetQuery = () => {\n // 清空搜索条件\n queryRef.value?.resetFields();\n // 清空多选\n selectObjs.value = [];\n // 重新查询\n getDataList();\n};\n\n/**\n * 表格多选事件处理\n * @param objs 选中的数据行\n */\nconst selectionChangHandle = (objs: { ${pk.attrName}: string }[]) => {\n selectObjs.value = objs.map(({ ${pk.attrName} }) => ${pk.attrName});\n multiple.value = !objs.length;\n};\n\n/**\n * 树形表格展开状态变化事件\n * 当用户手动点击展开/折叠按钮时触发\n * @param row 当前行数据\n * @param expanded 是否展开\n */\nconst onExpandChange = (row: any, expanded: boolean) => {\n // 可以在这里添加额外的逻辑,比如记录展开状态等\n // console.log(\'Row expand changed:\', row, expanded);\n};\n\n/**\n * 删除数据处理\n * @param ids 要删除的数据ID数组\n */\nconst handleDelete = async (ids: string[]) => {\n try {\n await useMessageBox().confirm(\'此操作将永久删除选中数据及其子数据,是否继续?\');\n } catch {\n return;\n }\n\n try {\n await delObjs(ids);\n getDataList();\n useMessage().success(\'删除成功\');\n } catch (err: any) {\n useMessage().error(err.msg);\n }\n};\n\n/**\n * 展开/折叠树形表格\n * 基于Element Plus官方文档的toggleRowExpansion方法实现\n */\nconst handleExpand = () => {\n isExpand.value = !isExpand.value;\n \n // 等待DOM更新后再进行展开/折叠操作\n nextTick(() => {\n if (state.dataList && state.dataList.length > 0 && tableRef.value) {\n toggleExpand(state.dataList, isExpand.value);\n }\n });\n};\n\n/**\n * 递归展开/折叠所有节点\n * 使用Element Plus Table组件的toggleRowExpansion方法\n * @param children 子节点数组\n * @param unfold 是否展开\n */\nconst toggleExpand = (children: any[], unfold = true) => {\n for (const item of children) {\n // 使用Element Plus官方的toggleRowExpansion方法\n // 第二个参数为可选的布尔值,直接设置展开状态\n tableRef.value?.toggleRowExpansion(item, unfold);\n \n // 递归处理子节点\n if (item.children && item.children.length > 0) {\n toggleExpand(item.children, unfold);\n }\n }\n};\n\n// ========== 生命周期 ==========\n// 组件挂载时获取数据\nonMounted(() => {\n getDataList();\n});\n</script>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (32,'树形表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','树形表单V2026001','<template>\n <el-dialog :title=\"form.${pk.attrName} ? \'编辑\' : \'新增\'\" v-model=\"visible\"\n :close-on-click-modal=\"false\" draggable>\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" formDialogRef label-width=\"90px\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n <!-- 父级节点选择 -->\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n <el-form-item label=\"父级节点\" prop=\"${parentField}\">\n <el-tree-select\n v-model=\"form.${parentField}\"\n :data=\"parentNodes\"\n :props=\"treeSelectProps\"\n check-strictly\n :render-after-expand=\"false\"\n placeholder=\"请选择父级节点\"\n style=\"width: 100%\"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${parentField})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetime\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"daterange\" range-separator=\"至\" start-placeholder=\"开始日期\" end-placeholder=\"结束日期\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetimerange\" range-separator=\"至\" start-placeholder=\"开始时间\" end-placeholder=\"结束时间\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'number\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input-number :min=\"1\" :max=\"1000\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"></el-input-number>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'upload-file\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <upload-file v-model=\"form.${field.attrName}\"></upload-file>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'upload-img\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <upload-img v-model:imageUrl=\"form.${field.attrName}\"></upload-img>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'editor\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <editor v-if=\"visible\" v-model:get-html=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"></editor>\n </el-form-item>\n </el-col>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#end\n#end\n#end\n </el-row>\n </el-form>\n <template #footer>\n <span class=\"dialog-footer\">\n <el-button @click=\"visible = false\">取 消</el-button>\n <el-button type=\"primary\" @click=\"onSubmit\" :disabled=\"loading\">确 认</el-button>\n </span>\n </template>\n </el-dialog>\n</template>\n\n<script setup lang=\"ts\" name=\"${ClassName}TreeDialog\">\n// ========== 导入语句 ==========\nimport { useMessage } from \"/@/hooks/message\";\nimport { getObj, addObj, putObj, fetchTreeList } from \'/@/api/${moduleName}/${functionName}\';\n#if($fieldDict && $fieldDict.size() > 0)\nimport { useDict } from \'/@/hooks/dict\';\n#end\n#foreach($field in $formList)\n#if($field.formValidator && $field.formValidator != \'duplicate\')\nimport { rule } from \'/@/utils/validate\';\n#break\n#end\n#end\n\n// ========== 类型定义 ==========\ninterface TreeNode {\n ${pk.attrName}: string | number | null;\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${parentField})\n#set($treeNameField = $field)\n#break\n#end\n#end\n#if($treeNameField)\n ${treeNameField.attrName}: string;\n#end\n children?: TreeNode[];\n}\n\ninterface FormData {\n#if(!$formList.contains(${pk.attrName}))\n ${pk.attrName}?: string;\n#end\n ${parentField}?: string | number | null;\n#foreach($field in $formList)\n#if($field.attrName != ${parentField})\n#if($field.formType == \'number\')\n ${field.attrName}: number;\n#elseif($field.formType == \'checkbox\')\n ${field.attrName}: any[];\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n ${field.attrName}: any[];\n#else\n ${field.attrName}: string;\n#end\n#end\n#end\n}\n\n// ========== 组件定义 ==========\nconst emit = defineEmits([\'refresh\']);\n\n// ========== 响应式数据定义 ==========\nconst dataFormRef = ref(); // 表单引用\nconst visible = ref(false); // 弹窗显示状态\nconst loading = ref(false); // 加载状态\nconst parentNodes = ref<TreeNode[]>([]); // 父级节点数据\n\n// 树形选择器配置\nconst treeSelectProps = {\n children: \'children\',\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${parentField})\n label: \'${field.attrName}\',\n#break\n#end\n#end\n value: \'${pk.attrName}\',\n checkStrictly: true\n};\n\n// 表单数据对象\nconst form = reactive<FormData>({\n#if(!$formList.contains(${pk.attrName}))\n ${pk.attrName}: \'\', // 主键\n#end\n ${parentField}: null, // 父级ID\n#foreach($field in $formList)\n#if($field.attrName != ${parentField})\n#if($field.formType == \'number\')\n ${field.attrName}: 0, // ${field.fieldComment}\n#elseif($field.formType == \'checkbox\' || $field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n ${field.attrName}: [], // ${field.fieldComment}\n#else\n ${field.attrName}: \'\', // ${field.fieldComment}\n#end\n#end\n#end\n});\n\n// ========== 字典数据处理 ==========\n#set($fieldDict=[])\n#foreach($field in $formList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n#if($fieldDict && $fieldDict.size() > 0)\n// 加载字典数据\nconst { $dict.format($fieldDict) } = useDict($dict.quotation($fieldDict));\n#end\n\n// ========== 表单校验规则 ==========\nconst dataRules = ref({\n ${parentField}: [\n { \n required: true, \n validator: (rule: any, value: any, callback: any) => {\n if (value === null || value === undefined || value === \'\') {\n callback(new Error(\'请选择父级节点\'));\n } else {\n callback();\n }\n },\n trigger: \'change\' \n }\n ],\n#foreach($field in $formList)\n#if($field.formRequired == \'1\' && $field.formValidator == \'duplicate\')\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' },\n {\n validator: (rule: any, value: any, callback: any) => {\n // 重复性校验(编辑时跳过)\n validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n },\n trigger: \'blur\',\n }\n ],\n#elseif($field.formRequired == \'1\' && $field.formValidator)\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' },\n { validator: rule.${field.formValidator}, trigger: \'blur\' }\n ],\n#elseif($field.formRequired == \'1\')\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' }\n ],\n#elseif($field.formValidator)\n ${field.attrName}: [\n { validator: rule.${field.formValidator}, trigger: \'blur\' }\n ],\n#end\n#end\n});\n\n// ========== 方法定义 ==========\n/**\n * 获取详情数据\n */\nconst get${ClassName}Data = async (id: string) => {\n try {\n loading.value = true;\n const { data } = await getObj({ ${pk.attrName}: id });\n if (data && data.length > 0) {\n Object.assign(form, data[0]);\n }\n } catch (error) {\n useMessage().error(\'获取数据失败\');\n } finally {\n loading.value = false;\n }\n};\n\n\n/**\n * 打开弹窗方法\n * @param id 编辑时的数据ID\n * @param parentId 新增时的父级ID\n */\nconst openDialog = async (id?: string, parentId?: string | number) => {\n visible.value = true;\n form.${pk.attrName} = \'\';\n form.${parentField} = parentId || \'0\';\n\n // 初始化父级节点数据\n const { data } = await fetchTreeList();\n parentNodes.value = [{ ${pk.attrName}: \'0\', ${treeNameField.attrName}: \'根节点\', children: data }];\n\n // 重置表单验证\n nextTick(() => {\n dataFormRef.value?.resetFields();\n });\n\n if (id) {\n form.${pk.attrName} = id;\n await get${ClassName}Data(id);\n }\n};\n\n/**\n * 提交表单方法\n */\nconst onSubmit = async () => {\n // 防止重复提交\n if (loading.value) return;\n loading.value = true;\n \n try {\n const valid = await dataFormRef.value.validate().catch(() => {});\n if (!valid) {\n loading.value = false;\n return false;\n }\n\n // 处理父级ID,如果选择根节点(null)则设为null,其他情况保持原值\n if (form.${pk.attrName}) {\n await putObj(form);\n useMessage().success(\'修改成功\');\n } else {\n await addObj(form);\n useMessage().success(\'添加成功\');\n }\n \n visible.value = false;\n emit(\'refresh\'); // 通知父组件刷新列表\n } catch (err: any) {\n useMessage().error(err.msg || \'操作失败\');\n } finally {\n loading.value = false;\n }\n};\n\n// ========== 对外暴露 ==========\ndefineExpose({\n openDialog\n});\n</script> \n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (33,'ControllerV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java','ControllerV2026001','package ${package}.${moduleName}.controller;\n\nimport cn.hutool.core.util.StrUtil;\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport ${package}.common.core.util.R;\nimport ${package}.common.log.annotation.SysLog;\n#if($opensource)\nimport com.pig4cloud.plugin.excel.annotation.ResponseExcel;\nimport com.pig4cloud.plugin.excel.annotation.RequestExcel;\n#else\nimport ${package}.common.excel.annotation.ResponseExcel;\nimport ${package}.common.excel.annotation.RequestExcel;\n#end\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\nimport ${package}.${moduleName}.service.${ClassName}Service;\n\nimport io.swagger.v3.oas.annotations.security.SecurityRequirement;\n#if($isSpringBoot3)\nimport ${package}.common.security.annotation.HasPermission;\nimport org.springdoc.core.annotations.ParameterObject;\n#else\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springdoc.api.annotations.ParameterObject;\n#end\nimport org.springframework.http.HttpHeaders;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.annotations.Operation;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.validation.BindingResult;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\nimport java.util.Objects;\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($childFieldGetter = $str.getProperty($childField))\n@RestController\n@RequiredArgsConstructor\n@RequestMapping(\"/${functionName}\" )\n@Tag(description = \"${functionName}\" , name = \"${tableComment}管理\" )\n@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)\npublic class ${ClassName}Controller {\n\n private final ${ClassName}Service ${className}Service;\n\n /**\n * 分页查询\n * @param page 分页对象\n * @param ${className} ${tableComment}\n * @return\n */\n @Operation(summary = \"分页查询\" , description = \"分页查询\" )\n @GetMapping(\"/page\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R get${ClassName}Page(@ParameterObject Page page, @ParameterObject ${ClassName}Entity ${className}) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n#foreach ($field in $queryList)\n#set($getAttrName=$str.getProperty($field.attrName))\n#set($var=\"${className}.$getAttrName()\")\n#if($field.attrType == \'String\')\n#set($expression=\"StrUtil.isNotBlank\")\n#else\n#set($expression=\"Objects.nonNull\")\n#end\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n if (ArrayUtil.isNotEmpty(${className}.${getAttrName}Range())) {\n wrapper.between(${ClassName}Entity::$getAttrName, ${className}.${getAttrName}Range()[0], ${className}.${getAttrName}Range()[1]);\n }\n#elseif($field.queryType == \'=\')\n wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'like\' )\n wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'!-\' )\n wrapper.ne($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>\' )\n wrapper.gt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<\' )\n wrapper.lt($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'>=\' )\n wrapper.ge($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'<=\' )\n wrapper.le($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'left like\' )\n wrapper.likeLeft($expression($var),${ClassName}Entity::$getAttrName,$var);\n#elseif( $field.queryType == \'right like\' )\n wrapper.likeRight($expression($var),${ClassName}Entity::$getAttrName,$var);\n#end\n#end\n#if($childField)\n if (Objects.nonNull(${className}.$childFieldGetter())) {\n wrapper.eq(${ClassName}Entity::$str.getProperty($childField), ${className}.$childFieldGetter());\n }\n#end\n return R.ok(${className}Service.page(page, wrapper));\n }\n\n\n /**\n * 通过条件查询${tableComment}\n * @param ${className} 查询条件\n * @return R 对象列表\n */\n @Operation(summary = \"通过条件查询\" , description = \"通过条件查询对象\" )\n @GetMapping(\"/details\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R getDetails(@ParameterObject ${ClassName}Entity ${className}) {\n return R.ok(${className}Service.list(Wrappers.query(${className})));\n }\n\n /**\n * 新增${tableComment}\n * @param ${className} ${tableComment}\n * @return R\n */\n @Operation(summary = \"新增${tableComment}\" , description = \"新增${tableComment}\" )\n @SysLog(\"新增${tableComment}\" )\n @PostMapping\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\')\" )\n #end\n public R save(@RequestBody ${ClassName}Entity ${className}) {\n return R.ok(${className}Service.save(${className}));\n }\n\n /**\n * 修改${tableComment}\n * @param ${className} ${tableComment}\n * @return R\n */\n @Operation(summary = \"修改${tableComment}\" , description = \"修改${tableComment}\" )\n @SysLog(\"修改${tableComment}\" )\n @PutMapping\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\')\" )\n #end\n public R updateById(@RequestBody ${ClassName}Entity ${className}) {\n return R.ok(${className}Service.updateById(${className}));\n }\n\n /**\n * 通过id删除${tableComment}\n * @param ids ${pk.attrName}列表\n * @return R\n */\n @Operation(summary = \"通过id删除${tableComment}\" , description = \"通过id删除${tableComment}\" )\n @SysLog(\"通过id删除${tableComment}\" )\n @DeleteMapping\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\')\" )\n #end\n public R removeById(@RequestBody ${pk.attrType}[] ids) {\n return R.ok(${className}Service.removeBatchByIds(CollUtil.toList(ids)));\n }\n\n /**\n * 导出excel 表格\n * @param ${className} 查询条件\n * @param ids 导出指定ID\n * @return excel 文件流\n */\n @ResponseExcel\n @GetMapping(\"/export\")\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\')\" )\n #end\n public List<${ClassName}Entity> exportExcel(${ClassName}Entity ${className},${pk.attrType}[] ids) {\n return ${className}Service.list(Wrappers.lambdaQuery(${className}).in(ArrayUtil.isNotEmpty(ids), ${ClassName}Entity::$str.getProperty($pk.attrName), ids));\n }\n\n /**\n * 导入excel 表\n * @param ${className}List 对象实体列表\n * @param bindingResult 错误信息列表\n * @return ok fail\n */\n @PostMapping(\"/import\")\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\')\" )\n #end\n public R importExcel(@RequestExcel List<${ClassName}Entity> ${className}List, BindingResult bindingResult) {\n return R.ok(${className}Service.saveBatch(${className}List));\n }\n\n /**\n * 获取树形列表\n * @param ${childClassName} 树节点查询条件\n * @return 树形数据\n */\n @Operation(summary = \"获取树形列表\" , description = \"获取树形列表\" )\n @GetMapping(\"/tree\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R getTree(@ParameterObject ${ChildClassName}Entity ${childClassName}) {\n return R.ok(${className}Service.buildTree(Wrappers.lambdaQuery(${childClassName})));\n }\n\n /**\n * 通过条件查询树节点\n * @param ${childClassName} 树节点查询条件\n * @return 树节点列表\n */\n @Operation(summary = \"通过条件查询树节点\" , description = \"通过条件查询树节点\" )\n @GetMapping(\"/tree/details\" )\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\')\" )\n #end\n public R getTreeDetails(@ParameterObject ${ChildClassName}Entity ${childClassName}) {\n return R.ok(${className}Service.getTreeDetails(${childClassName}));\n }\n\n /**\n * 新增树节点\n * @param ${childClassName} 树节点\n * @return R\n */\n @Operation(summary = \"新增树节点\" , description = \"新增树节点\" )\n @SysLog(\"新增树节点\" )\n @PostMapping(\"/tree\")\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\')\" )\n #end\n public R saveTree(@RequestBody ${ChildClassName}Entity ${childClassName}) {\n return R.ok(${className}Service.saveTree(${childClassName}));\n }\n\n /**\n * 修改树节点\n * @param ${childClassName} 树节点\n * @return R\n */\n @Operation(summary = \"修改树节点\" , description = \"修改树节点\" )\n @SysLog(\"修改树节点\" )\n @PutMapping(\"/tree\")\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\')\" )\n #end\n public R updateTree(@RequestBody ${ChildClassName}Entity ${childClassName}) {\n return R.ok(${className}Service.updateTree(${childClassName}));\n }\n\n /**\n * 通过id删除树节点\n * @param ids 树节点ID列表\n * @return R\n */\n @Operation(summary = \"通过id删除树节点\" , description = \"通过id删除树节点\" )\n @SysLog(\"通过id删除树节点\" )\n @DeleteMapping(\"/tree\")\n #if($isSpringBoot3)\n @HasPermission(\"$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\")\n #else\n @PreAuthorize(\"@pms.hasPermission(\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\')\" )\n #end\n public R removeTree(@RequestBody ${childPkField.attrType}[] ids) {\n return R.ok(${className}Service.removeTreeByIds(ids));\n }\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (34,'ServiceV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java','ServiceV2026001','package ${package}.${moduleName}.service;\n\nimport cn.hutool.core.lang.tree.Tree;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.extension.service.IService;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\n\nimport java.util.List;\n\n/**\n * ${tableComment} Service接口\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\npublic interface ${ClassName}Service extends IService<${ClassName}Entity> {\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n List<Tree<${childPkField.attrType}>> buildTree(LambdaQueryWrapper<${ChildClassName}Entity> wrapper);\n\n /**\n * 获取树节点详情\n * @param ${childClassName} 树节点查询对象\n * @return 树节点详情列表\n */\n List<${ChildClassName}Entity> getTreeDetails(${ChildClassName}Entity ${childClassName});\n\n /**\n * 保存树节点\n * @param ${childClassName} 树节点对象\n * @return 保存结果\n */\n Boolean saveTree(${ChildClassName}Entity ${childClassName});\n\n /**\n * 更新树节点\n * @param ${childClassName} 树节点对象\n * @return 更新结果\n */\n Boolean updateTree(${ChildClassName}Entity ${childClassName});\n\n /**\n * 批量删除树节点\n * @param ids 树节点ID列表\n * @return 删除结果\n */\n Boolean removeTreeByIds(${childPkField.attrType}[] ids);\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (35,'ServiceImplV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java','ServiceImplV2026001','package ${package}.${moduleName}.service.impl;\n\nimport cn.hutool.core.collection.CollUtil;\nimport cn.hutool.core.util.ArrayUtil;\nimport cn.hutool.core.lang.tree.Tree;\nimport cn.hutool.core.lang.tree.TreeNode;\nimport cn.hutool.core.lang.tree.TreeUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport ${entityClassName};\nimport ${package}.${moduleName}.mapper.${ChildClassName}Mapper;\nimport ${package}.${moduleName}.mapper.${ClassName}Mapper;\nimport ${package}.${moduleName}.service.${ClassName}Service;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\nimport java.util.function.Function;\n\n/**\n * ${tableComment} Service实现类\n *\n * @author ${author}\n * @date ${datetime}\n */\n#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#set($childPkGetter = $str.getProperty($childPkField.attrName))\n#break\n#end\n#end\n#set($parentGetter = $str.getProperty($parentField))\n#set($childFieldGetter = $str.getProperty($childField))\n#if($childPkField.attrType == \'Long\')\n#set($treeRootId = \'0L\')\n#elseif($childPkField.attrType == \'String\')\n#set($treeRootId = \'\"0\"\')\n#else\n#set($treeRootId = \'0\')\n#end\n@Service\n@RequiredArgsConstructor\npublic class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> implements ${ClassName}Service {\n\n private final ${ChildClassName}Mapper ${childClassName}Mapper;\n\n /**\n * 构建树形结构数据\n * @param wrapper 查询条件\n * @return 树形结构数据\n */\n @Override\n public List<Tree<${childPkField.attrType}>> buildTree(LambdaQueryWrapper<${ChildClassName}Entity> wrapper) {\n List<${ChildClassName}Entity> allList = ${childClassName}Mapper.selectList(wrapper);\n\n if (CollUtil.isEmpty(allList)) {\n return new ArrayList<>();\n }\n\n List<TreeNode<${childPkField.attrType}>> collect = allList.stream().map(getNodeFunction()).toList();\n return TreeUtil.build(collect, ${treeRootId});\n }\n\n /**\n * 获取树节点详情\n * @param ${childClassName} 树节点查询对象\n * @return 树节点详情列表\n */\n @Override\n public List<${ChildClassName}Entity> getTreeDetails(${ChildClassName}Entity ${childClassName}) {\n return ${childClassName}Mapper.selectList(Wrappers.query(${childClassName}));\n }\n\n /**\n * 保存树节点\n * @param ${childClassName} 树节点对象\n * @return 保存结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean saveTree(${ChildClassName}Entity ${childClassName}) {\n ${childClassName}.$str.setProperty($parentField)(validateParentRelation(null, ${childClassName}.$str.getProperty($parentField)()));\n return ${childClassName}Mapper.insert(${childClassName}) > 0;\n }\n\n /**\n * 更新树节点\n * @param ${childClassName} 树节点对象\n * @return 更新结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean updateTree(${ChildClassName}Entity ${childClassName}) {\n ${childClassName}.$str.setProperty($parentField)(validateParentRelation(${childClassName}.$str.getProperty($childPkField.attrName)(), ${childClassName}.$str.getProperty($parentField)()));\n return ${childClassName}Mapper.updateById(${childClassName}) > 0;\n }\n\n /**\n * 批量删除树节点\n * @param ids 树节点ID列表\n * @return 删除结果\n */\n @Override\n @Transactional(rollbackFor = Exception.class)\n public Boolean removeTreeByIds(${childPkField.attrType}[] ids) {\n if (ArrayUtil.isEmpty(ids)) {\n return Boolean.TRUE;\n }\n\n for (${childPkField.attrType} id : ids) {\n if (hasChildNodes(id)) {\n throw new RuntimeException(\"当前节点存在子节点,不能删除\");\n }\n if (hasMainRecords(id)) {\n throw new RuntimeException(\"当前节点已关联主表数据,不能删除\");\n }\n }\n\n return ${childClassName}Mapper.deleteBatchIds(CollUtil.toList(ids)) > 0;\n }\n\n /**\n * 获取TreeNode转换函数\n * @return TreeNode转换函数\n */\n private Function<${ChildClassName}Entity, TreeNode<${childPkField.attrType}>> getNodeFunction() {\n return entity -> {\n TreeNode<${childPkField.attrType}> node = new TreeNode<>();\n node.setId(entity.$childPkGetter());\n node.setName(entity.$str.getProperty($nameField)());\n node.setParentId(normalizeParentId(entity.$parentGetter()));\n\n Map<String, Object> extra = new HashMap<>();\n#foreach($field in $childFieldList)\n extra.put(\"${field.attrName}\", entity.$str.getProperty($field.attrName)());\n#end\n node.setExtra(extra);\n return node;\n };\n }\n\n /**\n * 规范化父节点ID,并校验父子关系\n * @param currentId 当前节点ID\n * @param parentId 父节点ID\n * @return 规范化后的父节点ID\n */\n private ${childPkField.attrType} validateParentRelation(${childPkField.attrType} currentId, ${childPkField.attrType} parentId) {\n ${childPkField.attrType} normalizedParentId = normalizeParentId(parentId);\n\n if (Objects.nonNull(currentId) && Objects.equals(currentId, normalizedParentId)) {\n throw new RuntimeException(\"不能选择当前节点作为父节点\");\n }\n\n if (Objects.nonNull(currentId) && isDescendant(currentId, normalizedParentId)) {\n throw new RuntimeException(\"不能选择当前节点的后代节点作为父节点\");\n }\n\n return normalizedParentId;\n }\n\n /**\n * 判断候选父节点是否是当前节点的后代节点\n * @param currentId 当前节点ID\n * @param candidateParentId 候选父节点ID\n * @return 是否为后代节点\n */\n private boolean isDescendant(${childPkField.attrType} currentId, ${childPkField.attrType} candidateParentId) {\n if (Objects.isNull(currentId) || Objects.isNull(candidateParentId) || Objects.equals(candidateParentId, ${treeRootId})) {\n return false;\n }\n\n Set<${childPkField.attrType}> visited = new HashSet<>();\n ${ChildClassName}Entity parent = ${childClassName}Mapper.selectById(candidateParentId);\n\n while (Objects.nonNull(parent) && visited.add(parent.$childPkGetter())) {\n if (Objects.equals(currentId, parent.$childPkGetter())) {\n return true;\n }\n\n ${childPkField.attrType} nextParentId = parent.$parentGetter();\n if (Objects.isNull(nextParentId) || Objects.equals(nextParentId, ${treeRootId})) {\n return false;\n }\n parent = ${childClassName}Mapper.selectById(nextParentId);\n }\n\n return false;\n }\n\n /**\n * 判断是否存在子节点\n * @param parentId 父节点ID\n * @return 是否存在子节点\n */\n private boolean hasChildNodes(${childPkField.attrType} parentId) {\n LambdaQueryWrapper<${ChildClassName}Entity> wrapper = Wrappers.lambdaQuery();\n wrapper.eq(${ChildClassName}Entity::$parentGetter, parentId);\n return ${childClassName}Mapper.selectCount(wrapper) > 0;\n }\n\n /**\n * 判断是否存在关联主表数据\n * @param treeId 树节点ID\n * @return 是否存在主表数据\n */\n private boolean hasMainRecords(${childPkField.attrType} treeId) {\n LambdaQueryWrapper<${ClassName}Entity> wrapper = Wrappers.lambdaQuery();\n wrapper.eq(${ClassName}Entity::$childFieldGetter, treeId);\n return baseMapper.selectCount(wrapper) > 0;\n }\n\n /**\n * 规范化父节点ID\n * @param parentId 父节点ID\n * @return 规范化后的父节点ID\n */\n private ${childPkField.attrType} normalizeParentId(${childPkField.attrType} parentId) {\n return Objects.nonNull(parentId) ? parentId : ${treeRootId};\n }\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (36,'实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ClassName}Entity.java','实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#if($isTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isTenant)\n@TenantTable\n#end\n@TableName(\"${tableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${tableComment}\")\npublic class ${ClassName}Entity extends Model<${ClassName}Entity> {\n\n#foreach ($field in $fieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#elseif($field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n private String[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end\n#end\n#foreach ($field in $queryList)\n#if($field.queryFormType == \'daterange\' || $field.queryFormType == \'datetimerange\')\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n\n /**\n * $comment 查询范围\n */\n @TableField(exist = false)\n @Schema(description=\"$comment 查询范围\",hidden=true)\n private String[] ${field.attrName}Range;\n#end\n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (37,'MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java','MapperV2026001','package ${package}.${moduleName}.mapper;\n\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport ${entityClassName};\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (38,'Mapper.xmlV2026001','${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml','Mapper.xmlV2026001','<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n\n<mapper namespace=\"${package}.${moduleName}.mapper.${ClassName}Mapper\">\n\n <resultMap id=\"${className}Map\" type=\"${entityClassName}\">\n#foreach ($field in $fieldList)\n #if($field.primaryPk == \'1\')\n <id property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #else\n <result property=\"$field.attrName\" column=\"$field.fieldName\"/>\n #end\n#end\n </resultMap>\n</mapper>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (39,'子实体V2026001','${entityPath}/src/main/java/${entityPackagePath}/${ChildClassName}Entity.java','子实体V2026001','package ${entityPackage};\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport io.swagger.v3.oas.annotations.media.Schema;\n#if($isChildTenant)\nimport ${package}.common.core.util.TenantTable;\n#end\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#foreach($import in $importList)\nimport $import;\n#end\n\n/**\n * ${tableComment}\n *\n * @author ${author}\n * @date ${datetime}\n */\n@Data\n#if($isChildTenant)\n@TenantTable\n#end\n@TableName(\"${childTableName}\")\n@EqualsAndHashCode(callSuper = true)\n@Schema(description = \"${childTableName}\")\npublic class ${ChildClassName}Entity extends Model<${ChildClassName}Entity> {\n\n#foreach ($field in $childFieldList)\n#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end\n /**\n * $comment\n */\n#if($field.primaryPk == \'1\')\n @TableId(type = IdType.ASSIGN_ID)\n#end\n#if($field.autoFill == \'INSERT\')\n @TableField(fill = FieldFill.INSERT)\n#elseif($field.autoFill == \'INSERT_UPDATE\')\n @TableField(fill = FieldFill.INSERT_UPDATE)\n#elseif($field.autoFill == \'UPDATE\')\n @TableField(fill = FieldFill.UPDATE)\n#end\n#if($field.fieldName == \'del_flag\')\n @TableLogic\n @TableField(fill = FieldFill.INSERT)\n#end\n @Schema(description=\"$comment\"#if($field.hidden),hidden=$field.hidden#end)\n#if($field.formType == \'checkbox\')\n private ${field.attrType}[] $field.attrName;\n#else\n private $field.attrType $field.attrName;\n#end \n#end\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (40,'子MapperV2026001','${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ChildClassName}Mapper.java','子MapperV2026001','package ${package}.${moduleName}.mapper;\n\nimport ${package}.common.data.datascope.PigxBaseMapper;\nimport ${entityPackage}.${ChildClassName}Entity;\nimport org.apache.ibatis.annotations.Mapper;\n\n@Mapper\npublic interface ${ChildClassName}Mapper extends PigxBaseMapper<${ChildClassName}Entity> {\n\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (41,'权限菜单V2026001','${backendPath}/menu/${functionName}_menu.sql','权限菜单V2026001','-- 该脚本不要直接执行, 注意维护菜单的父节点ID 默认 父节点-1 , #if(!$opensource)默认租户 1#end\n#set($menuId=${dateTool.getSystemTime()})\n\n-- 菜单SQL\ninsert into sys_menu ( menu_id,parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${menuId}, \'-1\', \'/${moduleName}/${functionName}/index\', \'\', \'0\', \'icon-bangzhushouji\', \'0\', null , \'8\', null , \'${tableComment}管理\'#if(!$opensource), 1#end);\n\n-- 菜单对应按钮SQL\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,1)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_view\', \'1\', null, \'1\', \'0\', null, \'0\', null, \'${tableComment}查看\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,2)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\', \'1\', null, \'1\', \'0\', null, \'1\', null, \'${tableComment}新增\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,3)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\', \'1\', null, \'1\', \'0\', null, \'2\', null, \'${tableComment}修改\'#if(!$opensource), 1#end);\n\ninsert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,4)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'${tableComment}删除\'#if(!$opensource), 1#end);\n\ninsert into sys_menu ( menu_id,parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name#if(!$opensource), tenant_id#end)\nvalues (${math.add($menuId,5)},${menuId}, \'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\', \'1\', null, \'1\', \'0\', null, \'3\', null, \'导入导出\'#if(!$opensource), 1#end);\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (42,'api.tsV2026001','${frontendPath}/src/api/${moduleName}/${functionName}.ts','api.tsV2026001','import request from \"/@/utils/request\"\n\n// ========== 基础CRUD接口 ==========\n\n/**\n * 分页查询列表数据\n * @param query - 查询参数对象\n * @returns Promise<分页数据>\n */\nexport function fetchList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/page\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 新增数据\n * @param obj - 要新增的数据对象\n * @returns Promise<boolean> - 操作结果\n */\nexport function addObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 获取详情数据\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<数据详情>\n */\nexport function getObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 批量删除数据\n * @param ids - 要删除的ID数组\n * @returns Promise<操作结果>\n */\nexport function delObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'delete\',\n data: ids\n })\n}\n\n/**\n * 更新数据\n * @param obj - 要更新的数据对象\n * @returns Promise<操作结果>\n */\nexport function putObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}\',\n method: \'put\',\n data: obj\n })\n}\n\n// ========== 树形CRUD接口 ==========\n\n/**\n * 获取树形列表数据\n * @param query - 查询参数对象\n * @returns Promise<树形数据>\n */\nexport function fetchTreeList(query?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'get\',\n params: query\n })\n}\n\n/**\n * 获取树节点详情\n * @param obj - 查询参数对象(包含ID等)\n * @returns Promise<树节点详情>\n */\nexport function getTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree/details\',\n method: \'get\',\n params: obj\n })\n}\n\n/**\n * 新增树节点\n * @param obj - 要新增的树节点对象\n * @returns Promise<操作结果>\n */\nexport function addTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'post\',\n data: obj\n })\n}\n\n/**\n * 更新树节点\n * @param obj - 要更新的树节点对象\n * @returns Promise<操作结果>\n */\nexport function putTreeObj(obj?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'put\',\n data: obj\n })\n}\n\n/**\n * 删除树节点\n * @param ids - 要删除的树节点ID数组\n * @returns Promise<操作结果>\n */\nexport function delTreeObjs(ids?: Object) {\n return request({\n url: \'/${moduleName}/${functionName}/tree\',\n method: \'delete\',\n data: ids\n })\n}\n\n// ========== 工具函数 ==========\n\n/**\n * 验证字段值唯一性\n * @param rule - 验证规则对象\n * @param value - 要验证的值\n * @param callback - 验证回调函数\n * @param isEdit - 是否为编辑模式\n *\n * @example\n * // 在表单验证规则中使用\n * fieldName: [\n * {\n * validator: (rule, value, callback) => {\n * validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n * },\n * trigger: \'blur\',\n * },\n * ]\n */\nexport function validateExist(rule: any, value: any, callback: any, isEdit: boolean) {\n // 编辑模式下跳过验证\n if (isEdit) {\n return callback();\n }\n\n // 查询是否存在相同值\n getObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n}\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (43,'表格V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/index.vue','表格V2026001','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n<template>\n <div class=\"layout-padding\">\n <splitpanes>\n <pane size=\"15\">\n <div class=\"layout-padding-auto layout-padding-view\">\n <el-scrollbar>\n <div class=\"mb8\" style=\"display: flex; align-items: center; justify-content: space-between;\">\n <span style=\"font-weight: 500;\">左侧节点</span>\n <div>\n <el-tooltip :content=\"currentTreeId ? \'新增子节点\' : \'新增根节点\'\" placement=\"top\">\n <el-button link type=\"primary\" icon=\"FolderAdd\" @click=\"handleAddTree\" />\n </el-tooltip>\n </div>\n </div>\n <el-tree\n ref=\"treeRef\"\n :data=\"treeData\"\n :props=\"treeProps\"\n node-key=\"${childPkField.attrName}\"\n highlight-current\n default-expand-all\n :expand-on-click-node=\"false\"\n @node-click=\"handleTreeNodeClick\"\n >\n <template #default=\"{ node, data }\">\n <span style=\"flex: 1; display: flex; align-items: center; justify-content: space-between;\">\n <span>{{ node.label }}</span>\n <span v-if=\"currentTreeId === data.${childPkField.attrName}\" style=\"margin-left: 8px;\">\n <el-tooltip content=\"编辑\" placement=\"top\">\n <el-button link type=\"primary\" icon=\"Edit\" size=\"small\" @click.stop=\"handleEditTree\" />\n </el-tooltip>\n <el-tooltip content=\"删除\" placement=\"top\">\n <el-button link type=\"danger\" icon=\"Delete\" size=\"small\" @click.stop=\"handleDeleteTree\" />\n </el-tooltip>\n </span>\n </span>\n </template>\n </el-tree>\n </el-scrollbar>\n </div>\n </pane>\n <pane class=\"ml8\">\n <div class=\"layout-padding-auto layout-padding-view\">\n#if($queryList)\n <el-row v-show=\"showSearch\">\n <el-form :model=\"state.queryForm\" ref=\"queryRef\" :inline=\"true\" @keyup.enter=\"getDataList\">\n#foreach($field in $queryList)\n#if($field.attrName != ${childField})\n#if($field.queryFormType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"state.queryForm.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option \n :label=\"item.label\" \n :value=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n :key=\"index\"\n />\n#else\n <el-option label=\"请选择\" value=\"0\" />\n#end\n </el-select>\n </el-form-item>\n#elseif($field.queryFormType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"date\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"daterange\"\n range-separator=\"至\"\n start-placeholder=\"开始日期\"\n end-placeholder=\"结束日期\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker\n type=\"datetime\"\n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n v-model=\"state.queryForm.${field.attrName}\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.queryFormType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}Range\">\n <el-date-picker\n type=\"datetimerange\"\n range-separator=\"至\"\n start-placeholder=\"开始时间\"\n end-placeholder=\"结束时间\"\n v-model=\"state.queryForm.${field.attrName}Range\"\n :value-format=\"dateTimeStr\"\n />\n </el-form-item>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"state.queryForm.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio \n :label=\"item.value\" \n v-for=\"(item, index) in ${field.fieldDict}\" \n border \n :key=\"index\"\n >\n {{ item.label }}\n </el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>\n ${field.fieldComment}\n </el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input \n placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" \n v-model=\"state.queryForm.${field.attrName}\" \n />\n </el-form-item>\n#end\n#end\n#end\n <el-form-item>\n <el-button icon=\"search\" type=\"primary\" @click=\"getDataList\">\n 查询\n </el-button>\n <el-button icon=\"Refresh\" @click=\"resetQuery\">重置</el-button>\n </el-form-item>\n </el-form>\n </el-row>\n#end\n\n <el-row>\n <div class=\"mb8\" style=\"width: 100%\">\n <el-button \n icon=\"folder-add\" \n type=\"primary\" \n class=\"ml10\" \n @click=\"handleAddRow\"\n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\'\"\n >\n 新增\n </el-button>\n <el-button \n plain \n icon=\"upload-filled\" \n type=\"primary\" \n class=\"ml10\" \n @click=\"excelUploadRef.show()\" \n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add\'\"\n >\n 导入\n </el-button>\n <el-button \n plain \n :disabled=\"multiple\" \n icon=\"Delete\" \n type=\"primary\"\n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\'\" \n @click=\"handleDelete(selectObjs)\"\n >\n 删除\n </el-button>\n <right-toolbar \n v-model:showSearch=\"showSearch\" \n :export=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export\'\"\n @exportExcel=\"exportExcel\" \n class=\"ml10 mr20\" \n style=\"float: right;\"\n @queryTable=\"getDataList\"\n />\n </div>\n </el-row>\n\n <el-table \n :data=\"state.dataList\" \n v-loading=\"state.loading\" \n border \n :cell-style=\"tableStyle.cellStyle\" \n :header-cell-style=\"tableStyle.headerCellStyle\"\n @selection-change=\"selectionChangeHandle\"\n @sort-change=\"sortChangeHandle\"\n >\n <el-table-column type=\"selection\" width=\"40\" align=\"center\" />\n <el-table-column type=\"index\" label=\"#\" width=\"40\" />\n#foreach($field in $gridList)\n#if($field.fieldDict)\n <el-table-column prop=\"${field.attrName}\" label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" show-overflow-tooltip>\n <template #default=\"scope\">\n <dict-tag :options=\"${field.fieldDict}\" :value=\"scope.row.${field.attrName}\" />\n </template>\n </el-table-column>\n#elseif(${field.formType} == \'upload-img\')\n <el-table-column prop=\"${field.attrName}\" label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n <template #default=\"{ row }\">\n <upload-img disabled v-model:imageUrl=\"row.${field.attrName}\"></upload-img>\n </template>\n </el-table-column>\n#else\n <el-table-column\n prop=\"${field.attrName}\"\n label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"\n#if(${field.gridSort} == \'1\')\n sortable=\"custom\"\n#end\n show-overflow-tooltip\n />\n#end\n#end\n <el-table-column label=\"操作\" width=\"200\">\n <template #default=\"scope\">\n <el-button \n icon=\"edit-pen\" \n text \n type=\"primary\" \n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit\'\"\n @click=\"handleEditRow(scope.row)\"\n >\n 编辑\n </el-button>\n <el-button \n icon=\"delete\" \n text \n type=\"primary\" \n v-auth=\"\'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del\'\" \n @click=\"handleDelete([scope.row.${pk.attrName}])\"\n >\n 删除\n </el-button>\n </template>\n </el-table-column>\n </el-table>\n\n <pagination\n @size-change=\"sizeChangeHandle\"\n @current-change=\"currentChangeHandle\"\n v-bind=\"state.pagination\"\n />\n </div>\n </pane>\n </splitpanes>\n\n <tree-form ref=\"treeFormDialogRef\" @refresh=\"reloadTree\" />\n <form-dialog ref=\"formDialogRef\" @refresh=\"getDataList(false)\" />\n\n <upload-excel\n ref=\"excelUploadRef\"\n title=\"导入\"\n url=\"/${moduleName}/${functionName}/import\"\n temp-url=\"/admin/sys-file/local/file/${functionName}.xlsx\"\n @refreshDataList=\"getDataList\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\" name=\"system${ClassName}TreeTable\">\nimport { BasicTableProps, useTable } from \"/@/hooks/table\";\nimport { fetchList, delObjs, fetchTreeList, delTreeObjs } from \"/@/api/${moduleName}/${functionName}\";\nimport { useMessage, useMessageBox } from \"/@/hooks/message\";\nimport { useDict } from \'/@/hooks/dict\';\n\nconst FormDialog = defineAsyncComponent(() => import(\'./form.vue\'));\nconst TreeForm = defineAsyncComponent(() => import(\'./tree-form.vue\'));\n\n#set($fieldDict=[])\n#foreach($field in $queryList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n#foreach($field in $gridList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n#if($fieldDict && $fieldDict.size() > 0)\nconst { $dict.format($fieldDict) } = useDict($dict.quotation($fieldDict));\n#end\n\ninterface TreeNode {\n [key: string]: any;\n children?: TreeNode[];\n}\n\nconst formDialogRef = ref();\nconst treeFormDialogRef = ref();\nconst excelUploadRef = ref();\nconst queryRef = ref();\nconst treeRef = ref();\n\nconst showSearch = ref(true);\nconst selectObjs = ref([]) as any;\nconst multiple = ref(true);\nconst currentTreeId = ref<string | number | null>(null);\nconst treeData = ref<TreeNode[]>([]);\n\nconst treeProps = {\n children: \'children\',\n label: \'${nameField}\'\n};\n\nconst state: BasicTableProps = reactive<BasicTableProps>({\n queryForm: {},\n pageList: fetchList\n});\n\nconst {\n getDataList,\n currentChangeHandle,\n sizeChangeHandle,\n sortChangeHandle,\n downBlobFile,\n tableStyle\n} = useTable(state);\n\nconst reloadTree = async () => {\n const { data } = await fetchTreeList();\n treeData.value = data || [];\n nextTick(() => {\n treeRef.value?.setCurrentKey(currentTreeId.value);\n });\n};\n\nconst resetQuery = () => {\n queryRef.value?.resetFields();\n selectObjs.value = [];\n if (currentTreeId.value) {\n state.queryForm.${childField} = currentTreeId.value;\n } else {\n delete state.queryForm.${childField};\n }\n getDataList();\n};\n\nconst exportExcel = () => {\n downBlobFile(\n \'/${moduleName}/${functionName}/export\',\n { ...state.queryForm, ids: selectObjs.value },\n \'${functionName}.xlsx\'\n );\n};\n\nconst selectionChangeHandle = (objs: { ${pk.attrName}: string }[]) => {\n selectObjs.value = objs.map(({ ${pk.attrName} }) => ${pk.attrName});\n multiple.value = !objs.length;\n};\n\nconst handleDelete = async (ids: string[]) => {\n try {\n await useMessageBox().confirm(\'此操作将永久删除\');\n } catch {\n return;\n }\n\n try {\n await delObjs(ids);\n getDataList();\n useMessage().success(\'删除成功\');\n } catch (err: any) {\n useMessage().error(err.msg);\n }\n};\n\nconst handleTreeNodeClick = (data: TreeNode) => {\n currentTreeId.value = data.${childPkField.attrName};\n state.queryForm.${childField} = currentTreeId.value;\n treeRef.value?.setCurrentKey(currentTreeId.value);\n getDataList();\n};\n\nconst clearTreeSelection = () => {\n currentTreeId.value = null;\n treeRef.value?.setCurrentKey(null);\n delete state.queryForm.${childField};\n};\n\nconst handleAddTree = () => {\n treeFormDialogRef.value?.openDialog(undefined, currentTreeId.value ?? 0);\n};\n\nconst handleEditTree = () => {\n if (!currentTreeId.value) {\n useMessage().warning(\'请先选择一个左侧节点\');\n return;\n }\n treeFormDialogRef.value?.openDialog(currentTreeId.value);\n};\n\nconst handleDeleteTree = async () => {\n if (!currentTreeId.value) {\n useMessage().warning(\'请先选择一个左侧节点\');\n return;\n }\n\n try {\n await useMessageBox().confirm(\'此操作将永久删除左侧节点\');\n } catch {\n return;\n }\n\n try {\n await delTreeObjs([currentTreeId.value]);\n clearTreeSelection();\n await reloadTree();\n getDataList();\n useMessage().success(\'删除成功\');\n } catch (err: any) {\n useMessage().error(err.msg);\n }\n};\n\nconst handleAddRow = () => {\n formDialogRef.value?.openDialog(undefined, currentTreeId.value ?? undefined);\n};\n\nconst handleEditRow = (row: any) => {\n formDialogRef.value?.openDialog(row.${pk.attrName}, currentTreeId.value ?? undefined);\n};\n\nonMounted(async () => {\n await reloadTree();\n getDataList();\n});\n</script>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (44,'树表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/tree-form.vue','树表单V2026001','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($fieldDict=[])\n#foreach($field in $childFieldList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n<template>\n <el-dialog :title=\"form.${childPkField.attrName} ? \'编辑\' : \'新增\'\" v-model=\"visible\"\n :close-on-click-modal=\"false\" draggable>\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" label-width=\"90px\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n <el-form-item label=\"父级节点\" prop=\"${parentField}\">\n <el-tree-select\n v-model=\"form.${parentField}\"\n :data=\"parentNodes\"\n :props=\"treeSelectProps\"\n check-strictly\n :render-after-expand=\"false\"\n placeholder=\"请选择父级节点\"\n style=\"width: 100%\"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $childFieldList)\n#if($field.attrName != ${childPkField.attrName} && $field.attrName != ${parentField})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetime\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"daterange\" range-separator=\"至\" start-placeholder=\"开始日期\" end-placeholder=\"结束日期\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetimerange\" range-separator=\"至\" start-placeholder=\"开始时间\" end-placeholder=\"结束时间\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'number\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input-number :min=\"1\" :max=\"1000\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"></el-input-number>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'upload-file\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <upload-file v-model=\"form.${field.attrName}\"></upload-file>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'upload-img\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <upload-img v-model:imageUrl=\"form.${field.attrName}\"></upload-img>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'editor\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <editor v-if=\"visible\" v-model:get-html=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"></editor>\n </el-form-item>\n </el-col>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#end\n#end\n#end\n </el-row>\n </el-form>\n <template #footer>\n <span class=\"dialog-footer\">\n <el-button @click=\"visible = false\">取 消</el-button>\n <el-button type=\"primary\" @click=\"onSubmit\" :disabled=\"loading\">确 认</el-button>\n </span>\n </template>\n </el-dialog>\n</template>\n\n<script setup lang=\"ts\" name=\"${ChildClassName}TreeDialog\">\nimport { useMessage } from \"/@/hooks/message\";\nimport { addTreeObj, fetchTreeList, getTreeObj, putTreeObj } from \'/@/api/${moduleName}/${functionName}\';\n#if($fieldDict && $fieldDict.size() > 0)\nimport { useDict } from \'/@/hooks/dict\';\n#end\n#foreach($field in $childFieldList)\n#if($field.formValidator && $field.formValidator != \'duplicate\')\nimport { rule } from \'/@/utils/validate\';\n#break\n#end\n#end\n\ninterface TreeNode {\n [key: string]: any;\n children?: TreeNode[];\n}\n\ninterface FormData {\n ${childPkField.attrName}?: string | number;\n ${parentField}?: string | number | null;\n#foreach($field in $childFieldList)\n#if($field.attrName != ${childPkField.attrName} && $field.attrName != ${parentField})\n#if($field.formType == \'number\')\n ${field.attrName}: number;\n#elseif($field.formType == \'checkbox\' || $field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n ${field.attrName}: any[];\n#else\n ${field.attrName}: string;\n#end\n#end\n#end\n}\n\nconst emit = defineEmits([\'refresh\']);\nconst dataFormRef = ref();\nconst visible = ref(false);\nconst loading = ref(false);\nconst parentNodes = ref<TreeNode[]>([]);\nconst currentNodeId = ref<string | number | null>(null);\n\nconst treeSelectProps = {\n children: \'children\',\n label: \'${nameField}\',\n value: \'${childPkField.attrName}\',\n checkStrictly: true\n};\n\nconst form = reactive<FormData>({\n ${childPkField.attrName}: \'\', // 主键\n ${parentField}: 0,\n#foreach($field in $childFieldList)\n#if($field.attrName != ${childPkField.attrName} && $field.attrName != ${parentField})\n#if($field.formType == \'number\')\n ${field.attrName}: 0, // ${field.fieldComment}\n#elseif($field.formType == \'checkbox\' || $field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n ${field.attrName}: [], // ${field.fieldComment}\n#else\n ${field.attrName}: \'\', // ${field.fieldComment}\n#end\n#end\n#end\n});\n\n#if($fieldDict && $fieldDict.size() > 0)\nconst { $dict.format($fieldDict) } = useDict($dict.quotation($fieldDict));\n#end\n\nconst dataRules = ref({\n ${parentField}: [\n {\n required: true,\n validator: (rule: any, value: any, callback: any) => {\n if (value === null || value === undefined || value === \'\') {\n callback(new Error(\'请选择父级节点\'));\n } else {\n callback();\n }\n },\n trigger: \'change\'\n }\n ],\n#foreach($field in $childFieldList)\n#if($field.attrName != ${parentField} && $field.formRequired == \'1\' && $field.formValidator == \'duplicate\')\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' },\n {\n validator: (rule: any, value: any, callback: any) => {\n validateExist(rule, value, callback, form.${childPkField.attrName} !== \'\');\n },\n trigger: \'blur\',\n }\n ],\n#elseif($field.attrName != ${parentField} && $field.formRequired == \'1\' && $field.formValidator)\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' },\n { validator: rule.${field.formValidator}, trigger: \'blur\' }\n ],\n#elseif($field.attrName != ${parentField} && $field.formRequired == \'1\')\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' }\n ],\n#elseif($field.attrName != ${parentField} && $field.formValidator)\n ${field.attrName}: [\n { validator: rule.${field.formValidator}, trigger: \'blur\' }\n ],\n#end\n#end\n});\n\nconst get${ChildClassName}Data = async (id: string) => {\n try {\n loading.value = true;\n const { data } = await getTreeObj({ ${childPkField.attrName}: id });\n if (data && data.length > 0) {\n Object.assign(form, data[0]);\n }\n } catch (error) {\n useMessage().error(\'获取数据失败\');\n } finally {\n loading.value = false;\n }\n};\n\nconst buildParentNodes = (nodes: TreeNode[], excludedIds: Set<string | number> = new Set()): TreeNode[] => {\n return nodes\n .filter((node) => !excludedIds.has(node.${childPkField.attrName}))\n .map((node) => ({\n ...node,\n children: node.children ? buildParentNodes(node.children, excludedIds) : []\n }));\n};\n\nconst collectDescendantIds = (nodes: TreeNode[], targetId: string | number, collect: Set<string | number>) => {\n nodes.forEach((node) => {\n if (node.${childPkField.attrName} === targetId) {\n const traverse = (children?: TreeNode[]) => {\n children?.forEach((child) => {\n collect.add(child.${childPkField.attrName});\n traverse(child.children);\n });\n };\n traverse(node.children);\n } else if (node.children?.length) {\n collectDescendantIds(node.children, targetId, collect);\n }\n });\n};\n\nconst loadParentNodes = async (excludeCurrent = false) => {\n const { data } = await fetchTreeList();\n const rootNode: TreeNode = {\n ${childPkField.attrName}: 0,\n ${nameField}: \'根节点\',\n children: data || []\n };\n\n if (excludeCurrent && currentNodeId.value !== null && currentNodeId.value !== undefined) {\n const excludedIds = new Set<string | number>([currentNodeId.value]);\n collectDescendantIds(rootNode.children || [], currentNodeId.value, excludedIds);\n parentNodes.value = [{ ...rootNode, children: buildParentNodes(rootNode.children || [], excludedIds) }];\n return;\n }\n\n parentNodes.value = [rootNode];\n};\n\nconst openDialog = async (id?: string, parentId?: string | number) => {\n visible.value = true;\n form.${childPkField.attrName} = \'\';\n currentNodeId.value = id || null;\n\n nextTick(() => {\n dataFormRef.value?.resetFields();\n });\n\n await loadParentNodes(Boolean(id));\n form.${parentField} = parentId ?? 0;\n\n if (id) {\n form.${childPkField.attrName} = id;\n await get${ChildClassName}Data(id);\n }\n};\n\nconst validateExist = (rule: any, value: any, callback: any, isEdit: boolean) => {\n if (isEdit) {\n return callback();\n }\n\n getTreeObj({ [rule.field]: value }).then((response) => {\n const result = response.data;\n if (result !== null && result.length > 0) {\n callback(new Error(\'数据已经存在\'));\n } else {\n callback();\n }\n });\n};\n\nconst onSubmit = async () => {\n loading.value = true;\n\n const valid = await dataFormRef.value.validate().catch(() => {});\n if (!valid) {\n loading.value = false;\n return false;\n }\n\n try {\n form.${parentField} = form.${parentField} ?? 0;\n form.${childPkField.attrName} ? await putTreeObj(form) : await addTreeObj(form);\n useMessage().success(form.${childPkField.attrName} ? \'修改成功\' : \'添加成功\');\n visible.value = false;\n emit(\'refresh\');\n } catch (error: any) {\n useMessage().error(error.msg || \'操作失败\');\n } finally {\n loading.value = false;\n }\n};\n\ndefineExpose({\n openDialog\n});\n</script>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
INSERT INTO `gen_template` (`id`, `template_name`, `generator_path`, `template_desc`, `template_code`, `create_time`, `update_time`, `del_flag`, `tenant_id`, `create_by`, `update_by`) VALUES (45,'主表单V2026001','${frontendPath}/src/views/${moduleName}/${functionName}/form.vue','主表单V2026001','#foreach($field in $childFieldList)\n#if($field.primaryPk == \'1\')\n#set($childPkField = $field)\n#break\n#end\n#end\n#set($relationFieldLabel = $childField)\n#foreach($field in $fieldList)\n#if($field.attrName == $childField)\n#if($field.fieldComment)\n#set($relationFieldLabel = $field.fieldComment)\n#else\n#set($relationFieldLabel = $field.attrName)\n#end\n#break\n#end\n#end\n#set($fieldDict=[])\n#foreach($field in $formList)\n#if($field.fieldDict)\n#set($void=$fieldDict.add($field.fieldDict))\n#end\n#end\n<template>\n <el-dialog :title=\"form.${pk.attrName} ? \'编辑\' : \'新增\'\" v-model=\"visible\"\n :close-on-click-modal=\"false\" draggable>\n <el-form ref=\"dataFormRef\" :model=\"form\" :rules=\"dataRules\" label-width=\"90px\" v-loading=\"loading\">\n <el-row :gutter=\"24\">\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n <el-form-item label=\"${relationFieldLabel}\" prop=\"${childField}\">\n <el-tree-select\n v-model=\"form.${childField}\"\n :data=\"treeNodes\"\n :props=\"treeSelectProps\"\n check-strictly\n :render-after-expand=\"false\"\n placeholder=\"请选择${relationFieldLabel}\"\n style=\"width: 100%\"\n clearable\n filterable\n />\n </el-form-item>\n </el-col>\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${childField})\n#if($formLayout == 1)\n <el-col :span=\"24\" class=\"mb20\">\n#elseif($formLayout == 2)\n <el-col :span=\"12\" class=\"mb20\">\n#end\n#if($field.formType == \'text\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'textarea\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input type=\"textarea\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'select\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-select v-model=\"form.${field.attrName}\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\">\n#if($field.fieldDict)\n <el-option :value=\"item.value\" :label=\"item.label\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\"></el-option>\n#else\n <el-option label=\"请选择\" value=\"0\"></el-option>\n#end\n </el-select>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'radio\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-radio-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-radio :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" border :key=\"index\">{{ item.label }}</el-radio>\n#else\n <el-radio label=\"${field.fieldComment}\" border>${field.fieldComment}</el-radio>\n#end\n </el-radio-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'checkbox\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-checkbox-group v-model=\"form.${field.attrName}\">\n#if($field.fieldDict)\n <el-checkbox :label=\"item.value\" v-for=\"(item, index) in ${field.fieldDict}\" :key=\"index\">{{ item.label }}</el-checkbox>\n#else\n <el-checkbox label=\"启用\" name=\"type\"></el-checkbox>\n <el-checkbox label=\"禁用\" name=\"type\"></el-checkbox>\n#end\n </el-checkbox-group>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'date\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"date\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetime\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetime\" placeholder=\"请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'daterange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"daterange\" range-separator=\"至\" start-placeholder=\"开始日期\" end-placeholder=\"结束日期\" v-model=\"form.${field.attrName}\" :value-format=\"dateStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'datetimerange\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-date-picker type=\"datetimerange\" range-separator=\"至\" start-placeholder=\"开始时间\" end-placeholder=\"结束时间\" v-model=\"form.${field.attrName}\" :value-format=\"dateTimeStr\"></el-date-picker>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'number\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input-number :min=\"1\" :max=\"1000\" v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"></el-input-number>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'upload-file\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <upload-file v-model=\"form.${field.attrName}\"></upload-file>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'upload-img\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <upload-img v-model:imageUrl=\"form.${field.attrName}\"></upload-img>\n </el-form-item>\n </el-col>\n#elseif($field.formType == \'editor\')\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <editor v-if=\"visible\" v-model:get-html=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"></editor>\n </el-form-item>\n </el-col>\n#else\n <el-form-item label=\"#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\" prop=\"${field.attrName}\">\n <el-input v-model=\"form.${field.attrName}\" placeholder=\"请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end\"/>\n </el-form-item>\n </el-col>\n#end\n#end\n#end\n </el-row>\n </el-form>\n <template #footer>\n <span class=\"dialog-footer\">\n <el-button @click=\"visible = false\">取 消</el-button>\n <el-button type=\"primary\" @click=\"onSubmit\" :disabled=\"loading\">确 认</el-button>\n </span>\n </template>\n </el-dialog>\n</template>\n\n<script setup lang=\"ts\" name=\"${ClassName}Dialog\">\nimport { useMessage } from \"/@/hooks/message\";\nimport { addObj, fetchTreeList, getObj, putObj, validateExist } from \'/@/api/${moduleName}/${functionName}\';\n#if($fieldDict && $fieldDict.size() > 0)\nimport { useDict } from \'/@/hooks/dict\';\n#end\n#foreach($field in $formList)\n#if($field.formValidator && $field.formValidator != \'duplicate\')\nimport { rule } from \'/@/utils/validate\';\n#break\n#end\n#end\n\ninterface TreeNode {\n [key: string]: any;\n children?: TreeNode[];\n}\n\ninterface FormData {\n ${pk.attrName}?: string | number;\n ${childField}?: string | number | null;\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${childField})\n#if($field.formType == \'number\')\n ${field.attrName}: number;\n#elseif($field.formType == \'checkbox\' || $field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n ${field.attrName}: any[];\n#else\n ${field.attrName}: string;\n#end\n#end\n#end\n}\n\nconst emit = defineEmits([\'refresh\']);\nconst dataFormRef = ref();\nconst visible = ref(false);\nconst loading = ref(false);\nconst treeNodes = ref<TreeNode[]>([]);\nconst currentTreeId = ref<string | number | null>(null);\n\nconst treeSelectProps = {\n children: \'children\',\n label: \'${nameField}\',\n value: \'${childPkField.attrName}\',\n checkStrictly: true\n};\n\nconst form = reactive<FormData>({\n ${pk.attrName}: \'\', // 主键\n ${childField}: null,\n#foreach($field in $formList)\n#if($field.attrName != ${pk.attrName} && $field.attrName != ${childField})\n#if($field.formType == \'number\')\n ${field.attrName}: 0, // ${field.fieldComment}\n#elseif($field.formType == \'checkbox\' || $field.formType == \'daterange\' || $field.formType == \'datetimerange\')\n ${field.attrName}: [], // ${field.fieldComment}\n#else\n ${field.attrName}: \'\', // ${field.fieldComment}\n#end\n#end\n#end\n});\n\n#if($fieldDict && $fieldDict.size() > 0)\nconst { $dict.format($fieldDict) } = useDict($dict.quotation($fieldDict));\n#end\n\nconst dataRules = ref({\n ${childField}: [\n {\n required: true,\n validator: (rule: any, value: any, callback: any) => {\n if (value === null || value === undefined || value === \'\') {\n callback(new Error(\'请选择${relationFieldLabel}\'));\n } else {\n callback();\n }\n },\n trigger: \'change\'\n }\n ],\n#foreach($field in $formList)\n#if($field.attrName != ${childField} && $field.formRequired == \'1\' && $field.formValidator == \'duplicate\')\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' },\n {\n validator: (rule: any, value: any, callback: any) => {\n validateExist(rule, value, callback, form.${pk.attrName} !== \'\');\n },\n trigger: \'blur\',\n }\n ],\n#elseif($field.attrName != ${childField} && $field.formRequired == \'1\' && $field.formValidator)\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' },\n { validator: rule.${field.formValidator}, trigger: \'blur\' }\n ],\n#elseif($field.attrName != ${childField} && $field.formRequired == \'1\')\n ${field.attrName}: [\n { required: true, message: \'${field.fieldComment}不能为空\', trigger: \'blur\' }\n ],\n#elseif($field.attrName != ${childField} && $field.formValidator)\n ${field.attrName}: [\n { validator: rule.${field.formValidator}, trigger: \'blur\' }\n ],\n#end\n#end\n});\n\nconst get${ClassName}Data = async (id: string) => {\n try {\n loading.value = true;\n const { data } = await getObj({ ${pk.attrName}: id });\n if (data && data.length > 0) {\n Object.assign(form, data[0]);\n }\n } catch (error) {\n useMessage().error(\'获取数据失败\');\n } finally {\n loading.value = false;\n }\n};\n\nconst loadTreeNodes = async () => {\n const { data } = await fetchTreeList();\n treeNodes.value = data || [];\n};\n\nconst openDialog = async (id?: string, treeId?: string | number) => {\n visible.value = true;\n currentTreeId.value = treeId ?? null;\n form.${pk.attrName} = \'\';\n\n nextTick(() => {\n dataFormRef.value?.resetFields();\n });\n\n await loadTreeNodes();\n form.${childField} = treeId ?? null;\n\n if (id) {\n form.${pk.attrName} = id;\n await get${ClassName}Data(id);\n }\n};\n\nconst onSubmit = async () => {\n loading.value = true;\n\n const valid = await dataFormRef.value.validate().catch(() => {});\n if (!valid) {\n loading.value = false;\n return false;\n }\n\n try {\n form.${childField} = form.${childField} ?? null;\n form.${pk.attrName} ? await putObj(form) : await addObj(form);\n useMessage().success(form.${pk.attrName} ? \'修改成功\' : \'添加成功\');\n visible.value = false;\n emit(\'refresh\');\n } catch (error: any) {\n useMessage().error(error.msg || \'操作失败\');\n } finally {\n loading.value = false;\n }\n};\n\ndefineExpose({\n openDialog\n});\n</script>\n','2026-04-08 17:38:24','2026-04-08 17:38:24','0',1,'admin','admin');
|
|
COMMIT;
|
|
|
|
-- ----------------------------
|
|
-- Table structure for gen_template_group
|
|
-- ----------------------------
|
|
DROP TABLE IF EXISTS `gen_template_group`;
|
|
CREATE TABLE `gen_template_group` (
|
|
`group_id` bigint NOT NULL COMMENT '分组id',
|
|
`template_id` bigint NOT NULL COMMENT '模板id',
|
|
PRIMARY KEY (`group_id`,`template_id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='模板分组关联表';
|
|
|
|
-- ----------------------------
|
|
-- Records of gen_template_group
|
|
-- ----------------------------
|
|
BEGIN;
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (1,1);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (1,2);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (1,3);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (1,4);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (1,5);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (1,6);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (1,7);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (1,8);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (1,9);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (1,10);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (2,11);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (2,12);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (2,13);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (2,14);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (2,15);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (2,16);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (2,17);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (2,18);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (2,19);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (2,20);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (2,21);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (2,22);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (3,23);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (3,24);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (3,25);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (3,26);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (3,27);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (3,28);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (3,29);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (3,30);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (3,31);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (3,32);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (4,33);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (4,34);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (4,35);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (4,36);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (4,37);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (4,38);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (4,39);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (4,40);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (4,41);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (4,42);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (4,43);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (4,44);
|
|
INSERT INTO `gen_template_group` (`group_id`, `template_id`) VALUES (4,45);
|
|
COMMIT;
|
|
|
|
-- ----------------------------
|
|
-- Table structure for gen_create_table
|
|
-- ----------------------------
|
|
DROP TABLE IF EXISTS `gen_create_table`;
|
|
CREATE TABLE `gen_create_table` (
|
|
`id` bigint NOT NULL COMMENT '主键ID',
|
|
`table_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '表名称',
|
|
`ds_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '数据源',
|
|
`comments` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '表注释',
|
|
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '创建人',
|
|
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
|
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
|
`update_time` datetime DEFAULT NULL,
|
|
`column_info` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '字段信息',
|
|
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '删除标记',
|
|
`tenant_id` bigint DEFAULT NULL COMMENT '租户ID',
|
|
PRIMARY KEY (`id`) USING BTREE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC COMMENT='自动创建表管理';
|
|
|
|
SET FOREIGN_KEY_CHECKS = 1;
|