|
12 | 12 |
|
13 | 13 | package com.tinyengine.it.service.app.impl.v1; |
14 | 14 |
|
15 | | -import com.aliyun.bailian20231229.Client; |
16 | | -import com.aliyun.tea.TeaException; |
17 | | -import com.aliyun.teaopenapi.models.Config; |
18 | | -import com.aliyun.teaopenapi.models.OpenApiRequest; |
19 | | -import com.aliyun.teaopenapi.models.Params; |
20 | | -import com.aliyun.teautil.models.RuntimeOptions; |
21 | 15 | import com.fasterxml.jackson.databind.JsonNode; |
22 | | -import com.tinyengine.it.common.base.Result; |
23 | 16 | import com.tinyengine.it.common.log.SystemServiceLog; |
24 | 17 | import com.tinyengine.it.common.utils.JsonUtils; |
25 | 18 | import com.tinyengine.it.config.OpenAIConfig; |
26 | 19 | import com.tinyengine.it.model.dto.ChatRequest; |
27 | | -import com.tinyengine.it.model.dto.NodeDto; |
28 | 20 | import com.tinyengine.it.service.app.v1.AiChatV1Service; |
29 | | -import org.slf4j.Logger; |
30 | | -import org.slf4j.LoggerFactory; |
31 | 21 | import org.springframework.stereotype.Service; |
32 | 22 | import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; |
33 | 23 |
|
|
39 | 29 | import java.net.http.HttpResponse; |
40 | 30 | import java.nio.charset.StandardCharsets; |
41 | 31 | import java.time.Duration; |
42 | | -import java.util.ArrayList; |
43 | 32 | import java.util.HashMap; |
44 | | -import java.util.List; |
45 | 33 | import java.util.Map; |
46 | 34 |
|
47 | 35 | /** |
|
51 | 39 | */ |
52 | 40 | @Service |
53 | 41 | public class AiChatV1ServiceImpl implements AiChatV1Service { |
54 | | - private static final String ACCESS_KEY_ID = System.getenv("ACCESS_KEY_ID"); |
55 | | - private static final String ACCESS_KEY_SECRET = System.getenv("ACCESS_KEY_SECRET"); |
56 | | - private static final String ENDPOINT = "bailian.cn-beijing.aliyuncs.com"; |
57 | | - private static final String INDEX_ID = System.getenv("INDEX_ID"); |
58 | | - private static final String WORK_SPACE_ID = System.getenv("WORK_SPACE_ID"); |
59 | 42 | private final OpenAIConfig config = new OpenAIConfig(); |
60 | | - private static final Logger log = LoggerFactory.getLogger(AiChatV1ServiceImpl.class); |
61 | 43 | private HttpClient httpClient = HttpClient.newBuilder() |
62 | 44 | .connectTimeout(Duration.ofSeconds(config.getTimeoutSeconds())) |
63 | 45 | .build(); |
@@ -122,160 +104,6 @@ private String ensureUrlProtocol(String url) { |
122 | 104 | return "https://" + url; |
123 | 105 | } |
124 | 106 |
|
125 | | - /** |
126 | | - * 创建客户端 |
127 | | - */ |
128 | | - private Client createClient() throws Exception { |
129 | | - return new Client(new Config() |
130 | | - .setAccessKeyId(ACCESS_KEY_ID) |
131 | | - .setAccessKeySecret(ACCESS_KEY_SECRET) |
132 | | - .setEndpoint(ENDPOINT) |
133 | | - .setEndpointType("access_key")); |
134 | | - } |
135 | | - |
136 | | - /** |
137 | | - * 创建API信息 |
138 | | - */ |
139 | | - private Params createApiInfo(String WorkspaceId) throws Exception { |
140 | | - return new Params() |
141 | | - // 接口名称 |
142 | | - .setAction("Retrieve") |
143 | | - // 接口版本 |
144 | | - .setVersion("2023-12-29") |
145 | | - // 接口协议 |
146 | | - .setProtocol("HTTPS") |
147 | | - // 接口 HTTP 方法 |
148 | | - .setMethod("POST") |
149 | | - .setAuthType("AK") |
150 | | - .setStyle("ROA") |
151 | | - // 接口 PATH |
152 | | - .setPathname("/" + com.aliyun.openapiutil.Client.getEncodeParam(WorkspaceId) + "/index/retrieve") |
153 | | - // 接口请求体内容格式 |
154 | | - .setReqBodyType("json") |
155 | | - // 接口响应体内容格式 |
156 | | - .setBodyType("json"); |
157 | | - } |
158 | | - |
159 | | - /** |
160 | | - * 安全类型转换工具方法 |
161 | | - */ |
162 | | - private <T> T safeCast(Object obj, Class<T> clazz, T defaultValue) { |
163 | | - if (obj == null) { |
164 | | - return defaultValue; |
165 | | - } |
166 | | - try { |
167 | | - return clazz.cast(obj); |
168 | | - } catch (ClassCastException e) { |
169 | | - log.warn("类型转换失败: {} 无法转换为 {}", obj.getClass().getName(), clazz.getName()); |
170 | | - return defaultValue; |
171 | | - } |
172 | | - } |
173 | | - |
174 | | - private String safeCastToString(Object obj) { |
175 | | - return safeCast(obj, String.class, ""); |
176 | | - } |
177 | | - |
178 | | - private Double safeCastToDouble(Object obj) { |
179 | | - return safeCast(obj, Double.class, 0.0); |
180 | | - } |
181 | | - |
182 | | - private Long safeCastToLong(Object obj) { |
183 | | - return safeCast(obj, Long.class, 0L); |
184 | | - } |
185 | | - |
186 | | - /** |
187 | | - * chatSearch. |
188 | | - * |
189 | | - * @param content the content |
190 | | - * @return String the String |
191 | | - */ |
192 | | - public Result chatSearch(String content) { |
193 | | - try { |
194 | | - Client client = createClient(); |
195 | | - Params params = createApiInfo(WORK_SPACE_ID); |
196 | | - |
197 | | - Map<String, Object> queries = new HashMap<>(); |
198 | | - queries.put("IndexId", INDEX_ID); |
199 | | - queries.put("Query", content); |
200 | | - queries.put("EnableRewrite", "true"); |
201 | | - |
202 | | - RuntimeOptions runtime = new RuntimeOptions(); |
203 | | - OpenApiRequest request = new OpenApiRequest() |
204 | | - .setQuery(com.aliyun.openapiutil.Client.query(queries)); |
205 | | - |
206 | | - Map<String, ?> response = client.callApi(params, request, runtime); |
207 | | - Map<String, Object> body = (Map<String, Object>) response.get("body"); |
208 | | - |
209 | | - if (body == null) { |
210 | | - return Result.failed("响应体为空"); |
211 | | - } |
212 | | - |
213 | | - long status = safeCastToLong(body.get("Status")); |
214 | | - if (status != 200L) { |
215 | | - String message = safeCastToString(body.get("Message")); |
216 | | - log.error("搜索失败: status={}, message={}", status, message); |
217 | | - return Result.failed("搜索失败: " + message); |
218 | | - } |
219 | | - |
220 | | - Map data = safeCast(body.get("Data"), Map.class, new HashMap<>()); |
221 | | - if (data == null || data.isEmpty()) { |
222 | | - return Result.success(new ArrayList<>()); |
223 | | - } |
224 | | - |
225 | | - List nodes = safeCast(data.get("Nodes"), List.class, new ArrayList<>()); |
226 | | - if (nodes.isEmpty()) { |
227 | | - return Result.success(new ArrayList<>()); |
228 | | - } |
229 | | - |
230 | | - List nodeDtos = convertToNodeDtos(nodes); |
231 | | - return Result.success(nodeDtos); |
232 | | - |
233 | | - } catch (TeaException e) { |
234 | | - log.error("阿里云Tea异常: {}", e.getMessage(), e); |
235 | | - return Result.failed("阿里云服务异常: " + e.getMessage()); |
236 | | - } catch (Exception e) { |
237 | | - log.error("搜索异常: {}", e.getMessage(), e); |
238 | | - return Result.failed("系统异常: " + e.getMessage()); |
239 | | - } |
240 | | - } |
241 | | - |
242 | | - /** |
243 | | - * 转换节点数据 |
244 | | - */ |
245 | | - private List<NodeDto> convertToNodeDtos(List<Map<String, Object>> nodes) { |
246 | | - List<NodeDto> nodeDtos = new ArrayList<>(); |
247 | | - |
248 | | - for (Map<String, Object> node : nodes) { |
249 | | - try { |
250 | | - NodeDto nodeDto = new NodeDto(); |
251 | | - |
252 | | - // 安全获取文本内容 |
253 | | - nodeDto.setContent(safeCastToString(node.get("Text"))); |
254 | | - |
255 | | - // 安全获取分数 |
256 | | - Object scoreObj = node.get("Score"); |
257 | | - if (scoreObj instanceof Number) { |
258 | | - nodeDto.setScore(((Number) scoreObj).doubleValue()); |
259 | | - } else { |
260 | | - nodeDto.setScore(safeCastToDouble(scoreObj)); |
261 | | - } |
262 | | - |
263 | | - // 安全获取元数据 |
264 | | - Map metadata = safeCast(node.get("Metadata"), Map.class, new HashMap<>()); |
265 | | - if (metadata != null) { |
266 | | - nodeDto.setDocName(safeCastToString(metadata.get("doc_name"))); |
267 | | - } |
268 | | - |
269 | | - nodeDtos.add(nodeDto); |
270 | | - |
271 | | - } catch (Exception e) { |
272 | | - log.warn("节点数据转换失败: {}", e.getMessage()); |
273 | | - } |
274 | | - } |
275 | | - |
276 | | - return nodeDtos; |
277 | | - } |
278 | | - |
279 | 107 | private String buildRequestBody(ChatRequest request) { |
280 | 108 | Map<String, Object> body = new HashMap<>(); |
281 | 109 | body.put("model", request.getModel() != null ? request.getModel() : config.getDefaultModel()); |
|
0 commit comments