|
|
@@ -0,0 +1,245 @@
|
|
|
+package shop.alien.store.util;
|
|
|
+
|
|
|
+import com.alibaba.fastjson2.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.collections4.map.HashedMap;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.http.*;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.util.LinkedMultiValueMap;
|
|
|
+import org.springframework.util.MultiValueMap;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
+import org.springframework.web.client.RestTemplate;
|
|
|
+import shop.alien.entity.result.R;
|
|
|
+import shop.alien.entity.store.LifeMessage;
|
|
|
+import shop.alien.entity.store.LifeUser;
|
|
|
+import shop.alien.entity.store.LifeUserViolation;
|
|
|
+import shop.alien.entity.store.vo.LifeUserVo;
|
|
|
+import shop.alien.mapper.LifeMessageMapper;
|
|
|
+import shop.alien.mapper.LifeUserMapper;
|
|
|
+
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class AiUserViolationUtils {
|
|
|
+
|
|
|
+ private final RestTemplate restTemplate;
|
|
|
+ private final LifeUserMapper lifeUserMapper;
|
|
|
+ private final LifeMessageMapper lifeMessageMapper;
|
|
|
+
|
|
|
+ // @Value("${third-party-login.base-url:http://192.168.2.250:9000/ai/user-auth-core/api/v1/auth/login}")
|
|
|
+ private String loginUrl = "http://192.168.2.78:9000/ai/user-auth-core/api/v1/auth/login";
|
|
|
+
|
|
|
+ @Value("${third-party-user-name.base-url:UdUser}")
|
|
|
+ private String userName;
|
|
|
+
|
|
|
+ @Value("${third-party-pass-word.base-url:123456}")
|
|
|
+ private String passWord;
|
|
|
+
|
|
|
+ private String userComplaintRecordUrl = "http://192.168.2.78:9000/ai/auto-review/api/v1/user_complaint_record/submit";
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 登录 AI 服务,获取 token
|
|
|
+ *
|
|
|
+ * @return accessToken
|
|
|
+ */
|
|
|
+ public String getAccessToken() {
|
|
|
+ log.info("登录Ai服务获取token...{}", loginUrl);
|
|
|
+ MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
|
|
|
+ formData.add("username", userName);
|
|
|
+ formData.add("password", passWord);
|
|
|
+
|
|
|
+ HttpHeaders headers = new HttpHeaders();
|
|
|
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
|
|
+ HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);
|
|
|
+
|
|
|
+ ResponseEntity<String> response;
|
|
|
+ try {
|
|
|
+ log.info("请求Ai服务登录接口===================>");
|
|
|
+ response = restTemplate.postForEntity(loginUrl, requestEntity, String.class);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("请求AI服务登录接口失败", e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (response != null && response.getStatusCode() == HttpStatus.OK) {
|
|
|
+ String body = response.getBody();
|
|
|
+ log.info("请求Ai服务登录成功 postForEntity.getBody()\t{}", body);
|
|
|
+ if (StringUtils.hasText(body)) {
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(body);
|
|
|
+ if (jsonObject != null) {
|
|
|
+ JSONObject dataJson = jsonObject.getJSONObject("data");
|
|
|
+ if (dataJson != null) {
|
|
|
+ return dataJson.getString("access_token");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.warn("AI服务登录响应解析失败 body: {}", body);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ log.error("请求AI服务 登录接口失败 http状态:{}", response != null ? response.getStatusCode() : null);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 调用AI服务创建任务
|
|
|
+ *
|
|
|
+ * @return accessToken
|
|
|
+ */
|
|
|
+ public String createTask(String accessToken, LifeUserViolation lifeuserViolation) {
|
|
|
+ log.info("创建Ai服务任务...{}", userComplaintRecordUrl);
|
|
|
+
|
|
|
+ HttpHeaders analyzeHeaders = new HttpHeaders();
|
|
|
+ analyzeHeaders.setContentType(MediaType.APPLICATION_JSON);
|
|
|
+ analyzeHeaders.set("Authorization", "Bearer " + accessToken);
|
|
|
+
|
|
|
+ Map<String, Object> analyzeRequest = new HashedMap<>();
|
|
|
+ // 对应参数
|
|
|
+ analyzeRequest.put("complaint_type", lifeuserViolation.getViolationType());
|
|
|
+ analyzeRequest.put("reporter_user_id", lifeuserViolation.getReportingUserId());
|
|
|
+ analyzeRequest.put("reported_user_id", lifeuserViolation.getReportedUserId());
|
|
|
+
|
|
|
+ //举报人
|
|
|
+ String reporterUserId = lifeuserViolation.getReportingUserId();
|
|
|
+ //被举报人
|
|
|
+ String reportedUserId = lifeuserViolation.getReportedUserId();
|
|
|
+
|
|
|
+ //通过双方userId查询用户信息,查出用户电话,
|
|
|
+ QueryWrapper<LifeUserVo> reporterUserQueryWrapper = new QueryWrapper<>();
|
|
|
+ reporterUserQueryWrapper.eq("id", reporterUserId);
|
|
|
+ LifeUserVo reporterUserById = lifeUserMapper.getUserById(reporterUserQueryWrapper);
|
|
|
+ QueryWrapper<LifeUserVo> reportedUserQueryWrapper = new QueryWrapper<>();
|
|
|
+ reportedUserQueryWrapper.eq("id", reportedUserId);
|
|
|
+ LifeUserVo reportedUserById = lifeUserMapper.getUserById(reportedUserQueryWrapper);
|
|
|
+ // 用user_去拼接,查询life_message表,获取双方两天记录
|
|
|
+ String userReporterUserById = "user_" + reporterUserById.getUserPhone();
|
|
|
+ String userReportedUserById = "user_" + reportedUserById.getUserPhone();
|
|
|
+
|
|
|
+ //将双方两天记录拼接成text,传入analyzeRequest
|
|
|
+ // 获取双方最近的聊天记录
|
|
|
+ List<LifeMessage> chatMessages = getRecentChatMessages(userReporterUserById, userReportedUserById);
|
|
|
+
|
|
|
+ // 将聊天记录转换为文本格式
|
|
|
+ String text = convertMessagesToText(chatMessages);
|
|
|
+ analyzeRequest.put("conversation_context", StringUtils.hasText(text) ? text : "");
|
|
|
+
|
|
|
+// analyzeRequest.put("text", StringUtils.hasText(text) ? text : "");
|
|
|
+// analyzeRequest.put("img_urls", img_urls);
|
|
|
+
|
|
|
+ HttpEntity<Map<String, Object>> analyzeEntity = new HttpEntity<>(analyzeRequest, analyzeHeaders);
|
|
|
+
|
|
|
+ ResponseEntity<String> analyzeResp = null;
|
|
|
+ try {
|
|
|
+ analyzeResp = restTemplate.postForEntity(userComplaintRecordUrl, analyzeEntity, String.class);
|
|
|
+ } catch (org.springframework.web.client.HttpServerErrorException.ServiceUnavailable e) {
|
|
|
+ log.error("调用提交用户投诉审核任务接口返回503 Service Unavailable错误: {}", e.getResponseBodyAsString());
|
|
|
+ return null;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("调用提交用户投诉审核任务接口异常", e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (analyzeResp != null && analyzeResp.getStatusCodeValue() == 200) {
|
|
|
+ String analyzeBody = analyzeResp.getBody();
|
|
|
+ log.info("提交用户投诉审核任务提交成功, 返回: {}", analyzeBody);
|
|
|
+
|
|
|
+ JSONObject analyzeJson = JSONObject.parseObject(analyzeBody);
|
|
|
+ JSONObject dataJsonObj = analyzeJson.getJSONObject("data");
|
|
|
+
|
|
|
+ if (dataJsonObj == null) {
|
|
|
+ log.error("提交用户投诉审核任务返回数据为空");
|
|
|
+ R.fail("提交用户投诉审核任务返回数据为空");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取record_id用于后续查询
|
|
|
+ Integer taskId = dataJsonObj.getInteger("task_id");
|
|
|
+ if (taskId == null) {
|
|
|
+ log.error("提交用户投诉审核任务返回record_id为空");
|
|
|
+ R.fail("提交用户投诉审核任务返回record_id为空");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return taskId.toString();
|
|
|
+ } else {
|
|
|
+ if (analyzeResp != null) {
|
|
|
+ log.error("调用提交用户投诉审核任务接口失败, http状态: {}", analyzeResp.getStatusCode());
|
|
|
+ R.fail("调用提交用户投诉审核任务接口失败, http状态: " + analyzeResp.getStatusCode());
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取双方用户的最近聊天记录
|
|
|
+ * @param userReporterUserById 举报人ID
|
|
|
+ * @param userReportedUserById 被举报人ID
|
|
|
+ * @return 聊天记录列表
|
|
|
+ */
|
|
|
+ public List<LifeMessage> getRecentChatMessages(String userReporterUserById, String userReportedUserById) {
|
|
|
+ // 构建查询条件
|
|
|
+ QueryWrapper<LifeMessage> queryWrapper = new QueryWrapper<>();
|
|
|
+
|
|
|
+ // 查询双方的聊天记录
|
|
|
+ queryWrapper.and(wrapper -> wrapper
|
|
|
+ .eq("sender_id", userReporterUserById)
|
|
|
+ .eq("receiver_id", userReportedUserById))
|
|
|
+ .or(wrapper -> wrapper
|
|
|
+ .eq("sender_id", userReportedUserById)
|
|
|
+ .eq("receiver_id", userReporterUserById));
|
|
|
+
|
|
|
+ // 按时间倒序排列
|
|
|
+ queryWrapper.orderByDesc("create_time");
|
|
|
+
|
|
|
+ // 限制50条记录
|
|
|
+ queryWrapper.last("LIMIT 50");
|
|
|
+
|
|
|
+ return lifeMessageMapper.selectList(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将聊天消息列表转换为文本格式
|
|
|
+ * @param messages 聊天消息列表
|
|
|
+ * @return 格式化后的文本字符串
|
|
|
+ */
|
|
|
+ private String convertMessagesToText(List<LifeMessage> messages) {
|
|
|
+ if (messages == null || messages.isEmpty()) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ // 按时间顺序排列(因为数据库查询是倒序的,这里需要重新排序)
|
|
|
+ for (int i = messages.size() - 1; i >= 0; i--) {
|
|
|
+ LifeMessage message = messages.get(i);
|
|
|
+ // 格式:[时间] 发送者ID: 消息内容
|
|
|
+ sb.append("[").append(formatTime(message.getCreatedTime())).append("] ")
|
|
|
+ .append(message.getSenderId()).append(": ")
|
|
|
+ .append(message.getContent()).append("\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ return sb.toString().trim();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 格式化时间显示
|
|
|
+ * @param date 时间
|
|
|
+ * @return 格式化后的时间字符串
|
|
|
+ */
|
|
|
+ private String formatTime(Date date) {
|
|
|
+ if (date == null) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ return sdf.format(date);
|
|
|
+ }
|
|
|
+}
|