From 2e73959a2c13ec22b983c0e47832fcc6da767233 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 5 Jul 2024 09:42:36 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E4=BB=A3=E7=A0=81=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E3=80=91AI=EF=BC=9A=E5=BC=80=E5=90=AF=20AI=20=E7=A7=9F?= =?UTF-8?q?=E6=88=B7=E7=9A=84=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-module-ai/yudao-module-ai-biz/pom.xml | 5 +++++ .../admin/chat/AiChatMessageController.http | 4 +++- .../ai/controller/admin/image/vo/AiImageRespVO.java | 2 -- .../module/ai/dal/dataobject/image/AiImageDO.java | 10 +++++----- .../ai/service/chat/AiChatMessageServiceImpl.java | 10 +++++++--- .../module/ai/service/write/AiWriteServiceImpl.java | 11 ++++++++--- .../ai/core/factory/AiClientFactoryImpl.java | 6 +++--- .../src/main/resources/application-local.yaml | 8 -------- yudao-server/src/main/resources/application.yaml | 7 +++++++ 9 files changed, 38 insertions(+), 25 deletions(-) diff --git a/yudao-module-ai/yudao-module-ai-biz/pom.xml b/yudao-module-ai/yudao-module-ai-biz/pom.xml index f0c73246d..0be1e4df6 100644 --- a/yudao-module-ai/yudao-module-ai-biz/pom.xml +++ b/yudao-module-ai/yudao-module-ai-biz/pom.xml @@ -32,6 +32,11 @@ ${revision} + + cn.iocoder.boot + yudao-spring-boot-starter-biz-tenant + + cn.iocoder.boot diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/AiChatMessageController.http b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/AiChatMessageController.http index 924f21866..e75e0d333 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/AiChatMessageController.http +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/AiChatMessageController.http @@ -2,6 +2,7 @@ POST {{baseUrl}}/ai/chat/message/send Content-Type: application/json Authorization: {{token}} +tenant-id: {{adminTenentId}} { "conversationId": "1781604279872581724", @@ -12,9 +13,10 @@ Authorization: {{token}} POST {{baseUrl}}/ai/chat/message/send-stream Content-Type: application/json Authorization: {{token}} +tenant-id: {{adminTenentId}} { - "conversationId": "1781604279872581690", + "conversationId": "1781604279872581724", "content": "1+1=?" } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/AiImageRespVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/AiImageRespVO.java index 8499692e2..f73d05aaa 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/AiImageRespVO.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/AiImageRespVO.java @@ -57,6 +57,4 @@ public class AiImageRespVO { @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; - - } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/image/AiImageDO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/image/AiImageDO.java index b5acec987..6768d904b 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/image/AiImageDO.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/image/AiImageDO.java @@ -76,6 +76,11 @@ public class AiImageDO extends BaseDO { */ private Integer status; + /** + * 完成时间 + */ + private LocalDateTime finishTime; + /** * 绘画错误信息 */ @@ -112,11 +117,6 @@ public class AiImageDO extends BaseDO { */ private String taskId; - /** - * 完成时间 - */ - private LocalDateTime finishTime; - public static class ButtonTypeHandler extends AbstractJsonTypeHandler { @Override diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageServiceImpl.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageServiceImpl.java index 3a9b34fc8..44b48a66a 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageServiceImpl.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageServiceImpl.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.ai.core.util.AiUtils; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO; import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO; import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO; @@ -125,11 +126,14 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { return success(new AiChatMessageSendRespVO().setSend(BeanUtils.toBean(userMessage, AiChatMessageSendRespVO.Message.class)) .setReceive(BeanUtils.toBean(assistantMessage, AiChatMessageSendRespVO.Message.class).setContent(newContent))); }).doOnComplete(() -> { - chatMessageMapper.updateById(new AiChatMessageDO().setId(assistantMessage.getId()).setContent(contentBuffer.toString())); + // 忽略租户,因为 Flux 异步无法透传租户 + TenantUtils.executeIgnore(() -> + chatMessageMapper.updateById(new AiChatMessageDO().setId(assistantMessage.getId()).setContent(contentBuffer.toString()))); }).doOnError(throwable -> { - // TODO @芋艿:失败的情况下,要不要删除消息 log.error("[sendChatMessageStream][userId({}) sendReqVO({}) 发生异常]", userId, sendReqVO, throwable); - chatMessageMapper.updateById(new AiChatMessageDO().setId(assistantMessage.getId()).setContent(throwable.getMessage())); + // 忽略租户,因为 Flux 异步无法透传租户 + TenantUtils.executeIgnore(() -> + chatMessageMapper.updateById(new AiChatMessageDO().setId(assistantMessage.getId()).setContent(throwable.getMessage()))); }).onErrorResume(error -> Flux.just(error(ErrorCodeConstants.CHAT_STREAM_ERROR))); } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/write/AiWriteServiceImpl.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/write/AiWriteServiceImpl.java index 9e5c0a7ff..0051e4a8e 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/write/AiWriteServiceImpl.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/write/AiWriteServiceImpl.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum; import cn.iocoder.yudao.framework.ai.core.util.AiUtils; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.module.ai.controller.admin.write.vo.AiWriteGenerateReqVO; import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO; import cn.iocoder.yudao.module.ai.dal.dataobject.write.AiWriteDO; @@ -75,10 +76,14 @@ public class AiWriteServiceImpl implements AiWriteService { // 响应结果 return success(newContent); }).doOnComplete(() -> { - writeMapper.updateById(new AiWriteDO().setId(writeDO.getId()).setGeneratedContent(contentBuffer.toString())); + // 忽略租户,因为 Flux 异步无法透传租户 + TenantUtils.executeIgnore(() -> + writeMapper.updateById(new AiWriteDO().setId(writeDO.getId()).setGeneratedContent(contentBuffer.toString()))); }).doOnError(throwable -> { - log.error("[AI Write][generateReqVO({}) 发生异常]", generateReqVO, throwable); - writeMapper.updateById(new AiWriteDO().setId(writeDO.getId()).setErrorMessage(throwable.getMessage())); + log.error("[generateWriteContent][generateReqVO({}) 发生异常]", generateReqVO, throwable); + // 忽略租户,因为 Flux 异步无法透传租户 + TenantUtils.executeIgnore(() -> + writeMapper.updateById(new AiWriteDO().setId(writeDO.getId()).setErrorMessage(throwable.getMessage()))); }).onErrorResume(error -> Flux.just(error(ErrorCodeConstants.WRITE_STREAM_ERROR))); } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiClientFactoryImpl.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiClientFactoryImpl.java index 10f4b7503..0ab34fdf8 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiClientFactoryImpl.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiClientFactoryImpl.java @@ -163,7 +163,7 @@ public class AiClientFactoryImpl implements AiClientFactory { * 可参考 {@link QianFanAutoConfiguration#qianFanChatModel(QianFanConnectionProperties, QianFanChatProperties, RestClient.Builder, RetryTemplate, ResponseErrorHandler)} */ private static QianFanChatModel buildYiYanChatClient(String key) { - // TODO 芋艿:貌似目前设置,request 势必会报错 + // TODO @xin:貌似目前设置,request 势必会报错;看看能不能有办法,参考 buildQianWenChatClient,调用 QianFanAutoConfiguration#qianFanChatModel初始化,当然 key 要用自己的哈 List keys = StrUtil.split(key, '|'); Assert.equals(keys.size(), 2, "YiYanChatClient 的密钥需要 (appKey|secretKey) 格式"); String appKey = keys.get(0); @@ -191,8 +191,8 @@ public class AiClientFactoryImpl implements AiClientFactory { private static TongYiChatModel buildQianWenChatClient(String key) { com.alibaba.dashscope.aigc.generation.Generation generation = SpringUtil.getBean(Generation.class); TongYiChatProperties chatOptions = SpringUtil.getBean(TongYiChatProperties.class); - // TODO @芋艿:貌似 apiKey 是全局唯一的???得测试下 - // TODO @芋艿:貌似阿里云不是增量返回的 + // TODO @xin:貌似 apiKey 是全局唯一的???得测试下 + // TODO @xin:貌似阿里云不是增量返回的 TongYiConnectionProperties connectionProperties = new TongYiConnectionProperties(); connectionProperties.setApiKey(key); return new TongYiAutoConfiguration().tongYiChatClient(generation, chatOptions, connectionProperties); diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index b62bc3e7f..09ea358af 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -70,12 +70,6 @@ spring: port: 6379 # 端口 database: 0 # 数据库索引 # password: dev # 密码,建议生产环境开启 -server: - servlet: - encoding: - enabled: true - charset: UTF-8 - force: true --- #################### 定时任务相关配置 #################### @@ -226,8 +220,6 @@ yudao: enable: false demo: false # 关闭演示模式 tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc - tenant: - enable: false justauth: enabled: true diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index f48352baf..b2e2ddcd7 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -34,6 +34,13 @@ spring: redis: time-to-live: 1h # 设置过期时间为 1 小时 +server: + servlet: + encoding: + enabled: true + charset: UTF-8 # 必须设置 UTF-8,避免 WebFlux 流式返回(AI 场景)会乱码问题 + force: true + --- #################### 接口文档配置 #################### springdoc: