|
|
@@ -0,0 +1,196 @@
|
|
|
+package com.ylx.massage.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.ylx.massage.domain.Product;
|
|
|
+import com.ylx.massage.domain.TXiangmu;
|
|
|
+import com.ylx.massage.domain.dto.OptionDTO;
|
|
|
+import com.ylx.massage.domain.vo.ProductOptionVO;
|
|
|
+import com.ylx.massage.service.ProductSelectionService;
|
|
|
+import com.ylx.massage.service.ProductService;
|
|
|
+import com.ylx.massage.service.TXiangmuService;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class ProductSelectionServiceImpl implements ProductSelectionService {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private TXiangmuService xiangmuService; // 项目服务
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private ProductService productService; // 积分商品服务
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Page<ProductOptionVO> optionsPage(OptionDTO dto) {
|
|
|
+ Page page = new Page(dto.getCurrent(), dto.getSize());
|
|
|
+ Integer productType = dto.getProductType();
|
|
|
+
|
|
|
+ // 1. 只查积分商品 (Type = 1)
|
|
|
+ if (productType != null && productType == 1) {
|
|
|
+ return queryIntegralProducts(page, dto);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 只查项目/服务商品 (Type = 0)
|
|
|
+ if (productType != null && productType == 0) {
|
|
|
+ return queryProjectProducts(page, dto);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 查询全部 (Type = null)
|
|
|
+ // 注意:跨表分页比较复杂,这里采用“分别查询当前页数据然后合并”的策略
|
|
|
+ // 如果数据量极大且必须严格排序,建议使用自定义 SQL 或 搜索引擎
|
|
|
+ return queryAllProducts(page, dto);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询积分商品
|
|
|
+ */
|
|
|
+ private Page<ProductOptionVO> queryIntegralProducts(Page page, OptionDTO dto) {
|
|
|
+ // 构建查询条件
|
|
|
+ LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.eq(Product::getStatus, 1) // 假设 1 是上架
|
|
|
+ .eq(Product::getDeleted, 0); // 假设 0 是未删除
|
|
|
+ if (StrUtil.isNotEmpty(dto.getTitle())) {
|
|
|
+ wrapper.like(Product::getName, dto.getTitle());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 执行分页查询
|
|
|
+ Page<Product> productPage = productService.page(page, wrapper);
|
|
|
+
|
|
|
+ // 转换 VO
|
|
|
+ return convertToVOPage(productPage, p -> {
|
|
|
+ ProductOptionVO vo = new ProductOptionVO();
|
|
|
+ vo.setId(String.valueOf(p.getId())); // Long 转 String
|
|
|
+ vo.setTitle(p.getName());
|
|
|
+ vo.setProductType(1); // 设置商品类型
|
|
|
+ return vo;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询项目商品
|
|
|
+ */
|
|
|
+ private Page<ProductOptionVO> queryProjectProducts(Page page, OptionDTO dto) {
|
|
|
+ // 构建查询条件
|
|
|
+ LambdaQueryWrapper<TXiangmu> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.eq(TXiangmu::getIsDelete, 0);
|
|
|
+ if (StrUtil.isNotEmpty(dto.getTitle())) {
|
|
|
+ wrapper.like(TXiangmu::getcTitle, dto.getTitle());
|
|
|
+ }
|
|
|
+ // 执行分页查询
|
|
|
+ Page<TXiangmu> xiangmuPage = xiangmuService.page(page, wrapper);
|
|
|
+
|
|
|
+ // 转换 VO
|
|
|
+ return convertToVOPage(xiangmuPage, x -> {
|
|
|
+ ProductOptionVO vo = new ProductOptionVO();
|
|
|
+ vo.setId(x.getcId()); // String 直接赋值
|
|
|
+ vo.setTitle(x.getcTitle());
|
|
|
+ vo.setProductType(0); // 设置商品类型
|
|
|
+ return vo;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询全部 (合并分页逻辑)
|
|
|
+ * 核心逻辑:
|
|
|
+ * 1. 分别查询两张表的所有符合条件的数据(全量)。
|
|
|
+ * 2. 在内存中合并为一个总列表。
|
|
|
+ * 3. 获取总列表的大小作为 total。
|
|
|
+ * 4. 根据分页参数截取当前页的数据。
|
|
|
+ */
|
|
|
+ private Page<ProductOptionVO> queryAllProducts(Page<ProductOptionVO> page, OptionDTO dto) {
|
|
|
+ long current = page.getCurrent();
|
|
|
+ long size = page.getSize();
|
|
|
+
|
|
|
+ // --- 1. 查出积分商品列表 (全量) ---
|
|
|
+ LambdaQueryWrapper<Product> productWrapper = new LambdaQueryWrapper<>();
|
|
|
+ productWrapper.eq(Product::getStatus, 1)
|
|
|
+ .eq(Product::getDeleted, 0);
|
|
|
+ if (StrUtil.isNotEmpty(dto.getTitle())) {
|
|
|
+ productWrapper.like(Product::getName, dto.getTitle());
|
|
|
+ }
|
|
|
+ List<Product> integralList = productService.list(productWrapper);
|
|
|
+
|
|
|
+ // --- 2. 查出项目商品列表 (全量) ---
|
|
|
+ LambdaQueryWrapper<TXiangmu> xiangmuWrapper = new LambdaQueryWrapper<>();
|
|
|
+ xiangmuWrapper.eq(TXiangmu::getIsDelete, 0);
|
|
|
+ if (StrUtil.isNotEmpty(dto.getTitle())) {
|
|
|
+ xiangmuWrapper.like(TXiangmu::getcTitle, dto.getTitle());
|
|
|
+ }
|
|
|
+ List<TXiangmu> projectList = xiangmuService.list(xiangmuWrapper);
|
|
|
+
|
|
|
+ // --- 3. 转换为 VO 并合并 (关键步骤) ---
|
|
|
+ List<ProductOptionVO> totalList = new ArrayList<>();
|
|
|
+
|
|
|
+ // 添加积分商品
|
|
|
+ totalList.addAll(integralList.stream().map(p -> {
|
|
|
+ ProductOptionVO vo = new ProductOptionVO();
|
|
|
+ vo.setId(String.valueOf(p.getId()));
|
|
|
+ vo.setProductType(1);
|
|
|
+ vo.setTitle(p.getName());
|
|
|
+ return vo;
|
|
|
+ }).collect(Collectors.toList()));
|
|
|
+
|
|
|
+ // 添加项目商品
|
|
|
+ totalList.addAll(projectList.stream().map(x -> {
|
|
|
+ ProductOptionVO vo = new ProductOptionVO();
|
|
|
+ vo.setId(x.getcId());
|
|
|
+ vo.setProductType(0);
|
|
|
+ vo.setTitle(x.getcTitle());
|
|
|
+ return vo;
|
|
|
+ }).collect(Collectors.toList()));
|
|
|
+
|
|
|
+ // --- 4. 计算总记录数 (这就是你要的修正点) ---
|
|
|
+ // total 是两张表数据的总和
|
|
|
+ long total = totalList.size();
|
|
|
+
|
|
|
+ // --- 5. 内存分页截取 ---
|
|
|
+ // 计算起始索引
|
|
|
+ long offset = (current - 1) * size;
|
|
|
+
|
|
|
+ // 边界检查:如果起始位置超过总数,说明这一页没数据
|
|
|
+ if (offset >= total) {
|
|
|
+ // 返回空列表,但保留 total 以便前端计算页数
|
|
|
+ Page<ProductOptionVO> resultPage = new Page<>(current, size);
|
|
|
+ resultPage.setRecords(new ArrayList<>());
|
|
|
+ resultPage.setTotal(total);
|
|
|
+ resultPage.setPages(total == 0 ? 0 : (total + size - 1) / size);
|
|
|
+ return resultPage;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算结束索引
|
|
|
+ long limit = Math.min(offset + size, total);
|
|
|
+
|
|
|
+ // 截取当前页数据
|
|
|
+ List<ProductOptionVO> records = totalList.subList((int) offset, (int) limit);
|
|
|
+
|
|
|
+ // --- 6. 构建返回结果 ---
|
|
|
+ Page<ProductOptionVO> resultPage = new Page<>(current, size);
|
|
|
+ resultPage.setRecords(records);
|
|
|
+ resultPage.setTotal(total); // 设置总和
|
|
|
+ resultPage.setPages(total == 0 ? 0 : (total + size - 1) / size); // 计算总页数
|
|
|
+
|
|
|
+ return resultPage;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通用的 MyBatis-Plus Page 转 VO Page 方法
|
|
|
+ */
|
|
|
+ private <T, R> Page<R> convertToVOPage(Page<T> sourcePage, java.util.function.Function<T, R> converter) {
|
|
|
+ Page<R> voPage = new Page<>(sourcePage.getCurrent(), sourcePage.getSize());
|
|
|
+ voPage.setTotal(sourcePage.getTotal());
|
|
|
+ voPage.setPages(sourcePage.getPages());
|
|
|
+
|
|
|
+ List<R> records = sourcePage.getRecords().stream()
|
|
|
+ .map(converter)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ voPage.setRecords(records);
|
|
|
+
|
|
|
+ return voPage;
|
|
|
+ }
|
|
|
+}
|