mirror of https://github.com/jeecgboot/jeecg-boot
JeecgBoot低代码平台 3.0版本发布—新里程牌开始,迎接VUE3版本到来!!
parent
9760185bf6
commit
0acea1abff
|
@ -1,13 +1,13 @@
|
||||||
Jeecg-Boot 低代码开发平台
|
Jeecg-Boot 低代码开发平台
|
||||||
===============
|
===============
|
||||||
|
|
||||||
当前最新版本: 2.4.6(发布日期:20210813)
|
当前最新版本: 3.0(发布日期:2021-11-01)
|
||||||
|
|
||||||
|
|
||||||
## 后端技术架构
|
## 后端技术架构
|
||||||
- 基础框架:Spring Boot 2.3.5.RELEASE
|
- 基础框架:Spring Boot 2.3.5.RELEASE
|
||||||
|
|
||||||
- 持久层框架:Mybatis-plus 3.4.3.1
|
- 持久层框架:Mybatis-plus 3.4.1
|
||||||
|
|
||||||
- 安全框架:Apache Shiro 1.7.0,Jwt 3.11.0
|
- 安全框架:Apache Shiro 1.7.0,Jwt 3.11.0
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ Jeecg-Boot 低代码开发平台
|
||||||
|
|
||||||
- 依赖管理:Maven
|
- 依赖管理:Maven
|
||||||
|
|
||||||
- 数据库:MySQL5.7+ & Oracle 11g & SqlServer & postgresql
|
- 数据库:MySQL5.7+ & Oracle 11g & SqlServer & postgresql & 国产等更多数据库
|
||||||
|
|
||||||
- 缓存:Redis
|
- 缓存:Redis
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ Jeecg-Boot 低代码开发平台
|
||||||
|
|
||||||
- 常见问题: [http://jeecg.com/doc/qa](http://jeecg.com/doc/qa)
|
- 常见问题: [http://jeecg.com/doc/qa](http://jeecg.com/doc/qa)
|
||||||
|
|
||||||
- QQ交流群 : ④774126647、③816531124、①284271917、②769925425
|
- QQ交流群 : ⑤860162132、④774126647(满)、③816531124(满)、②769925425(满)、①284271917(满)
|
||||||
|
|
||||||
|
|
||||||
## 专项文档
|
## 专项文档
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,96 +0,0 @@
|
||||||
|
|
||||||
-- 平台基础模块
|
|
||||||
ALTER TABLE `sys_third_account`
|
|
||||||
ADD UNIQUE INDEX `uniq_sys_third_account_third_type_third_user_id` (`third_type`, `third_user_id`) USING BTREE ;
|
|
||||||
|
|
||||||
INSERT INTO `sys_permission`(`id`, `parent_id`, `name`, `url`, `component`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_route`, `is_leaf`, `keep_alive`, `hidden`, `description`, `status`, `del_flag`, `rule_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `internal_or_external`) VALUES ('1404684556047024130', '08e6b9dc3c04489c8e1ff2ce6f105aa4', '在线用户', '/isystem/online', 'system/SysUserOnlineList', NULL, NULL, 1, NULL, '1', NULL, 0, NULL, 1, 1, 0, 0, NULL, '1', 0, 0, 'admin', '2021-06-15 14:17:51', NULL, NULL, 0);
|
|
||||||
|
|
||||||
DELETE FROM sys_depart WHERE id = '743ba9dbdc114af8953a11022ef3096a';
|
|
||||||
|
|
||||||
alter table sys_quartz_job engine = InnoDB;
|
|
||||||
|
|
||||||
UPDATE `sys_dict_item` SET `item_value` = '6' WHERE `item_text` = 'MYSQL5.7';
|
|
||||||
|
|
||||||
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1414837074500976641', '1209733563293962241', 'Postgresql', '6', '', '5', '1', 'admin', '2021-07-13 14:40:20', 'admin', '2021-07-15 13:44:15');
|
|
||||||
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1415547541091504129', '1209733563293962241', 'MarialDB', '5', '', '6', '1', 'admin', '2021-07-15 13:43:28', 'admin', '2021-07-15 13:44:23');
|
|
||||||
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050323111399425', '1209733563293962241', 'Derby', '13', '', '13', '1', 'admin', '2021-07-22 11:28:38', NULL, NULL);
|
|
||||||
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050209823248385', '1209733563293962241', 'Hsqldb', '12', '', '12', '1', 'admin', '2021-07-22 11:28:11', 'admin', '2021-07-22 11:28:27');
|
|
||||||
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050149475602434', '1209733563293962241', 'DB2', '11', '', '11', '1', 'admin', '2021-07-22 11:27:56', NULL, NULL);
|
|
||||||
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050110669901826', '1209733563293962241', 'SQLite', '10', '', '10', '1', 'admin', '2021-07-22 11:27:47', NULL, NULL);
|
|
||||||
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050075555188737', '1209733563293962241', '神通', '9', '', '9', '1', 'admin', '2021-07-22 11:27:39', NULL, NULL);
|
|
||||||
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050017053036545', '1209733563293962241', '人大金仓', '8', '', '8', '1', 'admin', '2021-07-22 11:27:25', NULL, NULL);
|
|
||||||
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418049969003089922', '1209733563293962241', '达梦', '7', '', '7', '1', 'admin', '2021-07-22 11:27:13', 'admin', '2021-07-22 11:27:30');
|
|
||||||
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418117316707590146', '1209733563293962241', 'H2', '14', '', '14', '1', 'admin', '2021-07-22 15:54:50', NULL, NULL);
|
|
||||||
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418491604048449537', '1209733563293962241', '其他数据库', '15', '', 15, 1, 'admin', '2021-07-23 16:42:07', NULL, NULL);
|
|
||||||
|
|
||||||
ALTER TABLE demo ADD COLUMN tenant_id int(10) NULL DEFAULT 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Online模块
|
|
||||||
ALTER TABLE `onl_cgform_head`
|
|
||||||
ADD COLUMN `ext_config_json` varchar(1000) NULL COMMENT '扩展JSON' AFTER `physic_id`;
|
|
||||||
|
|
||||||
ALTER TABLE `onl_cgreport_head`
|
|
||||||
ADD COLUMN `low_app_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '关联的应用ID' AFTER `content`;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- 积木报表模块
|
|
||||||
|
|
||||||
UPDATE `jimu_report` SET `json_str` = '{\"loopBlockList\":[],\"area\":{\"sri\":16,\"sci\":5,\"eri\":16,\"eci\":5,\"width\":147,\"height\":25},\"excel_config_id\":\"1347373863746539520\",\"printConfig\":{\"paper\":\"A4\",\"width\":210,\"height\":297,\"definition\":1,\"isBackend\":false,\"marginX\":10,\"marginY\":10,\"layout\":\"portrait\"},\"rows\":{\"0\":{\"cells\":{\"0\":{\"text\":\"\"},\"1\":{\"text\":\"\"}}},\"1\":{\"cells\":{\"0\":{\"text\":\"\"}}},\"3\":{\"cells\":{\"2\":{\"text\":\"\",\"rendered\":\"\"}}},\"5\":{\"cells\":{},\"height\":29},\"6\":{\"cells\":{\"2\":{\"text\":\"\",\"style\":2}},\"height\":34},\"7\":{\"cells\":{\"2\":{\"merge\":[0,4],\"text\":\"实习证明\",\"style\":2}},\"height\":41},\"8\":{\"cells\":{\"1\":{\"text\":\"\",\"style\":3},\"2\":{\"text\":\"\"}}},\"9\":{\"cells\":{\"1\":{\"text\":\"\",\"style\":3},\"2\":{\"text\":\"\",\"style\":3},\"3\":{\"text\":\"\"}},\"isDrag\":true,\"height\":33},\"10\":{\"cells\":{\"2\":{\"text\":\"${tt.name}\",\"style\":11},\"3\":{\"text\":\"同学在我公司与 2020年4月1日 至 2020年5月1日 实习。\",\"style\":19,\"merge\":[0,3],\"height\":34}},\"height\":34},\"11\":{\"cells\":{},\"height\":28},\"12\":{\"cells\":{\"1\":{\"text\":\"\",\"style\":6},\"2\":{\"style\":13,\"text\":\"${tt.pingjia}\",\"merge\":[3,4],\"height\":129}},\"height\":36},\"13\":{\"cells\":{},\"height\":29},\"14\":{\"cells\":{},\"height\":33},\"15\":{\"cells\":{},\"height\":31},\"16\":{\"cells\":{}},\"17\":{\"cells\":{\"1\":{\"text\":\"\"},\"2\":{\"text\":\"特此证明!\",\"style\":12}}},\"20\":{\"cells\":{\"2\":{\"text\":\"\"},\"3\":{\"text\":\"\",\"style\":3},\"4\":{\"text\":\"\"}}},\"21\":{\"cells\":{\"4\":{\"text\":\"\"}}},\"22\":{\"cells\":{\"3\":{\"text\":\"\",\"style\":3},\"4\":{\"text\":\"证明人:\",\"style\":11},\"5\":{\"text\":\"${tt.lingdao}\",\"style\":12}}},\"23\":{\"cells\":{\"4\":{\"text\":\"\"},\"5\":{\"text\":\"${tt.shijian}\",\"style\":15}}},\"len\":100},\"dbexps\":[],\"dicts\":[],\"freeze\":\"A1\",\"dataRectWidth\":576,\"displayConfig\":{},\"background\":{\"path\":\"https://static.jeecg.com/designreport/images/11_1611283832037.png\",\"repeat\":\"no-repeat\",\"width\":\"\",\"height\":\"\"},\"name\":\"sheet1\",\"autofilter\":{},\"styles\":[{\"align\":\"center\"},{\"align\":\"center\",\"font\":{\"size\":14}},{\"align\":\"center\",\"font\":{\"size\":16}},{\"align\":\"right\"},{\"align\":\"left\"},{\"align\":\"left\",\"valign\":\"top\"},{\"align\":\"left\",\"valign\":\"top\",\"textwrap\":true},{\"font\":{\"size\":16}},{\"align\":\"left\",\"valign\":\"top\",\"textwrap\":false},{\"textwrap\":false},{\"textwrap\":true},{\"align\":\"right\",\"font\":{\"size\":12}},{\"font\":{\"size\":12}},{\"align\":\"left\",\"valign\":\"top\",\"textwrap\":true,\"font\":{\"size\":12}},{\"textwrap\":true,\"font\":{\"size\":12}},{\"align\":\"left\",\"font\":{\"size\":12}},{\"font\":{\"size\":12},\"border\":{\"bottom\":[\"thin\",\"#000\"],\"top\":[\"thin\",\"#000\"],\"left\":[\"thin\",\"#000\"],\"right\":[\"thin\",\"#000\"]}},{\"font\":{\"size\":14}},{\"font\":{\"size\":10}},{\"textwrap\":false,\"font\":{\"size\":12}}],\"validations\":[],\"cols\":{\"0\":{\"width\":69},\"1\":{\"width\":41},\"4\":{\"width\":119},\"5\":{\"width\":147},\"6\":{\"width\":31},\"len\":50},\"merges\":[\"C8:G8\",\"D11:G11\",\"C13:G16\"]}' WHERE `id` = '1347373863746539520';
|
|
||||||
|
|
||||||
update jimu_report_data_source set connect_times = 0;
|
|
||||||
ALTER TABLE `jimu_report_data_source`
|
|
||||||
MODIFY COLUMN `connect_times` int(1) UNSIGNED NULL DEFAULT 0 COMMENT '连接失败次数' AFTER `update_time`;
|
|
||||||
|
|
||||||
ALTER TABLE `jimu_report_db_param`
|
|
||||||
MODIFY COLUMN `param_value` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '参数默认值' AFTER `param_txt`;
|
|
||||||
|
|
||||||
DELETE FROM jimu_report_map
|
|
||||||
WHERE
|
|
||||||
id IN (SELECT id FROM (SELECT id FROM jimu_report_map WHERE NAME IN ( SELECT NAME FROM jimu_report_map GROUP BY NAME HAVING count(NAME) > 1)) T)
|
|
||||||
AND id NOT IN (SELECT id FROM ( SELECT min(id) id FROM jimu_report_map GROUP BY NAME HAVING count(NAME) > 1) M);
|
|
||||||
|
|
||||||
ALTER TABLE `jimu_report_map`
|
|
||||||
ADD UNIQUE INDEX `uniq_jmreport_map_name`(`name`);
|
|
||||||
|
|
||||||
update jimu_report set VIEW_COUNT = 0 WHERE VIEW_COUNT is null or VIEW_COUNT = '';
|
|
||||||
ALTER TABLE `jimu_report`
|
|
||||||
MODIFY COLUMN `view_count` bigint(15) NULL DEFAULT 0 COMMENT '浏览次数' AFTER `template`;
|
|
||||||
|
|
||||||
ALTER TABLE `jimu_report_db`
|
|
||||||
ADD INDEX `idx_jimu_report_id`(`jimu_report_id`);
|
|
||||||
ALTER TABLE `jimu_report_db`
|
|
||||||
ADD INDEX `idx_db_source_id`(`db_source`);
|
|
||||||
ALTER TABLE `jimu_report_db_field`
|
|
||||||
ADD INDEX `idx_dbfield_order_num`(`order_num`);
|
|
||||||
ALTER TABLE `jimu_report`
|
|
||||||
ADD INDEX `uniq_jmreport_createby`(`create_by`);
|
|
||||||
ALTER TABLE `jimu_report`
|
|
||||||
ADD INDEX `uniq_jmreport_delflag`(`del_flag`);
|
|
||||||
ALTER TABLE `jimu_report_link`
|
|
||||||
ADD INDEX `uniq_link_reportid`(`report_id`);
|
|
||||||
|
|
||||||
ALTER TABLE `jimu_report`
|
|
||||||
MODIFY COLUMN `json_str` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT 'json字符串' AFTER `type`;
|
|
||||||
|
|
||||||
ALTER TABLE `jimu_report_link`
|
|
||||||
ADD COLUMN `expression` varchar(255) NULL COMMENT '表达式' AFTER `link_chart_id`;
|
|
||||||
|
|
||||||
|
|
||||||
-- 执行下面段可能会报错,说明此部分升级过了,忽略即可
|
|
||||||
ALTER TABLE `jimu_report_db_param`
|
|
||||||
ADD COLUMN `search_flag` int(1) NULL COMMENT '查询标识0否1是 默认0' AFTER `update_time`;
|
|
||||||
update jimu_report_db_param set search_flag = 0;
|
|
||||||
|
|
||||||
create table jimu_dict like sys_dict;
|
|
||||||
insert into jimu_dict select * from sys_dict;
|
|
||||||
create table jimu_dict_item like sys_dict_item;
|
|
||||||
insert into jimu_dict_item select * from sys_dict_item;
|
|
||||||
|
|
||||||
ALTER TABLE `jimu_report_db_param`
|
|
||||||
ADD COLUMN `widget_type` varchar(50) NULL COMMENT '查询控件类型' AFTER `search_flag`,
|
|
||||||
ADD COLUMN `search_mode` int(1) NULL COMMENT '查询模式1简单2范围' AFTER `widget_type`,
|
|
||||||
ADD COLUMN `dict_code` varchar(255) NULL COMMENT '字典' AFTER `search_mode`;
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
-- 字段长度不规范,导致转库错误Specified key was too long; max key length is 767 bytes
|
||||||
|
ALTER TABLE `rep_demo_dxtj`
|
||||||
|
MODIFY COLUMN `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键' FIRST;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_third_account`
|
||||||
|
MODIFY COLUMN `third_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '登录来源' AFTER `third_user_id`;
|
||||||
|
|
||||||
|
|
||||||
|
-- 数据源字典sql整理
|
||||||
|
DELETE FROM `sys_dict_item` WHERE dict_id ='1209733563293962241';
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1209733775114702850', '1209733563293962241', 'MySQL5.5', '1', '', 1, 1, 'admin', '2019-12-25 15:13:02', NULL, NULL);
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1334440962954936321', '1209733563293962241', 'MYSQL5.7+', '4', '', 2, 1, 'admin', '2020-12-03 18:16:02', 'admin', '2021-07-15 13:44:29');
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1209733839933476865', '1209733563293962241', 'Oracle', '2', '', 3, 1, 'admin', '2019-12-25 15:13:18', 'admin', '2021-07-15 13:44:08');
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1209733903020003330', '1209733563293962241', 'SQLServer', '3', '', 4, 1, 'admin', '2019-12-25 15:13:33', 'admin', '2021-07-15 13:44:11');
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1414837074500976641', '1209733563293962241', 'postgresql', '6', '', 5, 1, 'admin', '2021-07-13 14:40:20', 'admin', '2021-07-15 13:44:15');
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1415547541091504129', '1209733563293962241', 'marialDB', '5', '', 6, 1, 'admin', '2021-07-15 13:43:28', 'admin', '2021-07-15 13:44:23');
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418049969003089922', '1209733563293962241', '达梦', '7', '', 7, 1, 'admin', '2021-07-22 11:27:13', 'admin', '2021-07-22 11:27:30');
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050017053036545', '1209733563293962241', '人大金仓', '8', '', 8, 1, 'admin', '2021-07-22 11:27:25', NULL, NULL);
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050075555188737', '1209733563293962241', '神通', '9', '', 9, 1, 'admin', '2021-07-22 11:27:39', NULL, NULL);
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050110669901826', '1209733563293962241', 'SQLite', '10', '', 10, 1, 'admin', '2021-07-22 11:27:47', NULL, NULL);
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050149475602434', '1209733563293962241', 'DB2', '11', '', 11, 1, 'admin', '2021-07-22 11:27:56', NULL, NULL);
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050209823248385', '1209733563293962241', 'Hsqldb', '12', '', 12, 1, 'admin', '2021-07-22 11:28:11', 'admin', '2021-07-22 11:28:27');
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050323111399425', '1209733563293962241', 'Derby', '13', '', 13, 1, 'admin', '2021-07-22 11:28:38', NULL, NULL);
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418117316707590146', '1209733563293962241', 'H2', '14', '', 14, 1, 'admin', '2021-07-22 15:54:50', NULL, NULL);
|
||||||
|
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418491604048449537', '1209733563293962241', '其他数据库', '15', '', 15, 1, 'admin', '2021-07-23 16:42:07', NULL, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
-- 新增 hideTab 字段
|
||||||
|
ALTER TABLE `sys_permission`
|
||||||
|
ADD COLUMN `hide_tab` int(2) NULL COMMENT '是否隐藏tab: 0否,1是' AFTER `hidden`;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- 【online表单】新增 low_app_id 字段
|
||||||
|
ALTER TABLE `onl_cgform_head`
|
||||||
|
ADD COLUMN `low_app_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '关联的应用ID' AFTER `des_form_code`;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- online老数据,存在字符串类型key值不一致的情况,String改为string
|
||||||
|
UPDATE onl_cgform_field SET db_type = 'string' where binary db_type = 'String';
|
||||||
|
|
||||||
|
-- 积木报表升级
|
||||||
|
ALTER TABLE `jimu_report`
|
||||||
|
MODIFY COLUMN `view_count` bigint(15) NULL DEFAULT 0 COMMENT '浏览次数' AFTER `template`;
|
||||||
|
ALTER TABLE `jimu_report`
|
||||||
|
MODIFY COLUMN `json_str` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT 'json字符串' AFTER `type`;
|
||||||
|
ALTER TABLE `jimu_report_db_field`
|
||||||
|
ADD COLUMN `search_format` varchar(50) NULL COMMENT '查询时间格式化表达式' AFTER `search_value`;
|
||||||
|
ALTER TABLE `jimu_report_db_param`
|
||||||
|
ADD COLUMN `search_format` varchar(50) NULL COMMENT '查询时间格式化表达式' AFTER `dict_code`;
|
||||||
|
UPDATE jimu_report SET json_str=replace(json_str,'"subtotal":"totalField"','"funcname":"SUM"');
|
||||||
|
ALTER TABLE `jimu_report`
|
||||||
|
ADD COLUMN `css_str` text NULL COMMENT 'css增强' AFTER `view_count`,
|
||||||
|
ADD COLUMN `js_str` text NULL COMMENT 'js增强' AFTER `css_str`;
|
||||||
|
ALTER TABLE `jimu_report_link`
|
||||||
|
CHANGE COLUMN `expression` `requirement` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '条件' AFTER `link_chart_id`;
|
||||||
|
ALTER TABLE `jimu_report_db_field`
|
||||||
|
ADD COLUMN `ext_json` text NULL COMMENT '参数配置' AFTER `search_format`;
|
||||||
|
ALTER TABLE `jimu_report_db_param`
|
||||||
|
ADD COLUMN `ext_json` text NULL COMMENT '参数配置' AFTER `search_format`;
|
||||||
|
ALTER TABLE `jimu_report_db`
|
||||||
|
MODIFY COLUMN `is_list` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0' COMMENT '是否是列表0否1是 默认0' AFTER `api_method`;
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>jeecg-boot-base-api</artifactId>
|
<artifactId>jeecg-boot-base-api</artifactId>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<version>2.4.6</version>
|
<version>3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,10 @@ import java.util.SortedMap;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.jeecg.common.config.mqtoken.UserTokenContext;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.util.DateUtils;
|
import org.jeecg.common.util.DateUtils;
|
||||||
import org.jeecg.common.util.PathMatcherUtil;
|
import org.jeecg.common.util.PathMatcherUtil;
|
||||||
import org.jeecg.common.config.mqtoken.UserTokenContext;
|
|
||||||
import org.jeecg.config.sign.interceptor.SignAuthConfiguration;
|
import org.jeecg.config.sign.interceptor.SignAuthConfiguration;
|
||||||
import org.jeecg.config.sign.util.HttpUtils;
|
import org.jeecg.config.sign.util.HttpUtils;
|
||||||
import org.jeecg.config.sign.util.SignUtil;
|
import org.jeecg.config.sign.util.SignUtil;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>jeecg-boot-base-api</artifactId>
|
<artifactId>jeecg-boot-base-api</artifactId>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<version>2.4.6</version>
|
<version>3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>jeecg-boot-base</artifactId>
|
<artifactId>jeecg-boot-base</artifactId>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<version>2.4.6</version>
|
<version>3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<artifactId>jeecg-boot-base</artifactId>
|
<artifactId>jeecg-boot-base</artifactId>
|
||||||
<version>2.4.6</version>
|
<version>3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<artifactId>hibernate-re</artifactId>
|
<artifactId>hibernate-re</artifactId>
|
||||||
<version>2.4.6-beta1</version>
|
<version>3.0.0-beta</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 数据库驱动 -->
|
<!-- 数据库驱动 -->
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
package org.jeecg.common.api;
|
|
||||||
|
|
||||||
import org.jeecg.common.api.vo.OaWpsModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description: WPS通用接口
|
|
||||||
* @Author: wangshuai
|
|
||||||
* @Date:20200709
|
|
||||||
* @Version:V1.0
|
|
||||||
*/
|
|
||||||
public interface IWpsBaseAPI {
|
|
||||||
|
|
||||||
/*根据模板id获取模板信息*/
|
|
||||||
OaWpsModel getById(String id);
|
|
||||||
|
|
||||||
/*根据文件路径下载文件*/
|
|
||||||
void downloadOosFiles(String objectName, String basePath,String fileName);
|
|
||||||
|
|
||||||
/*WPS 设置数据存储,用于逻辑判断*/
|
|
||||||
void context(String type,String text);
|
|
||||||
|
|
||||||
/*删除WPS模板相关信息*/
|
|
||||||
void deleteById(String id);
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package org.jeecg.common.api.desform;
|
|
||||||
|
|
||||||
import org.jeecg.common.system.vo.DictModel;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 表单设计器【System】翻译API接口
|
|
||||||
*
|
|
||||||
* @author sunjianlei
|
|
||||||
*/
|
|
||||||
public interface ISysTranslateAPI {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询分类字典翻译
|
|
||||||
*/
|
|
||||||
List<String> categoryLoadDictItem(String ids);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据字典code加载字典text
|
|
||||||
*
|
|
||||||
* @param dictCode 顺序:tableName,text,code
|
|
||||||
* @param keys 要查询的key
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
List<String> dictLoadDictItem(String dictCode, String keys);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取字典数据
|
|
||||||
*
|
|
||||||
* @param dictCode 顺序:tableName,text,code
|
|
||||||
* @param dictCode 要查询的key
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
List<DictModel> dictGetDictItems(String dictCode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【JSearchSelectTag下拉搜索组件专用接口】
|
|
||||||
* 大数据量的字典表 走异步加载 即前端输入内容过滤数据
|
|
||||||
*
|
|
||||||
* @param dictCode 字典code格式:table,text,code
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
List<DictModel> dictLoadDict(String dictCode, String keyword, Integer pageSize);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
package org.jeecg.common.api.vo;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description: 文档
|
|
||||||
* @Author: jeecg-boot
|
|
||||||
* @Date: 2020-06-09
|
|
||||||
* @Version: V1.0
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@TableName("oa_wps_file")
|
|
||||||
@Accessors(chain = true)
|
|
||||||
@EqualsAndHashCode(callSuper = false)
|
|
||||||
@ApiModel(value = "oa_wps_file对象", description = "文档")
|
|
||||||
public class OaWpsModel implements Serializable {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* id
|
|
||||||
*/
|
|
||||||
@TableId(type = IdType.ASSIGN_ID)
|
|
||||||
@ApiModelProperty(value = "id")
|
|
||||||
private String id;
|
|
||||||
/**
|
|
||||||
* name
|
|
||||||
*/
|
|
||||||
@Excel(name = "name", width = 15)
|
|
||||||
@ApiModelProperty(value = "name")
|
|
||||||
private String name;
|
|
||||||
/**
|
|
||||||
* version
|
|
||||||
*/
|
|
||||||
@Excel(name = "version", width = 15)
|
|
||||||
@ApiModelProperty(value = "version")
|
|
||||||
private Integer version;
|
|
||||||
/**
|
|
||||||
* size
|
|
||||||
*/
|
|
||||||
@Excel(name = "size", width = 15)
|
|
||||||
@ApiModelProperty(value = "size")
|
|
||||||
private Integer size;
|
|
||||||
/**
|
|
||||||
* downloadUrl
|
|
||||||
*/
|
|
||||||
@Excel(name = "downloadUrl", width = 15)
|
|
||||||
@ApiModelProperty(value = "downloadUrl")
|
|
||||||
private String downloadUrl;
|
|
||||||
/**
|
|
||||||
* deleted
|
|
||||||
*/
|
|
||||||
@Excel(name = "deleted", width = 15)
|
|
||||||
@ApiModelProperty(value = "deleted")
|
|
||||||
private String deleted;
|
|
||||||
/**
|
|
||||||
* canDelete
|
|
||||||
*/
|
|
||||||
@Excel(name = "canDelete", width = 15)
|
|
||||||
@ApiModelProperty(value = "canDelete")
|
|
||||||
private String canDelete;
|
|
||||||
/**
|
|
||||||
* 创建人
|
|
||||||
*/
|
|
||||||
@ApiModelProperty(value = "创建人")
|
|
||||||
private String createBy;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
|
||||||
@ApiModelProperty(value = "创建时间")
|
|
||||||
private Date createTime;
|
|
||||||
/**
|
|
||||||
* 更新人
|
|
||||||
*/
|
|
||||||
@ApiModelProperty(value = "更新人")
|
|
||||||
private String updateBy;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
|
||||||
@ApiModelProperty(value = "更新时间")
|
|
||||||
private Date updateTime;
|
|
||||||
/**
|
|
||||||
* 组织机构编码
|
|
||||||
*/
|
|
||||||
@ApiModelProperty(value = "组织机构编码")
|
|
||||||
private String sysOrgCode;
|
|
||||||
|
|
||||||
@TableField(exist = false)
|
|
||||||
private String userId;
|
|
||||||
}
|
|
|
@ -30,7 +30,7 @@ public class Result<T> implements Serializable {
|
||||||
* 返回处理消息
|
* 返回处理消息
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "返回处理消息")
|
@ApiModelProperty(value = "返回处理消息")
|
||||||
private String message = "操作成功!";
|
private String message = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回代码
|
* 返回代码
|
||||||
|
@ -51,7 +51,16 @@ public class Result<T> implements Serializable {
|
||||||
private long timestamp = System.currentTimeMillis();
|
private long timestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
public Result() {
|
public Result() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兼容VUE3版token失效不跳转登录页面
|
||||||
|
* @param code
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
public Result(Integer code,String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<T> success(String message) {
|
public Result<T> success(String message) {
|
||||||
|
@ -66,7 +75,6 @@ public class Result<T> implements Serializable {
|
||||||
Result<Object> r = new Result<Object>();
|
Result<Object> r = new Result<Object>();
|
||||||
r.setSuccess(true);
|
r.setSuccess(true);
|
||||||
r.setCode(CommonConstant.SC_OK_200);
|
r.setCode(CommonConstant.SC_OK_200);
|
||||||
r.setMessage("成功");
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +100,6 @@ public class Result<T> implements Serializable {
|
||||||
Result<T> r = new Result<T>();
|
Result<T> r = new Result<T>();
|
||||||
r.setSuccess(true);
|
r.setSuccess(true);
|
||||||
r.setCode(CommonConstant.SC_OK_200);
|
r.setCode(CommonConstant.SC_OK_200);
|
||||||
r.setMessage("成功");
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.springframework.util.StringUtils;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -261,7 +262,10 @@ public class DictAspect {
|
||||||
for (DictModel dict : texts) {
|
for (DictModel dict : texts) {
|
||||||
String redisKey = String.format("sys:cache:dictTable::SimpleKey [%s,%s]", dictCode, dict.getValue());
|
String redisKey = String.format("sys:cache:dictTable::SimpleKey [%s,%s]", dictCode, dict.getValue());
|
||||||
try {
|
try {
|
||||||
redisTemplate.opsForValue().set(redisKey, dict.getText());
|
// update-begin-author:taoyan date:20211012 for: 字典表翻译注解缓存未更新 issues/3061
|
||||||
|
// 保留5分钟
|
||||||
|
redisTemplate.opsForValue().set(redisKey, dict.getText(), 300, TimeUnit.SECONDS);
|
||||||
|
// update-end-author:taoyan date:20211012 for: 字典表翻译注解缓存未更新 issues/3061
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn(e.getMessage(), e);
|
log.warn(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,6 +292,7 @@ public interface CommonConstant {
|
||||||
public final static String X_ACCESS_TOKEN = "X-Access-Token";
|
public final static String X_ACCESS_TOKEN = "X-Access-Token";
|
||||||
public final static String X_SIGN = "X-Sign";
|
public final static String X_SIGN = "X-Sign";
|
||||||
public final static String X_TIMESTAMP = "X-TIMESTAMP";
|
public final static String X_TIMESTAMP = "X-TIMESTAMP";
|
||||||
|
public final static String TOKEN_IS_INVALID_MSG = "Token失效,请重新登录!";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多租户 请求头
|
* 多租户 请求头
|
||||||
|
|
|
@ -10,6 +10,8 @@ public interface DataBaseConstant {
|
||||||
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";
|
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";
|
||||||
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";
|
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";
|
||||||
public static final String DB_TYPE_MARIADB = "MARIADB";
|
public static final String DB_TYPE_MARIADB = "MARIADB";
|
||||||
|
public static final String DB_TYPE_DB2 = "DB2";
|
||||||
|
public static final String DB_TYPE_HSQL = "HSQL";
|
||||||
|
|
||||||
// // 数据库类型,对应 database_type 字典
|
// // 数据库类型,对应 database_type 字典
|
||||||
// public static final String DB_TYPE_MYSQL_NUM = "1";
|
// public static final String DB_TYPE_MYSQL_NUM = "1";
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package org.jeecg.common.exception;
|
||||||
|
|
||||||
|
public class JeecgBoot401Exception extends RuntimeException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public JeecgBoot401Exception(String message){
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JeecgBoot401Exception(Throwable cause)
|
||||||
|
{
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JeecgBoot401Exception(String message, Throwable cause)
|
||||||
|
{
|
||||||
|
super(message,cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,8 +7,10 @@ import org.jeecg.common.api.vo.Result;
|
||||||
import org.springframework.dao.DataIntegrityViolationException;
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
import org.springframework.dao.DuplicateKeyException;
|
import org.springframework.dao.DuplicateKeyException;
|
||||||
import org.springframework.data.redis.connection.PoolException;
|
import org.springframework.data.redis.connection.PoolException;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||||
|
@ -29,11 +31,21 @@ public class JeecgBootExceptionHandler {
|
||||||
* 处理自定义异常
|
* 处理自定义异常
|
||||||
*/
|
*/
|
||||||
@ExceptionHandler(JeecgBootException.class)
|
@ExceptionHandler(JeecgBootException.class)
|
||||||
public Result<?> handleRRException(JeecgBootException e){
|
public Result<?> handleJeecgBootException(JeecgBootException e){
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
return Result.error(e.getMessage());
|
return Result.error(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理自定义异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(JeecgBoot401Exception.class)
|
||||||
|
@ResponseStatus(HttpStatus.UNAUTHORIZED)
|
||||||
|
public Result<?> handleJeecgBoot401Exception(JeecgBoot401Exception e){
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
return new Result(401,e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
@ExceptionHandler(NoHandlerFoundException.class)
|
@ExceptionHandler(NoHandlerFoundException.class)
|
||||||
public Result<?> handlerNoFoundException(Exception e) {
|
public Result<?> handlerNoFoundException(Exception e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
|
|
|
@ -37,8 +37,9 @@ import java.util.stream.Collectors;
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class JeecgController<T, S extends IService<T>> {
|
public class JeecgController<T, S extends IService<T>> {
|
||||||
|
//issues/2933 JeecgController注入service时改用protected修饰,能避免重复引用service
|
||||||
@Autowired
|
@Autowired
|
||||||
S service;
|
protected S service;
|
||||||
|
|
||||||
@Value("${jeecg.path.upload}")
|
@Value("${jeecg.path.upload}")
|
||||||
private String upLoadPath;
|
private String upLoadPath;
|
||||||
|
|
|
@ -99,7 +99,7 @@ public class QueryGenerator {
|
||||||
* <br>正确示例:QueryWrapper<JeecgDemo> queryWrapper = new QueryWrapper<JeecgDemo>();
|
* <br>正确示例:QueryWrapper<JeecgDemo> queryWrapper = new QueryWrapper<JeecgDemo>();
|
||||||
* <br>3.也可以不使用这个方法直接调用 {@link #initQueryWrapper}直接获取实例
|
* <br>3.也可以不使用这个方法直接调用 {@link #initQueryWrapper}直接获取实例
|
||||||
*/
|
*/
|
||||||
public static void installMplus(QueryWrapper<?> queryWrapper,Object searchObj,Map<String, String[]> parameterMap) {
|
private static void installMplus(QueryWrapper<?> queryWrapper,Object searchObj,Map<String, String[]> parameterMap) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 注意:权限查询由前端配置数据规则 当一个人有多个所属部门时候 可以在规则配置包含条件 orgCode 包含 #{sys_org_code}
|
* 注意:权限查询由前端配置数据规则 当一个人有多个所属部门时候 可以在规则配置包含条件 orgCode 包含 #{sys_org_code}
|
||||||
|
@ -216,7 +216,7 @@ public class QueryGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
//多字段排序 TODO 需要修改前端
|
//多字段排序 TODO 需要修改前端
|
||||||
public static void doMultiFieldsOrder(QueryWrapper<?> queryWrapper,Map<String, String[]> parameterMap) {
|
private static void doMultiFieldsOrder(QueryWrapper<?> queryWrapper,Map<String, String[]> parameterMap) {
|
||||||
String column=null,order=null;
|
String column=null,order=null;
|
||||||
if(parameterMap!=null&& parameterMap.containsKey(ORDER_COLUMN)) {
|
if(parameterMap!=null&& parameterMap.containsKey(ORDER_COLUMN)) {
|
||||||
column = parameterMap.get(ORDER_COLUMN)[0];
|
column = parameterMap.get(ORDER_COLUMN)[0];
|
||||||
|
@ -258,7 +258,7 @@ public class QueryGenerator {
|
||||||
* @param parameterMap 参数对象
|
* @param parameterMap 参数对象
|
||||||
* @param fieldColumnMap 实体字段和数据库列对应的map
|
* @param fieldColumnMap 实体字段和数据库列对应的map
|
||||||
*/
|
*/
|
||||||
public static void doSuperQuery(QueryWrapper<?> queryWrapper,Map<String, String[]> parameterMap, Map<String,String> fieldColumnMap) {
|
private static void doSuperQuery(QueryWrapper<?> queryWrapper,Map<String, String[]> parameterMap, Map<String,String> fieldColumnMap) {
|
||||||
if(parameterMap!=null&& parameterMap.containsKey(SUPER_QUERY_PARAMS)){
|
if(parameterMap!=null&& parameterMap.containsKey(SUPER_QUERY_PARAMS)){
|
||||||
String superQueryParams = parameterMap.get(SUPER_QUERY_PARAMS)[0];
|
String superQueryParams = parameterMap.get(SUPER_QUERY_PARAMS)[0];
|
||||||
String superQueryMatchType = parameterMap.get(SUPER_QUERY_MATCH_TYPE) != null ? parameterMap.get(SUPER_QUERY_MATCH_TYPE)[0] : MatchTypeEnum.AND.getValue();
|
String superQueryMatchType = parameterMap.get(SUPER_QUERY_MATCH_TYPE) != null ? parameterMap.get(SUPER_QUERY_MATCH_TYPE)[0] : MatchTypeEnum.AND.getValue();
|
||||||
|
@ -347,7 +347,7 @@ public class QueryGenerator {
|
||||||
* @param value
|
* @param value
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private static QueryRuleEnum convert2Rule(Object value) {
|
public static QueryRuleEnum convert2Rule(Object value) {
|
||||||
// 避免空数据
|
// 避免空数据
|
||||||
// update-begin-author:taoyan date:20210629 for: 查询条件输入空格导致return null后续判断导致抛出null异常
|
// update-begin-author:taoyan date:20210629 for: 查询条件输入空格导致return null后续判断导致抛出null异常
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
@ -595,7 +595,7 @@ public class QueryGenerator {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取请求对应的数据权限规则
|
* 获取请求对应的数据权限规则 TODO 相同列权限多个 有问题
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static Map<String, SysPermissionDataRuleModel> getRuleMap() {
|
public static Map<String, SysPermissionDataRuleModel> getRuleMap() {
|
||||||
|
@ -616,30 +616,6 @@ public class QueryGenerator {
|
||||||
return ruleMap;
|
return ruleMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取请求对应的数据权限规则
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static Map<String, SysPermissionDataRuleModel> getRuleMap(List<SysPermissionDataRuleModel> list) {
|
|
||||||
Map<String, SysPermissionDataRuleModel> ruleMap = new HashMap<String, SysPermissionDataRuleModel>();
|
|
||||||
if(list==null){
|
|
||||||
list =JeecgDataAutorUtils.loadDataSearchConditon();
|
|
||||||
}
|
|
||||||
if(list != null&&list.size()>0){
|
|
||||||
if(list.get(0)==null){
|
|
||||||
return ruleMap;
|
|
||||||
}
|
|
||||||
for (SysPermissionDataRuleModel rule : list) {
|
|
||||||
String column = rule.getRuleColumn();
|
|
||||||
if(QueryRuleEnum.SQL_RULES.getValue().equals(rule.getRuleConditions())) {
|
|
||||||
column = SQL_RULES_COLUMN+rule.getId();
|
|
||||||
}
|
|
||||||
ruleMap.put(column, rule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ruleMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void addRuleToQueryWrapper(SysPermissionDataRuleModel dataRule, String name, Class propertyType, QueryWrapper<?> queryWrapper) {
|
private static void addRuleToQueryWrapper(SysPermissionDataRuleModel dataRule, String name, Class propertyType, QueryWrapper<?> queryWrapper) {
|
||||||
QueryRuleEnum rule = QueryRuleEnum.getByValue(dataRule.getRuleConditions());
|
QueryRuleEnum rule = QueryRuleEnum.getByValue(dataRule.getRuleConditions());
|
||||||
if(rule.equals(QueryRuleEnum.IN) && ! propertyType.equals(String.class)) {
|
if(rule.equals(QueryRuleEnum.IN) && ! propertyType.equals(String.class)) {
|
||||||
|
@ -761,7 +737,7 @@ public class QueryGenerator {
|
||||||
* @param dataBaseType
|
* @param dataBaseType
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String getSingleSqlByRule(QueryRuleEnum rule,String field,Object value,boolean isString, String dataBaseType) {
|
private static String getSingleSqlByRule(QueryRuleEnum rule,String field,Object value,boolean isString, String dataBaseType) {
|
||||||
String res = "";
|
String res = "";
|
||||||
switch (rule) {
|
switch (rule) {
|
||||||
case GT:
|
case GT:
|
||||||
|
@ -813,7 +789,7 @@ public class QueryGenerator {
|
||||||
* @param isString
|
* @param isString
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String getSingleSqlByRule(QueryRuleEnum rule,String field,Object value,boolean isString) {
|
private static String getSingleSqlByRule(QueryRuleEnum rule,String field,Object value,boolean isString) {
|
||||||
return getSingleSqlByRule(rule, field, value, isString, null);
|
return getSingleSqlByRule(rule, field, value, isString, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,19 @@ import com.auth0.jwt.JWTVerifier;
|
||||||
import com.auth0.jwt.algorithms.Algorithm;
|
import com.auth0.jwt.algorithms.Algorithm;
|
||||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.constant.DataBaseConstant;
|
import org.jeecg.common.constant.DataBaseConstant;
|
||||||
import org.jeecg.common.exception.JeecgBootException;
|
import org.jeecg.common.exception.JeecgBootException;
|
||||||
|
@ -31,6 +37,28 @@ public class JwtUtil {
|
||||||
// Token过期时间30分钟(用户登录过期时间是此时间的两倍,以token在reids缓存时间为准)
|
// Token过期时间30分钟(用户登录过期时间是此时间的两倍,以token在reids缓存时间为准)
|
||||||
public static final long EXPIRE_TIME = 30 * 60 * 1000;
|
public static final long EXPIRE_TIME = 30 * 60 * 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param response
|
||||||
|
* @param code
|
||||||
|
* @param errorMsg
|
||||||
|
*/
|
||||||
|
public static void responseError(ServletResponse response, Integer code, String errorMsg) {
|
||||||
|
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
||||||
|
Result jsonResult = new Result(code, errorMsg);
|
||||||
|
OutputStream os = null;
|
||||||
|
try {
|
||||||
|
os = httpServletResponse.getOutputStream();
|
||||||
|
httpServletResponse.setCharacterEncoding("UTF-8");
|
||||||
|
httpServletResponse.setStatus(401);
|
||||||
|
os.write(new ObjectMapper().writeValueAsString(jsonResult).getBytes("UTF-8"));
|
||||||
|
os.flush();
|
||||||
|
os.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验token是否正确
|
* 校验token是否正确
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,26 +1,30 @@
|
||||||
package org.jeecg.common.util;
|
package org.jeecg.common.util;
|
||||||
|
|
||||||
import java.io.*;
|
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
|
||||||
import java.sql.Connection;
|
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
|
||||||
import java.sql.DatabaseMetaData;
|
import com.baomidou.mybatisplus.annotation.DbType;
|
||||||
import java.sql.SQLException;
|
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
|
||||||
import java.util.regex.Matcher;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.constant.DataBaseConstant;
|
import org.jeecg.common.constant.DataBaseConstant;
|
||||||
import org.jeecg.common.util.filter.FileTypeFilter;
|
import org.jeecg.common.util.filter.FileTypeFilter;
|
||||||
import org.jeecg.common.util.oss.OssBootUtil;
|
import org.jeecg.common.util.oss.OssBootUtil;
|
||||||
import org.jeecgframework.poi.util.PoiPublicUtil;
|
import org.jeecgframework.poi.util.PoiPublicUtil;
|
||||||
|
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.DbType;
|
import javax.sql.DataSource;
|
||||||
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.File;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class CommonUtils {
|
public class CommonUtils {
|
||||||
|
@ -207,6 +211,42 @@ public class CommonUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据数据源key获取DataSourceProperty
|
||||||
|
* @param sourceKey
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static DataSourceProperty getDataSourceProperty(String sourceKey){
|
||||||
|
DynamicDataSourceProperties prop = SpringContextUtils.getApplicationContext().getBean(DynamicDataSourceProperties.class);
|
||||||
|
Map<String, DataSourceProperty> map = prop.getDatasource();
|
||||||
|
DataSourceProperty db = (DataSourceProperty)map.get(sourceKey);
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据sourceKey 获取数据源连接
|
||||||
|
* @param sourceKey
|
||||||
|
* @return
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public static Connection getDataSourceConnect(String sourceKey) throws SQLException {
|
||||||
|
if (oConvertUtils.isEmpty(sourceKey)) {
|
||||||
|
sourceKey = "master";
|
||||||
|
}
|
||||||
|
DynamicDataSourceProperties prop = SpringContextUtils.getApplicationContext().getBean(DynamicDataSourceProperties.class);
|
||||||
|
Map<String, DataSourceProperty> map = prop.getDatasource();
|
||||||
|
DataSourceProperty db = (DataSourceProperty)map.get(sourceKey);
|
||||||
|
if(db==null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
DriverManagerDataSource ds = new DriverManagerDataSource ();
|
||||||
|
ds.setDriverClassName(db.getDriverClassName());
|
||||||
|
ds.setUrl(db.getUrl());
|
||||||
|
ds.setUsername(db.getUsername());
|
||||||
|
ds.setPassword(db.getPassword());
|
||||||
|
return ds.getConnection();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取数据库类型
|
* 获取数据库类型
|
||||||
* @param dataSource
|
* @param dataSource
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class ImportExcelUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> importDateSave(List<Object> list, Class serviceClass,List<String> errorMessage,String errorFlag) {
|
public static List<String> importDateSave(List<?> list, Class serviceClass, List<String> errorMessage, String errorFlag) {
|
||||||
IService bean =(IService) SpringContextUtils.getBean(serviceClass);
|
IService bean =(IService) SpringContextUtils.getBean(serviceClass);
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.jeecg.common.util;
|
package org.jeecg.common.util;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.jeecg.common.constant.ServiceNameConstants;
|
import org.jeecg.common.constant.ServiceNameConstants;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
|
@ -38,6 +39,12 @@ public class SpringContextUtils implements ApplicationContextAware {
|
||||||
public static HttpServletRequest getHttpServletRequest() {
|
public static HttpServletRequest getHttpServletRequest() {
|
||||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 获取HttpServletResponse
|
||||||
|
*/
|
||||||
|
public static HttpServletResponse getHttpServletResponse() {
|
||||||
|
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取项目根路径 basePath
|
* 获取项目根路径 basePath
|
||||||
|
|
|
@ -2,9 +2,9 @@ package org.jeecg.common.util;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.shiro.authc.AuthenticationException;
|
|
||||||
import org.jeecg.common.api.CommonAPI;
|
import org.jeecg.common.api.CommonAPI;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.jeecg.common.exception.JeecgBoot401Exception;
|
||||||
import org.jeecg.common.system.util.JwtUtil;
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
import org.jeecg.common.system.vo.LoginUser;
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
|
||||||
|
@ -40,27 +40,57 @@ public class TokenUtils {
|
||||||
String token = getTokenByRequest(request);
|
String token = getTokenByRequest(request);
|
||||||
|
|
||||||
if (StringUtils.isBlank(token)) {
|
if (StringUtils.isBlank(token)) {
|
||||||
throw new AuthenticationException("Token不能为空!");
|
throw new JeecgBoot401Exception("Token不能为空!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解密获得username,用于和数据库进行对比
|
// 解密获得username,用于和数据库进行对比
|
||||||
String username = JwtUtil.getUsername(token);
|
String username = JwtUtil.getUsername(token);
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
throw new AuthenticationException("Token非法无效!");
|
throw new JeecgBoot401Exception("Token非法无效!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询用户信息
|
// 查询用户信息
|
||||||
LoginUser user = commonAPI.getUserByName(username);
|
LoginUser user = commonAPI.getUserByName(username);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new AuthenticationException("用户不存在!");
|
throw new JeecgBoot401Exception("用户不存在!");
|
||||||
}
|
}
|
||||||
// 判断用户状态
|
// 判断用户状态
|
||||||
if (user.getStatus() != 1) {
|
if (user.getStatus() != 1) {
|
||||||
throw new AuthenticationException("账号已锁定,请联系管理员!");
|
throw new JeecgBoot401Exception("账号已锁定,请联系管理员!");
|
||||||
}
|
}
|
||||||
// 校验token是否超时失效 & 或者账号密码是否错误
|
// 校验token是否超时失效 & 或者账号密码是否错误
|
||||||
if (!jwtTokenRefresh(token, username, user.getPassword(), redisUtil)) {
|
if (!jwtTokenRefresh(token, username, user.getPassword(), redisUtil)) {
|
||||||
throw new AuthenticationException("Token失效,请重新登录");
|
throw new JeecgBoot401Exception("Token失效,请重新登录");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证Token
|
||||||
|
*/
|
||||||
|
public static boolean verifyToken(String token, CommonAPI commonAPI, RedisUtil redisUtil) {
|
||||||
|
if (StringUtils.isBlank(token)) {
|
||||||
|
throw new JeecgBoot401Exception("token不能为空!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解密获得username,用于和数据库进行对比
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
if (username == null) {
|
||||||
|
throw new JeecgBoot401Exception("token非法无效!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询用户信息
|
||||||
|
LoginUser user = commonAPI.getUserByName(username);
|
||||||
|
if (user == null) {
|
||||||
|
throw new JeecgBoot401Exception("用户不存在!");
|
||||||
|
}
|
||||||
|
// 判断用户状态
|
||||||
|
if (user.getStatus() != 1) {
|
||||||
|
throw new JeecgBoot401Exception("账号已被锁定,请联系管理员!");
|
||||||
|
}
|
||||||
|
// 校验token是否超时失效 & 或者账号密码是否错误
|
||||||
|
if (!jwtTokenRefresh(token, username, user.getPassword(), redisUtil)) {
|
||||||
|
throw new JeecgBoot401Exception(CommonConstant.TOKEN_IS_INVALID_MSG);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -95,34 +125,4 @@ public class TokenUtils {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证Token
|
|
||||||
*/
|
|
||||||
public static boolean verifyToken(String token, CommonAPI commonAPI, RedisUtil redisUtil) {
|
|
||||||
if (StringUtils.isBlank(token)) {
|
|
||||||
throw new AuthenticationException("token不能为空!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 解密获得username,用于和数据库进行对比
|
|
||||||
String username = JwtUtil.getUsername(token);
|
|
||||||
if (username == null) {
|
|
||||||
throw new AuthenticationException("token非法无效!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询用户信息
|
|
||||||
LoginUser user = commonAPI.getUserByName(username);
|
|
||||||
if (user == null) {
|
|
||||||
throw new AuthenticationException("用户不存在!");
|
|
||||||
}
|
|
||||||
// 判断用户状态
|
|
||||||
if (user.getStatus() != 1) {
|
|
||||||
throw new AuthenticationException("账号已被锁定,请联系管理员!");
|
|
||||||
}
|
|
||||||
// 校验token是否超时失效 & 或者账号密码是否错误
|
|
||||||
if (!jwtTokenRefresh(token, username, user.getPassword(), redisUtil)) {
|
|
||||||
throw new AuthenticationException("Token失效,请重新登录!");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package org.jeecg.common.util.dynamic.db;
|
package org.jeecg.common.util.dynamic.db;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.DbType;
|
import com.baomidou.mybatisplus.annotation.DbType;
|
||||||
|
import org.jeecg.common.constant.DataBaseConstant;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据库类型判断
|
* 数据库类型判断
|
||||||
|
@ -8,6 +12,34 @@ import com.baomidou.mybatisplus.annotation.DbType;
|
||||||
*/
|
*/
|
||||||
public class DbTypeUtils {
|
public class DbTypeUtils {
|
||||||
|
|
||||||
|
public static Map<String, String> dialectMap = new HashMap<String, String>();
|
||||||
|
static{
|
||||||
|
dialectMap.put("mysql", "org.hibernate.dialect.MySQL5InnoDBDialect");
|
||||||
|
dialectMap.put("mariadb", "org.hibernate.dialect.MariaDBDialect");// 1 --
|
||||||
|
dialectMap.put("oracle", "org.hibernate.dialect.OracleDialect");//1
|
||||||
|
dialectMap.put("oracle12c", "org.hibernate.dialect.OracleDialect"); // TODO 没找到不确定
|
||||||
|
dialectMap.put("db2", "org.hibernate.dialect.DB2390Dialect"); // 1xx
|
||||||
|
dialectMap.put("h2", "org.hibernate.dialect.HSQLDialect");// H2数据库
|
||||||
|
dialectMap.put("hsql", "org.hibernate.dialect.HSQLDialect");// HSQL数据库 1
|
||||||
|
dialectMap.put("sqlite", "org.jeecg.modules.online.config.dialect.SQLiteDialect"); //SQLite数据库 应用平台mobile
|
||||||
|
dialectMap.put("postgresql", "org.hibernate.dialect.PostgreSQLDialect"); //1 --
|
||||||
|
dialectMap.put("sqlserver2005", "org.hibernate.dialect.SQLServer2005Dialect");
|
||||||
|
dialectMap.put("sqlserver", "org.hibernate.dialect.SQLServerDialect"); //1
|
||||||
|
dialectMap.put("dm", "org.hibernate.dialect.OracleDialect");//达梦数据库 [国产] 1--
|
||||||
|
dialectMap.put("xugu", "org.hibernate.dialect.HSQLDialect"); //虚谷数据库
|
||||||
|
dialectMap.put("kingbasees", "org.hibernate.dialect.PostgreSQLDialect"); //人大金仓 [国产] 1
|
||||||
|
dialectMap.put("phoenix", "org.hibernate.dialect.HSQLDialect"); // Phoenix HBase数据库
|
||||||
|
dialectMap.put("zenith", "org.hibernate.dialect.PostgreSQLDialect"); // Gauss 数据库
|
||||||
|
dialectMap.put("clickhouse", "org.hibernate.dialect.MySQLDialect"); //阿里云PolarDB
|
||||||
|
dialectMap.put("gbase", "org.hibernate.dialect.PostgreSQLDialect"); // 南大通用数据库 TODO 没找到不确定
|
||||||
|
dialectMap.put("oscar", "org.hibernate.dialect.PostgreSQLDialect"); //神通数据库 [国产] TODO 没找到不确定
|
||||||
|
dialectMap.put("sybase", "org.hibernate.dialect.SybaseDialect"); //Sybase ASE 数据库
|
||||||
|
dialectMap.put("oceanbase", "org.hibernate.dialect.PostgreSQLDialect"); //OceanBase 数据库 TODO 没找到不确定
|
||||||
|
dialectMap.put("Firebird", "org.hibernate.dialect.FirebirdDialect");
|
||||||
|
dialectMap.put("highgo", "org.hibernate.dialect.HSQLDialect"); //瀚高数据库
|
||||||
|
dialectMap.put("other", "org.hibernate.dialect.PostgreSQLDialect");
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean dbTypeIsMySQL(DbType dbType) {
|
public static boolean dbTypeIsMySQL(DbType dbType) {
|
||||||
return dbTypeIf(dbType, DbType.MYSQL, DbType.MARIADB, DbType.CLICK_HOUSE, DbType.SQLITE);
|
return dbTypeIf(dbType, DbType.MYSQL, DbType.MARIADB, DbType.CLICK_HOUSE, DbType.SQLITE);
|
||||||
}
|
}
|
||||||
|
@ -24,6 +56,37 @@ public class DbTypeUtils {
|
||||||
return dbTypeIf(dbType, DbType.POSTGRE_SQL, DbType.KINGBASE_ES, DbType.GAUSS);
|
return dbTypeIf(dbType, DbType.POSTGRE_SQL, DbType.KINGBASE_ES, DbType.GAUSS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据枚举类 获取数据库类型的字符串
|
||||||
|
* @param dbType
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getDbTypeString(DbType dbType){
|
||||||
|
if(DbType.DB2.equals(dbType)){
|
||||||
|
return DataBaseConstant.DB_TYPE_DB2;
|
||||||
|
}else if(DbType.HSQL.equals(dbType)){
|
||||||
|
return DataBaseConstant.DB_TYPE_HSQL;
|
||||||
|
}else if(dbTypeIsOracle(dbType)){
|
||||||
|
return DataBaseConstant.DB_TYPE_ORACLE;
|
||||||
|
}else if(dbTypeIsSQLServer(dbType)){
|
||||||
|
return DataBaseConstant.DB_TYPE_SQLSERVER;
|
||||||
|
}else if(dbTypeIsPostgre(dbType)){
|
||||||
|
return DataBaseConstant.DB_TYPE_POSTGRESQL;
|
||||||
|
}
|
||||||
|
return DataBaseConstant.DB_TYPE_MYSQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据枚举类 获取数据库方言字符串
|
||||||
|
* @param dbType
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getDbDialect(DbType dbType){
|
||||||
|
return dialectMap.get(dbType.getDb());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断数据库类型
|
* 判断数据库类型
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -111,6 +111,16 @@ public class DynamicDBUtil {
|
||||||
return new JdbcTemplate(dataSource);
|
return new JdbcTemplate(dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据数据源获取NamedParameterJdbcTemplate
|
||||||
|
* @param dbKey
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static NamedParameterJdbcTemplate getNamedParameterJdbcTemplate(String dbKey) {
|
||||||
|
DruidDataSource dataSource = getDbSourceByDbKey(dbKey);
|
||||||
|
return new NamedParameterJdbcTemplate(dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the SQL statement in this <code>PreparedStatement</code> object,
|
* Executes the SQL statement in this <code>PreparedStatement</code> object,
|
||||||
* which must be an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
|
* which must be an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
|
||||||
|
@ -221,6 +231,31 @@ public class DynamicDBUtil {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询数量
|
||||||
|
* @param dbKey
|
||||||
|
* @param sql
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> queryCount(String dbKey, String sql, Map<String, Object> param){
|
||||||
|
NamedParameterJdbcTemplate npJdbcTemplate = getNamedParameterJdbcTemplate(dbKey);
|
||||||
|
return npJdbcTemplate.queryForMap(sql, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询列表数据
|
||||||
|
* @param dbKey
|
||||||
|
* @param sql
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<Map<String, Object>> findListByNamedParam(final String dbKey, String sql, Map<String, Object> param) {
|
||||||
|
NamedParameterJdbcTemplate npJdbcTemplate = getNamedParameterJdbcTemplate(dbKey);
|
||||||
|
List<Map<String, Object>> list = npJdbcTemplate.queryForList(sql, param);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支持miniDao语法操作的查询
|
* 支持miniDao语法操作的查询
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package org.jeecg.config;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载项目配置
|
||||||
|
*/
|
||||||
|
@Component("jeeccgBaseConfig")
|
||||||
|
@ConfigurationProperties(prefix = "jeecg")
|
||||||
|
public class JeeccgBaseConfig {
|
||||||
|
/**
|
||||||
|
* 是否启用安全模式
|
||||||
|
*/
|
||||||
|
private Boolean safeMode = false;
|
||||||
|
|
||||||
|
public Boolean getSafeMode() {
|
||||||
|
return safeMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSafeMode(Boolean safeMode) {
|
||||||
|
this.safeMode = safeMode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,6 +35,11 @@ public class MybatisPlusSaasConfig {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
tenantTable.add("demo");
|
tenantTable.add("demo");
|
||||||
|
|
||||||
|
// //角色、菜单、部门
|
||||||
|
// tenantTable.add("sys_role");
|
||||||
|
// tenantTable.add("sys_permission");
|
||||||
|
// tenantTable.add("sys_depart");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -118,8 +118,12 @@ public class ShiroConfig {
|
||||||
filterChainDefinitionMap.put("/jmreport/**", "anon");
|
filterChainDefinitionMap.put("/jmreport/**", "anon");
|
||||||
filterChainDefinitionMap.put("/**/*.js.map", "anon");
|
filterChainDefinitionMap.put("/**/*.js.map", "anon");
|
||||||
filterChainDefinitionMap.put("/**/*.css.map", "anon");
|
filterChainDefinitionMap.put("/**/*.css.map", "anon");
|
||||||
//大屏模板例子
|
|
||||||
filterChainDefinitionMap.put("/test/bigScreen/**", "anon");
|
//测试示例
|
||||||
|
filterChainDefinitionMap.put("/test/bigScreen/**", "anon"); //大屏模板例子
|
||||||
|
//filterChainDefinitionMap.put("/test/jeecgDemo/rabbitMqClientTest/**", "anon"); //MQ测试
|
||||||
|
//filterChainDefinitionMap.put("/test/jeecgDemo/html", "anon"); //模板页面
|
||||||
|
//filterChainDefinitionMap.put("/test/jeecgDemo/redis/**", "anon"); //redis测试
|
||||||
|
|
||||||
//websocket排除
|
//websocket排除
|
||||||
filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告
|
filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.jeecg.config.shiro;
|
package org.jeecg.config.shiro;
|
||||||
|
|
||||||
import cn.hutool.crypto.SecureUtil;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.shiro.authc.AuthenticationException;
|
import org.apache.shiro.authc.AuthenticationException;
|
||||||
import org.apache.shiro.authc.AuthenticationInfo;
|
import org.apache.shiro.authc.AuthenticationInfo;
|
||||||
|
@ -11,7 +10,6 @@ import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
||||||
import org.apache.shiro.realm.AuthorizingRealm;
|
import org.apache.shiro.realm.AuthorizingRealm;
|
||||||
import org.apache.shiro.subject.PrincipalCollection;
|
import org.apache.shiro.subject.PrincipalCollection;
|
||||||
import org.jeecg.common.api.CommonAPI;
|
import org.jeecg.common.api.CommonAPI;
|
||||||
import org.jeecg.common.constant.CacheConstant;
|
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.system.util.JwtUtil;
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
import org.jeecg.common.system.vo.LoginUser;
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
@ -97,7 +95,14 @@ public class ShiroRealm extends AuthorizingRealm {
|
||||||
throw new AuthenticationException("token为空!");
|
throw new AuthenticationException("token为空!");
|
||||||
}
|
}
|
||||||
// 校验token有效性
|
// 校验token有效性
|
||||||
LoginUser loginUser = this.checkUserTokenIsEffect(token);
|
LoginUser loginUser = null;
|
||||||
|
try {
|
||||||
|
loginUser = this.checkUserTokenIsEffect(token);
|
||||||
|
} catch (AuthenticationException e) {
|
||||||
|
JwtUtil.responseError(SpringContextUtils.getHttpServletResponse(),401,e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return new SimpleAuthenticationInfo(loginUser, token, getName());
|
return new SimpleAuthenticationInfo(loginUser, token, getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +130,7 @@ public class ShiroRealm extends AuthorizingRealm {
|
||||||
}
|
}
|
||||||
// 校验token是否超时失效 & 或者账号密码是否错误
|
// 校验token是否超时失效 & 或者账号密码是否错误
|
||||||
if (!jwtTokenRefresh(token, username, loginUser.getPassword())) {
|
if (!jwtTokenRefresh(token, username, loginUser.getPassword())) {
|
||||||
throw new AuthenticationException("Token失效,请重新登录!");
|
throw new AuthenticationException(CommonConstant.TOKEN_IS_INVALID_MSG);
|
||||||
}
|
}
|
||||||
//update-begin-author:taoyan date:20210609 for:校验用户的tenant_id和前端传过来的是否一致
|
//update-begin-author:taoyan date:20210609 for:校验用户的tenant_id和前端传过来的是否一致
|
||||||
String userTenantIds = loginUser.getRelTenantIds();
|
String userTenantIds = loginUser.getRelTenantIds();
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package org.jeecg.config.shiro.filters;
|
package org.jeecg.config.shiro.filters;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.shiro.authc.AuthenticationException;
|
|
||||||
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
|
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.jeecg.config.mybatis.TenantContext;
|
import org.jeecg.config.mybatis.TenantContext;
|
||||||
import org.jeecg.config.shiro.JwtToken;
|
import org.jeecg.config.shiro.JwtToken;
|
||||||
|
@ -48,7 +48,9 @@ public class JwtFilter extends BasicHttpAuthenticationFilter {
|
||||||
executeLogin(request, response);
|
executeLogin(request, response);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new AuthenticationException("Token失效,请重新登录", e);
|
JwtUtil.responseError(response,401,CommonConstant.TOKEN_IS_INVALID_MSG);
|
||||||
|
return false;
|
||||||
|
//throw new AuthenticationException("Token失效,请重新登录", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<artifactId>jeecg-boot-base</artifactId>
|
<artifactId>jeecg-boot-base</artifactId>
|
||||||
<version>2.4.6</version>
|
<version>3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<description>公共模块</description>
|
<description>公共模块</description>
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package org.jeecg.common.config.mqtoken;
|
package org.jeecg.common.config.mqtoken;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.servlet.*;
|
import javax.servlet.*;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存放token到上下文供队列调用feign使用
|
* 存放token到上下文供队列调用feign使用
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>jeecg-boot-parent</artifactId>
|
<artifactId>jeecg-boot-parent</artifactId>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<version>2.4.6</version>
|
<version>3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>jeecg-boot-parent</artifactId>
|
<artifactId>jeecg-boot-parent</artifactId>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<version>2.4.6</version>
|
<version>3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
package org.jeecg.modules.demo.mock;
|
package org.jeecg.modules.demo.mock;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.swing.filechooser.FileSystemView;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -8,20 +17,6 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.swing.filechooser.FileSystemView;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.jeecg.common.api.vo.Result;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/mock/api")
|
@RequestMapping("/mock/api")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -42,8 +37,9 @@ public class MockController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/asynTreeList")
|
@GetMapping(value = "/asynTreeList")
|
||||||
public String asynTreeList(String id) {
|
public Result asynTreeList(String id) {
|
||||||
return readJson(JSON_PATH + "/asyn_tree_list_" + id + ".json");
|
String json = readJson(JSON_PATH + "/asyn_tree_list_" + id + ".json");
|
||||||
|
return Result.OK(JSON.parseArray(json));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/user")
|
@GetMapping(value = "/user")
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
{
|
[
|
||||||
"status": 200,
|
|
||||||
"success": true,
|
|
||||||
"message": "ok",
|
|
||||||
"result": [
|
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"name": "首页",
|
"name": "首页",
|
||||||
|
@ -24,6 +20,4 @@
|
||||||
"orderNum": 3,
|
"orderNum": 3,
|
||||||
"hasChildren": true
|
"hasChildren": true
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"timestamp": 1554950583837
|
|
||||||
}
|
|
|
@ -1,8 +1,4 @@
|
||||||
{
|
[
|
||||||
"status": 200,
|
|
||||||
"success": true,
|
|
||||||
"message": "ok",
|
|
||||||
"result": [
|
|
||||||
{
|
{
|
||||||
"id": 11,
|
"id": 11,
|
||||||
"name": "首页",
|
"name": "首页",
|
||||||
|
@ -24,6 +20,4 @@
|
||||||
"orderNum": 3,
|
"orderNum": 3,
|
||||||
"hasChildren": true
|
"hasChildren": true
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"timestamp": 1554950583837
|
|
||||||
}
|
|
|
@ -1,8 +1,4 @@
|
||||||
{
|
[
|
||||||
"status": 200,
|
|
||||||
"success": true,
|
|
||||||
"message": "ok",
|
|
||||||
"result": [
|
|
||||||
{
|
{
|
||||||
"id": 21,
|
"id": 21,
|
||||||
"name": "弹框选择Demo",
|
"name": "弹框选择Demo",
|
||||||
|
@ -24,6 +20,4 @@
|
||||||
"orderNum": 3,
|
"orderNum": 3,
|
||||||
"hasChildren": false
|
"hasChildren": false
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"timestamp": 1554950583837
|
|
||||||
}
|
|
|
@ -1,8 +1,4 @@
|
||||||
{
|
[
|
||||||
"status": 200,
|
|
||||||
"success": true,
|
|
||||||
"message": "ok",
|
|
||||||
"result": [
|
|
||||||
{
|
{
|
||||||
"id": 31,
|
"id": 31,
|
||||||
"name": "性能监控",
|
"name": "性能监控",
|
||||||
|
@ -24,6 +20,4 @@
|
||||||
"orderNum": 3,
|
"orderNum": 3,
|
||||||
"hasChildren": false
|
"hasChildren": false
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"timestamp": 1554950583837
|
|
||||||
}
|
|
|
@ -1,8 +1,4 @@
|
||||||
{
|
[
|
||||||
"status": 200,
|
|
||||||
"success": true,
|
|
||||||
"message": "ok",
|
|
||||||
"result": [
|
|
||||||
{
|
{
|
||||||
"id": 311,
|
"id": 311,
|
||||||
"name": "Redis监控",
|
"name": "Redis监控",
|
||||||
|
@ -24,6 +20,4 @@
|
||||||
"orderNum": 3,
|
"orderNum": 3,
|
||||||
"hasChildren": false
|
"hasChildren": false
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"timestamp": 1554950583837
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.jeecg.modules.demo.test.controller;
|
package org.jeecg.modules.demo.test.controller;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
@ -282,4 +283,38 @@ public class JeecgDemoController extends JeecgController<JeecgDemo, IJeecgDemoSe
|
||||||
return Result.OK(pageList);
|
return Result.OK(pageList);
|
||||||
}
|
}
|
||||||
/*----------------------------------------外部获取权限示例------------------------------------*/
|
/*----------------------------------------外部获取权限示例------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* online api增强 列表
|
||||||
|
* @param params
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/enhanceJavaListHttp")
|
||||||
|
public Result enhanceJavaListHttp(@RequestBody JSONObject params) {
|
||||||
|
log.info(" =========================================================== ");
|
||||||
|
log.info("params: " + params.toJSONString());
|
||||||
|
log.info("params.tableName: " + params.getString("tableName"));
|
||||||
|
log.info("params.json: " + params.getJSONObject("json").toJSONString());
|
||||||
|
JSONArray dataList = params.getJSONArray("dataList");
|
||||||
|
log.info("params.dataList: " + dataList.toJSONString());
|
||||||
|
log.info(" =========================================================== ");
|
||||||
|
return Result.OK(dataList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* online api增强 表单
|
||||||
|
* @param params
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/enhanceJavaFormHttp")
|
||||||
|
public Result enhanceJavaFormHttp(@RequestBody JSONObject params) {
|
||||||
|
log.info(" =========================================================== ");
|
||||||
|
log.info("params: " + params.toJSONString());
|
||||||
|
log.info("params.tableName: " + params.getString("tableName"));
|
||||||
|
log.info("params.json: " + params.getJSONObject("json").toJSONString());
|
||||||
|
log.info(" =========================================================== ");
|
||||||
|
return Result.OK("1");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,6 @@ import lombok.experimental.Accessors;
|
||||||
@TableName("demo")
|
@TableName("demo")
|
||||||
public class JeecgDemo extends JeecgEntity implements Serializable {
|
public class JeecgDemo extends JeecgEntity implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
/** 部门编码 */
|
|
||||||
@Excel(name="部门编码",width=25)
|
|
||||||
@ApiModelProperty(value = "部门编码")
|
|
||||||
private java.lang.String sysOrgCode;
|
|
||||||
/** 姓名 */
|
/** 姓名 */
|
||||||
@Excel(name="姓名",width=25)
|
@Excel(name="姓名",width=25)
|
||||||
@ApiModelProperty(value = "姓名")
|
@ApiModelProperty(value = "姓名")
|
||||||
|
@ -75,7 +71,10 @@ public class JeecgDemo extends JeecgEntity implements Serializable {
|
||||||
/** 个人简介 */
|
/** 个人简介 */
|
||||||
@ApiModelProperty(value = "个人简介")
|
@ApiModelProperty(value = "个人简介")
|
||||||
private java.lang.String content;
|
private java.lang.String content;
|
||||||
|
|
||||||
@ApiModelProperty(value = "租户ID")
|
@ApiModelProperty(value = "租户ID")
|
||||||
private java.lang.Integer tenantId;
|
private java.lang.Integer tenantId;
|
||||||
|
/** 部门编码 */
|
||||||
|
@Excel(name="部门编码",width=25)
|
||||||
|
@ApiModelProperty(value = "部门编码")
|
||||||
|
private java.lang.String sysOrgCode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,6 @@ WORKDIR /jeecg-boot
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
ADD ./target/jeecg-boot-module-system-2.4.6.jar ./
|
ADD ./target/jeecg-boot-module-system-3.0.jar ./
|
||||||
|
|
||||||
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-2.4.6.jar
|
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-3.0.jar
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<artifactId>jeecg-boot-parent</artifactId>
|
<artifactId>jeecg-boot-parent</artifactId>
|
||||||
<version>2.4.6</version>
|
<version>3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jeecgframework.jimureport</groupId>
|
<groupId>org.jeecgframework.jimureport</groupId>
|
||||||
<artifactId>jimureport-spring-boot-starter</artifactId>
|
<artifactId>jimureport-spring-boot-starter</artifactId>
|
||||||
<version>1.3.78</version>
|
<version>1.4.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<artifactId>jeecg-boot-module-demo</artifactId>
|
<artifactId>jeecg-boot-module-demo</artifactId>
|
||||||
<version>2.4.6</version>
|
<version>3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
|
@ -1,17 +1,12 @@
|
||||||
package org.jeecg;
|
package org.jeecg;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.catalina.Context;
|
|
||||||
import org.apache.tomcat.util.scan.StandardJarScanner;
|
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
//import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
|
||||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
|
|
@ -80,8 +80,12 @@ public class WebSocket {
|
||||||
Session session = sessionPool.get(userId);
|
Session session = sessionPool.get(userId);
|
||||||
if (session != null && session.isOpen()) {
|
if (session != null && session.isOpen()) {
|
||||||
try {
|
try {
|
||||||
|
//update-begin-author:taoyan date:20211012 for: websocket报错 https://gitee.com/jeecg/jeecg-boot/issues/I4C0MU
|
||||||
|
synchronized (session){
|
||||||
log.info("【websocket消息】 单点消息:" + message);
|
log.info("【websocket消息】 单点消息:" + message);
|
||||||
session.getAsyncRemote().sendText(message);
|
session.getBasicRemote().sendText(message);
|
||||||
|
}
|
||||||
|
//update-end-author:taoyan date:20211012 for: websocket报错 https://gitee.com/jeecg/jeecg-boot/issues/I4C0MU
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,6 @@ package org.jeecg.modules.oss.controller;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.system.query.QueryGenerator;
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
@ -13,14 +9,18 @@ import org.jeecg.modules.oss.entity.OSSFile;
|
||||||
import org.jeecg.modules.oss.service.IOSSFileService;
|
import org.jeecg.modules.oss.service.IOSSFileService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云存储示例 DEMO
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/sys/oss/file")
|
@RequestMapping("/sys/oss/file")
|
||||||
|
|
|
@ -89,7 +89,7 @@ public class QuartzJobController {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
//@RequiresRoles("admin")
|
//@RequiresRoles("admin")
|
||||||
@RequestMapping(value = "/edit", method = RequestMethod.PUT)
|
@RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST})
|
||||||
public Result<?> eidt(@RequestBody QuartzJob quartzJob) {
|
public Result<?> eidt(@RequestBody QuartzJob quartzJob) {
|
||||||
try {
|
try {
|
||||||
quartzJobService.editAndScheduleJob(quartzJob);
|
quartzJobService.editAndScheduleJob(quartzJob);
|
||||||
|
@ -228,8 +228,13 @@ public class QuartzJobController {
|
||||||
params.setHeadRows(1);
|
params.setHeadRows(1);
|
||||||
params.setNeedSave(true);
|
params.setNeedSave(true);
|
||||||
try {
|
try {
|
||||||
List<Object> listQuartzJobs = ExcelImportUtil.importExcel(file.getInputStream(), QuartzJob.class, params);
|
List<QuartzJob> listQuartzJobs = ExcelImportUtil.importExcel(file.getInputStream(), QuartzJob.class, params);
|
||||||
|
//add-begin-author:taoyan date:20210909 for:导入定时任务,并不会被启动和调度,需要手动点击启动,才会加入调度任务中 #2986
|
||||||
|
for(QuartzJob job: listQuartzJobs){
|
||||||
|
job.setStatus(CommonConstant.STATUS_DISABLE);
|
||||||
|
}
|
||||||
List<String> list = ImportExcelUtil.importDateSave(listQuartzJobs, IQuartzJobService.class, errorMessage,CommonConstant.SQL_INDEX_UNIQ_JOB_CLASS_NAME);
|
List<String> list = ImportExcelUtil.importDateSave(listQuartzJobs, IQuartzJobService.class, errorMessage,CommonConstant.SQL_INDEX_UNIQ_JOB_CLASS_NAME);
|
||||||
|
//add-end-author:taoyan date:20210909 for:导入定时任务,并不会被启动和调度,需要手动点击启动,才会加入调度任务中 #2986
|
||||||
errorLines+=list.size();
|
errorLines+=list.size();
|
||||||
successLines+=(listQuartzJobs.size()-errorLines);
|
successLines+=(listQuartzJobs.size()-errorLines);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -118,6 +118,30 @@ public class LoginController {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【vue3专用】获取用户信息
|
||||||
|
*/
|
||||||
|
@GetMapping("/user/getUserInfo")
|
||||||
|
public Result<JSONObject> getUserInfo(HttpServletRequest request){
|
||||||
|
Result<JSONObject> result = new Result<JSONObject>();
|
||||||
|
String username = JwtUtil.getUserNameByToken(request);
|
||||||
|
if(oConvertUtils.isNotEmpty(username)) {
|
||||||
|
// 根据用户名查询用户信息
|
||||||
|
SysUser sysUser = sysUserService.getUserByName(username);
|
||||||
|
//用户登录信息
|
||||||
|
Result<JSONObject> resultObj=userInfo(sysUser, result);
|
||||||
|
JSONObject jsonObject=resultObj.getResult();
|
||||||
|
JSONObject obj=new JSONObject();
|
||||||
|
obj.put("userInfo",jsonObject.get("userInfo"));
|
||||||
|
obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
|
||||||
|
result.setResult(obj);
|
||||||
|
result.success("");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 退出登录
|
* 退出登录
|
||||||
* @param request
|
* @param request
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package org.jeecg.modules.system.controller;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vue3前端临时接口
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/")
|
||||||
|
@Slf4j
|
||||||
|
public class MockVue3Controller {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -140,7 +140,7 @@ public class SysAnnouncementController {
|
||||||
* @param sysAnnouncement
|
* @param sysAnnouncement
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/edit", method = RequestMethod.PUT)
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
public Result<SysAnnouncement> eidt(@RequestBody SysAnnouncement sysAnnouncement) {
|
public Result<SysAnnouncement> eidt(@RequestBody SysAnnouncement sysAnnouncement) {
|
||||||
Result<SysAnnouncement> result = new Result<SysAnnouncement>();
|
Result<SysAnnouncement> result = new Result<SysAnnouncement>();
|
||||||
SysAnnouncement sysAnnouncementEntity = sysAnnouncementService.getById(sysAnnouncement.getId());
|
SysAnnouncement sysAnnouncementEntity = sysAnnouncementService.getById(sysAnnouncement.getId());
|
||||||
|
@ -314,7 +314,7 @@ public class SysAnnouncementController {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/listByUser", method = RequestMethod.GET)
|
@RequestMapping(value = "/listByUser", method = RequestMethod.GET)
|
||||||
public Result<Map<String,Object>> listByUser() {
|
public Result<Map<String, Object>> listByUser(@RequestParam(required = false, defaultValue = "5") Integer pageSize) {
|
||||||
Result<Map<String,Object>> result = new Result<Map<String,Object>>();
|
Result<Map<String,Object>> result = new Result<Map<String,Object>>();
|
||||||
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
|
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
|
||||||
String userId = sysUser.getId();
|
String userId = sysUser.getId();
|
||||||
|
@ -347,9 +347,9 @@ public class SysAnnouncementController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 2.查询用户未读的系统消息
|
// 2.查询用户未读的系统消息
|
||||||
Page<SysAnnouncement> anntMsgList = new Page<SysAnnouncement>(0,5);
|
Page<SysAnnouncement> anntMsgList = new Page<SysAnnouncement>(0, pageSize);
|
||||||
anntMsgList = sysAnnouncementService.querySysCementPageByUserId(anntMsgList,userId,"1");//通知公告消息
|
anntMsgList = sysAnnouncementService.querySysCementPageByUserId(anntMsgList,userId,"1");//通知公告消息
|
||||||
Page<SysAnnouncement> sysMsgList = new Page<SysAnnouncement>(0,5);
|
Page<SysAnnouncement> sysMsgList = new Page<SysAnnouncement>(0, pageSize);
|
||||||
sysMsgList = sysAnnouncementService.querySysCementPageByUserId(sysMsgList,userId,"2");//系统消息
|
sysMsgList = sysAnnouncementService.querySysCementPageByUserId(sysMsgList,userId,"2");//系统消息
|
||||||
Map<String,Object> sysMsgMap = new HashMap<String, Object>();
|
Map<String,Object> sysMsgMap = new HashMap<String, Object>();
|
||||||
sysMsgMap.put("sysMsgList", sysMsgList.getRecords());
|
sysMsgMap.put("sysMsgList", sysMsgList.getRecords());
|
||||||
|
|
|
@ -8,8 +8,10 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.jeecg.common.constant.WebsocketConst;
|
||||||
import org.jeecg.common.system.vo.LoginUser;
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.message.websocket.WebSocket;
|
||||||
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
||||||
import org.jeecg.modules.system.model.AnnouncementSendModel;
|
import org.jeecg.modules.system.model.AnnouncementSendModel;
|
||||||
import org.jeecg.modules.system.service.ISysAnnouncementSendService;
|
import org.jeecg.modules.system.service.ISysAnnouncementSendService;
|
||||||
|
@ -45,6 +47,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
public class SysAnnouncementSendController {
|
public class SysAnnouncementSendController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysAnnouncementSendService sysAnnouncementSendService;
|
private ISysAnnouncementSendService sysAnnouncementSendService;
|
||||||
|
@Autowired
|
||||||
|
private WebSocket webSocket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页列表查询
|
* 分页列表查询
|
||||||
|
@ -235,6 +239,9 @@ public class SysAnnouncementSendController {
|
||||||
updateWrapper.last("where user_id ='"+userId+"'");
|
updateWrapper.last("where user_id ='"+userId+"'");
|
||||||
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
|
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
|
||||||
sysAnnouncementSendService.update(announcementSend, updateWrapper);
|
sysAnnouncementSendService.update(announcementSend, updateWrapper);
|
||||||
|
JSONObject socketParams = new JSONObject();
|
||||||
|
socketParams.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_TOPIC);
|
||||||
|
webSocket.sendMessage(socketParams.toJSONString());
|
||||||
result.setSuccess(true);
|
result.setSuccess(true);
|
||||||
result.setMessage("全部已读");
|
result.setMessage("全部已读");
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -111,7 +111,7 @@ public class SysCategoryController {
|
||||||
* @param sysCategory
|
* @param sysCategory
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@PutMapping(value = "/edit")
|
@RequestMapping(value = "/edit", method = { RequestMethod.PUT,RequestMethod.POST })
|
||||||
public Result<SysCategory> edit(@RequestBody SysCategory sysCategory) {
|
public Result<SysCategory> edit(@RequestBody SysCategory sysCategory) {
|
||||||
Result<SysCategory> result = new Result<SysCategory>();
|
Result<SysCategory> result = new Result<SysCategory>();
|
||||||
SysCategory sysCategoryEntity = sysCategoryService.getById(sysCategory.getId());
|
SysCategory sysCategoryEntity = sysCategoryService.getById(sysCategory.getId());
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class SysDataSourceController extends JeecgController<SysDataSource, ISys
|
||||||
*/
|
*/
|
||||||
@AutoLog(value = "多数据源管理-编辑")
|
@AutoLog(value = "多数据源管理-编辑")
|
||||||
@ApiOperation(value = "多数据源管理-编辑", notes = "多数据源管理-编辑")
|
@ApiOperation(value = "多数据源管理-编辑", notes = "多数据源管理-编辑")
|
||||||
@PutMapping(value = "/edit")
|
@RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST})
|
||||||
public Result<?> edit(@RequestBody SysDataSource sysDataSource) {
|
public Result<?> edit(@RequestBody SysDataSource sysDataSource) {
|
||||||
try {
|
try {
|
||||||
SysDataSource d = sysDataSourceService.getById(sysDataSource.getId());
|
SysDataSource d = sysDataSourceService.getById(sysDataSource.getId());
|
||||||
|
|
|
@ -97,7 +97,7 @@ public class SysDepartController {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/queryTreeList", method = RequestMethod.GET)
|
@RequestMapping(value = "/queryTreeList", method = RequestMethod.GET)
|
||||||
public Result<List<SysDepartTreeModel>> queryTreeList() {
|
public Result<List<SysDepartTreeModel>> queryTreeList(@RequestParam(name = "ids", required = false) String ids) {
|
||||||
Result<List<SysDepartTreeModel>> result = new Result<>();
|
Result<List<SysDepartTreeModel>> result = new Result<>();
|
||||||
try {
|
try {
|
||||||
// 从内存中读取
|
// 从内存中读取
|
||||||
|
@ -105,8 +105,13 @@ public class SysDepartController {
|
||||||
// if (CollectionUtils.isEmpty(list)) {
|
// if (CollectionUtils.isEmpty(list)) {
|
||||||
// list = sysDepartService.queryTreeList();
|
// list = sysDepartService.queryTreeList();
|
||||||
// }
|
// }
|
||||||
|
if(oConvertUtils.isNotEmpty(ids)){
|
||||||
|
List<SysDepartTreeModel> departList = sysDepartService.queryTreeList(ids);
|
||||||
|
result.setResult(departList);
|
||||||
|
}else{
|
||||||
List<SysDepartTreeModel> list = sysDepartService.queryTreeList();
|
List<SysDepartTreeModel> list = sysDepartService.queryTreeList();
|
||||||
result.setResult(list);
|
result.setResult(list);
|
||||||
|
}
|
||||||
result.setSuccess(true);
|
result.setSuccess(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(),e);
|
log.error(e.getMessage(),e);
|
||||||
|
@ -116,14 +121,15 @@ public class SysDepartController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异步查询部门list
|
* 异步查询部门list
|
||||||
*
|
* @param parentId 父节点 异步加载时传递
|
||||||
|
* @param ids 前端回显是传递
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/queryDepartTreeSync", method = RequestMethod.GET)
|
@RequestMapping(value = "/queryDepartTreeSync", method = RequestMethod.GET)
|
||||||
public Result<List<SysDepartTreeModel>> queryDepartTreeSync(@RequestParam(name = "pid", required = false) String parentId) {
|
public Result<List<SysDepartTreeModel>> queryDepartTreeSync(@RequestParam(name = "pid", required = false) String parentId,@RequestParam(name = "ids", required = false) String ids) {
|
||||||
Result<List<SysDepartTreeModel>> result = new Result<>();
|
Result<List<SysDepartTreeModel>> result = new Result<>();
|
||||||
try {
|
try {
|
||||||
List<SysDepartTreeModel> list = sysDepartService.queryTreeListByPid(parentId);
|
List<SysDepartTreeModel> list = sysDepartService.queryTreeListByPid(parentId,ids);
|
||||||
result.setResult(list);
|
result.setResult(list);
|
||||||
result.setSuccess(true);
|
result.setSuccess(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -359,7 +359,7 @@ public class SysDictController {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
//@RequiresRoles({"admin"})
|
//@RequiresRoles({"admin"})
|
||||||
@RequestMapping(value = "/edit", method = RequestMethod.PUT)
|
@RequestMapping(value = "/edit", method = { RequestMethod.PUT,RequestMethod.POST })
|
||||||
public Result<SysDict> edit(@RequestBody SysDict sysDict) {
|
public Result<SysDict> edit(@RequestBody SysDict sysDict) {
|
||||||
Result<SysDict> result = new Result<SysDict>();
|
Result<SysDict> result = new Result<SysDict>();
|
||||||
SysDict sysdict = sysDictService.getById(sysDict.getId());
|
SysDict sysdict = sysDictService.getById(sysDict.getId());
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class SysDictItemController {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
//@RequiresRoles({"admin"})
|
//@RequiresRoles({"admin"})
|
||||||
@RequestMapping(value = "/edit", method = RequestMethod.PUT)
|
@RequestMapping(value = "/edit", method = { RequestMethod.PUT,RequestMethod.POST })
|
||||||
@CacheEvict(value={CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true)
|
@CacheEvict(value={CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true)
|
||||||
public Result<SysDictItem> edit(@RequestBody SysDictItem sysDictItem) {
|
public Result<SysDictItem> edit(@RequestBody SysDictItem sysDictItem) {
|
||||||
Result<SysDictItem> result = new Result<SysDictItem>();
|
Result<SysDictItem> result = new Result<SysDictItem>();
|
||||||
|
|
|
@ -14,16 +14,13 @@ import org.jeecg.common.constant.enums.RoleIndexConfigEnum;
|
||||||
import org.jeecg.common.system.vo.LoginUser;
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
import org.jeecg.common.util.MD5Util;
|
import org.jeecg.common.util.MD5Util;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.jeecg.modules.system.entity.SysDepartPermission;
|
import org.jeecg.config.JeeccgBaseConfig;
|
||||||
import org.jeecg.modules.system.entity.SysPermission;
|
import org.jeecg.modules.system.entity.*;
|
||||||
import org.jeecg.modules.system.entity.SysPermissionDataRule;
|
|
||||||
import org.jeecg.modules.system.entity.SysRolePermission;
|
|
||||||
import org.jeecg.modules.system.model.SysPermissionTree;
|
import org.jeecg.modules.system.model.SysPermissionTree;
|
||||||
import org.jeecg.modules.system.model.TreeModel;
|
import org.jeecg.modules.system.model.TreeModel;
|
||||||
import org.jeecg.modules.system.service.*;
|
import org.jeecg.modules.system.service.*;
|
||||||
import org.jeecg.modules.system.util.PermissionDataUtil;
|
import org.jeecg.modules.system.util.PermissionDataUtil;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -56,12 +53,9 @@ public class SysPermissionController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysUserService sysUserService;
|
private ISysUserService sysUserService;
|
||||||
/**
|
|
||||||
* 系统安全模式(true开启,false关闭)
|
|
||||||
*/
|
|
||||||
@Value(value = "${jeecg.safeMode:false}")
|
|
||||||
private Boolean sysSafeMode;
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private JeeccgBaseConfig jeeccgBaseConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载数据节点
|
* 加载数据节点
|
||||||
|
@ -238,6 +232,9 @@ public class SysPermissionController {
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
JSONArray menujsonArray = new JSONArray();
|
JSONArray menujsonArray = new JSONArray();
|
||||||
this.getPermissionJsonArray(menujsonArray, metaList, null);
|
this.getPermissionJsonArray(menujsonArray, metaList, null);
|
||||||
|
//一级菜单下的子菜单全部是隐藏路由,则一级菜单不显示
|
||||||
|
this.handleFirstLevelMenuHidden(menujsonArray);
|
||||||
|
|
||||||
JSONArray authjsonArray = new JSONArray();
|
JSONArray authjsonArray = new JSONArray();
|
||||||
this.getAuthJsonArray(authjsonArray, metaList);
|
this.getAuthJsonArray(authjsonArray, metaList);
|
||||||
//查询所有的权限
|
//查询所有的权限
|
||||||
|
@ -254,9 +251,37 @@ public class SysPermissionController {
|
||||||
json.put("auth", authjsonArray);
|
json.put("auth", authjsonArray);
|
||||||
//全部权限配置集合(按钮权限,访问权限)
|
//全部权限配置集合(按钮权限,访问权限)
|
||||||
json.put("allAuth", allauthjsonArray);
|
json.put("allAuth", allauthjsonArray);
|
||||||
json.put("sysSafeMode", sysSafeMode);
|
json.put("sysSafeMode", jeeccgBaseConfig.getSafeMode());
|
||||||
result.setResult(json);
|
result.setResult(json);
|
||||||
result.success("查询成功");
|
} catch (Exception e) {
|
||||||
|
result.error500("查询失败:" + e.getMessage());
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【vue3专用】查询用户拥有的按钮/表单访问权限
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequestMapping(value = "/getPermCode", method = RequestMethod.GET)
|
||||||
|
public Result<?> getPermCode() {
|
||||||
|
Result<List<String>> result = new Result<List<String>>();
|
||||||
|
try {
|
||||||
|
//直接获取当前用户
|
||||||
|
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||||
|
//获取当前用户的权限集合
|
||||||
|
List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getUsername());
|
||||||
|
//按钮权限(用户拥有的权限集合)
|
||||||
|
List<String> authList = metaList.stream()
|
||||||
|
.filter((permission) -> permission.getMenuType().equals(CommonConstant.MENU_TYPE_2)
|
||||||
|
&& CommonConstant.STATUS_1.equals(permission.getStatus())
|
||||||
|
)
|
||||||
|
.collect(() -> new ArrayList<String>(),
|
||||||
|
(list, permission) -> list.add(permission.getPerms()),
|
||||||
|
(list1, list2) -> list1.addAll(list2)
|
||||||
|
);
|
||||||
|
result.setResult(authList);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
result.error500("查询失败:" + e.getMessage());
|
result.error500("查询失败:" + e.getMessage());
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
|
@ -380,7 +405,7 @@ public class SysPermissionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异步加载数据节点
|
* 异步加载数据节点 [接口是废的,没有用到]
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -482,6 +507,31 @@ public class SysPermissionController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一级菜单的子菜单全部是隐藏路由,则一级菜单不显示
|
||||||
|
* @param jsonArray
|
||||||
|
*/
|
||||||
|
private void handleFirstLevelMenuHidden(JSONArray jsonArray) {
|
||||||
|
jsonArray = jsonArray.stream().map(obj -> {
|
||||||
|
JSONObject returnObj = new JSONObject();
|
||||||
|
JSONObject jsonObj = (JSONObject)obj;
|
||||||
|
if(jsonObj.containsKey("children")){
|
||||||
|
JSONArray childrens = jsonObj.getJSONArray("children");
|
||||||
|
childrens = childrens.stream().filter(arrObj -> !"true".equals(((JSONObject) arrObj).getString("hidden"))).collect(Collectors.toCollection(JSONArray::new));
|
||||||
|
if(childrens==null || childrens.size()==0){
|
||||||
|
jsonObj.put("hidden",true);
|
||||||
|
|
||||||
|
//vue3版本兼容代码
|
||||||
|
JSONObject meta = new JSONObject();
|
||||||
|
meta.put("hideMenu",true);
|
||||||
|
jsonObj.put("meta", meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnObj;
|
||||||
|
}).collect(Collectors.toCollection(JSONArray::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取权限JSON数组
|
* 获取权限JSON数组
|
||||||
* @param jsonArray
|
* @param jsonArray
|
||||||
|
@ -605,16 +655,18 @@ public class SysPermissionController {
|
||||||
json.put("name", urlToRouteName(permission.getUrl()));
|
json.put("name", urlToRouteName(permission.getUrl()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSONObject meta = new JSONObject();
|
||||||
// 是否隐藏路由,默认都是显示的
|
// 是否隐藏路由,默认都是显示的
|
||||||
if (permission.isHidden()) {
|
if (permission.isHidden()) {
|
||||||
json.put("hidden", true);
|
json.put("hidden", true);
|
||||||
|
//vue3版本兼容代码
|
||||||
|
meta.put("hideMenu",true);
|
||||||
}
|
}
|
||||||
// 聚合路由
|
// 聚合路由
|
||||||
if (permission.isAlwaysShow()) {
|
if (permission.isAlwaysShow()) {
|
||||||
json.put("alwaysShow", true);
|
json.put("alwaysShow", true);
|
||||||
}
|
}
|
||||||
json.put("component", permission.getComponent());
|
json.put("component", permission.getComponent());
|
||||||
JSONObject meta = new JSONObject();
|
|
||||||
// 由用户设置是否缓存页面 用布尔值
|
// 由用户设置是否缓存页面 用布尔值
|
||||||
if (permission.isKeepAlive()) {
|
if (permission.isKeepAlive()) {
|
||||||
meta.put("keepAlive", true);
|
meta.put("keepAlive", true);
|
||||||
|
@ -654,6 +706,11 @@ public class SysPermissionController {
|
||||||
if (isWWWHttpUrl(permission.getUrl())) {
|
if (isWWWHttpUrl(permission.getUrl())) {
|
||||||
meta.put("url", permission.getUrl());
|
meta.put("url", permission.getUrl());
|
||||||
}
|
}
|
||||||
|
// update-begin--Author:sunjianlei Date:20210918 for:新增适配vue3项目的隐藏tab功能
|
||||||
|
if (permission.isHideTab()) {
|
||||||
|
meta.put("hideTab", true);
|
||||||
|
}
|
||||||
|
// update-end--Author:sunjianlei Date:20210918 for:新增适配vue3项目的隐藏tab功能
|
||||||
json.put("meta", meta);
|
json.put("meta", meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -776,7 +833,6 @@ public class SysPermissionController {
|
||||||
try {
|
try {
|
||||||
List<SysPermissionDataRule> permRuleList = sysPermissionDataRuleService.queryPermissionRule(sysPermissionDataRule);
|
List<SysPermissionDataRule> permRuleList = sysPermissionDataRuleService.queryPermissionRule(sysPermissionDataRule);
|
||||||
result.setResult(permRuleList);
|
result.setResult(permRuleList);
|
||||||
result.success("查询成功!");
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
result.error500("操作失败");
|
result.error500("操作失败");
|
||||||
|
|
|
@ -107,7 +107,7 @@ public class SysPositionController {
|
||||||
*/
|
*/
|
||||||
@AutoLog(value = "职务表-编辑")
|
@AutoLog(value = "职务表-编辑")
|
||||||
@ApiOperation(value = "职务表-编辑", notes = "职务表-编辑")
|
@ApiOperation(value = "职务表-编辑", notes = "职务表-编辑")
|
||||||
@PutMapping(value = "/edit")
|
@RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST})
|
||||||
public Result<SysPosition> edit(@RequestBody SysPosition sysPosition) {
|
public Result<SysPosition> edit(@RequestBody SysPosition sysPosition) {
|
||||||
Result<SysPosition> result = new Result<SysPosition>();
|
Result<SysPosition> result = new Result<SysPosition>();
|
||||||
SysPosition sysPositionEntity = sysPositionService.getById(sysPosition.getId());
|
SysPosition sysPositionEntity = sysPositionService.getById(sysPosition.getId());
|
||||||
|
|
|
@ -129,7 +129,7 @@ public class SysRoleController {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
//@RequiresRoles({"admin"})
|
//@RequiresRoles({"admin"})
|
||||||
@RequestMapping(value = "/edit", method = RequestMethod.PUT)
|
@RequestMapping(value = "/edit",method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
public Result<SysRole> edit(@RequestBody SysRole role) {
|
public Result<SysRole> edit(@RequestBody SysRole role) {
|
||||||
Result<SysRole> result = new Result<SysRole>();
|
Result<SysRole> result = new Result<SysRole>();
|
||||||
SysRole sysrole = sysRoleService.getById(role.getId());
|
SysRole sysrole = sysRoleService.getById(role.getId());
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,7 +44,23 @@ public class SysTenantController {
|
||||||
public Result<IPage<SysTenant>> queryPageList(SysTenant sysTenant,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
public Result<IPage<SysTenant>> queryPageList(SysTenant sysTenant,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
|
||||||
Result<IPage<SysTenant>> result = new Result<IPage<SysTenant>>();
|
Result<IPage<SysTenant>> result = new Result<IPage<SysTenant>>();
|
||||||
|
//---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询---
|
||||||
|
Date beginDate=null;
|
||||||
|
Date endDate=null;
|
||||||
|
if(oConvertUtils.isNotEmpty(sysTenant)) {
|
||||||
|
beginDate=sysTenant.getBeginDate();
|
||||||
|
endDate=sysTenant.getEndDate();
|
||||||
|
sysTenant.setBeginDate(null);
|
||||||
|
sysTenant.setEndDate(null);
|
||||||
|
}
|
||||||
|
//---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询---
|
||||||
QueryWrapper<SysTenant> queryWrapper = QueryGenerator.initQueryWrapper(sysTenant, req.getParameterMap());
|
QueryWrapper<SysTenant> queryWrapper = QueryGenerator.initQueryWrapper(sysTenant, req.getParameterMap());
|
||||||
|
//---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询---
|
||||||
|
if(oConvertUtils.isNotEmpty(sysTenant)){
|
||||||
|
queryWrapper.ge(oConvertUtils.isNotEmpty(beginDate),"begin_date",beginDate);
|
||||||
|
queryWrapper.le(oConvertUtils.isNotEmpty(endDate),"end_date",endDate);
|
||||||
|
}
|
||||||
|
//---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询---
|
||||||
Page<SysTenant> page = new Page<SysTenant>(pageNo, pageSize);
|
Page<SysTenant> page = new Page<SysTenant>(pageNo, pageSize);
|
||||||
IPage<SysTenant> pageList = sysTenantService.page(page, queryWrapper);
|
IPage<SysTenant> pageList = sysTenantService.page(page, queryWrapper);
|
||||||
result.setSuccess(true);
|
result.setSuccess(true);
|
||||||
|
@ -58,7 +75,7 @@ public class SysTenantController {
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/add", method = RequestMethod.POST)
|
@RequestMapping(value = "/add", method = RequestMethod.POST)
|
||||||
public Result<SysTenant> add(@RequestBody SysTenant sysTenant) {
|
public Result<SysTenant> add(@RequestBody SysTenant sysTenant) {
|
||||||
Result<SysTenant> result = new Result<SysTenant>();
|
Result<SysTenant> result = new Result();
|
||||||
if(sysTenantService.getById(sysTenant.getId())!=null){
|
if(sysTenantService.getById(sysTenant.getId())!=null){
|
||||||
return result.error500("该编号已存在!");
|
return result.error500("该编号已存在!");
|
||||||
}
|
}
|
||||||
|
@ -77,18 +94,17 @@ public class SysTenantController {
|
||||||
* @param
|
* @param
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/edit", method = RequestMethod.PUT)
|
@RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST})
|
||||||
public Result<SysTenant> edit(@RequestBody SysTenant tenant) {
|
public Result<SysTenant> edit(@RequestBody SysTenant tenant) {
|
||||||
Result<SysTenant> result = new Result<SysTenant>();
|
Result<SysTenant> result = new Result();
|
||||||
SysTenant sysTenant = sysTenantService.getById(tenant.getId());
|
SysTenant sysTenant = sysTenantService.getById(tenant.getId());
|
||||||
if(sysTenant==null) {
|
if(sysTenant==null) {
|
||||||
result.error500("未找到对应实体");
|
return result.error500("未找到对应实体");
|
||||||
}else {
|
}
|
||||||
boolean ok = sysTenantService.updateById(tenant);
|
boolean ok = sysTenantService.updateById(tenant);
|
||||||
if(ok) {
|
if(ok) {
|
||||||
result.success("修改成功!");
|
result.success("修改成功!");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +113,7 @@ public class SysTenantController {
|
||||||
* @param id
|
* @param id
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
|
@RequestMapping(value = "/delete", method ={RequestMethod.DELETE, RequestMethod.POST})
|
||||||
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
|
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
sysTenantService.removeTenantById(id);
|
sysTenantService.removeTenantById(id);
|
||||||
return Result.ok("删除成功");
|
return Result.ok("删除成功");
|
||||||
|
|
|
@ -107,7 +107,7 @@ public class SysUserAgentController {
|
||||||
* @param sysUserAgent
|
* @param sysUserAgent
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@PutMapping(value = "/edit")
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
public Result<SysUserAgent> edit(@RequestBody SysUserAgent sysUserAgent) {
|
public Result<SysUserAgent> edit(@RequestBody SysUserAgent sysUserAgent) {
|
||||||
Result<SysUserAgent> result = new Result<SysUserAgent>();
|
Result<SysUserAgent> result = new Result<SysUserAgent>();
|
||||||
SysUserAgent sysUserAgentEntity = sysUserAgentService.getById(sysUserAgent.getId());
|
SysUserAgent sysUserAgentEntity = sysUserAgentService.getById(sysUserAgent.getId());
|
||||||
|
|
|
@ -157,7 +157,7 @@ public class SysUserController {
|
||||||
|
|
||||||
//@RequiresRoles({"admin"})
|
//@RequiresRoles({"admin"})
|
||||||
//@RequiresPermissions("user:edit")
|
//@RequiresPermissions("user:edit")
|
||||||
@RequestMapping(value = "/edit", method = RequestMethod.PUT)
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
public Result<SysUser> edit(@RequestBody JSONObject jsonObject) {
|
public Result<SysUser> edit(@RequestBody JSONObject jsonObject) {
|
||||||
Result<SysUser> result = new Result<SysUser>();
|
Result<SysUser> result = new Result<SysUser>();
|
||||||
try {
|
try {
|
||||||
|
@ -172,6 +172,10 @@ public class SysUserController {
|
||||||
user.setPassword(sysUser.getPassword());
|
user.setPassword(sysUser.getPassword());
|
||||||
String roles = jsonObject.getString("selectedroles");
|
String roles = jsonObject.getString("selectedroles");
|
||||||
String departs = jsonObject.getString("selecteddeparts");
|
String departs = jsonObject.getString("selecteddeparts");
|
||||||
|
if(oConvertUtils.isEmpty(departs)){
|
||||||
|
//vue3.0前端只传递了departIds
|
||||||
|
departs=user.getDepartIds();
|
||||||
|
}
|
||||||
// 修改用户走一个service 保证事务
|
// 修改用户走一个service 保证事务
|
||||||
sysUserService.editUser(user, roles, departs);
|
sysUserService.editUser(user, roles, departs);
|
||||||
result.success("修改成功!");
|
result.success("修改成功!");
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package org.jeecg.modules.system.controller;
|
package org.jeecg.modules.system.controller;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
@ -55,27 +52,22 @@ public class SysUserOnlineController {
|
||||||
private BaseCommonService baseCommonService;
|
private BaseCommonService baseCommonService;
|
||||||
|
|
||||||
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
||||||
public Result<Page<SysUserOnlineVO>> list(@RequestParam(name="username", required=false) String username, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
public Result<Page<SysUserOnlineVO>> list(@RequestParam(name="username", required=false) String username,
|
||||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
|
||||||
Collection<String> keys = redisTemplate.keys(CommonConstant.PREFIX_USER_TOKEN + "*");
|
Collection<String> keys = redisTemplate.keys(CommonConstant.PREFIX_USER_TOKEN + "*");
|
||||||
SysUserOnlineVO online;
|
|
||||||
List<SysUserOnlineVO> onlineList = new ArrayList<SysUserOnlineVO>();
|
List<SysUserOnlineVO> onlineList = new ArrayList<SysUserOnlineVO>();
|
||||||
for (String key : keys) {
|
for (String key : keys) {
|
||||||
online = new SysUserOnlineVO();
|
|
||||||
String token = (String)redisUtil.get(key);
|
String token = (String)redisUtil.get(key);
|
||||||
if (!StringUtils.isEmpty(token)){
|
if (StringUtils.isNotEmpty(token)) {
|
||||||
|
SysUserOnlineVO online = new SysUserOnlineVO();
|
||||||
online.setToken(token);
|
online.setToken(token);
|
||||||
|
//TODO 改成一次性查询
|
||||||
LoginUser loginUser = sysBaseAPI.getUserByName(JwtUtil.getUsername(token));
|
LoginUser loginUser = sysBaseAPI.getUserByName(JwtUtil.getUsername(token));
|
||||||
BeanUtils.copyProperties(loginUser, online);
|
BeanUtils.copyProperties(loginUser, online);
|
||||||
if (StringUtils.isNotEmpty(username)) {
|
|
||||||
if (StringUtils.equals(username, online.getUsername())) {
|
|
||||||
onlineList.add(online);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
onlineList.add(online);
|
onlineList.add(online);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Collections.reverse(onlineList);
|
||||||
|
|
||||||
Page<SysUserOnlineVO> page = new Page<SysUserOnlineVO>(pageNo, pageSize);
|
Page<SysUserOnlineVO> page = new Page<SysUserOnlineVO>(pageNo, pageSize);
|
||||||
int count = onlineList.size();
|
int count = onlineList.size();
|
||||||
|
@ -92,8 +84,6 @@ public class SysUserOnlineController {
|
||||||
page.setPages(count % 10 == 0 ? count / 10 : count / 10 + 1);
|
page.setPages(count % 10 == 0 ? count / 10 : count / 10 + 1);
|
||||||
page.setRecords(pages);
|
page.setRecords(pages);
|
||||||
|
|
||||||
Collections.reverse(onlineList);
|
|
||||||
onlineList.removeAll(Collections.singleton(null));
|
|
||||||
Result<Page<SysUserOnlineVO>> result = new Result<Page<SysUserOnlineVO>>();
|
Result<Page<SysUserOnlineVO>> result = new Result<Page<SysUserOnlineVO>>();
|
||||||
result.setSuccess(true);
|
result.setSuccess(true);
|
||||||
result.setResult(page);
|
result.setResult(page);
|
||||||
|
|
|
@ -130,6 +130,11 @@ public class SysPermission implements Serializable {
|
||||||
*/
|
*/
|
||||||
private boolean hidden;
|
private boolean hidden;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否隐藏Tab: 0否,1是(默认值0)
|
||||||
|
*/
|
||||||
|
private boolean hideTab;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建时间
|
* 创建时间
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -127,7 +127,7 @@
|
||||||
select ${text} as "title",
|
select ${text} as "title",
|
||||||
${code} as "key",
|
${code} as "key",
|
||||||
<if test="hasChildField != null and hasChildField != ''">
|
<if test="hasChildField != null and hasChildField != ''">
|
||||||
(case when ${hasChildField} = '1' then 0 else 1 end) as isLeaf,
|
${hasChildField} as "isLeaf",
|
||||||
</if>
|
</if>
|
||||||
${pidField} as parentId
|
${pidField} as parentId
|
||||||
from ${table}
|
from ${table}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<result column="name" property="title" jdbcType="VARCHAR"/>
|
<result column="name" property="title" jdbcType="VARCHAR"/>
|
||||||
<result column="icon" property="icon" jdbcType="VARCHAR"/>
|
<result column="icon" property="icon" jdbcType="VARCHAR"/>
|
||||||
<result column="parent_id" property="parentId" jdbcType="VARCHAR"/>
|
<result column="parent_id" property="parentId" jdbcType="VARCHAR"/>
|
||||||
<result column="leaf_flag" property="isLeaf" jdbcType="INTEGER"/>
|
<result column="is_leaf" property="isLeaf" jdbcType="INTEGER"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<!-- 通过<resultMap>映射实体类属性名和表的字段名对应关系 -->
|
<!-- 通过<resultMap>映射实体类属性名和表的字段名对应关系 -->
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
,parent_id
|
,parent_id
|
||||||
,name
|
,name
|
||||||
,icon
|
,icon
|
||||||
,leaf_flag
|
,is_leaf
|
||||||
FROM sys_permission
|
FROM sys_permission
|
||||||
WHERE 1=1
|
WHERE 1=1
|
||||||
<choose>
|
<choose>
|
||||||
|
|
|
@ -29,6 +29,13 @@ public interface ISysDepartService extends IService<SysDepart>{
|
||||||
*/
|
*/
|
||||||
List<SysDepartTreeModel> queryTreeList();
|
List<SysDepartTreeModel> queryTreeList();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有部门信息,并分节点进行显示
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<SysDepartTreeModel> queryTreeList(String ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询所有部门DepartId信息,并分节点进行显示
|
* 查询所有部门DepartId信息,并分节点进行显示
|
||||||
* @return
|
* @return
|
||||||
|
@ -112,7 +119,7 @@ public interface ISysDepartService extends IService<SysDepart>{
|
||||||
* 获取我的部门下级所有部门
|
* 获取我的部门下级所有部门
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<SysDepartTreeModel> queryTreeListByPid(String parentId);
|
List<SysDepartTreeModel> queryTreeListByPid(String parentId,String ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取某个部门的所有父级部门的ID
|
* 获取某个部门的所有父级部门的ID
|
||||||
|
|
|
@ -115,7 +115,11 @@ public class SysAnnouncementServiceImpl extends ServiceImpl<SysAnnouncementMappe
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<SysAnnouncement> querySysCementPageByUserId(Page<SysAnnouncement> page, String userId, String msgCategory) {
|
public Page<SysAnnouncement> querySysCementPageByUserId(Page<SysAnnouncement> page, String userId, String msgCategory) {
|
||||||
|
if (page.getSize() == -1) {
|
||||||
|
return page.setRecords(sysAnnouncementMapper.querySysCementListByUserId(null, userId, msgCategory));
|
||||||
|
} else {
|
||||||
return page.setRecords(sysAnnouncementMapper.querySysCementListByUserId(page, userId, msgCategory));
|
return page.setRecords(sysAnnouncementMapper.querySysCementListByUserId(page, userId, msgCategory));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -77,8 +78,8 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||||
/**
|
/**
|
||||||
* queryTreeList 对应 queryTreeList 查询所有的部门数据,以树结构形式响应给前端
|
* queryTreeList 对应 queryTreeList 查询所有的部门数据,以树结构形式响应给前端
|
||||||
*/
|
*/
|
||||||
@Cacheable(value = CacheConstant.SYS_DEPARTS_CACHE)
|
|
||||||
@Override
|
@Override
|
||||||
|
@Cacheable(value = CacheConstant.SYS_DEPARTS_CACHE)
|
||||||
public List<SysDepartTreeModel> queryTreeList() {
|
public List<SysDepartTreeModel> queryTreeList() {
|
||||||
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
|
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
|
||||||
query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
|
query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
|
||||||
|
@ -89,6 +90,26 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||||
return listResult;
|
return listResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* queryTreeList 根据部门id查询,前端回显调用
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<SysDepartTreeModel> queryTreeList(String ids) {
|
||||||
|
List<SysDepartTreeModel> listResult=new ArrayList<>();
|
||||||
|
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
|
||||||
|
query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
|
||||||
|
if(oConvertUtils.isNotEmpty(ids)){
|
||||||
|
query.in(true,SysDepart::getId,ids.split(","));
|
||||||
|
}
|
||||||
|
query.orderByAsc(SysDepart::getDepartOrder);
|
||||||
|
List<SysDepart> list= this.list(query);
|
||||||
|
for (SysDepart depart : list) {
|
||||||
|
listResult.add(new SysDepartTreeModel(depart));
|
||||||
|
}
|
||||||
|
return listResult;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Cacheable(value = CacheConstant.SYS_DEPART_IDS_CACHE)
|
@Cacheable(value = CacheConstant.SYS_DEPART_IDS_CACHE)
|
||||||
@Override
|
@Override
|
||||||
public List<DepartIdModel> queryDepartIdTreeList() {
|
public List<DepartIdModel> queryDepartIdTreeList() {
|
||||||
|
@ -458,11 +479,27 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||||
/**
|
/**
|
||||||
* 根据parentId查询部门树
|
* 根据parentId查询部门树
|
||||||
* @param parentId
|
* @param parentId
|
||||||
|
* @param ids 前端回显传递
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<SysDepartTreeModel> queryTreeListByPid(String parentId) {
|
public List<SysDepartTreeModel> queryTreeListByPid(String parentId,String ids) {
|
||||||
List<SysDepart> list = this.baseMapper.queryTreeListByPid(parentId);
|
Consumer<LambdaQueryWrapper<SysDepart>> square = i -> {
|
||||||
|
if (oConvertUtils.isNotEmpty(ids)) {
|
||||||
|
i.in(SysDepart::getId, ids.split(","));
|
||||||
|
} else {
|
||||||
|
if(oConvertUtils.isEmpty(parentId)){
|
||||||
|
i.and(q->q.isNull(true,SysDepart::getParentId).or().eq(true,SysDepart::getParentId,""));
|
||||||
|
}else{
|
||||||
|
i.eq(true,SysDepart::getParentId,parentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
LambdaQueryWrapper<SysDepart> lqw=new LambdaQueryWrapper();
|
||||||
|
lqw.eq(true,SysDepart::getDelFlag,CommonConstant.DEL_FLAG_0);
|
||||||
|
lqw.func(square);
|
||||||
|
lqw.orderByDesc(SysDepart::getDepartOrder);
|
||||||
|
List<SysDepart> list = list(lqw);
|
||||||
List<SysDepartTreeModel> records = new ArrayList<>();
|
List<SysDepartTreeModel> records = new ArrayList<>();
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
SysDepart depart = list.get(i);
|
SysDepart depart = list.get(i);
|
||||||
|
|
|
@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jeecg.common.base.BaseMap;
|
import org.jeecg.common.base.BaseMap;
|
||||||
import org.jeecg.common.constant.CacheConstant;
|
import org.jeecg.common.constant.CacheConstant;
|
||||||
import org.jeecg.common.constant.GlobalConstants;
|
import org.jeecg.common.constant.GlobalConstants;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.jeecg.modules.system.entity.SysGatewayRoute;
|
import org.jeecg.modules.system.entity.SysGatewayRoute;
|
||||||
import org.jeecg.modules.system.mapper.SysGatewayRouteMapper;
|
import org.jeecg.modules.system.mapper.SysGatewayRouteMapper;
|
||||||
import org.jeecg.modules.system.service.ISysGatewayRouteService;
|
import org.jeecg.modules.system.service.ISysGatewayRouteService;
|
||||||
|
@ -17,7 +18,9 @@ import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: gateway路由管理
|
* @Description: gateway路由管理
|
||||||
|
@ -42,7 +45,7 @@ public class SysGatewayRouteServiceImpl extends ServiceImpl<SysGatewayRouteMappe
|
||||||
@Override
|
@Override
|
||||||
public void deleteById(String id) {
|
public void deleteById(String id) {
|
||||||
this.removeById(id);
|
this.removeById(id);
|
||||||
this.resreshRouter();
|
this.resreshRouter(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,7 +55,14 @@ public class SysGatewayRouteServiceImpl extends ServiceImpl<SysGatewayRouteMappe
|
||||||
try {
|
try {
|
||||||
json = json.getJSONObject("router");
|
json = json.getJSONObject("router");
|
||||||
String id = json.getString("id");
|
String id = json.getString("id");
|
||||||
SysGatewayRoute route = getById(id);
|
//update-begin-author:taoyan date:20211025 for: oracle路由网关新增小bug /issues/I4EV2J
|
||||||
|
SysGatewayRoute route;
|
||||||
|
if(oConvertUtils.isEmpty(id)){
|
||||||
|
route = new SysGatewayRoute();
|
||||||
|
}else{
|
||||||
|
route = getById(id);
|
||||||
|
}
|
||||||
|
//update-end-author:taoyan date:20211025 for: oracle路由网关新增小bug /issues/I4EV2J
|
||||||
if (ObjectUtil.isEmpty(route)) {
|
if (ObjectUtil.isEmpty(route)) {
|
||||||
route = new SysGatewayRoute();
|
route = new SysGatewayRoute();
|
||||||
}
|
}
|
||||||
|
@ -71,10 +81,10 @@ public class SysGatewayRouteServiceImpl extends ServiceImpl<SysGatewayRouteMappe
|
||||||
route.setStatus(json.getInteger("status"));
|
route.setStatus(json.getInteger("status"));
|
||||||
}
|
}
|
||||||
this.saveOrUpdate(route);
|
this.saveOrUpdate(route);
|
||||||
resreshRouter();
|
resreshRouter(null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("路由配置解析失败", e);
|
log.error("路由配置解析失败", e);
|
||||||
resreshRouter();
|
resreshRouter(null);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,11 +92,12 @@ public class SysGatewayRouteServiceImpl extends ServiceImpl<SysGatewayRouteMappe
|
||||||
/**
|
/**
|
||||||
* 更新redis路由缓存
|
* 更新redis路由缓存
|
||||||
*/
|
*/
|
||||||
private void resreshRouter() {
|
private void resreshRouter(String id) {
|
||||||
//更新redis路由缓存
|
//更新redis路由缓存
|
||||||
addRoute2Redis(CacheConstant.GATEWAY_ROUTES);
|
addRoute2Redis(CacheConstant.GATEWAY_ROUTES);
|
||||||
BaseMap params = new BaseMap();
|
BaseMap params = new BaseMap();
|
||||||
params.put(GlobalConstants.HANDLER_NAME, "loderRouderHandler");
|
params.put(GlobalConstants.HANDLER_NAME, "loderRouderHandler");
|
||||||
|
params.put("routerId", id);
|
||||||
//刷新网关
|
//刷新网关
|
||||||
redisTemplate.convertAndSend(GlobalConstants.REDIS_TOPIC_NAME, params);
|
redisTemplate.convertAndSend(GlobalConstants.REDIS_TOPIC_NAME, params);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
package org.jeecg.modules.system.service.impl.desform;
|
|
||||||
|
|
||||||
import org.jeecg.common.api.desform.ISysTranslateAPI;
|
|
||||||
import org.jeecg.common.system.vo.DictModel;
|
|
||||||
import org.jeecg.modules.system.service.ISysCategoryService;
|
|
||||||
import org.jeecg.modules.system.service.ISysDictService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 表单设计器翻译API接口(system实现类)
|
|
||||||
*
|
|
||||||
* @author sunjianlei
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class SysTranslateAPIImpl implements ISysTranslateAPI {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
ISysCategoryService sysCategoryService;
|
|
||||||
@Autowired
|
|
||||||
ISysDictService sysDictService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> categoryLoadDictItem(String ids) {
|
|
||||||
return sysCategoryService.loadDictItem(ids, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> dictLoadDictItem(String dictCode, String keys) {
|
|
||||||
String[] params = dictCode.split(",");
|
|
||||||
return sysDictService.queryTableDictByKeys(params[0], params[1], params[2], keys, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<DictModel> dictGetDictItems(String dictCode) {
|
|
||||||
List<DictModel> ls = sysDictService.getDictItems(dictCode);
|
|
||||||
if (ls == null) {
|
|
||||||
ls = new ArrayList<>();
|
|
||||||
}
|
|
||||||
return ls;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<DictModel> dictLoadDict(String dictCode, String keyword, Integer pageSize) {
|
|
||||||
return sysDictService.loadDict(dictCode, keyword, pageSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
//package org.jeecg.modules.system.util;
|
|
||||||
//
|
|
||||||
//import lombok.extern.slf4j.Slf4j;
|
|
||||||
//
|
|
||||||
///**
|
|
||||||
// * 多租户 tenant_id存储器
|
|
||||||
// */
|
|
||||||
//@Slf4j
|
|
||||||
//public class TenantContext {
|
|
||||||
//
|
|
||||||
// private static ThreadLocal<String> currentTenant = new ThreadLocal<>();
|
|
||||||
//
|
|
||||||
// public static void setTenant(String tenant) {
|
|
||||||
// log.debug(" setting tenant to " + tenant);
|
|
||||||
// currentTenant.set(tenant);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static String getTenant() {
|
|
||||||
// return currentTenant.get();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static void clear(){
|
|
||||||
// currentTenant.remove();
|
|
||||||
// }
|
|
||||||
//}
|
|
|
@ -1,60 +0,0 @@
|
||||||
package org.jeecg.modules.system.vo;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.jeecg.common.aspect.annotation.Dict;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @Author: chenli
|
|
||||||
* @Date: 2020-06-07
|
|
||||||
* @Version: V1.0
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class SysOnlineVO {
|
|
||||||
/**
|
|
||||||
* 会话id
|
|
||||||
*/
|
|
||||||
private String id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 会话编号
|
|
||||||
*/
|
|
||||||
private String token;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户名
|
|
||||||
*/
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户名
|
|
||||||
*/
|
|
||||||
private String realname;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 头像
|
|
||||||
*/
|
|
||||||
private String avatar;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生日
|
|
||||||
*/
|
|
||||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
|
||||||
private Date birthday;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 性别(1:男 2:女)
|
|
||||||
*/
|
|
||||||
@Dict(dicCode = "sex")
|
|
||||||
private Integer sex;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 手机号
|
|
||||||
*/
|
|
||||||
private String phone;
|
|
||||||
}
|
|
|
@ -131,7 +131,7 @@ spring:
|
||||||
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
|
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
|
||||||
datasource:
|
datasource:
|
||||||
master:
|
master:
|
||||||
url: jdbc:mysql://127.0.0.1:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
|
url: jdbc:mysql://127.0.0.1:3306/jeecg-boot-os-re?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
|
||||||
username: root
|
username: root
|
||||||
password: root
|
password: root
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
@ -176,6 +176,8 @@ minidao :
|
||||||
#DB类型(mysql | postgresql | oracle | sqlserver| other)
|
#DB类型(mysql | postgresql | oracle | sqlserver| other)
|
||||||
db-type: mysql
|
db-type: mysql
|
||||||
jeecg :
|
jeecg :
|
||||||
|
# 是否启用安全模式
|
||||||
|
safeMode: false
|
||||||
# 签名密钥串(前后端要一致,正式发布请自行修改)
|
# 签名密钥串(前后端要一致,正式发布请自行修改)
|
||||||
signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
|
signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
|
||||||
# 本地:local\Minio:minio\阿里云:alioss
|
# 本地:local\Minio:minio\阿里云:alioss
|
||||||
|
|
|
@ -174,6 +174,8 @@ mybatis-plus:
|
||||||
minidao :
|
minidao :
|
||||||
base-package: org.jeecg.modules.jmreport.*
|
base-package: org.jeecg.modules.jmreport.*
|
||||||
jeecg :
|
jeecg :
|
||||||
|
# 是否启用安全模式
|
||||||
|
safeMode: false
|
||||||
# 签名密钥串(前后端要一致,正式发布请自行修改)
|
# 签名密钥串(前后端要一致,正式发布请自行修改)
|
||||||
signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
|
signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
|
||||||
# 本地:local\Minio:minio\阿里云:alioss
|
# 本地:local\Minio:minio\阿里云:alioss
|
||||||
|
|
|
@ -174,6 +174,8 @@ mybatis-plus:
|
||||||
minidao :
|
minidao :
|
||||||
base-package: org.jeecg.modules.jmreport.*
|
base-package: org.jeecg.modules.jmreport.*
|
||||||
jeecg :
|
jeecg :
|
||||||
|
# 是否启用安全模式
|
||||||
|
safeMode: false
|
||||||
# 签名密钥串(前后端要一致,正式发布请自行修改)
|
# 签名密钥串(前后端要一致,正式发布请自行修改)
|
||||||
signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
|
signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
|
||||||
# 本地:local\Minio:minio\阿里云:alioss
|
# 本地:local\Minio:minio\阿里云:alioss
|
||||||
|
|
|
@ -9,6 +9,6 @@ ${AnsiColor.BRIGHT_BLUE}
|
||||||
|
|
||||||
|
|
||||||
${AnsiColor.BRIGHT_GREEN}
|
${AnsiColor.BRIGHT_GREEN}
|
||||||
Jeecg Boot Version: 2.4.6
|
Jeecg Boot Version: 3.0
|
||||||
Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
|
Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
|
||||||
${AnsiColor.BLACK}
|
${AnsiColor.BLACK}
|
||||||
|
|
|
@ -0,0 +1,244 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<#assign list_need_category=false>
|
||||||
|
<#assign list_need_pca=false>
|
||||||
|
<#assign bpm_flag=false>
|
||||||
|
|
||||||
|
<#-- 开始循环 -->
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='cat_tree' && po.dictText?default("")?trim?length == 0>
|
||||||
|
<#assign list_need_category=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='pca'>
|
||||||
|
<#assign list_need_pca=true>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#-- 结束循环 -->
|
||||||
|
<!--引用表格-->
|
||||||
|
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||||
|
<!--插槽:table标题-->
|
||||||
|
<template #tableTitle>
|
||||||
|
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||||
|
<ExcelButton :config="excelConfig"></ExcelButton>
|
||||||
|
<a-dropdown v-if="checkedKeys.length > 0">
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu>
|
||||||
|
<a-menu-item key="1" @click="batchHandleDelete">
|
||||||
|
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||||
|
删除
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
<a-button>批量操作
|
||||||
|
<Icon icon="mdi:chevron-down"></Icon>
|
||||||
|
</a-button>
|
||||||
|
</a-dropdown>
|
||||||
|
</template>
|
||||||
|
<!--操作栏-->
|
||||||
|
<template #action="{ record }">
|
||||||
|
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
|
||||||
|
</template>
|
||||||
|
<!--字段回显插槽-->
|
||||||
|
<template #htmlSlot="{text}">
|
||||||
|
<div v-html="text"></div>
|
||||||
|
</template>
|
||||||
|
<template #fileSlot="{text}">
|
||||||
|
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||||
|
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
|
||||||
|
</template>
|
||||||
|
</BasicTable>
|
||||||
|
<!-- 表单区域 -->
|
||||||
|
<${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {ref, computed, unref} from 'vue';
|
||||||
|
import {BasicTable, useTable, TableAction} from '/@/components/Table';
|
||||||
|
import ExcelButton from '/@/components/jeecg/ExcelButton.vue'
|
||||||
|
import {useModal} from '/@/components/Modal';
|
||||||
|
import ${entityName}Modal from './components/${entityName}Modal.vue'
|
||||||
|
import {columns, searchFormSchema} from './${entityName?uncap_first}.data';
|
||||||
|
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName?uncap_first}.api';
|
||||||
|
<#if list_need_category>
|
||||||
|
import { loadCategoryData } from '/@/api/common/api'
|
||||||
|
import { getAuthCache, setAuthCache } from '/@/utils/auth';
|
||||||
|
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
|
||||||
|
</#if>
|
||||||
|
const checkedKeys = ref<Array<string | number>>([]);
|
||||||
|
//注册model
|
||||||
|
const [registerModal, {openModal}] = useModal();
|
||||||
|
//注册table数据
|
||||||
|
const [registerTable, {reload}] = useTable({
|
||||||
|
title: '${tableVo.ftlDescription}',
|
||||||
|
api: list,
|
||||||
|
rowKey: 'id',
|
||||||
|
columns,
|
||||||
|
formConfig: {
|
||||||
|
labelWidth: 120,
|
||||||
|
schemas: searchFormSchema,
|
||||||
|
autoSubmitOnEnter:true,
|
||||||
|
showAdvancedButton:true,
|
||||||
|
fieldMapToTime: [
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.isQuery=='Y'>
|
||||||
|
<#if po.queryMode!='single'>
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD'],
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD HH:mm:ss'],
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
],
|
||||||
|
},
|
||||||
|
striped: true,
|
||||||
|
useSearchForm: true,
|
||||||
|
showTableSetting: true,
|
||||||
|
clickToRowSelect: false,
|
||||||
|
bordered: true,
|
||||||
|
showIndexColumn: false,
|
||||||
|
tableSetting: {fullScreen: true},
|
||||||
|
actionColumn: {
|
||||||
|
width: 120,
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
slots: {customRender: 'action'},
|
||||||
|
fixed: 'right',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* excel导入导出配置
|
||||||
|
*/
|
||||||
|
const excelConfig = {
|
||||||
|
export: {
|
||||||
|
name:'${tableVo.ftlDescription}',
|
||||||
|
url: getExportUrl,
|
||||||
|
},
|
||||||
|
import: {
|
||||||
|
url: getImportUrl,
|
||||||
|
success: reload,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 选择列配置
|
||||||
|
*/
|
||||||
|
const rowSelection = {
|
||||||
|
type: 'checkbox',
|
||||||
|
columnWidth: 30,
|
||||||
|
selectedRowKeys: checkedKeys,
|
||||||
|
onChange: onSelectChange
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 选择事件
|
||||||
|
*/
|
||||||
|
function onSelectChange(selectedRowKeys: (string | number)[]) {
|
||||||
|
checkedKeys.value = selectedRowKeys;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 新增事件
|
||||||
|
*/
|
||||||
|
function handleAdd() {
|
||||||
|
openModal(true, {
|
||||||
|
isUpdate: false,
|
||||||
|
showFooter: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 编辑事件
|
||||||
|
*/
|
||||||
|
function handleEdit(record: Recordable) {
|
||||||
|
openModal(true, {
|
||||||
|
record,
|
||||||
|
isUpdate: true,
|
||||||
|
showFooter: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 详情
|
||||||
|
*/
|
||||||
|
function handleDetail(record: Recordable) {
|
||||||
|
openModal(true, {
|
||||||
|
record,
|
||||||
|
isUpdate: true,
|
||||||
|
showFooter: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 删除事件
|
||||||
|
*/
|
||||||
|
async function handleDelete(record) {
|
||||||
|
await deleteOne({id: record.id}, reload);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 批量删除事件
|
||||||
|
*/
|
||||||
|
async function batchHandleDelete() {
|
||||||
|
await batchDelete({ids: checkedKeys.value}, reload);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 成功回调
|
||||||
|
*/
|
||||||
|
function handleSuccess() {
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 操作栏
|
||||||
|
*/
|
||||||
|
function getTableAction(record){
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: '编辑',
|
||||||
|
onClick: handleEdit.bind(null, record),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 下拉操作栏
|
||||||
|
*/
|
||||||
|
function getDropDownAction(record){
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: '详情',
|
||||||
|
onClick: handleDetail.bind(null, record),
|
||||||
|
}, {
|
||||||
|
label: '删除',
|
||||||
|
popConfirm: {
|
||||||
|
title: '是否确认删除',
|
||||||
|
confirm: handleDelete.bind(null, record),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
<#if list_need_category>
|
||||||
|
/**
|
||||||
|
* 初始化字典配置
|
||||||
|
*/
|
||||||
|
function initDictConfig(){
|
||||||
|
<#list columns as po>
|
||||||
|
<#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>
|
||||||
|
<#if po.classType=='cat_tree' && list_need_category==true>
|
||||||
|
loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => {
|
||||||
|
if (res) {
|
||||||
|
let allDictDate = getAuthCache(DB_DICT_DATA_KEY);
|
||||||
|
if(!allDictDate['${po.dictField?default("")}']){
|
||||||
|
Object.assign(allDictDate,{'${po.dictField?default("")}':res})
|
||||||
|
}
|
||||||
|
setAuthCache(DB_DICT_DATA_KEY,allDictDate)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
initDictConfig();
|
||||||
|
</#if>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,61 @@
|
||||||
|
import {defHttp} from '/@/utils/http/axios';
|
||||||
|
import {Modal} from 'ant-design-vue';
|
||||||
|
|
||||||
|
enum Api {
|
||||||
|
list = '/${entityPackage}/${entityName?uncap_first}/list',
|
||||||
|
save='/${entityPackage}/${entityName?uncap_first}/add',
|
||||||
|
edit='/${entityPackage}/${entityName?uncap_first}/edit',
|
||||||
|
deleteOne = '/${entityPackage}/${entityName?uncap_first}/delete',
|
||||||
|
deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
|
||||||
|
importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
|
||||||
|
exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 导出api
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const getExportUrl = Api.exportXls;
|
||||||
|
/**
|
||||||
|
* 导入api
|
||||||
|
*/
|
||||||
|
export const getImportUrl = Api.importExcel;
|
||||||
|
/**
|
||||||
|
* 列表接口
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const list = (params) =>
|
||||||
|
defHttp.get({url: Api.list, params});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除单个
|
||||||
|
*/
|
||||||
|
export const deleteOne = (params,handleSuccess) => {
|
||||||
|
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
||||||
|
handleSuccess();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const batchDelete = (params, handleSuccess) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认删除',
|
||||||
|
content: '是否删除选中数据',
|
||||||
|
okText: '确认',
|
||||||
|
cancelText: '取消',
|
||||||
|
onOk: () => {
|
||||||
|
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||||
|
handleSuccess();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 保存或者更新
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const saveOrUpdate = (params, isUpdate) => {
|
||||||
|
let url = isUpdate ? Api.edit : Api.save;
|
||||||
|
return defHttp.post({url: url, params});
|
||||||
|
}
|
|
@ -0,0 +1,352 @@
|
||||||
|
import {BasicColumn} from '/@/components/Table';
|
||||||
|
import {FormSchema} from '/@/components/Table';
|
||||||
|
import { rules} from '/@/utils/helper/validator';
|
||||||
|
import { render } from '/@/utils/common/renderUtils';
|
||||||
|
//列表数据
|
||||||
|
export const columns: BasicColumn[] = [
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||||
|
{
|
||||||
|
title: '${po.filedComment}',
|
||||||
|
align:"center",
|
||||||
|
<#if po.sort=='Y'>
|
||||||
|
sorter: true,
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
customRender:({text}) =>{
|
||||||
|
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||||
|
},
|
||||||
|
<#elseif po.fieldDbType=='Blob'>
|
||||||
|
dataIndex: '${po.fieldName}String'
|
||||||
|
<#elseif po.classType=='umeditor'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
slots: { customRender: 'htmlSlot' },
|
||||||
|
<#elseif po.classType=='pca'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||||
|
<#elseif po.classType=='file'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
slots: { customRender: 'fileSlot' },
|
||||||
|
<#elseif po.classType=='image'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
customRender:render.renderAvatar,
|
||||||
|
<#elseif po.classType=='switch'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#assign switch_extend_arr=['Y','N']>
|
||||||
|
<#if po.dictField?default("")?contains("[")>
|
||||||
|
<#assign switch_extend_arr=po.dictField?eval>
|
||||||
|
</#if>
|
||||||
|
<#list switch_extend_arr as a>
|
||||||
|
<#if a_index == 0>
|
||||||
|
<#assign switch_extend_arr1=a>
|
||||||
|
<#else>
|
||||||
|
<#assign switch_extend_arr2=a>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
customRender:({text}) => {
|
||||||
|
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||||
|
},
|
||||||
|
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||||
|
dataIndex: '${po.fieldName}_dictText'
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#if po.dictText?default("")?trim?length == 0>
|
||||||
|
customRender:({text}) => {
|
||||||
|
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||||
|
},
|
||||||
|
<#else>
|
||||||
|
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
dataIndex: '${po.fieldName}'
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
];
|
||||||
|
//查询数据
|
||||||
|
export const searchFormSchema: FormSchema[] = [
|
||||||
|
<#-- 开始循环 -->
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.isQuery=='Y'>
|
||||||
|
<#assign query_flag=true>
|
||||||
|
<#assign query_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign query_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
<#if po.queryMode=='single'>
|
||||||
|
{
|
||||||
|
label: "${po.filedComment}",
|
||||||
|
field: "${po.fieldName}",
|
||||||
|
<#if po.classType=='sel_search'>
|
||||||
|
component: 'JSearchSelect',
|
||||||
|
componentProps:{
|
||||||
|
dict:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='sel_user'>
|
||||||
|
component: 'JSelectUserByDept',
|
||||||
|
<#elseif po.classType=='switch'>
|
||||||
|
component: 'JSwitch',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictField != 'is_open'>
|
||||||
|
options:"${po.dictField}"
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='sel_depart'>
|
||||||
|
component: 'JSelectDept',
|
||||||
|
<#elseif po.classType=='list_multi'>
|
||||||
|
component: 'JMultiSelectTag',//暂无该组件
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"query_field_dictCode?default("")"
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
component: 'JCategorySelect',
|
||||||
|
componentProps:{
|
||||||
|
pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='date'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime:true
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='pca'>
|
||||||
|
component: 'JAreaLinkage',
|
||||||
|
<#elseif po.classType=='popup'>
|
||||||
|
component: 'JPopup',
|
||||||
|
componentProps: ({ formActionType }) => {
|
||||||
|
const {setFieldsValue} = formActionType;
|
||||||
|
return{
|
||||||
|
setFieldsValue:setFieldsValue,
|
||||||
|
code:"${po.dictTable}",
|
||||||
|
fieldConfig:"${po.dictField}",
|
||||||
|
multi:${po.extendParams.popupMulti?c},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||||
|
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||||
|
component: 'JDictSelectTag',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
dictCode:"${po.dictField}"
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#else>
|
||||||
|
component: 'Input',
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
{
|
||||||
|
label: "${po.filedComment}",
|
||||||
|
field: "${po.fieldName}",
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
component: 'RangePicker',
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
component: 'RangePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime:true
|
||||||
|
},
|
||||||
|
<#else>
|
||||||
|
component: 'Input', //TODO 范围查询
|
||||||
|
</#if>
|
||||||
|
colProps: {span: 6},
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#-- 结束循环 -->
|
||||||
|
];
|
||||||
|
//表单数据
|
||||||
|
export const formSchema: FormSchema[] = [
|
||||||
|
<#assign form_cat_tree = false>
|
||||||
|
<#assign form_cat_back = "">
|
||||||
|
<#assign bpm_flag=false>
|
||||||
|
<#list columns as po><#rt/>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.isShow =='Y'>
|
||||||
|
<#assign form_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
{
|
||||||
|
label: '${po.filedComment}',
|
||||||
|
field: '${po.fieldName}',
|
||||||
|
<#if po.classType =='date'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
<#elseif po.fieldType =='datetime'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime:true
|
||||||
|
},
|
||||||
|
<#elseif po.fieldType =='time'>
|
||||||
|
component: 'TimePicker',
|
||||||
|
<#elseif po.classType =='popup'>
|
||||||
|
component: 'JPopup',
|
||||||
|
componentProps: ({ formActionType }) => {
|
||||||
|
const {setFieldsValue} = formActionType;
|
||||||
|
return{
|
||||||
|
setFieldsValue:setFieldsValue,
|
||||||
|
code:"${po.dictTable}",
|
||||||
|
fieldConfig:${po.dictField},
|
||||||
|
multi:${po.extendParams.popupMulti?c},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<#elseif po.classType =='sel_depart'>
|
||||||
|
component: 'JSelectDept',
|
||||||
|
<#elseif po.classType =='switch'>
|
||||||
|
component: 'JSwitch',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictField != 'is_open'>
|
||||||
|
options:${po.dictField}
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
<#elseif po.classType =='pca'>
|
||||||
|
component: 'JAreaLinkage',
|
||||||
|
<#elseif po.classType =='markdown'>
|
||||||
|
component: 'JMarkdownEditor',//注意string转换问题
|
||||||
|
<#elseif po.classType =='password'>
|
||||||
|
component: 'InputPassword',
|
||||||
|
<#elseif po.classType =='sel_user'>
|
||||||
|
component: 'JSelectUserByDept',
|
||||||
|
componentProps:{
|
||||||
|
labelKey:'realname',
|
||||||
|
}
|
||||||
|
<#elseif po.classType =='textarea'>
|
||||||
|
component: 'InputTextArea',//TODO 注意string转换问题
|
||||||
|
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||||
|
component: 'JDictSelectTag',
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"${form_field_dictCode}"
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||||
|
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"${form_field_dictCode}"
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='sel_search'>
|
||||||
|
component: 'JSearchSelect',
|
||||||
|
componentProps:{
|
||||||
|
dict:"${form_field_dictCode}"
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
<#assign form_cat_tree = true>
|
||||||
|
component: 'JCategorySelect',
|
||||||
|
componentProps:{
|
||||||
|
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||||
|
}
|
||||||
|
<#if po.dictText?default("")?trim?length gt 1>
|
||||||
|
<#assign form_cat_back = "${po.dictText}">
|
||||||
|
</#if>
|
||||||
|
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
component: 'InputNumber',
|
||||||
|
<#elseif po.classType=='file'>
|
||||||
|
component: 'JUpload',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.uploadnum??>
|
||||||
|
maxCount:${po.uploadnum}
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='image'>
|
||||||
|
component: 'JImageUpload',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.uploadnum??>
|
||||||
|
fileMax:${po.uploadnum}
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='umeditor'>
|
||||||
|
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||||
|
<#elseif po.classType == 'sel_tree'>
|
||||||
|
component: 'JTreeSelect',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictText??>
|
||||||
|
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||||
|
dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}",
|
||||||
|
<#elseif po.dictText?split(',')[1]??>
|
||||||
|
pidField:"${po.dictText?split(',')[1]}",
|
||||||
|
<#elseif po.dictText?split(',')[3]??>
|
||||||
|
hasChildField:"${po.dictText?split(',')[3]}",
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
pidValue:"${po.dictField}",
|
||||||
|
}
|
||||||
|
<#else>
|
||||||
|
component: 'Input',
|
||||||
|
</#if>
|
||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||||
|
dynamicRules: ({model,schema}) => {
|
||||||
|
<#if po.fieldName != 'id'>
|
||||||
|
<#assign fieldValidType = po.fieldValidType!''>
|
||||||
|
return [
|
||||||
|
<#-- 非空校验 -->
|
||||||
|
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||||
|
{ required: true, message: '请输入${po.filedComment}!'},
|
||||||
|
<#elseif fieldValidType!=''>
|
||||||
|
{ required: false},
|
||||||
|
</#if>
|
||||||
|
<#-- 唯一校验 -->
|
||||||
|
<#if fieldValidType == 'only'>
|
||||||
|
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||||
|
<#-- 6到16位数字 -->
|
||||||
|
<#elseif fieldValidType == 'n6-16'>
|
||||||
|
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||||
|
<#-- 6到16位任意字符 -->
|
||||||
|
<#elseif fieldValidType == '*6-16'>
|
||||||
|
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||||
|
<#-- 6到18位字符串 -->
|
||||||
|
<#elseif fieldValidType == 's6-18'>
|
||||||
|
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||||
|
<#-- 网址 -->
|
||||||
|
<#elseif fieldValidType == 'url'>
|
||||||
|
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||||
|
<#-- 电子邮件 -->
|
||||||
|
<#elseif fieldValidType == 'e'>
|
||||||
|
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||||
|
<#-- 手机号码 -->
|
||||||
|
<#elseif fieldValidType == 'm'>
|
||||||
|
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||||
|
<#-- 邮政编码 -->
|
||||||
|
<#elseif fieldValidType == 'p'>
|
||||||
|
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||||
|
<#-- 字母 -->
|
||||||
|
<#elseif fieldValidType == 's'>
|
||||||
|
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||||
|
<#-- 数字 -->
|
||||||
|
<#elseif fieldValidType == 'n'>
|
||||||
|
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||||
|
<#-- 整数 -->
|
||||||
|
<#elseif fieldValidType == 'z'>
|
||||||
|
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||||
|
<#-- 金额 -->
|
||||||
|
<#elseif fieldValidType == 'money'>
|
||||||
|
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||||
|
<#-- 正则校验 -->
|
||||||
|
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||||
|
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||||
|
<#-- 无校验 -->
|
||||||
|
<#else>
|
||||||
|
<#t>
|
||||||
|
</#if>
|
||||||
|
];
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
<#if po.readonly=='Y'>
|
||||||
|
dynamicDisabled:true
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
];
|
|
@ -0,0 +1,58 @@
|
||||||
|
<template>
|
||||||
|
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
|
||||||
|
<BasicForm @register="registerForm"/>
|
||||||
|
</BasicModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {ref, computed, unref} from 'vue';
|
||||||
|
import {BasicModal, useModalInner} from '/@/components/Modal';
|
||||||
|
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||||
|
import {formSchema} from '../${entityName?uncap_first}.data';
|
||||||
|
import {saveOrUpdate} from '../${entityName?uncap_first}.api';
|
||||||
|
// Emits声明
|
||||||
|
const emit = defineEmits(['register','success']);
|
||||||
|
const isUpdate = ref(true);
|
||||||
|
//表单配置
|
||||||
|
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
|
||||||
|
labelWidth: 150,
|
||||||
|
schemas: formSchema,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
});
|
||||||
|
//表单赋值
|
||||||
|
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||||
|
//重置表单
|
||||||
|
await resetFields();
|
||||||
|
setModalProps({confirmLoading: false,showFooter:!!data?.showFooter});
|
||||||
|
isUpdate.value = !!data?.isUpdate;
|
||||||
|
if (unref(isUpdate)) {
|
||||||
|
//表单赋值
|
||||||
|
await setFieldsValue({
|
||||||
|
...data.record,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 隐藏底部时禁用整个表单
|
||||||
|
setProps({ disabled: !data?.showFooter })
|
||||||
|
});
|
||||||
|
//设置标题
|
||||||
|
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||||
|
//表单提交事件
|
||||||
|
async function handleSubmit(v) {
|
||||||
|
try {
|
||||||
|
let values = await validate();
|
||||||
|
setModalProps({confirmLoading: true});
|
||||||
|
//提交表单
|
||||||
|
await saveOrUpdate(values, isUpdate.value);
|
||||||
|
//关闭弹窗
|
||||||
|
closeModal();
|
||||||
|
//刷新列表
|
||||||
|
emit('success');
|
||||||
|
} finally {
|
||||||
|
setModalProps({confirmLoading: false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -266,6 +266,34 @@
|
||||||
<#if col.readonly=='Y'>
|
<#if col.readonly=='Y'>
|
||||||
disabled:true,
|
disabled:true,
|
||||||
</#if>
|
</#if>
|
||||||
|
<#elseif col.classType =='sel_depart'>
|
||||||
|
type: FormTypes.sel_depart,
|
||||||
|
<#if col.extendParams.multiSelect?default(true) == false>
|
||||||
|
multi: false,
|
||||||
|
</#if>
|
||||||
|
<#if col.extendParams.store?default("")?trim?length gt 1>
|
||||||
|
store: "${col.extendParams.store}",
|
||||||
|
</#if>
|
||||||
|
<#if col.extendParams.text?default("")?trim?length gt 1>
|
||||||
|
text: "${col.extendParams.text}",
|
||||||
|
</#if>
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#elseif col.classType =='sel_user'>
|
||||||
|
type: FormTypes.sel_user,
|
||||||
|
<#if col.extendParams.multiSelect?default(true) == false>
|
||||||
|
multi: false,
|
||||||
|
</#if>
|
||||||
|
<#if col.extendParams.store?default("")?trim?length gt 1>
|
||||||
|
store: "${col.extendParams.store}",
|
||||||
|
</#if>
|
||||||
|
<#if col.extendParams.text?default("")?trim?length gt 1>
|
||||||
|
text: "${col.extendParams.text}",
|
||||||
|
</#if>
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled: true,
|
||||||
|
</#if>
|
||||||
<#elseif col.classType =='image'>
|
<#elseif col.classType =='image'>
|
||||||
type: FormTypes.image,
|
type: FormTypes.image,
|
||||||
token:true,
|
token:true,
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
import {defHttp} from "/@/utils/http/axios";
|
||||||
|
import {Modal} from 'ant-design-vue';
|
||||||
|
|
||||||
|
enum Api {
|
||||||
|
list = '/${entityPackage}/${entityName?uncap_first}/rootList',
|
||||||
|
save='/${entityPackage}/${entityName?uncap_first}/add',
|
||||||
|
edit='/${entityPackage}/${entityName?uncap_first}/edit',
|
||||||
|
delete${entityName} = '/sys/${entityName?uncap_first}/delete',
|
||||||
|
deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
|
||||||
|
importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
|
||||||
|
exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
|
||||||
|
loadTreeData = '/${entityPackage}/${entityName?uncap_first}/loadTreeRoot',
|
||||||
|
getChildList = '/${entityPackage}/${entityName?uncap_first}/childList',
|
||||||
|
getChildListBatch = '/${entityPackage}/${entityName?uncap_first}/getChildListBatch',
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 导出api
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const getExportUrl = Api.exportXls;
|
||||||
|
/**
|
||||||
|
* 导入api
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const getImportUrl = Api.importExcel;
|
||||||
|
/**
|
||||||
|
* 列表接口
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const list = (params) =>
|
||||||
|
defHttp.get({url: Api.list, params});
|
||||||
|
/**
|
||||||
|
* 删除
|
||||||
|
*/
|
||||||
|
export const delete${entityName} = (params,handleSuccess) => {
|
||||||
|
return defHttp.delete({url: Api.delete${entityName}, params}, {joinParamsToUrl: true}).then(() => {
|
||||||
|
handleSuccess();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const batchDelete${entityName} = (params, handleSuccess) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认删除',
|
||||||
|
content: '是否删除选中数据',
|
||||||
|
okText: '确认',
|
||||||
|
cancelText: '取消',
|
||||||
|
onOk: () => {
|
||||||
|
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||||
|
handleSuccess();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 保存或者更新
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const saveOrUpdateDict = (params, isUpdate) => {
|
||||||
|
let url = isUpdate ? Api.edit : Api.save;
|
||||||
|
return defHttp.post({url: url, params});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 查询全部树形节点数据
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const loadTreeData = (params) =>
|
||||||
|
defHttp.get({url: Api.loadTreeData,params});
|
||||||
|
/**
|
||||||
|
* 查询子节点数据
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const getChildList = (params) =>
|
||||||
|
defHttp.get({url: Api.getChildList, params});
|
||||||
|
/**
|
||||||
|
* 批量查询子节点数据
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const getChildListBatch = (params) =>
|
||||||
|
defHttp.get({url: Api.getChildListBatch, params},{isTransformResponse:false});
|
|
@ -0,0 +1,352 @@
|
||||||
|
import {BasicColumn} from '/@/components/Table';
|
||||||
|
import {FormSchema} from '/@/components/Table';
|
||||||
|
import { rules} from '/@/utils/helper/validator';
|
||||||
|
import { render } from '/@/utils/common/renderUtils';
|
||||||
|
//列表数据
|
||||||
|
export const columns: BasicColumn[] = [
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||||
|
{
|
||||||
|
title: '${po.filedComment}',
|
||||||
|
align:"center",
|
||||||
|
<#if po.sort=='Y'>
|
||||||
|
sorter: true,
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
customRender:({text}) =>{
|
||||||
|
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||||
|
},
|
||||||
|
<#elseif po.fieldDbType=='Blob'>
|
||||||
|
dataIndex: '${po.fieldName}String'
|
||||||
|
<#elseif po.classType=='umeditor'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
slots: { customRender: 'htmlSlot' },
|
||||||
|
<#elseif po.classType=='pca'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||||
|
<#elseif po.classType=='file'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
slots: { customRender: 'fileSlot' },
|
||||||
|
<#elseif po.classType=='image'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
customRender:render.renderAvatar,
|
||||||
|
<#elseif po.classType=='switch'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#assign switch_extend_arr=['Y','N']>
|
||||||
|
<#if po.dictField?default("")?contains("[")>
|
||||||
|
<#assign switch_extend_arr=po.dictField?eval>
|
||||||
|
</#if>
|
||||||
|
<#list switch_extend_arr as a>
|
||||||
|
<#if a_index == 0>
|
||||||
|
<#assign switch_extend_arr1=a>
|
||||||
|
<#else>
|
||||||
|
<#assign switch_extend_arr2=a>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
customRender:({text}) => {
|
||||||
|
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||||
|
},
|
||||||
|
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||||
|
dataIndex: '${po.fieldName}_dictText'
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#if po.dictText?default("")?trim?length == 0>
|
||||||
|
customRender:({text}) => {
|
||||||
|
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||||
|
},
|
||||||
|
<#else>
|
||||||
|
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
dataIndex: '${po.fieldName}'
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
];
|
||||||
|
//查询数据
|
||||||
|
export const searchFormSchema: FormSchema[] = [
|
||||||
|
<#-- 开始循环 -->
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.isQuery=='Y'>
|
||||||
|
<#assign query_flag=true>
|
||||||
|
<#assign query_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign query_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
<#if po.queryMode=='single'>
|
||||||
|
{
|
||||||
|
label: "${po.filedComment}",
|
||||||
|
field: "${po.fieldName}",
|
||||||
|
<#if po.classType=='sel_search'>
|
||||||
|
component: 'JSearchSelect',
|
||||||
|
componentProps:{
|
||||||
|
dict:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='sel_user'>
|
||||||
|
component: 'JSelectUserByDept',
|
||||||
|
<#elseif po.classType=='switch'>
|
||||||
|
component: 'JSwitch',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictField != 'is_open'>
|
||||||
|
options:"${po.dictField}"
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='sel_depart'>
|
||||||
|
component: 'JSelectDept',
|
||||||
|
<#elseif po.classType=='list_multi'>
|
||||||
|
component: 'JMultiSelectTag',//暂无该组件
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"query_field_dictCode?default("")"
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
component: 'JCategorySelect',
|
||||||
|
componentProps:{
|
||||||
|
pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='date'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime:true
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='pca'>
|
||||||
|
component: 'JAreaLinkage',
|
||||||
|
<#elseif po.classType=='popup'>
|
||||||
|
component: 'JPopup',
|
||||||
|
componentProps: ({ formActionType }) => {
|
||||||
|
const {setFieldsValue} = formActionType;
|
||||||
|
return{
|
||||||
|
setFieldsValue:setFieldsValue,
|
||||||
|
code:"${po.dictTable}",
|
||||||
|
fieldConfig:"${po.dictField}",
|
||||||
|
multi:${po.extendParams.popupMulti?c},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||||
|
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||||
|
component: 'JDictSelectTag',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
dictCode:"${po.dictField}"
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#else>
|
||||||
|
component: 'Input',
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
{
|
||||||
|
label: "${po.filedComment}",
|
||||||
|
field: "${po.fieldName}",
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
component: 'RangePicker',
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
component: 'RangePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime:true
|
||||||
|
},
|
||||||
|
<#else>
|
||||||
|
component: 'Input', //TODO 范围查询
|
||||||
|
</#if>
|
||||||
|
colProps: {span: 6},
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#-- 结束循环 -->
|
||||||
|
];
|
||||||
|
//表单数据
|
||||||
|
export const formSchema: FormSchema[] = [
|
||||||
|
<#assign form_cat_tree = false>
|
||||||
|
<#assign form_cat_back = "">
|
||||||
|
<#assign bpm_flag=false>
|
||||||
|
<#list columns as po><#rt/>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.isShow =='Y'>
|
||||||
|
<#assign form_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
{
|
||||||
|
label: '${po.filedComment}',
|
||||||
|
field: '${po.fieldName}',
|
||||||
|
<#if po.classType =='date'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
<#elseif po.fieldType =='datetime'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime:true
|
||||||
|
},
|
||||||
|
<#elseif po.fieldType =='time'>
|
||||||
|
component: 'TimePicker',
|
||||||
|
<#elseif po.classType =='popup'>
|
||||||
|
component: 'JPopup',
|
||||||
|
componentProps: ({ formActionType }) => {
|
||||||
|
const {setFieldsValue} = formActionType;
|
||||||
|
return{
|
||||||
|
setFieldsValue:setFieldsValue,
|
||||||
|
code:"${po.dictTable}",
|
||||||
|
fieldConfig:${po.dictField},
|
||||||
|
multi:${po.extendParams.popupMulti?c},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<#elseif po.classType =='sel_depart'>
|
||||||
|
component: 'JSelectDept',
|
||||||
|
<#elseif po.classType =='switch'>
|
||||||
|
component: 'JSwitch',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictField != 'is_open'>
|
||||||
|
options:${po.dictField}
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
<#elseif po.classType =='pca'>
|
||||||
|
component: 'JAreaLinkage',
|
||||||
|
<#elseif po.classType =='markdown'>
|
||||||
|
component: 'JMarkdownEditor',//注意string转换问题
|
||||||
|
<#elseif po.classType =='password'>
|
||||||
|
component: 'InputPassword',
|
||||||
|
<#elseif po.classType =='sel_user'>
|
||||||
|
component: 'JSelectUserByDept',
|
||||||
|
componentProps:{
|
||||||
|
labelKey:'realname',
|
||||||
|
}
|
||||||
|
<#elseif po.classType =='textarea'>
|
||||||
|
component: 'InputTextArea',//TODO 注意string转换问题
|
||||||
|
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||||
|
component: 'JDictSelectTag',
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"${form_field_dictCode}"
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||||
|
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"${form_field_dictCode}"
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='sel_search'>
|
||||||
|
component: 'JSearchSelect',
|
||||||
|
componentProps:{
|
||||||
|
dict:"${form_field_dictCode}"
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
<#assign form_cat_tree = true>
|
||||||
|
component: 'JCategorySelect',
|
||||||
|
componentProps:{
|
||||||
|
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||||
|
}
|
||||||
|
<#if po.dictText?default("")?trim?length gt 1>
|
||||||
|
<#assign form_cat_back = "${po.dictText}">
|
||||||
|
</#if>
|
||||||
|
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
component: 'InputNumber',
|
||||||
|
<#elseif po.classType=='file'>
|
||||||
|
component: 'JUpload',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.uploadnum??>
|
||||||
|
maxCount:${po.uploadnum}
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='image'>
|
||||||
|
component: 'JImageUpload',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.uploadnum??>
|
||||||
|
fileMax:${po.uploadnum}
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='umeditor'>
|
||||||
|
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||||
|
<#elseif po.classType == 'sel_tree'>
|
||||||
|
component: 'JTreeSelect',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictText??>
|
||||||
|
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||||
|
dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}",
|
||||||
|
<#elseif po.dictText?split(',')[1]??>
|
||||||
|
pidField:"${po.dictText?split(',')[1]}",
|
||||||
|
<#elseif po.dictText?split(',')[3]??>
|
||||||
|
hasChildField:"${po.dictText?split(',')[3]}",
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
pidValue:"${po.dictField}",
|
||||||
|
}
|
||||||
|
<#else>
|
||||||
|
component: 'Input',
|
||||||
|
</#if>
|
||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||||
|
dynamicRules: ({model,schema}) => {
|
||||||
|
<#if po.fieldName != 'id'>
|
||||||
|
<#assign fieldValidType = po.fieldValidType!''>
|
||||||
|
return [
|
||||||
|
<#-- 非空校验 -->
|
||||||
|
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||||
|
{ required: true, message: '请输入${po.filedComment}!'},
|
||||||
|
<#elseif fieldValidType!=''>
|
||||||
|
{ required: false},
|
||||||
|
</#if>
|
||||||
|
<#-- 唯一校验 -->
|
||||||
|
<#if fieldValidType == 'only'>
|
||||||
|
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||||
|
<#-- 6到16位数字 -->
|
||||||
|
<#elseif fieldValidType == 'n6-16'>
|
||||||
|
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||||
|
<#-- 6到16位任意字符 -->
|
||||||
|
<#elseif fieldValidType == '*6-16'>
|
||||||
|
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||||
|
<#-- 6到18位字符串 -->
|
||||||
|
<#elseif fieldValidType == 's6-18'>
|
||||||
|
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||||
|
<#-- 网址 -->
|
||||||
|
<#elseif fieldValidType == 'url'>
|
||||||
|
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||||
|
<#-- 电子邮件 -->
|
||||||
|
<#elseif fieldValidType == 'e'>
|
||||||
|
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||||
|
<#-- 手机号码 -->
|
||||||
|
<#elseif fieldValidType == 'm'>
|
||||||
|
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||||
|
<#-- 邮政编码 -->
|
||||||
|
<#elseif fieldValidType == 'p'>
|
||||||
|
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||||
|
<#-- 字母 -->
|
||||||
|
<#elseif fieldValidType == 's'>
|
||||||
|
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||||
|
<#-- 数字 -->
|
||||||
|
<#elseif fieldValidType == 'n'>
|
||||||
|
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||||
|
<#-- 整数 -->
|
||||||
|
<#elseif fieldValidType == 'z'>
|
||||||
|
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||||
|
<#-- 金额 -->
|
||||||
|
<#elseif fieldValidType == 'money'>
|
||||||
|
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||||
|
<#-- 正则校验 -->
|
||||||
|
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||||
|
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||||
|
<#-- 无校验 -->
|
||||||
|
<#else>
|
||||||
|
<#t>
|
||||||
|
</#if>
|
||||||
|
];
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
<#if po.readonly=='Y'>
|
||||||
|
dynamicDisabled:true
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
];
|
|
@ -0,0 +1,87 @@
|
||||||
|
<template>
|
||||||
|
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
|
||||||
|
<BasicForm @register="registerForm"/>
|
||||||
|
</BasicModal>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {ref, computed, unref} from 'vue';
|
||||||
|
import {BasicModal, useModalInner} from '/src/components/Modal';
|
||||||
|
import {BasicForm, useForm} from '/src/components/Form';
|
||||||
|
import {formSchema} from '../${entityName?uncap_first}.data';
|
||||||
|
import {loadTreeData, saveOrUpdateDict} from '../${entityName?uncap_first}.api';
|
||||||
|
// 获取emit
|
||||||
|
const emit = defineEmits(['register', 'success']);
|
||||||
|
const isUpdate = ref(true);
|
||||||
|
const expandedRowKeys = ref([]);
|
||||||
|
const treeData = ref([]);
|
||||||
|
//表单配置
|
||||||
|
const [registerForm, {resetFields, setFieldsValue, validate, updateSchema}] = useForm({
|
||||||
|
schemas: formSchema,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
labelCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 4 },
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 18 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
//表单赋值
|
||||||
|
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||||
|
//重置表单
|
||||||
|
await resetFields();
|
||||||
|
expandedRowKeys.value = [];
|
||||||
|
setModalProps({confirmLoading: false, minHeight: 80});
|
||||||
|
isUpdate.value = !!data?.isUpdate;
|
||||||
|
if (data?.record) {
|
||||||
|
//表单赋值
|
||||||
|
await setFieldsValue({
|
||||||
|
...data.record,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//父级节点树信息
|
||||||
|
treeData.value = await loadTreeData({'async': false,'pcode':''});
|
||||||
|
updateSchema({
|
||||||
|
field: 'pid',
|
||||||
|
componentProps: {treeData},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//设置标题
|
||||||
|
const getTitle = computed(() => (!unref(isUpdate) ? '新增字典' : '编辑字典'));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据pid获取展开的节点
|
||||||
|
* @param pid
|
||||||
|
* @param arr
|
||||||
|
*/
|
||||||
|
function getExpandKeysByPid(pid,arr){
|
||||||
|
if(pid && arr && arr.length>0){
|
||||||
|
for(let i=0;i<arr.length;i++){
|
||||||
|
if(arr[i].key==pid && unref(expandedRowKeys).indexOf(pid)<0){
|
||||||
|
expandedRowKeys.value.push(arr[i].key);
|
||||||
|
getExpandKeysByPid(arr[i]['parentId'],unref(treeData))
|
||||||
|
}else{
|
||||||
|
getExpandKeysByPid(pid,arr[i].children)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//表单提交事件
|
||||||
|
async function handleSubmit() {
|
||||||
|
try {
|
||||||
|
let values = await validate();
|
||||||
|
setModalProps({confirmLoading: true});
|
||||||
|
//提交表单
|
||||||
|
await saveOrUpdateDict(values, isUpdate.value);
|
||||||
|
//关闭弹窗
|
||||||
|
closeModal();
|
||||||
|
//展开的节点信息
|
||||||
|
await getExpandKeysByPid(values['pid'],unref(treeData))
|
||||||
|
//刷新列表(isUpdate:是否编辑;values:表单信息;expandedArr:展开的节点信息)
|
||||||
|
emit('success', {isUpdate: unref(isUpdate), values:{...values},expandedArr: unref(expandedRowKeys).reverse()});
|
||||||
|
} finally {
|
||||||
|
setModalProps({confirmLoading: false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,295 @@
|
||||||
|
<template>
|
||||||
|
<div class="p-4">
|
||||||
|
<!--引用表格-->
|
||||||
|
<BasicTable @register="registerTable" :rowSelection="rowSelection" :expandedRowKeys="expandedRowKeys" @expand="handleExpand" @fetch-success="onFetchSuccess">
|
||||||
|
<!--插槽:table标题-->
|
||||||
|
<template #tableTitle>
|
||||||
|
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate"> 新增</a-button>
|
||||||
|
<a-upload name="file" :showUploadList="false" :customRequest="(file)=>handleImportXls(file,getImportUrl,importSuccess)">
|
||||||
|
<a-button type="primary" preIcon="ant-design:import-outlined">导入</a-button>
|
||||||
|
</a-upload>
|
||||||
|
<a-button type="primary" preIcon="ant-design:export-outlined" @click="handleExportXls('${tableVo.ftlDescription}管理',getExportUrl)"> 导出</a-button>
|
||||||
|
|
||||||
|
<a-dropdown v-if="checkedKeys.length > 0">
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu>
|
||||||
|
<a-menu-item key="1" @click="batchHandleDelete">
|
||||||
|
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||||
|
删除
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
<a-button>批量操作
|
||||||
|
<Icon icon="ant-design:down-outlined"></Icon>
|
||||||
|
</a-button>
|
||||||
|
</a-dropdown>
|
||||||
|
</template>
|
||||||
|
<!--操作栏-->
|
||||||
|
<template #action="{ record }">
|
||||||
|
<TableAction :actions="getTableAction(record)"/>
|
||||||
|
</template>
|
||||||
|
</BasicTable>
|
||||||
|
<!--字典弹窗-->
|
||||||
|
<${entityName}Modal @register="registerModal" @success="handleSuccess"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
//ts语法
|
||||||
|
import {ref, computed, unref, toRaw, nextTick} from 'vue';
|
||||||
|
import {BasicTable, useTable, TableAction} from '/src/components/Table';
|
||||||
|
import {useDrawer} from '/src/components/Drawer';
|
||||||
|
import ${entityName}Modal from './components/${entityName}Modal.vue';
|
||||||
|
import {useModal} from '/src/components/Modal';
|
||||||
|
import {useMethods} from '/src/hooks/system/useMethods';
|
||||||
|
import {columns} from './${entityName}.data';
|
||||||
|
import {list, delete${entityName}, batchDelete${entityName}, getExportUrl,getImportUrl, getChildList,getChildListBatch} from './${entityName}.api';
|
||||||
|
|
||||||
|
const checkedKeys = ref<Array<string | number>>([]);
|
||||||
|
const expandedRowKeys = ref([]);
|
||||||
|
const {handleExportXls,handleImportXls} = useMethods();
|
||||||
|
//字典model
|
||||||
|
const [registerModal, {openModal}] = useModal();
|
||||||
|
//注册table数据
|
||||||
|
const [registerTable, {reload, collapseAll, updateTableDataRecord, findTableDataRecord,getDataSource}] = useTable({
|
||||||
|
api: list,
|
||||||
|
rowKey: 'id',
|
||||||
|
columns,
|
||||||
|
striped: true,
|
||||||
|
useSearchForm: false,
|
||||||
|
showTableSetting: true,
|
||||||
|
clickToRowSelect: false,
|
||||||
|
bordered: true,
|
||||||
|
showIndexColumn: false,
|
||||||
|
tableSetting: {fullScreen: true},
|
||||||
|
canResize: false,
|
||||||
|
actionColumn: {
|
||||||
|
width: 80,
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
slots: {customRender: 'action'},
|
||||||
|
fixed: undefined,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择列配置
|
||||||
|
*/
|
||||||
|
const rowSelection = {
|
||||||
|
type: 'checkbox',
|
||||||
|
columnWidth: 10,
|
||||||
|
selectedRowKeys: checkedKeys,
|
||||||
|
onChange: onSelectChange
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择事件
|
||||||
|
*/
|
||||||
|
function onSelectChange(selectedRowKeys: (string | number)[]) {
|
||||||
|
checkedKeys.value = selectedRowKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增事件
|
||||||
|
*/
|
||||||
|
function handleCreate() {
|
||||||
|
openModal(true, {
|
||||||
|
isUpdate: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑事件
|
||||||
|
*/
|
||||||
|
async function handleEdit(record) {
|
||||||
|
openModal(true, {
|
||||||
|
record,
|
||||||
|
isUpdate: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 详情
|
||||||
|
*/
|
||||||
|
async function handleDetail(record) {
|
||||||
|
openModal(true, {
|
||||||
|
record,
|
||||||
|
isUpdate: true,
|
||||||
|
hideFooter: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除事件
|
||||||
|
*/
|
||||||
|
async function handleDelete(record) {
|
||||||
|
await delete${entityName}({id: record.id}, importSuccess);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除事件
|
||||||
|
*/
|
||||||
|
async function batchHandleDelete() {
|
||||||
|
const ids = checkedKeys.value.filter(item => !item.includes('loading'))
|
||||||
|
await batchDelete${entityName}({ids: ids}, importSuccess);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 导入
|
||||||
|
*/
|
||||||
|
function importSuccess() {
|
||||||
|
reload() && (expandedRowKeys.value = []);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 添加下级
|
||||||
|
*/
|
||||||
|
function handleAddSub(record) {
|
||||||
|
openModal(true, {
|
||||||
|
record,
|
||||||
|
isUpdate: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 成功回调
|
||||||
|
*/
|
||||||
|
async function handleSuccess({isUpdate, values, expandedArr}) {
|
||||||
|
if (isUpdate) {
|
||||||
|
//编辑回调
|
||||||
|
updateTableDataRecord(values.id, values);
|
||||||
|
} else {
|
||||||
|
if(!values['pid']){
|
||||||
|
//新增根节点
|
||||||
|
reload();
|
||||||
|
}else{
|
||||||
|
//新增子集
|
||||||
|
expandedRowKeys.value = [];
|
||||||
|
for (let key of unref(expandedArr)) {
|
||||||
|
await expandTreeNode(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口请求成功后回调
|
||||||
|
*/
|
||||||
|
function onFetchSuccess(result) {
|
||||||
|
getDataByResult(result.items)&&loadDataByExpandedRows();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 根据已展开的行查询数据(用于保存后刷新时异步加载子级的数据)
|
||||||
|
*/
|
||||||
|
async function loadDataByExpandedRows() {
|
||||||
|
if (unref(expandedRowKeys).length > 0) {
|
||||||
|
const res = await getChildListBatch({ parentIds: unref(expandedRowKeys).join(',')});
|
||||||
|
if (res.success && res.result.records.length>0) {
|
||||||
|
//已展开的数据批量子节点
|
||||||
|
let records = res.result.records
|
||||||
|
const listMap = new Map();
|
||||||
|
for (let item of records) {
|
||||||
|
let pid = item['pid'];
|
||||||
|
if (unref(expandedRowKeys).includes(pid)) {
|
||||||
|
let mapList = listMap.get(pid);
|
||||||
|
if (mapList == null) {
|
||||||
|
mapList = [];
|
||||||
|
}
|
||||||
|
mapList.push(item);
|
||||||
|
listMap.set(pid, mapList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let childrenMap = listMap;
|
||||||
|
let fn = (list) => {
|
||||||
|
if(list) {
|
||||||
|
list.forEach(data => {
|
||||||
|
if (unref(expandedRowKeys).includes(data.id)) {
|
||||||
|
data.children = getDataByResult(childrenMap.get(data.id))
|
||||||
|
fn(data.children)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fn(getDataSource())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 处理数据集
|
||||||
|
*/
|
||||||
|
function getDataByResult(result){
|
||||||
|
if(result && result.length>0){
|
||||||
|
return result.map(item=>{
|
||||||
|
//判断是否标记了带有子节点
|
||||||
|
if(item["hasChild"]=='1'){
|
||||||
|
let loadChild = { id: item.id+'_loadChild', name: 'loading...', isLoading: true }
|
||||||
|
item.children = [loadChild]
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*树节点展开合并
|
||||||
|
* */
|
||||||
|
async function handleExpand(expanded, record) {
|
||||||
|
// 判断是否是展开状态,展开状态(expanded)并且存在子集(children)并且未加载过(isLoading)的就去查询子节点数据
|
||||||
|
if (expanded) {
|
||||||
|
expandedRowKeys.value.push(record.id)
|
||||||
|
if (record.children.length > 0 && !!record.children[0].isLoading) {
|
||||||
|
let result = await getChildList({pid: record.id});
|
||||||
|
result=result.records?result.records:result;
|
||||||
|
if (result && result.length > 0) {
|
||||||
|
record.children = getDataByResult(result);
|
||||||
|
} else {
|
||||||
|
record.children = null
|
||||||
|
record.hasChild = '0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let keyIndex = expandedRowKeys.value.indexOf(record.id)
|
||||||
|
if (keyIndex >= 0) {
|
||||||
|
expandedRowKeys.value.splice(keyIndex, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*操作表格后处理树节点展开合并
|
||||||
|
* */
|
||||||
|
async function expandTreeNode(key) {
|
||||||
|
let record = findTableDataRecord(key)
|
||||||
|
expandedRowKeys.value.push(key);
|
||||||
|
let result = await getChildList({pid: key});
|
||||||
|
if (result && result.length > 0) {
|
||||||
|
record.children = getDataByResult(result);
|
||||||
|
} else {
|
||||||
|
record.children = null
|
||||||
|
record.hasChild = '0'
|
||||||
|
}
|
||||||
|
updateTableDataRecord(key, record);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 操作栏
|
||||||
|
*/
|
||||||
|
function getTableAction(record) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: '编辑',
|
||||||
|
onClick: handleEdit.bind(null, record),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '删除',
|
||||||
|
popConfirm: {
|
||||||
|
title: '确定删除吗?',
|
||||||
|
confirm: handleDelete.bind(null, record),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '添加下级',
|
||||||
|
onClick: handleAddSub.bind(null, {pid: record.id}),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -255,6 +255,34 @@
|
||||||
<#if col.readonly=='Y'>
|
<#if col.readonly=='Y'>
|
||||||
disabled:true,
|
disabled:true,
|
||||||
</#if>
|
</#if>
|
||||||
|
<#elseif col.classType =='sel_depart'>
|
||||||
|
type: FormTypes.sel_depart,
|
||||||
|
<#if col.extendParams.multiSelect?default(true) == false>
|
||||||
|
multi: false,
|
||||||
|
</#if>
|
||||||
|
<#if col.extendParams.store?default("")?trim?length gt 1>
|
||||||
|
store: "${col.extendParams.store}",
|
||||||
|
</#if>
|
||||||
|
<#if col.extendParams.text?default("")?trim?length gt 1>
|
||||||
|
text: "${col.extendParams.text}",
|
||||||
|
</#if>
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#elseif col.classType =='sel_user'>
|
||||||
|
type: FormTypes.sel_user,
|
||||||
|
<#if col.extendParams.multiSelect?default(true) == false>
|
||||||
|
multi: false,
|
||||||
|
</#if>
|
||||||
|
<#if col.extendParams.store?default("")?trim?length gt 1>
|
||||||
|
store: "${col.extendParams.store}",
|
||||||
|
</#if>
|
||||||
|
<#if col.extendParams.text?default("")?trim?length gt 1>
|
||||||
|
text: "${col.extendParams.text}",
|
||||||
|
</#if>
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled: true,
|
||||||
|
</#if>
|
||||||
<#elseif col.classType =='image'>
|
<#elseif col.classType =='image'>
|
||||||
type: FormTypes.image,
|
type: FormTypes.image,
|
||||||
token:true,
|
token:true,
|
||||||
|
|
|
@ -119,7 +119,7 @@ public class ${entityName}Controller {
|
||||||
*/
|
*/
|
||||||
@AutoLog(value = "${tableVo.ftlDescription}-编辑")
|
@AutoLog(value = "${tableVo.ftlDescription}-编辑")
|
||||||
@ApiOperation(value="${tableVo.ftlDescription}-编辑", notes="${tableVo.ftlDescription}-编辑")
|
@ApiOperation(value="${tableVo.ftlDescription}-编辑", notes="${tableVo.ftlDescription}-编辑")
|
||||||
@PutMapping(value = "/edit")
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
public Result<?> edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) {
|
public Result<?> edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) {
|
||||||
${entityName} ${entityName?uncap_first} = new ${entityName}();
|
${entityName} ${entityName?uncap_first} = new ${entityName}();
|
||||||
BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first});
|
BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first});
|
||||||
|
|
|
@ -266,6 +266,34 @@
|
||||||
<#if col.readonly=='Y'>
|
<#if col.readonly=='Y'>
|
||||||
disabled:true,
|
disabled:true,
|
||||||
</#if>
|
</#if>
|
||||||
|
<#elseif col.classType =='sel_depart'>
|
||||||
|
type: JVXETypes.departSelect,
|
||||||
|
<#if col.extendParams.multiSelect?default(true) == false>
|
||||||
|
multi: false,
|
||||||
|
</#if>
|
||||||
|
<#if col.extendParams.store?default("")?trim?length gt 1>
|
||||||
|
store: "${col.extendParams.store}",
|
||||||
|
</#if>
|
||||||
|
<#if col.extendParams.text?default("")?trim?length gt 1>
|
||||||
|
text: "${col.extendParams.text}",
|
||||||
|
</#if>
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#elseif col.classType =='sel_user'>
|
||||||
|
type: JVXETypes.userSelect,
|
||||||
|
<#if col.extendParams.multiSelect?default(true) == false>
|
||||||
|
multi: false,
|
||||||
|
</#if>
|
||||||
|
<#if col.extendParams.store?default("")?trim?length gt 1>
|
||||||
|
store: "${col.extendParams.store}",
|
||||||
|
</#if>
|
||||||
|
<#if col.extendParams.text?default("")?trim?length gt 1>
|
||||||
|
text: "${col.extendParams.text}",
|
||||||
|
</#if>
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled: true,
|
||||||
|
</#if>
|
||||||
<#elseif col.classType =='image'>
|
<#elseif col.classType =='image'>
|
||||||
type: JVXETypes.image,
|
type: JVXETypes.image,
|
||||||
token:true,
|
token:true,
|
||||||
|
|
|
@ -0,0 +1,244 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<#assign list_need_category=false>
|
||||||
|
<#assign list_need_pca=false>
|
||||||
|
<#assign bpm_flag=false>
|
||||||
|
|
||||||
|
<#-- 开始循环 -->
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='cat_tree' && po.dictText?default("")?trim?length == 0>
|
||||||
|
<#assign list_need_category=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='pca'>
|
||||||
|
<#assign list_need_pca=true>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#-- 结束循环 -->
|
||||||
|
<!--引用表格-->
|
||||||
|
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||||
|
<!--插槽:table标题-->
|
||||||
|
<template #tableTitle>
|
||||||
|
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||||
|
<ExcelButton :config="excelConfig"></ExcelButton>
|
||||||
|
<a-dropdown v-if="checkedKeys.length > 0">
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu>
|
||||||
|
<a-menu-item key="1" @click="batchHandleDelete">
|
||||||
|
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||||
|
删除
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
<a-button>批量操作
|
||||||
|
<Icon icon="mdi:chevron-down"></Icon>
|
||||||
|
</a-button>
|
||||||
|
</a-dropdown>
|
||||||
|
</template>
|
||||||
|
<!--操作栏-->
|
||||||
|
<template #action="{ record }">
|
||||||
|
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
|
||||||
|
</template>
|
||||||
|
<!--字段回显插槽-->
|
||||||
|
<template #htmlSlot="{text}">
|
||||||
|
<div v-html="text"></div>
|
||||||
|
</template>
|
||||||
|
<template #fileSlot="{text}">
|
||||||
|
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||||
|
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
|
||||||
|
</template>
|
||||||
|
</BasicTable>
|
||||||
|
<!-- 表单区域 -->
|
||||||
|
<${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {ref, computed, unref} from 'vue';
|
||||||
|
import {BasicTable, useTable, TableAction} from '/@/components/Table';
|
||||||
|
import ExcelButton from '/@/components/jeecg/ExcelButton.vue'
|
||||||
|
import {useModal} from '/@/components/Modal';
|
||||||
|
import ${entityName}Modal from './components/${entityName}Modal.vue'
|
||||||
|
import {columns, searchFormSchema} from './${entityName?uncap_first}.data';
|
||||||
|
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName?uncap_first}.api';
|
||||||
|
<#if list_need_category>
|
||||||
|
import { loadCategoryData } from '/@/api/common/api'
|
||||||
|
import { getAuthCache, setAuthCache } from '/@/utils/auth';
|
||||||
|
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
|
||||||
|
</#if>
|
||||||
|
const checkedKeys = ref<Array<string | number>>([]);
|
||||||
|
//注册model
|
||||||
|
const [registerModal, {openModal}] = useModal();
|
||||||
|
//注册table数据
|
||||||
|
const [registerTable, {reload}] = useTable({
|
||||||
|
title: '${tableVo.ftlDescription}',
|
||||||
|
api: list,
|
||||||
|
rowKey: 'id',
|
||||||
|
columns,
|
||||||
|
formConfig: {
|
||||||
|
labelWidth: 120,
|
||||||
|
schemas: searchFormSchema,
|
||||||
|
autoSubmitOnEnter:true,
|
||||||
|
showAdvancedButton:true,
|
||||||
|
fieldMapToTime: [
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.isQuery=='Y'>
|
||||||
|
<#if po.queryMode!='single'>
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD'],
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD HH:mm:ss'],
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
],
|
||||||
|
},
|
||||||
|
striped: true,
|
||||||
|
useSearchForm: true,
|
||||||
|
showTableSetting: true,
|
||||||
|
clickToRowSelect: false,
|
||||||
|
bordered: true,
|
||||||
|
showIndexColumn: false,
|
||||||
|
tableSetting: {fullScreen: true},
|
||||||
|
actionColumn: {
|
||||||
|
width: 120,
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
slots: {customRender: 'action'},
|
||||||
|
fixed: 'right',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* excel导入导出配置
|
||||||
|
*/
|
||||||
|
const excelConfig = {
|
||||||
|
export: {
|
||||||
|
name:'${tableVo.ftlDescription}',
|
||||||
|
url: getExportUrl,
|
||||||
|
},
|
||||||
|
import: {
|
||||||
|
url: getImportUrl,
|
||||||
|
success: reload,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 选择列配置
|
||||||
|
*/
|
||||||
|
const rowSelection = {
|
||||||
|
type: 'checkbox',
|
||||||
|
columnWidth: 30,
|
||||||
|
selectedRowKeys: checkedKeys,
|
||||||
|
onChange: onSelectChange
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 选择事件
|
||||||
|
*/
|
||||||
|
function onSelectChange(selectedRowKeys: (string | number)[]) {
|
||||||
|
checkedKeys.value = selectedRowKeys;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 新增事件
|
||||||
|
*/
|
||||||
|
function handleAdd() {
|
||||||
|
openModal(true, {
|
||||||
|
isUpdate: false,
|
||||||
|
showFooter: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 编辑事件
|
||||||
|
*/
|
||||||
|
function handleEdit(record: Recordable) {
|
||||||
|
openModal(true, {
|
||||||
|
record,
|
||||||
|
isUpdate: true,
|
||||||
|
showFooter: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 详情
|
||||||
|
*/
|
||||||
|
function handleDetail(record: Recordable) {
|
||||||
|
openModal(true, {
|
||||||
|
record,
|
||||||
|
isUpdate: true,
|
||||||
|
showFooter: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 删除事件
|
||||||
|
*/
|
||||||
|
async function handleDelete(record) {
|
||||||
|
await deleteOne({id: record.id}, reload);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 批量删除事件
|
||||||
|
*/
|
||||||
|
async function batchHandleDelete() {
|
||||||
|
await batchDelete({ids: checkedKeys.value}, reload);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 成功回调
|
||||||
|
*/
|
||||||
|
function handleSuccess() {
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 操作栏
|
||||||
|
*/
|
||||||
|
function getTableAction(record){
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: '编辑',
|
||||||
|
onClick: handleEdit.bind(null, record),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 下拉操作栏
|
||||||
|
*/
|
||||||
|
function getDropDownAction(record){
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: '详情',
|
||||||
|
onClick: handleDetail.bind(null, record),
|
||||||
|
}, {
|
||||||
|
label: '删除',
|
||||||
|
popConfirm: {
|
||||||
|
title: '是否确认删除',
|
||||||
|
confirm: handleDelete.bind(null, record),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
<#if list_need_category>
|
||||||
|
/**
|
||||||
|
* 初始化字典配置
|
||||||
|
*/
|
||||||
|
function initDictConfig(){
|
||||||
|
<#list columns as po>
|
||||||
|
<#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>
|
||||||
|
<#if po.classType=='cat_tree' && list_need_category==true>
|
||||||
|
loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => {
|
||||||
|
if (res) {
|
||||||
|
let allDictDate = getAuthCache(DB_DICT_DATA_KEY);
|
||||||
|
if(!allDictDate['${po.dictField?default("")}']){
|
||||||
|
Object.assign(allDictDate,{'${po.dictField?default("")}':res})
|
||||||
|
}
|
||||||
|
setAuthCache(DB_DICT_DATA_KEY,allDictDate)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
initDictConfig();
|
||||||
|
</#if>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,72 @@
|
||||||
|
import {defHttp} from '/@/utils/http/axios';
|
||||||
|
import {Modal} from 'ant-design-vue';
|
||||||
|
|
||||||
|
enum Api {
|
||||||
|
list = '/${entityPackage}/${entityName?uncap_first}/list',
|
||||||
|
save='/${entityPackage}/${entityName?uncap_first}/add',
|
||||||
|
edit='/${entityPackage}/${entityName?uncap_first}/edit',
|
||||||
|
deleteOne = '/${entityPackage}/${entityName?uncap_first}/delete',
|
||||||
|
deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
|
||||||
|
importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
|
||||||
|
exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
|
||||||
|
<#list subTables as sub><#rt/>
|
||||||
|
${sub.entityName?uncap_first}List = '/${entityPackage}/${entityName?uncap_first}/query${sub.entityName}ByMainId',
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 导出api
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const getExportUrl = Api.exportXls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入api
|
||||||
|
*/
|
||||||
|
export const getImportUrl = Api.importExcel;
|
||||||
|
<#list subTables as sub><#rt/>
|
||||||
|
/**
|
||||||
|
* 查询子表数据
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const ${sub.entityName?uncap_first}List = Api.${sub.entityName?uncap_first}List;
|
||||||
|
</#list>
|
||||||
|
/**
|
||||||
|
* 列表接口
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const list = (params) =>
|
||||||
|
defHttp.get({url: Api.list, params});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除单个
|
||||||
|
*/
|
||||||
|
export const deleteOne = (params,handleSuccess) => {
|
||||||
|
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
||||||
|
handleSuccess();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const batchDelete = (params, handleSuccess) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认删除',
|
||||||
|
content: '是否删除选中数据',
|
||||||
|
okText: '确认',
|
||||||
|
cancelText: '取消',
|
||||||
|
onOk: () => {
|
||||||
|
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||||
|
handleSuccess();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 保存或者更新
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const saveOrUpdate = (params, isUpdate) => {
|
||||||
|
let url = isUpdate ? Api.edit : Api.save;
|
||||||
|
return defHttp.post({url: url, params});
|
||||||
|
}
|
|
@ -0,0 +1,698 @@
|
||||||
|
import {BasicColumn} from '/@/components/Table';
|
||||||
|
import {FormSchema} from '/@/components/Table';
|
||||||
|
import { rules} from '/@/utils/helper/validator';
|
||||||
|
import { render } from '/@/utils/common/renderUtils';
|
||||||
|
import {JVxeTypes,JVxeColumn} from '/@/components/jeecg/JVxeTable/types'
|
||||||
|
//列表数据
|
||||||
|
export const columns: BasicColumn[] = [
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||||
|
{
|
||||||
|
title: '${po.filedComment}',
|
||||||
|
align:"center",
|
||||||
|
<#if po.sort=='Y'>
|
||||||
|
sorter: true,
|
||||||
|
</#if>
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
customRender:({text}) =>{
|
||||||
|
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||||
|
},
|
||||||
|
<#elseif po.fieldDbType=='Blob'>
|
||||||
|
dataIndex: '${po.fieldName}String'
|
||||||
|
<#elseif po.classType=='umeditor'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
slots: { customRender: 'htmlSlot' },
|
||||||
|
<#elseif po.classType=='pca'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||||
|
<#elseif po.classType=='file'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
slots: { customRender: 'fileSlot' },
|
||||||
|
<#elseif po.classType=='image'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
customRender:render.renderAvatar,
|
||||||
|
<#elseif po.classType=='switch'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#assign switch_extend_arr=['Y','N']>
|
||||||
|
<#if po.dictField?default("")?contains("[")>
|
||||||
|
<#assign switch_extend_arr=po.dictField?eval>
|
||||||
|
</#if>
|
||||||
|
<#list switch_extend_arr as a>
|
||||||
|
<#if a_index == 0>
|
||||||
|
<#assign switch_extend_arr1=a>
|
||||||
|
<#else>
|
||||||
|
<#assign switch_extend_arr2=a>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
customRender:({text}) => {
|
||||||
|
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||||
|
},
|
||||||
|
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||||
|
dataIndex: '${po.fieldName}_dictText'
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
dataIndex: '${po.fieldName}',
|
||||||
|
<#if po.dictText?default("")?trim?length == 0>
|
||||||
|
customRender:({text}) => {
|
||||||
|
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||||
|
},
|
||||||
|
<#else>
|
||||||
|
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
dataIndex: '${po.fieldName}'
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
];
|
||||||
|
//查询数据
|
||||||
|
export const searchFormSchema: FormSchema[] = [
|
||||||
|
<#-- 开始循环 -->
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.isQuery=='Y'>
|
||||||
|
<#assign query_flag=true>
|
||||||
|
<#assign query_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign query_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
<#if po.queryMode=='single'>
|
||||||
|
{
|
||||||
|
label: "${po.filedComment}",
|
||||||
|
field: "${po.fieldName}",
|
||||||
|
<#if po.classType=='sel_search'>
|
||||||
|
component: 'JSearchSelect',
|
||||||
|
componentProps:{
|
||||||
|
dict:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='sel_user'>
|
||||||
|
component: 'JSelectUserByDept',
|
||||||
|
<#elseif po.classType=='switch'>
|
||||||
|
component: 'JSwitch',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictField != 'is_open'>
|
||||||
|
options:"${po.dictField}"
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='sel_depart'>
|
||||||
|
component: 'JSelectDept',
|
||||||
|
<#elseif po.classType=='list_multi'>
|
||||||
|
component: 'JMultiSelectTag',//暂无该组件
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"query_field_dictCode?default("")"
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
component: 'JCategorySelect',
|
||||||
|
componentProps:{
|
||||||
|
pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='date'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime:true
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='pca'>
|
||||||
|
component: 'JAreaLinkage',
|
||||||
|
<#elseif po.classType=='popup'>
|
||||||
|
component: 'JPopup',
|
||||||
|
componentProps: ({ formActionType }) => {
|
||||||
|
const {setFieldsValue} = formActionType;
|
||||||
|
return{
|
||||||
|
setFieldsValue:setFieldsValue,
|
||||||
|
code:"${po.dictTable}",
|
||||||
|
fieldConfig:"${po.dictField}",
|
||||||
|
multi:${po.extendParams.popupMulti?c},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||||
|
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||||
|
component: 'JDictSelectTag',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
dictCode:"${po.dictField}"
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
<#else>
|
||||||
|
component: 'Input',
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
{
|
||||||
|
label: "${po.filedComment}",
|
||||||
|
field: "${po.fieldName}",
|
||||||
|
<#if po.classType=='date'>
|
||||||
|
component: 'RangePicker',
|
||||||
|
<#elseif po.classType=='datetime'>
|
||||||
|
component: 'RangePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime:true
|
||||||
|
},
|
||||||
|
<#else>
|
||||||
|
component: 'Input', //TODO 范围查询
|
||||||
|
</#if>
|
||||||
|
colProps: {span: 6},
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#-- 结束循环 -->
|
||||||
|
];
|
||||||
|
//表单数据
|
||||||
|
export const formSchema: FormSchema[] = [
|
||||||
|
<#assign form_cat_tree = false>
|
||||||
|
<#assign form_cat_back = "">
|
||||||
|
<#assign bpm_flag=false>
|
||||||
|
<#list columns as po><#rt/>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.isShow =='Y'>
|
||||||
|
<#assign form_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
{
|
||||||
|
label: '${po.filedComment}',
|
||||||
|
field: '${po.fieldName}',
|
||||||
|
<#if po.classType =='date'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
<#elseif po.fieldType =='datetime'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime:true
|
||||||
|
},
|
||||||
|
<#elseif po.fieldType =='time'>
|
||||||
|
component: 'TimePicker',
|
||||||
|
<#elseif po.classType =='popup'>
|
||||||
|
component: 'JPopup',
|
||||||
|
componentProps: ({ formActionType }) => {
|
||||||
|
const {setFieldsValue} = formActionType;
|
||||||
|
return{
|
||||||
|
setFieldsValue:setFieldsValue,
|
||||||
|
code:"${po.dictTable}",
|
||||||
|
fieldConfig:${po.dictField},
|
||||||
|
multi:${po.extendParams.popupMulti?c},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<#elseif po.classType =='sel_depart'>
|
||||||
|
component: 'JSelectDept',
|
||||||
|
<#elseif po.classType =='switch'>
|
||||||
|
component: 'JSwitch',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictField != 'is_open'>
|
||||||
|
options:${po.dictField}
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
<#elseif po.classType =='pca'>
|
||||||
|
component: 'JAreaLinkage',
|
||||||
|
<#elseif po.classType =='markdown'>
|
||||||
|
component: 'JMarkdownEditor',//注意string转换问题
|
||||||
|
<#elseif po.classType =='password'>
|
||||||
|
component: 'InputPassword',
|
||||||
|
<#elseif po.classType =='sel_user'>
|
||||||
|
component: 'JSelectUserByDept',
|
||||||
|
componentProps:{
|
||||||
|
labelKey:'realname',
|
||||||
|
}
|
||||||
|
<#elseif po.classType =='textarea'>
|
||||||
|
component: 'InputTextArea',//TODO 注意string转换问题
|
||||||
|
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||||
|
component: 'JDictSelectTag',
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"${form_field_dictCode}"
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||||
|
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"${form_field_dictCode}"
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='sel_search'>
|
||||||
|
component: 'JSearchSelect',
|
||||||
|
componentProps:{
|
||||||
|
dict:"${form_field_dictCode}"
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
<#assign form_cat_tree = true>
|
||||||
|
component: 'JCategorySelect',
|
||||||
|
componentProps:{
|
||||||
|
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||||
|
}
|
||||||
|
<#if po.dictText?default("")?trim?length gt 1>
|
||||||
|
<#assign form_cat_back = "${po.dictText}">
|
||||||
|
</#if>
|
||||||
|
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
component: 'InputNumber',
|
||||||
|
<#elseif po.classType=='file'>
|
||||||
|
component: 'JUpload',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.uploadnum??>
|
||||||
|
maxCount:${po.uploadnum}
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='image'>
|
||||||
|
component: 'JImageUpload',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.uploadnum??>
|
||||||
|
fileMax:${po.uploadnum}
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='umeditor'>
|
||||||
|
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||||
|
<#elseif po.classType == 'sel_tree'>
|
||||||
|
component: 'JTreeSelect',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictText??>
|
||||||
|
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||||
|
dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}",
|
||||||
|
<#elseif po.dictText?split(',')[1]??>
|
||||||
|
pidField:"${po.dictText?split(',')[1]}",
|
||||||
|
<#elseif po.dictText?split(',')[3]??>
|
||||||
|
hasChildField:"${po.dictText?split(',')[3]}",
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
pidValue:"${po.dictField}",
|
||||||
|
}
|
||||||
|
<#else>
|
||||||
|
component: 'Input',
|
||||||
|
</#if>
|
||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||||
|
dynamicRules: ({model,schema}) => {
|
||||||
|
<#if po.fieldName != 'id'>
|
||||||
|
<#assign fieldValidType = po.fieldValidType!''>
|
||||||
|
return [
|
||||||
|
<#-- 非空校验 -->
|
||||||
|
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||||
|
{ required: true, message: '请输入${po.filedComment}!'},
|
||||||
|
<#elseif fieldValidType!=''>
|
||||||
|
{ required: false},
|
||||||
|
</#if>
|
||||||
|
<#-- 唯一校验 -->
|
||||||
|
<#if fieldValidType == 'only'>
|
||||||
|
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||||
|
<#-- 6到16位数字 -->
|
||||||
|
<#elseif fieldValidType == 'n6-16'>
|
||||||
|
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||||
|
<#-- 6到16位任意字符 -->
|
||||||
|
<#elseif fieldValidType == '*6-16'>
|
||||||
|
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||||
|
<#-- 6到18位字符串 -->
|
||||||
|
<#elseif fieldValidType == 's6-18'>
|
||||||
|
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||||
|
<#-- 网址 -->
|
||||||
|
<#elseif fieldValidType == 'url'>
|
||||||
|
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||||
|
<#-- 电子邮件 -->
|
||||||
|
<#elseif fieldValidType == 'e'>
|
||||||
|
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||||
|
<#-- 手机号码 -->
|
||||||
|
<#elseif fieldValidType == 'm'>
|
||||||
|
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||||
|
<#-- 邮政编码 -->
|
||||||
|
<#elseif fieldValidType == 'p'>
|
||||||
|
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||||
|
<#-- 字母 -->
|
||||||
|
<#elseif fieldValidType == 's'>
|
||||||
|
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||||
|
<#-- 数字 -->
|
||||||
|
<#elseif fieldValidType == 'n'>
|
||||||
|
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||||
|
<#-- 整数 -->
|
||||||
|
<#elseif fieldValidType == 'z'>
|
||||||
|
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||||
|
<#-- 金额 -->
|
||||||
|
<#elseif fieldValidType == 'money'>
|
||||||
|
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||||
|
<#-- 正则校验 -->
|
||||||
|
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||||
|
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||||
|
<#-- 无校验 -->
|
||||||
|
<#else>
|
||||||
|
<#t>
|
||||||
|
</#if>
|
||||||
|
];
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
<#if po.readonly=='Y'>
|
||||||
|
dynamicDisabled:true
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
];
|
||||||
|
//子表单数据
|
||||||
|
<#list subTables as sub>
|
||||||
|
<#if sub.foreignRelationType =='1'>
|
||||||
|
export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
|
||||||
|
<#assign form_cat_tree = false>
|
||||||
|
<#assign form_cat_back = "">
|
||||||
|
<#assign bpm_flag=false>
|
||||||
|
<#list sub.colums as po><#rt/>
|
||||||
|
<#if po.fieldDbName=='bpm_status'>
|
||||||
|
<#assign bpm_flag=true>
|
||||||
|
</#if>
|
||||||
|
<#if po.isShow =='Y'>
|
||||||
|
<#assign form_field_dictCode="">
|
||||||
|
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||||
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
|
<#assign form_field_dictCode="${po.dictField}">
|
||||||
|
</#if>
|
||||||
|
{
|
||||||
|
label: '${po.filedComment}',
|
||||||
|
field: '${po.fieldName}',
|
||||||
|
<#if po.classType =='date'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
<#elseif po.fieldType =='datetime'>
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime:true
|
||||||
|
},
|
||||||
|
<#elseif po.fieldType =='time'>
|
||||||
|
component: 'TimePicker',
|
||||||
|
<#elseif po.classType =='popup'>
|
||||||
|
component: 'JPopup',
|
||||||
|
componentProps: ({ formActionType }) => {
|
||||||
|
const {setFieldsValue} = formActionType;
|
||||||
|
return{
|
||||||
|
setFieldsValue:setFieldsValue,
|
||||||
|
code:"${po.dictTable}",
|
||||||
|
fieldConfig:${po.dictField},
|
||||||
|
multi:${po.extendParams.popupMulti?c},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<#elseif po.classType =='sel_depart'>
|
||||||
|
component: 'JSelectDept',
|
||||||
|
<#elseif po.classType =='switch'>
|
||||||
|
component: 'JSwitch',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictField != 'is_open'>
|
||||||
|
options:${po.dictField}
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
<#elseif po.classType =='pca'>
|
||||||
|
component: 'JAreaLinkage',
|
||||||
|
<#elseif po.classType =='markdown'>
|
||||||
|
component: 'JMarkdownEditor',//注意string转换问题
|
||||||
|
<#elseif po.classType =='password'>
|
||||||
|
component: 'InputPassword',
|
||||||
|
<#elseif po.classType =='sel_user'>
|
||||||
|
component: 'JSelectUserByDept',
|
||||||
|
componentProps:{
|
||||||
|
labelKey:'realname',
|
||||||
|
}
|
||||||
|
<#elseif po.classType =='textarea'>
|
||||||
|
component: 'InputTextArea',//TODO 注意string转换问题
|
||||||
|
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||||
|
component: 'JDictSelectTag',
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"${form_field_dictCode}"
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||||
|
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||||
|
componentProps:{
|
||||||
|
dictCode:"${form_field_dictCode}"
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='sel_search'>
|
||||||
|
component: 'JSearchSelect',
|
||||||
|
componentProps:{
|
||||||
|
dict:"${form_field_dictCode}"
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='cat_tree'>
|
||||||
|
<#assign form_cat_tree = true>
|
||||||
|
component: 'JCategorySelect',
|
||||||
|
componentProps:{
|
||||||
|
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||||
|
}
|
||||||
|
<#if po.dictText?default("")?trim?length gt 1>
|
||||||
|
<#assign form_cat_back = "${po.dictText}">
|
||||||
|
</#if>
|
||||||
|
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||||
|
component: 'InputNumber',
|
||||||
|
<#elseif po.classType=='file'>
|
||||||
|
component: 'JUpload',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.uploadnum??>
|
||||||
|
maxCount:${po.uploadnum}
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='image'>
|
||||||
|
component: 'JImageUpload',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.uploadnum??>
|
||||||
|
fileMax:${po.uploadnum}
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
<#elseif po.classType=='umeditor'>
|
||||||
|
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||||
|
<#elseif po.classType == 'sel_tree'>
|
||||||
|
component: 'JTreeSelect',
|
||||||
|
componentProps:{
|
||||||
|
<#if po.dictText??>
|
||||||
|
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||||
|
dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}",
|
||||||
|
<#elseif po.dictText?split(',')[1]??>
|
||||||
|
pidField:"${po.dictText?split(',')[1]}",
|
||||||
|
<#elseif po.dictText?split(',')[3]??>
|
||||||
|
hasChildField:"${po.dictText?split(',')[3]}",
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
pidValue:"${po.dictField}",
|
||||||
|
}
|
||||||
|
<#else>
|
||||||
|
component: 'Input',
|
||||||
|
</#if>
|
||||||
|
<#include "/common/utils.ftl">
|
||||||
|
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||||
|
dynamicRules: ({model,schema}) => {
|
||||||
|
<#if po.fieldName != 'id'>
|
||||||
|
<#assign fieldValidType = po.fieldValidType!''>
|
||||||
|
return [
|
||||||
|
<#-- 非空校验 -->
|
||||||
|
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||||
|
{ required: true, message: '请输入${po.filedComment}!'},
|
||||||
|
<#elseif fieldValidType!=''>
|
||||||
|
{ required: false},
|
||||||
|
</#if>
|
||||||
|
<#-- 唯一校验 -->
|
||||||
|
<#if fieldValidType == 'only'>
|
||||||
|
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||||
|
<#-- 6到16位数字 -->
|
||||||
|
<#elseif fieldValidType == 'n6-16'>
|
||||||
|
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||||
|
<#-- 6到16位任意字符 -->
|
||||||
|
<#elseif fieldValidType == '*6-16'>
|
||||||
|
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||||
|
<#-- 6到18位字符串 -->
|
||||||
|
<#elseif fieldValidType == 's6-18'>
|
||||||
|
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||||
|
<#-- 网址 -->
|
||||||
|
<#elseif fieldValidType == 'url'>
|
||||||
|
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||||
|
<#-- 电子邮件 -->
|
||||||
|
<#elseif fieldValidType == 'e'>
|
||||||
|
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||||
|
<#-- 手机号码 -->
|
||||||
|
<#elseif fieldValidType == 'm'>
|
||||||
|
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||||
|
<#-- 邮政编码 -->
|
||||||
|
<#elseif fieldValidType == 'p'>
|
||||||
|
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||||
|
<#-- 字母 -->
|
||||||
|
<#elseif fieldValidType == 's'>
|
||||||
|
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||||
|
<#-- 数字 -->
|
||||||
|
<#elseif fieldValidType == 'n'>
|
||||||
|
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||||
|
<#-- 整数 -->
|
||||||
|
<#elseif fieldValidType == 'z'>
|
||||||
|
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||||
|
<#-- 金额 -->
|
||||||
|
<#elseif fieldValidType == 'money'>
|
||||||
|
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||||
|
<#-- 正则校验 -->
|
||||||
|
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||||
|
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||||
|
<#-- 无校验 -->
|
||||||
|
<#else>
|
||||||
|
<#t>
|
||||||
|
</#if>
|
||||||
|
];
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
<#if po.readonly=='Y'>
|
||||||
|
dynamicDisabled:true
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
];
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
//子表表格配置
|
||||||
|
<#list subTables as sub>
|
||||||
|
<#if sub.foreignRelationType =='0'>
|
||||||
|
export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
|
||||||
|
<#assign popupBackFields = "">
|
||||||
|
|
||||||
|
<#-- 循环子表的列 开始 -->
|
||||||
|
<#list sub.colums as col><#rt/>
|
||||||
|
<#if col.isShow =='Y'>
|
||||||
|
<#if col.filedComment !='外键' >
|
||||||
|
{
|
||||||
|
title: '${col.filedComment}',
|
||||||
|
key: '${autoStringSuffixForModel(col)}',
|
||||||
|
<#if col.classType =='date'>
|
||||||
|
type: JVxeTypes.date,
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#elseif col.classType =='datetime'>
|
||||||
|
type: JVxeTypes.datetime,
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#elseif col.classType =='textarea'>
|
||||||
|
type: JVxeTypes.textarea,
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#elseif "int,decimal,double,"?contains(col.classType)>
|
||||||
|
type: JVxeTypes.inputNumber,
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#elseif col.classType =='list' || col.classType =='radio'>
|
||||||
|
type: JVxeTypes.select,
|
||||||
|
options:[],
|
||||||
|
<#if col.dictTable?default("")?trim?length gt 1>
|
||||||
|
dictCode:"${col.dictTable},${col.dictText},${col.dictField}",
|
||||||
|
<#else>
|
||||||
|
dictCode:"${col.dictField}",
|
||||||
|
</#if>
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#elseif col.classType =='list_multi' || col.classType =='checkbox'>
|
||||||
|
type: JVxeTypes.selectMultiple,
|
||||||
|
options:[],
|
||||||
|
<#if col.dictTable?default("")?trim?length gt 1>
|
||||||
|
dictCode:"${col.dictTable},${col.dictText},${col.dictField}",
|
||||||
|
<#else>
|
||||||
|
dictCode:"${col.dictField}",
|
||||||
|
</#if>
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#elseif col.classType =='sel_search'>
|
||||||
|
type: JVxeTypes.selectSearch,
|
||||||
|
<#if col.dictTable?default("")?trim?length gt 1>
|
||||||
|
dictCode:"${col.dictTable},${col.dictText},${col.dictField}",
|
||||||
|
<#else>
|
||||||
|
dictCode:"${col.dictField}",
|
||||||
|
</#if>
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#elseif col.classType =='image'>
|
||||||
|
type: JVxeTypes.image,
|
||||||
|
token:true,
|
||||||
|
responseName:"message",
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#if col.uploadnum??>
|
||||||
|
number: ${col.uploadnum},
|
||||||
|
</#if>
|
||||||
|
<#elseif col.classType =='file'>
|
||||||
|
type: JVxeTypes.file,
|
||||||
|
token:true,
|
||||||
|
responseName:"message",
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#if col.uploadnum??>
|
||||||
|
number: ${col.uploadnum},
|
||||||
|
</#if>
|
||||||
|
<#elseif col.classType =='switch'>
|
||||||
|
type: JVxeTypes.checkbox,
|
||||||
|
<#if col.dictField == 'is_open'>
|
||||||
|
customValue: ['Y', 'N'],
|
||||||
|
<#else>
|
||||||
|
customValue: ${col.dictField},
|
||||||
|
</#if>
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#elseif col.classType =='popup'>
|
||||||
|
<#if popupBackFields?length gt 0>
|
||||||
|
<#assign popupBackFields = "${popupBackFields}"+","+"${col.dictText}">
|
||||||
|
<#else>
|
||||||
|
<#assign popupBackFields = "${col.dictText}">
|
||||||
|
</#if>
|
||||||
|
type: JVxeTypes.popup,
|
||||||
|
popupCode:"${col.dictTable}",
|
||||||
|
field:"${col.dictField}",
|
||||||
|
orgFields:"${col.dictField}",
|
||||||
|
destFields:"${Format.underlineToHump(col.dictText)}",
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
type: JVxeTypes.input,
|
||||||
|
<#if col.readonly=='Y'>
|
||||||
|
disabled:true,
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
<#if col.classType =='list_multi' || col.classType =='checkbox'>
|
||||||
|
width:"250px",
|
||||||
|
<#else>
|
||||||
|
width:"200px",
|
||||||
|
</#if>
|
||||||
|
<#if col.classType =='file'>
|
||||||
|
placeholder: '请选择文件',
|
||||||
|
<#else>
|
||||||
|
placeholder: '请输入${'$'}{title}',
|
||||||
|
</#if>
|
||||||
|
<#if col.defaultVal??>
|
||||||
|
<#if col.fieldDbType=="BigDecimal" || col.fieldDbType=="double" || col.fieldDbType=="int">
|
||||||
|
defaultValue:${col.defaultVal},
|
||||||
|
<#else>
|
||||||
|
defaultValue:"${col.defaultVal}",
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
defaultValue:'',
|
||||||
|
</#if>
|
||||||
|
<#-- 子表的校验 -->
|
||||||
|
<#assign subFieldValidType = col.fieldValidType!''>
|
||||||
|
<#-- 非空校验 -->
|
||||||
|
<#if col.nullable == 'N' || subFieldValidType == '*'>
|
||||||
|
validateRules: [{ required: true, message: '${'$'}{title}不能为空' }],
|
||||||
|
<#-- 其他情况下,只要有值就被认为是正则校验 -->
|
||||||
|
<#elseif subFieldValidType?length gt 0>
|
||||||
|
<#assign subMessage = '格式不正确'>
|
||||||
|
<#if subFieldValidType == 'only' >
|
||||||
|
<#assign subMessage = '不能重复'>
|
||||||
|
</#if>
|
||||||
|
validateRules: [{ pattern: "${subFieldValidType}", message: "${'$'}{title}${subMessage}" }],
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#-- 循环子表的列 结束 -->
|
||||||
|
]
|
||||||
|
</#if>
|
||||||
|
</#list>
|
|
@ -0,0 +1,179 @@
|
||||||
|
<template>
|
||||||
|
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
|
||||||
|
<BasicForm @register="registerForm" ref="formRef"/>
|
||||||
|
<!-- 子表单区域 -->
|
||||||
|
<a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs">
|
||||||
|
<#list subTables as sub><#rt/>
|
||||||
|
<#if sub.foreignRelationType =='1'>
|
||||||
|
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index}]" :forceRender="true">
|
||||||
|
<${sub.entityName}Form ref="${sub.entityName?uncap_first}Form"></${sub.entityName}Form>
|
||||||
|
</a-tab-pane>
|
||||||
|
|
||||||
|
<#else>
|
||||||
|
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index}]" :forceRender="true">
|
||||||
|
<JVxeTable
|
||||||
|
keep-source
|
||||||
|
resizable
|
||||||
|
:ref="refKeys[${sub_index}]"
|
||||||
|
:loading="${sub.entityName?uncap_first}Table.loading"
|
||||||
|
:columns="${sub.entityName?uncap_first}Table.columns"
|
||||||
|
:dataSource="${sub.entityName?uncap_first}Table.dataSource"
|
||||||
|
:maxHeight="300"
|
||||||
|
:rowNumber="true"
|
||||||
|
:rowSelection="true"
|
||||||
|
:toolbar="true"
|
||||||
|
/>
|
||||||
|
</a-tab-pane>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</a-tabs>
|
||||||
|
</BasicModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {ref, computed, unref,reactive} from 'vue';
|
||||||
|
import {BasicModal, useModalInner} from '/@/components/Modal';
|
||||||
|
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||||
|
import { JVxeTable } from '/@/components/jeecg/JVxeTable'
|
||||||
|
import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts'
|
||||||
|
<#list subTables as sub>
|
||||||
|
<#if sub.foreignRelationType =='1'>
|
||||||
|
import ${sub.entityName}Form from './${sub.entityName}Form.vue'
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
import {formSchema<#list subTables as sub><#if sub.foreignRelationType =='0'>,${sub.entityName?uncap_first}Columns</#if></#list>} from '../${entityName?uncap_first}.data';
|
||||||
|
import {saveOrUpdate<#list subTables as sub>,${sub.entityName?uncap_first}List</#list>} from '../${entityName?uncap_first}.api';
|
||||||
|
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
|
||||||
|
// Emits声明
|
||||||
|
const emit = defineEmits(['register','success']);
|
||||||
|
const isUpdate = ref(true);
|
||||||
|
const refKeys = ref([<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]);
|
||||||
|
<#assign hasOne2Many = false>
|
||||||
|
<#assign hasOne2One = false>
|
||||||
|
const activeKey = ref('${subTables[0].entityName?uncap_first}');
|
||||||
|
<#list subTables as sub>
|
||||||
|
<#if sub.foreignRelationType =='0'>
|
||||||
|
<#assign hasOne2Many = true>
|
||||||
|
const ${sub.entityName?uncap_first} = ref();
|
||||||
|
</#if>
|
||||||
|
<#if sub.foreignRelationType =='1'>
|
||||||
|
<#assign hasOne2One = true>
|
||||||
|
const ${sub.entityName?uncap_first}Form = ref();
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
const tableRefs = {<#list subTables as sub><#if sub.foreignRelationType =='0'>${sub.entityName?uncap_first}, <#assign hasOne2Many = true></#if></#list>};
|
||||||
|
<#list subTables as sub>
|
||||||
|
<#if sub.foreignRelationType =='0'>
|
||||||
|
const ${sub.entityName?uncap_first}Table = reactive({
|
||||||
|
loading: false,
|
||||||
|
dataSource: [],
|
||||||
|
columns:${sub.entityName?uncap_first}Columns
|
||||||
|
})
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
//表单配置
|
||||||
|
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
|
||||||
|
labelWidth: 150,
|
||||||
|
schemas: formSchema,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
});
|
||||||
|
//表单赋值
|
||||||
|
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||||
|
//重置表单
|
||||||
|
await reset();
|
||||||
|
setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter});
|
||||||
|
isUpdate.value = !!data?.isUpdate;
|
||||||
|
if (unref(isUpdate)) {
|
||||||
|
//表单赋值
|
||||||
|
await setFieldsValue({
|
||||||
|
...data.record,
|
||||||
|
});
|
||||||
|
<#list subTables as sub><#rt/>
|
||||||
|
<#if sub.foreignRelationType =='1'>
|
||||||
|
${sub.entityName?uncap_first}Form.value.initFormData(${sub.entityName?uncap_first}List,data?.record?.id)
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#list subTables as sub><#rt/>
|
||||||
|
<#if sub.foreignRelationType =='0'>
|
||||||
|
requestSubTableData(${sub.entityName?uncap_first}List, {id:data?.record?.id}, ${sub.entityName?uncap_first}Table)
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
// 隐藏底部时禁用整个表单
|
||||||
|
setProps({ disabled: !data?.showFooter })
|
||||||
|
});
|
||||||
|
//方法配置
|
||||||
|
const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys<#if hasOne2One==true>,validateSubForm</#if>);
|
||||||
|
|
||||||
|
//设置标题
|
||||||
|
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||||
|
|
||||||
|
async function reset(){
|
||||||
|
await resetFields();
|
||||||
|
activeKey.value = ref('${subTables[0].entityName?uncap_first}');
|
||||||
|
<#list subTables as sub>
|
||||||
|
<#if sub.foreignRelationType =='0'>
|
||||||
|
${sub.entityName?uncap_first}Table.dataSource = [];
|
||||||
|
</#if>
|
||||||
|
<#if sub.foreignRelationType =='1'>
|
||||||
|
${sub.entityName?uncap_first}Form.value.resetFields();
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
function classifyIntoFormData(allValues) {
|
||||||
|
let main = Object.assign({}, allValues.formValue)
|
||||||
|
return {
|
||||||
|
...main, // 展开
|
||||||
|
<#assign subManyIndex = 0>
|
||||||
|
<#list subTables as sub><#rt/>
|
||||||
|
<#if sub.foreignRelationType =='0'>
|
||||||
|
${sub.entityName?uncap_first}List: allValues.tablesValue[${subManyIndex}].tableData,
|
||||||
|
<#assign subManyIndex = subManyIndex+1>
|
||||||
|
<#else>
|
||||||
|
${sub.entityName?uncap_first}List: ${sub.entityName?uncap_first}Form.value.getFormData(),
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<#if hasOne2One==true>
|
||||||
|
//校验所有一对一子表表单
|
||||||
|
function validateSubForm(allValues){
|
||||||
|
return new Promise((resolve,reject)=>{
|
||||||
|
Promise.all([
|
||||||
|
<#list subTables as sub><#rt/>
|
||||||
|
<#if sub.foreignRelationType =='1'>
|
||||||
|
${sub.entityName?uncap_first}Form.value.validateForm(${sub_index}),
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
]).then(() => {
|
||||||
|
resolve(allValues)
|
||||||
|
}).catch(e => {
|
||||||
|
if (e.error === VALIDATE_FAILED) {
|
||||||
|
// 如果有未通过表单验证的子表,就自动跳转到它所在的tab
|
||||||
|
activeKey.value = e.index == null ? unref(activeKey) : refKeys.value[e.index]
|
||||||
|
} else {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
//表单提交事件
|
||||||
|
async function requestAddOrEdit(values) {
|
||||||
|
try {
|
||||||
|
setModalProps({confirmLoading: true});
|
||||||
|
//提交表单
|
||||||
|
await saveOrUpdate(values, isUpdate.value);
|
||||||
|
//关闭弹窗
|
||||||
|
closeModal();
|
||||||
|
//刷新列表
|
||||||
|
emit('success');
|
||||||
|
} finally {
|
||||||
|
setModalProps({confirmLoading: false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,64 @@
|
||||||
|
<#list subTables as sub>
|
||||||
|
<#if sub.foreignRelationType=='1'>
|
||||||
|
#segment#${sub.entityName}Form.vue
|
||||||
|
<template>
|
||||||
|
<BasicForm @register="registerForm"/>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import {defineComponent} from 'vue';
|
||||||
|
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||||
|
import {${sub.entityName?uncap_first}FormSchema} from '../${entityName?uncap_first}.data';
|
||||||
|
import {defHttp} from '/@/utils/http/axios';
|
||||||
|
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name:"${sub.entityName}Form",
|
||||||
|
components: {BasicForm},
|
||||||
|
emits:['register'],
|
||||||
|
setup(_,{emit}) {
|
||||||
|
const [registerForm, {resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
|
||||||
|
labelWidth: 150,
|
||||||
|
schemas: ${sub.entityName?uncap_first}FormSchema,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
});
|
||||||
|
/**
|
||||||
|
*初始化加载数据
|
||||||
|
*/
|
||||||
|
function initFormData(url,id){
|
||||||
|
if(id){
|
||||||
|
defHttp.get({url,params:{id}},{isTransformResponse:false}).then(res=>{
|
||||||
|
res.success && setFieldsValue({...res.result[0]});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*获取表单数据
|
||||||
|
*/
|
||||||
|
function getFormData(){
|
||||||
|
return [getFieldsValue()];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*表单校验
|
||||||
|
*/
|
||||||
|
function validateForm(index){
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// 验证子表表单
|
||||||
|
validate().then(()=>{
|
||||||
|
return resolve()
|
||||||
|
}).catch(()=> {
|
||||||
|
return reject({ error: VALIDATE_FAILED ,index})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
registerForm,
|
||||||
|
resetFields,
|
||||||
|
initFormData,
|
||||||
|
getFormData,
|
||||||
|
validateForm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue