|
@@ -6,21 +6,31 @@ import com.xxl.job.core.context.XxlJobHelper;
|
|
|
import com.xxl.job.core.handler.annotation.XxlJob;
|
|
import com.xxl.job.core.handler.annotation.XxlJob;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.apache.commons.collections4.map.HashedMap;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.http.HttpEntity;
|
|
import org.springframework.http.HttpEntity;
|
|
|
import org.springframework.http.HttpHeaders;
|
|
import org.springframework.http.HttpHeaders;
|
|
|
import org.springframework.http.MediaType;
|
|
import org.springframework.http.MediaType;
|
|
|
import org.springframework.http.ResponseEntity;
|
|
import org.springframework.http.ResponseEntity;
|
|
|
|
|
+import org.springframework.http.client.ClientHttpRequestInterceptor;
|
|
|
import org.springframework.stereotype.Component;
|
|
import org.springframework.stereotype.Component;
|
|
|
import org.springframework.util.LinkedMultiValueMap;
|
|
import org.springframework.util.LinkedMultiValueMap;
|
|
|
import org.springframework.util.MultiValueMap;
|
|
import org.springframework.util.MultiValueMap;
|
|
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
import org.springframework.web.client.RestTemplate;
|
|
import org.springframework.web.client.RestTemplate;
|
|
|
|
|
+import shop.alien.entity.store.StoreComment;
|
|
|
import shop.alien.entity.store.StoreCommentAppeal;
|
|
import shop.alien.entity.store.StoreCommentAppeal;
|
|
|
import shop.alien.entity.result.R;
|
|
import shop.alien.entity.result.R;
|
|
|
import shop.alien.mapper.StoreCommentAppealMapper;
|
|
import shop.alien.mapper.StoreCommentAppealMapper;
|
|
|
|
|
+import shop.alien.mapper.StoreCommentMapper;
|
|
|
|
|
|
|
|
|
|
+import java.net.URI;
|
|
|
|
|
+import java.net.URISyntaxException;
|
|
|
import java.time.LocalDate;
|
|
import java.time.LocalDate;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.time.format.DateTimeFormatter;
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 调用AI差评申诉辅助系统服务类
|
|
* 调用AI差评申诉辅助系统服务类
|
|
@@ -37,8 +47,13 @@ public class BadReviewAppealJob {
|
|
|
|
|
|
|
|
private final StoreCommentAppealMapper storeCommentAppealMapper;
|
|
private final StoreCommentAppealMapper storeCommentAppealMapper;
|
|
|
|
|
|
|
|
- @Value("${third-party-login.base-url}")
|
|
|
|
|
- private String loginUrl;
|
|
|
|
|
|
|
+ private final StoreCommentMapper storeCommentMapper;
|
|
|
|
|
+
|
|
|
|
|
+// @Value("${third-party-login.base-url}")
|
|
|
|
|
+// private String loginUrl;
|
|
|
|
|
+
|
|
|
|
|
+ private String loginUrl = "http://192.168.2.250:9000/ai/user-auth-core/api/v1/auth/login";
|
|
|
|
|
+
|
|
|
|
|
|
|
|
@Value("${third-party-user-name.base-url}")
|
|
@Value("${third-party-user-name.base-url}")
|
|
|
private String userName;
|
|
private String userName;
|
|
@@ -46,160 +61,352 @@ public class BadReviewAppealJob {
|
|
|
@Value("${third-party-pass-word.base-url}")
|
|
@Value("${third-party-pass-word.base-url}")
|
|
|
private String passWord;
|
|
private String passWord;
|
|
|
|
|
|
|
|
|
|
+ private String analyzeUrl = "http://192.168.2.250:9000/ai/auto-review/api/v1/analyze";
|
|
|
|
|
+
|
|
|
|
|
+ private String resultUrl = "http://192.168.2.250:9000/ai/auto-review";
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 差评申述置信度分析接口地址
|
|
* 差评申述置信度分析接口地址
|
|
|
* 例如: http://192.168.2.250:9004/api/v1/analyze 或通过网关: http://192.168.2.250:9000/ai/auto_review/api/v1/analyze
|
|
* 例如: http://192.168.2.250:9004/api/v1/analyze 或通过网关: http://192.168.2.250:9000/ai/auto_review/api/v1/analyze
|
|
|
*/
|
|
*/
|
|
|
- @Value("${bad-review-analyze.base-url}")
|
|
|
|
|
- private String analyzeUrl;
|
|
|
|
|
|
|
+// @Value("${bad-review-analyze.base-url}")
|
|
|
|
|
+// private String analyzeUrl;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 调用AI服务获取Token
|
|
* 调用AI服务获取Token
|
|
|
*/
|
|
*/
|
|
|
- @XxlJob("badReviewAppealJob")
|
|
|
|
|
- public R<String> badReviewAppealJob() {
|
|
|
|
|
- log.info("登录Ai服务获取token..." + loginUrl);
|
|
|
|
|
- //构建请求参数
|
|
|
|
|
- MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
|
|
|
|
|
- formData.add("username", userName); // 表单字段 1:用户名
|
|
|
|
|
- formData.add("password", passWord); // 表单字段 2:密码
|
|
|
|
|
|
|
+ @XxlJob("getBadReviewAppealJob")
|
|
|
|
|
+ public R<String> getBadReviewAppealJob() {
|
|
|
|
|
+ String accessToken = fetchAiServiceToken();
|
|
|
|
|
+ if (!StringUtils.hasText(accessToken)) {
|
|
|
|
|
+ return R.fail("调用差评申诉辅助系统登录任务执行失败 返回异常");
|
|
|
|
|
+ }
|
|
|
|
|
+ return invokeAnalyzeTask(accessToken);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- HttpHeaders headers = new HttpHeaders();
|
|
|
|
|
- headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
|
|
|
|
- HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);
|
|
|
|
|
- ResponseEntity<String> postForEntity = null;
|
|
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- log.info("请求差评申诉辅助系统登录接口===================>");
|
|
|
|
|
- postForEntity = restTemplate.postForEntity(loginUrl, requestEntity, String.class);
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- log.error("调用差评申诉辅助系统登录接口异常", e);
|
|
|
|
|
|
|
+ @XxlJob("getAppealCompletedResult")
|
|
|
|
|
+ public R<String> getAppealCompletedResult() {
|
|
|
|
|
+ String accessToken = fetchAiServiceToken();
|
|
|
|
|
+ if (!StringUtils.hasText(accessToken)) {
|
|
|
|
|
+ return R.fail("调用差评申诉辅助系统 登录接口失败");
|
|
|
}
|
|
}
|
|
|
|
|
+ return getNegativeReviewAppealCompletedResult(accessToken);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (postForEntity != null) {
|
|
|
|
|
- if (postForEntity.getStatusCodeValue() == 200) {
|
|
|
|
|
- log.info("差评申诉辅助系统登录成功 postForEntity.getBody()\t{}", postForEntity.getBody());
|
|
|
|
|
- String responseBody = postForEntity.getBody();
|
|
|
|
|
- JSONObject jsonObject = JSONObject.parseObject(responseBody);
|
|
|
|
|
- JSONObject dataJson = jsonObject.getJSONObject("data");
|
|
|
|
|
- String accessToken = dataJson.getString("access_token");
|
|
|
|
|
- // 调用差评申述置信度分析任务
|
|
|
|
|
- return invokeAnalyzeTask(accessToken);
|
|
|
|
|
- } else {
|
|
|
|
|
- log.error("请求差评申诉辅助系统 登录接口失败 http状态:" + postForEntity.getStatusCode());
|
|
|
|
|
- return R.fail("请求差评申诉辅助系统 登录接口失败 http状态:" + postForEntity.getStatusCode());
|
|
|
|
|
|
|
+ private R<String> getNegativeReviewAppealCompletedResult(String accessToken) {
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ HttpHeaders analyzeHeaders = new HttpHeaders();
|
|
|
|
|
+ analyzeHeaders.setContentType(MediaType.APPLICATION_JSON);
|
|
|
|
|
+ analyzeHeaders.set("Authorization", "Bearer " + accessToken);
|
|
|
|
|
+ // 查询所有状态为处理中的申诉
|
|
|
|
|
+ List<StoreCommentAppeal> pendingAppeals = storeCommentAppealMapper.getPendingAppeals();
|
|
|
|
|
+ // 循环调用查询结果接口
|
|
|
|
|
+ for (StoreCommentAppeal appeal : pendingAppeals) {
|
|
|
|
|
+ String completedUrl = buildCompletedUrl(appeal.getRecordId());
|
|
|
|
|
+
|
|
|
|
|
+ ResponseEntity<String> analyzeResp;
|
|
|
|
|
+
|
|
|
|
|
+ RestTemplate restTemplateWithAuth = new RestTemplate();
|
|
|
|
|
+ List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
|
|
|
|
|
+ interceptors.add((request, body, execution) -> {
|
|
|
|
|
+ request.getHeaders().set("Authorization", "Bearer " + accessToken);
|
|
|
|
|
+ return execution.execute(request, body);
|
|
|
|
|
+ });
|
|
|
|
|
+ restTemplateWithAuth.setInterceptors(interceptors);
|
|
|
|
|
+
|
|
|
|
|
+ ResponseEntity<String> response = null;
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ analyzeResp = restTemplateWithAuth.getForEntity(completedUrl, String.class);
|
|
|
|
|
+
|
|
|
|
|
+ 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("差评申述置信度分析返回数据为空");
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取record_id用于后续查询
|
|
|
|
|
+ Integer recordId = dataJsonObj.getInteger("record_id");
|
|
|
|
|
+ if (recordId == null) {
|
|
|
|
|
+ log.error("差评申述置信度分析返回record_id为空");
|
|
|
|
|
+ R.fail("差评申述置信度分析返回record_id为空");
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ StoreCommentAppeal sCommentAppeal = new StoreCommentAppeal();
|
|
|
|
|
+ sCommentAppeal.setRecordId(appeal.getRecordId());
|
|
|
|
|
+ // 判断得分大小
|
|
|
|
|
+ if (dataJsonObj.getDouble("user_confidence") > dataJsonObj.getDouble("merchant_confidence")){
|
|
|
|
|
+ sCommentAppeal.setAppealStatus(1);
|
|
|
|
|
+ sCommentAppeal.setFinalResult("已驳回");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ sCommentAppeal.setAppealStatus(2);
|
|
|
|
|
+ sCommentAppeal.setFinalResult("已同意");
|
|
|
|
|
+ //假删除评论
|
|
|
|
|
+ StoreComment storeComment = new StoreComment();
|
|
|
|
|
+ storeComment.setId(appeal.getCommentId());
|
|
|
|
|
+ storeComment.setDeleteFlag(1);
|
|
|
|
|
+ storeCommentMapper.updateById(storeComment);
|
|
|
|
|
+ }
|
|
|
|
|
+ sCommentAppeal.setAppealAiApproval(dataJsonObj.toJSONString());
|
|
|
|
|
+
|
|
|
|
|
+ sCommentAppeal.setRecordId(recordId);
|
|
|
|
|
+ storeCommentAppealMapper.updateByRecordId(appeal.getRecordId(),
|
|
|
|
|
+ sCommentAppeal.getAppealStatus(),
|
|
|
|
|
+ sCommentAppeal.getFinalResult());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (analyzeResp != null) {
|
|
|
|
|
+ log.error("调用差评申述置信度分析接口失败, http状态: {}", analyzeResp.getStatusCode());
|
|
|
|
|
+ R.fail("调用差评申述置信度分析接口失败, http状态: " + analyzeResp.getStatusCode());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("调用差评申述查询结果接口异常", e);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- XxlJobHelper.handleFail("调用差评申诉辅助系统登录任务执行失败 返回异常");
|
|
|
|
|
- return R.fail("调用差评申诉辅助系统登录任务执行失败 返回异常");
|
|
|
|
|
-
|
|
|
|
|
|
|
+ return R.success("调用差评申述置信度分析结果接口完成");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private R<String> invokeAnalyzeTask(String token) {
|
|
|
|
|
- log.info("开始调用差评申述置信度分析接口, url: {}", analyzeUrl);
|
|
|
|
|
-
|
|
|
|
|
- // 获取当前日期
|
|
|
|
|
- LocalDate today = LocalDate.now();
|
|
|
|
|
|
|
|
|
|
- // 获取当月第一天
|
|
|
|
|
- LocalDate firstDayOfMonth = today.withDayOfMonth(1);
|
|
|
|
|
|
|
|
|
|
- // 获取当月最后一天
|
|
|
|
|
- LocalDate lastDayOfMonth = today.withDayOfMonth(today.lengthOfMonth());
|
|
|
|
|
|
|
|
|
|
- // 格式化为字符串(可根据需要调整格式)
|
|
|
|
|
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
|
|
- String startDate = firstDayOfMonth.format(formatter);
|
|
|
|
|
- String endDate = lastDayOfMonth.format(formatter);
|
|
|
|
|
|
|
+ private R<String> invokeAnalyzeTask(String token) {
|
|
|
|
|
+ log.info("开始调用差评申述置信度分析接口, url: {}", analyzeUrl);
|
|
|
|
|
|
|
|
HttpHeaders analyzeHeaders = new HttpHeaders();
|
|
HttpHeaders analyzeHeaders = new HttpHeaders();
|
|
|
analyzeHeaders.setContentType(MediaType.APPLICATION_JSON);
|
|
analyzeHeaders.setContentType(MediaType.APPLICATION_JSON);
|
|
|
analyzeHeaders.set("Authorization", "Bearer " + token);
|
|
analyzeHeaders.set("Authorization", "Bearer " + token);
|
|
|
|
|
|
|
|
- AnalyzeRequest analyzeRequest = new AnalyzeRequest();
|
|
|
|
|
- analyzeRequest.setStart_time(startDate + "T00:00:00");
|
|
|
|
|
- analyzeRequest.setEnd_time(endDate + "T23:59:59");
|
|
|
|
|
|
|
+ // 查询一段时间内的差评申述
|
|
|
|
|
+ // 循环插入
|
|
|
|
|
+ List<Map<String, Object>> appealList = storeCommentAppealMapper.getAppealList();
|
|
|
|
|
|
|
|
- HttpEntity<AnalyzeRequest> analyzeEntity = new HttpEntity<>(analyzeRequest, analyzeHeaders);
|
|
|
|
|
- ResponseEntity<String> analyzeResp = null;
|
|
|
|
|
- try {
|
|
|
|
|
- analyzeResp = restTemplate.postForEntity(analyzeUrl, analyzeEntity, String.class);
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- log.error("调用差评申述置信度分析接口异常", e);
|
|
|
|
|
|
|
+ if (appealList == null || appealList.isEmpty()) {
|
|
|
|
|
+ log.info("没有需要处理的差评申述");
|
|
|
|
|
+ return R.success("没有需要处理的差评申述");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (analyzeResp != null) {
|
|
|
|
|
- if (analyzeResp.getStatusCodeValue() == 200) {
|
|
|
|
|
- log.info("postForEntity.getBody()\t" + analyzeResp.getStatusCode());
|
|
|
|
|
|
|
+ for (Map<String, Object> storeCommentAppeal : appealList) {
|
|
|
|
|
+ Map<String, Object> analyzeRequest = new HashedMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 商家申诉材料
|
|
|
|
|
+ analyzeRequest.put("merchant_material",
|
|
|
|
|
+ storeCommentAppeal.get("appeal_reason") == null ? "" : storeCommentAppeal.get("appeal_reason").toString());
|
|
|
|
|
+
|
|
|
|
|
+ // 用户差评内容
|
|
|
|
|
+ analyzeRequest.put("user_material",
|
|
|
|
|
+ storeCommentAppeal.get("comment_content") == null ? "" : storeCommentAppeal.get("comment_content").toString());
|
|
|
|
|
+
|
|
|
|
|
+ // 商家图片:支持多张,转成 Base64 数组
|
|
|
|
|
+ List<String> merchantImages = new ArrayList<>();
|
|
|
|
|
+ String imgUrls = storeCommentAppeal.get("img_url") == null ? "" : storeCommentAppeal.get("img_url").toString();
|
|
|
|
|
+ if (StringUtils.hasText(imgUrls)) {
|
|
|
|
|
+ // 假设 img_url 是多个图片用逗号分隔的字符串
|
|
|
|
|
+ for (String imageUrl : imgUrls.split(",")) {
|
|
|
|
|
+ String base64 = convertImageToBase64(imageUrl.trim());
|
|
|
|
|
+ if (StringUtils.hasText(base64)) {
|
|
|
|
|
+ merchantImages.add(base64);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ analyzeRequest.put("merchant_images", merchantImages);
|
|
|
|
|
+
|
|
|
|
|
+ // 用户图片:同理
|
|
|
|
|
+ List<String> userImages = new ArrayList<>();
|
|
|
|
|
+ String userImgUrls = storeCommentAppeal.get("user_img_url") == null ? "" : storeCommentAppeal.get("user_img_url").toString();
|
|
|
|
|
+ if (StringUtils.hasText(userImgUrls)) {
|
|
|
|
|
+ for (String imageUrl : userImgUrls.split(",")) {
|
|
|
|
|
+ String base64 = convertImageToBase64(imageUrl.trim());
|
|
|
|
|
+ if (StringUtils.hasText(base64)) {
|
|
|
|
|
+ userImages.add(base64);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ analyzeRequest.put("user_images", userImages);
|
|
|
|
|
+
|
|
|
|
|
+ // 其他字段
|
|
|
|
|
+ analyzeRequest.put("case_id", storeCommentAppeal.get("comment_id") == null ? "" : storeCommentAppeal.get("comment_id").toString());
|
|
|
|
|
+ analyzeRequest.put("order_id", storeCommentAppeal.get("business_id") == null ? "" : storeCommentAppeal.get("business_id").toString());
|
|
|
|
|
+
|
|
|
|
|
+ HttpEntity<Map<String, Object>> analyzeEntity = new HttpEntity<>(analyzeRequest, analyzeHeaders);
|
|
|
|
|
+
|
|
|
|
|
+ ResponseEntity<String> analyzeResp = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ analyzeResp = restTemplate.postForEntity(analyzeUrl, analyzeEntity, String.class);
|
|
|
|
|
+ } catch (org.springframework.web.client.HttpServerErrorException.ServiceUnavailable e) {
|
|
|
|
|
+ log.error("调用差评申述置信度分析接口返回503 Service Unavailable错误: {}", e.getResponseBodyAsString());
|
|
|
|
|
+ continue;
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("调用差评申述置信度分析接口异常", e);
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (analyzeResp != null && analyzeResp.getStatusCodeValue() == 200) {
|
|
|
String analyzeBody = analyzeResp.getBody();
|
|
String analyzeBody = analyzeResp.getBody();
|
|
|
- log.info("差评申述置信度分析成功, 返回: {}", analyzeBody);
|
|
|
|
|
|
|
+ log.info("差评申述置信度分析提交成功, 返回: {}", analyzeBody);
|
|
|
|
|
|
|
|
JSONObject analyzeJson = JSONObject.parseObject(analyzeBody);
|
|
JSONObject analyzeJson = JSONObject.parseObject(analyzeBody);
|
|
|
- JSONObject dataJsonObj = null;
|
|
|
|
|
- if (analyzeJson != null) {
|
|
|
|
|
- dataJsonObj = analyzeJson.getJSONObject("data");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ JSONObject dataJsonObj = analyzeJson.getJSONObject("data");
|
|
|
|
|
+
|
|
|
if (dataJsonObj == null) {
|
|
if (dataJsonObj == null) {
|
|
|
log.error("差评申述置信度分析返回数据为空");
|
|
log.error("差评申述置信度分析返回数据为空");
|
|
|
- XxlJobHelper.handleFail("差评申述置信度分析返回数据为空");
|
|
|
|
|
- return R.fail("差评申述置信度分析返回数据为空");
|
|
|
|
|
|
|
+ R.fail("差评申述置信度分析返回数据为空");
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取record_id用于后续查询
|
|
|
|
|
+ Integer recordId = dataJsonObj.getInteger("record_id");
|
|
|
|
|
+ if (recordId == null) {
|
|
|
|
|
+ log.error("差评申述置信度分析返回record_id为空");
|
|
|
|
|
+ R.fail("差评申述置信度分析返回record_id为空");
|
|
|
|
|
+ continue;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- StoreCommentAppeal storeCommentAppeal = new StoreCommentAppeal();
|
|
|
|
|
-// storeCommentAppeal.setStoreId(dataJsonObj.get());
|
|
|
|
|
-// storeCommentAppeal.setCommentId(appealParam.getCommentId());
|
|
|
|
|
-// storeCommentAppeal.setAppealReason(appealParam.getMerchantMaterial());
|
|
|
|
|
-// storeCommentAppeal.setFinalResult(dataJsonObj.toJSONString());
|
|
|
|
|
-// storeCommentAppeal.setAppealStatus(0);
|
|
|
|
|
-// storeCommentAppeal.setDeleteFlag(0);
|
|
|
|
|
-// storeCommentAppealMapper.insert(storeCommentAppeal);
|
|
|
|
|
-
|
|
|
|
|
- XxlJobHelper.handleSuccess("差评申述置信度分析任务执行成功并写入 store_comment_appeal");
|
|
|
|
|
- return R.success("差评申述置信度分析成功,已写入 store_comment_appeal 表");
|
|
|
|
|
|
|
+ //修改评论状态为"处理中"
|
|
|
|
|
+ StoreCommentAppeal sCommentAppeal = new StoreCommentAppeal();
|
|
|
|
|
+ sCommentAppeal.setId((Integer) storeCommentAppeal.get("id"));
|
|
|
|
|
+ sCommentAppeal.setAppealStatus(0);
|
|
|
|
|
+ sCommentAppeal.setRecordId(recordId);
|
|
|
|
|
+ storeCommentAppealMapper.updateById(sCommentAppeal);
|
|
|
|
|
+
|
|
|
} else {
|
|
} else {
|
|
|
- log.error("调用差评申述置信度分析接口失败, http状态: {}", analyzeResp.getStatusCode());
|
|
|
|
|
- XxlJobHelper.handleFail("调用差评申述置信度分析接口失败, http状态:" + analyzeResp.getStatusCode());
|
|
|
|
|
- return R.fail("调用差评申述置信度分析接口失败 http状态:" + analyzeResp.getStatusCode());
|
|
|
|
|
|
|
+ if (analyzeResp != null) {
|
|
|
|
|
+ log.error("调用差评申述置信度分析接口失败, http状态: {}", analyzeResp.getStatusCode());
|
|
|
|
|
+ R.fail("调用差评申述置信度分析接口失败, http状态: " + analyzeResp.getStatusCode());
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- log.error("调用差评申述置信度分析接口返回为空或异常");
|
|
|
|
|
- XxlJobHelper.handleFail("调用差评申述置信度分析接口返回为空或异常");
|
|
|
|
|
- return R.fail("调用差评申述置信度分析接口返回为空或异常");
|
|
|
|
|
|
|
+ return R.success("调用差评申述置信度分析接口完成");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 差评申述置信度分析请求体
|
|
|
|
|
|
|
+ * 将图片URL转换为Base64编码
|
|
|
*
|
|
*
|
|
|
- * 对应文档中的:
|
|
|
|
|
- * {
|
|
|
|
|
- * "merchant_material": "商家申述材料内容(必填)",
|
|
|
|
|
- * "user_material": "用户举证材料内容(必填)",
|
|
|
|
|
- * "order_id": "关联订单ID(可选)",
|
|
|
|
|
- * "case_id": "申述案件ID(可选)",
|
|
|
|
|
- * "merchant_images": [...],
|
|
|
|
|
- * "user_images": [...]
|
|
|
|
|
- * }
|
|
|
|
|
|
|
+ * @param imageUrl 图片URL
|
|
|
|
|
+ * @return Base64编码字符串
|
|
|
*/
|
|
*/
|
|
|
- class AnalyzeRequest {
|
|
|
|
|
- private String start_time;
|
|
|
|
|
- private String end_time;
|
|
|
|
|
|
|
+ private String convertImageToBase64(String imageUrl) {
|
|
|
|
|
+ // 1. 检查是否为空
|
|
|
|
|
+ if (!StringUtils.hasText(imageUrl)) {
|
|
|
|
|
+ log.warn("图片URL为空");
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 对URL进行编码处理(解决特殊字符问题)
|
|
|
|
|
+ String encodedUrl = encodeImageUrl(imageUrl);
|
|
|
|
|
|
|
|
- public String getStart_time() {
|
|
|
|
|
- return start_time;
|
|
|
|
|
|
|
+ // 3. 验证URL格式
|
|
|
|
|
+ if (!isValidUrl(encodedUrl)) {
|
|
|
|
|
+ log.warn("无效的图片URL: {}", imageUrl);
|
|
|
|
|
+ return "";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public void setStart_time(String start_time) {
|
|
|
|
|
- this.start_time = start_time;
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 4. 下载图片并转换Base64
|
|
|
|
|
+ byte[] imageBytes = restTemplate.getForObject(encodedUrl, byte[].class);
|
|
|
|
|
+ if (imageBytes != null) {
|
|
|
|
|
+ return java.util.Base64.getEncoder().encodeToString(imageBytes);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (org.springframework.web.client.HttpClientErrorException.NotFound e) {
|
|
|
|
|
+ log.warn("图片不存在 (404), URL: {}", imageUrl);
|
|
|
|
|
+ return "";
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("图片转换为Base64失败, URL: {}", imageUrl, e);
|
|
|
|
|
+ return "";
|
|
|
}
|
|
}
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 新增方法:对URL中的特殊字符进行编码
|
|
|
|
|
+ private String encodeImageUrl(String imageUrl) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ URI uri = new URI(imageUrl);
|
|
|
|
|
+ String scheme = uri.getScheme();
|
|
|
|
|
+ String host = uri.getHost();
|
|
|
|
|
+ String path = uri.getPath();
|
|
|
|
|
+ String query = uri.getQuery();
|
|
|
|
|
+
|
|
|
|
|
+ // 对路径中的特殊字符进行编码
|
|
|
|
|
+ String encodedPath = java.net.URLEncoder.encode(path, "UTF-8")
|
|
|
|
|
+ .replace("%2F", "/") // 保留斜杠
|
|
|
|
|
+ .replace("+", "%20"); // 空格编码
|
|
|
|
|
+
|
|
|
|
|
+ StringBuilder encodedUrl = new StringBuilder();
|
|
|
|
|
+ encodedUrl.append(scheme).append("://").append(host).append(encodedPath);
|
|
|
|
|
+
|
|
|
|
|
+ if (query != null) {
|
|
|
|
|
+ encodedUrl.append("?").append(query);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- public String getEnd_time() {
|
|
|
|
|
- return end_time;
|
|
|
|
|
|
|
+ return encodedUrl.toString();
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("URL编码失败,使用原始URL: {}", imageUrl);
|
|
|
|
|
+ return imageUrl;
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
|
|
|
- public void setEnd_time(String end_time) {
|
|
|
|
|
- this.end_time = end_time;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 辅助方法:验证URL格式合法性
|
|
|
|
|
+ private boolean isValidUrl(String url) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 尝试构造URI,验证格式
|
|
|
|
|
+ new URI(url);
|
|
|
|
|
+ // 进一步检查是否以http/https开头(可选,根据业务需求)
|
|
|
|
|
+ return url.startsWith("http://") || url.startsWith("https://");
|
|
|
|
|
+ } catch (URISyntaxException e) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String fetchAiServiceToken() {
|
|
|
|
|
+ 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);
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ ResponseEntity<String> response = restTemplate.postForEntity(loginUrl, requestEntity, String.class);
|
|
|
|
|
+ if (response != null && response.getStatusCodeValue() == 200 && response.getBody() != null) {
|
|
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(response.getBody());
|
|
|
|
|
+ JSONObject dataJson = jsonObject.getJSONObject("data");
|
|
|
|
|
+ return dataJson != null ? dataJson.getString("access_token") : null;
|
|
|
|
|
+ }
|
|
|
|
|
+ log.error("请求差评申诉辅助系统 登录接口失败 http状态:{}", response != null ? response.getStatusCode() : null);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("调用差评申诉辅助系统登录接口异常", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String buildCompletedUrl(Integer recordId) {
|
|
|
|
|
+ String baseUrl = resultUrl;
|
|
|
|
|
+ if (!StringUtils.hasText(baseUrl)) {
|
|
|
|
|
+ throw new IllegalStateException("差评申述分析接口地址未配置");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (baseUrl.endsWith("/")) {
|
|
|
|
|
+ baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ String completedBase = baseUrl.replace("/api/v1/analyze", "");
|
|
|
|
|
+ if (!completedBase.endsWith("/")) {
|
|
|
|
|
+ completedBase = completedBase + "/";
|
|
|
}
|
|
}
|
|
|
|
|
+ return completedBase + "api/v1/records/" + recordId + "/completed";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|