|
|
@@ -1,17 +1,41 @@
|
|
|
package shop.alien.store.controller;
|
|
|
|
|
|
+import com.alibaba.fastjson2.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
import io.swagger.annotations.*;
|
|
|
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.HttpEntity;
|
|
|
+import org.springframework.http.HttpHeaders;
|
|
|
+import org.springframework.http.HttpMethod;
|
|
|
+import org.springframework.http.MediaType;
|
|
|
+import org.springframework.http.ResponseEntity;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.util.LinkedMultiValueMap;
|
|
|
+import org.springframework.util.MultiValueMap;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
+import org.springframework.web.client.RestTemplate;
|
|
|
import shop.alien.entity.result.R;
|
|
|
+import shop.alien.entity.store.StoreComment;
|
|
|
+import shop.alien.entity.store.StoreCommentAppeal;
|
|
|
+import shop.alien.entity.store.vo.StoreCommentAppealVo;
|
|
|
+import shop.alien.mapper.StoreCommentAppealMapper;
|
|
|
+import shop.alien.mapper.StoreCommentMapper;
|
|
|
import shop.alien.store.service.LifeUserStoreService;
|
|
|
import shop.alien.util.common.AlipayTradeAppPay;
|
|
|
import shop.alien.util.common.ListToPage;
|
|
|
import shop.alien.util.common.UniqueRandomNumGenerator;
|
|
|
|
|
|
+import java.net.URI;
|
|
|
+import java.net.URISyntaxException;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.Collections;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
|
|
|
@@ -25,6 +49,30 @@ public class UserStoreController {
|
|
|
|
|
|
private final LifeUserStoreService lifeUserStoreService;
|
|
|
|
|
|
+ private final RestTemplate restTemplate;
|
|
|
+
|
|
|
+ private final StoreCommentAppealMapper storeCommentAppealMapper;
|
|
|
+
|
|
|
+ private final StoreCommentMapper storeCommentMapper;
|
|
|
+
|
|
|
+// @Value("${third-party-login.base-url}")
|
|
|
+ private String loginUrl = "http://192.168.2.250:9000/ai/user-auth-core/api/v1/auth/login";
|
|
|
+
|
|
|
+ private String resultUrl = "http://192.168.2.250:9000/ai/auto-review/api/v1/records/{record_id}/completed";
|
|
|
+
|
|
|
+// @Value("${third-party-user-name.base-url}")
|
|
|
+ private String userName = "UdUser";
|
|
|
+
|
|
|
+// @Value("${third-party-pass-word.base-url}")
|
|
|
+ private String passWord = "123456";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 差评申述置信度分析接口地址
|
|
|
+ * 例如: 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 = "http://192.168.2.250:9000/ai/auto-review/api/v1/analyze";
|
|
|
+
|
|
|
@ApiOperation("查询商铺列表")
|
|
|
@ApiOperationSupport(order = 1)
|
|
|
@ApiImplicitParams({@ApiImplicitParam(name = "page", value = "分页页数", dataType = "String", paramType = "query", required = true),
|
|
|
@@ -118,4 +166,256 @@ public class UserStoreController {
|
|
|
log.info("LifeUserStoreController.buyQuan?quanId={},couponId={},userId={},cnt={},payPrice={},orderNo={}", quanId, couponId, userId, cnt, payPrice, orderNo);
|
|
|
return R.data(lifeUserStoreService.buyQuan(quanId, couponId, userId, cnt, payPrice, orderNo));
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ @PostMapping("/getBadReviewAppealJob")
|
|
|
+ @ApiOperation("调用查询差评申诉")
|
|
|
+ public R<String> getBadReviewAppealJob() {
|
|
|
+ String accessToken = fetchAiServiceToken();
|
|
|
+ if (!StringUtils.hasText(accessToken)) {
|
|
|
+ return R.fail("调用差评申诉辅助系统登录任务执行失败 返回异常");
|
|
|
+ }
|
|
|
+ return invokeAnalyzeTask(accessToken);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("差评申述处理完成结果查询")
|
|
|
+ @GetMapping("/getAppealCompletedResult")
|
|
|
+ public R<String> getAppealCompletedResult() {
|
|
|
+ String accessToken = fetchAiServiceToken();
|
|
|
+ if (!StringUtils.hasText(accessToken)) {
|
|
|
+ return R.fail("调用差评申诉辅助系统 登录接口失败");
|
|
|
+ }
|
|
|
+ return getNegativeReviewAppealCompletedResult(accessToken);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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());
|
|
|
+ Map<String, Object> analyzeRequest = new HashedMap<>();
|
|
|
+ analyzeRequest.put("record_id", appeal.getRecordId());
|
|
|
+
|
|
|
+ HttpEntity<Map<String, Object>> analyzeEntity = new HttpEntity<>(analyzeRequest, analyzeHeaders);
|
|
|
+
|
|
|
+ ResponseEntity<String> analyzeResp;
|
|
|
+ try {
|
|
|
+ analyzeResp = restTemplate.postForEntity(completedUrl, analyzeEntity, 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);
|
|
|
+ } else {
|
|
|
+ sCommentAppeal.setAppealStatus(2);
|
|
|
+ //假删除评论
|
|
|
+ StoreComment storeComment = new StoreComment();
|
|
|
+ storeComment.setId(appeal.getCommentId());
|
|
|
+ storeComment.setDeleteFlag(1);
|
|
|
+ storeCommentMapper.updateById(storeComment);
|
|
|
+ }
|
|
|
+ sCommentAppeal.setFinalResult(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);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return R.success("调用差评申述置信度分析结果接口完成");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private R<String> invokeAnalyzeTask(String token) {
|
|
|
+ log.info("开始调用差评申述置信度分析接口, url: {}", analyzeUrl);
|
|
|
+
|
|
|
+ HttpHeaders analyzeHeaders = new HttpHeaders();
|
|
|
+ analyzeHeaders.setContentType(MediaType.APPLICATION_JSON);
|
|
|
+ analyzeHeaders.set("Authorization", "Bearer " + token);
|
|
|
+
|
|
|
+ // 查询一段时间内的差评申述
|
|
|
+ // 循环插入
|
|
|
+ List<Map<String, Object>> appealList = storeCommentAppealMapper.getAppealList();
|
|
|
+
|
|
|
+ if (appealList == null || appealList.isEmpty()) {
|
|
|
+ log.info("没有需要处理的差评申述");
|
|
|
+ return R.success("没有需要处理的差评申述");
|
|
|
+ }
|
|
|
+
|
|
|
+ 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());
|
|
|
+ analyzeRequest.put("merchant_images", storeCommentAppeal.get("img_url") == null ? "" :convertImageToBase64(storeCommentAppeal.get("img_url").toString()));
|
|
|
+ analyzeRequest.put("user_images", storeCommentAppeal.get("user_img_url") == null ? "" :convertImageToBase64(storeCommentAppeal.get("user_img_url").toString()));
|
|
|
+ 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 (Exception e) {
|
|
|
+ log.error("调用差评申述置信度分析接口异常", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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.setId((Integer) storeCommentAppeal.get("id"));
|
|
|
+ sCommentAppeal.setAppealStatus(3);
|
|
|
+ sCommentAppeal.setRecordId(recordId);
|
|
|
+ storeCommentAppealMapper.updateById(sCommentAppeal);
|
|
|
+
|
|
|
+ } else {
|
|
|
+ if (analyzeResp != null) {
|
|
|
+ log.error("调用差评申述置信度分析接口失败, http状态: {}", analyzeResp.getStatusCode());
|
|
|
+ R.fail("调用差评申述置信度分析接口失败, http状态: " + analyzeResp.getStatusCode());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return R.success("调用差评申述置信度分析接口完成");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将图片URL转换为Base64编码
|
|
|
+ *
|
|
|
+ * @param imageUrl 图片URL
|
|
|
+ * @return Base64编码字符串
|
|
|
+ */
|
|
|
+ private String convertImageToBase64(String imageUrl) {
|
|
|
+ // 1. 检查是否为空或非URL格式
|
|
|
+ if (!StringUtils.hasText(imageUrl) || !isValidUrl(imageUrl)) {
|
|
|
+ log.warn("无效的图片URL: {}", imageUrl);
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 2. 下载图片并转换Base64
|
|
|
+ byte[] imageBytes = restTemplate.getForObject(imageUrl, byte[].class);
|
|
|
+ if (imageBytes != null) {
|
|
|
+ return java.util.Base64.getEncoder().encodeToString(imageBytes);
|
|
|
+ }
|
|
|
+ } catch (org.springframework.web.client.HttpClientErrorException.NotFound e) {
|
|
|
+ // 专门处理404错误
|
|
|
+ log.warn("图片不存在 (404), URL: {}", imageUrl);
|
|
|
+ return ""; // 返回空字符串而不是抛出异常
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("图片转换为Base64失败, URL: {}", imageUrl, e);
|
|
|
+ return ""; // 其他异常也返回空字符串,避免中断整个流程
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 辅助方法:验证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 = analyzeUrl;
|
|
|
+ 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";
|
|
|
+ }
|
|
|
}
|