SYSTEM:同步 jdk21 boot 最新代码

 INFRA:同步 jdk21 boot 最新代码
pull/95/MERGE
YunaiV 2024-01-19 20:34:59 +08:00
parent dbf844592a
commit 8289a22f03
314 changed files with 1960 additions and 1189 deletions

View File

@ -0,0 +1,77 @@
-- 菜单 SQL
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status, component_name
)
VALUES (
'Ureport2报表管理', '', 2, 0, 1281,
'ureport-data', '', 'report/ureport/index', 0, 'UReportData'
);
-- 按钮父菜单ID
-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码
SELECT @parentId := LAST_INSERT_ID();
-- 按钮 SQL
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'Ureport2报表查询', 'report:ureport-data:query', 3, 1, @parentId,
'', '', '', 0
);
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'Ureport2报表创建', 'report:ureport-data:create', 3, 2, @parentId,
'', '', '', 0
);
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'Ureport2报表更新', 'report:ureport-data:update', 3, 3, @parentId,
'', '', '', 0
);
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'Ureport2报表删除', 'report:ureport-data:delete', 3, 4, @parentId,
'', '', '', 0
);
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'Ureport2报表导出', 'report:ureport-data:export', 3, 5, @parentId,
'', '', '', 0
);
DROP TABLE IF EXISTS `report_ureport_data`;
CREATE TABLE `report_ureport_data` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '文件名称',
`status` tinyint(4) NOT NULL COMMENT '状态',
`content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '文件内容',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '备注',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Ureport2报表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of report_ureport_data
-- ----------------------------
INSERT INTO `report_ureport_data` VALUES (11, 'role.ureport.xml', 0, '<?xml version=\"1.0\" encoding=\"UTF-8\"?><ureport><cell expand=\"Down\" name=\"A1\" row=\"1\" col=\"1\"><cell-style font-size=\"10\" align=\"center\" valign=\"middle\"></cell-style><dataset-value dataset-name=\"role\" aggregate=\"group\" property=\"name\" order=\"none\" mapping-type=\"simple\"></dataset-value></cell><cell expand=\"Down\" name=\"B1\" row=\"1\" col=\"2\"><cell-style font-size=\"10\" align=\"center\" valign=\"middle\"></cell-style><dataset-value dataset-name=\"role\" aggregate=\"group\" property=\"code\" order=\"none\" mapping-type=\"simple\"></dataset-value></cell><cell expand=\"Down\" name=\"C1\" row=\"1\" col=\"3\"><cell-style font-size=\"10\" align=\"center\" valign=\"middle\"></cell-style><dataset-value dataset-name=\"role\" aggregate=\"group\" property=\"status\" order=\"none\" mapping-type=\"simple\"></dataset-value></cell><cell expand=\"None\" name=\"D1\" row=\"1\" col=\"4\"><cell-style font-size=\"10\" align=\"center\" valign=\"middle\"></cell-style><simple-value><![CDATA[]]></simple-value></cell><cell expand=\"None\" name=\"A2\" row=\"2\" col=\"1\"><cell-style font-size=\"10\" align=\"center\" valign=\"middle\"></cell-style><simple-value><![CDATA[]]></simple-value></cell><cell expand=\"None\" name=\"B2\" row=\"2\" col=\"2\"><cell-style font-size=\"10\" align=\"center\" valign=\"middle\"></cell-style><simple-value><![CDATA[]]></simple-value></cell><cell expand=\"None\" name=\"C2\" row=\"2\" col=\"3\"><cell-style font-size=\"10\" align=\"center\" valign=\"middle\"></cell-style><simple-value><![CDATA[]]></simple-value></cell><cell expand=\"None\" name=\"D2\" row=\"2\" col=\"4\"><cell-style font-size=\"10\" align=\"center\" valign=\"middle\"></cell-style><simple-value><![CDATA[]]></simple-value></cell><cell expand=\"None\" name=\"A3\" row=\"3\" col=\"1\"><cell-style font-size=\"10\" align=\"center\" valign=\"middle\"></cell-style><simple-value><![CDATA[]]></simple-value></cell><cell expand=\"None\" name=\"B3\" row=\"3\" col=\"2\"><cell-style font-size=\"10\" align=\"center\" valign=\"middle\"></cell-style><simple-value><![CDATA[]]></simple-value></cell><cell expand=\"None\" name=\"C3\" row=\"3\" col=\"3\"><cell-style font-size=\"10\" align=\"center\" valign=\"middle\"></cell-style><simple-value><![CDATA[]]></simple-value></cell><cell expand=\"None\" name=\"D3\" row=\"3\" col=\"4\"><cell-style font-size=\"10\" align=\"center\" valign=\"middle\"></cell-style><simple-value><![CDATA[]]></simple-value></cell><row row-number=\"1\" height=\"18\"/><row row-number=\"2\" height=\"18\"/><row row-number=\"3\" height=\"18\"/><column col-number=\"1\" width=\"80\"/><column col-number=\"2\" width=\"80\"/><column col-number=\"3\" width=\"80\"/><column col-number=\"4\" width=\"80\"/><datasource name=\"UReportDataSource\" type=\"buildin\"><dataset name=\"role\" type=\"sql\"><sql><![CDATA[select * from system_role]]></sql><field name=\"id\"/><field name=\"name\"/><field name=\"code\"/><field name=\"sort\"/><field name=\"data_scope\"/><field name=\"data_scope_dept_ids\"/><field name=\"status\"/><field name=\"type\"/><field name=\"remark\"/><field name=\"creator\"/><field name=\"create_time\"/><field name=\"updater\"/><field name=\"update_time\"/><field name=\"deleted\"/><field name=\"tenant_id\"/></dataset></datasource><paper type=\"A4\" left-margin=\"90\" right-margin=\"90\"\n top-margin=\"72\" bottom-margin=\"72\" paging-mode=\"fitpage\" fixrows=\"0\"\n width=\"595\" height=\"842\" orientation=\"portrait\" html-report-align=\"left\" bg-image=\"\" html-interval-refresh-value=\"0\" column-enabled=\"false\"></paper></ureport>', NULL, NULL, '2023-11-25 22:40:58', NULL, '2023-11-25 23:00:42', b'0', 0);

View File

@ -1,20 +0,0 @@
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (184, '回款管理审批状态', 'crm_receivable_check_status', 0, '回款管理审批状态(0 未审核 1 审核通过 2 审核拒绝 3 审核中 4 已撤回)', '1', '2023-10-18 21:44:24', '1', '2023-10-18 21:44:24', b'0', '1970-01-01 00:00:00');
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (185, '回款管理-回款方式', 'crm_return_type', 0, '回款管理-回款方式', '1', '2023-10-18 21:54:10', '1', '2023-10-18 21:54:10', b'0', '1970-01-01 00:00:00');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1389, 0, '未审核', '0', 'crm_receivable_check_status', 0, 'default', '', '0 未审核 ', '1', '2023-10-18 21:46:00', '1', '2023-10-18 21:47:16', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1390, 1, '审核通过', '1', 'crm_receivable_check_status', 0, 'default', '', '1 审核通过', '1', '2023-10-18 21:46:18', '1', '2023-10-18 21:47:08', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1391, 2, '审核拒绝', '2', 'crm_receivable_check_status', 0, 'default', '', ' 2 审核拒绝', '1', '2023-10-18 21:46:58', '1', '2023-10-18 21:47:21', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1392, 3, '审核中', '3', 'crm_receivable_check_status', 0, 'default', '', ' 3 审核中', '1', '2023-10-18 21:47:35', '1', '2023-10-18 21:47:35', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1393, 4, '已撤回', '4', 'crm_receivable_check_status', 0, 'default', '', ' 4 已撤回', '1', '2023-10-18 21:47:46', '1', '2023-10-18 21:47:46', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1394, 1, '支票', '1', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:54:29', '1', '2023-10-18 21:54:29', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1395, 2, '现金', '2', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:54:41', '1', '2023-10-18 21:54:41', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1396, 3, '邮政汇款', '3', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:54:53', '1', '2023-10-18 21:54:53', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1397, 4, '电汇', '4', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:55:07', '1', '2023-10-18 21:55:07', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1398, 5, '网上转账', '5', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:55:24', '1', '2023-10-18 21:55:24', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1399, 6, '支付宝', '6', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:55:38', '1', '2023-10-18 21:55:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1400, 7, '微信支付', '7', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:55:53', '1', '2023-10-18 21:55:53', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1401, 8, '其他', '8', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:56:06', '1', '2023-10-18 21:56:06', b'0');

View File

@ -2370,6 +2370,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2369, '拼团记录', 'promotion:combination-record:query', 2, 2, 2303, 'record', 'ep:avatar', 'mall/promotion/combination/record/index.vue', 'PromotionCombinationRecord', 0, b'1', b'1', b'1', '1', '2023-10-08 07:10:22', '1', '2023-10-08 07:34:11', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2369, '拼团记录', 'promotion:combination-record:query', 2, 2, 2303, 'record', 'ep:avatar', 'mall/promotion/combination/record/index.vue', 'PromotionCombinationRecord', 0, b'1', b'1', b'1', '1', '2023-10-08 07:10:22', '1', '2023-10-08 07:34:11', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2374, '会员统计', '', 2, 2, 2358, 'member', 'ep:avatar', 'statistics/member/index', 'MemberStatistics', 0, b'1', b'1', b'1', '', '2023-10-11 04:39:24', '1', '2023-10-11 12:50:22', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2374, '会员统计', '', 2, 2, 2358, 'member', 'ep:avatar', 'statistics/member/index', 'MemberStatistics', 0, b'1', b'1', b'1', '', '2023-10-11 04:39:24', '1', '2023-10-11 12:50:22', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2375, '会员统计查询', 'statistics:member:query', 3, 1, 2374, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-11 04:39:24', '', '2023-10-11 04:39:24', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2375, '会员统计查询', 'statistics:member:query', 3, 1, 2374, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-11 04:39:24', '', '2023-10-11 04:39:24', b'0');
--trade:order:query trade:order:update
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2376, '订单核销', 'trade:order:pick-up', 3, 10, 2076, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-10-14 17:11:58', '1', '2023-10-14 17:11:58', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2376, '订单核销', 'trade:order:pick-up', 3, 10, 2076, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-10-14 17:11:58', '1', '2023-10-14 17:11:58', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2377, '文章分类', '', 2, 0, 2387, 'article/category', 'fa:certificate', 'mall/promotion/article/category/index', 'ArticleCategory', 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '1', '2023-10-16 09:38:26', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2377, '文章分类', '', 2, 0, 2387, 'article/category', 'fa:certificate', 'mall/promotion/article/category/index', 'ArticleCategory', 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '1', '2023-10-16 09:38:26', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2378, '分类查询', 'promotion:article-category:query', 3, 1, 2377, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '', '2023-10-16 01:26:18', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2378, '分类查询', 'promotion:article-category:query', 3, 1, 2377, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '', '2023-10-16 01:26:18', b'0');
@ -2416,12 +2417,12 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2419, '联系人更新', 'crm:contact:update', 3, 3, 2416, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:14:56', '', '2023-10-29 11:14:56', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2419, '联系人更新', 'crm:contact:update', 3, 3, 2416, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:14:56', '', '2023-10-29 11:14:56', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2420, '联系人删除', 'crm:contact:delete', 3, 4, 2416, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:14:56', '', '2023-10-29 11:14:56', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2420, '联系人删除', 'crm:contact:delete', 3, 4, 2416, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:14:56', '', '2023-10-29 11:14:56', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2421, '联系人导出', 'crm:contact:export', 3, 5, 2416, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:14:56', '', '2023-10-29 11:14:56', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2421, '联系人导出', 'crm:contact:export', 3, 5, 2416, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:14:56', '', '2023-10-29 11:14:56', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2422, '回款管理', '', 2, 0, 2397, 'receivable', 'ep:money', 'crm/receivable/index', 'CrmReceivable', 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '1', '2023-10-29 19:18:52', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2422, '回款', '', 2, 0, 2397, 'receivable', 'ep:money', 'crm/receivable/index', 'CrmReceivable', 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '1', '2023-10-29 19:18:52', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2423, '回款管理查询', 'crm:receivable:query', 3, 1, 2422, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2423, '回款查询', 'crm:receivable:query', 3, 1, 2422, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2424, '回款管理创建', 'crm:receivable:create', 3, 2, 2422, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2424, '回款创建', 'crm:receivable:create', 3, 2, 2422, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2425, '回款管理更新', 'crm:receivable:update', 3, 3, 2422, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2425, '回款更新', 'crm:receivable:update', 3, 3, 2422, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2426, '回款管理删除', 'crm:receivable:delete', 3, 4, 2422, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2426, '回款删除', 'crm:receivable:delete', 3, 4, 2422, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2427, '回款管理导出', 'crm:receivable:export', 3, 5, 2422, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2427, '回款导出', 'crm:receivable:export', 3, 5, 2422, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2428, '回款计划管理', '', 2, 0, 2397, 'receivable-plan', 'fa:money', 'crm/receivablePlan/index', 'CrmReceivablePlan', 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '1', '2023-10-29 19:19:08', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2428, '回款计划管理', '', 2, 0, 2397, 'receivable-plan', 'fa:money', 'crm/receivablePlan/index', 'CrmReceivablePlan', 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '1', '2023-10-29 19:19:08', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2429, '回款计划查询', 'crm:receivable-plan:query', 3, 1, 2428, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2429, '回款计划查询', 'crm:receivable-plan:query', 3, 1, 2428, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2430, '回款计划创建', 'crm:receivable-plan:create', 3, 2, 2428, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2430, '回款计划创建', 'crm:receivable-plan:create', 3, 2, 2428, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-29 11:18:09', '', '2023-10-29 11:18:09', b'0');
@ -2478,6 +2479,15 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2523, '客户限制配置导出', 'crm:customer-limit-config:export', 3, 5, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2523, '客户限制配置导出', 'crm:customer-limit-config:export', 3, 5, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2524, '系统配置', '', 1, 99, 2397, 'config', 'ep:connection', '', '', 0, b'1', b'1', b'1', '1', '2023-11-18 21:58:00', '1', '2023-11-18 21:58:00', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2524, '系统配置', '', 1, 99, 2397, 'config', 'ep:connection', '', '', 0, b'1', b'1', b'1', '1', '2023-11-18 21:58:00', '1', '2023-11-18 21:58:00', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2525, 'WebSocket 测试', '', 2, 7, 2, 'websocket', 'ep:connection', 'infra/webSocket/index', 'InfraWebSocket', 0, b'1', b'1', b'1', '1', '2023-11-23 19:41:55', '1', '2023-11-24 19:22:30', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2525, 'WebSocket 测试', '', 2, 7, 2, 'websocket', 'ep:connection', 'infra/webSocket/index', 'InfraWebSocket', 0, b'1', b'1', b'1', '1', '2023-11-23 19:41:55', '1', '2023-11-24 19:22:30', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`,
`component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`,
`updater`, `update_time`, `deleted`)
VALUES (2526, '抄送流程', '', 2, 21, 1200, 'processInstanceCC', 'eye', '/bpm/task/cc/index',
'BpmCCProcessInstance', 0, true, true, true, 1, '2023-01-13 16:14:00', '1', '2023-01-13 16:14:00', false),
(2527, '抄送流程查询', 'bpm:process-instance-cc:query', 3, 1, 2526, '', '', '', NULL, 0, b'1', b'1', b'1', '1',
'2023-01-13 16:14:00', '1', '2023-01-13 16:14:00', b'0'),
(2528, '抄送流程创建', 'bpm:process-instance-cc:create', 3, 2, 2526, '', '', '', NULL, 0, b'1', b'1', b'1', '1',
'2023-01-13 16:14:00', '1', '2023-01-13 16:14:00', b'0');
COMMIT; COMMIT;
-- ---------------------------- -- ----------------------------

View File

@ -68,6 +68,7 @@
<jsch.version>0.1.55</jsch.version> <jsch.version>0.1.55</jsch.version>
<tika-core.version>2.9.1</tika-core.version> <tika-core.version>2.9.1</tika-core.version>
<ip2region.version>2.7.0</ip2region.version> <ip2region.version>2.7.0</ip2region.version>
<bizlog-sdk.version>3.0.6</bizlog-sdk.version>
<reflections.version>0.10.2</reflections.version> <reflections.version>0.10.2</reflections.version>
<!-- 三方云服务相关 --> <!-- 三方云服务相关 -->
<okio.version>3.5.0</okio.version> <okio.version>3.5.0</okio.version>
@ -119,6 +120,17 @@
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId> <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<dependency>
<groupId>io.github.mouzt</groupId>
<artifactId>bizlog-sdk</artifactId>
<version>${bizlog-sdk.version}</version>
<exclusions>
<exclusion> <!-- 排除掉springboot依赖使用项目的 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>cn.iocoder.cloud</groupId> <groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-biz-dict</artifactId> <artifactId>yudao-spring-boot-starter-biz-dict</artifactId>

View File

@ -15,6 +15,7 @@ import java.util.Arrays;
@Getter @Getter
public enum TerminalEnum implements IntArrayValuable { public enum TerminalEnum implements IntArrayValuable {
UNKNOWN(0, "未知"), // 目的:在无法解析到 terminal 时,使用它
WECHAT_MINI_PROGRAM(10, "微信小程序"), WECHAT_MINI_PROGRAM(10, "微信小程序"),
WECHAT_WAP(11, "微信公众号"), WECHAT_WAP(11, "微信公众号"),
H5(20, "H5 网页"), H5(20, "H5 网页"),

View File

@ -30,6 +30,7 @@ public interface GlobalErrorCodeConstants {
ErrorCode INTERNAL_SERVER_ERROR = new ErrorCode(500, "系统异常"); ErrorCode INTERNAL_SERVER_ERROR = new ErrorCode(500, "系统异常");
ErrorCode NOT_IMPLEMENTED = new ErrorCode(501, "功能未实现/未开启"); ErrorCode NOT_IMPLEMENTED = new ErrorCode(501, "功能未实现/未开启");
ErrorCode ERROR_CONFIGURATION = new ErrorCode(502, "错误的配置项");
// ========== 自定义错误段 ========== // ========== 自定义错误段 ==========
ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求 ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求

View File

@ -35,9 +35,12 @@ public class ServiceErrorCodeRange {
// 模块 member 错误码区间 [1-004-000-000 ~ 1-005-000-000) // 模块 member 错误码区间 [1-004-000-000 ~ 1-005-000-000)
// 模块 mp 错误码区间 [1-006-000-000 ~ 1-007-000-000) // 模块 mp 错误码区间 [1-006-000-000 ~ 1-007-000-000)
// 模块 pay 错误码区间 [1-007-000-000 ~ 1-008-000-000) // 模块 pay 错误码区间 [1-007-000-000 ~ 1-008-000-000)
// 模块 product 错误码区间 [1-008-000-000 ~ 1-009-000-000)
// 模块 bpm 错误码区间 [1-009-000-000 ~ 1-010-000-000) // 模块 bpm 错误码区间 [1-009-000-000 ~ 1-010-000-000)
// 模块 product 错误码区间 [1-008-000-000 ~ 1-009-000-000)
// 模块 trade 错误码区间 [1-011-000-000 ~ 1-012-000-000) // 模块 trade 错误码区间 [1-011-000-000 ~ 1-012-000-000)
// 模块 promotion 错误码区间 [1-013-000-000 ~ 1-014-000-000) // 模块 promotion 错误码区间 [1-013-000-000 ~ 1-014-000-000)
// 模块 crm 错误码区间 [1-020-000-000 ~ 1-021-000-000)
} }

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.framework.common.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.List;
@Schema(description = "可排序的分页参数")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SortablePageParam extends PageParam {
@Schema(description = "排序字段")
private List<SortingField> sortingFields;
}

View File

@ -177,4 +177,14 @@ public class DateUtils {
return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now()); return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now());
} }
/**
*
*
* @param date
* @return
*/
public static boolean isYesterday(LocalDateTime date) {
return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now().minusDays(1));
}
} }

View File

@ -6,10 +6,11 @@ import java.time.Duration;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime; import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters; import java.time.temporal.TemporalAdjusters;
/** /**
* {@link java.time.LocalDateTime} * {@link LocalDateTime}
* *
* @author * @author
*/ */
@ -121,4 +122,14 @@ public class LocalDateTimeUtils {
return date.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX); return date.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
} }
/**
*
*
* @param dateTime
* @return
*/
public static Long between(LocalDateTime dateTime) {
return LocalDateTimeUtil.between(dateTime, LocalDateTime.now(), ChronoUnit.DAYS);
}
} }

View File

@ -5,11 +5,12 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
/** /**
* Bean * Bean
* *
* 1. 使 {@link cn.hutool.core.bean.BeanUtil} bean * 1. 使 {@link BeanUtil} bean
* 2. AuthConvert mapstruct + default * 2. AuthConvert mapstruct + default
* *
* @author * @author
@ -20,6 +21,14 @@ public class BeanUtils {
return BeanUtil.toBean(source, targetClass); return BeanUtil.toBean(source, targetClass);
} }
public static <T> T toBean(Object source, Class<T> targetClass, Consumer<T> peek) {
T target = toBean(source, targetClass);
if (target != null) {
peek.accept(target);
}
return target;
}
public static <S, T> List<T> toBean(List<S> source, Class<T> targetType) { public static <S, T> List<T> toBean(List<S> source, Class<T> targetType) {
if (source == null) { if (source == null) {
return null; return null;
@ -27,11 +36,27 @@ public class BeanUtils {
return CollectionUtils.convertList(source, s -> toBean(s, targetType)); return CollectionUtils.convertList(source, s -> toBean(s, targetType));
} }
public static <S, T> PageResult<T> toBean(PageResult<S> source, Class<T> targetType) { public static <S, T> List<T> toBean(List<S> source, Class<T> targetType, Consumer<T> peek) {
List<T> list = toBean(source, targetType);
if (list != null) {
list.forEach(peek);
}
return list;
}
public static <S, T> PageResult<T> toBean(PageResult<S> source, Class<T> targetType) {
return toBean(source, targetType, null);
}
public static <S, T> PageResult<T> toBean(PageResult<S> source, Class<T> targetType, Consumer<T> peek) {
if (source == null) { if (source == null) {
return null; return null;
} }
return new PageResult<>(toBean(source.getList(), targetType), source.getTotal()); List<T> list = toBean(source.getList(), targetType);
if (peek != null) {
list.forEach(peek);
}
return new PageResult<>(list, source.getTotal());
} }
} }

View File

@ -1,16 +1,67 @@
package cn.iocoder.yudao.framework.common.util.object; package cn.iocoder.yudao.framework.common.util.object;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.SortablePageParam;
import cn.iocoder.yudao.framework.common.pojo.SortingField;
import org.springframework.util.Assert;
import static java.util.Collections.singletonList;
/** /**
* {@link cn.iocoder.yudao.framework.common.pojo.PageParam} * {@link PageParam}
* *
* @author * @author
*/ */
public class PageUtils { public class PageUtils {
private static final Object[] ORDER_TYPES = new String[]{SortingField.ORDER_ASC, SortingField.ORDER_DESC};
public static int getStart(PageParam pageParam) { public static int getStart(PageParam pageParam) {
return (pageParam.getPageNo() - 1) * pageParam.getPageSize(); return (pageParam.getPageNo() - 1) * pageParam.getPageSize();
} }
/**
*
*
* @param func Lambda
* @param <T>
* @return
*/
public static <T> SortingField buildSortingField(Func1<T, ?> func) {
return buildSortingField(func, SortingField.ORDER_DESC);
}
/**
*
*
* @param func Lambda
* @param order {@link SortingField#ORDER_ASC} {@link SortingField#ORDER_DESC}
* @param <T>
* @return
*/
public static <T> SortingField buildSortingField(Func1<T, ?> func, String order) {
Assert.isTrue(ArrayUtil.contains(ORDER_TYPES, order), String.format("字段的排序类型只能是 %s/%s", ORDER_TYPES));
String fieldName = LambdaUtil.getFieldName(func);
return new SortingField(fieldName, order);
}
/**
*
*
*
* @param sortablePageParam
* @param func Lambda
* @param <T>
*/
public static <T> void buildDefaultSortingField(SortablePageParam sortablePageParam, Func1<T, ?> func) {
if (sortablePageParam != null && CollUtil.isEmpty(sortablePageParam.getSortingFields())) {
sortablePageParam.setSortingFields(singletonList(buildSortingField(func)));
}
}
} }

View File

@ -3,16 +3,15 @@ package cn.iocoder.yudao.framework.common.util.servlet;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.JakartaServletUtil; import cn.hutool.extra.servlet.JakartaServletUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Map; import java.util.Map;
@ -89,8 +88,6 @@ public class ServletUtils {
return JakartaServletUtil.getClientIP(request); return JakartaServletUtil.getClientIP(request);
} }
// TODO @疯狂terminal 还是从 ServletUtils 里拿,更容易全局治理;
public static boolean isJsonRequest(ServletRequest request) { public static boolean isJsonRequest(ServletRequest request) {
return StrUtil.startWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE); return StrUtil.startWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE);
} }

View File

@ -496,7 +496,8 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
Expression allExpression = null; Expression allExpression = null;
for (DataPermissionRule rule : ContextHolder.getRules()) { for (DataPermissionRule rule : ContextHolder.getRules()) {
// 判断表名是否匹配 // 判断表名是否匹配
if (!rule.getTableNames().contains(table.getName())) { String tableName = MyBatisUtils.getTableName(table);
if (!rule.getTableNames().contains(tableName)) {
continue; continue;
} }
// 如果有匹配的规则,说明可重写。 // 如果有匹配的规则,说明可重写。
@ -505,7 +506,6 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
ContextHolder.setRewrite(true); ContextHolder.setRewrite(true);
// 单条规则的条件 // 单条规则的条件
String tableName = MyBatisUtils.getTableName(table);
Expression oneExpress = rule.getExpression(tableName, table.getAlias()); Expression oneExpress = rule.getExpression(tableName, table.getAlias());
if (oneExpress == null){ if (oneExpress == null){
continue; continue;

View File

@ -490,6 +490,37 @@ id,name,type,parentId
441700,阳江市,3,440000 441700,阳江市,3,440000
441800,清远市,3,440000 441800,清远市,3,440000
441900,东莞市,3,440000 441900,东莞市,3,440000
441901,莞城区,4,441900
441902,南城区,4,441900
441904,万江区,4,441900
441905,石碣镇,4,441900
441906,石龙镇,4,441900
441907,茶山镇,4,441900
441908,石排镇,4,441900
441909,企石镇,4,441900
441910,横沥镇,4,441900
441911,桥头镇,4,441900
441912,谢岗镇,4,441900
441913,东坑镇,4,441900
441914,常平镇,4,441900
441915,寮步镇,4,441900
441916,大朗镇,4,441900
441917,麻涌镇,4,441900
441918,中堂镇,4,441900
441919,高埗镇,4,441900
441920,樟木头镇,4,441900
441921,大岭山镇,4,441900
441922,望牛墩镇,4,441900
441923,黄江镇,4,441900
441924,洪梅镇,4,441900
441925,清溪镇,4,441900
441926,沙田镇,4,441900
441927,道滘镇,4,441900
441928,塘厦镇,4,441900
441929,虎门镇,4,441900
441930,厚街镇,4,441900
441931,凤岗镇,4,441900
441932,长安镇,4,441900
442000,中山市,3,440000 442000,中山市,3,440000
445100,潮州市,3,440000 445100,潮州市,3,440000
445200,揭阳市,3,440000 445200,揭阳市,3,440000

1 id name type parentId
490 441700 阳江市 3 440000
491 441800 清远市 3 440000
492 441900 东莞市 3 440000
493 441901 莞城区 4 441900
494 441902 南城区 4 441900
495 441904 万江区 4 441900
496 441905 石碣镇 4 441900
497 441906 石龙镇 4 441900
498 441907 茶山镇 4 441900
499 441908 石排镇 4 441900
500 441909 企石镇 4 441900
501 441910 横沥镇 4 441900
502 441911 桥头镇 4 441900
503 441912 谢岗镇 4 441900
504 441913 东坑镇 4 441900
505 441914 常平镇 4 441900
506 441915 寮步镇 4 441900
507 441916 大朗镇 4 441900
508 441917 麻涌镇 4 441900
509 441918 中堂镇 4 441900
510 441919 高埗镇 4 441900
511 441920 樟木头镇 4 441900
512 441921 大岭山镇 4 441900
513 441922 望牛墩镇 4 441900
514 441923 黄江镇 4 441900
515 441924 洪梅镇 4 441900
516 441925 清溪镇 4 441900
517 441926 沙田镇 4 441900
518 441927 道滘镇 4 441900
519 441928 塘厦镇 4 441900
520 441929 虎门镇 4 441900
521 441930 厚街镇 4 441900
522 441931 凤岗镇 4 441900
523 441932 长安镇 4 441900
524 442000 中山市 3 440000
525 445100 潮州市 3 440000
526 445200 揭阳市 3 440000

View File

@ -9,7 +9,7 @@ import org.springframework.scheduling.annotation.Async;
/** /**
* Framework Service * Framework Service
* *
* {@link OperateLogApi} * {@link OperateLogApi}
* *
* @author * @author
*/ */

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.framework.tenant.core.context; package cn.iocoder.yudao.framework.tenant.core.context;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.DocumentEnum; import cn.iocoder.yudao.framework.common.enums.DocumentEnum;
import com.alibaba.ttl.TransmittableThreadLocal; import com.alibaba.ttl.TransmittableThreadLocal;
@ -21,7 +22,7 @@ public class TenantContextHolder {
private static final ThreadLocal<Boolean> IGNORE = new TransmittableThreadLocal<>(); private static final ThreadLocal<Boolean> IGNORE = new TransmittableThreadLocal<>();
/** /**
* *
* *
* @return * @return
*/ */
@ -29,6 +30,16 @@ public class TenantContextHolder {
return TENANT_ID.get(); return TENANT_ID.get();
} }
/**
* String
*
* @return
*/
public static String getTenantIdStr() {
Long tenantId = getTenantId();
return StrUtil.toStringOrNull(tenantId);
}
/** /**
* NullPointerException * NullPointerException
* *

View File

@ -92,7 +92,7 @@ public class TenantSecurityWebFilter extends ApiRequestFilter {
if (tenantId == null) { if (tenantId == null) {
log.error("[doFilterInternal][URL({}/{}) 未传递租户编号]", request.getRequestURI(), request.getMethod()); log.error("[doFilterInternal][URL({}/{}) 未传递租户编号]", request.getRequestURI(), request.getMethod());
ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),
"租户的请求未传递,请进行排查")); "请求的租户标识未传递,请进行排查"));
return; return;
} }
// 3. 校验租户是合法,例如说被禁用、到期 // 3. 校验租户是合法,例如说被禁用、到期

View File

@ -3,6 +3,8 @@ package cn.iocoder.yudao.framework.mybatis.core.mapper;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.SortablePageParam;
import cn.iocoder.yudao.framework.common.pojo.SortingField;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -13,6 +15,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.toolkit.Db; import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.github.yulichang.base.MPJBaseMapper; import com.github.yulichang.base.MPJBaseMapper;
import com.github.yulichang.interfaces.MPJBaseJoin; import com.github.yulichang.interfaces.MPJBaseJoin;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.Collection; import java.util.Collection;
@ -26,7 +29,15 @@ import java.util.List;
*/ */
public interface BaseMapperX<T> extends MPJBaseMapper<T> { public interface BaseMapperX<T> extends MPJBaseMapper<T> {
default PageResult<T> selectPage(SortablePageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
return selectPage(pageParam, pageParam.getSortingFields(), queryWrapper);
}
default PageResult<T> selectPage(PageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) { default PageResult<T> selectPage(PageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
return selectPage(pageParam, null, queryWrapper);
}
default PageResult<T> selectPage(PageParam pageParam, Collection<SortingField> sortingFields, @Param("ew") Wrapper<T> queryWrapper) {
// 特殊:不分页,直接查询全部 // 特殊:不分页,直接查询全部
if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) { if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {
List<T> list = selectList(queryWrapper); List<T> list = selectList(queryWrapper);
@ -34,12 +45,26 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
} }
// MyBatis Plus 查询 // MyBatis Plus 查询
IPage<T> mpPage = MyBatisUtils.buildPage(pageParam); IPage<T> mpPage = MyBatisUtils.buildPage(pageParam, sortingFields);
selectPage(mpPage, queryWrapper); selectPage(mpPage, queryWrapper);
// 转换返回 // 转换返回
return new PageResult<>(mpPage.getRecords(), mpPage.getTotal()); return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
} }
default <D> PageResult<D> selectJoinPage(PageParam pageParam, Class<D> clazz, MPJLambdaWrapper<T> lambdaWrapper) {
// 特殊:不分页,直接查询全部
if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageNo())) {
List<D> list = selectJoinList(clazz, lambdaWrapper);
return new PageResult<>(list, (long) list.size());
}
// MyBatis Plus Join 查询
IPage<D> mpPage = MyBatisUtils.buildPage(pageParam);
mpPage = selectJoinPage(mpPage, clazz, lambdaWrapper);
// 转换返回
return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
}
default <DTO> PageResult<DTO> selectJoinPage(PageParam pageParam, Class<DTO> resultTypeClass, MPJBaseJoin<T> joinQueryWrapper) { default <DTO> PageResult<DTO> selectJoinPage(PageParam pageParam, Class<DTO> resultTypeClass, MPJBaseJoin<T> joinQueryWrapper) {
IPage<DTO> mpPage = MyBatisUtils.buildPage(pageParam); IPage<DTO> mpPage = MyBatisUtils.buildPage(pageParam);
selectJoinPage(mpPage, resultTypeClass, joinQueryWrapper); selectJoinPage(mpPage, resultTypeClass, joinQueryWrapper);

View File

@ -34,7 +34,7 @@ public class MyBatisUtils {
// 排序字段 // 排序字段
if (!CollectionUtil.isEmpty(sortingFields)) { if (!CollectionUtil.isEmpty(sortingFields)) {
page.addOrder(sortingFields.stream().map(sortingField -> SortingField.ORDER_ASC.equals(sortingField.getOrder()) ? page.addOrder(sortingFields.stream().map(sortingField -> SortingField.ORDER_ASC.equals(sortingField.getOrder()) ?
OrderItem.asc(sortingField.getField()) : OrderItem.desc(sortingField.getField())) OrderItem.asc(sortingField.getField()) : OrderItem.desc(sortingField.getField()))
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
return page; return page;
@ -45,8 +45,8 @@ public class MyBatisUtils {
* MybatisPlusInterceptor * MybatisPlusInterceptor
* *
* @param interceptor * @param interceptor
* @param inner * @param inner
* @param index * @param index
*/ */
public static void addInterceptor(MybatisPlusInterceptor interceptor, InnerInterceptor inner, int index) { public static void addInterceptor(MybatisPlusInterceptor interceptor, InnerInterceptor inner, int index) {
List<InnerInterceptor> inners = new ArrayList<>(interceptor.getInterceptors()); List<InnerInterceptor> inners = new ArrayList<>(interceptor.getInterceptors());
@ -73,9 +73,9 @@ public class MyBatisUtils {
/** /**
* Column * Column
* *
* @param tableName * @param tableName
* @param tableAlias * @param tableAlias
* @param column * @param column
* @return Column * @return Column
*/ */
public static Column buildColumn(String tableName, Alias tableAlias, String column) { public static Column buildColumn(String tableName, Alias tableAlias, String column) {

View File

@ -12,7 +12,10 @@
<packaging>jar</packaging> <packaging>jar</packaging>
<name>${project.artifactId}</name> <name>${project.artifactId}</name>
<description>用户的认证、权限的校验</description> <description>
1. security用户的认证、权限的校验实现「谁」可以做「什么事」
2. operatelog操作日志实现「谁」在「什么时间」对「什么」做了「什么事」
</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url> <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies> <dependencies>
@ -63,6 +66,20 @@
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
</dependency> </dependency>
<dependency>
<!-- Spring Boot 通用操作日志组件,基于注解实现 -->
<!-- 此组件解决的问题是:「谁」在「什么时间」对「什么」做了「什么事」 -->
<groupId>io.github.mouzt</groupId>
<artifactId>bizlog-sdk</artifactId>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行 Token 的校验 -->
<version>${revision}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -0,0 +1,27 @@
package cn.iocoder.yudao.framework.operatelog.config;
import cn.iocoder.yudao.framework.operatelog.core.service.LogRecordServiceImpl;
import com.mzt.logapi.service.ILogRecordService;
import com.mzt.logapi.starter.annotation.EnableLogRecord;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
/**
*
*
* @author HUIHUI
*/
@EnableLogRecord(tenant = "") // 貌似用不上 tenant 这玩意给个空好啦
@AutoConfiguration
@Slf4j
public class YudaoOperateLogV2Configuration {
@Bean
@Primary
public ILogRecordService iLogRecordServiceImpl() {
return new LogRecordServiceImpl();
}
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.yudao.framework.operatelog.config;
import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* OperateLog 使 Feign
*
* @author
*/
@AutoConfiguration
@EnableFeignClients(clients = {OperateLogApi.class}) // 主要是引入相关的 API 服务
public class YudaoOperateLogV2RpcAutoConfiguration {
}

View File

@ -0,0 +1,4 @@
/**
*
*/
package cn.iocoder.yudao.framework.operatelog.core;

View File

@ -0,0 +1,89 @@
package cn.iocoder.yudao.framework.operatelog.core.service;
import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO;
import com.mzt.logapi.beans.LogRecord;
import com.mzt.logapi.service.ILogRecordService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
* ILogRecordService
*
* {@link OperateLogApi}
*
* @author HUIHUI
*/
@Slf4j
public class LogRecordServiceImpl implements ILogRecordService {
@Resource
private OperateLogApi operateLogApi;
@Override
public void record(LogRecord logRecord) {
// 1. 补全通用字段
OperateLogV2CreateReqDTO reqDTO = new OperateLogV2CreateReqDTO();
reqDTO.setTraceId(TracerUtils.getTraceId());
// 补充用户信息
fillUserFields(reqDTO);
// 补全模块信息
fillModuleFields(reqDTO, logRecord);
// 补全请求信息
fillRequestFields(reqDTO);
// 2. 异步记录日志
operateLogApi.createOperateLogV2(reqDTO);
// TODO 测试结束删除或搞个开关
log.info("操作日志 ===> {}", reqDTO);
}
private static void fillUserFields(OperateLogV2CreateReqDTO reqDTO) {
// 使用 SecurityFrameworkUtils。因为要考虑rpc、mq、job它其实不是 web
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
if (loginUser == null) {
return;
}
reqDTO.setUserId(loginUser.getId());
reqDTO.setUserType(loginUser.getUserType());
}
public static void fillModuleFields(OperateLogV2CreateReqDTO reqDTO, LogRecord logRecord) {
reqDTO.setType(logRecord.getType()); // 大模块类型例如CRM 客户
reqDTO.setSubType(logRecord.getSubType());// 操作名称,例如:转移客户
reqDTO.setBizId(Long.parseLong(logRecord.getBizNo())); // 业务编号,例如:客户编号
reqDTO.setAction(logRecord.getAction());// 操作内容,例如:修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
reqDTO.setExtra(logRecord.getExtra()); // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"}
}
private static void fillRequestFields(OperateLogV2CreateReqDTO reqDTO) {
// 获得 Request 对象
HttpServletRequest request = ServletUtils.getRequest();
if (request == null) {
return;
}
// 补全请求信息
reqDTO.setRequestMethod(request.getMethod());
reqDTO.setRequestUrl(request.getRequestURI());
reqDTO.setUserIp(ServletUtils.getClientIP(request));
reqDTO.setUserAgent(ServletUtils.getUserAgent(request));
}
@Override
public List<LogRecord> queryLog(String bizNo, String type) {
throw new UnsupportedOperationException("使用 OperateLogApi 进行操作日志的查询");
}
@Override
public List<LogRecord> queryLogByBizNo(String bizNo, String type, String subType) {
throw new UnsupportedOperationException("使用 OperateLogApi 进行操作日志的查询");
}
}

View File

@ -0,0 +1,7 @@
/**
* mzt-log
*
*
* @author HUIHUI
*/
package cn.iocoder.yudao.framework.operatelog;

View File

@ -1,3 +1,5 @@
cn.iocoder.yudao.framework.security.config.YudaoSecurityRpcAutoConfiguration cn.iocoder.yudao.framework.security.config.YudaoSecurityRpcAutoConfiguration
cn.iocoder.yudao.framework.security.config.YudaoSecurityAutoConfiguration cn.iocoder.yudao.framework.security.config.YudaoSecurityAutoConfiguration
cn.iocoder.yudao.framework.security.config.YudaoWebSecurityConfigurerAdapter cn.iocoder.yudao.framework.security.config.YudaoWebSecurityConfigurerAdapter
cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogV2Configuration
cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogV2RpcAutoConfiguration

View File

@ -22,7 +22,9 @@ public interface CodegenTableMapper extends BaseMapperX<CodegenTableDO> {
.likeIfPresent(CodegenTableDO::getTableName, pageReqVO.getTableName()) .likeIfPresent(CodegenTableDO::getTableName, pageReqVO.getTableName())
.likeIfPresent(CodegenTableDO::getTableComment, pageReqVO.getTableComment()) .likeIfPresent(CodegenTableDO::getTableComment, pageReqVO.getTableComment())
.likeIfPresent(CodegenTableDO::getClassName, pageReqVO.getClassName()) .likeIfPresent(CodegenTableDO::getClassName, pageReqVO.getClassName())
.betweenIfPresent(CodegenTableDO::getCreateTime, pageReqVO.getCreateTime())); .betweenIfPresent(CodegenTableDO::getCreateTime, pageReqVO.getCreateTime())
.orderByDesc(CodegenTableDO::getUpdateTime)
);
} }
default List<CodegenTableDO> selectListByDataSourceConfigId(Long dataSourceConfigId) { default List<CodegenTableDO> selectListByDataSourceConfigId(Long dataSourceConfigId) {

View File

@ -7,7 +7,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
/** /**
* Infra Security * Infra Security

View File

@ -1,7 +1,7 @@
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}; package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName};
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
#if ($sceneEnum.scene == 1)import org.springframework.security.access.prepost.PreAuthorize;#end #if ($sceneEnum.scene == 1)import org.springframework.security.access.prepost.PreAuthorize;#end
@ -9,9 +9,9 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*; import jakarta.validation.constraints.*;
import javax.validation.*; import jakarta.validation.*;
import javax.servlet.http.*; import jakarta.servlet.http.*;
import java.util.*; import java.util.*;
import java.io.IOException; import java.io.IOException;

View File

@ -3,9 +3,8 @@ package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePac
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import java.util.*; import java.util.*;
import javax.validation.constraints.*; import jakarta.validation.constraints.*;
## 处理 BigDecimal 字段的引入 ## 处理 BigDecimal 字段的引入
import java.util.*;
#foreach ($column in $columns) #foreach ($column in $columns)
#if (${column.javaType} == "BigDecimal") #if (${column.javaType} == "BigDecimal")
import java.math.BigDecimal; import java.math.BigDecimal;

View File

@ -1,7 +1,7 @@
package ${basePackage}.module.${table.moduleName}.service.${table.businessName}; package ${basePackage}.module.${table.moduleName}.service.${table.businessName};
import java.util.*; import java.util.*;
import javax.validation.*; import jakarta.validation.*;
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*; import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO; import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
## 特殊:主子表专属逻辑 ## 特殊:主子表专属逻辑

View File

@ -1,7 +1,7 @@
package ${basePackage}.module.${table.moduleName}.service.${table.businessName}; package ${basePackage}.module.${table.moduleName}.service.${table.businessName};
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;

View File

@ -4,7 +4,7 @@ import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.MockBean;
import javax.annotation.Resource; import jakarta.annotation.Resource;
import ${baseFrameworkPackage}.test.core.ut.BaseDbUnitTest; import ${baseFrameworkPackage}.test.core.ut.BaseDbUnitTest;
@ -13,7 +13,7 @@ import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.business
import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper; import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper;
import ${PageResultClassName}; import ${PageResultClassName};
import javax.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import java.util.*; import java.util.*;
import java.time.LocalDateTime; import java.time.LocalDateTime;

View File

@ -63,7 +63,7 @@ export function export${simpleClassName}Excel(params) {
responseType: 'blob' responseType: 'blob'
}) })
} }
## 特殊:主子表专属逻辑 TODO @puhui999下面方法的【空格】不太对 ## 特殊:主子表专属逻辑
#foreach ($subTable in $subTables) #foreach ($subTable in $subTables)
#set ($index = $foreach.count - 1) #set ($index = $foreach.count - 1)
#set ($subSimpleClassName = $subSimpleClassNames.get($index)) #set ($subSimpleClassName = $subSimpleClassNames.get($index))
@ -76,8 +76,7 @@ export function export${simpleClassName}Excel(params) {
// ==================== 子表($subTable.classComment ==================== // ==================== 子表($subTable.classComment ====================
## 情况一MASTER_ERP 时,需要分查询页子表 ## 情况一MASTER_ERP 时,需要分查询页子表
#if ( $table.templateType == 11 ) #if ($table.templateType == 11)
// 获得${subTable.classComment}分页 // 获得${subTable.classComment}分页
export function get${subSimpleClassName}Page(params) { export function get${subSimpleClassName}Page(params) {
return request({ return request({
@ -88,58 +87,53 @@ export function export${simpleClassName}Excel(params) {
} }
## 情况二:非 MASTER_ERP 时,需要列表查询子表 ## 情况二:非 MASTER_ERP 时,需要列表查询子表
#else #else
#if ( $subTable.subJoinMany ) #if ($subTable.subJoinMany)
// 获得${subTable.classComment}列表 // 获得${subTable.classComment}列表
export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}) { export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}) {
return request({ return request({
url: `${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField}, url: '${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=' + ${subJoinColumn.javaField},
method: 'get' method: 'get'
}) })
} }
#else #else
// 获得${subTable.classComment} // 获得${subTable.classComment}
export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}) { export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}) {
return request({ return request({
url: `${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField}, url: '${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=' + ${subJoinColumn.javaField},
method: 'get' method: 'get'
}) })
} }
#end #end
#end #end
## 特殊MASTER_ERP 时,支持单个的新增、修改、删除操作 ## 特殊MASTER_ERP 时,支持单个的新增、修改、删除操作
#if ( $table.templateType == 11 ) #if ($table.templateType == 11)
// 新增${subTable.classComment} // 新增${subTable.classComment}
export function create${subSimpleClassName}(data) { export function create${subSimpleClassName}(data) {
return request({ return request({
url: `${baseURL}/${subSimpleClassName_strikeCase}/create`, url: '${baseURL}/${subSimpleClassName_strikeCase}/create',
method: 'post', method: 'post',
data data
}) })
} }
// 修改${subTable.classComment} // 修改${subTable.classComment}
export function update${subSimpleClassName}(data) { export function update${subSimpleClassName}(data) {
return request({ return request({
url: `${baseURL}/${subSimpleClassName_strikeCase}/update`, url: '${baseURL}/${subSimpleClassName_strikeCase}/update',
method: 'post', method: 'post',
data data
}) })
} }
// 删除${subTable.classComment} // 删除${subTable.classComment}
export function delete${subSimpleClassName}(id) { export function delete${subSimpleClassName}(id) {
return request({ return request({
url: `${baseURL}/${subSimpleClassName_strikeCase}/delete?id=` + id, url: '${baseURL}/${subSimpleClassName_strikeCase}/delete?id=' + id,
method: 'delete' method: 'delete'
}) })
} }
// 获得${subTable.classComment} // 获得${subTable.classComment}
export function get${subSimpleClassName}(id) { export function get${subSimpleClassName}(id) {
return request({ return request({
url: `${baseURL}/${subSimpleClassName_strikeCase}/get?id=` + id, url: '${baseURL}/${subSimpleClassName_strikeCase}/get?id=' + id,
method: 'get' method: 'get'
}) })
} }

View File

@ -1,12 +1,14 @@
import request from '@/config/axios' import request from '@/config/axios'
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}") #set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
// ${table.classComment} VO
export interface ${simpleClassName}VO { export interface ${simpleClassName}VO {
#foreach ($column in $columns) #foreach ($column in $columns)
#if ($column.createOperation || $column.updateOperation) #if ($column.createOperation || $column.updateOperation)
// ${column.columnComment}
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal") #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
${column.javaField}: number ${column.javaField}: number
#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdatetime") #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
${column.javaField}: Date ${column.javaField}: Date
#else #else
${column.javaField}: ${column.javaType.toLowerCase()} ${column.javaField}: ${column.javaType.toLowerCase()}
@ -15,42 +17,44 @@ export interface ${simpleClassName}VO {
#end #end
} }
// ${table.classComment} API
export const ${simpleClassName}Api = {
#if ( $table.templateType != 2 ) #if ( $table.templateType != 2 )
// 查询${table.classComment}分页 // 查询${table.classComment}分页
export const get${simpleClassName}Page = async (params) => { get${simpleClassName}Page: async (params: any) => {
return await request.get({ url: `${baseURL}/page`, params }) return await request.get({ url: `${baseURL}/page`, params })
} },
#else #else
// 查询${table.classComment}列表 // 查询${table.classComment}列表
export const get${simpleClassName}List = async (params) => { get${simpleClassName}List: async (params) => {
return await request.get({ url: `${baseURL}/list`, params }) return await request.get({ url: `${baseURL}/list`, params })
} },
#end #end
// 查询${table.classComment}详情 // 查询${table.classComment}详情
export const get${simpleClassName} = async (id: number) => { get${simpleClassName}: async (id: number) => {
return await request.get({ url: `${baseURL}/get?id=` + id }) return await request.get({ url: `${baseURL}/get?id=` + id })
} },
// 新增${table.classComment} // 新增${table.classComment}
export const create${simpleClassName} = async (data: ${simpleClassName}VO) => { create${simpleClassName}: async (data: ${simpleClassName}VO) => {
return await request.post({ url: `${baseURL}/create`, data }) return await request.post({ url: `${baseURL}/create`, data })
} },
// 修改${table.classComment} // 修改${table.classComment}
export const update${simpleClassName} = async (data: ${simpleClassName}VO) => { update${simpleClassName}: async (data: ${simpleClassName}VO) => {
return await request.put({ url: `${baseURL}/update`, data }) return await request.put({ url: `${baseURL}/update`, data })
} },
// 删除${table.classComment} // 删除${table.classComment}
export const delete${simpleClassName} = async (id: number) => { delete${simpleClassName}: async (id: number) => {
return await request.delete({ url: `${baseURL}/delete?id=` + id }) return await request.delete({ url: `${baseURL}/delete?id=` + id })
} },
// 导出${table.classComment} Excel // 导出${table.classComment} Excel
export const export${simpleClassName} = async (params) => { export${simpleClassName}: async (params) => {
return await request.download({ url: `${baseURL}/export-excel`, params }) return await request.download({ url: `${baseURL}/export-excel`, params })
} },
## 特殊:主子表专属逻辑 ## 特殊:主子表专属逻辑
#foreach ($subTable in $subTables) #foreach ($subTable in $subTables)
#set ($index = $foreach.count - 1) #set ($index = $foreach.count - 1)
@ -66,46 +70,47 @@ export const export${simpleClassName} = async (params) => {
## 情况一MASTER_ERP 时,需要分查询页子表 ## 情况一MASTER_ERP 时,需要分查询页子表
#if ( $table.templateType == 11 ) #if ( $table.templateType == 11 )
// 获得${subTable.classComment}分页 // 获得${subTable.classComment}分页
export const get${subSimpleClassName}Page = async (params) => { get${subSimpleClassName}Page: async (params) => {
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/page`, params }) return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/page`, params })
} },
## 情况二:非 MASTER_ERP 时,需要列表查询子表 ## 情况二:非 MASTER_ERP 时,需要列表查询子表
#else #else
#if ( $subTable.subJoinMany ) #if ( $subTable.subJoinMany )
// 获得${subTable.classComment}列表 // 获得${subTable.classComment}列表
export const get${subSimpleClassName}ListBy${SubJoinColumnName} = async (${subJoinColumn.javaField}) => { get${subSimpleClassName}ListBy${SubJoinColumnName}: async (${subJoinColumn.javaField}) => {
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField} }) return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField} })
} },
#else #else
// 获得${subTable.classComment} // 获得${subTable.classComment}
export const get${subSimpleClassName}By${SubJoinColumnName} = async (${subJoinColumn.javaField}) => { get${subSimpleClassName}By${SubJoinColumnName}: async (${subJoinColumn.javaField}) => {
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField} }) return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField} })
} },
#end #end
#end #end
## 特殊MASTER_ERP 时,支持单个的新增、修改、删除操作 ## 特殊MASTER_ERP 时,支持单个的新增、修改、删除操作
#if ( $table.templateType == 11 ) #if ( $table.templateType == 11 )
// 新增${subTable.classComment} // 新增${subTable.classComment}
export const create${subSimpleClassName} = async (data) => { create${subSimpleClassName}: async (data) => {
return await request.post({ url: `${baseURL}/${subSimpleClassName_strikeCase}/create`, data }) return await request.post({ url: `${baseURL}/${subSimpleClassName_strikeCase}/create`, data })
} },
// 修改${subTable.classComment} // 修改${subTable.classComment}
export const update${subSimpleClassName} = async (data) => { update${subSimpleClassName}: async (data) => {
return await request.put({ url: `${baseURL}/${subSimpleClassName_strikeCase}/update`, data }) return await request.put({ url: `${baseURL}/${subSimpleClassName_strikeCase}/update`, data })
} },
// 删除${subTable.classComment} // 删除${subTable.classComment}
export const delete${subSimpleClassName} = async (id: number) => { delete${subSimpleClassName}: async (id: number) => {
return await request.delete({ url: `${baseURL}/${subSimpleClassName_strikeCase}/delete?id=` + id }) return await request.delete({ url: `${baseURL}/${subSimpleClassName_strikeCase}/delete?id=` + id })
} },
// 获得${subTable.classComment} // 获得${subTable.classComment}
export const get${subSimpleClassName} = async (id: number) => { get${subSimpleClassName}: async (id: number) => {
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get?id=` + id }) return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get?id=` + id })
} },
#end #end
#end #end
}

View File

@ -114,7 +114,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict' import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}' import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
const { t } = useI18n() // 国际化 const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗 const message = useMessage() // 消息弹窗

View File

@ -265,7 +265,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict' import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}' import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
const props = defineProps<{ const props = defineProps<{
${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段) ${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段)

View File

@ -85,7 +85,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict' import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime' import { dateFormatter } from '@/utils/formatTime'
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}' import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
#if ($table.templateType == 11) #if ($table.templateType == 11)
import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue' import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue'
#end #end

View File

@ -140,7 +140,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict' import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}' import { ${simpleClassName}Api, ${simpleClassName}VO } from '@/api/${table.moduleName}/${table.businessName}'
## 特殊:树表专属逻辑 ## 特殊:树表专属逻辑
#if ( $table.templateType == 2 ) #if ( $table.templateType == 2 )
import { defaultProps, handleTree } from '@/utils/tree' import { defaultProps, handleTree } from '@/utils/tree'
@ -152,6 +152,9 @@ import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vu
#end #end
#end #end
/** ${table.classComment} 表单 */
defineOptions({ name: '${simpleClassName}Form' })
const { t } = useI18n() // 国际化 const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗 const message = useMessage() // 消息弹窗

View File

@ -240,7 +240,7 @@ import { dateFormatter } from '@/utils/formatTime'
import { handleTree } from '@/utils/tree' import { handleTree } from '@/utils/tree'
#end #end
import download from '@/utils/download' import download from '@/utils/download'
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}' import { ${simpleClassName}Api, ${simpleClassName}VO } from '@/api/${table.moduleName}/${table.businessName}'
import ${simpleClassName}Form from './${simpleClassName}Form.vue' import ${simpleClassName}Form from './${simpleClassName}Form.vue'
## 特殊:主子表专属逻辑 ## 特殊:主子表专属逻辑
#if ( $table.templateType != 10 ) #if ( $table.templateType != 10 )
@ -249,16 +249,18 @@ import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vu
#end #end
#end #end
/** ${table.classComment} 列表 */
defineOptions({ name: '${table.className}' }) defineOptions({ name: '${table.className}' })
const message = useMessage() // 消息弹窗 const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化 const { t } = useI18n() // 国际化
const loading = ref(true) // 列表的加载中 const loading = ref(true) // 列表的加载中
const list = ref([]) // 列表的数据 const list = ref<${simpleClassName}VO[]>([]) // 列表的数据
## 特殊:树表专属逻辑(树不需要分页接口) ## 特殊:树表专属逻辑(树不需要分页接口)
#if ( $table.templateType != 2 ) #if ( $table.templateType != 2 )
const total = ref(0) // 列表的总页数 // 列表的总页数
const total = ref(0)
#end #end
const queryParams = reactive({ const queryParams = reactive({
## 特殊:树表专属逻辑(树不需要分页接口) ## 特殊:树表专属逻辑(树不需要分页接口)

View File

@ -31,6 +31,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
*/ */
public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest { public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
/**
*
*/
private String resourcesPath = "";
@InjectMocks @InjectMocks
protected CodegenEngine codegenEngine; protected CodegenEngine codegenEngine;
@ -41,6 +46,10 @@ public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
@BeforeEach @BeforeEach
public void setUp() { public void setUp() {
codegenEngine.initGlobalBindingMap(); codegenEngine.initGlobalBindingMap();
// 获取测试文件 resources 路径
String absolutePath = FileUtil.getAbsolutePath("application-unit-test.yaml");
// 系统不一样生成的文件也有差异,那就各自生成各自的
resourcesPath = absolutePath.split("/target")[0] + "/src/test/resources/codegen/";
} }
protected static CodegenTableDO getTable(String name) { protected static CodegenTableDO getTable(String name) {
@ -73,14 +82,14 @@ public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
protected static void assertResult(Map<String, String> result, String path) { protected static void assertResult(Map<String, String> result, String path) {
String assertContent = ResourceUtil.readUtf8Str(path + "/assert.json"); String assertContent = ResourceUtil.readUtf8Str("codegen/" + path + "/assert.json");
List<HashMap> asserts = JsonUtils.parseArray(assertContent, HashMap.class); List<HashMap> asserts = JsonUtils.parseArray(assertContent, HashMap.class);
assertEquals(asserts.size(), result.size()); assertEquals(asserts.size(), result.size());
// 校验每个文件 // 校验每个文件
asserts.forEach(assertMap -> { asserts.forEach(assertMap -> {
String contentPath = (String) assertMap.get("contentPath"); String contentPath = (String) assertMap.get("contentPath");
String filePath = (String) assertMap.get("filePath"); String filePath = (String) assertMap.get("filePath");
String content = ResourceUtil.readUtf8Str(path + "/" + contentPath); String content = ResourceUtil.readUtf8Str("codegen/" + path + "/" + contentPath);
assertEquals(content, result.get(filePath), filePath + ":不匹配"); assertEquals(content, result.get(filePath), filePath + ":不匹配");
}); });
} }
@ -91,7 +100,7 @@ public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
* 使 * 使
* *
* @param result * @param result
* @param path * @param path
*/ */
protected void writeFile(Map<String, String> result, String path) { protected void writeFile(Map<String, String> result, String path) {
// 生成压缩包 // 生成压缩包
@ -106,7 +115,7 @@ public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
/** /**
* 使 * 使
* *
* @param result * @param result
* @param basePath * @param basePath
*/ */
protected void writeResult(Map<String, String> result, String basePath) { protected void writeResult(Map<String, String> result, String basePath) {
@ -121,7 +130,7 @@ public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
FileUtil.writeUtf8String(fileContent, basePath + "/" + contentPath); FileUtil.writeUtf8String(fileContent, basePath + "/" + contentPath);
}); });
// 写入 assert.json 文件 // 写入 assert.json 文件
FileUtil.writeUtf8String(JsonUtils.toJsonPrettyString(asserts), basePath +"/assert.json"); FileUtil.writeUtf8String(JsonUtils.toJsonPrettyString(asserts), basePath + "/assert.json");
} }
} }

View File

@ -1,202 +0,0 @@
package cn.iocoder.yudao.module.infra.service.codegen.inner;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link CodegenEngine}
*
* @author
*/
public class CodegenEngineTest extends BaseMockitoUnitTest {
@InjectMocks
private CodegenEngine codegenEngine;
@Spy
private CodegenProperties codegenProperties = new CodegenProperties()
.setBasePackage("cn.iocoder.yudao");
@BeforeEach
public void setUp() {
codegenEngine.initGlobalBindingMap();
}
@Test
public void testExecute_vue3_one() {
// 准备参数
CodegenTableDO table = getTable("student")
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
.setTemplateType(CodegenTemplateTypeEnum.ONE.getType());
List<CodegenColumnDO> columns = getColumnList("student");
// 调用
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
// 断言
assertResult(result, "codegen/vue3_one");
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_one");
}
@Test
public void testExecute_vue3_tree() {
// 准备参数
CodegenTableDO table = getTable("category")
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
.setTemplateType(CodegenTemplateTypeEnum.TREE.getType());
List<CodegenColumnDO> columns = getColumnList("category");
// 调用
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
// 断言
assertResult(result, "codegen/vue3_tree");
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_tree");
// writeFile(result, "/Users/yunai/test/demo66.zip");
}
@Test
public void testExecute_vue3_master_normal() {
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_NORMAL, "codegen/vue3_master_normal");
}
@Test
public void testExecute_vue3_master_erp() {
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_ERP, "codegen/vue3_master_erp");
}
@Test
public void testExecute_vue3_master_inner() {
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_INNER, "codegen/vue3_master_inner");
}
private void testExecute_vue3_master(CodegenTemplateTypeEnum templateType,
String path) {
// 准备参数
CodegenTableDO table = getTable("student")
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
.setTemplateType(templateType.getType());
List<CodegenColumnDO> columns = getColumnList("student");
// 准备参数(子表)
CodegenTableDO contactTable = getTable("contact")
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
.setSubJoinColumnId(100L).setSubJoinMany(true);
List<CodegenColumnDO> contactColumns = getColumnList("contact");
// 准备参数(班主任)
CodegenTableDO teacherTable = getTable("teacher")
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
.setSubJoinColumnId(200L).setSubJoinMany(false);
List<CodegenColumnDO> teacherColumns = getColumnList("teacher");
// 调用
Map<String, String> result = codegenEngine.execute(table, columns,
Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns));
// 断言
assertResult(result, path);
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/" + path);
// writeFile(result, "/Users/yunai/test/demo11.zip");
}
private static CodegenTableDO getTable(String name) {
String content = ResourceUtil.readUtf8Str("codegen/table/" + name + ".json");
return JsonUtils.parseObject(content, "table", CodegenTableDO.class);
}
private static List<CodegenColumnDO> getColumnList(String name) {
String content = ResourceUtil.readUtf8Str("codegen/table/" + name + ".json");
List<CodegenColumnDO> list = JsonUtils.parseArray(content, "columns", CodegenColumnDO.class);
list.forEach(column -> {
if (column.getNullable() == null) {
column.setNullable(false);
}
if (column.getCreateOperation() == null) {
column.setCreateOperation(false);
}
if (column.getUpdateOperation() == null) {
column.setUpdateOperation(false);
}
if (column.getListOperation() == null) {
column.setListOperation(false);
}
if (column.getListOperationResult() == null) {
column.setListOperationResult(false);
}
});
return list;
}
@SuppressWarnings("rawtypes")
private static void assertResult(Map<String, String> result, String path) {
String assertContent = ResourceUtil.readUtf8Str(path + "/assert.json");
List<HashMap> asserts = JsonUtils.parseArray(assertContent, HashMap.class);
assertEquals(asserts.size(), result.size());
// 校验每个文件
asserts.forEach(assertMap -> {
String contentPath = (String) assertMap.get("contentPath");
String filePath = (String) assertMap.get("filePath");
String content = ResourceUtil.readUtf8Str(path + "/" + contentPath);
assertEquals(content, result.get(filePath), filePath + ":不匹配");
});
}
// ==================== 调试专用 ====================
/**
* 使
*
* @param result
* @param path
*/
private void writeFile(Map<String, String> result, String path) {
// 生成压缩包
String[] paths = result.keySet().toArray(new String[0]);
ByteArrayInputStream[] ins = result.values().stream().map(IoUtil::toUtf8Stream).toArray(ByteArrayInputStream[]::new);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipUtil.zip(outputStream, paths, ins);
// 写入文件
FileUtil.writeBytes(outputStream.toByteArray(), path);
}
/**
* 使
*
* @param result
* @param basePath
*/
private void writeResult(Map<String, String> result, String basePath) {
// 写入文件内容
List<Map<String, String>> asserts = new ArrayList<>();
result.forEach((filePath, fileContent) -> {
String lastFilePath = StrUtil.subAfter(filePath, '/', true);
String contentPath = StrUtil.subAfter(lastFilePath, '.', true)
+ '/' + StrUtil.subBefore(lastFilePath, '.', true);
asserts.add(MapUtil.<String, String>builder().put("filePath", filePath)
.put("contentPath", contentPath).build());
FileUtil.writeUtf8String(fileContent, basePath + "/" + contentPath);
});
// 写入 assert.json 文件
FileUtil.writeUtf8String(JsonUtils.toJsonPrettyString(asserts), basePath +"/assert.json");
}
}

View File

@ -11,7 +11,6 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
// TODO @puhui999单测需要 fix
/** /**
* {@link CodegenEngine} Vue2 + Element UI * {@link CodegenEngine} Vue2 + Element UI
* *
@ -30,9 +29,10 @@ public class CodegenEngineVue2Test extends CodegenEngineAbstractTest {
// 调用 // 调用
Map<String, String> result = codegenEngine.execute(table, columns, null, null); Map<String, String> result = codegenEngine.execute(table, columns, null, null);
// 生成测试文件
//writeResult(result, resourcesPath + "/vue2_one");
// 断言 // 断言
assertResult(result, "codegen/vue2_one"); assertResult(result, "/vue2_one");
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue2_one");
} }
@Test @Test
@ -45,25 +45,26 @@ public class CodegenEngineVue2Test extends CodegenEngineAbstractTest {
// 调用 // 调用
Map<String, String> result = codegenEngine.execute(table, columns, null, null); Map<String, String> result = codegenEngine.execute(table, columns, null, null);
// 生成测试文件
//writeResult(result, resourcesPath + "/vue2_tree");
// 断言 // 断言
assertResult(result, "codegen/vue2_tree"); assertResult(result, "/vue2_tree");
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue2_tree");
// writeFile(result, "/Users/yunai/test/demo66.zip"); // writeFile(result, "/Users/yunai/test/demo66.zip");
} }
@Test @Test
public void testExecute_vue2_master_normal() { public void testExecute_vue2_master_normal() {
testExecute_vue2_master(CodegenTemplateTypeEnum.MASTER_NORMAL, "codegen/vue2_master_normal"); testExecute_vue2_master(CodegenTemplateTypeEnum.MASTER_NORMAL, "/vue2_master_normal");
} }
@Test @Test
public void testExecute_vue2_master_erp() { public void testExecute_vue2_master_erp() {
testExecute_vue2_master(CodegenTemplateTypeEnum.MASTER_ERP, "codegen/vue2_master_erp"); testExecute_vue2_master(CodegenTemplateTypeEnum.MASTER_ERP, "/vue2_master_erp");
} }
@Test @Test
public void testExecute_vue2_master_inner() { public void testExecute_vue2_master_inner() {
testExecute_vue2_master(CodegenTemplateTypeEnum.MASTER_INNER, "codegen/vue2_master_inner"); testExecute_vue2_master(CodegenTemplateTypeEnum.MASTER_INNER, "/vue2_master_inner");
} }
private void testExecute_vue2_master(CodegenTemplateTypeEnum templateType, private void testExecute_vue2_master(CodegenTemplateTypeEnum templateType,
@ -89,9 +90,10 @@ public class CodegenEngineVue2Test extends CodegenEngineAbstractTest {
// 调用 // 调用
Map<String, String> result = codegenEngine.execute(table, columns, Map<String, String> result = codegenEngine.execute(table, columns,
Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns)); Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns));
// 生成测试文件
//writeResult(result, resourcesPath + path);
// 断言 // 断言
assertResult(result, path); assertResult(result, path);
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/" + path);
// writeFile(result, "/Users/yunai/test/demo11.zip"); // writeFile(result, "/Users/yunai/test/demo11.zip");
} }

View File

@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum; import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum; import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.Arrays; import java.util.Arrays;
@ -15,6 +16,7 @@ import java.util.Map;
* *
* @author * @author
*/ */
@Disabled
public class CodegenEngineVue3Test extends CodegenEngineAbstractTest { public class CodegenEngineVue3Test extends CodegenEngineAbstractTest {
@Test @Test
@ -27,9 +29,10 @@ public class CodegenEngineVue3Test extends CodegenEngineAbstractTest {
// 调用 // 调用
Map<String, String> result = codegenEngine.execute(table, columns, null, null); Map<String, String> result = codegenEngine.execute(table, columns, null, null);
// 生成测试文件
//writeResult(result, resourcesPath + "/vue3_one");
// 断言 // 断言
assertResult(result, "codegen/vue3_one"); assertResult(result, "/vue3_one");
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_one");
} }
@Test @Test
@ -42,25 +45,26 @@ public class CodegenEngineVue3Test extends CodegenEngineAbstractTest {
// 调用 // 调用
Map<String, String> result = codegenEngine.execute(table, columns, null, null); Map<String, String> result = codegenEngine.execute(table, columns, null, null);
// 生成测试文件
//writeResult(result, resourcesPath + "/vue3_tree");
// 断言 // 断言
assertResult(result, "codegen/vue3_tree"); assertResult(result, "/vue3_tree");
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_tree");
// writeFile(result, "/Users/yunai/test/demo66.zip"); // writeFile(result, "/Users/yunai/test/demo66.zip");
} }
@Test @Test
public void testExecute_vue3_master_normal() { public void testExecute_vue3_master_normal() {
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_NORMAL, "codegen/vue3_master_normal"); testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_NORMAL, "/vue3_master_normal");
} }
@Test @Test
public void testExecute_vue3_master_erp() { public void testExecute_vue3_master_erp() {
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_ERP, "codegen/vue3_master_erp"); testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_ERP, "/vue3_master_erp");
} }
@Test @Test
public void testExecute_vue3_master_inner() { public void testExecute_vue3_master_inner() {
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_INNER, "codegen/vue3_master_inner"); testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_INNER, "/vue3_master_inner");
} }
private void testExecute_vue3_master(CodegenTemplateTypeEnum templateType, private void testExecute_vue3_master(CodegenTemplateTypeEnum templateType,
@ -86,10 +90,11 @@ public class CodegenEngineVue3Test extends CodegenEngineAbstractTest {
// 调用 // 调用
Map<String, String> result = codegenEngine.execute(table, columns, Map<String, String> result = codegenEngine.execute(table, columns,
Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns)); Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns));
// 生成测试文件
//writeResult(result, resourcesPath + path);
// 断言 // 断言
assertResult(result, path); assertResult(result, path);
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/" + path); // writeFile(result, "/Users/yunai/test/demo11.zip");
// writeFile(result, "/Users/yunai/test/demo11.zip");
} }
} }

View File

@ -51,13 +51,13 @@ public class ApiErrorLogServiceImplTest extends BaseDbUnitTest {
// 测试 userId 不匹配 // 测试 userId 不匹配
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, o -> o.setUserId(3344L))); apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, o -> o.setUserId(3344L)));
// 测试 userType 不匹配 // 测试 userType 不匹配
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
// 测试 applicationName 不匹配 // 测试 applicationName 不匹配
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setApplicationName("test"))); apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, o -> o.setApplicationName("test")));
// 测试 requestUrl 不匹配 // 测试 requestUrl 不匹配
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setRequestUrl("bar"))); apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, o -> o.setRequestUrl("bar")));
// 测试 exceptionTime 不匹配:构造一个早期时间 2021-02-06 00:00:00 // 测试 exceptionTime 不匹配:构造一个早期时间 2021-02-06 00:00:00
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6)))); apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, o -> o.setExceptionTime(buildTime(2021, 2, 6))));
// 测试 progressStatus 不匹配 // 测试 progressStatus 不匹配
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setProcessStatus(ApiErrorLogProcessStatusEnum.DONE.getStatus()))); apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setProcessStatus(ApiErrorLogProcessStatusEnum.DONE.getStatus())));
// 准备参数 // 准备参数

View File

@ -53,8 +53,8 @@
"contentPath" : "vue/index", "contentPath" : "vue/index",
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/index.vue" "filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/index.vue"
}, { }, {
"contentPath" : "js/student", "contentPath": "js/index",
"filePath" : "yudao-ui-admin-vue2/src/api/infra/student.js" "filePath": "yudao-ui-admin-vue2/src/api/infra/demo/index.js"
}, { }, {
"contentPath" : "vue/StudentForm", "contentPath" : "vue/StudentForm",
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/StudentForm.vue" "filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/StudentForm.vue"

View File

@ -53,8 +53,8 @@
"contentPath" : "vue/index", "contentPath" : "vue/index",
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/index.vue" "filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/index.vue"
}, { }, {
"contentPath" : "js/student", "contentPath": "js/index",
"filePath" : "yudao-ui-admin-vue2/src/api/infra/student.js" "filePath": "yudao-ui-admin-vue2/src/api/infra/demo/index.js"
}, { }, {
"contentPath" : "vue/StudentForm", "contentPath" : "vue/StudentForm",
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/StudentForm.vue" "filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/StudentForm.vue"

View File

@ -53,8 +53,8 @@
"contentPath" : "vue/index", "contentPath" : "vue/index",
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/index.vue" "filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/index.vue"
}, { }, {
"contentPath" : "js/student", "contentPath": "js/index",
"filePath" : "yudao-ui-admin-vue2/src/api/infra/student.js" "filePath": "yudao-ui-admin-vue2/src/api/infra/demo/index.js"
}, { }, {
"contentPath" : "vue/StudentForm", "contentPath" : "vue/StudentForm",
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/StudentForm.vue" "filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/StudentForm.vue"

Some files were not shown because too many files have changed in this diff Show More