From c8392c9b47f994fb090c721700dbe00ec39f42a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=89=91=E9=9B=A8?= <2375294554@qq.com> Date: Wed, 14 May 2025 12:22:13 +0800 Subject: [PATCH 01/58] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8F=91=E9=80=81?= =?UTF-8?q?=E7=9F=AD=E4=BF=A1=E5=8F=82=E6=95=B0=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=88=B0=E6=95=B0=E6=8D=AE=E5=BA=93=E9=87=8C=20--202505141129.?= =?UTF-8?q?sql=20--db.changelog-master.yaml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/db/changelog/202505141129.sql | 11 +++++++++++ .../resources/db/changelog/db.changelog-master.yaml | 9 ++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 main/manager-api/src/main/resources/db/changelog/202505141129.sql diff --git a/main/manager-api/src/main/resources/db/changelog/202505141129.sql b/main/manager-api/src/main/resources/db/changelog/202505141129.sql new file mode 100644 index 00000000..e18bb523 --- /dev/null +++ b/main/manager-api/src/main/resources/db/changelog/202505141129.sql @@ -0,0 +1,11 @@ +-- 添加手机短信注册功能的需要的参数 +INSERT INTO + xiaozhi_esp32_server.sys_params +(id, param_code, param_value, value_type, param_type, remark, creator, create_date, updater, update_date) + VALUES +(501, 'system.enable_mobile_register', 'false', 'boolean', 1, '是否开启手机注册', NULL, NULL, NULL, NULL), +(502, 'system.sms.max_send_count', '5', 'number', 1, '单号码最大短信发送条数', NULL, NULL, NULL, NULL), +(510, 'aliyun.sms.access_key_id', '', 'string', 1, '阿里云平台access_key', NULL, NULL, NULL, NULL), +(511, 'aliyun.sms.access_key_secret', '', 'string', 1, '阿里云平台access_key_secret', NULL, NULL, NULL, NULL), +(512, 'aliyun.sms.sign_name', '', 'string', 1, '阿里云短信签名', NULL, NULL, NULL, NULL), +(513, 'aliyun.sms.sms_code_template_code', '', 'string', 1, '阿里云短信模板', NULL, NULL, NULL, NULL); \ No newline at end of file diff --git a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml index 53f4609d..299efc9c 100755 --- a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml @@ -113,4 +113,11 @@ databaseChangeLog: changes: - sqlFile: encoding: utf8 - path: classpath:db/changelog/202505091409.sql \ No newline at end of file + path: classpath:db/changelog/202505091409.sql + - changeSet: + id: 202505141129 + author: zjy + changes: + - sqlFile: + encoding: utf8 + path: classpath:db/changelog/202505141129.sql \ No newline at end of file From e4194cdf4d29b9b5415c5c456463523fa0662c75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=89=91=E9=9B=A8?= <2375294554@qq.com> Date: Wed, 14 May 2025 14:18:01 +0800 Subject: [PATCH 02/58] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E9=98=BF=E9=87=8C=E4=BA=91=E5=B9=B3=E5=8F=B0=E5=8F=91=E9=80=81?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E7=A0=81=E7=9F=AD=E4=BF=A1=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E6=B3=95=20--pom.xml=20=E6=B7=BB=E5=8A=A0=E7=9F=AD=E4=BF=A1?= =?UTF-8?q?=E5=8F=91=E9=80=81sdk=20--Constant.java=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=8F=91=E9=80=81=E7=9F=AD=E4=BF=A1=E7=9A=84=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E6=9E=9A=E4=B8=BE=20--ALiYunSmsService.java=20=E9=98=BF?= =?UTF-8?q?=E9=87=8C=E4=BA=91=E5=AE=9E=E7=8E=B0=E7=9F=AD=E4=BF=A1=E6=96=B9?= =?UTF-8?q?=E6=B3=95=20--SmsService.java=20=E7=9F=AD=E4=BF=A1=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/manager-api/pom.xml | 15 ++++ .../xiaozhi/common/constant/Constant.java | 40 ++++++++++ .../modules/sms/service/SmsService.java | 17 +++++ .../sms/service/imp/ALiYunSmsService.java | 76 +++++++++++++++++++ 4 files changed, 148 insertions(+) create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/sms/service/SmsService.java create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/sms/service/imp/ALiYunSmsService.java diff --git a/main/manager-api/pom.xml b/main/manager-api/pom.xml index d08e32f2..c4234647 100644 --- a/main/manager-api/pom.xml +++ b/main/manager-api/pom.xml @@ -28,6 +28,8 @@ 1.6.2 33.0.0-jre 4.20.0 + 4.1.0 + 3.4.0 @@ -37,6 +39,7 @@ jakarta ${shiro.version} + org.apache.shiro shiro-spring @@ -201,6 +204,18 @@ com.fasterxml.jackson.datatype jackson-datatype-jsr310 + + + com.aliyun + dysmsapi20170525 + ${the-latest-version} + + + + com.squareup.okio + okio + ${okio-version} + diff --git a/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java b/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java index 78154b5c..171d1a21 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java +++ b/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java @@ -146,6 +146,46 @@ public interface Constant { } } + /** + * 系统短信 + */ + enum SysMSMParam { + /** + * 阿里云授权keyID + */ + ALIYUN_SMS_ACCESS_KEY_ID("aliyun.sms.access_key_id"), + /** + * 阿里云授权密钥 + */ + ALIYUN_SMS_ACCESS_KEY_SECRET("aliyun.sms.access_key_secret"), + /** + * + */ + ALIYUN_SMS_SIGN_NAME("aliyun.sms.sign_name"), + /** + * 已删除 + */ + ALIYUN_SMS_SMS_CODE_TEMPLATE_CODE("aliyun.sms.sms_code_template_code"), + /** + * 已删除 + */ + SYSTEM_SMS_MAX_SEND_COUNT("system.sms.max_send_count"), + /** + * 是否开启手机注册 + */ + SYSTEM_ENABLE_MOBILE_REGISTER("system.enable_mobile_register"); + + private String value; + + SysMSMParam(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + /** * 数据状态 */ diff --git a/main/manager-api/src/main/java/xiaozhi/modules/sms/service/SmsService.java b/main/manager-api/src/main/java/xiaozhi/modules/sms/service/SmsService.java new file mode 100644 index 00000000..c33ad945 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/sms/service/SmsService.java @@ -0,0 +1,17 @@ +package xiaozhi.modules.sms.service; + +/** + * 短信服务的方法定义接口 + * + * @author zjy + * @since 2025-05-12 + */ +public interface SmsService { + + /** + * 发送验证码短信 + * @param phone 手机号码 + * @param VerificationCode 验证码 + */ + void sendVerificationCodeSms(String phone, String VerificationCode) ; +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/sms/service/imp/ALiYunSmsService.java b/main/manager-api/src/main/java/xiaozhi/modules/sms/service/imp/ALiYunSmsService.java new file mode 100644 index 00000000..0a73bf68 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/sms/service/imp/ALiYunSmsService.java @@ -0,0 +1,76 @@ +package xiaozhi.modules.sms.service.imp; + +import com.aliyun.dysmsapi20170525.Client; +import com.aliyun.dysmsapi20170525.models.SendSmsRequest; +import com.aliyun.dysmsapi20170525.models.SendSmsResponse; +import com.aliyun.tea.TeaException; +import com.aliyun.teaopenapi.models.Config; +import com.aliyun.teautil.Common; +import com.aliyun.teautil.models.RuntimeOptions; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import xiaozhi.common.constant.Constant; +import xiaozhi.modules.sms.service.SmsService; +import xiaozhi.modules.sys.service.SysParamsService; + +@Service +@AllArgsConstructor +@Slf4j +public class ALiYunSmsService implements SmsService { + private final SysParamsService sysParamsService; + + @Override + public void sendVerificationCodeSms(String phone, String VerificationCode) { + String SignName = sysParamsService.getValue(Constant.SysMSMParam + .ALIYUN_SMS_SIGN_NAME.getValue(),true); + String TemplateCode = sysParamsService.getValue(Constant.SysMSMParam + .ALIYUN_SMS_SMS_CODE_TEMPLATE_CODE.getValue(),true); + try { + Client client = createClient(); + SendSmsRequest sendSmsRequest = new SendSmsRequest() + .setSignName(SignName) + .setTemplateCode(TemplateCode) + .setPhoneNumbers(phone) + .setTemplateParam(String.format("{\"code\":\"%s\"}", VerificationCode)); + RuntimeOptions runtime = new RuntimeOptions(); + try { + // 复制代码运行请自行打印 API 的返回值 + SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime); + System.out.println(sendSmsResponse.getBody().getRequestId()); + System.out.println(sendSmsResponse.getBody().getRequestId()); + } catch (TeaException error) { + // 错误 message + log.error(error.getMessage()); + // 诊断地址 + log.error(error.getData().get("Recommend").toString()); + log.error(Common.assertAsString(error.message)); + } + } catch (Exception e) { + // 错误 message + log.error(e.getMessage()); + throw new RuntimeException(e); + } + + } + + + /** + * 创建阿里云连接 + * @return 返回连接对象 + * @throws Exception + */ + private Client createClient() throws Exception { + String ACCESS_KEY_ID = sysParamsService.getValue(Constant.SysMSMParam + .ALIYUN_SMS_ACCESS_KEY_ID.getValue(),true); + String ACCESS_KEY_SECRET = sysParamsService.getValue(Constant.SysMSMParam + .ALIYUN_SMS_ACCESS_KEY_SECRET.getValue(),true); + Config config = new Config() + .setAccessKeyId(ACCESS_KEY_ID) + .setAccessKeySecret(ACCESS_KEY_SECRET); + // 配置 Endpoint。中国站请使用dysmsapi.aliyuncs.com + config.endpoint = "dysmsapi.aliyuncs.com"; + + return new Client(config); + } +} From 0509ddb1292d515a6428c5f15fa87dffdd2543a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=89=91=E9=9B=A8?= <2375294554@qq.com> Date: Thu, 15 May 2025 21:45:33 +0800 Subject: [PATCH 03/58] =?UTF-8?q?=E9=AA=8C=E8=AF=81=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8F=91=E9=80=81=E7=9F=AD=E4=BF=A1=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81=E5=92=8C=E9=AA=8C=E8=AF=81=E7=9F=AD=E4=BF=A1?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E7=A0=81=20--CaptchaService.java=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=8F=91=E9=80=81=E7=9F=AD=E4=BF=A1=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E7=A0=81=E5=92=8C=E9=AA=8C=E8=AF=81=E7=9F=AD=E4=BF=A1=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81=E6=96=B9=E6=B3=95=E5=AE=9A=E4=B9=89=20--Capt?= =?UTF-8?q?chaServiceImpl.java=20=E5=AE=9E=E7=8E=B0=E6=96=B0=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=AE=9A=E4=B9=89=E7=9A=84=E6=96=B9=E6=B3=95=20--Redi?= =?UTF-8?q?sKeys.java=20=E6=B7=BB=E5=8A=A0=E7=9F=AD=E4=BF=A1=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81key?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/xiaozhi/common/redis/RedisKeys.java | 8 +++++ .../security/service/CaptchaService.java | 13 +++++++- .../service/impl/CaptchaServiceImpl.java | 33 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/main/manager-api/src/main/java/xiaozhi/common/redis/RedisKeys.java b/main/manager-api/src/main/java/xiaozhi/common/redis/RedisKeys.java index 62487456..cc56e0ee 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/redis/RedisKeys.java +++ b/main/manager-api/src/main/java/xiaozhi/common/redis/RedisKeys.java @@ -117,4 +117,12 @@ public class RedisKeys { public static String getAgentAudioIdKey(String uuid) { return "agent:audio:id:" + uuid; } + + /** + * 获取短信验证码的缓存key + */ + public static String getSMSValidateCodeKey(String phone) { + return "sms:Validate:Code:" + phone; + } + } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/service/CaptchaService.java b/main/manager-api/src/main/java/xiaozhi/modules/security/service/CaptchaService.java index 9e5c153f..43ae6432 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/security/service/CaptchaService.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/security/service/CaptchaService.java @@ -18,10 +18,21 @@ public interface CaptchaService { /** * 验证码效验 - * * @param uuid uuid * @param code 验证码 * @return true:成功 false:失败 */ boolean validate(String uuid, String code); + + /** + * 发送短信验证码 + * @param phone 手机 + */ + void sendSMSValidateCode(String phone); + + /** + * 验证短信验证码 + * @param phone 手机 + */ + boolean validateSMSValidateCode(String phone,String code); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/service/impl/CaptchaServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/security/service/impl/CaptchaServiceImpl.java index 012b4d3e..f151d178 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/security/service/impl/CaptchaServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/security/service/impl/CaptchaServiceImpl.java @@ -1,6 +1,7 @@ package xiaozhi.modules.security.service.impl; import java.io.IOException; +import java.util.Random; import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.StringUtils; @@ -17,6 +18,7 @@ import jakarta.servlet.http.HttpServletResponse; import xiaozhi.common.redis.RedisKeys; import xiaozhi.common.redis.RedisUtils; import xiaozhi.modules.security.service.CaptchaService; +import xiaozhi.modules.sms.service.SmsService; /** * 验证码 @@ -25,6 +27,8 @@ import xiaozhi.modules.security.service.CaptchaService; public class CaptchaServiceImpl implements CaptchaService { @Resource private RedisUtils redisUtils; + @Resource + private SmsService smsService; @Value("${renren.redis.open}") private boolean open; /** @@ -66,6 +70,35 @@ public class CaptchaServiceImpl implements CaptchaService { return false; } + @Override + public void sendSMSValidateCode(String phone) { + String key = RedisKeys.getSMSValidateCodeKey(phone); + String validateCodes = generateValidateCode(6); + setCache(key,validateCodes); + //发送验证码短信 + smsService.sendVerificationCodeSms(phone,validateCodes); + } + + @Override + public boolean validateSMSValidateCode(String phone,String code) { + String key = RedisKeys.getSMSValidateCodeKey(phone); + return validate(key, code); + } + /** + * 生成指定数量的随机数验证码 + * @param length 数量 + * @return 随机码 + */ + private String generateValidateCode(Integer length) { + String chars = "0123456789"; // 字符范围可以自定义:数字 + Random random = new Random(); + StringBuilder code = new StringBuilder(); + for (int i = 0; i < length; i++) { + code.append(chars.charAt(random.nextInt(chars.length()))); + } + return code.toString(); + } + private void setCache(String key, String value) { if (open) { key = RedisKeys.getCaptchaKey(key); From aa251aa011b9608093dc64cef7a4597dc39b4d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=89=91=E9=9B=A8?= <2375294554@qq.com> Date: Thu, 15 May 2025 22:47:57 +0800 Subject: [PATCH 04/58] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E5=8D=95=E5=8F=82=E6=95=B0=E6=98=AF=E5=90=A6=E6=98=AF=E6=AD=A3?= =?UTF-8?q?=E7=A1=AE=E7=9A=84=E6=89=8B=E6=9C=BA=E5=8F=B7=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E6=B3=95=20--ValidatorUtils.java=20=E6=B7=BB=E5=8A=A0=E6=96=B0?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/validator/ValidatorUtils.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/main/manager-api/src/main/java/xiaozhi/common/validator/ValidatorUtils.java b/main/manager-api/src/main/java/xiaozhi/common/validator/ValidatorUtils.java index 9e31c964..b2e5b296 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/validator/ValidatorUtils.java +++ b/main/manager-api/src/main/java/xiaozhi/common/validator/ValidatorUtils.java @@ -2,6 +2,8 @@ package xiaozhi.common.validator; import java.util.Locale; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; import org.springframework.context.i18n.LocaleContextHolder; @@ -45,4 +47,23 @@ public class ValidatorUtils { throw new RenException(constraint.getMessage()); } } + + /** + * 手机号正则表达式 + */ + private static final String PHONE_REGEX = "^1[3-9]\\d{9}$"; + + /** + * 校验单参数是否是正确的手机号 + * @param phone 手机号 + * @return boolean + */ + public static boolean isValidPhone(String phone) { + if (phone == null || phone.isEmpty()) { + return false; + } + Pattern pattern = Pattern.compile(PHONE_REGEX); + Matcher matcher = pattern.matcher(phone); + return matcher.matches(); + } } \ No newline at end of file From 2741e11078ccedd9ac925c7efd3ab053001f632c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=89=91=E9=9B=A8?= <2375294554@qq.com> Date: Fri, 16 May 2025 00:16:20 +0800 Subject: [PATCH 05/58] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8F=91=E9=80=81?= =?UTF-8?q?=E7=9F=AD=E4=BF=A1=E9=AA=8C=E8=AF=81=E7=A0=81=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E6=89=BE=E5=9B=9E=E5=AF=86=E7=A0=81=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E6=94=B9=E6=B3=A8=E5=86=8C=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E5=A6=82=E6=9E=9C=E5=BC=80=E5=90=AF=E6=89=8B=E6=9C=BA?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E6=A8=A1=E5=BC=8F=EF=BC=8C=E5=BC=80=E5=90=AF?= =?UTF-8?q?=E7=9F=AD=E4=BF=A1=E9=AA=8C=E8=AF=81=E6=A8=A1=E5=BC=8F=20--Logi?= =?UTF-8?q?nController.java=20=E6=B7=BB=E5=8A=A0=E5=92=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=96=B9=E6=B3=95=20--RetrievePasswordDTO.java=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=89=BE=E5=9B=9E=E5=AF=86=E7=A0=81dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../security/controller/LoginController.java | 69 +++++++++++++++++-- .../modules/sys/dto/RetrievePasswordDTO.java | 30 ++++++++ 2 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/sys/dto/RetrievePasswordDTO.java diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/controller/LoginController.java b/main/manager-api/src/main/java/xiaozhi/modules/security/controller/LoginController.java index 7cbaa8af..7731caa0 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/security/controller/LoginController.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/security/controller/LoginController.java @@ -29,7 +29,9 @@ import xiaozhi.modules.security.service.CaptchaService; import xiaozhi.modules.security.service.SysUserTokenService; import xiaozhi.modules.security.user.SecurityUser; import xiaozhi.modules.sys.dto.PasswordDTO; +import xiaozhi.modules.sys.dto.RetrievePasswordDTO; import xiaozhi.modules.sys.dto.SysUserDTO; +import xiaozhi.modules.sys.service.SysParamsService; import xiaozhi.modules.sys.service.SysUserService; /** @@ -43,17 +45,26 @@ public class LoginController { private final SysUserService sysUserService; private final SysUserTokenService sysUserTokenService; private final CaptchaService captchaService; + private final SysParamsService sysParamsService; @GetMapping("/captcha") @Operation(summary = "验证码") public void captcha(HttpServletResponse response, String uuid) throws IOException { // uuid不能为空 AssertUtils.isBlank(uuid, ErrorCode.IDENTIFIER_NOT_NULL); - // 生成验证码 captchaService.create(response, uuid); } + @GetMapping("/smsVerification") + @Operation(summary = "短信验证码") + public void smsVerification(String phone) throws IOException { + // uuid不能为空 + AssertUtils.isBlank(phone, ErrorCode.IDENTIFIER_NOT_NULL); + // 发送短信验证码 + captchaService.sendSMSValidateCode(phone); + } + @PostMapping("/login") @Operation(summary = "登录") public Result login(@RequestBody LoginDTO login) { @@ -81,8 +92,23 @@ public class LoginController { if (!sysUserService.getAllowUserRegister()) { throw new RenException("当前不允许普通用户注册"); } - // 验证是否正确输入验证码 - boolean validate = captchaService.validate(login.getCaptchaId(), login.getCaptcha()); + // 是否开启手机注册 + Boolean isMobileRegister = sysParamsService.getValueObject(Constant.SysMSMParam + .SYSTEM_ENABLE_MOBILE_REGISTER.getValue(), Boolean.class); + boolean validate; + if (isMobileRegister) { + // 验证用户是否是手机号码 + boolean validPhone = ValidatorUtils.isValidPhone(login.getUsername()); + if (validPhone) { + throw new RenException("用户名不是手机号码,请重新输入"); + } + // 验证短信验证码是否正常 + validate = captchaService.validateSMSValidateCode(login.getUsername(),login.getCaptcha()); + } else { + // 验证是否正确输入验证码 + validate = captchaService.validate(login.getCaptchaId(), login.getCaptcha()); + } + // 判断是否通过验证 if (!validate) { throw new RenException("验证码错误,请重新获取"); } @@ -96,7 +122,6 @@ public class LoginController { userDTO.setPassword(login.getPassword()); sysUserService.save(userDTO); return new Result<>(); - } @GetMapping("/info") @@ -118,6 +143,42 @@ public class LoginController { return new Result<>(); } + @PutMapping("/retrieve-password") + @Operation(summary = "找回密码") + public Result retrievePassword(@RequestBody RetrievePasswordDTO dto) { + // 是否开启手机注册 + Boolean isMobileRegister = sysParamsService.getValueObject(Constant.SysMSMParam + .SYSTEM_ENABLE_MOBILE_REGISTER.getValue(), Boolean.class); + if (!isMobileRegister) { + throw new RenException("没有开启手机注册,没法使用找回密码功能"); + } + // 判断非空 + ValidatorUtils.validateEntity(dto); + // 验证用户是否是手机号码 + boolean validPhone = ValidatorUtils.isValidPhone(dto.getPhone()); + if (validPhone) { + throw new RenException("用户名不是手机号码,请重新输入"); + }; + + // 按照用户名获取用户 + SysUserDTO userDTO = sysUserService.getByUsername(dto.getPhone()); + if (userDTO == null) { + throw new RenException("用户名或验证码错误"); + } + // 验证用户是否是手机号码 + ValidatorUtils.isValidPhone(dto.getPhone()); + // 验证短信验证码是否正常 + boolean validate = captchaService.validateSMSValidateCode(dto.getPhone(),dto.getCode()); + // 判断是否通过验证 + if (!validate) { + throw new RenException("用户名或验证码错误"); + } + + Long userId = SecurityUser.getUserId(); + sysUserService.changePasswordDirectly(userId, dto.getPassword()); + return new Result<>(); + } + @GetMapping("/pub-config") @Operation(summary = "公共配置") public Result> pubConfig() { diff --git a/main/manager-api/src/main/java/xiaozhi/modules/sys/dto/RetrievePasswordDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/sys/dto/RetrievePasswordDTO.java new file mode 100644 index 00000000..efac8099 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/sys/dto/RetrievePasswordDTO.java @@ -0,0 +1,30 @@ +package xiaozhi.modules.sys.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +import java.io.Serializable; + +/** + * 找回密码DTO + */ +@Data +@Schema(description = "找回密码") +public class RetrievePasswordDTO implements Serializable { + + @Schema(description = "手机号码") + @NotBlank(message = "{sysuser.password.require}") + private String phone; + + @Schema(description = "验证码") + @NotBlank(message = "{sysuser.password.require}") + private String code; + + @Schema(description = "新密码") + @NotBlank(message = "{sysuser.password.require}") + private String password; + + + +} \ No newline at end of file From c51c8b4af0cf0affa397f3b97bb898b22fb0f266 Mon Sep 17 00:00:00 2001 From: ljwwd2 <1205484020@qq.com> Date: Fri, 16 May 2025 01:42:19 +0800 Subject: [PATCH 06/58] =?UTF-8?q?=E4=BE=9B=E5=BA=94=E5=99=A8=E7=AE=A1?= =?UTF-8?q?=E7=90=86-=E5=A2=9E=E5=88=A0=E6=94=B9=E6=9F=A5api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/annotation/CreateGroup.java | 13 +++++ .../common/annotation/UpdateGroup.java | 13 +++++ .../common/exception/RenExceptionHandler.java | 17 ++++++ .../controller/ModelProviderController.java | 57 +++++++++++++++++++ .../modules/model/dto/ModelProviderDTO.java | 13 ++++- .../model/service/ModelProviderService.java | 10 ++-- .../impl/ModelProviderServiceImpl.java | 55 ++++++++++++++++-- 7 files changed, 167 insertions(+), 11 deletions(-) create mode 100644 main/manager-api/src/main/java/xiaozhi/common/annotation/CreateGroup.java create mode 100644 main/manager-api/src/main/java/xiaozhi/common/annotation/UpdateGroup.java create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelProviderController.java diff --git a/main/manager-api/src/main/java/xiaozhi/common/annotation/CreateGroup.java b/main/manager-api/src/main/java/xiaozhi/common/annotation/CreateGroup.java new file mode 100644 index 00000000..7864ec3f --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/common/annotation/CreateGroup.java @@ -0,0 +1,13 @@ +package xiaozhi.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface CreateGroup { + // 可以定义一些元数据或者参数 +} + diff --git a/main/manager-api/src/main/java/xiaozhi/common/annotation/UpdateGroup.java b/main/manager-api/src/main/java/xiaozhi/common/annotation/UpdateGroup.java new file mode 100644 index 00000000..ce168f99 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/common/annotation/UpdateGroup.java @@ -0,0 +1,13 @@ +package xiaozhi.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface UpdateGroup { + // 可以定义一些元数据或者参数 +} + diff --git a/main/manager-api/src/main/java/xiaozhi/common/exception/RenExceptionHandler.java b/main/manager-api/src/main/java/xiaozhi/common/exception/RenExceptionHandler.java index 0d0aa118..df9023ae 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/exception/RenExceptionHandler.java +++ b/main/manager-api/src/main/java/xiaozhi/common/exception/RenExceptionHandler.java @@ -1,7 +1,10 @@ package xiaozhi.common.exception; import org.apache.shiro.authz.UnauthorizedException; +import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.dao.DuplicateKeyException; +import org.springframework.validation.ObjectError; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.resource.NoResourceFoundException; @@ -10,6 +13,8 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import xiaozhi.common.utils.Result; +import java.util.List; +import java.util.Objects; /** * 异常处理器 * Copyright (c) 人人开源 All rights reserved. @@ -60,4 +65,16 @@ public class RenExceptionHandler { return new Result().error(404, "资源不存在"); } + @ExceptionHandler(MethodArgumentNotValidException.class) + public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) { + StringBuilder sb = new StringBuilder(); + List allErrors = ex.getBindingResult().getAllErrors(); + String errorMsg = allErrors.stream() + .filter(Objects::nonNull) + .map(DefaultMessageSourceResolvable::getDefaultMessage) + .findFirst() + .orElse(""); + return new Result().error(400, errorMsg); + } + } \ No newline at end of file diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelProviderController.java b/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelProviderController.java new file mode 100644 index 00000000..5c6c3904 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelProviderController.java @@ -0,0 +1,57 @@ +package xiaozhi.modules.model.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.AllArgsConstructor; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import xiaozhi.common.annotation.UpdateGroup; +import xiaozhi.common.page.PageData; +import xiaozhi.common.utils.Result; +import xiaozhi.modules.model.dto.ModelProviderDTO; +import xiaozhi.modules.model.service.ModelProviderService; + +@AllArgsConstructor +@RestController +@RequestMapping("/models/provider") +@Tag(name = "模型配置") +public class ModelProviderController { + + private final ModelProviderService modelProviderService; + + @GetMapping + @Operation(summary = "获取模型配置列表") + @RequiresPermissions("sys:role:superAdmin") + public Result> getListPage(@RequestBody ModelProviderDTO modelProviderDTO, + @RequestParam(required = true, defaultValue = "0") String page, + @RequestParam(required = true, defaultValue = "10") String limit) { + return new Result>() + .ok(modelProviderService.getListPage(modelProviderDTO, page, limit)); + } + + @PostMapping + @Operation(summary = "获取模型配置列表") + @RequiresPermissions("sys:role:superAdmin") + public Result add(@RequestBody @Validated ModelProviderDTO modelProviderDTO) { + ModelProviderDTO resp = modelProviderService.add(modelProviderDTO); + return new Result().ok(resp); + } + + @PutMapping + @Operation(summary = "获取模型配置列表") + @RequiresPermissions("sys:role:superAdmin") + public Result edit(@RequestBody @Validated(UpdateGroup.class) ModelProviderDTO modelProviderDTO) { + ModelProviderDTO resp = modelProviderService.edit(modelProviderDTO); + return new Result().ok(resp); + } + + @DeleteMapping("/{id}") + @Operation(summary = "获取模型配置列表") + @RequiresPermissions("sys:role:superAdmin") + public Result delete(@PathVariable String id) { + modelProviderService.delete(id); + return new Result<>(); + } + +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelProviderDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelProviderDTO.java index 605ed13a..fdb33960 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelProviderDTO.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelProviderDTO.java @@ -8,29 +8,38 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Data; +import xiaozhi.common.annotation.UpdateGroup; @Data @Schema(description = "模型供应器/商") public class ModelProviderDTO implements Serializable { // - // @Schema(description = "主键") - // private Long id; + @Schema(description = "主键") + @NotBlank(message = "id不能为空", groups = UpdateGroup.class) + private String id; @Schema(description = "模型类型(Memory/ASR/VAD/LLM/TTS)") + @NotBlank(message = "modelType不能为空") private String modelType; @Schema(description = "供应器类型") + @NotBlank(message = "providerCode不能为空") private String providerCode; @Schema(description = "供应器名称") + @NotBlank(message = "name不能为空") private String name; @Schema(description = "供应器字段列表(JSON格式)") @TableField(typeHandler = JacksonTypeHandler.class) + @NotBlank(message = "fields(JSON格式)不能为空") private String fields; @Schema(description = "排序") + @NotNull(message = "sort不能为空") private Integer sort; @Schema(description = "更新者") diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelProviderService.java b/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelProviderService.java index 2ace101e..fbb009fd 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelProviderService.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelProviderService.java @@ -2,8 +2,8 @@ package xiaozhi.modules.model.service; import java.util.List; +import xiaozhi.common.page.PageData; import xiaozhi.modules.model.dto.ModelProviderDTO; -import xiaozhi.modules.model.entity.ModelProviderEntity; public interface ModelProviderService { @@ -11,11 +11,13 @@ public interface ModelProviderService { List getListByModelType(String modelType); - ModelProviderDTO add(ModelProviderEntity modelProviderEntity); + ModelProviderDTO add(ModelProviderDTO modelProviderDTO); - ModelProviderDTO edit(ModelProviderEntity modelProviderEntity); + ModelProviderDTO edit(ModelProviderDTO modelProviderDTO); - void delete(); + void delete(String id); + + PageData getListPage(ModelProviderDTO modelProviderDTO, String page, String limit); List getList(String modelType, String provideCode); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java index fb06e4d5..4222b108 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java @@ -1,19 +1,28 @@ package xiaozhi.modules.model.service.impl; +import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import com.baomidou.mybatisplus.core.metadata.IPage; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import lombok.AllArgsConstructor; +import xiaozhi.common.constant.Constant; +import xiaozhi.common.exception.RenException; +import xiaozhi.common.page.PageData; import xiaozhi.common.service.impl.BaseServiceImpl; +import xiaozhi.common.user.UserDetail; import xiaozhi.common.utils.ConvertUtils; import xiaozhi.modules.model.dao.ModelProviderDao; import xiaozhi.modules.model.dto.ModelProviderDTO; import xiaozhi.modules.model.entity.ModelProviderEntity; import xiaozhi.modules.model.service.ModelProviderService; +import xiaozhi.modules.security.user.SecurityUser; @Service @AllArgsConstructor @@ -32,18 +41,54 @@ public class ModelProviderServiceImpl extends BaseServiceImpl getListPage(ModelProviderDTO modelProviderEntity, String page, String limit) { + + Map params = new HashMap(); + params.put(Constant.PAGE, page); + params.put(Constant.LIMIT, limit); + + IPage pageParam = getPage(params, "model_type", true); + + QueryWrapper wrapper = new QueryWrapper(); + + if (StringUtils.isNotBlank(modelProviderEntity.getModelType())) { + wrapper.eq("model_type", modelProviderEntity.getModelType()); + } + + if (StringUtils.isNotBlank(modelProviderEntity.getName())) { + wrapper.like("name", "%" + modelProviderEntity.getName() + "%"); + } + return getPageData(modelProviderDao.selectPage(pageParam, wrapper), ModelProviderDTO.class); } @Override - public ModelProviderDTO edit(ModelProviderEntity modelProviderEntity) { - return null; + public ModelProviderDTO add(ModelProviderDTO modelProviderEntity) { + UserDetail user = SecurityUser.getUser(); + modelProviderEntity.setCreator(user.getId()); + modelProviderEntity.setUpdater(user.getId()); + modelProviderEntity.setCreateDate(new Date()); + modelProviderEntity.setUpdateDate(new Date()); + if (modelProviderDao.insert(ConvertUtils.sourceToTarget(modelProviderEntity, ModelProviderEntity.class)) == 0) { + throw new RenException("新增数据失败"); + } + + return ConvertUtils.sourceToTarget(modelProviderEntity, ModelProviderDTO.class); } @Override - public void delete() { + public ModelProviderDTO edit(ModelProviderDTO modelProviderEntity) { + UserDetail user = SecurityUser.getUser(); + modelProviderEntity.setUpdater(user.getId()); + modelProviderEntity.setUpdateDate(new Date()); + if (modelProviderDao.updateById(ConvertUtils.sourceToTarget(modelProviderEntity, ModelProviderEntity.class)) == 0) { + throw new RenException("修改数据失败"); + } + return ConvertUtils.sourceToTarget(modelProviderEntity, ModelProviderDTO.class); + } + @Override + public void delete(String id) { + modelProviderDao.deleteById(id); } @Override From cbabf01902dc8e30030dbad00212ac02c6262f84 Mon Sep 17 00:00:00 2001 From: ljwwd2 <1205484020@qq.com> Date: Fri, 16 May 2025 03:04:52 +0800 Subject: [PATCH 07/58] =?UTF-8?q?=E4=BE=9B=E5=BA=94=E5=99=A8=E7=AE=A1?= =?UTF-8?q?=E7=90=86-=E5=A2=9E=E5=88=A0=E6=94=B9=E6=9F=A5api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/controller/ModelProviderController.java | 12 ++++++------ .../model/service/impl/ModelProviderServiceImpl.java | 4 +++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelProviderController.java b/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelProviderController.java index 5c6c3904..b296c240 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelProviderController.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelProviderController.java @@ -15,15 +15,15 @@ import xiaozhi.modules.model.service.ModelProviderService; @AllArgsConstructor @RestController @RequestMapping("/models/provider") -@Tag(name = "模型配置") +@Tag(name = "模型供应器") public class ModelProviderController { private final ModelProviderService modelProviderService; @GetMapping - @Operation(summary = "获取模型配置列表") + @Operation(summary = "获取模型供应器列表") @RequiresPermissions("sys:role:superAdmin") - public Result> getListPage(@RequestBody ModelProviderDTO modelProviderDTO, + public Result> getListPage(ModelProviderDTO modelProviderDTO, @RequestParam(required = true, defaultValue = "0") String page, @RequestParam(required = true, defaultValue = "10") String limit) { return new Result>() @@ -31,7 +31,7 @@ public class ModelProviderController { } @PostMapping - @Operation(summary = "获取模型配置列表") + @Operation(summary = "获取模型供应器列表") @RequiresPermissions("sys:role:superAdmin") public Result add(@RequestBody @Validated ModelProviderDTO modelProviderDTO) { ModelProviderDTO resp = modelProviderService.add(modelProviderDTO); @@ -39,7 +39,7 @@ public class ModelProviderController { } @PutMapping - @Operation(summary = "获取模型配置列表") + @Operation(summary = "获取模型供应器列表") @RequiresPermissions("sys:role:superAdmin") public Result edit(@RequestBody @Validated(UpdateGroup.class) ModelProviderDTO modelProviderDTO) { ModelProviderDTO resp = modelProviderService.edit(modelProviderDTO); @@ -47,7 +47,7 @@ public class ModelProviderController { } @DeleteMapping("/{id}") - @Operation(summary = "获取模型配置列表") + @Operation(summary = "获取模型供应器列表") @RequiresPermissions("sys:role:superAdmin") public Result delete(@PathVariable String id) { modelProviderService.delete(id); diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java index 4222b108..90f69f32 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java @@ -88,7 +88,9 @@ public class ModelProviderServiceImpl extends BaseServiceImpl Date: Fri, 16 May 2025 12:28:32 +0800 Subject: [PATCH 08/58] =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E7=9A=84=E6=90=9C=E7=B4=A2=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=A8=A1=E7=B3=8A=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xiaozhi/modules/sys/service/impl/SysUserServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/manager-api/src/main/java/xiaozhi/modules/sys/service/impl/SysUserServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/sys/service/impl/SysUserServiceImpl.java index 97944ba9..54048fe0 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/sys/service/impl/SysUserServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/sys/service/impl/SysUserServiceImpl.java @@ -159,7 +159,7 @@ public class SysUserServiceImpl extends BaseServiceImpl page = baseDao.selectPage( getPage(params, "id", true), - new QueryWrapper().eq(StringUtils.isNotBlank(dto.getMobile()), "username", + new QueryWrapper().like(StringUtils.isNotBlank(dto.getMobile()), "username", dto.getMobile())); // 循环处理page获取回来的数据,返回需要的字段 List list = page.getRecords().stream().map(user -> { From bdd8597f696494c0de82c606b652682ae5805c1b Mon Sep 17 00:00:00 2001 From: CGD <3030332422@qq.com> Date: Fri, 16 May 2025 14:33:37 +0800 Subject: [PATCH 09/58] =?UTF-8?q?update:=E5=9C=A8=E8=AF=86=E5=88=AB?= =?UTF-8?q?=E5=88=B0continue=5Fchat=E6=84=8F=E5=9B=BE=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E6=B8=85=E7=90=86=E5=AF=B9=E8=AF=9D=E5=8E=86=E5=8F=B2=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E5=B7=A5=E5=85=B7=E8=B0=83=E7=94=A8=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/providers/intent/intent_llm/intent_llm.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py b/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py index 195d058a..2a3e023f 100644 --- a/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py +++ b/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py @@ -218,6 +218,15 @@ class IntentProvider(IntentProviderBase): f"llm 识别到意图: {function_name}, 参数: {function_args}" ) + # 如果是继续聊天,清理工具调用相关的历史消息 + if function_name == "continue_chat": + # 保留非工具相关的消息 + clean_history = [ + msg for msg in conn.dialogue.dialogue + if msg.role not in ["tool", "function"] + ] + conn.dialogue.dialogue = clean_history + # 添加到缓存 self.intent_cache[cache_key] = { "intent": intent, From 76c3f401eac993c03437c66d45d635313043d300 Mon Sep 17 00:00:00 2001 From: Sakura-RanChen <1908198662@qq.com> Date: Fri, 16 May 2025 14:55:53 +0800 Subject: [PATCH 10/58] =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/manager-web/src/views/ProviderManagement.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/manager-web/src/views/ProviderManagement.vue b/main/manager-web/src/views/ProviderManagement.vue index f047f482..38f4ca36 100644 --- a/main/manager-web/src/views/ProviderManagement.vue +++ b/main/manager-web/src/views/ProviderManagement.vue @@ -24,7 +24,7 @@
- + Date: Fri, 16 May 2025 17:10:55 +0800 Subject: [PATCH 11/58] Update 202504112044.sql MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix:修复智控台fish-speech无法按声音播放bug --- .../src/main/resources/db/changelog/202504112044.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/manager-api/src/main/resources/db/changelog/202504112044.sql b/main/manager-api/src/main/resources/db/changelog/202504112044.sql index 9fd2257d..df00d3b8 100644 --- a/main/manager-api/src/main/resources/db/changelog/202504112044.sql +++ b/main/manager-api/src/main/resources/db/changelog/202504112044.sql @@ -32,7 +32,7 @@ INSERT INTO `ai_model_config` VALUES ('TTS_EdgeTTS', 'TTS', 'EdgeTTS', 'Edge语 INSERT INTO `ai_model_config` VALUES ('TTS_DoubaoTTS', 'TTS', 'DoubaoTTS', '豆包语音合成', 0, 1, '{\"type\": \"doubao\", \"api_url\": \"https://openspeech.bytedance.com/api/v1/tts\", \"voice\": \"BV001_streaming\", \"output_dir\": \"tmp/\", \"authorization\": \"Bearer;\", \"appid\": \"\", \"access_token\": \"\", \"cluster\": \"volcano_tts\"}', NULL, NULL, 2, NULL, NULL, NULL, NULL); INSERT INTO `ai_model_config` VALUES ('TTS_CosyVoiceSiliconflow', 'TTS', 'CosyVoiceSiliconflow', '硅基流动语音合成', 0, 1, '{\"type\": \"siliconflow\", \"model\": \"FunAudioLLM/CosyVoice2-0.5B\", \"voice\": \"FunAudioLLM/CosyVoice2-0.5B:alex\", \"output_dir\": \"tmp/\", \"access_token\": \"\", \"response_format\": \"wav\"}', NULL, NULL, 3, NULL, NULL, NULL, NULL); INSERT INTO `ai_model_config` VALUES ('TTS_CozeCnTTS', 'TTS', 'CozeCnTTS', 'Coze中文语音合成', 0, 1, '{\"type\": \"cozecn\", \"voice\": \"7426720361733046281\", \"output_dir\": \"tmp/\", \"access_token\": \"\", \"response_format\": \"wav\"}', NULL, NULL, 4, NULL, NULL, NULL, NULL); -INSERT INTO `ai_model_config` VALUES ('TTS_FishSpeech', 'TTS', 'FishSpeech', 'FishSpeech语音合成', 0, 1, '{\"type\": \"fishspeech\", \"output_dir\": \"tmp/\", \"response_format\": \"wav\", \"reference_id\": null, \"reference_audio\": [\"/tmp/test.wav\"], \"reference_text\": [\"你弄来这些吟词宴曲来看,还是这些混话来欺负我。\"], \"normalize\": true, \"max_new_tokens\": 1024, \"chunk_length\": 200, \"top_p\": 0.7, \"repetition_penalty\": 1.2, \"temperature\": 0.7, \"streaming\": false, \"use_memory_cache\": \"on\", \"seed\": null, \"channels\": 1, \"rate\": 44100, \"api_key\": \"\", \"api_url\": \"http://127.0.0.1:8080/v1/tts\"}', NULL, NULL, 5, NULL, NULL, NULL, NULL); +INSERT INTO `ai_model_config` VALUES ('TTS_FishSpeech', 'TTS', 'FishSpeech', 'FishSpeech语音合成', 0, 1, '{\"type\": \"fishspeech\", \"output_dir\": \"tmp/\", \"response_format\": \"wav\", \"reference_id\": null, \"reference_audio\": [\"/tmp/test.wav\"], \"reference_text\": [\"你弄来这些吟词宴曲来看,还是这些混话来欺负我。\"], \"normalize\": true, \"max_new_tokens\": 1024, \"chunk_length\": 200, \"top_p\": 0.7, \"repetition_penalty\": 1.2, \"temperature\": 0.7, \"streaming\": false, \"use_memory_cache\": \"on\", \"seed\": 1, \"channels\": 1, \"rate\": 44100, \"api_key\": \"\", \"api_url\": \"http://127.0.0.1:8080/v1/tts\"}', NULL, NULL, 5, NULL, NULL, NULL, NULL); INSERT INTO `ai_model_config` VALUES ('TTS_GPT_SOVITS_V2', 'TTS', 'GPT_SOVITS_V2', 'GPT-SoVITS V2', 0, 1, '{\"type\": \"gpt_sovits_v2\", \"url\": \"http://127.0.0.1:9880/tts\", \"output_dir\": \"tmp/\", \"text_lang\": \"auto\", \"ref_audio_path\": \"caixukun.wav\", \"prompt_text\": \"\", \"prompt_lang\": \"zh\", \"top_k\": 5, \"top_p\": 1, \"temperature\": 1, \"text_split_method\": \"cut0\", \"batch_size\": 1, \"batch_threshold\": 0.75, \"split_bucket\": true, \"return_fragment\": false, \"speed_factor\": 1.0, \"streaming_mode\": false, \"seed\": -1, \"parallel_infer\": true, \"repetition_penalty\": 1.35, \"aux_ref_audio_paths\": []}', NULL, NULL, 6, NULL, NULL, NULL, NULL); INSERT INTO `ai_model_config` VALUES ('TTS_GPT_SOVITS_V3', 'TTS', 'GPT_SOVITS_V3', 'GPT-SoVITS V3', 0, 1, '{\"type\": \"gpt_sovits_v3\", \"url\": \"http://127.0.0.1:9880\", \"output_dir\": \"tmp/\", \"text_language\": \"auto\", \"refer_wav_path\": \"caixukun.wav\", \"prompt_language\": \"zh\", \"prompt_text\": \"\", \"top_k\": 15, \"top_p\": 1.0, \"temperature\": 1.0, \"cut_punc\": \"\", \"speed\": 1.0, \"inp_refs\": [], \"sample_steps\": 32, \"if_sr\": false}', NULL, NULL, 7, NULL, NULL, NULL, NULL); INSERT INTO `ai_model_config` VALUES ('TTS_MinimaxTTS', 'TTS', 'MinimaxTTS', 'MiniMax语音合成', 0, 1, '{\"type\": \"minimax\", \"output_dir\": \"tmp/\", \"group_id\": \"\", \"api_key\": \"你的api_key\", \"model\": \"speech-01-turbo\", \"voice_id\": \"female-shaonv\"}', NULL, NULL, 8, NULL, NULL, NULL, NULL); From ae8f11d5a82bd092d46a3aaf186650e8a876e9b0 Mon Sep 17 00:00:00 2001 From: ljwwd2 <1205484020@qq.com> Date: Sat, 17 May 2025 01:18:03 +0800 Subject: [PATCH 12/58] =?UTF-8?q?=E4=BE=9B=E5=BA=94=E5=99=A8=E7=AE=A1?= =?UTF-8?q?=E7=90=86-=E5=A2=9E=E5=88=A0=E6=94=B9=E6=9F=A5api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/service/impl/BaseServiceImpl.java | 55 +++++++++++++++ .../controller/ModelProviderController.java | 31 ++++++--- .../model/entity/ModelProviderEntity.java | 2 +- .../model/service/ModelProviderService.java | 2 + .../impl/ModelProviderServiceImpl.java | 68 ++++++++++++------- 5 files changed, 123 insertions(+), 35 deletions(-) diff --git a/main/manager-api/src/main/java/xiaozhi/common/service/impl/BaseServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/common/service/impl/BaseServiceImpl.java index 9d2ba5d5..49a003cb 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/service/impl/BaseServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/common/service/impl/BaseServiceImpl.java @@ -1,6 +1,7 @@ package xiaozhi.common.service.impl; import java.io.Serializable; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -18,6 +19,7 @@ import com.baomidou.mybatisplus.core.enums.SqlMethod; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Constants; import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; import com.baomidou.mybatisplus.core.toolkit.StringUtils; @@ -92,6 +94,59 @@ public abstract class BaseServiceImpl, T> implements Bas return page; } + /** + * 获取分页对象 + * @see xiaozhi.common.constant.Constant + * params.put(Constant.PAGE, "1"); + * params.put(Constant.LIMIT, "10"); + * params.put(Constant.ORDER_FIELD, List.of("model_type", "sort")); + * params.put(Constant.ORDER, "asc"); + * + * @param params 分页查询参数 + */ + protected IPage getPage(Map params) { + // 分页参数 + long curPage = 1; + long limit = 10; + + if (params.get(Constant.PAGE) != null) { + curPage = Long.parseLong((String) params.get(Constant.PAGE)); + } + + if (params.get(Constant.LIMIT) != null) { + limit = Long.parseLong((String) params.get(Constant.LIMIT)); + } + + // 分页对象 + Page page = new Page<>(curPage, limit); + + // 分页参数 + params.put(Constant.PAGE, page); + + // 排序字段 + Object orderField = params.get(Constant.ORDER_FIELD); + + List orderFields = new ArrayList<>(); + + if (orderField instanceof String) { + orderFields.add((String) orderField); + } else if (orderField instanceof List) { + orderFields.addAll( (List) orderField); + } + String order = (String) params.get(Constant.ORDER); + + // 有排序字段则排序,默认降序 + if (CollectionUtils.isNotEmpty(orderFields)) { + if (StringUtils.isNotBlank(order) && Constant.ASC.equalsIgnoreCase(order)) { + return page.addOrder(OrderItem.ascs(orderFields.toArray(new String[orderFields.size()]))); + } else { + return page.addOrder(OrderItem.descs(orderFields.toArray(new String[orderFields.size()]))); + } + } + + return page; + } + protected PageData getPageData(List list, long total, Class target) { List targetList = ConvertUtils.sourceToTarget(list, target); diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelProviderController.java b/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelProviderController.java index b296c240..64e14cb3 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelProviderController.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelProviderController.java @@ -1,11 +1,21 @@ package xiaozhi.modules.model.controller; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.AllArgsConstructor; +import java.util.List; + import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.AllArgsConstructor; import xiaozhi.common.annotation.UpdateGroup; import xiaozhi.common.page.PageData; import xiaozhi.common.utils.Result; @@ -31,7 +41,7 @@ public class ModelProviderController { } @PostMapping - @Operation(summary = "获取模型供应器列表") + @Operation(summary = "新增模型供应器") @RequiresPermissions("sys:role:superAdmin") public Result add(@RequestBody @Validated ModelProviderDTO modelProviderDTO) { ModelProviderDTO resp = modelProviderService.add(modelProviderDTO); @@ -39,18 +49,19 @@ public class ModelProviderController { } @PutMapping - @Operation(summary = "获取模型供应器列表") + @Operation(summary = "修改模型供应器") @RequiresPermissions("sys:role:superAdmin") public Result edit(@RequestBody @Validated(UpdateGroup.class) ModelProviderDTO modelProviderDTO) { ModelProviderDTO resp = modelProviderService.edit(modelProviderDTO); return new Result().ok(resp); } - @DeleteMapping("/{id}") - @Operation(summary = "获取模型供应器列表") + @PostMapping("/delete") + @Operation(summary = "删除模型供应器") @RequiresPermissions("sys:role:superAdmin") - public Result delete(@PathVariable String id) { - modelProviderService.delete(id); + @Parameter(name = "ids", description = "ID数组", required = true) + public Result delete(@RequestBody List ids) { + modelProviderService.delete(ids); return new Result<>(); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/entity/ModelProviderEntity.java b/main/manager-api/src/main/java/xiaozhi/modules/model/entity/ModelProviderEntity.java index 62e84f67..0509e09c 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/model/entity/ModelProviderEntity.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/entity/ModelProviderEntity.java @@ -30,7 +30,7 @@ public class ModelProviderEntity { private String name; @Schema(description = "供应器字段列表(JSON格式)") - @TableField(typeHandler = JacksonTypeHandler.class) +// @TableField(typeHandler = JacksonTypeHandler.class) private String fields; @Schema(description = "排序") diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelProviderService.java b/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelProviderService.java index fbb009fd..d41766f6 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelProviderService.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelProviderService.java @@ -17,6 +17,8 @@ public interface ModelProviderService { void delete(String id); + void delete(List id); + PageData getListPage(ModelProviderDTO modelProviderDTO, String page, String limit); List getList(String modelType, String provideCode); diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java index 90f69f32..3ea21367 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java @@ -5,12 +5,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import com.baomidou.mybatisplus.core.metadata.IPage; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import cn.hutool.json.JSONArray; import lombok.AllArgsConstructor; import xiaozhi.common.constant.Constant; import xiaozhi.common.exception.RenException; @@ -41,49 +42,61 @@ public class ModelProviderServiceImpl extends BaseServiceImpl getListPage(ModelProviderDTO modelProviderEntity, String page, String limit) { + public PageData getListPage(ModelProviderDTO modelProviderDTO, String page, String limit) { Map params = new HashMap(); params.put(Constant.PAGE, page); params.put(Constant.LIMIT, limit); + params.put(Constant.ORDER_FIELD, List.of("model_type", "sort")); + params.put(Constant.ORDER, "asc"); - IPage pageParam = getPage(params, "model_type", true); + IPage pageParam = getPage(params); QueryWrapper wrapper = new QueryWrapper(); - if (StringUtils.isNotBlank(modelProviderEntity.getModelType())) { - wrapper.eq("model_type", modelProviderEntity.getModelType()); + if (StringUtils.isNotBlank(modelProviderDTO.getModelType())) { + wrapper.eq("model_type", modelProviderDTO.getModelType()); } - if (StringUtils.isNotBlank(modelProviderEntity.getName())) { - wrapper.like("name", "%" + modelProviderEntity.getName() + "%"); + if (StringUtils.isNotBlank(modelProviderDTO.getName())) { + wrapper.like("name", "%" + modelProviderDTO.getName() + "%"); } return getPageData(modelProviderDao.selectPage(pageParam, wrapper), ModelProviderDTO.class); } - @Override - public ModelProviderDTO add(ModelProviderDTO modelProviderEntity) { - UserDetail user = SecurityUser.getUser(); - modelProviderEntity.setCreator(user.getId()); - modelProviderEntity.setUpdater(user.getId()); - modelProviderEntity.setCreateDate(new Date()); - modelProviderEntity.setUpdateDate(new Date()); - if (modelProviderDao.insert(ConvertUtils.sourceToTarget(modelProviderEntity, ModelProviderEntity.class)) == 0) { - throw new RenException("新增数据失败"); - } - - return ConvertUtils.sourceToTarget(modelProviderEntity, ModelProviderDTO.class); + public static void main(String[] args) { + String jsonString = "\"[]\""; + JSONArray jsonArray = new JSONArray(jsonString); + System.out.println("字符串转 JSONArray: " + jsonArray.toString()); } @Override - public ModelProviderDTO edit(ModelProviderDTO modelProviderEntity) { + public ModelProviderDTO add(ModelProviderDTO modelProviderDTO) { UserDetail user = SecurityUser.getUser(); - modelProviderEntity.setUpdater(user.getId()); - modelProviderEntity.setUpdateDate(new Date()); - if (modelProviderDao.updateById(ConvertUtils.sourceToTarget(modelProviderEntity, ModelProviderEntity.class)) == 0) { + modelProviderDTO.setCreator(user.getId()); + modelProviderDTO.setUpdater(user.getId()); + modelProviderDTO.setCreateDate(new Date()); + modelProviderDTO.setUpdateDate(new Date()); + // 去除Fields左右的双引号 + + modelProviderDTO.setFields(modelProviderDTO.getFields()); + ModelProviderEntity entity = ConvertUtils.sourceToTarget(modelProviderDTO, ModelProviderEntity.class); + if (modelProviderDao.insert(entity) == 0) { + throw new RenException("新增数据失败"); + } + + return ConvertUtils.sourceToTarget(modelProviderDTO, ModelProviderDTO.class); + } + + @Override + public ModelProviderDTO edit(ModelProviderDTO modelProviderDTO) { + UserDetail user = SecurityUser.getUser(); + modelProviderDTO.setUpdater(user.getId()); + modelProviderDTO.setUpdateDate(new Date()); + if (modelProviderDao.updateById(ConvertUtils.sourceToTarget(modelProviderDTO, ModelProviderEntity.class)) == 0) { throw new RenException("修改数据失败"); } - return ConvertUtils.sourceToTarget(modelProviderEntity, ModelProviderDTO.class); + return ConvertUtils.sourceToTarget(modelProviderDTO, ModelProviderDTO.class); } @Override @@ -93,6 +106,13 @@ public class ModelProviderServiceImpl extends BaseServiceImpl ids) { + if (modelProviderDao.deleteBatchIds(ids) == 0) { + throw new RenException("删除数据失败"); + } + } + @Override public List getList(String modelType, String providerCode) { QueryWrapper queryWrapper = new QueryWrapper<>(); From 38a97d6b5a125276f674ca27d5004e382ccc7fb3 Mon Sep 17 00:00:00 2001 From: ljwwd2 <1205484020@qq.com> Date: Sat, 17 May 2025 01:18:19 +0800 Subject: [PATCH 13/58] =?UTF-8?q?=E4=BE=9B=E5=BA=94=E5=99=A8=E7=AE=A1?= =?UTF-8?q?=E7=90=86-=E5=89=8D=E7=AB=AF=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/manager-web/src/apis/module/model.js | 142 +++++++- .../src/components/ProviderDialog.vue | 12 +- .../src/views/ProviderManagement.vue | 326 +++++++----------- 3 files changed, 266 insertions(+), 214 deletions(-) diff --git a/main/manager-web/src/apis/module/model.js b/main/manager-web/src/apis/module/model.js index ec0ea32f..e64072a8 100644 --- a/main/manager-web/src/apis/module/model.js +++ b/main/manager-web/src/apis/module/model.js @@ -166,20 +166,20 @@ export default { configJson: formData.configJson }; RequestService.sendRequest() - .url(`${getServiceUrl()}/models/${modelType}/${provideCode}/${id}`) - .method('PUT') - .data(payload) - .success((res) => { - RequestService.clearRequestTime(); - callback(res); - }) - .fail((err) => { - console.error('更新模型失败:', err); - this.$message.error(err.msg || '更新模型失败'); - RequestService.reAjaxFun(() => { - this.updateModel(params, callback); - }); - }).send(); + .url(`${getServiceUrl()}/models/${modelType}/${provideCode}/${id}`) + .method('PUT') + .data(payload) + .success((res) => { + RequestService.clearRequestTime(); + callback(res); + }) + .fail((err) => { + console.error('更新模型失败:', err); + this.$message.error(err.msg || '更新模型失败'); + RequestService.reAjaxFun(() => { + this.updateModel(params, callback); + }); + }).send(); }, // 设置默认模型 setDefaultModel(id, callback) { @@ -197,5 +197,117 @@ export default { this.setDefaultModel(id, callback) }) }).send() - } + }, + + /** + * 获取模型配置列表(支持查询参数) + * @param {Object} params - 查询参数对象,例如 { name: 'test', modelType: 1 } + * @param {Function} callback - 回调函数 + */ + getModelProvidersPage(params, callback) { + // 构建查询参数 + const queryParams = new URLSearchParams(); + if (params.name) queryParams.append('name', params.name); + if (params.modelType !== undefined) queryParams.append('modelType', params.modelType); + if (params.page !== undefined) queryParams.append('page', params.page); + if (params.limit !== undefined) queryParams.append('limit', params.limit); + + RequestService.sendRequest() + .url(`${getServiceUrl()}/models/provider?${queryParams.toString()}`) + .method('GET') + // 如果需要额外设置 header,可以在这里添加 + // .headers({ 'X-Custom-Header': 'xxx' }) + .success((res) => { + RequestService.clearRequestTime(); + callback(res); + }) + .fail((err) => { + console.error('获取供应器列表失败:', err); + this.$message.error('获取供应器列表失败'); + RequestService.reAjaxFun(() => { + this.getModelProviders(params, callback); + }); + }).send(); + }, + + /** + * 新增模型供应器配置 + * @param {Object} params - 请求参数对象,例如 { modelType: '1', providerCode: '1', name: '1', fields: '1', sort: 1 } + * @param {Function} callback - 成功回调函数 + */ + addModelProvider(params, callback) { + const postData = { + modelType: params.modelType || '', + providerCode: params.providerCode || '', + name: params.name || '', + fields: JSON.stringify(params.fields || []), + sort: params.sort || 0 + }; + + RequestService.sendRequest() + .url(`${getServiceUrl()}/models/provider`) + .method('POST') + .data(postData) + .success((res) => { + console.log('新增模型供应器成功:', res); + RequestService.clearRequestTime(); + // this.$message.success('新增模型供应器成功'); + callback(res); + }) + .fail((err) => { + console.error('新增模型供应器失败:', err); + // this.$message.error(err.msg || '新增模型供应器失败'); + // RequestService.reAjaxFun(() => { + // this.addModelProvider(params, callback); + // }); + }).send(); + }, + + /** + * 更新模型供应器配置 + * @param {Object} params - 请求参数对象,例如 { id: '111', modelType: '1', providerCode: '1', name: '1', fields: '1', sort: 1 } + * @param {Function} callback - 成功回调函数 + */ + updateModelProvider(params, callback) { + const putData = { + id: params.id || '', + modelType: params.modelType || '', + providerCode: params.providerCode || '', + name: params.name || '', + fields: JSON.stringify(params.fields || []), + sort: params.sort || 0 + }; + + RequestService.sendRequest() + .url(`${getServiceUrl()}/models/provider`) + .method('PUT') + .data(putData) + .success((res) => { + RequestService.clearRequestTime(); + callback(res); + }) + .fail((err) => { + console.error('更新模型供应器失败:', err); + RequestService.reAjaxFun(() => { + this.updateModelProvider(params, callback); + }); + }).send(); + }, + // 删除 + deleteModelProviderByIds(ids, callback) { + RequestService.sendRequest() + .url(`${getServiceUrl()}/models/provider/delete`) + .method('POST') + .data(ids) + .success((res) => { + RequestService.clearRequestTime() + callback(res); + }) + .fail((err) => { + console.error('删除参数失败:', err) + RequestService.reAjaxFun(() => { + this.deleteParam(ids, callback) + }) + }).send() + }, } diff --git a/main/manager-web/src/components/ProviderDialog.vue b/main/manager-web/src/components/ProviderDialog.vue index 844282ee..72437450 100644 --- a/main/manager-web/src/components/ProviderDialog.vue +++ b/main/manager-web/src/components/ProviderDialog.vue @@ -10,15 +10,15 @@
- - + + - - + +
@@ -135,8 +135,8 @@ export default { return { saving: false, rules: { - model_type: [{required: true, message: '请选择类别', trigger: 'change'}], - provider_code: [{required: true, message: '请输入供应器编码', trigger: 'blur'}], + modelType: [{required: true, message: '请选择类别', trigger: 'change'}], + providerCode: [{required: true, message: '请输入供应器编码', trigger: 'blur'}], name: [{required: true, message: '请输入供应器名称', trigger: 'blur'}] }, isAllFieldsSelected: false, diff --git a/main/manager-web/src/views/ProviderManagement.vue b/main/manager-web/src/views/ProviderManagement.vue index f047f482..a476c5e2 100644 --- a/main/manager-web/src/views/ProviderManagement.vue +++ b/main/manager-web/src/views/ProviderManagement.vue @@ -1,13 +1,14 @@