|
@@ -0,0 +1,313 @@
|
|
|
|
|
+package shop.alien.store.service.impl;
|
|
|
|
|
+
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
|
|
+import shop.alien.entity.store.StoreInfo;
|
|
|
|
|
+import shop.alien.entity.store.StoreRenovationBrowseRecord;
|
|
|
|
|
+import shop.alien.entity.store.StoreRenovationRequirement;
|
|
|
|
|
+import shop.alien.entity.store.StoreUser;
|
|
|
|
|
+import shop.alien.entity.store.dto.StoreRenovationBrowseRequirementDto;
|
|
|
|
|
+import shop.alien.mapper.StoreInfoMapper;
|
|
|
|
|
+import shop.alien.mapper.StoreRenovationBrowseRecordMapper;
|
|
|
|
|
+import shop.alien.mapper.StoreUserMapper;
|
|
|
|
|
+import shop.alien.store.service.StoreRenovationBrowseRecordService;
|
|
|
|
|
+import shop.alien.store.service.StoreRenovationRequirementService;
|
|
|
|
|
+import shop.alien.util.common.JwtUtil;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.Arrays;
|
|
|
|
|
+import java.util.Date;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 装修商铺访问装修需求浏览记录表 服务实现类
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author auto-generated
|
|
|
|
|
+ * @since 2025-01-15
|
|
|
|
|
+ */
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+@Service
|
|
|
|
|
+@RequiredArgsConstructor
|
|
|
|
|
+@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+public class StoreRenovationBrowseRecordServiceImpl extends ServiceImpl<StoreRenovationBrowseRecordMapper, StoreRenovationBrowseRecord> implements StoreRenovationBrowseRecordService {
|
|
|
|
|
+
|
|
|
|
|
+ private final StoreRenovationRequirementService requirementService;
|
|
|
|
|
+ private final StoreUserMapper storeUserMapper;
|
|
|
|
|
+ private final StoreInfoMapper storeInfoMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean recordBrowse(Integer renovationStoreId, Integer requirementId) {
|
|
|
|
|
+ log.info("StoreRenovationBrowseRecordServiceImpl.recordBrowse?renovationStoreId={}, requirementId={}", renovationStoreId, requirementId);
|
|
|
|
|
+ try {
|
|
|
|
|
+ StoreRenovationBrowseRecord record = new StoreRenovationBrowseRecord();
|
|
|
|
|
+ record.setRenovationStoreId(renovationStoreId);
|
|
|
|
|
+ record.setRequirementId(requirementId);
|
|
|
|
|
+ record.setBrowseTime(new Date());
|
|
|
|
|
+ record.setIsContacted(0); // 仅浏览,未咨询
|
|
|
|
|
+
|
|
|
|
|
+ // 获取当前登录用户ID
|
|
|
|
|
+ Integer currentUserId = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ com.alibaba.fastjson.JSONObject userInfo = JwtUtil.getCurrentUserInfo();
|
|
|
|
|
+ if (userInfo != null) {
|
|
|
|
|
+ currentUserId = userInfo.getInteger("userId");
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("获取当前用户ID失败: {}", e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ record.setCreatedUserId(currentUserId);
|
|
|
|
|
+
|
|
|
|
|
+ return this.save(record);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("记录浏览失败: {}", e.getMessage(), e);
|
|
|
|
|
+ throw new RuntimeException("记录浏览失败: " + e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean recordInquiry(Integer renovationStoreId, Integer requirementId) {
|
|
|
|
|
+ log.info("StoreRenovationBrowseRecordServiceImpl.recordInquiry?renovationStoreId={}, requirementId={}", renovationStoreId, requirementId);
|
|
|
|
|
+ try {
|
|
|
|
|
+ Date now = new Date();
|
|
|
|
|
+
|
|
|
|
|
+ // 检查是否已有浏览记录
|
|
|
|
|
+ LambdaQueryWrapper<StoreRenovationBrowseRecord> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ queryWrapper.eq(StoreRenovationBrowseRecord::getRenovationStoreId, renovationStoreId);
|
|
|
|
|
+ queryWrapper.eq(StoreRenovationBrowseRecord::getRequirementId, requirementId);
|
|
|
|
|
+ queryWrapper.eq(StoreRenovationBrowseRecord::getDeleteFlag, 0);
|
|
|
|
|
+ StoreRenovationBrowseRecord existingRecord = this.getOne(queryWrapper, false);
|
|
|
|
|
+
|
|
|
|
|
+ boolean isFirstContact = false;
|
|
|
|
|
+
|
|
|
|
|
+ if (existingRecord != null) {
|
|
|
|
|
+ // 如果已有记录但未咨询过,更新为已咨询
|
|
|
|
|
+ if (existingRecord.getIsContacted() == null || existingRecord.getIsContacted() == 0) {
|
|
|
|
|
+ LambdaUpdateWrapper<StoreRenovationBrowseRecord> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
|
|
+ updateWrapper.eq(StoreRenovationBrowseRecord::getId, existingRecord.getId());
|
|
|
|
|
+ updateWrapper.set(StoreRenovationBrowseRecord::getIsContacted, 1);
|
|
|
|
|
+ updateWrapper.set(StoreRenovationBrowseRecord::getContactTime, now);
|
|
|
|
|
+
|
|
|
|
|
+ // 获取当前登录用户ID
|
|
|
|
|
+ Integer currentUserId = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ com.alibaba.fastjson.JSONObject userInfo = JwtUtil.getCurrentUserInfo();
|
|
|
|
|
+ if (userInfo != null) {
|
|
|
|
|
+ currentUserId = userInfo.getInteger("userId");
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("获取当前用户ID失败: {}", e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ updateWrapper.set(StoreRenovationBrowseRecord::getUpdatedUserId, currentUserId);
|
|
|
|
|
+
|
|
|
|
|
+ this.update(updateWrapper);
|
|
|
|
|
+ isFirstContact = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 如果已咨询过,不再重复记录,但可以记录新的浏览记录(可选)
|
|
|
|
|
+ // 这里选择不重复记录咨询,只更新浏览时间
|
|
|
|
|
+ existingRecord.setBrowseTime(now);
|
|
|
|
|
+ this.updateById(existingRecord);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果没有记录,创建新记录(浏览+咨询)
|
|
|
|
|
+ StoreRenovationBrowseRecord record = new StoreRenovationBrowseRecord();
|
|
|
|
|
+ record.setRenovationStoreId(renovationStoreId);
|
|
|
|
|
+ record.setRequirementId(requirementId);
|
|
|
|
|
+ record.setBrowseTime(now);
|
|
|
|
|
+ record.setIsContacted(1); // 已咨询
|
|
|
|
|
+ record.setContactTime(now);
|
|
|
|
|
+
|
|
|
|
|
+ // 获取当前登录用户ID
|
|
|
|
|
+ Integer currentUserId = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ com.alibaba.fastjson.JSONObject userInfo = JwtUtil.getCurrentUserInfo();
|
|
|
|
|
+ if (userInfo != null) {
|
|
|
|
|
+ currentUserId = userInfo.getInteger("userId");
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("获取当前用户ID失败: {}", e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ record.setCreatedUserId(currentUserId);
|
|
|
|
|
+
|
|
|
|
|
+ this.save(record);
|
|
|
|
|
+ isFirstContact = true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果是首次咨询,增加需求的咨询数
|
|
|
|
|
+ if (isFirstContact) {
|
|
|
|
|
+ requirementService.incrementInquiryCount(requirementId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("记录咨询失败: {}", e.getMessage(), e);
|
|
|
|
|
+ throw new RuntimeException("记录咨询失败: " + e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean recordInquiryByCurrentUser(Integer requirementId) {
|
|
|
|
|
+ log.info("StoreRenovationBrowseRecordServiceImpl.recordInquiryByCurrentUser?requirementId={}", requirementId);
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 获取当前登录用户信息
|
|
|
|
|
+ Integer currentUserId = null;
|
|
|
|
|
+ String phone = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ com.alibaba.fastjson.JSONObject userInfo = JwtUtil.getCurrentUserInfo();
|
|
|
|
|
+ if (userInfo != null) {
|
|
|
|
|
+ currentUserId = userInfo.getInteger("userId");
|
|
|
|
|
+ phone = userInfo.getString("phone");
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("获取当前用户信息失败: {}", e.getMessage());
|
|
|
|
|
+ throw new RuntimeException("获取当前用户信息失败,请先登录");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (currentUserId == null) {
|
|
|
|
|
+ throw new RuntimeException("用户未登录");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 根据用户ID或手机号查询 StoreUser,获取门店ID
|
|
|
|
|
+ StoreUser storeUser = null;
|
|
|
|
|
+ if (currentUserId != null) {
|
|
|
|
|
+ storeUser = storeUserMapper.selectById(currentUserId);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (storeUser == null && phone != null) {
|
|
|
|
|
+ LambdaQueryWrapper<StoreUser> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ queryWrapper.eq(StoreUser::getPhone, phone);
|
|
|
|
|
+ storeUser = storeUserMapper.selectOne(queryWrapper);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (storeUser == null || storeUser.getStoreId() == null) {
|
|
|
|
|
+ throw new RuntimeException("未找到用户门店信息");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Integer renovationStoreId = storeUser.getStoreId();
|
|
|
|
|
+ return recordInquiry(renovationStoreId, requirementId);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("记录咨询失败: {}", e.getMessage(), e);
|
|
|
|
|
+ throw new RuntimeException(e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<StoreRenovationBrowseRequirementDto> getBrowsedRequirementsByStoreTel(String renovationStoreTel, String normalStoreTel) {
|
|
|
|
|
+ log.info("StoreRenovationBrowseRecordServiceImpl.getBrowsedRequirementsByStoreTel?renovationStoreTel={}, normalStoreTel={}", renovationStoreTel, normalStoreTel);
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 0. 通过门店电话查询门店ID
|
|
|
|
|
+ LambdaQueryWrapper<StoreInfo> renovationStoreWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ renovationStoreWrapper.eq(StoreInfo::getStoreTel, renovationStoreTel);
|
|
|
|
|
+ renovationStoreWrapper.eq(StoreInfo::getDeleteFlag, 0);
|
|
|
|
|
+ StoreInfo renovationStoreInfo = storeInfoMapper.selectOne(renovationStoreWrapper);
|
|
|
|
|
+ if (renovationStoreInfo == null) {
|
|
|
|
|
+ throw new RuntimeException("装修商铺不存在,门店电话: " + renovationStoreTel);
|
|
|
|
|
+ }
|
|
|
|
|
+ Integer renovationStoreId = renovationStoreInfo.getId();
|
|
|
|
|
+
|
|
|
|
|
+ LambdaQueryWrapper<StoreInfo> normalStoreWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ normalStoreWrapper.eq(StoreInfo::getStoreTel, normalStoreTel);
|
|
|
|
|
+ normalStoreWrapper.eq(StoreInfo::getDeleteFlag, 0);
|
|
|
|
|
+ StoreInfo normalStoreInfo = storeInfoMapper.selectOne(normalStoreWrapper);
|
|
|
|
|
+ if (normalStoreInfo == null) {
|
|
|
|
|
+ throw new RuntimeException("普通商铺不存在,门店电话: " + normalStoreTel);
|
|
|
|
|
+ }
|
|
|
|
|
+ Integer normalStoreId = normalStoreInfo.getId();
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 查询普通商铺发布的所有装修需求ID
|
|
|
|
|
+ LambdaQueryWrapper<StoreRenovationRequirement> requirementWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ requirementWrapper.eq(StoreRenovationRequirement::getStoreId, normalStoreId);
|
|
|
|
|
+ requirementWrapper.eq(StoreRenovationRequirement::getDeleteFlag, 0);
|
|
|
|
|
+ List<StoreRenovationRequirement> requirements = requirementService.list(requirementWrapper);
|
|
|
|
|
+
|
|
|
|
|
+ if (requirements.isEmpty()) {
|
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<Integer> requirementIds = requirements.stream()
|
|
|
|
|
+ .map(StoreRenovationRequirement::getId)
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 查询装修商铺浏览过哪些需求
|
|
|
|
|
+ LambdaQueryWrapper<StoreRenovationBrowseRecord> browseWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ browseWrapper.eq(StoreRenovationBrowseRecord::getRenovationStoreId, renovationStoreId);
|
|
|
|
|
+ browseWrapper.in(StoreRenovationBrowseRecord::getRequirementId, requirementIds);
|
|
|
|
|
+ browseWrapper.eq(StoreRenovationBrowseRecord::getDeleteFlag, 0);
|
|
|
|
|
+ browseWrapper.orderByDesc(StoreRenovationBrowseRecord::getBrowseTime);
|
|
|
|
|
+ List<StoreRenovationBrowseRecord> browseRecords = this.list(browseWrapper);
|
|
|
|
|
+
|
|
|
|
|
+ if (browseRecords.isEmpty()) {
|
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 创建需求ID到浏览记录的映射(取最新的浏览记录)
|
|
|
|
|
+ Map<Integer, StoreRenovationBrowseRecord> browseRecordMap = browseRecords.stream()
|
|
|
|
|
+ .collect(Collectors.toMap(
|
|
|
|
|
+ StoreRenovationBrowseRecord::getRequirementId,
|
|
|
|
|
+ record -> record,
|
|
|
|
|
+ (existing, replacement) -> existing.getBrowseTime().after(replacement.getBrowseTime()) ? existing : replacement
|
|
|
|
|
+ ));
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 创建需求ID到需求详情的映射
|
|
|
|
|
+ Map<Integer, StoreRenovationRequirement> requirementMap = requirements.stream()
|
|
|
|
|
+ .collect(Collectors.toMap(StoreRenovationRequirement::getId, req -> req));
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 组装返回数据(只返回浏览过的需求)
|
|
|
|
|
+ List<StoreRenovationBrowseRequirementDto> result = new ArrayList<>();
|
|
|
|
|
+ for (StoreRenovationBrowseRecord browseRecord : browseRecordMap.values()) {
|
|
|
|
|
+ StoreRenovationRequirement requirement = requirementMap.get(browseRecord.getRequirementId());
|
|
|
|
|
+ if (requirement != null) {
|
|
|
|
|
+ StoreRenovationBrowseRequirementDto dto = new StoreRenovationBrowseRequirementDto();
|
|
|
|
|
+
|
|
|
|
|
+ // 复制需求信息
|
|
|
|
|
+ dto.setRequirementId(requirement.getId());
|
|
|
|
|
+ dto.setRequirementTitle(requirement.getRequirementTitle());
|
|
|
|
|
+ dto.setRenovationType(requirement.getRenovationType());
|
|
|
|
|
+ dto.setHouseArea(requirement.getHouseArea());
|
|
|
|
|
+ dto.setRenovationBudget(requirement.getRenovationBudget());
|
|
|
|
|
+ dto.setDetailedRequirement(requirement.getDetailedRequirement());
|
|
|
|
|
+ dto.setExpectedRenovationTime(requirement.getExpectedRenovationTime());
|
|
|
|
|
+ dto.setContactName(requirement.getContactName());
|
|
|
|
|
+ dto.setContactPhone(requirement.getContactPhone());
|
|
|
|
|
+ dto.setCity(requirement.getCity());
|
|
|
|
|
+ dto.setDetailedAddress(requirement.getDetailedAddress());
|
|
|
|
|
+ dto.setCreatedTime(requirement.getCreatedTime());
|
|
|
|
|
+
|
|
|
|
|
+ // 处理附件URL字符串:逗号拼接转List
|
|
|
|
|
+ if (StringUtils.hasText(requirement.getAttachmentUrls())) {
|
|
|
|
|
+ List<String> attachmentUrls = Arrays.asList(requirement.getAttachmentUrls().split(","));
|
|
|
|
|
+ dto.setAttachmentUrls(attachmentUrls);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ dto.setAttachmentUrls(new ArrayList<>());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 复制浏览信息
|
|
|
|
|
+ dto.setBrowseTime(browseRecord.getBrowseTime());
|
|
|
|
|
+ dto.setIsContacted(browseRecord.getIsContacted());
|
|
|
|
|
+ dto.setContactTime(browseRecord.getContactTime());
|
|
|
|
|
+
|
|
|
|
|
+ result.add(dto);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 按浏览时间倒序排序
|
|
|
|
|
+ result.sort((a, b) -> {
|
|
|
|
|
+ if (a.getBrowseTime() == null && b.getBrowseTime() == null) return 0;
|
|
|
|
|
+ if (a.getBrowseTime() == null) return 1;
|
|
|
|
|
+ if (b.getBrowseTime() == null) return -1;
|
|
|
|
|
+ return b.getBrowseTime().compareTo(a.getBrowseTime());
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("查询浏览过的装修需求失败: {}", e.getMessage(), e);
|
|
|
|
|
+ throw new RuntimeException("查询浏览过的装修需求失败: " + e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|