package cc.mrbird.febs.ai.controller;
|
|
import cc.mrbird.febs.ai.entity.AiMember;
|
import cc.mrbird.febs.ai.mapper.AiMemberMapper;
|
import cc.mrbird.febs.ai.req.talk.AiTalkAnswerStream;
|
import cc.mrbird.febs.ai.res.memberTalk.ApiMemberTalkStreamVo;
|
import cc.mrbird.febs.ai.utils.UUID;
|
import cc.mrbird.febs.common.entity.FebsResponse;
|
import cc.mrbird.febs.common.utils.AppContants;
|
import cc.mrbird.febs.common.utils.RedisUtils;
|
import cc.mrbird.febs.mall.entity.MallMember;
|
import cc.mrbird.febs.mall.mapper.MallMemberMapper;
|
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.crypto.asymmetric.KeyType;
|
import cn.hutool.crypto.asymmetric.RSA;
|
import cn.hutool.json.JSONUtil;
|
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import io.reactivex.Flowable;
|
import io.swagger.annotations.Api;
|
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiResponse;
|
import io.swagger.annotations.ApiResponses;
|
import lombok.RequiredArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.validation.annotation.Validated;
|
import org.springframework.web.bind.annotation.*;
|
|
import com.alibaba.dashscope.aigc.generation.Generation;
|
import com.alibaba.dashscope.aigc.generation.GenerationParam;
|
import com.alibaba.dashscope.aigc.generation.GenerationResult;
|
import com.alibaba.dashscope.common.Message;
|
import com.alibaba.dashscope.common.Role;
|
import com.alibaba.dashscope.exception.ApiException;
|
import com.alibaba.dashscope.exception.InputRequiredException;
|
import com.alibaba.dashscope.exception.NoApiKeyException;
|
import reactor.core.publisher.Flux;
|
|
import java.util.Arrays;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* @author Administrator
|
*/
|
@Slf4j
|
@Validated
|
@RestController
|
@RequiredArgsConstructor
|
@RequestMapping(value = "/api/ai/test")
|
@Api(value = "ApiProductController", tags = "AI-登录测试")
|
public class TestController {
|
|
private final MallMemberMapper mallMemberMapper;
|
private final AiMemberMapper aiMemberMapper;
|
private final RedisUtils redisUtils;
|
@ApiOperation(value = "登录测试", notes = "登录测试")
|
@GetMapping(value = "/login")
|
public FebsResponse info() {
|
|
MallMember mallMember = mallMemberMapper.selectById(3634);
|
if(StrUtil.isEmpty(mallMember.getMemberUuid())){
|
AiMember aiMember = new AiMember();
|
aiMember.setId(UUID.getSimpleUUIDString());
|
aiMemberMapper.insert(aiMember);
|
mallMember.setMemberUuid(aiMember.getId());
|
mallMemberMapper.update(null,
|
Wrappers.lambdaUpdate(MallMember.class)
|
.set(MallMember::getMemberUuid, aiMember.getId())
|
.eq(MallMember::getId, mallMember.getId())
|
);
|
}
|
// 存放redis
|
String redisKey = AppContants.XCX_LOGIN_PREFIX + mallMember.getId();
|
String existToken = redisUtils.getString(redisKey);
|
if (StrUtil.isNotBlank(existToken)) {
|
Object o = redisUtils.get(existToken);
|
if (ObjectUtil.isNotEmpty(o)) {
|
redisUtils.del(existToken);
|
}
|
}
|
String token = IdUtil.simpleUUID();
|
redisUtils.set(token, JSONObject.toJSONString(mallMember), -1);
|
redisUtils.set(redisKey, token, -1);
|
Map<String, Object> authInfo = new HashMap<>();
|
authInfo.put("token", token);
|
authInfo.put("member", mallMember);
|
authInfo.put("rasToken", generateAsaToken(token));
|
return new FebsResponse().success().data(authInfo);
|
}
|
|
public String generateAsaToken(String token) {
|
RSA rsa = new RSA(null, AppContants.PUBLIC_KEY);
|
// return rsa.encryptBase64(token + "_" + System.currentTimeMillis(), KeyType.PublicKey);
|
//去掉时间戳
|
return rsa.encryptBase64(token, KeyType.PublicKey);
|
}
|
|
|
|
@ApiOperation("提问AI(流式)V2")
|
@ApiResponses({
|
@ApiResponse(code = 200, message = "流式响应", response = ApiMemberTalkStreamVo.class),
|
})
|
@PostMapping("/answer-streamV2")
|
public Flux<FebsResponse> answerStreamV2(@RequestBody @Validated AiTalkAnswerStream dto) {
|
if (StrUtil.isEmpty(dto.getQuestion())){
|
return Flux.just(new FebsResponse().fail().message("请输入问题"));
|
}
|
|
long startTime = System.currentTimeMillis();
|
|
Flowable<GenerationResult> result;
|
try {
|
result = callWithMessage();
|
} catch (NoApiKeyException | InputRequiredException e) {
|
e.printStackTrace();
|
return Flux.just(new FebsResponse().fail().message("调用AI服务失败: " + e.getMessage()));
|
}
|
|
return Flux.from(result)
|
.map(message -> {
|
String content = message.getOutput().getChoices().get(0).getMessage().getContent();
|
System.out.print(content);
|
return new FebsResponse().success().message(content);
|
})
|
.doOnComplete(() -> {
|
long endTime = System.currentTimeMillis();
|
System.out.println("运行时间:" + (endTime - startTime) + "毫秒");
|
})
|
.doOnError(error -> {
|
long endTime = System.currentTimeMillis();
|
System.err.println("运行时间:" + (endTime - startTime) + "毫秒,发生错误:" + error.getMessage());
|
});
|
}
|
|
|
public static Flowable<GenerationResult> callWithMessage() throws NoApiKeyException, InputRequiredException {
|
Generation gen = new Generation();
|
Message systemMsg = Message.builder()
|
.role(Role.SYSTEM.getValue())
|
.content("You are a helpful assistant.")
|
.build();
|
Message userMsg = Message.builder()
|
.role(Role.USER.getValue())
|
.content("你是谁?")
|
.build();
|
GenerationParam param = GenerationParam.builder()
|
// 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:.apiKey("sk-xxx")
|
.apiKey("sk-babdcf8799144134915cee2683794b2f")
|
// 模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
|
.model("qwen-plus")
|
// .model("deepseek-r1")
|
// .model("qwen-turbo-0624-ft-202508281725-c2dc")
|
.messages(Arrays.asList(systemMsg, userMsg))
|
// .resultFormat(GenerationParam.ResultFormat.TEXT)
|
.resultFormat(GenerationParam.ResultFormat.MESSAGE)
|
.incrementalOutput(true)
|
.build();
|
return gen.streamCall(param);
|
}
|
public static void main(String[] args) {
|
//定义一个开始时间为启动这个main方法的开始时间,用于计算运行时间
|
long startTime = System.currentTimeMillis();
|
|
Flowable<GenerationResult> result = null;
|
try {
|
result = callWithMessage();
|
} catch (NoApiKeyException e) {
|
e.printStackTrace();
|
} catch (InputRequiredException e) {
|
e.printStackTrace();
|
}
|
Flux.from(result)
|
.doOnNext(message -> {
|
String content = message.getOutput().getChoices().get(0).getMessage().getContent();
|
System.out.print(content);
|
})
|
.subscribe();
|
long endTime = System.currentTimeMillis();
|
System.out.println("运行时间:" + (endTime - startTime) + "毫秒");
|
// result.blockingForEach(item -> {
|
//// log.info("item: {}", JSONUtil.toJsonStr(item));
|
// // 提取文本内容
|
// if (item.getOutput() != null && item.getOutput().getChoices() != null) {
|
// item.getOutput().getChoices().forEach(choice -> {
|
// if (choice.getMessage() != null) {
|
// // 根据实际 API 文档确定使用哪个方法
|
//// if (choice.getMessage().getContents() != null) {
|
//// try {
|
//// choice.getMessage().getContents().forEach(content -> {
|
//// if (content != null) {
|
//// System.out.print(content.getType());
|
//// }
|
//// });
|
//// } catch (NullPointerException e) {
|
//// log.error("Error processing contents", e);
|
//// }
|
//// }
|
// if (choice.getMessage().getContent() != null) {
|
// System.out.print(choice.getMessage().getContent());
|
// }
|
// }
|
// });
|
// }
|
// });
|
}
|
}
|