diff --git a/sql/mysql/optinal/Ureport.sql b/sql/mysql/optinal/Ureport.sql
new file mode 100644
index 000000000..8d343960d
--- /dev/null
+++ b/sql/mysql/optinal/Ureport.sql
@@ -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, ' | | | | | | | | | | | | |
|
', NULL, NULL, '2023-11-25 22:40:58', NULL, '2023-11-25 23:00:42', b'0', 0);
diff --git a/sql/mysql/optinal/crm_data.sql b/sql/mysql/optinal/crm_data.sql
index b5be1e691..e69de29bb 100644
--- a/sql/mysql/optinal/crm_data.sql
+++ b/sql/mysql/optinal/crm_data.sql
@@ -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');
diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql
index 50ae2fbd3..f96d5e10b 100644
--- a/sql/mysql/ruoyi-vue-pro.sql
+++ b/sql/mysql/ruoyi-vue-pro.sql
@@ -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;
-- ----------------------------
diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml
index b657e5515..776f2d063 100644
--- a/yudao-dependencies/pom.xml
+++ b/yudao-dependencies/pom.xml
@@ -68,6 +68,7 @@
0.1.55
2.9.1
2.7.0
+ 3.0.6
0.10.2
3.5.0
@@ -119,6 +120,17 @@
yudao-spring-boot-starter-biz-operatelog
${revision}
+
+ io.github.mouzt
+ bizlog-sdk
+ ${bizlog-sdk.version}
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
cn.iocoder.cloud
yudao-spring-boot-starter-biz-dict
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/TerminalEnum.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/TerminalEnum.java
index 632675203..f256712b3 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/TerminalEnum.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/TerminalEnum.java
@@ -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 网页"),
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/GlobalErrorCodeConstants.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/GlobalErrorCodeConstants.java
index 962a94663..edf31f24a 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/GlobalErrorCodeConstants.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/GlobalErrorCodeConstants.java
@@ -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, "重复请求,请稍后重试"); // 重复请求
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/ServiceErrorCodeRange.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/ServiceErrorCodeRange.java
index be22815eb..94dd67c9e 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/ServiceErrorCodeRange.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/ServiceErrorCodeRange.java
@@ -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)
+
}
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/SortablePageParam.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/SortablePageParam.java
new file mode 100644
index 000000000..2365c41c4
--- /dev/null
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/SortablePageParam.java
@@ -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 sortingFields;
+
+}
\ No newline at end of file
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java
index c7e50a487..53b5574f9 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java
@@ -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));
+ }
+
}
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
index 2674a110e..0ee75a1dc 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
@@ -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);
+ }
+
}
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/BeanUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/BeanUtils.java
index e14572a7f..d85fa4944 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/BeanUtils.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/BeanUtils.java
@@ -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 toBean(Object source, Class targetClass, Consumer peek) {
+ T target = toBean(source, targetClass);
+ if (target != null) {
+ peek.accept(target);
+ }
+ return target;
+ }
+
public static List toBean(List source, Class targetType) {
if (source == null) {
return null;
@@ -27,11 +36,27 @@ public class BeanUtils {
return CollectionUtils.convertList(source, s -> toBean(s, targetType));
}
- public static PageResult toBean(PageResult source, Class targetType) {
+ public static List toBean(List source, Class targetType, Consumer peek) {
+ List list = toBean(source, targetType);
+ if (list != null) {
+ list.forEach(peek);
+ }
+ return list;
+ }
+
+ public static PageResult toBean(PageResult source, Class targetType) {
+ return toBean(source, targetType, null);
+ }
+
+ public static PageResult toBean(PageResult source, Class targetType, Consumer peek) {
if (source == null) {
return null;
}
- return new PageResult<>(toBean(source.getList(), targetType), source.getTotal());
+ List list = toBean(source.getList(), targetType);
+ if (peek != null) {
+ list.forEach(peek);
+ }
+ return new PageResult<>(list, source.getTotal());
}
}
\ No newline at end of file
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/PageUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/PageUtils.java
index 72403a9bd..4e3015204 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/PageUtils.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/PageUtils.java
@@ -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 排序字段所属的类型
+ * @return 排序字段
+ */
+ public static SortingField buildSortingField(Func1 func) {
+ return buildSortingField(func, SortingField.ORDER_DESC);
+ }
+
+ /**
+ * 构建排序字段
+ *
+ * @param func 排序字段的 Lambda 表达式
+ * @param order 排序类型 {@link SortingField#ORDER_ASC} {@link SortingField#ORDER_DESC}
+ * @param 排序字段所属的类型
+ * @return 排序字段
+ */
+ public static SortingField buildSortingField(Func1 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 排序字段所属的类型
+ */
+ public static void buildDefaultSortingField(SortablePageParam sortablePageParam, Func1 func) {
+ if (sortablePageParam != null && CollUtil.isEmpty(sortablePageParam.getSortingFields())) {
+ sortablePageParam.setSortingFields(singletonList(buildSortingField(func)));
+ }
+ }
+
}
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java
index 022e70ee3..bc592d890 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java
@@ -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);
}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java
index 98f64d11a..cbeedee4d 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java
@@ -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;
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/resources/area.csv b/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/resources/area.csv
index 27e753c90..c9a3a0e74 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/resources/area.csv
+++ b/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/resources/area.csv
@@ -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
\ No newline at end of file
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLogFrameworkServiceImpl.java b/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLogFrameworkServiceImpl.java
index e31ff2e33..495193f7c 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLogFrameworkServiceImpl.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLogFrameworkServiceImpl.java
@@ -9,7 +9,7 @@ import org.springframework.scheduling.annotation.Async;
/**
* 操作日志 Framework Service 实现类
*
- * 基于 {@link OperateLogApi} 远程服务,记录操作日志
+ * 基于 {@link OperateLogApi} 实现,记录操作日志
*
* @author 芋道源码
*/
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java
index 93a17b376..e78a8b859 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java
@@ -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 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 异常
*
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java
index b35b11736..784856fc1 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java
@@ -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. 校验租户是合法,例如说被禁用、到期
diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
index 0d970c9d6..d6bbe922b 100644
--- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
+++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
@@ -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 extends MPJBaseMapper {
+ default PageResult selectPage(SortablePageParam pageParam, @Param("ew") Wrapper queryWrapper) {
+ return selectPage(pageParam, pageParam.getSortingFields(), queryWrapper);
+ }
+
default PageResult selectPage(PageParam pageParam, @Param("ew") Wrapper queryWrapper) {
+ return selectPage(pageParam, null, queryWrapper);
+ }
+
+ default PageResult selectPage(PageParam pageParam, Collection sortingFields, @Param("ew") Wrapper queryWrapper) {
// 特殊:不分页,直接查询全部
if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {
List list = selectList(queryWrapper);
@@ -34,12 +45,26 @@ public interface BaseMapperX extends MPJBaseMapper {
}
// MyBatis Plus 查询
- IPage mpPage = MyBatisUtils.buildPage(pageParam);
+ IPage mpPage = MyBatisUtils.buildPage(pageParam, sortingFields);
selectPage(mpPage, queryWrapper);
// 转换返回
return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
}
+ default PageResult selectJoinPage(PageParam pageParam, Class clazz, MPJLambdaWrapper lambdaWrapper) {
+ // 特殊:不分页,直接查询全部
+ if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageNo())) {
+ List list = selectJoinList(clazz, lambdaWrapper);
+ return new PageResult<>(list, (long) list.size());
+ }
+
+ // MyBatis Plus Join 查询
+ IPage mpPage = MyBatisUtils.buildPage(pageParam);
+ mpPage = selectJoinPage(mpPage, clazz, lambdaWrapper);
+ // 转换返回
+ return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
+ }
+
default PageResult selectJoinPage(PageParam pageParam, Class resultTypeClass, MPJBaseJoin joinQueryWrapper) {
IPage mpPage = MyBatisUtils.buildPage(pageParam);
selectJoinPage(mpPage, resultTypeClass, joinQueryWrapper);
diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java
index 0b1b01b08..7bfc24d74 100644
--- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java
+++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java
@@ -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 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) {
diff --git a/yudao-framework/yudao-spring-boot-starter-security/pom.xml b/yudao-framework/yudao-spring-boot-starter-security/pom.xml
index 2e5dc7e2e..9cca4eede 100644
--- a/yudao-framework/yudao-spring-boot-starter-security/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-security/pom.xml
@@ -12,7 +12,10 @@
jar
${project.artifactId}
- 用户的认证、权限的校验
+
+ 1. security:用户的认证、权限的校验,实现「谁」可以做「什么事」
+ 2. operatelog:操作日志,实现「谁」在「什么时间」对「什么」做了「什么事」
+
https://github.com/YunaiV/ruoyi-vue-pro
@@ -63,6 +66,20 @@
com.google.guava
guava
+
+
+
+
+ io.github.mouzt
+ bizlog-sdk
+
+
+
+
+ cn.iocoder.cloud
+ yudao-module-system-api
+ ${revision}
+
diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/config/YudaoOperateLogV2Configuration.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/config/YudaoOperateLogV2Configuration.java
new file mode 100644
index 000000000..866f94f78
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/config/YudaoOperateLogV2Configuration.java
@@ -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();
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/config/YudaoOperateLogV2RpcAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/config/YudaoOperateLogV2RpcAutoConfiguration.java
new file mode 100644
index 000000000..39e01dcc7
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/config/YudaoOperateLogV2RpcAutoConfiguration.java
@@ -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 {
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/package-info.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/package-info.java
new file mode 100644
index 000000000..97ce4eaa7
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 占位,无特殊作用
+ */
+package cn.iocoder.yudao.framework.operatelog.core;
\ No newline at end of file
diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/LogRecordServiceImpl.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/LogRecordServiceImpl.java
new file mode 100644
index 000000000..5f0ba9b6d
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/LogRecordServiceImpl.java
@@ -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 queryLog(String bizNo, String type) {
+ throw new UnsupportedOperationException("使用 OperateLogApi 进行操作日志的查询");
+ }
+
+ @Override
+ public List queryLogByBizNo(String bizNo, String type, String subType) {
+ throw new UnsupportedOperationException("使用 OperateLogApi 进行操作日志的查询");
+ }
+
+}
\ No newline at end of file
diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/package-info.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/package-info.java
new file mode 100644
index 000000000..c90139b89
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * 基于 mzt-log 框架
+ * 实现操作日志功能
+ *
+ * @author HUIHUI
+ */
+package cn.iocoder.yudao.framework.operatelog;
diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/yudao-framework/yudao-spring-boot-starter-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 0e30c5ea1..939468e95 100644
--- a/yudao-framework/yudao-spring-boot-starter-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -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
\ No newline at end of file
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/codegen/CodegenTableMapper.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/codegen/CodegenTableMapper.java
index 1e4697d33..f19670061 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/codegen/CodegenTableMapper.java
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/codegen/CodegenTableMapper.java
@@ -22,7 +22,9 @@ public interface CodegenTableMapper extends BaseMapperX {
.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 selectListByDataSourceConfigId(Long dataSourceConfigId) {
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/security/config/SecurityConfiguration.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/security/config/SecurityConfiguration.java
index 21a7cc5a1..ba8cf8131 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/security/config/SecurityConfiguration.java
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/security/config/SecurityConfiguration.java
@@ -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 配置
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm
index 4c047c948..f58ce0cb2 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm
@@ -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;
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/saveReqVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/saveReqVO.vm
index 89829cc99..e6d96fbab 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/saveReqVO.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/saveReqVO.vm
@@ -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;
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/service.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/service.vm
index 4085889d9..828cabdf1 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/service.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/service.vm
@@ -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;
## 特殊:主子表专属逻辑
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm
index 6aa2fb2e9..4d7070926 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm
@@ -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;
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/test/serviceTest.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/test/serviceTest.vm
index eeac3ce66..f72945064 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/test/serviceTest.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/test/serviceTest.vm
@@ -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;
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/api/api.js.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/api/api.js.vm
index bfe2dc007..835c0192e 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/api/api.js.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/api/api.js.vm
@@ -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'
})
}
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/api.ts.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/api.ts.vm
index c4b0b4332..7c2ab277b 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/api.ts.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/api.ts.vm
@@ -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
\ No newline at end of file
+#end
+}
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_erp.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_erp.vue.vm
index ed318875e..3996a9caa 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_erp.vue.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_erp.vue.vm
@@ -114,7 +114,7 @@