diff --git a/pom.xml b/pom.xml index 3d64ab53a9..9c7b3d2b8b 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ - + yudao-module-mp @@ -42,7 +42,7 @@ 3.14.0 1.7.2 - 1.18.38 + 1.18.42 2.7.18 1.6.3 UTF-8 diff --git a/sql/dm/ruoyi-vue-pro-dm8.sql b/sql/dm/ruoyi-vue-pro-dm8.sql index 3e0dcda2aa..f97d09de47 100644 --- a/sql/dm/ruoyi-vue-pro-dm8.sql +++ b/sql/dm/ruoyi-vue-pro-dm8.sql @@ -1063,7 +1063,7 @@ INSERT INTO system_dict_data (id, sort, label, value, dict_type, status, color_t 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 (1690, 5, '向量', '5', 'ai_model_type', 0, '', '', '', '1', '2025-03-03 12:28:15', '1', '2025-03-03 12:28:15', '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 (1691, 6, '重排', '6', 'ai_model_type', 0, '', '', '', '1', '2025-03-03 12:28:26', '1', '2025-03-03 12:28:26', '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 (1692, 14, 'MiniMax', 'MiniMax', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:04:51', '1', '2025-03-11 20:04:51', '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 (1693, 15, '月之暗灭', 'Moonshot', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:05:08', '1', '2025-03-11 20:05:08', '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 (1693, 15, '月之暗面', 'Moonshot', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:05:08', '1', '2025-03-11 20:05:08', '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 (2000, 0, '标准数据格式(JSON)', '0', 'iot_data_format', 0, 'default', '', '', '1', '2024-08-10 11:53:26', '1', '2025-03-17 09:28:16', '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 (2001, 1, '透传/自定义', '1', 'iot_data_format', 0, 'default', '', '', '1', '2024-08-10 11:53:37', '1', '2025-03-17 09:28:19', '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 (2002, 0, '直连设备', '0', 'iot_product_device_type', 0, 'default', '', '', '1', '2024-08-10 11:54:58', '1', '2025-03-17 09:28:22', '0'); diff --git a/sql/kingbase/ruoyi-vue-pro.sql b/sql/kingbase/ruoyi-vue-pro.sql index 33c41c1c54..c1f8e76666 100644 --- a/sql/kingbase/ruoyi-vue-pro.sql +++ b/sql/kingbase/ruoyi-vue-pro.sql @@ -1177,7 +1177,7 @@ INSERT INTO system_dict_data (id, sort, label, value, dict_type, status, color_t 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 (1690, 5, '向量', '5', 'ai_model_type', 0, '', '', '', '1', '2025-03-03 12:28:15', '1', '2025-03-03 12:28:15', '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 (1691, 6, '重排', '6', 'ai_model_type', 0, '', '', '', '1', '2025-03-03 12:28:26', '1', '2025-03-03 12:28:26', '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 (1692, 14, 'MiniMax', 'MiniMax', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:04:51', '1', '2025-03-11 20:04:51', '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 (1693, 15, '月之暗灭', 'Moonshot', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:05:08', '1', '2025-03-11 20:05:08', '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 (1693, 15, '月之暗面', 'Moonshot', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:05:08', '1', '2025-03-11 20:05:08', '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 (2000, 0, '标准数据格式(JSON)', '0', 'iot_data_format', 0, 'default', '', '', '1', '2024-08-10 11:53:26', '1', '2025-03-17 09:28:16', '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 (2001, 1, '透传/自定义', '1', 'iot_data_format', 0, 'default', '', '', '1', '2024-08-10 11:53:37', '1', '2025-03-17 09:28:19', '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 (2002, 0, '直连设备', '0', 'iot_product_device_type', 0, 'default', '', '', '1', '2024-08-10 11:54:58', '1', '2025-03-17 09:28:22', '0'); diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index ff2618c80d..821d7e4a1b 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -883,7 +883,7 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st 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 (1690, 5, '向量', '5', 'ai_model_type', 0, '', '', '', '1', '2025-03-03 12:28:15', '1', '2025-03-03 12:28:15', 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 (1691, 6, '重排', '6', 'ai_model_type', 0, '', '', '', '1', '2025-03-03 12:28:26', '1', '2025-03-03 12:28:26', 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 (1692, 14, 'MiniMax', 'MiniMax', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:04:51', '1', '2025-03-11 20:04:51', 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 (1693, 15, '月之暗灭', 'Moonshot', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:05:08', '1', '2025-03-11 20:05: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 (1693, 15, '月之暗面', 'Moonshot', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:05:08', '1', '2025-03-11 20:05: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 (2002, 0, '直连设备', '0', 'iot_product_device_type', 0, 'default', '', '', '1', '2024-08-10 11:54:58', '1', '2025-03-17 09:28:22', 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 (2003, 2, '网关设备', '2', 'iot_product_device_type', 0, 'default', '', '', '1', '2024-08-10 11:55:08', '1', '2025-03-17 09:28:28', 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 (2004, 1, '网关子设备', '1', 'iot_product_device_type', 0, 'default', '', '', '1', '2024-08-10 11:55:20', '1', '2025-03-17 09:28:31', b'0'); diff --git a/sql/opengauss/ruoyi-vue-pro.sql b/sql/opengauss/ruoyi-vue-pro.sql index 33849b5c68..c0408f34c5 100644 --- a/sql/opengauss/ruoyi-vue-pro.sql +++ b/sql/opengauss/ruoyi-vue-pro.sql @@ -1177,7 +1177,7 @@ INSERT INTO system_dict_data (id, sort, label, value, dict_type, status, color_t 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 (1690, 5, '向量', '5', 'ai_model_type', 0, '', '', '', '1', '2025-03-03 12:28:15', '1', '2025-03-03 12:28:15', '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 (1691, 6, '重排', '6', 'ai_model_type', 0, '', '', '', '1', '2025-03-03 12:28:26', '1', '2025-03-03 12:28:26', '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 (1692, 14, 'MiniMax', 'MiniMax', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:04:51', '1', '2025-03-11 20:04:51', '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 (1693, 15, '月之暗灭', 'Moonshot', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:05:08', '1', '2025-03-11 20:05:08', '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 (1693, 15, '月之暗面', 'Moonshot', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:05:08', '1', '2025-03-11 20:05:08', '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 (2000, 0, '标准数据格式(JSON)', '0', 'iot_data_format', 0, 'default', '', '', '1', '2024-08-10 11:53:26', '1', '2025-03-17 09:28:16', '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 (2001, 1, '透传/自定义', '1', 'iot_data_format', 0, 'default', '', '', '1', '2024-08-10 11:53:37', '1', '2025-03-17 09:28:19', '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 (2002, 0, '直连设备', '0', 'iot_product_device_type', 0, 'default', '', '', '1', '2024-08-10 11:54:58', '1', '2025-03-17 09:28:22', '0'); diff --git a/sql/oracle/ruoyi-vue-pro.sql b/sql/oracle/ruoyi-vue-pro.sql index 4c844b1460..0af291458b 100644 --- a/sql/oracle/ruoyi-vue-pro.sql +++ b/sql/oracle/ruoyi-vue-pro.sql @@ -1129,7 +1129,7 @@ INSERT INTO system_dict_data (id, sort, label, value, dict_type, status, color_t 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 (1690, 5, '向量', '5', 'ai_model_type', 0, '', '', '', '1', to_date('2025-03-03 12:28:15', 'SYYYY-MM-DD HH24:MI:SS'), '1', to_date('2025-03-03 12:28:15', 'SYYYY-MM-DD HH24:MI:SS'), '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 (1691, 6, '重排', '6', 'ai_model_type', 0, '', '', '', '1', to_date('2025-03-03 12:28:26', 'SYYYY-MM-DD HH24:MI:SS'), '1', to_date('2025-03-03 12:28:26', 'SYYYY-MM-DD HH24:MI:SS'), '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 (1692, 14, 'MiniMax', 'MiniMax', 'ai_platform', 0, '', '', '', '1', to_date('2025-03-11 20:04:51', 'SYYYY-MM-DD HH24:MI:SS'), '1', to_date('2025-03-11 20:04:51', 'SYYYY-MM-DD HH24:MI:SS'), '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 (1693, 15, '月之暗灭', 'Moonshot', 'ai_platform', 0, '', '', '', '1', to_date('2025-03-11 20:05:08', 'SYYYY-MM-DD HH24:MI:SS'), '1', to_date('2025-03-11 20:05:08', 'SYYYY-MM-DD HH24:MI:SS'), '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 (1693, 15, '月之暗面', 'Moonshot', 'ai_platform', 0, '', '', '', '1', to_date('2025-03-11 20:05:08', 'SYYYY-MM-DD HH24:MI:SS'), '1', to_date('2025-03-11 20:05:08', 'SYYYY-MM-DD HH24:MI:SS'), '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 (2000, 0, '标准数据格式(JSON)', '0', 'iot_data_format', 0, 'default', '', '', '1', to_date('2024-08-10 11:53:26', 'SYYYY-MM-DD HH24:MI:SS'), '1', to_date('2025-03-17 09:28:16', 'SYYYY-MM-DD HH24:MI:SS'), '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 (2001, 1, '透传/自定义', '1', 'iot_data_format', 0, 'default', '', '', '1', to_date('2024-08-10 11:53:37', 'SYYYY-MM-DD HH24:MI:SS'), '1', to_date('2025-03-17 09:28:19', 'SYYYY-MM-DD HH24:MI:SS'), '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 (2002, 0, '直连设备', '0', 'iot_product_device_type', 0, 'default', '', '', '1', to_date('2024-08-10 11:54:58', 'SYYYY-MM-DD HH24:MI:SS'), '1', to_date('2025-03-17 09:28:22', 'SYYYY-MM-DD HH24:MI:SS'), '0'); diff --git a/sql/postgresql/ruoyi-vue-pro.sql b/sql/postgresql/ruoyi-vue-pro.sql index f85884776e..85eafefc4e 100644 --- a/sql/postgresql/ruoyi-vue-pro.sql +++ b/sql/postgresql/ruoyi-vue-pro.sql @@ -33,7 +33,7 @@ INSERT INTO dual VALUES (1); DROP TABLE IF EXISTS infra_api_access_log; CREATE TABLE infra_api_access_log ( - id int8 NOT NULL, + id int8 NOT NULL DEFAULT NEXTVAL('infra_api_access_log_seq'), trace_id varchar(64) NOT NULL DEFAULT '', user_id int8 NOT NULL DEFAULT 0, user_type int2 NOT NULL DEFAULT 0, @@ -102,7 +102,7 @@ CREATE SEQUENCE infra_api_access_log_seq DROP TABLE IF EXISTS infra_api_error_log; CREATE TABLE infra_api_error_log ( - id int8 NOT NULL, + id int8 NOT NULL DEFAULT NEXTVAL('infra_api_error_log_seq'), trace_id varchar(64) NOT NULL, user_id int8 NOT NULL DEFAULT 0, user_type int2 NOT NULL DEFAULT 0, @@ -175,7 +175,7 @@ CREATE SEQUENCE infra_api_error_log_seq DROP TABLE IF EXISTS infra_codegen_column; CREATE TABLE infra_codegen_column ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('infra_codegen_column_seq'), table_id int8 NOT NULL, column_name varchar(200) NOT NULL, data_type varchar(100) NOT NULL, @@ -238,7 +238,7 @@ CREATE SEQUENCE infra_codegen_column_seq DROP TABLE IF EXISTS infra_codegen_table; CREATE TABLE infra_codegen_table ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('infra_codegen_table_seq'), data_source_config_id int8 NOT NULL, scene int2 NOT NULL DEFAULT 1, table_name varchar(200) NOT NULL DEFAULT '', @@ -303,7 +303,7 @@ CREATE SEQUENCE infra_codegen_table_seq DROP TABLE IF EXISTS infra_config; CREATE TABLE infra_config ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('infra_config_seq'), category varchar(50) NOT NULL, type int2 NOT NULL, name varchar(100) NOT NULL DEFAULT '', @@ -362,7 +362,7 @@ CREATE SEQUENCE infra_config_seq DROP TABLE IF EXISTS infra_data_source_config; CREATE TABLE infra_data_source_config ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('infra_data_source_config_seq'), name varchar(100) NOT NULL DEFAULT '', url varchar(1024) NOT NULL, username varchar(255) NOT NULL, @@ -399,7 +399,7 @@ CREATE SEQUENCE infra_data_source_config_seq DROP TABLE IF EXISTS infra_file; CREATE TABLE infra_file ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('infra_file_seq'), config_id int8 NULL DEFAULT NULL, name varchar(256) NULL DEFAULT NULL, path varchar(512) NOT NULL, @@ -440,7 +440,7 @@ CREATE SEQUENCE infra_file_seq DROP TABLE IF EXISTS infra_file_config; CREATE TABLE infra_file_config ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('infra_file_config_seq'), name varchar(63) NOT NULL, storage int2 NOT NULL, remark varchar(255) NULL DEFAULT NULL, @@ -496,7 +496,7 @@ CREATE SEQUENCE infra_file_config_seq DROP TABLE IF EXISTS infra_file_content; CREATE TABLE infra_file_content ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('infra_file_content_seq'), config_id int8 NOT NULL, path varchar(512) NOT NULL, content bytea NOT NULL, @@ -531,7 +531,7 @@ CREATE SEQUENCE infra_file_content_seq DROP TABLE IF EXISTS infra_job; CREATE TABLE infra_job ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('infra_job_seq'), name varchar(32) NOT NULL, status int2 NOT NULL, handler_name varchar(64) NOT NULL, @@ -597,7 +597,7 @@ CREATE SEQUENCE infra_job_seq DROP TABLE IF EXISTS infra_job_log; CREATE TABLE infra_job_log ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('infra_job_log_seq'), job_id int8 NOT NULL, handler_name varchar(64) NOT NULL, handler_param varchar(255) NULL DEFAULT NULL, @@ -644,7 +644,7 @@ CREATE SEQUENCE infra_job_log_seq DROP TABLE IF EXISTS system_dept; CREATE TABLE system_dept ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_dept_seq'), name varchar(30) NOT NULL DEFAULT '', parent_id int8 NOT NULL DEFAULT 0, sort int4 NOT NULL DEFAULT 0, @@ -711,7 +711,7 @@ CREATE SEQUENCE system_dept_seq DROP TABLE IF EXISTS system_dict_data; CREATE TABLE system_dict_data ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_dict_data_seq'), sort int4 NOT NULL DEFAULT 0, label varchar(100) NOT NULL DEFAULT '', value varchar(100) NOT NULL DEFAULT '', @@ -1177,7 +1177,7 @@ INSERT INTO system_dict_data (id, sort, label, value, dict_type, status, color_t 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 (1690, 5, '向量', '5', 'ai_model_type', 0, '', '', '', '1', '2025-03-03 12:28:15', '1', '2025-03-03 12:28:15', '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 (1691, 6, '重排', '6', 'ai_model_type', 0, '', '', '', '1', '2025-03-03 12:28:26', '1', '2025-03-03 12:28:26', '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 (1692, 14, 'MiniMax', 'MiniMax', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:04:51', '1', '2025-03-11 20:04:51', '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 (1693, 15, '月之暗灭', 'Moonshot', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:05:08', '1', '2025-03-11 20:05:08', '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 (1693, 15, '月之暗面', 'Moonshot', 'ai_platform', 0, '', '', '', '1', '2025-03-11 20:05:08', '1', '2025-03-11 20:05:08', '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 (2000, 0, '标准数据格式(JSON)', '0', 'iot_data_format', 0, 'default', '', '', '1', '2024-08-10 11:53:26', '1', '2025-03-17 09:28:16', '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 (2001, 1, '透传/自定义', '1', 'iot_data_format', 0, 'default', '', '', '1', '2024-08-10 11:53:37', '1', '2025-03-17 09:28:19', '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 (2002, 0, '直连设备', '0', 'iot_product_device_type', 0, 'default', '', '', '1', '2024-08-10 11:54:58', '1', '2025-03-17 09:28:22', '0'); @@ -1367,7 +1367,7 @@ CREATE SEQUENCE system_dict_data_seq DROP TABLE IF EXISTS system_dict_type; CREATE TABLE system_dict_type ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_dict_type_seq'), name varchar(100) NOT NULL DEFAULT '', type varchar(100) NOT NULL DEFAULT '', status int2 NOT NULL DEFAULT 0, @@ -1521,7 +1521,7 @@ CREATE SEQUENCE system_dict_type_seq DROP TABLE IF EXISTS system_login_log; CREATE TABLE system_login_log ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_login_log_seq'), log_type int8 NOT NULL, trace_id varchar(64) NOT NULL DEFAULT '', user_id int8 NOT NULL DEFAULT 0, @@ -1568,7 +1568,7 @@ CREATE SEQUENCE system_login_log_seq DROP TABLE IF EXISTS system_mail_account; CREATE TABLE system_mail_account ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_mail_account_seq'), mail varchar(255) NOT NULL, username varchar(255) NOT NULL, password varchar(255) NOT NULL, @@ -1623,7 +1623,7 @@ CREATE SEQUENCE system_mail_account_seq DROP TABLE IF EXISTS system_mail_log; CREATE TABLE system_mail_log ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_mail_log_seq'), user_id int8 NULL DEFAULT NULL, user_type int2 NULL DEFAULT NULL, to_mail varchar(255) NOT NULL, @@ -1682,7 +1682,7 @@ CREATE SEQUENCE system_mail_log_seq DROP TABLE IF EXISTS system_mail_template; CREATE TABLE system_mail_template ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_mail_template_seq'), name varchar(63) NOT NULL, code varchar(63) NOT NULL, account_id int8 NOT NULL, @@ -1740,7 +1740,7 @@ CREATE SEQUENCE system_mail_template_seq DROP TABLE IF EXISTS system_menu; CREATE TABLE system_menu ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_menu_seq'), name varchar(50) NOT NULL, permission varchar(100) NOT NULL DEFAULT '', type int2 NOT NULL, @@ -2714,7 +2714,7 @@ CREATE SEQUENCE system_menu_seq DROP TABLE IF EXISTS system_notice; CREATE TABLE system_notice ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_notice_seq'), title varchar(50) NOT NULL, content text NOT NULL, type int2 NOT NULL, @@ -2764,7 +2764,7 @@ CREATE SEQUENCE system_notice_seq DROP TABLE IF EXISTS system_notify_message; CREATE TABLE system_notify_message ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_notify_message_seq'), user_id int8 NOT NULL, user_type int2 NOT NULL, template_id int8 NOT NULL, @@ -2832,7 +2832,7 @@ CREATE SEQUENCE system_notify_message_seq DROP TABLE IF EXISTS system_notify_template; CREATE TABLE system_notify_template ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_notify_template_seq'), name varchar(63) NOT NULL, code varchar(64) NOT NULL, nickname varchar(255) NOT NULL, @@ -2877,7 +2877,7 @@ CREATE SEQUENCE system_notify_template_seq DROP TABLE IF EXISTS system_oauth2_access_token; CREATE TABLE system_oauth2_access_token ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_oauth2_access_token_seq'), user_id int8 NOT NULL, user_type int2 NOT NULL, user_info varchar(512) NOT NULL, @@ -2927,7 +2927,7 @@ CREATE SEQUENCE system_oauth2_access_token_seq DROP TABLE IF EXISTS system_oauth2_approve; CREATE TABLE system_oauth2_approve ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_oauth2_approve_seq'), user_id int8 NOT NULL, user_type int2 NOT NULL, client_id varchar(255) NOT NULL, @@ -2970,7 +2970,7 @@ CREATE SEQUENCE system_oauth2_approve_seq DROP TABLE IF EXISTS system_oauth2_client; CREATE TABLE system_oauth2_client ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_oauth2_client_seq'), client_id varchar(255) NOT NULL, secret varchar(255) NOT NULL, name varchar(255) NOT NULL, @@ -3041,7 +3041,7 @@ CREATE SEQUENCE system_oauth2_client_seq DROP TABLE IF EXISTS system_oauth2_code; CREATE TABLE system_oauth2_code ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_oauth2_code_seq'), user_id int8 NOT NULL, user_type int2 NOT NULL, code varchar(32) NOT NULL, @@ -3088,7 +3088,7 @@ CREATE SEQUENCE system_oauth2_code_seq DROP TABLE IF EXISTS system_oauth2_refresh_token; CREATE TABLE system_oauth2_refresh_token ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_oauth2_refresh_token_seq'), user_id int8 NOT NULL, refresh_token varchar(32) NOT NULL, user_type int2 NOT NULL, @@ -3131,7 +3131,7 @@ CREATE SEQUENCE system_oauth2_refresh_token_seq DROP TABLE IF EXISTS system_operate_log; CREATE TABLE system_operate_log ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_operate_log_seq'), trace_id varchar(64) NOT NULL DEFAULT '', user_id int8 NOT NULL, user_type int2 NOT NULL DEFAULT 0, @@ -3188,7 +3188,7 @@ CREATE SEQUENCE system_operate_log_seq DROP TABLE IF EXISTS system_post; CREATE TABLE system_post ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_post_seq'), code varchar(64) NOT NULL, name varchar(50) NOT NULL, sort int4 NOT NULL, @@ -3241,7 +3241,7 @@ CREATE SEQUENCE system_post_seq DROP TABLE IF EXISTS system_role; CREATE TABLE system_role ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_role_seq'), name varchar(30) NOT NULL, code varchar(100) NOT NULL, sort int4 NOT NULL, @@ -3304,7 +3304,7 @@ CREATE SEQUENCE system_role_seq DROP TABLE IF EXISTS system_role_menu; CREATE TABLE system_role_menu ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_role_menu_seq'), role_id int8 NOT NULL, menu_id int8 NOT NULL, creator varchar(64) NULL DEFAULT '', @@ -4210,7 +4210,7 @@ CREATE SEQUENCE system_role_menu_seq DROP TABLE IF EXISTS system_sms_channel; CREATE TABLE system_sms_channel ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_sms_channel_seq'), signature varchar(12) NOT NULL, code varchar(63) NOT NULL, status int2 NOT NULL, @@ -4264,7 +4264,7 @@ CREATE SEQUENCE system_sms_channel_seq DROP TABLE IF EXISTS system_sms_code; CREATE TABLE system_sms_code ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_sms_code_seq'), mobile varchar(11) NOT NULL, code varchar(6) NOT NULL, create_ip varchar(15) NOT NULL, @@ -4313,7 +4313,7 @@ CREATE SEQUENCE system_sms_code_seq DROP TABLE IF EXISTS system_sms_log; CREATE TABLE system_sms_log ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_sms_log_seq'), channel_id int8 NOT NULL, channel_code varchar(63) NOT NULL, template_id int8 NOT NULL, @@ -4384,7 +4384,7 @@ CREATE SEQUENCE system_sms_log_seq DROP TABLE IF EXISTS system_sms_template; CREATE TABLE system_sms_template ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_sms_template_seq'), type int2 NOT NULL, status int2 NOT NULL, code varchar(63) NOT NULL, @@ -4456,7 +4456,7 @@ CREATE SEQUENCE system_sms_template_seq DROP TABLE IF EXISTS system_social_client; CREATE TABLE system_social_client ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_social_client_seq'), name varchar(255) NOT NULL, social_type int2 NOT NULL, user_type int2 NOT NULL, @@ -4514,7 +4514,7 @@ CREATE SEQUENCE system_social_client_seq DROP TABLE IF EXISTS system_social_user; CREATE TABLE system_social_user ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_social_user_seq'), type int2 NOT NULL, openid varchar(32) NOT NULL, token varchar(256) NULL DEFAULT NULL, @@ -4563,7 +4563,7 @@ CREATE SEQUENCE system_social_user_seq DROP TABLE IF EXISTS system_social_user_bind; CREATE TABLE system_social_user_bind ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_social_user_bind_seq'), user_id int8 NOT NULL, user_type int2 NOT NULL, social_type int2 NOT NULL, @@ -4602,7 +4602,7 @@ CREATE SEQUENCE system_social_user_bind_seq DROP TABLE IF EXISTS system_tenant; CREATE TABLE system_tenant ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_tenant_seq'), name varchar(30) NOT NULL, contact_user_id int8 NULL DEFAULT NULL, contact_name varchar(30) NOT NULL, @@ -4660,7 +4660,7 @@ CREATE SEQUENCE system_tenant_seq DROP TABLE IF EXISTS system_tenant_package; CREATE TABLE system_tenant_package ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_tenant_package_seq'), name varchar(30) NOT NULL, status int2 NOT NULL DEFAULT 0, remark varchar(256) NULL DEFAULT '', @@ -4707,7 +4707,7 @@ CREATE SEQUENCE system_tenant_package_seq DROP TABLE IF EXISTS system_user_post; CREATE TABLE system_user_post ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_user_post_seq'), user_id int8 NOT NULL DEFAULT 0, post_id int8 NOT NULL DEFAULT 0, creator varchar(64) NULL DEFAULT '', @@ -4759,7 +4759,7 @@ CREATE SEQUENCE system_user_post_seq DROP TABLE IF EXISTS system_user_role; CREATE TABLE system_user_role ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_user_role_seq'), user_id int8 NOT NULL, role_id int8 NOT NULL, creator varchar(64) NULL DEFAULT '', @@ -4819,7 +4819,7 @@ CREATE SEQUENCE system_user_role_seq DROP TABLE IF EXISTS system_users; CREATE TABLE system_users ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('system_users_seq'), username varchar(30) NOT NULL, password varchar(100) NOT NULL DEFAULT '', nickname varchar(30) NOT NULL, @@ -4902,7 +4902,7 @@ CREATE SEQUENCE system_users_seq DROP TABLE IF EXISTS yudao_demo01_contact; CREATE TABLE yudao_demo01_contact ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('yudao_demo01_contact_seq'), name varchar(100) NOT NULL DEFAULT '', sex int2 NOT NULL, birthday timestamp NOT NULL, @@ -4952,7 +4952,7 @@ CREATE SEQUENCE yudao_demo01_contact_seq DROP TABLE IF EXISTS yudao_demo02_category; CREATE TABLE yudao_demo02_category ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('yudao_demo02_category_seq'), name varchar(100) NOT NULL DEFAULT '', parent_id int8 NOT NULL, creator varchar(64) NULL DEFAULT '', @@ -5001,7 +5001,7 @@ CREATE SEQUENCE yudao_demo02_category_seq DROP TABLE IF EXISTS yudao_demo03_course; CREATE TABLE yudao_demo03_course ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('yudao_demo03_course_seq'), student_id int8 NOT NULL, name varchar(100) NOT NULL DEFAULT '', score int2 NOT NULL, @@ -5063,7 +5063,7 @@ CREATE SEQUENCE yudao_demo03_course_seq DROP TABLE IF EXISTS yudao_demo03_grade; CREATE TABLE yudao_demo03_grade ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('yudao_demo03_grade_seq'), student_id int8 NOT NULL, name varchar(100) NOT NULL DEFAULT '', teacher varchar(255) NOT NULL, @@ -5111,7 +5111,7 @@ CREATE SEQUENCE yudao_demo03_grade_seq DROP TABLE IF EXISTS yudao_demo03_student; CREATE TABLE yudao_demo03_student ( - id int8 NOT NULL, + id int8 NOT NULL default nextval('yudao_demo03_student_seq'), name varchar(100) NOT NULL DEFAULT '', sex int2 NOT NULL, birthday timestamp NOT NULL, diff --git a/sql/sqlserver/ruoyi-vue-pro.sql b/sql/sqlserver/ruoyi-vue-pro.sql index abf63c4e34..fc4c81bba4 100644 --- a/sql/sqlserver/ruoyi-vue-pro.sql +++ b/sql/sqlserver/ruoyi-vue-pro.sql @@ -2945,7 +2945,7 @@ INSERT INTO system_dict_data (id, sort, label, value, dict_type, status, color_t GO 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 (1692, 14, N'MiniMax', N'MiniMax', N'ai_platform', 0, N'', N'', N'', N'1', N'2025-03-11 20:04:51', N'1', N'2025-03-11 20:04:51', N'0') GO -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 (1693, 15, N'月之暗灭', N'Moonshot', N'ai_platform', 0, N'', N'', N'', N'1', N'2025-03-11 20:05:08', N'1', N'2025-03-11 20:05:08', N'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 (1693, 15, N'月之暗面', N'Moonshot', N'ai_platform', 0, N'', N'', N'', N'1', N'2025-03-11 20:05:08', N'1', N'2025-03-11 20:05:08', N'0') GO 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 (2000, 0, N'标准数据格式(JSON)', N'0', N'iot_data_format', 0, N'default', N'', N'', N'1', N'2024-08-10 11:53:26', N'1', N'2025-03-17 09:28:16', N'0') GO diff --git a/sql/tools/convertor.py b/sql/tools/convertor.py index b54d1337c8..d52a7a73c1 100644 --- a/sql/tools/convertor.py +++ b/sql/tools/convertor.py @@ -52,6 +52,7 @@ def load_and_clean(sql_file: str) -> str: REPLACE_PAIR_LIST = ( (")\nVALUES ", ") VALUES "), (" CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ", " "), + (" CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ", " "), (" KEY `", " INDEX `"), ("UNIQUE INDEX", "UNIQUE KEY"), ("b'0'", "'0'"), @@ -61,6 +62,11 @@ def load_and_clean(sql_file: str) -> str: content = open(sql_file, encoding="utf-8").read() for replace_pair in REPLACE_PAIR_LIST: content = content.replace(*replace_pair) + # 移除索引字段的前缀长度定义,例如: `name`(32) -> `name` + # 移除索引定义上的 USING BTREE COMMENT 部分 + # 相关 issue:https://t.zsxq.com/96IFc 、https://t.zsxq.com/rC3A3 + content = re.sub(r'`([^`]+)`\(\d+\)', r'`\1`', content) + content = re.sub(r'\s+USING\s+BTREE\s+COMMENT\s+\'[^\']+\'', '', content) content = re.sub(r"ENGINE.*COMMENT", "COMMENT", content) content = re.sub(r"ENGINE.*;", ";", content) return content @@ -262,10 +268,10 @@ class Convertor(ABC): # 解析注释 for column in table_ddl["columns"]: column["comment"] = bytes(column["comment"], "utf-8").decode( - "unicode_escape" + r"unicode_escape" )[1:-1] table_ddl["comment"] = bytes(table_ddl["comment"], "utf-8").decode( - "unicode_escape" + r"unicode_escape" )[1:-1] # 为每个表生成个6个基本部分 diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index dbaab74ab3..ecb3503066 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -46,38 +46,37 @@ 0.33.0 7.2.11.RELEASE - 1.1.11 + 1.1.12 4.11.0 6.8.0 1.4.0 1.21.2 - 1.18.38 + 1.18.42 1.6.3 - 5.8.40 + 5.8.41 1.3.0 2.4 1.2.83 - 33.4.8-jre + 33.5.0-jre 2.14.5 - 3.11.1 - 3.18.0 - 2.27.3 + 3.12.0 + 3.20.0 + 2.27.6 2.9.3 2.7.0 3.0.6 - 4.2.4.Final + 4.2.7.Final 1.2.5 - 0.9.0 4.5.13 - 2.30.14 + 2.39.2 1.16.7 1.4.0 2.1.1 2.1.0 - 4.7.7-20250808.182223 + 4.7.8-20251117.120146 1.2.13 @@ -635,19 +634,6 @@ - - - org.pf4j - pf4j-spring - ${pf4j-spring.version} - - - org.slf4j - slf4j-log4j12 - - - - io.vertx diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/databind/TimestampLocalDateTimeSerializer.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/databind/TimestampLocalDateTimeSerializer.java index 12354256e3..bed47e93bb 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/databind/TimestampLocalDateTimeSerializer.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/databind/TimestampLocalDateTimeSerializer.java @@ -1,10 +1,10 @@ package cn.iocoder.yudao.framework.common.util.json.databind; +import cn.hutool.core.util.ReflectUtil; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; -import org.apache.commons.lang3.reflect.FieldUtils; import java.io.IOException; import java.lang.reflect.Field; @@ -25,7 +25,7 @@ public class TimestampLocalDateTimeSerializer extends JsonSerializer clazz = gen.getOutputContext().getCurrentValue().getClass(); - Field field = FieldUtils.getField(clazz, fieldName, true); + Field field = ReflectUtil.getField(clazz, fieldName); // 情况一:有 JsonFormat 自定义注解,则使用它。https://github.com/YunaiV/ruoyi-vue-pro/pull/1019 JsonFormat[] jsonFormats = field.getAnnotationsByType(JsonFormat.class); if (jsonFormats.length > 0) { diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java index 3eaafec18f..8e37452a4e 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java @@ -9,6 +9,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.io.InputStream; import java.util.List; /** @@ -44,9 +45,12 @@ public class ExcelUtils { } public static List read(MultipartFile file, Class head) throws IOException { - return FastExcelFactory.read(file.getInputStream(), head, null) - .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理 - .doReadAllSync(); + // 参考 https://t.zsxq.com/zM77F 帖子,增加 try 处理,兼容 windows 场景 + try (InputStream inputStream = file.getInputStream()) { + return FastExcelFactory.read(inputStream, head, null) + .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理 + .doReadAllSync(); + } } } diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/IdTypeEnvironmentPostProcessor.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/IdTypeEnvironmentPostProcessor.java index 3a67b905f6..0ea6bf2522 100644 --- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/IdTypeEnvironmentPostProcessor.java +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/IdTypeEnvironmentPostProcessor.java @@ -9,7 +9,10 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MapPropertySource; +import java.util.HashMap; +import java.util.Map; import java.util.Set; /** @@ -56,11 +59,19 @@ public class IdTypeEnvironmentPostProcessor implements EnvironmentPostProcessor } public IdType getIdType(ConfigurableEnvironment environment) { - return environment.getProperty(ID_TYPE_KEY, IdType.class); + String value = environment.getProperty(ID_TYPE_KEY); + try { + return StrUtil.isNotBlank(value) ? IdType.valueOf(value) : IdType.NONE; + } catch (IllegalArgumentException ex) { + log.error("[getIdType][无法解析 id-type 配置值({})]", value, ex); + return IdType.NONE; + } } public void setIdType(ConfigurableEnvironment environment, IdType idType) { - environment.getSystemProperties().put(ID_TYPE_KEY, idType); + Map map = new HashMap<>(); + map.put(ID_TYPE_KEY, idType); + environment.getPropertySources().addFirst(new MapPropertySource("mybatisPlusIdType", map)); log.info("[setIdType][修改 MyBatis Plus 的 idType 为({})]", idType); } 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 52ca947cc5..9858a1aed6 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 @@ -68,6 +68,29 @@ public interface BaseMapperX extends MPJBaseMapper { return new PageResult<>(mpPage.getRecords(), mpPage.getTotal()); } + /** + * 执行分页查询并返回结果。 + * + * @param pageParam 分页参数,包含页码、每页条数和排序字段信息。如果 pageSize 为 {@link PageParam#PAGE_SIZE_NONE},则不分页,直接查询所有数据。 + * @param clazz 结果集的类类型 + * @param lambdaWrapper MyBatis Plus Join 查询条件包装器 + * @param 结果集的泛型类型 + * @return 返回分页查询的结果,包括总记录数和当前页的数据列表 + */ + default PageResult selectJoinPage(SortablePageParam pageParam, Class clazz, MPJLambdaWrapper lambdaWrapper) { + // 特殊:不分页,直接查询全部 + if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) { + List list = selectJoinList(clazz, lambdaWrapper); + return new PageResult<>(list, (long) list.size()); + } + + // MyBatis Plus Join 查询 + IPage mpPage = MyBatisUtils.buildPage(pageParam, pageParam.getSortingFields()); + 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-web/src/main/java/cn/iocoder/yudao/framework/encrypt/core/filter/ApiEncryptResponseWrapper.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/encrypt/core/filter/ApiEncryptResponseWrapper.java index fc49442c31..0f5a02cd52 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/encrypt/core/filter/ApiEncryptResponseWrapper.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/encrypt/core/filter/ApiEncryptResponseWrapper.java @@ -42,15 +42,16 @@ public class ApiEncryptResponseWrapper extends HttpServletResponseWrapper { this.flushBuffer(); byte[] body = byteArrayOutputStream.toByteArray(); - // 2. 加密 body - String encryptedBody = symmetricEncryptor != null ? symmetricEncryptor.encryptBase64(body) - : asymmetricEncryptor.encryptBase64(body, KeyType.PublicKey); - response.getWriter().write(encryptedBody); - - // 3. 添加加密 header 标识 + // 2. 添加加密 header 标识 this.addHeader(properties.getHeader(), "true"); // 特殊:特殊:https://juejin.cn/post/6867327674675625992 this.addHeader("Access-Control-Expose-Headers", properties.getHeader()); + + // 3.1 加密 body + String encryptedBody = symmetricEncryptor != null ? symmetricEncryptor.encryptBase64(body) + : asymmetricEncryptor.encryptBase64(body, KeyType.PublicKey); + // 3.2 输出加密后的 body:(设置 header 要放在 response 的 write 之前) + response.getWriter().write(encryptedBody); } @Override diff --git a/yudao-module-ai/pom.xml b/yudao-module-ai/pom.xml index 95a28979a1..14083c8de5 100644 --- a/yudao-module-ai/pom.xml +++ b/yudao-module-ai/pom.xml @@ -19,9 +19,9 @@ 国外:OpenAI、Ollama、Midjourney、StableDiffusion、Suno - 1.0.1 - 1.0.0.3 - 1.0.2 + 1.1.0 + 1.0.0.4 + 1.2.6 @@ -136,7 +136,7 @@ 1.0.0 - + org.springaicommunity moonshot-spring-boot-starter 1.0.0 diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/enums/model/AiPlatformEnum.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/enums/model/AiPlatformEnum.java index 47a4d2d719..bf15ec1f12 100644 --- a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/enums/model/AiPlatformEnum.java +++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/enums/model/AiPlatformEnum.java @@ -26,7 +26,7 @@ public enum AiPlatformEnum implements ArrayValuable { HUN_YUAN("HunYuan", "混元"), // 腾讯 SILICON_FLOW("SiliconFlow", "硅基流动"), // 硅基流动 MINI_MAX("MiniMax", "MiniMax"), // 稀宇科技 - MOONSHOT("Moonshot", "月之暗灭"), // KIMI + MOONSHOT("Moonshot", "月之暗面"), // KIMI BAI_CHUAN("BaiChuan", "百川智能"), // 百川智能 // ========== 国外平台 ========== @@ -40,6 +40,7 @@ public enum AiPlatformEnum implements ArrayValuable { STABLE_DIFFUSION("StableDiffusion", "StableDiffusion"), // Stability AI MIDJOURNEY("Midjourney", "Midjourney"), // Midjourney SUNO("Suno", "Suno"), // Suno AI + GROK("Grok","Grok"), // Grok ; diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/AiAutoConfiguration.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/AiAutoConfiguration.java index 26fbe0ad41..9009cbc8ca 100644 --- a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/AiAutoConfiguration.java +++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/AiAutoConfiguration.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.ai.framework.ai.core.model.AiModelFactoryImpl; import cn.iocoder.yudao.module.ai.framework.ai.core.model.baichuan.BaiChuanChatModel; import cn.iocoder.yudao.module.ai.framework.ai.core.model.doubao.DouBaoChatModel; import cn.iocoder.yudao.module.ai.framework.ai.core.model.gemini.GeminiChatModel; +import cn.iocoder.yudao.module.ai.framework.ai.core.model.grok.GrokChatModel; import cn.iocoder.yudao.module.ai.framework.ai.core.model.hunyuan.HunYuanChatModel; import cn.iocoder.yudao.module.ai.framework.ai.core.model.midjourney.api.MidjourneyApi; import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlowApiConstants; @@ -16,7 +17,9 @@ import cn.iocoder.yudao.module.ai.framework.ai.core.model.xinghuo.XingHuoChatMod import cn.iocoder.yudao.module.ai.framework.ai.core.webserch.AiWebSearchClient; import cn.iocoder.yudao.module.ai.framework.ai.core.webserch.bocha.AiBoChaWebSearchClient; import cn.iocoder.yudao.module.ai.tool.method.PersonService; +import io.micrometer.observation.ObservationRegistry; import lombok.extern.slf4j.Slf4j; +import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.deepseek.DeepSeekChatModel; import org.springframework.ai.deepseek.DeepSeekChatOptions; import org.springframework.ai.deepseek.api.DeepSeekApi; @@ -34,12 +37,14 @@ import org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusServiceClie import org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreProperties; import org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreProperties; import org.springframework.ai.vectorstore.redis.autoconfigure.RedisVectorStoreProperties; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.List; +import java.util.Optional; /** * 芋道 AI 自动配置 @@ -60,6 +65,13 @@ public class AiAutoConfiguration { return new AiModelFactoryImpl(); } + @Bean + @ConditionalOnMissingBean + public ObservationRegistry observationRegistry() { + // 特殊:兜底有 ObservationRegistry Bean,避免相关的 ChatModel 创建报错。相关 issue:https://t.zsxq.com/CuPu4 + return ObservationRegistry.NOOP; + } + // ========== 各种 AI Client 创建 ========== @Bean @@ -252,6 +264,28 @@ public class AiAutoConfiguration { return new SunoApi(yudaoAiProperties.getSuno().getBaseUrl()); } + public ChatModel buildGrokChatClient(YudaoAiProperties.Grok properties) { + if (StrUtil.isEmpty(properties.getModel())) { + properties.setModel(GrokChatModel.MODEL_DEFAULT); + } + OpenAiChatModel openAiChatModel = OpenAiChatModel.builder() + .openAiApi(OpenAiApi.builder() + .baseUrl(Optional.ofNullable(properties.getBaseUrl()) + .orElse(GrokChatModel.BASE_URL)) + .completionsPath(GrokChatModel.COMPLETE_PATH) + .apiKey(properties.getApiKey()) + .build()) + .defaultOptions(OpenAiChatOptions.builder() + .model(properties.getModel()) + .temperature(properties.getTemperature()) + .maxTokens(properties.getMaxTokens()) + .topP(properties.getTopP()) + .build()) + .toolCallingManager(getToolCallingManager()) + .build(); + return new DouBaoChatModel(openAiChatModel); + } + // ========== RAG 相关 ========== @Bean diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/YudaoAiProperties.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/YudaoAiProperties.java index 67d3bb5f3a..986c24c18c 100644 --- a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/YudaoAiProperties.java +++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/YudaoAiProperties.java @@ -160,6 +160,20 @@ public class YudaoAiProperties { } + @Data + public static class Grok { + + private String enable; + private String apiKey; + private String baseUrl; + + private String model; + private Double temperature; + private Integer maxTokens; + private Double topP; + + } + @Data public static class WebSearch { diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/AiModelFactoryImpl.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/AiModelFactoryImpl.java index 75798ebd2a..f8067dea2e 100644 --- a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/AiModelFactoryImpl.java +++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/AiModelFactoryImpl.java @@ -87,7 +87,7 @@ import org.springframework.ai.model.zhipuai.autoconfigure.ZhiPuAiImageAutoConfig import org.springframework.ai.ollama.OllamaChatModel; import org.springframework.ai.ollama.OllamaEmbeddingModel; import org.springframework.ai.ollama.api.OllamaApi; -import org.springframework.ai.ollama.api.OllamaOptions; +import org.springframework.ai.ollama.api.OllamaEmbeddingOptions; import org.springframework.ai.openai.OpenAiChatModel; import org.springframework.ai.openai.OpenAiEmbeddingModel; import org.springframework.ai.openai.OpenAiEmbeddingOptions; @@ -178,6 +178,8 @@ public class AiModelFactoryImpl implements AiModelFactory { return buildGeminiChatModel(apiKey); case OLLAMA: return buildOllamaChatModel(url); + case GROK: + return buildGrokChatModel(apiKey,url); default: throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform)); } @@ -436,10 +438,12 @@ public class AiModelFactoryImpl implements AiModelFactory { * 可参考 {@link ZhiPuAiChatAutoConfiguration} 的 zhiPuAiChatModel 方法 */ private ZhiPuAiChatModel buildZhiPuChatModel(String apiKey, String url) { - ZhiPuAiApi zhiPuAiApi = StrUtil.isEmpty(url) ? new ZhiPuAiApi(apiKey) - : new ZhiPuAiApi(url, apiKey); + ZhiPuAiApi.Builder zhiPuAiApiBuilder = ZhiPuAiApi.builder().apiKey(apiKey); + if (StrUtil.isNotEmpty(url)) { + zhiPuAiApiBuilder.baseUrl(url); + } ZhiPuAiChatOptions options = ZhiPuAiChatOptions.builder().model(ZhiPuAiApi.DEFAULT_CHAT_MODEL).temperature(0.7).build(); - return new ZhiPuAiChatModel(zhiPuAiApi, options, getToolCallingManager(), DEFAULT_RETRY_TEMPLATE, + return new ZhiPuAiChatModel(zhiPuAiApiBuilder.build(), options, getToolCallingManager(), DEFAULT_RETRY_TEMPLATE, getObservationRegistry().getIfAvailable()); } @@ -586,6 +590,13 @@ public class AiModelFactoryImpl implements AiModelFactory { return new StabilityAiImageModel(stabilityAiApi); } + private ChatModel buildGrokChatModel(String apiKey,String url) { + YudaoAiProperties.Grok properties = new YudaoAiProperties.Grok() + .setBaseUrl(url) + .setApiKey(apiKey); + return new AiAutoConfiguration().buildGrokChatClient(properties); + } + // ========== 各种创建 EmbeddingModel 的方法 ========== /** @@ -601,10 +612,12 @@ public class AiModelFactoryImpl implements AiModelFactory { * 可参考 {@link ZhiPuAiEmbeddingAutoConfiguration} 的 zhiPuAiEmbeddingModel 方法 */ private ZhiPuAiEmbeddingModel buildZhiPuEmbeddingModel(String apiKey, String url, String model) { - ZhiPuAiApi zhiPuAiApi = StrUtil.isEmpty(url) ? new ZhiPuAiApi(apiKey) - : new ZhiPuAiApi(url, apiKey); + ZhiPuAiApi.Builder zhiPuAiApiBuilder = ZhiPuAiApi.builder().apiKey(apiKey); + if (StrUtil.isNotEmpty(url)) { + zhiPuAiApiBuilder.baseUrl(url); + } ZhiPuAiEmbeddingOptions zhiPuAiEmbeddingOptions = ZhiPuAiEmbeddingOptions.builder().model(model).build(); - return new ZhiPuAiEmbeddingModel(zhiPuAiApi, MetadataMode.EMBED, zhiPuAiEmbeddingOptions); + return new ZhiPuAiEmbeddingModel(zhiPuAiApiBuilder.build(), MetadataMode.EMBED, zhiPuAiEmbeddingOptions); } /** @@ -632,7 +645,7 @@ public class AiModelFactoryImpl implements AiModelFactory { private OllamaEmbeddingModel buildOllamaEmbeddingModel(String url, String model) { OllamaApi ollamaApi = OllamaApi.builder().baseUrl(url).build(); - OllamaOptions ollamaOptions = OllamaOptions.builder().model(model).build(); + OllamaEmbeddingOptions ollamaOptions = OllamaEmbeddingOptions.builder().model(model).build(); return OllamaEmbeddingModel.builder() .ollamaApi(ollamaApi) .defaultOptions(ollamaOptions) diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/grok/GrokChatModel.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/grok/GrokChatModel.java new file mode 100644 index 0000000000..06eed2504f --- /dev/null +++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/grok/GrokChatModel.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.ai.framework.ai.core.model.grok; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.ai.chat.model.ChatModel; +import org.springframework.ai.chat.model.ChatResponse; +import org.springframework.ai.chat.prompt.ChatOptions; +import org.springframework.ai.chat.prompt.Prompt; +import reactor.core.publisher.Flux; + +/** + * Grok {@link ChatModel} 实现类 + * + * + */ +@Slf4j +@RequiredArgsConstructor +public class GrokChatModel implements ChatModel { + + public static final String BASE_URL = "https://api.x.ai"; + public static final String COMPLETE_PATH = "/v1/chat/completions"; + public static final String MODEL_DEFAULT = "grok-4-fast-reasoning"; + + /** + * 兼容 OpenAI 接口,进行复用 + */ + private final ChatModel openAiChatModel; + + @Override + public ChatResponse call(Prompt prompt) { + return openAiChatModel.call(prompt); + } + + @Override + public Flux stream(Prompt prompt) { + return openAiChatModel.stream(prompt); + } + + @Override + public ChatOptions getDefaultOptions() { + return openAiChatModel.getDefaultOptions(); + } + +} diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/security/config/SecurityConfiguration.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/security/config/SecurityConfiguration.java index 6ca5934b62..12cff651d5 100644 --- a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/security/config/SecurityConfiguration.java +++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/security/config/SecurityConfiguration.java @@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.ai.framework.security.config; import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer; import jakarta.annotation.Resource; -import org.springframework.ai.mcp.server.autoconfigure.McpServerProperties; +import org.springframework.ai.mcp.server.common.autoconfigure.properties.McpServerSseProperties; +import org.springframework.ai.mcp.server.common.autoconfigure.properties.McpServerStreamableHttpProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -17,7 +18,9 @@ import java.util.Optional; public class SecurityConfiguration { @Resource - private Optional serverProperties; + private Optional mcpServerSseProperties; + @Resource + private Optional mcpServerStreamableHttpProperties; @Bean("aiAuthorizeRequestsCustomizer") public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() { @@ -25,11 +28,12 @@ public class SecurityConfiguration { @Override public void customize(AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry registry) { - // MCP Server - serverProperties.ifPresent(properties -> { + mcpServerSseProperties.ifPresent(properties -> { registry.requestMatchers(properties.getSseEndpoint()).permitAll(); registry.requestMatchers(properties.getSseMessageEndpoint()).permitAll(); }); + mcpServerStreamableHttpProperties.ifPresent(properties -> + registry.requestMatchers(properties.getMcpEndpoint()).permitAll()); } }; diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageServiceImpl.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageServiceImpl.java index 0f44eacbf4..f29a5c3f99 100644 --- a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageServiceImpl.java +++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageServiceImpl.java @@ -49,7 +49,7 @@ import org.springframework.ai.chat.model.StreamingChatModel; import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.mcp.SyncMcpToolCallbackProvider; -import org.springframework.ai.mcp.client.autoconfigure.properties.McpClientCommonProperties; +import org.springframework.ai.mcp.client.common.autoconfigure.properties.McpClientCommonProperties; import org.springframework.ai.tool.ToolCallback; import org.springframework.ai.tool.resolution.ToolCallbackResolver; import org.springframework.beans.factory.annotation.Autowired; diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java index dd0f91315b..43c7e9cefe 100644 --- a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java +++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java @@ -227,6 +227,9 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService // 2. 检索 List documents = searchDocument(knowledge, reqBO); + if (CollUtil.isEmpty(documents)) { + return ListUtil.empty(); + } // 3.1 段落召回 List segments = segmentMapper diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java index d209c62d44..dab4d5aa49 100644 --- a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java +++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java @@ -16,7 +16,7 @@ import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.deepseek.DeepSeekAssistantMessage; import org.springframework.ai.deepseek.DeepSeekChatOptions; import org.springframework.ai.minimax.MiniMaxChatOptions; -import org.springframework.ai.ollama.api.OllamaOptions; +import org.springframework.ai.ollama.api.OllamaChatOptions; import org.springframework.ai.openai.OpenAiChatOptions; import org.springframework.ai.tool.ToolCallback; import org.springframework.ai.zhipuai.ZhiPuAiChatOptions; @@ -68,6 +68,7 @@ public class AiUtils { case OPENAI: case GEMINI: // 复用 OpenAI 客户端 case BAI_CHUAN: // 复用 OpenAI 客户端 + case GROK: // 复用 OpenAI 客户端 return OpenAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens) .toolCallbacks(toolCallbacks).toolContext(toolContext).build(); case AZURE_OPENAI: @@ -77,7 +78,7 @@ public class AiUtils { return AnthropicChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens) .toolCallbacks(toolCallbacks).toolContext(toolContext).build(); case OLLAMA: - return OllamaOptions.builder().model(model).temperature(temperature).numPredict(maxTokens) + return OllamaChatOptions.builder().model(model).temperature(temperature).numPredict(maxTokens) .toolCallbacks(toolCallbacks).toolContext(toolContext).build(); default: throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform)); diff --git a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/AnthropicChatModelTest.java b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/AnthropicChatModelTest.java index 454fad47b6..bbcc055a26 100644 --- a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/AnthropicChatModelTest.java +++ b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/AnthropicChatModelTest.java @@ -28,7 +28,7 @@ public class AnthropicChatModelTest { .baseUrl("https://aihubmix.com") .build()) .defaultOptions(AnthropicChatOptions.builder() - .model(AnthropicApi.ChatModel.CLAUDE_SONNET_4) + .model(AnthropicApi.ChatModel.CLAUDE_SONNET_4_5) .temperature(0.7) .maxTokens(4096) .build()) @@ -70,7 +70,7 @@ public class AnthropicChatModelTest { List messages = new ArrayList<>(); messages.add(new UserMessage("thkinking 下,1+1 为什么等于 2 ")); AnthropicChatOptions options = AnthropicChatOptions.builder() - .model(AnthropicApi.ChatModel.CLAUDE_SONNET_4) + .model(AnthropicApi.ChatModel.CLAUDE_SONNET_4_5) .thinking(AnthropicApi.ThinkingType.ENABLED, 3096) .temperature(1D) .build(); diff --git a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/LlamaChatModelTests.java b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/LlamaChatModelTests.java index 14f32e06ec..080146e5a2 100644 --- a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/LlamaChatModelTests.java +++ b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/LlamaChatModelTests.java @@ -9,8 +9,8 @@ import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.ollama.OllamaChatModel; import org.springframework.ai.ollama.api.OllamaApi; +import org.springframework.ai.ollama.api.OllamaChatOptions; import org.springframework.ai.ollama.api.OllamaModel; -import org.springframework.ai.ollama.api.OllamaOptions; import reactor.core.publisher.Flux; import java.util.ArrayList; @@ -27,7 +27,7 @@ public class LlamaChatModelTests { .ollamaApi(OllamaApi.builder() .baseUrl("http://127.0.0.1:11434") // Ollama 服务地址 .build()) - .defaultOptions(OllamaOptions.builder() + .defaultOptions(OllamaChatOptions.builder() .model(OllamaModel.LLAMA3.getName()) // 模型 .build()) .build(); @@ -70,7 +70,7 @@ public class LlamaChatModelTests { // 准备参数 List messages = new ArrayList<>(); messages.add(new UserMessage("详细分析下,如何设计一个电商系统?")); - OllamaOptions options = OllamaOptions.builder() + OllamaChatOptions options = OllamaChatOptions.builder() .model("qwen3") .build(); @@ -83,5 +83,4 @@ public class LlamaChatModelTests { }).then().block(); } - } diff --git a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/OllamaChatModelTests.java b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/OllamaChatModelTests.java index d2bf68812b..c03a5de158 100644 --- a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/OllamaChatModelTests.java +++ b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/OllamaChatModelTests.java @@ -9,7 +9,7 @@ import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.ollama.OllamaChatModel; import org.springframework.ai.ollama.api.OllamaApi; -import org.springframework.ai.ollama.api.OllamaOptions; +import org.springframework.ai.ollama.api.OllamaChatOptions; import reactor.core.publisher.Flux; import java.util.ArrayList; @@ -26,7 +26,7 @@ public class OllamaChatModelTests { .ollamaApi(OllamaApi.builder() .baseUrl("http://127.0.0.1:11434") // Ollama 服务地址 .build()) - .defaultOptions(OllamaOptions.builder() + .defaultOptions(OllamaChatOptions.builder() // .model("qwen") // 模型(https://ollama.com/library/qwen) .model("deepseek-r1") // 模型(https://ollama.com/library/deepseek-r1) .build()) diff --git a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/ZhiPuAiChatModelTests.java b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/ZhiPuAiChatModelTests.java index 0b0b006935..18c317989b 100644 --- a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/ZhiPuAiChatModelTests.java +++ b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/ZhiPuAiChatModelTests.java @@ -23,7 +23,7 @@ import java.util.List; public class ZhiPuAiChatModelTests { private final ZhiPuAiChatModel chatModel = new ZhiPuAiChatModel( - new ZhiPuAiApi("2f35fb6ca4ea41fab898729b7fac086c.6ESSfPcCkxaKEUlR"), // 密钥 + ZhiPuAiApi.builder().apiKey("2f35fb6ca4ea41fab898729b7fac086c.6ESSfPcCkxaKEUlR").build(), // 密钥 ZhiPuAiChatOptions.builder() .model(ZhiPuAiApi.ChatModel.GLM_4.getName()) // 模型 .build() diff --git a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/websearch/AiBoChaWebSearchClientTest.java b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/websearch/AiBoChaWebSearchClientTest.java index 0a02ab589d..e947e0fe3b 100644 --- a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/websearch/AiBoChaWebSearchClientTest.java +++ b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/websearch/AiBoChaWebSearchClientTest.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.module.ai.framework.ai.core.webserch.AiWebSearchRequest; import cn.iocoder.yudao.module.ai.framework.ai.core.webserch.AiWebSearchResponse; import cn.iocoder.yudao.module.ai.framework.ai.core.webserch.bocha.AiBoChaWebSearchClient; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; /** @@ -17,6 +18,7 @@ public class AiBoChaWebSearchClientTest { "sk-40500e52840f4d24b956d0b1d80d9abe"); @Test + @Disabled public void testSearch() { AiWebSearchRequest request = new AiWebSearchRequest() .setQuery("阿里巴巴") diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java index 349f88048f..b624c532e4 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java @@ -18,11 +18,11 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConsta import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; import org.flowable.bpmn.converter.BpmnXMLConverter; -import org.flowable.bpmn.model.Process; import org.flowable.bpmn.model.*; +import org.flowable.bpmn.model.Process; import org.flowable.common.engine.api.FlowableException; +import org.flowable.common.engine.api.delegate.Expression; import org.flowable.common.engine.impl.util.io.BytesStreamSource; -import org.flowable.engine.impl.el.FixedValue; import java.util.*; @@ -406,7 +406,7 @@ public class BpmnModelUtils { flowableListener.getFieldExtensions().add(fieldExtension); } - public static BpmSimpleModelNodeVO.ListenerHandler parseListenerConfig(FixedValue fixedValue) { + public static BpmSimpleModelNodeVO.ListenerHandler parseListenerConfig(Expression fixedValue) { String expressionText = fixedValue.getExpressionText(); Assert.notNull(expressionText, "监听器扩展字段({})不能为空", expressionText); return JsonUtils.parseObject(expressionText, BpmSimpleModelNodeVO.ListenerHandler.class); diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java index f4a8993d38..1ebe6a8c65 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java @@ -54,7 +54,7 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy } // 执行抄送 createProcessInstanceCopy(userIds, reason, - task.getProcessInstanceId(), task.getTaskDefinitionKey(), task.getId(), task.getName()); + task.getProcessInstanceId(), task.getTaskDefinitionKey(), task.getName(), task.getId()); } @Override diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index 7b8e8003de..fe43820e0e 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -12,6 +12,7 @@ import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.common.util.object.PageUtils; +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; @@ -752,6 +753,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @Override @Transactional(rollbackFor = Exception.class) + @DataPermission(enable = false) // 关闭数据权限,避免查询不到用户数据。相关案例:https://gitee.com/zhijiantianya/yudao-cloud/issues/ID1UYA public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService @@ -762,6 +764,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService } @Override + @DataPermission(enable = false) // 关闭数据权限,避免查询不到用户数据。相关案例:https://gitee.com/zhijiantianya/yudao-cloud/issues/ID1UYA public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { return FlowableUtils.executeAuthenticatedUserId(userId, () -> { // 获得流程定义 @@ -878,6 +881,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService } @Override + @DataPermission(enable = false) // 关闭数据权限,避免查询不到用户数据。相关案例:https://gitee.com/zhijiantianya/yudao-cloud/issues/ID1UYA public void cancelProcessInstanceByStartUser(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { // 1.1 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); @@ -907,6 +911,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService } @Override + @DataPermission(enable = false) // 关闭数据权限,避免查询不到用户数据。相关案例:https://gitee.com/zhijiantianya/yudao-cloud/issues/ID1UYA public void cancelProcessInstanceByAdmin(Long userId, BpmProcessInstanceCancelReqVO cancelReqVO) { // 1.1 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index 2bc4e2ae9c..05c1d3a405 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -376,6 +376,11 @@ public class BpmTaskServiceImpl implements BpmTaskService { } // 2.2 过滤:只有串行可到达的节点,才可以退回。类似非串行、子流程无法退回 previousUserList.removeIf(userTask -> !BpmnModelUtils.isSequentialReachable(source, userTask, null)); + + // 2.3 过滤:只能退回到已经处理过的节点(排除审批未经过的节点)。相关 issue:https://github.com/YunaiV/ruoyi-vue-pro/issues/982 + List finishedTasks = getFinishedTaskListByProcessInstanceIdWithoutCancel(task.getProcessInstanceId()); + Set finishedTaskDefinitionKeys = convertSet(finishedTasks, HistoricTaskInstance::getTaskDefinitionKey); + previousUserList.removeIf(userTask -> !finishedTaskDefinitionKeys.contains(userTask.getId())); return previousUserList; } @@ -544,6 +549,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override @Transactional(rollbackFor = Exception.class) + @DataPermission(enable = false) // 关闭数据权限,避免查询不到用户数据。相关案例:https://gitee.com/zhijiantianya/yudao-cloud/issues/ID1UYA public void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO) { // 1.1 校验任务存在 Task task = validateTask(userId, reqVO.getId()); @@ -788,6 +794,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override @Transactional(rollbackFor = Exception.class) + @DataPermission(enable = false) // 关闭数据权限,避免查询不到用户数据。相关案例:https://gitee.com/zhijiantianya/yudao-cloud/issues/ID1UYA public void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO) { // 1.1 校验任务存在 Task task = validateTask(userId, reqVO.getId()); @@ -855,6 +862,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override @Transactional(rollbackFor = Exception.class) + @DataPermission(enable = false) // 关闭数据权限,避免查询不到用户数据。相关案例:https://gitee.com/zhijiantianya/yudao-cloud/issues/ID1UYA public void returnTask(Long userId, BpmTaskReturnReqVO reqVO) { // 1.1 当前任务 task Task task = validateTask(userId, reqVO.getId()); @@ -983,6 +991,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override @Transactional(rollbackFor = Exception.class) + @DataPermission(enable = false) // 关闭数据权限,避免查询不到用户数据。相关案例:https://gitee.com/zhijiantianya/yudao-cloud/issues/ID1UYA public void delegateTask(Long userId, BpmTaskDelegateReqVO reqVO) { String taskId = reqVO.getId(); // 1.1 校验任务 @@ -1012,6 +1021,8 @@ public class BpmTaskServiceImpl implements BpmTaskService { } @Override + @Transactional(rollbackFor = Exception.class) + @DataPermission(enable = false) // 关闭数据权限,避免查询不到用户数据。相关案例:https://gitee.com/zhijiantianya/yudao-cloud/issues/ID1UYA public void transferTask(Long userId, BpmTaskTransferReqVO reqVO) { String taskId = reqVO.getId(); // 1.1 校验任务 @@ -1042,6 +1053,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override @Transactional(rollbackFor = Exception.class) + @DataPermission(enable = false) // 关闭数据权限,避免查询不到用户数据。相关案例:https://gitee.com/zhijiantianya/yudao-cloud/issues/ID1UYA public void moveTaskToEnd(String processInstanceId, String reason) { List taskList = getRunningTaskListByProcessInstanceId(processInstanceId, null, null); if (CollUtil.isEmpty(taskList)) { @@ -1080,6 +1092,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override @Transactional(rollbackFor = Exception.class) + @DataPermission(enable = false) // 关闭数据权限,避免查询不到用户数据。相关案例:https://gitee.com/zhijiantianya/yudao-cloud/issues/ID1UYA public void createSignTask(Long userId, BpmTaskSignCreateReqVO reqVO) { // 1. 获取和校验任务 TaskEntityImpl taskEntity = validateTaskCanCreateSign(userId, reqVO); @@ -1196,6 +1209,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override @Transactional(rollbackFor = Exception.class) + @DataPermission(enable = false) // 关闭数据权限,避免查询不到用户数据。相关案例:https://gitee.com/zhijiantianya/yudao-cloud/issues/ID1UYA @SuppressWarnings("DataFlowIssue") public void deleteSignTask(Long userId, BpmTaskSignDeleteReqVO reqVO) { // 1.1 校验 task 可以被减签 @@ -1235,6 +1249,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override @Transactional(rollbackFor = Exception.class) + @DataPermission(enable = false) // 关闭数据权限,避免查询不到用户数据。相关案例:https://gitee.com/zhijiantianya/yudao-cloud/issues/ID1UYA public void withdrawTask(Long userId, String taskId) { // 1.1 查询本人已办任务 HistoricTaskInstance taskInstance = historyService.createHistoricTaskInstanceQuery() diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmCallActivityListener.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmCallActivityListener.java index 4766f4dd02..5eea679ab3 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmCallActivityListener.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmCallActivityListener.java @@ -13,9 +13,9 @@ import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionServic import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import org.flowable.common.engine.api.delegate.Expression; import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.ExecutionListener; -import org.flowable.engine.impl.el.FixedValue; import org.flowable.engine.runtime.ProcessInstance; import org.springframework.stereotype.Component; @@ -34,7 +34,7 @@ public class BpmCallActivityListener implements ExecutionListener { public static final String DELEGATE_EXPRESSION = "${bpmCallActivityListener}"; @Setter - private FixedValue listenerConfig; + private Expression listenerConfig; @Resource private BpmProcessDefinitionService processDefinitionService; diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmUserTaskListener.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmUserTaskListener.java index 646982e381..b76f9eb406 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmUserTaskListener.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmUserTaskListener.java @@ -6,8 +6,8 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmHttpRequestUt import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import org.flowable.common.engine.api.delegate.Expression; import org.flowable.engine.delegate.TaskListener; -import org.flowable.engine.impl.el.FixedValue; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.service.delegate.DelegateTask; import org.springframework.context.annotation.Scope; @@ -34,7 +34,7 @@ public class BpmUserTaskListener implements TaskListener { private BpmProcessInstanceService processInstanceService; @Setter - private FixedValue listenerConfig; + private Expression listenerConfig; @Override public void notify(DelegateTask delegateTask) { diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java index 2208887db5..5feb99c223 100644 --- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java +++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java @@ -59,7 +59,6 @@ public class CrmReceivablePlanRespVO { @ExcelProperty("回款编号") private Long receivableId; @Schema(description = "回款信息") - @ExcelProperty("回款信息") private CrmReceivableRespVO receivable; @Schema(description = "提前几天提醒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/AbstractFileClient.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/AbstractFileClient.java index 3c7883b83d..7ddade3eac 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/AbstractFileClient.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/AbstractFileClient.java @@ -19,10 +19,18 @@ public abstract class AbstractFileClient implem * 文件配置 */ protected Config config; + /** + * 原始的文件配置 + * + * 原因:{@link #config} 可能被子类所修改,无法用于判断配置是否变更 + * @link 相关案例 + */ + private Config originalConfig; public AbstractFileClient(Long id, Config config) { this.id = id; this.config = config; + this.originalConfig = config; } /** @@ -40,11 +48,12 @@ public abstract class AbstractFileClient implem public final void refresh(Config config) { // 判断是否更新 - if (config.equals(this.config)) { + if (config.equals(this.originalConfig)) { return; } log.info("[refresh][配置({})发生变化,重新初始化]", config); this.config = config; + this.originalConfig = config; // 初始化 this.init(); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/alert/IotAlertConfigMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/alert/IotAlertConfigMapper.java index c5d7154ff6..52b0d360dd 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/alert/IotAlertConfigMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/alert/IotAlertConfigMapper.java @@ -33,7 +33,7 @@ public interface IotAlertConfigMapper extends BaseMapperX { default List selectListBySceneRuleIdAndStatus(Long sceneRuleId, Integer status) { return selectList(new LambdaQueryWrapperX() .eq(IotAlertConfigDO::getStatus, status) - .apply(MyBatisUtils.findInSet("scene_rule_id", sceneRuleId))); + .apply(MyBatisUtils.findInSet("scene_rule_ids", sceneRuleId))); } } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/rule/IotSceneRuleMessageHandler.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/rule/IotSceneRuleMessageHandler.java index 278cd775e9..800344dd2b 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/rule/IotSceneRuleMessageHandler.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/rule/IotSceneRuleMessageHandler.java @@ -43,9 +43,6 @@ public class IotSceneRuleMessageHandler implements IotMessageSubscriber couponTemplate.getTotalCount()) { // 已领取数量 >= 总发放数量 throw exception(COUPON_TEMPLATE_NOT_ENOUGH); } // 校验"固定日期"的有效期类型是否过期 diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index beacddab87..c90d9ed81a 100644 --- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -268,7 +268,9 @@ public interface TradeOrderConvert { .setTitle(StrUtil.format("{}成功购买{}", user.getNickname(), item.getSpuName())) .setFirstFixedPrice(0).setSecondFixedPrice(0); if (BooleanUtil.isTrue(spu.getSubCommissionType())) { - bo.setFirstFixedPrice(sku.getFirstBrokeragePrice()).setSecondFixedPrice(sku.getSecondBrokeragePrice()); + // 特殊:单独设置的佣金需要乘以购买数量。关联 https://gitee.com/yudaocode/yudao-mall-uniapp/issues/ICY7SJ + bo.setFirstFixedPrice(sku.getFirstBrokeragePrice() * item.getCount()) + .setSecondFixedPrice(sku.getSecondBrokeragePrice() * item.getCount()); } return bo; } diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageRecordDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageRecordDO.java index c819d723bc..7dec2b850a 100644 --- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageRecordDO.java +++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageRecordDO.java @@ -29,7 +29,7 @@ public class BrokerageRecordDO extends BaseDO { * 编号 */ @TableId - private Integer id; + private Long id; /** * 用户编号 *

diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java index a17c3bfca8..8c64354f8b 100644 --- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java +++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java @@ -44,7 +44,7 @@ public interface BrokerageRecordMapper extends BaseMapperX { .lt(BrokerageRecordDO::getUnfreezeTime, unfreezeTime)); } - default int updateByIdAndStatus(Integer id, Integer status, BrokerageRecordDO updateObj) { + default int updateByIdAndStatus(Long id, Integer status, BrokerageRecordDO updateObj) { return update(updateObj, new LambdaQueryWrapper() .eq(BrokerageRecordDO::getId, id) .eq(BrokerageRecordDO::getStatus, status)); diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java index 75471196af..82d4ae96b5 100644 --- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.trade.service.aftersale; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; @@ -352,12 +353,20 @@ public class AfterSaleServiceImpl implements AfterSaleService { throw exception(AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND); } - // 发起退款单。注意,需要在事务提交后,再进行发起,避免重复发起 - createPayRefund(userIp, afterSale); + Integer newStatus; + if (ObjUtil.equals(afterSale.getRefundPrice(), 0)) { + // 特殊:退款为 0 的订单,直接标记为完成(积分商城)。关联案例:https://t.zsxq.com/AQEvL + updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.WAIT_REFUND.getStatus(), new AfterSaleDO() + .setStatus(AfterSaleStatusEnum.COMPLETE.getStatus()).setRefundTime(LocalDateTime.now())); + newStatus = AfterSaleStatusEnum.COMPLETE.getStatus(); + } else { + // 发起退款单。注意,需要在事务提交后,再进行发起,避免重复发起 + createPayRefund(userIp, afterSale); + newStatus = afterSale.getStatus(); // 特殊:这里状态不变,而是最终 updateAfterSaleRefunded 处理!!! + } // 记录售后日志 - AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), - afterSale.getStatus()); // 特殊:这里状态不变,而是最终 updateAfterSaleRefunded 处理!!! + AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), newStatus); } private void createPayRefund(String userIp, AfterSaleDO afterSale) { diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index 0926683979..9268c42e30 100644 --- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -147,9 +147,10 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { userAccount = wallet.getId().toString(); } // 1.2 构建请求 + Integer transferPrice = withdraw.getPrice() - withdraw.getFeePrice(); // 计算实际转账金额(提现金额 - 手续费) PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO() .setAppKey(tradeOrderProperties.getPayAppKey()).setChannelCode(channelCode) - .setMerchantTransferId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(withdraw.getPrice()) + .setMerchantTransferId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(transferPrice) .setUserAccount(userAccount).setUserName(userName).setUserIp(getClientIP()) .setUserId(withdraw.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) // 用户信息 .setChannelExtras(channelExtras); @@ -280,9 +281,10 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_STATUS_NOT_SUCCESS_OR_CLOSED); } // 2.2 校验转账金额一致 - if (ObjectUtil.notEqual(payTransfer.getPrice(), withdraw.getPrice())) { - log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) payTransfer({}) 转账金额不匹配,请进行处理!withdraw 数据是:{},payTransfer 数据是:{}]", - withdraw.getId(), payTransferId, JsonUtils.toJsonString(withdraw), JsonUtils.toJsonString(payTransfer)); + Integer expectedTransferPrice = withdraw.getPrice() - withdraw.getFeePrice(); // 转账金额 = 提现金额 - 手续费 + if (ObjectUtil.notEqual(payTransfer.getPrice(), expectedTransferPrice)) { + log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) payTransfer({}) 转账金额不匹配,请进行处理!withdraw 数据是:{},payTransfer 数据是:{},期望转账金额:{}]", + withdraw.getId(), payTransferId, JsonUtils.toJsonString(withdraw), JsonUtils.toJsonString(payTransfer), expectedTransferPrice); throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH); } // 2.3 校验转账订单匹配 diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java index 3e25ee912d..d75270ab9f 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java @@ -153,6 +153,7 @@ public class SocialUserServiceImpl implements SocialUserService { if (socialUser.getId() == null) { socialUserMapper.insert(socialUser); } else { + socialUser.clean(); // 避免 updateTime 不更新:https://gitee.com/yudaocode/yudao-boot-mini/issues/ID7FUL socialUserMapper.updateById(socialUser); } return socialUser; diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index f75733505c..22152465dd 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java @@ -276,7 +276,9 @@ public class AdminUserServiceImpl implements AdminUserService { // 如果有角色编号,查询角色对应的用户编号 Set userIds = reqVO.getRoleId() != null ? permissionService.getUserRoleIdListByRoleId(singleton(reqVO.getRoleId())) : null; - + if (userIds != null && userIds.isEmpty()) { + return PageResult.empty(); + } // 分页查询 return userMapper.selectPage(reqVO, getDeptCondition(reqVO.getDeptId()), userIds); } diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index 97ee0daf38..9d2fa34b66 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -59,11 +59,11 @@ - - - - - + + cn.iocoder.boot + yudao-module-mp + ${revision} + diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 5ad93a1d83..f844a5ee9e 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -187,7 +187,7 @@ spring: api-key: sk-47aa124781be4bfb95244cc62f6xxxx minimax: # Minimax:https://www.minimaxi.com/ api-key: xxxx - moonshot: # 月之暗灭(KIMI) + moonshot: # 月之暗面(KIMI) api-key: sk-abc deepseek: # DeepSeek api-key: sk-e94db327cc7d457d99a8de8810fc6b12 @@ -211,6 +211,8 @@ spring: filesystem: url: http://127.0.0.1:8089 sse-endpoint: /sse + annotation-scanner: + enabled: false # TODO @芋艿:有 bug https://github.com/spring-projects/spring-ai/issues/4917 需要官方修复 yudao: ai: