|
|
@@ -19,8 +19,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
import org.springframework.web.client.RestTemplate;
|
|
|
import shop.alien.entity.result.R;
|
|
|
+import shop.alien.entity.store.StoreImg;
|
|
|
import shop.alien.entity.store.StoreUser;
|
|
|
import shop.alien.entity.store.vo.StoreInfoVo;
|
|
|
+import shop.alien.mapper.StoreImgMapper;
|
|
|
import shop.alien.mapper.StoreUserMapper;
|
|
|
import shop.alien.store.service.StoreImgService;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
@@ -42,9 +44,13 @@ import java.util.Comparator;
|
|
|
@RefreshScope
|
|
|
public class AiSearchController {
|
|
|
|
|
|
- private final StoreUserMapper storeUserMapper;
|
|
|
- @Value("${third-party-ai-search.base-url:http://124.93.18.180:7870/api/v1/search}")
|
|
|
- private String aiSearchUrl;
|
|
|
+ private final StoreImgMapper storeImgMapper;
|
|
|
+
|
|
|
+ @Value("${third-party-ai-search.exact.base-url:http://124.93.18.180:7870/api/v1/search}")
|
|
|
+ private String aiSearchExactUrl;
|
|
|
+
|
|
|
+ @Value("${third-party-ai-search.fuzzy.base-url:http://124.93.18.180:7869/api/v1/search}")
|
|
|
+ private String aiSearchFuzzyUrl;
|
|
|
|
|
|
private final RestTemplate restTemplate;
|
|
|
private final StoreImgService storeImgService;
|
|
|
@@ -69,57 +75,28 @@ public class AiSearchController {
|
|
|
|
|
|
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, null);
|
|
|
try {
|
|
|
- ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(aiSearchUrl, request, String.class);
|
|
|
+
|
|
|
+ ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(aiSearchExactUrl, request, String.class);
|
|
|
String body = stringResponseEntity.getBody();
|
|
|
JSONObject jsonObject = JSONObject.parseObject(body);
|
|
|
JSONObject jsonObject1 = new JSONObject();
|
|
|
-// if ("生活服务".equals(requestBody.get("category")) || "休闲娱乐".equals(requestBody.get("category"))) {
|
|
|
- // 生活服务类别:转换为StoreInfoVo,确保返回的字段名按照StoreInfoVo定义
|
|
|
- List<StoreInfoVo> result = convertToStoreInfoList(jsonObject.getJSONArray("results"));
|
|
|
-
|
|
|
- // 从结果中提取所有的id,放到集合中
|
|
|
- List<Integer> storeIdList = result.stream()
|
|
|
- .map(StoreInfoVo::getId)
|
|
|
- .filter(id -> id != null)
|
|
|
- .collect(Collectors.toList());
|
|
|
-
|
|
|
- // 使用storeImgService批量查询,imgType为10
|
|
|
- List<StoreUser> storeImgList = new ArrayList<>();
|
|
|
- if (!storeIdList.isEmpty()) {
|
|
|
- QueryWrapper<StoreUser> queryWrapper = new QueryWrapper<>();
|
|
|
- queryWrapper.in("store_id", storeIdList);
|
|
|
- storeImgList = storeUserMapper.selectList(queryWrapper);
|
|
|
- }
|
|
|
+ // 生活服务类别:转换为StoreInfoVo,确保返回的字段名按照StoreInfoVo定义
|
|
|
+ // 模糊搜索:从related_results和matched_results字段获取数据
|
|
|
+ List<StoreInfoVo> relatedResult = convertToStoreInfoList(jsonObject.getJSONArray("related_results"));
|
|
|
+ List<StoreInfoVo> matchedResult = convertToStoreInfoList(jsonObject.getJSONArray("matched_results"));
|
|
|
+
|
|
|
+ // 查找图片并设置到result中(图片类型1-入口图)
|
|
|
+ fillStoreImages(relatedResult, 1);
|
|
|
+ fillStoreImages(matchedResult, 1);
|
|
|
+
|
|
|
+ // 合并两个列表
|
|
|
+// List<StoreInfoVo> relatedResults = new ArrayList<>();
|
|
|
+// List<StoreInfoVo> matchedResults = new ArrayList<>();
|
|
|
+// matchedResults.addAll(matchedResult);
|
|
|
+// relatedResults.addAll(relatedResult);
|
|
|
+ jsonObject1.put("matchedRecords", matchedResult);
|
|
|
+ jsonObject1.put("relatedRecords", relatedResult);
|
|
|
|
|
|
- // 将storeImgList按照storeId分组,并关联到对应的result中
|
|
|
- Map<Integer, List<StoreUser>> storeImgMap = storeImgList.stream()
|
|
|
- .collect(Collectors.groupingBy(StoreUser::getStoreId));
|
|
|
-
|
|
|
- // 将图片列表设置到对应的StoreInfoVo中
|
|
|
- for (StoreInfoVo storeInfo : result) {
|
|
|
- if (storeInfo.getId() != null) {
|
|
|
- List<StoreUser> imgs = storeImgMap.get(storeInfo.getId());
|
|
|
- if (imgs != null && !imgs.isEmpty()) {
|
|
|
- // 将图片列表转换为URL列表,按照imgSort排序
|
|
|
- List<String> imgUrlList = imgs.stream()
|
|
|
- .sorted(Comparator.comparing(StoreUser::getStoreId))
|
|
|
- .map(StoreUser::getHeadImg)
|
|
|
- .filter(url -> url != null)
|
|
|
- .collect(Collectors.toList());
|
|
|
- storeInfo.setStoreAlbumUrlList(imgUrlList);
|
|
|
- // 如果第一个图片存在,也可以设置到imgUrl字段作为头像
|
|
|
- if (!imgUrlList.isEmpty()) {
|
|
|
- storeInfo.setImgUrl(imgUrlList.get(0));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- jsonObject1.put("records", result);
|
|
|
-// } else {
|
|
|
-// // 其他类别:直接返回原始结果
|
|
|
-// jsonObject1.put("records", jsonObject.get("results"));
|
|
|
-// }
|
|
|
|
|
|
jsonObject1.put("total", jsonObject.get("total"));
|
|
|
jsonObject1.put("size", map.get("pageSize"));
|
|
|
@@ -131,6 +108,44 @@ public class AiSearchController {
|
|
|
return R.fail("请求失败");
|
|
|
}
|
|
|
|
|
|
+ @RequestMapping("/fuzzySearch")
|
|
|
+ public R fuzzySearch(@RequestBody Map<String,String> map) {
|
|
|
+ // 初始化请求体Map
|
|
|
+ Map<String, Object> requestBody = new HashMap<>();
|
|
|
+ requestBody.put("query", map.get("storeName"));
|
|
|
+ requestBody.put("limit", map.get("pageSize"));
|
|
|
+ requestBody.put("user_lat", map.get("lat"));
|
|
|
+ requestBody.put("user_lng", map.get("lon"));
|
|
|
+ requestBody.put("category", map.get("category"));
|
|
|
+ requestBody.put("page", map.get("pageNum"));
|
|
|
+ requestBody.put("sort_by", map.get("sortBy"));
|
|
|
+ HttpHeaders aiHeaders = new HttpHeaders();
|
|
|
+ aiHeaders.setContentType(MediaType.APPLICATION_JSON);
|
|
|
+
|
|
|
+ HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, null);
|
|
|
+ try {
|
|
|
+ ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(aiSearchFuzzyUrl, request, String.class);
|
|
|
+ String body = stringResponseEntity.getBody();
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(body);
|
|
|
+ JSONObject jsonObject1 = new JSONObject();
|
|
|
+ // 模糊搜索:从related_results和matched_results字段获取数据
|
|
|
+ List<StoreInfoVo> result = convertToStoreInfoList(jsonObject.getJSONArray("results"));
|
|
|
+
|
|
|
+ // 查找图片并设置到result中(图片类型1-入口图)
|
|
|
+ fillStoreImages(result, 1);
|
|
|
+
|
|
|
+ jsonObject1.put("records", result);
|
|
|
+
|
|
|
+ jsonObject1.put("total", jsonObject.get("total"));
|
|
|
+ jsonObject1.put("size", map.get("pageSize"));
|
|
|
+ log.info("调用AI模糊搜索接口 接口返回------{}", body);
|
|
|
+ return R.data(jsonObject1);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("调用AI模糊搜索接口 接口异常------", e);
|
|
|
+ }
|
|
|
+ return R.fail("请求失败");
|
|
|
+ }
|
|
|
+
|
|
|
private List<StoreInfoVo> convertToStoreInfoList(JSONArray results) {
|
|
|
List<StoreInfoVo> storeInfoList = new ArrayList<>();
|
|
|
if (results != null) {
|
|
|
@@ -162,6 +177,60 @@ public class AiSearchController {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 查找店铺图片并设置到StoreInfoVo列表中
|
|
|
+ *
|
|
|
+ * @param result StoreInfoVo列表
|
|
|
+ * @param imgType 图片类型(1:入口图, 2:相册, 10:商家头像等)
|
|
|
+ */
|
|
|
+ private void fillStoreImages(List<StoreInfoVo> result, Integer imgType) {
|
|
|
+ if (result == null || result.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从结果中提取所有的id,放到集合中
|
|
|
+ List<Integer> storeIdList = result.stream()
|
|
|
+ .map(StoreInfoVo::getId)
|
|
|
+ .filter(id -> id != null)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (storeIdList.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量查询图片
|
|
|
+ QueryWrapper<StoreImg> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.in("store_id", storeIdList)
|
|
|
+ .eq("img_type", imgType)
|
|
|
+ .orderByAsc("img_sort");
|
|
|
+ List<StoreImg> storeImgList = storeImgMapper.selectList(queryWrapper);
|
|
|
+
|
|
|
+ // 将图片列表按照storeId分组
|
|
|
+ Map<Integer, List<StoreImg>> storeImgMap = storeImgList.stream()
|
|
|
+ .collect(Collectors.groupingBy(StoreImg::getStoreId));
|
|
|
+
|
|
|
+ // 将图片列表设置到对应的StoreInfoVo中
|
|
|
+ for (StoreInfoVo storeInfo : result) {
|
|
|
+ if (storeInfo.getId() != null) {
|
|
|
+ List<StoreImg> imgs = storeImgMap.get(storeInfo.getId());
|
|
|
+ if (imgs != null && !imgs.isEmpty()) {
|
|
|
+ // 将图片列表转换为URL列表,按照imgSort排序
|
|
|
+ List<String> imgUrlList = imgs.stream()
|
|
|
+ .sorted(Comparator.comparing(StoreImg::getImgSort, Comparator.nullsLast(Comparator.naturalOrder())))
|
|
|
+ .map(StoreImg::getImgUrl)
|
|
|
+ .filter(url -> url != null)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ storeInfo.setStoreAlbumUrlList(imgUrlList);
|
|
|
+ // 如果第一个图片存在,也可以设置到imgUrl字段作为头像
|
|
|
+ if (!imgUrlList.isEmpty()) {
|
|
|
+ storeInfo.setImgUrl(imgUrlList.get(0));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 将下划线命名转换为驼峰命名
|
|
|
* 例如: store_tel -> storeTel, created_time -> createdTime
|
|
|
*/
|