Commit ac0de5d485d5447d8eb8ad062d455b6105c2d3a0

Authored by cherishsince
1 parent 02ac6f30

优化自动注入,可以创建多个 client

yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/ChatController.java
1   -//package cn.iocoder.yudao.module.ai.controller.admin;
2   -//
3   -//import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
4   -//import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5   -//import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
6   -//import cn.iocoder.yudao.module.ai.controller.admin.vo.AiChatReqVO;
7   -//import cn.iocoder.yudao.module.ai.enums.OpenAiModelEnum;
8   -//import io.swagger.v3.oas.annotations.Operation;
9   -//import io.swagger.v3.oas.annotations.tags.Tag;
10   -//import jakarta.servlet.http.HttpServletResponse;
11   -//import lombok.extern.slf4j.Slf4j;
12   -//import org.springframework.ai.chat.ChatClient;
13   -//import org.springframework.ai.chat.ChatResponse;
14   -//import org.springframework.ai.chat.prompt.Prompt;
15   -//import org.springframework.ai.openai.OpenAiChatClient;
16   -//import org.springframework.beans.factory.annotation.Autowired;
17   -//import org.springframework.context.ApplicationContext;
18   -//import org.springframework.validation.annotation.Validated;
19   -//import org.springframework.web.bind.annotation.PostMapping;
20   -//import org.springframework.web.bind.annotation.RequestBody;
21   -//import org.springframework.web.bind.annotation.RequestMapping;
22   -//import org.springframework.web.bind.annotation.RestController;
23   -//import reactor.core.publisher.Flux;
24   -//
25   -//import java.util.function.Consumer;
26   -//
27   -//// TODO done @fansili:有了 swagger 注释,就不用类注释了
28   -//@Tag(name = "AI模块")
29   -//@RestController
30   -//@RequestMapping("/ai-api")
31   -//@Slf4j
32   -//public class ChatController {
  1 +package cn.iocoder.yudao.module.ai.controller.admin;
  2 +
  3 +import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatClient;
  4 +import io.swagger.v3.oas.annotations.tags.Tag;
  5 +import lombok.AllArgsConstructor;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.web.bind.annotation.GetMapping;
  9 +import org.springframework.web.bind.annotation.RequestMapping;
  10 +import org.springframework.web.bind.annotation.RequestParam;
  11 +import org.springframework.web.bind.annotation.RestController;
  12 +
  13 +/**
  14 + * @author fansili
  15 + * @since 1.0
  16 + * @time 2024/4/13 17:44
  17 + */
  18 +@Tag(name = "AI模块")
  19 +@RestController
  20 +@RequestMapping("/ai-api")
  21 +@Slf4j
  22 +@AllArgsConstructor
  23 +public class ChatController {
  24 +
33 25 //
34 26 // @Autowired
35   -// private ApplicationContext applicationContext;
36   -//
37   -// @PostMapping("/chat")
38   -// @Operation(summary = "对话聊天", description = "简单的ai聊天")
39   -// public CommonResult chat(@RequestBody @Validated AiChatReqVO reqVO) {
40   -// ChatClient chatClient = getChatClient(reqVO.getAiModel());
41   -// String res;
42   -// try {
43   -// res = chatClient.call(reqVO.getPrompt());
44   -// } catch (Exception e) {
45   -// res = e.getMessage();
46   -// }
47   -// return CommonResult.success(res);
48   -// }
49   -//
50   -// @PostMapping("/chatStream")
51   -// @Operation(summary = "对话聊天chatStream", description = "简单的ai聊天")
52   -// public CommonResult chatStream(HttpServletResponse response, @RequestBody @Validated AiChatReqVO reqVO) throws InterruptedException {
53   -// OpenAiChatClient chatClient = applicationContext.getBean(OpenAiChatClient.class);
54   -// Flux<ChatResponse> chatResponse = chatClient.stream(new Prompt(reqVO.getPrompt()));
55   -// chatResponse.subscribe(new Consumer<ChatResponse>() {
56   -// @Override
57   -// public void accept(ChatResponse chatResponse) {
58   -// System.err.println(chatResponse.getResults().get(0).getOutput().getContent());
59   -// }
60   -// });
61   -// return CommonResult.success(null);
62   -// }
  27 +// private QianWenChatClient qianWenChatClient;
63 28 //
64   -// /**
65   -// * 根据 ai模型 获取对于的 模型实现类
66   -// *
67   -// * @param aiModelEnum
68   -// * @return
69   -// */
70   -// private ChatClient getChatClient(OpenAiModelEnum aiModelEnum) {
71   -// if (OpenAiModelEnum.OPEN_AI_GPT_3_5 == aiModelEnum) {
72   -// return applicationContext.getBean(OpenAiChatClient.class);
73   -// }
74   -// // AI模型暂不支持
75   -// throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODULE_NOT_SUPPORTED);
  29 +// @GetMapping("/chat")
  30 +// public String chat(@RequestParam("prompt") String prompt) {
  31 +// return qianWenChatClient.call(prompt);
76 32 // }
77   -//}
  33 +
  34 +}
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/OldChatController.java 0 → 100644
  1 +//package cn.iocoder.yudao.module.ai.controller.admin;
  2 +//
  3 +//import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
  4 +//import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +//import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
  6 +//import cn.iocoder.yudao.module.ai.controller.admin.vo.AiChatReqVO;
  7 +//import cn.iocoder.yudao.module.ai.enums.OpenAiModelEnum;
  8 +//import io.swagger.v3.oas.annotations.Operation;
  9 +//import io.swagger.v3.oas.annotations.tags.Tag;
  10 +//import jakarta.servlet.http.HttpServletResponse;
  11 +//import lombok.extern.slf4j.Slf4j;
  12 +//import org.springframework.ai.chat.ChatClient;
  13 +//import org.springframework.ai.chat.ChatResponse;
  14 +//import org.springframework.ai.chat.prompt.Prompt;
  15 +//import org.springframework.ai.openai.OpenAiChatClient;
  16 +//import org.springframework.beans.factory.annotation.Autowired;
  17 +//import org.springframework.context.ApplicationContext;
  18 +//import org.springframework.validation.annotation.Validated;
  19 +//import org.springframework.web.bind.annotation.PostMapping;
  20 +//import org.springframework.web.bind.annotation.RequestBody;
  21 +//import org.springframework.web.bind.annotation.RequestMapping;
  22 +//import org.springframework.web.bind.annotation.RestController;
  23 +//import reactor.core.publisher.Flux;
  24 +//
  25 +//import java.util.function.Consumer;
  26 +//
  27 +//// TODO done @fansili:有了 swagger 注释,就不用类注释了
  28 +//@Tag(name = "AI模块")
  29 +//@RestController
  30 +//@RequestMapping("/ai-api")
  31 +//@Slf4j
  32 +//public class ChatController {
  33 +//
  34 +// @Autowired
  35 +// private ApplicationContext applicationContext;
  36 +//
  37 +// @PostMapping("/chat")
  38 +// @Operation(summary = "对话聊天", description = "简单的ai聊天")
  39 +// public CommonResult chat(@RequestBody @Validated AiChatReqVO reqVO) {
  40 +// ChatClient chatClient = getChatClient(reqVO.getAiModel());
  41 +// String res;
  42 +// try {
  43 +// res = chatClient.call(reqVO.getPrompt());
  44 +// } catch (Exception e) {
  45 +// res = e.getMessage();
  46 +// }
  47 +// return CommonResult.success(res);
  48 +// }
  49 +//
  50 +// @PostMapping("/chatStream")
  51 +// @Operation(summary = "对话聊天chatStream", description = "简单的ai聊天")
  52 +// public CommonResult chatStream(HttpServletResponse response, @RequestBody @Validated AiChatReqVO reqVO) throws InterruptedException {
  53 +// OpenAiChatClient chatClient = applicationContext.getBean(OpenAiChatClient.class);
  54 +// Flux<ChatResponse> chatResponse = chatClient.stream(new Prompt(reqVO.getPrompt()));
  55 +// chatResponse.subscribe(new Consumer<ChatResponse>() {
  56 +// @Override
  57 +// public void accept(ChatResponse chatResponse) {
  58 +// System.err.println(chatResponse.getResults().get(0).getOutput().getContent());
  59 +// }
  60 +// });
  61 +// return CommonResult.success(null);
  62 +// }
  63 +//
  64 +// /**
  65 +// * 根据 ai模型 获取对于的 模型实现类
  66 +// *
  67 +// * @param aiModelEnum
  68 +// * @return
  69 +// */
  70 +// private ChatClient getChatClient(OpenAiModelEnum aiModelEnum) {
  71 +// if (OpenAiModelEnum.OPEN_AI_GPT_3_5 == aiModelEnum) {
  72 +// return applicationContext.getBean(OpenAiChatClient.class);
  73 +// }
  74 +// // AI模型暂不支持
  75 +// throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODULE_NOT_SUPPORTED);
  76 +// }
  77 +//}
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/AiPlatformEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.ai;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Getter;
  5 +
  6 +import java.util.Arrays;
  7 +import java.util.Map;
  8 +import java.util.stream.Collectors;
  9 +
  10 +/**
  11 + * 讯飞星火 模型
  12 + *
  13 + * 文档地址:https://www.xfyun.cn/doc/spark/Web.html#_1-%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E
  14 + *
  15 + * 1tokens 约等于1.5个中文汉字 或者 0.8个英文单词
  16 + * 星火V1.5支持[搜索]内置插件;星火V2.0、V3.0和V3.5支持[搜索]、[天气]、[日期]、[诗词]、[字词]、[股票]六个内置插件
  17 + * 星火V3.5 现已支持system、Function Call 功能。
  18 + *
  19 + * author: fansili
  20 + * time: 2024/3/11 10:12
  21 + */
  22 +@Getter
  23 +@AllArgsConstructor
  24 +public enum AiPlatformEnum {
  25 +
  26 +
  27 + YI_YAN("yiyan"),
  28 + QIAN_WEN("qianwen"),
  29 + XING_HUO("xinghuo"),
  30 +
  31 + ;
  32 +
  33 + public static final Map<String, AiPlatformEnum> mapValues
  34 + = Arrays.stream(values()).collect(Collectors.toMap(AiPlatformEnum::name, o -> o));
  35 +
  36 + private String value;
  37 +
  38 +}
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java
1 1 package cn.iocoder.yudao.framework.ai.config;
2 2  
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
  5 +import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatClient;
  6 +import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenOptions;
  7 +import cn.iocoder.yudao.framework.ai.chatqianwen.api.QianWenApi;
3 8 import cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatClient;
4 9 import cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoOptions;
5 10 import cn.iocoder.yudao.framework.ai.chatxinghuo.api.XingHuoApi;
  11 +import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatClient;
  12 +import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanOptions;
  13 +import cn.iocoder.yudao.framework.ai.chatyiyan.api.YiYanApi;
  14 +import cn.iocoder.yudao.framework.ai.exception.AiException;
  15 +import org.springframework.beans.BeansException;
  16 +import org.springframework.beans.factory.InitializingBean;
  17 +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
6 18 import org.springframework.boot.autoconfigure.AutoConfiguration;
  19 +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
7 20 import org.springframework.boot.context.properties.EnableConfigurationProperties;
  21 +import org.springframework.context.ApplicationContext;
  22 +import org.springframework.context.ApplicationContextAware;
8 23 import org.springframework.context.annotation.Bean;
  24 +import org.springframework.context.support.GenericApplicationContext;
  25 +
  26 +import java.util.Map;
9 27  
10 28 /**
11 29 * ai 自动配置
... ... @@ -18,15 +36,118 @@ import org.springframework.context.annotation.Bean;
18 36 @EnableConfigurationProperties(YudaoAiProperties.class)
19 37 public class YudaoAiAutoConfiguration {
20 38  
  39 + // TODO @芋艿:我看sharding jdbc 差不多这么玩的
21 40 @Bean
22   - public XingHuoChatClient xingHuoChatClient(YudaoAiProperties yudaoAiProperties) {
23   - return new XingHuoChatClient(
24   - new XingHuoApi(
25   - yudaoAiProperties.getXingHuo().getAppId(),
26   - yudaoAiProperties.getXingHuo().getAppKey(),
27   - yudaoAiProperties.getXingHuo().getSecretKey()
28   - ),
29   - new XingHuoOptions().setChatModel(yudaoAiProperties.getXingHuo().getChatModel())
30   - );
  41 + @ConditionalOnMissingBean(value = InitChatClient.class)
  42 + public InitChatClient initChatClient(YudaoAiProperties yudaoAiProperties) {
  43 + return new InitChatClient(yudaoAiProperties);
  44 + }
  45 +
  46 + public static class InitChatClient implements InitializingBean, ApplicationContextAware {
  47 +
  48 + private GenericApplicationContext applicationContext;
  49 + private YudaoAiProperties yudaoAiProperties;
  50 +
  51 + public InitChatClient(YudaoAiProperties yudaoAiProperties) {
  52 + this.yudaoAiProperties = yudaoAiProperties;
  53 + }
  54 +
  55 + @Override
  56 + public void afterPropertiesSet() throws Exception {
  57 + for (Map.Entry<String, Map<String, Object>> properties : yudaoAiProperties.entrySet()) {
  58 + String beanName = properties.getKey();
  59 + Map<String, Object> aiPlatformMap = properties.getValue();
  60 +
  61 + // 检查平台类型是否正确
  62 + String aiPlatform = String.valueOf(aiPlatformMap.get("aiPlatform"));
  63 + if (!AiPlatformEnum.mapValues.containsKey(aiPlatform)) {
  64 + throw new AiException("AI平台名称错误! 可以参考 AiPlatformEnum 类!");
  65 + }
  66 + // 获取平台类型
  67 + AiPlatformEnum aiPlatformEnum = AiPlatformEnum.mapValues.get(aiPlatform);
  68 + // 获取 chat properties
  69 + YudaoAiProperties.ChatProperties chatProperties = getChatProperties(aiPlatformEnum, aiPlatformMap);
  70 + // 创建客户端
  71 + registerChatClient(applicationContext, chatProperties, beanName);
  72 +// applicationContext.refresh();
  73 +
  74 +
  75 + }
  76 +
  77 + System.err.println(applicationContext.getBean("qianWen"));
  78 + System.err.println(applicationContext.getBean("yiYan"));
  79 + }
  80 +
  81 + @Override
  82 + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  83 + this.applicationContext = (GenericApplicationContext) applicationContext;
  84 + }
  85 + }
  86 +
  87 + private static void registerChatClient(GenericApplicationContext applicationContext, YudaoAiProperties.ChatProperties chatProperties, String beanName) {
  88 + ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
  89 + Object wrapperBean = null;
  90 + if (AiPlatformEnum.XING_HUO == chatProperties.getAiPlatform()) {
  91 + YudaoAiProperties.XingHuoProperties xingHuoProperties = (YudaoAiProperties.XingHuoProperties) chatProperties;
  92 + wrapperBean = beanFactory.initializeBean(
  93 + new XingHuoChatClient(
  94 + new XingHuoApi(
  95 + xingHuoProperties.getAppId(),
  96 + xingHuoProperties.getAppKey(),
  97 + xingHuoProperties.getSecretKey()
  98 + ),
  99 + new XingHuoOptions().setChatModel(xingHuoProperties.getChatModel())
  100 + ),
  101 + beanName
  102 + );
  103 + } else if (AiPlatformEnum.QIAN_WEN == chatProperties.getAiPlatform()) {
  104 + YudaoAiProperties.QianWenProperties qianWenProperties = (YudaoAiProperties.QianWenProperties) chatProperties;
  105 + wrapperBean = beanFactory.initializeBean(new QianWenChatClient(
  106 + new QianWenApi(
  107 + qianWenProperties.getAccessKeyId(),
  108 + qianWenProperties.getAccessKeySecret(),
  109 + qianWenProperties.getAgentKey(),
  110 + qianWenProperties.getEndpoint()
  111 + ),
  112 + new QianWenOptions()
  113 + .setAppId(qianWenProperties.getAppId())
  114 + ),
  115 + beanName
  116 + );
  117 + } else if (AiPlatformEnum.YI_YAN == chatProperties.getAiPlatform()) {
  118 + YudaoAiProperties.YiYanProperties yiYanProperties = (YudaoAiProperties.YiYanProperties) chatProperties;
  119 +
  120 + wrapperBean = beanFactory.initializeBean(new YiYanChatClient(
  121 + new YiYanApi(
  122 + yiYanProperties.getAppKey(),
  123 + yiYanProperties.getSecretKey(),
  124 + yiYanProperties.getChatModel(),
  125 + yiYanProperties.getRefreshTokenSecondTime()
  126 + ),
  127 + new YiYanOptions().setMax_output_tokens(2048)),
  128 + beanName
  129 + );
  130 + }
  131 + if (wrapperBean != null) {
  132 + beanFactory.registerSingleton(beanName, wrapperBean);
  133 + }
  134 + }
  135 +
  136 +
  137 + private static YudaoAiProperties.ChatProperties getChatProperties(AiPlatformEnum aiPlatformEnum, Map<String, Object> aiPlatformMap) {
  138 + if (AiPlatformEnum.XING_HUO == aiPlatformEnum) {
  139 + YudaoAiProperties.XingHuoProperties xingHuoProperties = new YudaoAiProperties.XingHuoProperties();
  140 + BeanUtil.fillBeanWithMap(aiPlatformMap, xingHuoProperties, true);
  141 + return xingHuoProperties;
  142 + } else if (AiPlatformEnum.YI_YAN == aiPlatformEnum) {
  143 + YudaoAiProperties.YiYanProperties yiYanProperties = new YudaoAiProperties.YiYanProperties();
  144 + BeanUtil.fillBeanWithMap(aiPlatformMap, yiYanProperties, true);
  145 + return yiYanProperties;
  146 + } else if (AiPlatformEnum.QIAN_WEN == aiPlatformEnum) {
  147 + YudaoAiProperties.QianWenProperties qianWenProperties = new YudaoAiProperties.QianWenProperties();
  148 + BeanUtil.fillBeanWithMap(aiPlatformMap, qianWenProperties, true);
  149 + return qianWenProperties;
  150 + }
  151 + throw new AiException("不支持的Ai类型!");
31 152 }
32 153 -}
  154 +}
33 155 \ No newline at end of file
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiProperties.java
1 1 package cn.iocoder.yudao.framework.ai.config;
2 2  
  3 +import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
3 4 import cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatModel;
4 5 import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel;
5 6 import lombok.Data;
6 7 import lombok.experimental.Accessors;
7 8 import org.springframework.boot.context.properties.ConfigurationProperties;
8 9  
  10 +import java.util.LinkedHashMap;
  11 +import java.util.Map;
  12 +
9 13 /**
10 14 * ai 自动配置
11 15 *
... ... @@ -15,16 +19,18 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
15 19 */
16 20 @Data
17 21 @ConfigurationProperties(prefix = "yudao.ai")
18   -public class YudaoAiProperties {
  22 +public class YudaoAiProperties extends LinkedHashMap<String, Map<String, Object>> {
19 23  
20   - private QianWenProperties qianWen;
21   - private XingHuoProperties xingHuo;
22   - private YiYanProperties yiYan;
  24 +// private QianWenProperties qianWen;
  25 +// private XingHuoProperties xingHuo;
  26 +// private YiYanProperties yiYan;
23 27  
24 28 @Data
25 29 @Accessors(chain = true)
26 30 public static class ChatProperties {
27 31  
  32 + private AiPlatformEnum aiPlatform;
  33 +
28 34 private Float temperature;
29 35  
30 36 private Float topP;
... ... @@ -48,9 +54,14 @@ public class YudaoAiProperties {
48 54 */
49 55 private String accessKeySecret;
50 56 /**
51   - * 阿里云:agentKey(相当于应用id)
  57 + * 阿里云:agentKey
52 58 */
53 59 private String agentKey;
  60 + /**
  61 + * 阿里云:agentKey(相当于应用id)
  62 + */
  63 + private String appId;
  64 +
54 65 }
55 66  
56 67 @Data
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/exception/AiException.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.ai.exception;
  2 +
  3 +/**
  4 + * ai 异常
  5 + *
  6 + * @author fansili
  7 + * @time 2024/4/13 17:05
  8 + * @since 1.0
  9 + */
  10 +public class AiException extends RuntimeException {
  11 +
  12 + public AiException(String message) {
  13 + super(message);
  14 + }
  15 +}
... ...
yudao-server/src/main/resources/application-local.yaml
... ... @@ -224,20 +224,30 @@ wx:
224 224 # 芋道配置项,设置当前项目所有自定义的配置
225 225 yudao:
226 226 ai:
227   - temperature: 1
228   - topP: 1
229   - topK: 1
230 227 qianWen:
  228 + aiPlatform: QIAN_WEN
  229 + temperature: 1
  230 + topP: 1
  231 + topK: 1
231 232 endpoint: bailian.cn-beijing.aliyuncs.com
232 233 accessKeyId: LTAI5tNTVhXW4fLKUjMrr98z
233 234 accessKeySecret: ZJ0JQeyjzxxm5CfeTV6k1wNE9UsvZP
234 235 agentKey: f0c1088824594f589c8f10567ccd929f_p_efm
  236 + appId: 5f14955f201a44eb8dbe0c57250a32ce
235 237 xingHuo:
  238 + aiPlatform: XING_HUO
  239 + temperature: 1
  240 + topP: 1
  241 + topK: 1
236 242 appId: 13c8cca6
237 243 appKey: cb6415c19d6162cda07b47316fcb0416
238 244 secretKey: Y2JiYTIxZjA3MDMxMjNjZjQzYzVmNzdh
239 245 chatModel: XING_HUO_3_5
240 246 yiYan:
  247 + aiPlatform: YI_YAN
  248 + temperature: 1
  249 + topP: 1
  250 + topK: 1
241 251 appKey: x0cuLZ7XsaTCU08vuJWO87Lg
242 252 secretKey: R9mYF9dl9KASgi5RUq0FQt3wRisSnOcK
243 253 refreshTokenSecondTime: 86400
... ...