parent
dbf844592a
commit
8289a22f03
|
@ -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);
|
|
@ -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');
|
|
@ -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 (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');
|
||||
--此处缺少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 (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');
|
||||
|
@ -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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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;
|
||||
|
||||
-- ----------------------------
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
<jsch.version>0.1.55</jsch.version>
|
||||
<tika-core.version>2.9.1</tika-core.version>
|
||||
<ip2region.version>2.7.0</ip2region.version>
|
||||
<bizlog-sdk.version>3.0.6</bizlog-sdk.version>
|
||||
<reflections.version>0.10.2</reflections.version>
|
||||
<!-- 三方云服务相关 -->
|
||||
<okio.version>3.5.0</okio.version>
|
||||
|
@ -119,6 +120,17 @@
|
|||
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
|
||||
<version>${revision}</version>
|
||||
</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>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-dict</artifactId>
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.util.Arrays;
|
|||
@Getter
|
||||
public enum TerminalEnum implements IntArrayValuable {
|
||||
|
||||
UNKNOWN(0, "未知"), // 目的:在无法解析到 terminal 时,使用它
|
||||
WECHAT_MINI_PROGRAM(10, "微信小程序"),
|
||||
WECHAT_WAP(11, "微信公众号"),
|
||||
H5(20, "H5 网页"),
|
||||
|
|
|
@ -30,6 +30,7 @@ public interface GlobalErrorCodeConstants {
|
|||
|
||||
ErrorCode INTERNAL_SERVER_ERROR = new ErrorCode(500, "系统异常");
|
||||
ErrorCode NOT_IMPLEMENTED = new ErrorCode(501, "功能未实现/未开启");
|
||||
ErrorCode ERROR_CONFIGURATION = new ErrorCode(502, "错误的配置项");
|
||||
|
||||
// ========== 自定义错误段 ==========
|
||||
ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求
|
||||
|
|
|
@ -35,9 +35,12 @@ public class ServiceErrorCodeRange {
|
|||
// 模块 member 错误码区间 [1-004-000-000 ~ 1-005-000-000)
|
||||
// 模块 mp 错误码区间 [1-006-000-000 ~ 1-007-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)
|
||||
|
||||
// 模块 product 错误码区间 [1-008-000-000 ~ 1-009-000-000)
|
||||
// 模块 trade 错误码区间 [1-011-000-000 ~ 1-012-000-000)
|
||||
// 模块 promotion 错误码区间 [1-013-000-000 ~ 1-014-000-000)
|
||||
|
||||
// 模块 crm 错误码区间 [1-020-000-000 ~ 1-021-000-000)
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -177,4 +177,14 @@ public class DateUtils {
|
|||
return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now());
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否昨天
|
||||
*
|
||||
* @param date 日期
|
||||
* @return 是否
|
||||
*/
|
||||
public static boolean isYesterday(LocalDateTime date) {
|
||||
return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now().minusDays(1));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,10 +6,11 @@ import java.time.Duration;
|
|||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
|
||||
/**
|
||||
* 时间工具类,用于 {@link java.time.LocalDateTime}
|
||||
* 时间工具类,用于 {@link LocalDateTime}
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
|
@ -121,4 +122,14 @@ public class LocalDateTimeUtils {
|
|||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,11 +5,12 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Bean 工具类
|
||||
*
|
||||
* 1. 默认使用 {@link cn.hutool.core.bean.BeanUtil} 作为实现类,虽然不同 bean 工具的性能有差别,但是对绝大多数同学的项目,不用在意这点性能
|
||||
* 1. 默认使用 {@link BeanUtil} 作为实现类,虽然不同 bean 工具的性能有差别,但是对绝大多数同学的项目,不用在意这点性能
|
||||
* 2. 针对复杂的对象转换,可以搜参考 AuthConvert 实现,通过 mapstruct + default 配合实现
|
||||
*
|
||||
* @author 芋道源码
|
||||
|
@ -20,6 +21,14 @@ public class BeanUtils {
|
|||
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) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
|
@ -27,11 +36,27 @@ public class BeanUtils {
|
|||
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) {
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +1,67 @@
|
|||
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.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 芋道源码
|
||||
*/
|
||||
public class PageUtils {
|
||||
|
||||
private static final Object[] ORDER_TYPES = new String[]{SortingField.ORDER_ASC, SortingField.ORDER_DESC};
|
||||
|
||||
public static int getStart(PageParam pageParam) {
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,16 +3,15 @@ package cn.iocoder.yudao.framework.common.util.servlet;
|
|||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.JakartaServletUtil;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
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.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
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.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
|
@ -89,8 +88,6 @@ public class ServletUtils {
|
|||
return JakartaServletUtil.getClientIP(request);
|
||||
}
|
||||
|
||||
// TODO @疯狂:terminal 还是从 ServletUtils 里拿,更容易全局治理;
|
||||
|
||||
public static boolean isJsonRequest(ServletRequest request) {
|
||||
return StrUtil.startWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
|
|
@ -496,7 +496,8 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
|
|||
Expression allExpression = null;
|
||||
for (DataPermissionRule rule : ContextHolder.getRules()) {
|
||||
// 判断表名是否匹配
|
||||
if (!rule.getTableNames().contains(table.getName())) {
|
||||
String tableName = MyBatisUtils.getTableName(table);
|
||||
if (!rule.getTableNames().contains(tableName)) {
|
||||
continue;
|
||||
}
|
||||
// 如果有匹配的规则,说明可重写。
|
||||
|
@ -505,7 +506,6 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
|
|||
ContextHolder.setRewrite(true);
|
||||
|
||||
// 单条规则的条件
|
||||
String tableName = MyBatisUtils.getTableName(table);
|
||||
Expression oneExpress = rule.getExpression(tableName, table.getAlias());
|
||||
if (oneExpress == null){
|
||||
continue;
|
||||
|
|
|
@ -490,6 +490,37 @@ id,name,type,parentId
|
|||
441700,阳江市,3,440000
|
||||
441800,清远市,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
|
||||
445100,潮州市,3,440000
|
||||
445200,揭阳市,3,440000
|
||||
|
@ -3605,4 +3636,4 @@ id,name,type,parentId
|
|||
659008,可克达拉市,4,659000
|
||||
659009,昆玉市,4,659000
|
||||
659010,胡杨河市,4,659000
|
||||
659011,新星市,4,659000
|
||||
659011,新星市,4,659000
|
|
|
@ -9,7 +9,7 @@ import org.springframework.scheduling.annotation.Async;
|
|||
/**
|
||||
* 操作日志 Framework Service 实现类
|
||||
*
|
||||
* 基于 {@link OperateLogApi} 远程服务,记录操作日志
|
||||
* 基于 {@link OperateLogApi} 实现,记录操作日志
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package cn.iocoder.yudao.framework.tenant.core.context;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.DocumentEnum;
|
||||
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||
|
||||
|
@ -21,7 +22,7 @@ public class TenantContextHolder {
|
|||
private static final ThreadLocal<Boolean> IGNORE = new TransmittableThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 获得租户编号。
|
||||
* 获得租户编号
|
||||
*
|
||||
* @return 租户编号
|
||||
*/
|
||||
|
@ -29,6 +30,16 @@ public class TenantContextHolder {
|
|||
return TENANT_ID.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得租户编号 String
|
||||
*
|
||||
* @return 租户编号
|
||||
*/
|
||||
public static String getTenantIdStr() {
|
||||
Long tenantId = getTenantId();
|
||||
return StrUtil.toStringOrNull(tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得租户编号。如果不存在,则抛出 NullPointerException 异常
|
||||
*
|
||||
|
|
|
@ -92,7 +92,7 @@ public class TenantSecurityWebFilter extends ApiRequestFilter {
|
|||
if (tenantId == null) {
|
||||
log.error("[doFilterInternal][URL({}/{}) 未传递租户编号]", request.getRequestURI(), request.getMethod());
|
||||
ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),
|
||||
"租户的请求未传递,请进行排查"));
|
||||
"请求的租户标识未传递,请进行排查"));
|
||||
return;
|
||||
}
|
||||
// 3. 校验租户是合法,例如说被禁用、到期
|
||||
|
|
|
@ -3,6 +3,8 @@ package cn.iocoder.yudao.framework.mybatis.core.mapper;
|
|||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
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 com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
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.github.yulichang.base.MPJBaseMapper;
|
||||
import com.github.yulichang.interfaces.MPJBaseJoin;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Collection;
|
||||
|
@ -26,7 +29,15 @@ import java.util.List;
|
|||
*/
|
||||
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) {
|
||||
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())) {
|
||||
List<T> list = selectList(queryWrapper);
|
||||
|
@ -34,12 +45,26 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
|
|||
}
|
||||
|
||||
// MyBatis Plus 查询
|
||||
IPage<T> mpPage = MyBatisUtils.buildPage(pageParam);
|
||||
IPage<T> mpPage = MyBatisUtils.buildPage(pageParam, sortingFields);
|
||||
selectPage(mpPage, queryWrapper);
|
||||
// 转换返回
|
||||
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) {
|
||||
IPage<DTO> mpPage = MyBatisUtils.buildPage(pageParam);
|
||||
selectJoinPage(mpPage, resultTypeClass, joinQueryWrapper);
|
||||
|
|
|
@ -34,7 +34,7 @@ public class MyBatisUtils {
|
|||
// 排序字段
|
||||
if (!CollectionUtil.isEmpty(sortingFields)) {
|
||||
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()));
|
||||
}
|
||||
return page;
|
||||
|
@ -45,8 +45,8 @@ public class MyBatisUtils {
|
|||
* 由于 MybatisPlusInterceptor 不支持添加拦截器,所以只能全量设置
|
||||
*
|
||||
* @param interceptor 链
|
||||
* @param inner 拦截器
|
||||
* @param index 位置
|
||||
* @param inner 拦截器
|
||||
* @param index 位置
|
||||
*/
|
||||
public static void addInterceptor(MybatisPlusInterceptor interceptor, InnerInterceptor inner, int index) {
|
||||
List<InnerInterceptor> inners = new ArrayList<>(interceptor.getInterceptors());
|
||||
|
@ -73,9 +73,9 @@ public class MyBatisUtils {
|
|||
/**
|
||||
* 构建 Column 对象
|
||||
*
|
||||
* @param tableName 表名
|
||||
* @param tableName 表名
|
||||
* @param tableAlias 别名
|
||||
* @param column 字段名
|
||||
* @param column 字段名
|
||||
* @return Column 对象
|
||||
*/
|
||||
public static Column buildColumn(String tableName, Alias tableAlias, String column) {
|
||||
|
|
|
@ -12,7 +12,10 @@
|
|||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>用户的认证、权限的校验</description>
|
||||
<description>
|
||||
1. security:用户的认证、权限的校验,实现「谁」可以做「什么事」
|
||||
2. operatelog:操作日志,实现「谁」在「什么时间」对「什么」做了「什么事」
|
||||
</description>
|
||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||
|
||||
<dependencies>
|
||||
|
@ -63,6 +66,20 @@
|
|||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</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>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* 占位,无特殊作用
|
||||
*/
|
||||
package cn.iocoder.yudao.framework.operatelog.core;
|
|
@ -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 进行操作日志的查询");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/**
|
||||
* 基于 mzt-log 框架
|
||||
* 实现操作日志功能
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
package cn.iocoder.yudao.framework.operatelog;
|
|
@ -1,3 +1,5 @@
|
|||
cn.iocoder.yudao.framework.security.config.YudaoSecurityRpcAutoConfiguration
|
||||
cn.iocoder.yudao.framework.security.config.YudaoSecurityAutoConfiguration
|
||||
cn.iocoder.yudao.framework.security.config.YudaoWebSecurityConfigurerAdapter
|
||||
cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogV2Configuration
|
||||
cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogV2RpcAutoConfiguration
|
|
@ -22,7 +22,9 @@ public interface CodegenTableMapper extends BaseMapperX<CodegenTableDO> {
|
|||
.likeIfPresent(CodegenTableDO::getTableName, pageReqVO.getTableName())
|
||||
.likeIfPresent(CodegenTableDO::getTableComment, pageReqVO.getTableComment())
|
||||
.likeIfPresent(CodegenTableDO::getClassName, pageReqVO.getClassName())
|
||||
.betweenIfPresent(CodegenTableDO::getCreateTime, pageReqVO.getCreateTime()));
|
||||
.betweenIfPresent(CodegenTableDO::getCreateTime, pageReqVO.getCreateTime())
|
||||
.orderByDesc(CodegenTableDO::getUpdateTime)
|
||||
);
|
||||
}
|
||||
|
||||
default List<CodegenTableDO> selectListByDataSourceConfigId(Long dataSourceConfigId) {
|
||||
|
|
|
@ -7,7 +7,6 @@ import org.springframework.context.annotation.Bean;
|
|||
import org.springframework.context.annotation.Configuration;
|
||||
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.ExpressionUrlAuthorizationConfigurer;
|
||||
|
||||
/**
|
||||
* Infra 模块的 Security 配置
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName};
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import javax.annotation.Resource;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
#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.Operation;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
import javax.validation.*;
|
||||
import javax.servlet.http.*;
|
||||
import jakarta.validation.constraints.*;
|
||||
import jakarta.validation.*;
|
||||
import jakarta.servlet.http.*;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
|
|
|
@ -3,9 +3,8 @@ package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePac
|
|||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import javax.validation.constraints.*;
|
||||
import jakarta.validation.constraints.*;
|
||||
## 处理 BigDecimal 字段的引入
|
||||
import java.util.*;
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package ${basePackage}.module.${table.moduleName}.service.${table.businessName};
|
||||
|
||||
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}.dal.dataobject.${table.businessName}.${table.className}DO;
|
||||
## 特殊:主子表专属逻辑
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package ${basePackage}.module.${table.moduleName}.service.${table.businessName};
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import javax.annotation.Resource;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import org.junit.jupiter.api.Disabled;
|
|||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
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 ${PageResultClassName};
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
|
|
@ -63,7 +63,7 @@ export function export${simpleClassName}Excel(params) {
|
|||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
## 特殊:主子表专属逻辑 TODO @puhui999:下面方法的【空格】不太对
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
|
@ -76,8 +76,7 @@ export function export${simpleClassName}Excel(params) {
|
|||
|
||||
// ==================== 子表($subTable.classComment) ====================
|
||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ( $table.templateType == 11 )
|
||||
|
||||
#if ($table.templateType == 11)
|
||||
// 获得${subTable.classComment}分页
|
||||
export function get${subSimpleClassName}Page(params) {
|
||||
return request({
|
||||
|
@ -88,58 +87,53 @@ export function export${simpleClassName}Excel(params) {
|
|||
}
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
|
||||
#if ($subTable.subJoinMany)
|
||||
// 获得${subTable.classComment}列表
|
||||
export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}) {
|
||||
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'
|
||||
})
|
||||
}
|
||||
#else
|
||||
|
||||
// 获得${subTable.classComment}
|
||||
export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}) {
|
||||
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'
|
||||
})
|
||||
}
|
||||
#end
|
||||
#end
|
||||
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||
#if ( $table.templateType == 11 )
|
||||
#if ($table.templateType == 11)
|
||||
// 新增${subTable.classComment}
|
||||
export function create${subSimpleClassName}(data) {
|
||||
return request({
|
||||
url: `${baseURL}/${subSimpleClassName_strikeCase}/create`,
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改${subTable.classComment}
|
||||
export function update${subSimpleClassName}(data) {
|
||||
return request({
|
||||
url: `${baseURL}/${subSimpleClassName_strikeCase}/update`,
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除${subTable.classComment}
|
||||
export function delete${subSimpleClassName}(id) {
|
||||
return request({
|
||||
url: `${baseURL}/${subSimpleClassName_strikeCase}/delete?id=` + id,
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/delete?id=' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得${subTable.classComment}
|
||||
export function get${subSimpleClassName}(id) {
|
||||
return request({
|
||||
url: `${baseURL}/${subSimpleClassName_strikeCase}/get?id=` + id,
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/get?id=' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import request from '@/config/axios'
|
||||
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||
|
||||
// ${table.classComment} VO
|
||||
export interface ${simpleClassName}VO {
|
||||
#foreach ($column in $columns)
|
||||
#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")
|
||||
${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
|
||||
#else
|
||||
${column.javaField}: ${column.javaType.toLowerCase()}
|
||||
|
@ -15,42 +17,44 @@ export interface ${simpleClassName}VO {
|
|||
#end
|
||||
}
|
||||
|
||||
// ${table.classComment} API
|
||||
export const ${simpleClassName}Api = {
|
||||
#if ( $table.templateType != 2 )
|
||||
// 查询${table.classComment}分页
|
||||
export const get${simpleClassName}Page = async (params) => {
|
||||
return await request.get({ url: `${baseURL}/page`, params })
|
||||
}
|
||||
// 查询${table.classComment}分页
|
||||
get${simpleClassName}Page: async (params: any) => {
|
||||
return await request.get({ url: `${baseURL}/page`, params })
|
||||
},
|
||||
#else
|
||||
// 查询${table.classComment}列表
|
||||
export const get${simpleClassName}List = async (params) => {
|
||||
return await request.get({ url: `${baseURL}/list`, params })
|
||||
}
|
||||
// 查询${table.classComment}列表
|
||||
get${simpleClassName}List: async (params) => {
|
||||
return await request.get({ url: `${baseURL}/list`, params })
|
||||
},
|
||||
#end
|
||||
|
||||
// 查询${table.classComment}详情
|
||||
export const get${simpleClassName} = async (id: number) => {
|
||||
return await request.get({ url: `${baseURL}/get?id=` + id })
|
||||
}
|
||||
// 查询${table.classComment}详情
|
||||
get${simpleClassName}: async (id: number) => {
|
||||
return await request.get({ url: `${baseURL}/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增${table.classComment}
|
||||
export const create${simpleClassName} = async (data: ${simpleClassName}VO) => {
|
||||
return await request.post({ url: `${baseURL}/create`, data })
|
||||
}
|
||||
// 新增${table.classComment}
|
||||
create${simpleClassName}: async (data: ${simpleClassName}VO) => {
|
||||
return await request.post({ url: `${baseURL}/create`, data })
|
||||
},
|
||||
|
||||
// 修改${table.classComment}
|
||||
export const update${simpleClassName} = async (data: ${simpleClassName}VO) => {
|
||||
return await request.put({ url: `${baseURL}/update`, data })
|
||||
}
|
||||
// 修改${table.classComment}
|
||||
update${simpleClassName}: async (data: ${simpleClassName}VO) => {
|
||||
return await request.put({ url: `${baseURL}/update`, data })
|
||||
},
|
||||
|
||||
// 删除${table.classComment}
|
||||
export const delete${simpleClassName} = async (id: number) => {
|
||||
return await request.delete({ url: `${baseURL}/delete?id=` + id })
|
||||
}
|
||||
// 删除${table.classComment}
|
||||
delete${simpleClassName}: async (id: number) => {
|
||||
return await request.delete({ url: `${baseURL}/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出${table.classComment} Excel
|
||||
export const export${simpleClassName} = async (params) => {
|
||||
return await request.download({ url: `${baseURL}/export-excel`, params })
|
||||
}
|
||||
// 导出${table.classComment} Excel
|
||||
export${simpleClassName}: async (params) => {
|
||||
return await request.download({ url: `${baseURL}/export-excel`, params })
|
||||
},
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
|
@ -66,46 +70,47 @@ export const export${simpleClassName} = async (params) => {
|
|||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ( $table.templateType == 11 )
|
||||
|
||||
// 获得${subTable.classComment}分页
|
||||
export const get${subSimpleClassName}Page = async (params) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/page`, params })
|
||||
}
|
||||
// 获得${subTable.classComment}分页
|
||||
get${subSimpleClassName}Page: async (params) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/page`, params })
|
||||
},
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
|
||||
// 获得${subTable.classComment}列表
|
||||
export const get${subSimpleClassName}ListBy${SubJoinColumnName} = async (${subJoinColumn.javaField}) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField} })
|
||||
}
|
||||
// 获得${subTable.classComment}列表
|
||||
get${subSimpleClassName}ListBy${SubJoinColumnName}: async (${subJoinColumn.javaField}) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField} })
|
||||
},
|
||||
#else
|
||||
|
||||
// 获得${subTable.classComment}
|
||||
export const get${subSimpleClassName}By${SubJoinColumnName} = async (${subJoinColumn.javaField}) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField} })
|
||||
}
|
||||
// 获得${subTable.classComment}
|
||||
get${subSimpleClassName}By${SubJoinColumnName}: async (${subJoinColumn.javaField}) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField} })
|
||||
},
|
||||
#end
|
||||
#end
|
||||
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||
#if ( $table.templateType == 11 )
|
||||
// 新增${subTable.classComment}
|
||||
export const create${subSimpleClassName} = async (data) => {
|
||||
return await request.post({ url: `${baseURL}/${subSimpleClassName_strikeCase}/create`, data })
|
||||
}
|
||||
// 新增${subTable.classComment}
|
||||
create${subSimpleClassName}: async (data) => {
|
||||
return await request.post({ url: `${baseURL}/${subSimpleClassName_strikeCase}/create`, data })
|
||||
},
|
||||
|
||||
// 修改${subTable.classComment}
|
||||
export const update${subSimpleClassName} = async (data) => {
|
||||
return await request.put({ url: `${baseURL}/${subSimpleClassName_strikeCase}/update`, data })
|
||||
}
|
||||
// 修改${subTable.classComment}
|
||||
update${subSimpleClassName}: async (data) => {
|
||||
return await request.put({ url: `${baseURL}/${subSimpleClassName_strikeCase}/update`, data })
|
||||
},
|
||||
|
||||
// 删除${subTable.classComment}
|
||||
export const delete${subSimpleClassName} = async (id: number) => {
|
||||
return await request.delete({ url: `${baseURL}/${subSimpleClassName_strikeCase}/delete?id=` + id })
|
||||
}
|
||||
// 删除${subTable.classComment}
|
||||
delete${subSimpleClassName}: async (id: number) => {
|
||||
return await request.delete({ url: `${baseURL}/${subSimpleClassName_strikeCase}/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 获得${subTable.classComment}
|
||||
export const get${subSimpleClassName} = async (id: number) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get?id=` + id })
|
||||
}
|
||||
// 获得${subTable.classComment}
|
||||
get${subSimpleClassName}: async (id: number) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get?id=` + id })
|
||||
},
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
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 message = useMessage() // 消息弹窗
|
||||
|
|
|
@ -265,7 +265,7 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
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<{
|
||||
${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段)
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
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)
|
||||
import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue'
|
||||
#end
|
||||
|
|
|
@ -140,7 +140,7 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
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 )
|
||||
import { defaultProps, handleTree } from '@/utils/tree'
|
||||
|
@ -152,6 +152,9 @@ import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vu
|
|||
#end
|
||||
#end
|
||||
|
||||
/** ${table.classComment} 表单 */
|
||||
defineOptions({ name: '${simpleClassName}Form' })
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
|
|
|
@ -240,7 +240,7 @@ import { dateFormatter } from '@/utils/formatTime'
|
|||
import { handleTree } from '@/utils/tree'
|
||||
#end
|
||||
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'
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType != 10 )
|
||||
|
@ -249,16 +249,18 @@ import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vu
|
|||
#end
|
||||
#end
|
||||
|
||||
/** ${table.classComment} 列表 */
|
||||
defineOptions({ name: '${table.className}' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref([]) // 列表的数据
|
||||
const list = ref<${simpleClassName}VO[]>([]) // 列表的数据
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
const total = ref(0) // 列表的总页数
|
||||
// 列表的总页数
|
||||
const total = ref(0)
|
||||
#end
|
||||
const queryParams = reactive({
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
|
|
|
@ -31,6 +31,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||
*/
|
||||
public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
|
||||
|
||||
/**
|
||||
* 测试文件资源目录
|
||||
*/
|
||||
private String resourcesPath = "";
|
||||
|
||||
@InjectMocks
|
||||
protected CodegenEngine codegenEngine;
|
||||
|
||||
|
@ -41,6 +46,10 @@ public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
|
|||
@BeforeEach
|
||||
public void setUp() {
|
||||
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) {
|
||||
|
@ -73,14 +82,14 @@ public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
|
|||
|
||||
@SuppressWarnings("rawtypes")
|
||||
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);
|
||||
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);
|
||||
String content = ResourceUtil.readUtf8Str("codegen/" + path + "/" + contentPath);
|
||||
assertEquals(content, result.get(filePath), filePath + ":不匹配");
|
||||
});
|
||||
}
|
||||
|
@ -91,7 +100,7 @@ public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
|
|||
* 【调试使用】将生成的代码,写入到文件
|
||||
*
|
||||
* @param result 生成的代码
|
||||
* @param path 写入文件的路径
|
||||
* @param 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 写入文件的路径(绝对路径)
|
||||
*/
|
||||
protected void writeResult(Map<String, String> result, String basePath) {
|
||||
|
@ -121,7 +130,7 @@ public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
|
|||
FileUtil.writeUtf8String(fileContent, basePath + "/" + contentPath);
|
||||
});
|
||||
// 写入 assert.json 文件
|
||||
FileUtil.writeUtf8String(JsonUtils.toJsonPrettyString(asserts), basePath +"/assert.json");
|
||||
FileUtil.writeUtf8String(JsonUtils.toJsonPrettyString(asserts), basePath + "/assert.json");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
|
@ -11,7 +11,6 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
// TODO @puhui999:单测需要 fix
|
||||
/**
|
||||
* {@link CodegenEngine} 的 Vue2 + Element UI 单元测试
|
||||
*
|
||||
|
@ -30,9 +29,10 @@ public class CodegenEngineVue2Test extends CodegenEngineAbstractTest {
|
|||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||
// 生成测试文件
|
||||
//writeResult(result, resourcesPath + "/vue2_one");
|
||||
// 断言
|
||||
assertResult(result, "codegen/vue2_one");
|
||||
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue2_one");
|
||||
assertResult(result, "/vue2_one");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -45,25 +45,26 @@ public class CodegenEngineVue2Test extends CodegenEngineAbstractTest {
|
|||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||
// 生成测试文件
|
||||
//writeResult(result, resourcesPath + "/vue2_tree");
|
||||
// 断言
|
||||
assertResult(result, "codegen/vue2_tree");
|
||||
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue2_tree");
|
||||
assertResult(result, "/vue2_tree");
|
||||
// writeFile(result, "/Users/yunai/test/demo66.zip");
|
||||
}
|
||||
|
||||
@Test
|
||||
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
|
||||
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
|
||||
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,
|
||||
|
@ -89,9 +90,10 @@ public class CodegenEngineVue2Test extends CodegenEngineAbstractTest {
|
|||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns,
|
||||
Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns));
|
||||
// 生成测试文件
|
||||
//writeResult(result, resourcesPath + 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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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.enums.codegen.CodegenFrontTypeEnum;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -15,6 +16,7 @@ import java.util.Map;
|
|||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Disabled
|
||||
public class CodegenEngineVue3Test extends CodegenEngineAbstractTest {
|
||||
|
||||
@Test
|
||||
|
@ -27,9 +29,10 @@ public class CodegenEngineVue3Test extends CodegenEngineAbstractTest {
|
|||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||
// 生成测试文件
|
||||
//writeResult(result, resourcesPath + "/vue3_one");
|
||||
// 断言
|
||||
assertResult(result, "codegen/vue3_one");
|
||||
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_one");
|
||||
assertResult(result, "/vue3_one");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -42,25 +45,26 @@ public class CodegenEngineVue3Test extends CodegenEngineAbstractTest {
|
|||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||
// 生成测试文件
|
||||
//writeResult(result, resourcesPath + "/vue3_tree");
|
||||
// 断言
|
||||
assertResult(result, "codegen/vue3_tree");
|
||||
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_tree");
|
||||
assertResult(result, "/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");
|
||||
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_NORMAL, "/vue3_master_normal");
|
||||
}
|
||||
|
||||
@Test
|
||||
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
|
||||
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,
|
||||
|
@ -86,10 +90,11 @@ public class CodegenEngineVue3Test extends CodegenEngineAbstractTest {
|
|||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns,
|
||||
Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns));
|
||||
// 生成测试文件
|
||||
//writeResult(result, resourcesPath + 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");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,13 +51,13 @@ public class ApiErrorLogServiceImplTest extends BaseDbUnitTest {
|
|||
// 测试 userId 不匹配
|
||||
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, o -> o.setUserId(3344L)));
|
||||
// 测试 userType 不匹配
|
||||
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||
// 测试 applicationName 不匹配
|
||||
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setApplicationName("test")));
|
||||
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, o -> o.setApplicationName("test")));
|
||||
// 测试 requestUrl 不匹配
|
||||
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setRequestUrl("bar")));
|
||||
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, o -> o.setRequestUrl("bar")));
|
||||
// 测试 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 不匹配
|
||||
apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setProcessStatus(ApiErrorLogProcessStatusEnum.DONE.getStatus())));
|
||||
// 准备参数
|
||||
|
|
|
@ -53,8 +53,8 @@
|
|||
"contentPath" : "vue/index",
|
||||
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/index.vue"
|
||||
}, {
|
||||
"contentPath" : "js/student",
|
||||
"filePath" : "yudao-ui-admin-vue2/src/api/infra/student.js"
|
||||
"contentPath": "js/index",
|
||||
"filePath": "yudao-ui-admin-vue2/src/api/infra/demo/index.js"
|
||||
}, {
|
||||
"contentPath" : "vue/StudentForm",
|
||||
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/StudentForm.vue"
|
|
@ -53,8 +53,8 @@
|
|||
"contentPath" : "vue/index",
|
||||
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/index.vue"
|
||||
}, {
|
||||
"contentPath" : "js/student",
|
||||
"filePath" : "yudao-ui-admin-vue2/src/api/infra/student.js"
|
||||
"contentPath": "js/index",
|
||||
"filePath": "yudao-ui-admin-vue2/src/api/infra/demo/index.js"
|
||||
}, {
|
||||
"contentPath" : "vue/StudentForm",
|
||||
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/StudentForm.vue"
|
|
@ -53,8 +53,8 @@
|
|||
"contentPath" : "vue/index",
|
||||
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/index.vue"
|
||||
}, {
|
||||
"contentPath" : "js/student",
|
||||
"filePath" : "yudao-ui-admin-vue2/src/api/infra/student.js"
|
||||
"contentPath": "js/index",
|
||||
"filePath": "yudao-ui-admin-vue2/src/api/infra/demo/index.js"
|
||||
}, {
|
||||
"contentPath" : "vue/StudentForm",
|
||||
"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
Loading…
Reference in New Issue