diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/cons/repository/TbConsInfoRepository.java b/eladmin-system/src/main/java/cn/ysk/cashier/cons/repository/TbConsInfoRepository.java index 5b7c1a93..fc9ea24c 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/cons/repository/TbConsInfoRepository.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/cons/repository/TbConsInfoRepository.java @@ -6,6 +6,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import java.util.List; @@ -34,4 +35,15 @@ public interface TbConsInfoRepository extends JpaRepository " where conPro.con_info_id = :conInfoId " + " group by conPro.product_id ",nativeQuery = true) List> queryAllAndPro(@Param("shopId") Integer shopId, @Param("conInfoId")Integer conInfoId); + + @Query(value = + "SELECT *" + + " FROM" + + " tb_prosku_con conPro" + + " where conPro.shop_id = :shopId ",nativeQuery = true) + List searchConsInfoByShopId(Integer shopId); + + @Modifying + @Query(value = "delete FROM tb_prosku_con conPro where conPro.shop_id = :shopId ",nativeQuery = true) + void clearShopCons(Integer shopId); } \ No newline at end of file diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/cons/repository/TbConsTypeRepository.java b/eladmin-system/src/main/java/cn/ysk/cashier/cons/repository/TbConsTypeRepository.java index 25b7904d..37084fa0 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/cons/repository/TbConsTypeRepository.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/cons/repository/TbConsTypeRepository.java @@ -3,8 +3,11 @@ package cn.ysk.cashier.cons.repository; import cn.ysk.cashier.cons.domain.TbConsType; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; +import java.util.List; + /** * @website https://eladmin.vip * @author admin @@ -16,6 +19,13 @@ public interface TbConsTypeRepository extends JpaRepository TbConsType findByConTypeCode(String conTypeCode); + @Query("SELECT c FROM TbProskuCon c WHERE c.shopId = :shopId") + List searchConsTypeByShopId(Integer shopId); + + @Modifying + @Query("delete FROM TbProskuCon c WHERE c.shopId = :shopId") + void clearShopConType(Integer shopId); + @Query("SELECT count(*) FROM TbProskuCon c LEFT JOIN TbConsInfo i ON c.conInfoId = i.id WHERE i.conTypeId = :id") int countProByTypeId(Integer id); } diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/cons/repository/TbProskuConRepository.java b/eladmin-system/src/main/java/cn/ysk/cashier/cons/repository/TbProskuConRepository.java index e16d6305..b677992e 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/cons/repository/TbProskuConRepository.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/cons/repository/TbProskuConRepository.java @@ -30,4 +30,11 @@ public interface TbProskuConRepository extends JpaRepository searchAllByProductId(Integer productId); + @Query(value = "select * from tb_prosku_con where shop_id=?1 ",nativeQuery = true) + List searchConsProByShopId(Integer shopId); + + @Modifying + @Query(value = "delete from tb_prosku_con where shop_id=?1 ",nativeQuery = true) + void clearShopConPro(Integer shopId); + } \ No newline at end of file diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/controller/TbShopSyncInfoController.java b/eladmin-system/src/main/java/cn/ysk/cashier/controller/TbShopSyncInfoController.java new file mode 100644 index 00000000..780980e0 --- /dev/null +++ b/eladmin-system/src/main/java/cn/ysk/cashier/controller/TbShopSyncInfoController.java @@ -0,0 +1,68 @@ +package cn.ysk.cashier.controller; + +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUnit; +import cn.hutool.core.date.DateUtil; +import cn.ysk.cashier.annotation.rest.AnonymousPostMapping; +import cn.ysk.cashier.dto.TbShopSyncInfoQueryCriteria; +import cn.ysk.cashier.mybatis.entity.TbShopSyncInfo; +import cn.ysk.cashier.mybatis.mapper.TbShopSyncInfoMapper; +import cn.ysk.cashier.mybatis.service.TbShopSyncInfoService; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.Date; + +/** + * 店铺信息同步记录表(TbShopSyncInfo)表控制层 + * + * @author ww + * @since 2024-11-25 16:46:12 + */ +@RestController +@RequestMapping("/api/tbShopSyncInfo") +public class TbShopSyncInfoController { + + @Resource + private TbShopSyncInfoService tbShopSyncInfoService; + + @Autowired + private TbShopSyncInfoMapper tbShopSyncInfomapper; + + @GetMapping + @ApiOperation("查询同步数据情况") + public ResponseEntity selectAll(TbShopSyncInfoQueryCriteria criteria) { + return new ResponseEntity<>(tbShopSyncInfoService.queryByShopId(criteria), HttpStatus.OK); + } + + @PostMapping("/sync") + @ApiOperation("同步") + public ResponseEntity sync(@RequestBody TbShopSyncInfo tbShopSyncInfo){ + tbShopSyncInfo.setSyncTime(new Date()); + tbShopSyncInfo.setStatus(1); + tbShopSyncInfomapper.insert(tbShopSyncInfo); + tbShopSyncInfoService.sync(tbShopSyncInfo); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @AnonymousPostMapping("/clear") + @ApiOperation("一键清除店铺数据") + public ResponseEntity clear(@RequestBody TbShopSyncInfo tbShopSyncInfo){ + TbShopSyncInfoQueryCriteria criteria = new TbShopSyncInfoQueryCriteria(); + criteria.setPointShopId(tbShopSyncInfo.getPointShopId()); + TbShopSyncInfo tbShopSyncInfo1 = tbShopSyncInfoService.queryByShopId(criteria); + long between = DateUtil.between(new Date(), tbShopSyncInfo1.getSyncTime(), DateUnit.HOUR); + if(between > 24){ + throw new RuntimeException("数据同步已超过一天 无法清除"); + } + tbShopSyncInfoService.clear(tbShopSyncInfo); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + +} + diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/dto/TbShopSyncInfoQueryCriteria.java b/eladmin-system/src/main/java/cn/ysk/cashier/dto/TbShopSyncInfoQueryCriteria.java new file mode 100644 index 00000000..feff2e2d --- /dev/null +++ b/eladmin-system/src/main/java/cn/ysk/cashier/dto/TbShopSyncInfoQueryCriteria.java @@ -0,0 +1,22 @@ +package cn.ysk.cashier.dto; + +import lombok.Data; + +/** + * 店铺信息同步记录表(TbShopSyncInfo)表查询类 + * + * @author ww + * @since 2024-11-25 16:46:12 + */ +@Data +public class TbShopSyncInfoQueryCriteria { + + //目的shop + private Integer pointShopId; + //1-正在 2-完成 + private Integer status; + + private long page = 1; + private long size = 10; +} + diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/mybatis/entity/TbShopSyncInfo.java b/eladmin-system/src/main/java/cn/ysk/cashier/mybatis/entity/TbShopSyncInfo.java new file mode 100644 index 00000000..e25648ff --- /dev/null +++ b/eladmin-system/src/main/java/cn/ysk/cashier/mybatis/entity/TbShopSyncInfo.java @@ -0,0 +1,56 @@ +package cn.ysk.cashier.mybatis.entity; + +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import java.io.Serializable; + +/** + * 店铺信息同步记录表(TbShopSyncInfo)表实体类 + * + * @author ww + * @since 2024-11-25 16:46:12 + */ +@Data +@SuppressWarnings("serial") +public class TbShopSyncInfo extends Model { + + @GeneratedValue(strategy = GenerationType.IDENTITY) + @TableId(type = IdType.AUTO) + private Integer id; + //源shop + private Integer sourceShopId; + //目的shop + private Integer pointShopId; + //分组同步数量 + private Integer proGroup; + //规格同步数量 + private Integer proSpec; + //单位同步数量 + private Integer proUnit; + //分类同步数量 + private Integer proCategory; + //商品同步数量 + private Integer product; + //规格同步数量 + private Integer proSku; + //商品同步数量 + private Integer proSkuResult; + //耗材类型同步数量 + private Integer consType; + //耗材信息同步数量 + private Integer consInfo; + //商品耗材关联同步数量 + private Integer consPro; + //1-正在 2-完成 + private Integer status; + //同步时间 + private Date syncTime; +} + diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/mybatis/mapper/TbShopSyncInfoMapper.java b/eladmin-system/src/main/java/cn/ysk/cashier/mybatis/mapper/TbShopSyncInfoMapper.java new file mode 100644 index 00000000..5f535b7e --- /dev/null +++ b/eladmin-system/src/main/java/cn/ysk/cashier/mybatis/mapper/TbShopSyncInfoMapper.java @@ -0,0 +1,17 @@ +package cn.ysk.cashier.mybatis.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import cn.ysk.cashier.mybatis.entity.TbShopSyncInfo; +import org.apache.ibatis.annotations.Mapper; + +/** + * 店铺信息同步记录表(TbShopSyncInfo)表数据库访问层 + * + * @author ww + * @since 2024-11-25 16:46:12 + */ +@Mapper +public interface TbShopSyncInfoMapper extends BaseMapper { + +} + diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/mybatis/service/TbShopSyncInfoService.java b/eladmin-system/src/main/java/cn/ysk/cashier/mybatis/service/TbShopSyncInfoService.java new file mode 100644 index 00000000..a6573378 --- /dev/null +++ b/eladmin-system/src/main/java/cn/ysk/cashier/mybatis/service/TbShopSyncInfoService.java @@ -0,0 +1,22 @@ +package cn.ysk.cashier.mybatis.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import cn.ysk.cashier.mybatis.entity.TbShopSyncInfo; +import cn.ysk.cashier.dto.TbShopSyncInfoQueryCriteria; + +import java.util.Map; + +/** + * 店铺信息同步记录表(TbShopSyncInfo)表服务接口 + * + * @author ww + * @since 2024-11-25 16:46:12 + */ +public interface TbShopSyncInfoService extends IService { + + TbShopSyncInfo queryByShopId(TbShopSyncInfoQueryCriteria criteria); + void sync(TbShopSyncInfo tbShopSyncInfo); + void clear(TbShopSyncInfo tbShopSyncInfo); + +} + diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/mybatis/service/impl/TbShopSyncInfoServiceImpl.java b/eladmin-system/src/main/java/cn/ysk/cashier/mybatis/service/impl/TbShopSyncInfoServiceImpl.java new file mode 100644 index 00000000..18e7dca8 --- /dev/null +++ b/eladmin-system/src/main/java/cn/ysk/cashier/mybatis/service/impl/TbShopSyncInfoServiceImpl.java @@ -0,0 +1,474 @@ +package cn.ysk.cashier.mybatis.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.DateTime; +import cn.ysk.cashier.cons.domain.TbConsInfo; +import cn.ysk.cashier.cons.domain.TbConsType; +import cn.ysk.cashier.cons.repository.TbConsInfoRepository; +import cn.ysk.cashier.cons.repository.TbConsTypeRepository; +import cn.ysk.cashier.cons.repository.TbProskuConRepository; +import cn.ysk.cashier.dto.TbShopSyncInfoQueryCriteria; +import cn.ysk.cashier.exception.BadRequestException; +import cn.ysk.cashier.mybatis.entity.TbShopSyncInfo; +import cn.ysk.cashier.mybatis.mapper.TbShopSyncInfoMapper; +import cn.ysk.cashier.mybatis.service.TbShopSyncInfoService; +import cn.ysk.cashier.pojo.order.TbOrderInfo; +import cn.ysk.cashier.pojo.product.*; +import cn.ysk.cashier.pojo.shop.TbShopUnit; +import cn.ysk.cashier.repository.product.*; +import cn.ysk.cashier.repository.shop.TbShopUnitRepository; +import cn.ysk.cashier.utils.JSONUtil; +import cn.ysk.cashier.utils.ListUtil; +import cn.ysk.cashier.utils.PageUtil; +import cn.ysk.cashier.utils.QueryHelp; +import cn.ysk.cashier.vo.ProductGroupVo; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.gson.JsonObject; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import javax.persistence.criteria.Predicate; +import java.math.BigDecimal; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 店铺信息同步记录表(TbShopSyncInfo)表服务实现类 + * + * @author ww + * @since 2024-11-25 16:46:12 + */ +@Slf4j +@Service +public class TbShopSyncInfoServiceImpl extends ServiceImpl implements TbShopSyncInfoService { + + + @Autowired + private ApplicationContext applicationContext; + + @Autowired + private TbShopSyncInfoMapper tbShopSyncInfomapper; + //单位 + @Autowired + private TbShopUnitRepository unitRepository; + //规格 + @Autowired + private TbProductSpecRepository specRepository; + //分组 + @Autowired + private TbProductGroupRepository groupRepository; + //分类 + @Autowired + private TbShopCategoryRepository categoryRepository; + //商品 + @Autowired + private TbProductRepository productRepository; + @Autowired + private TbProductSkuRepository skuRepository; + @Autowired + private TbProductSkuResultRepository skuResultRepository; + + //耗材 + @Autowired + private TbConsInfoRepository consRepository; + @Autowired + private TbConsTypeRepository consTypeRepository; + @Autowired + private TbProskuConRepository proSkuConRepository; + + + @Override + public TbShopSyncInfo queryByShopId(TbShopSyncInfoQueryCriteria criteria) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("point_shop_id", criteria.getPointShopId()); + wrapper.orderByDesc("sync_time"); + TbShopSyncInfo tbShopSyncInfo = tbShopSyncInfomapper.selectOne(wrapper); + return tbShopSyncInfo; + } + + @Async + @Override + public void sync(TbShopSyncInfo tbShopSyncInfo) { + Map units; + Map specs; + Map cateGorys; + Map groups; + Map pros = new HashMap<>(); + Map skus = new HashMap<>(); + Map conTypes; + Map consInfos = new HashMap<>(); + Map consPros = new HashMap<>(); + Integer skuResults = 0; + TbShopSyncInfoServiceImpl self = applicationContext.getBean(TbShopSyncInfoServiceImpl.class); + + try { + List> futures = new ArrayList<>(); + List> futures2 = new ArrayList<>(); + if (tbShopSyncInfo.getProduct() != null && tbShopSyncInfo.getProduct() > 0) { + CompletableFuture> futureUnit = self.syncUnit(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId()); + CompletableFuture> futureSpec = self.syncSpec(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId()); + CompletableFuture> futureCate = self.syncCategory(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId()); + futures.add(futureUnit); + futures.add(futureSpec); + futures.add(futureCate); + + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); + + units = futureUnit.get(); + tbShopSyncInfo.setProUnit(units.size()); + + specs = futureSpec.get(); + tbShopSyncInfo.setProSpec(specs.size()); + + cateGorys = futureCate.get(); + tbShopSyncInfo.setProCategory(cateGorys.size()); + + CompletableFuture> futurePros = self.syncProduct(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId(), units, specs, cateGorys); + pros = futurePros.get(); + tbShopSyncInfo.setProduct(pros.size()); + + self.syncGroupPackage(tbShopSyncInfo.getPointShopId(), pros, skus); + CompletableFuture> futureGroup = self.syncGroup(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId(), pros); + CompletableFuture> futureSkus = self.syncSku(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId(), pros); + CompletableFuture futureSkuResults = self.syncSkuResult(pros); + futures2.add(futureGroup); + futures2.add(futureSkus); + futures2.add(futureSkuResults); + + CompletableFuture.allOf(futures2.toArray(new CompletableFuture[0])).join(); + + groups = futureGroup.get(); + tbShopSyncInfo.setProGroup(groups.size()); + + skus = futureSkus.get(); + tbShopSyncInfo.setProSku(skus.size()); + + skuResults = futureSkuResults.get(); + tbShopSyncInfo.setProSkuResult(skuResults); + } else { + if (tbShopSyncInfo.getProUnit() != null && tbShopSyncInfo.getProUnit() > 0) { + CompletableFuture> futureUnit = self.syncUnit(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId()); + units = futureUnit.get(); + tbShopSyncInfo.setProUnit(units.size()); + } + if (tbShopSyncInfo.getProCategory() != null && tbShopSyncInfo.getProCategory() > 0) { + CompletableFuture> futureCate = self.syncCategory(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId()); + cateGorys = futureCate.get(); + tbShopSyncInfo.setProCategory(cateGorys.size()); + } + if (tbShopSyncInfo.getProSpec() != null && tbShopSyncInfo.getProSpec() > 0) { + CompletableFuture> futureSpec = self.syncSpec(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId()); + specs = futureSpec.get(); + tbShopSyncInfo.setProSpec(specs.size()); + } + } + + if (tbShopSyncInfo.getConsInfo() != null && tbShopSyncInfo.getConsInfo() > 0) { + CompletableFuture> futureConTypes = self.syncConsType(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId()); + conTypes = futureConTypes.get(); + tbShopSyncInfo.setConsType(conTypes.size()); + + CompletableFuture> futureConsInfos = self.syncCons(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId(), conTypes); + consInfos = futureConsInfos.get(); + tbShopSyncInfo.setConsInfo(consInfos.size()); + } else if (tbShopSyncInfo.getConsType() != null && tbShopSyncInfo.getConsType() > 0) { + CompletableFuture> futureConTypes = self.syncConsType(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId()); + conTypes = futureConTypes.get(); + tbShopSyncInfo.setConsType(conTypes.size()); + } + + if (tbShopSyncInfo.getConsPro() != null && tbShopSyncInfo.getConsPro() > 0 + && tbShopSyncInfo.getConsInfo() != null && tbShopSyncInfo.getConsInfo() > 0 + && tbShopSyncInfo.getProduct() != null && tbShopSyncInfo.getProduct() > 0) { + CompletableFuture> mapCompletableFuture = self.syncConsPro(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId(), consInfos, pros, skus); + consPros = mapCompletableFuture.get(); + tbShopSyncInfo.setConsPro(consPros.size()); + } + tbShopSyncInfo.setSyncTime(new Date()); + tbShopSyncInfo.setStatus(2); + tbShopSyncInfomapper.updateById(tbShopSyncInfo); + } catch (Exception e) { + tbShopSyncInfo.setSyncTime(new Date()); + tbShopSyncInfo.setStatus(0); + tbShopSyncInfomapper.updateById(tbShopSyncInfo); + log.error("数据同步失败", e); + } + } + + @Override + public void clear(TbShopSyncInfo tbShopSyncInfo) { + unitRepository.clearShopUnit(tbShopSyncInfo.getPointShopId().toString()); + specRepository.clearShopSpec(tbShopSyncInfo.getPointShopId().toString()); + groupRepository.clearShopGroup(tbShopSyncInfo.getPointShopId()); + categoryRepository.clearShopCategory(tbShopSyncInfo.getPointShopId().toString()); + List products = productRepository.selectByShopId(tbShopSyncInfo.getPointShopId().toString()); + products.stream().map(TbProduct::getId).collect(Collectors.toList()).forEach(id -> skuResultRepository.deleteById(id)); + productRepository.clearShopPro(tbShopSyncInfo.getPointShopId().toString()); + skuRepository.clearShopSku(tbShopSyncInfo.getPointShopId().toString()); + consRepository.clearShopCons(tbShopSyncInfo.getPointShopId()); + consTypeRepository.clearShopConType(tbShopSyncInfo.getPointShopId()); + proSkuConRepository.clearShopConPro(tbShopSyncInfo.getPointShopId()); + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("point_shop_id", tbShopSyncInfo.getPointShopId()); + tbShopSyncInfomapper.delete(wrapper); + } + + //单位 + @Async + public CompletableFuture> syncUnit(Integer sourceShopId, Integer pointShopId) { + CompletableFuture> future = new CompletableFuture<>(); + Map unitMap = new HashMap<>(); + unitRepository.searchUnitByShopId(sourceShopId.toString()).forEach(tbShopUnit -> { + Integer sourceUnitId = tbShopUnit.getId(); + tbShopUnit.setId(null); + tbShopUnit.setShopId(pointShopId.toString()); + unitRepository.save(tbShopUnit); + unitMap.put(sourceUnitId, tbShopUnit.getId()); + }); + future.complete(unitMap); + return future; + } + + //规格 + @Async + public CompletableFuture> syncSpec(Integer sourceShopId, Integer pointShopId) { + CompletableFuture> future = new CompletableFuture<>(); + Map specMap = new HashMap<>(); + specRepository.searchSpecByShopId(sourceShopId.toString()).forEach(tbProductSpec -> { + Integer sourceSpecId = tbProductSpec.getId(); + tbProductSpec.setId(null); + tbProductSpec.setShopId(pointShopId.toString()); + specRepository.save(tbProductSpec); + specMap.put(sourceSpecId, tbProductSpec.getId()); + }); + future.complete(specMap); + return future; + } + + // 分类 + @Async + public CompletableFuture> syncCategory(Integer sourceShopId, Integer pointShopId) { + CompletableFuture> future = new CompletableFuture<>(); + Map categoryMap = new HashMap<>(); + List tbShopCategories = categoryRepository.searchCategoryByShopId(sourceShopId.toString()); + List treeIds = new ArrayList<>(); + for (TbShopCategory tbShopCategory : tbShopCategories) { + treeIds.add(tbShopCategory.getId()); + + Integer sourceCategoryId = tbShopCategory.getId(); + tbShopCategory.setId(null); + tbShopCategory.setShopId(pointShopId.toString()); + tbShopCategory.setTree(null); + tbShopCategory.setPid(""); + categoryRepository.save(tbShopCategory); + categoryMap.put(sourceCategoryId, tbShopCategory.getId()); + } + if (CollectionUtil.isNotEmpty(treeIds)) { + List children = categoryRepository.findChildren(treeIds); + for (TbShopCategory child : children) { + Integer sourceCategoryId = child.getId(); + child.setId(null); + child.setShopId(pointShopId.toString()); + child.setTree(categoryMap.get(child.getTree())); + child.setPid(StringUtils.isNotBlank(child.getPid()) ? categoryMap.get(Integer.valueOf(child.getPid())).toString() : ""); + categoryRepository.save(child); + categoryMap.put(sourceCategoryId, child.getId()); + } + } + future.complete(categoryMap); + return future; + } + + @Async + public CompletableFuture> syncProduct(Integer sourceShopId, Integer pointShopId, Map units, + Map specs, Map cateGorys) { + CompletableFuture> future = new CompletableFuture<>(); + Map proMap = new HashMap<>(); + productRepository.findByShopId(sourceShopId.toString()).forEach(tbProduct -> { + Integer sourceSpecId = tbProduct.getId(); + tbProduct.setId(null); + tbProduct.setShopId(pointShopId.toString()); + tbProduct.setCategoryId(StringUtils.isNotBlank(tbProduct.getCategoryId()) ? cateGorys.get(Integer.valueOf(tbProduct.getCategoryId())).toString() : ""); + tbProduct.setSpecId(tbProduct.getSpecId() != null ? specs.get(tbProduct.getSpecId()) : null); + tbProduct.setUnitId(tbProduct.getUnitId() != null ? units.get(tbProduct.getUnitId()) : null); + tbProduct.setStockNumber(0); + + productRepository.save(tbProduct); + proMap.put(sourceSpecId, tbProduct.getId()); + }); + future.complete(proMap); + return future; + } + + @Async + public CompletableFuture> syncGroup(Integer sourceShopId, Integer pointShopId, Map pros) { + CompletableFuture> future = new CompletableFuture<>(); + Map groupMap = new HashMap<>(); + groupRepository.searchGroupByShopId(sourceShopId).forEach(tbProductGroup -> { + Integer groupId = tbProductGroup.getId(); + tbProductGroup.setId(null); + tbProductGroup.setShopId(pointShopId); + tbProductGroup.setUseTime(0); + tbProductGroup.setProductIds(replaceProIds(tbProductGroup.getProductIds(), pros)); + groupRepository.save(tbProductGroup); + groupMap.put(groupId, tbProductGroup.getId()); + }); + future.complete(groupMap); + return future; + } + + //分组 + @Async + public void syncGroupPackage(Integer shopId, Map pros, Map skus) { + productRepository.findPackageByShopId(shopId.toString()).forEach(tbProduct -> { + tbProduct.setProGroupVo(JSONUtil.parseJSONStrTList(tbProduct.getGroupSnap(), ProductGroupVo.class)); + tbProduct.getProGroupVo().forEach(proGroupVo -> { + proGroupVo.getGoods().forEach(goods -> { + if (pros.containsKey(goods.getProId())) { + if (goods.getSkuId() != null && skus.containsKey(goods.getSkuId())) { + goods.setProId(pros.get(goods.getProId())); + goods.setSkuId(skus.get(goods.getSkuId())); + } else { + goods.setProId(pros.get(goods.getProId())); + } + } + }); + proGroupVo.setCount(proGroupVo.getGoods().size()); + if (proGroupVo.getNumber() != null && proGroupVo.getNumber() > 0) { + if (proGroupVo.getNumber() > proGroupVo.getCount()) { + proGroupVo.setNumber(proGroupVo.getCount()); + } + } + }); + tbProduct.setGroupSnap(ListUtil.listToJsonString(tbProduct.getProGroupVo())); + productRepository.save(tbProduct); + }); + } + + //分组 + @Async + public CompletableFuture> syncSku(Integer sourceShopId, Integer pointShopId, Map pros) { + CompletableFuture> future = new CompletableFuture<>(); + Map skuMap = new HashMap<>(); + skuRepository.searchSkuByShopId(sourceShopId.toString()).forEach(tbProductSku -> { + Integer productId = Integer.valueOf(tbProductSku.getProductId()); + if (pros.containsKey(productId)) { + Integer sourceSkuId = tbProductSku.getId(); + tbProductSku.setId(null); + tbProductSku.setShopId(pointShopId.toString()); + tbProductSku.setProductId(pros.get(productId).toString()); + skuRepository.save(tbProductSku); + skuMap.put(sourceSkuId, tbProductSku.getId()); + } + }); + future.complete(skuMap); + return future; + } + + @Async + public CompletableFuture syncSkuResult(Map pros) { + CompletableFuture future = new CompletableFuture<>(); + List skuResults = skuResultRepository.findAll((root, criteriaQuery, criteriaBuilder) -> { + Predicate predicate = root.get("id").in(pros.keySet()); + return predicate; + }); + skuResults.forEach(tbProductSkuResult -> { + tbProductSkuResult.setId(pros.get(tbProductSkuResult.getId())); + skuResultRepository.save(tbProductSkuResult); + }); + future.complete(skuResults.size()); + return future; + } + + @Async + public CompletableFuture> syncConsType(Integer sourceShopId, Integer pointShopId) { + CompletableFuture> future = new CompletableFuture<>(); + Map consTypeMap = new HashMap<>(); + + List tbConsTypes = consTypeRepository.searchConsTypeByShopId(sourceShopId); + for (TbConsType tbConsType : tbConsTypes) { + Integer sourceConsTypeId = tbConsType.getId(); + tbConsType.setId(null); + tbConsType.setShopId(pointShopId); + consTypeRepository.save(tbConsType); + consTypeMap.put(sourceConsTypeId, tbConsType.getId()); + } + + future.complete(consTypeMap); + return future; + } + + // 耗材 + @Async + public CompletableFuture> syncCons(Integer sourceShopId, Integer pointShopId, Map conTypes) { + CompletableFuture> future = new CompletableFuture<>(); + Map consMap = new HashMap<>(); + List tbConsInfos = consRepository.searchConsInfoByShopId(sourceShopId); + for (TbConsInfo tbConsInfo : tbConsInfos) { + Integer sourceConsId = tbConsInfo.getId(); + + tbConsInfo.setId(null); + tbConsInfo.setShopId(pointShopId); + tbConsInfo.setConTypeId(conTypes.get(tbConsInfo.getConTypeId())); + tbConsInfo.setStockNumber(BigDecimal.ZERO); + tbConsInfo.setStockConsume(BigDecimal.ZERO); + consRepository.save(tbConsInfo); + consMap.put(sourceConsId, tbConsInfo.getId()); + } + future.complete(consMap); + return future; + } + + @Async + public CompletableFuture> syncConsPro(Integer sourceShopId, Integer pointShopId, Map consMap, Map proMap, Map skuMap) { + CompletableFuture> future = new CompletableFuture<>(); + Map proSkuConMap = new HashMap<>(); + proSkuConRepository.searchConsProByShopId(sourceShopId).forEach(tbConsPro -> { + if (consMap.containsKey(tbConsPro.getConInfoId()) && proMap.containsKey(tbConsPro.getProductId()) && skuMap.containsKey(tbConsPro.getProductSkuId())) { + Integer sourceConsProId = tbConsPro.getId(); + tbConsPro.setId(null); + tbConsPro.setShopId(pointShopId); + tbConsPro.setConInfoId(consMap.get(tbConsPro.getConInfoId())); + tbConsPro.setProductId(proMap.get(tbConsPro.getProductId())); + if (tbConsPro.getProductSkuId() > 0) { + tbConsPro.setProductSkuId(skuMap.get(tbConsPro.getProductSkuId())); + } + proSkuConRepository.save(tbConsPro); + proSkuConMap.put(sourceConsProId, tbConsPro.getId()); + } + }); + future.complete(proSkuConMap); + return future; + } + + /** + * 分组关联商品 重组 如果绑定的商品Id 不存在 则抛弃 + */ + public static String replaceProIds(String proStr, Map pros) { + if (StringUtils.isNotBlank(proStr) && !"[]".equals(proStr)) { + proStr = proStr.substring(1, proStr.length() - 1); + String[] numbersStr = proStr.split(","); + String result = Stream.of(numbersStr) + .map(Integer::parseInt) + .filter(number -> pros.containsKey(number)) + .map(pros::get) + .map(Object::toString) + .collect(Collectors.joining(",", "[", "]")); + return result; + } + return "[]"; + } +} + diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductGroupRepository.java b/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductGroupRepository.java index 063d4e3e..e04741e4 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductGroupRepository.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductGroupRepository.java @@ -2,6 +2,7 @@ package cn.ysk.cashier.repository.product; import cn.ysk.cashier.pojo.product.TbProductGroup; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -23,4 +24,13 @@ public interface TbProductGroupRepository extends JpaRepository findByIds(List productIds); + + @Query("SELECT groups from TbProductGroup groups where groups.shopId = :shopId") + List searchGroupByShopId(@Param("shopId") Integer shopId); + + @Modifying + @Query("delete from TbProductGroup groups where groups.shopId = :shopId") + void clearShopGroup(@Param("shopId") Integer shopId); + + } \ No newline at end of file diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductRepository.java b/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductRepository.java index f2c9ce26..e5cdad6b 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductRepository.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductRepository.java @@ -14,23 +14,34 @@ import java.math.BigDecimal; import java.util.List; /** -* @website https://eladmin.vip -* @author lyf -* @date 2023-12-11 -**/ + * @author lyf + * @website https://eladmin.vip + * @date 2023-12-11 + **/ public interface TbProductRepository extends JpaRepository, JpaSpecificationExecutor { @Query("SELECT product from TbProduct product where product.id in :productIds order by product.sort") List findByIds(List productIds); - @Query(value = "update tb_product set status = -1 and is_del = 1 where id in :productIds",nativeQuery = true) + @Query("SELECT product from TbProduct product where product.shopId = :shopId and product.status=1 and product.isDel=0 and product.type in ('coupon','package') ") + List findPackageByShopId(@Param("shopId") String shopId); + + + @Query("SELECT product from TbProduct product where product.shopId = :shopId and product.status=1 and product.isDel=0") + List findByShopId(@Param("shopId") String shopId); + + @Modifying + @Query("delete FROM TbProduct product where product.shopId = :shopId") + void clearShopPro(@Param("shopId") String shopId); + + @Query(value = "update tb_product set status = -1 and is_del = 1 where id in :productIds", nativeQuery = true) @Modifying void updateByStatus(List productIds); @Modifying @Query("update FROM TbProduct pro set pro.stockNumber=:stockNumber WHERE pro.id =:productId") - void updateProductStockNumber(@Param("productId") Integer productId,@Param("stockNumber") Integer stockNumber); + void updateProductStockNumber(@Param("productId") Integer productId, @Param("stockNumber") Integer stockNumber); @Modifying @Query("update FROM TbProduct pro set pro.stockNumber=pro.stockNumber+:number WHERE pro.id =:productId") @@ -39,8 +50,8 @@ public interface TbProductRepository extends JpaRepository, @Transactional @Modifying @Query("update FROM TbProduct pro set pro.stockNumber=:stocktakinNum where pro.id=:id and pro.stockNumber=:stockNumber") - Integer updateStock(@Param("id") Integer id,@Param("stockNumber") Integer stockNumber, - @Param("stocktakinNum") Integer stocktakinNum); + Integer updateStock(@Param("id") Integer id, @Param("stockNumber") Integer stockNumber, + @Param("stocktakinNum") Integer stocktakinNum); @Modifying @Query("update TbProduct set stockNumber=stockNumber+:num where id=:id") @@ -64,6 +75,6 @@ public interface TbProductRepository extends JpaRepository, @Transactional @Modifying @Query("UPDATE TbProduct p SET p.warnLine = :warnLine WHERE p.shopId = :shopId") - Integer updateWarnLineByShopId(@Param("warnLine")Integer warnLine, @Param("shopId")String shopId); + Integer updateWarnLineByShopId(@Param("warnLine") Integer warnLine, @Param("shopId") String shopId); } diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductSkuRepository.java b/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductSkuRepository.java index c04d9045..598b5a01 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductSkuRepository.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductSkuRepository.java @@ -22,6 +22,12 @@ public interface TbProductSkuRepository extends JpaRepository searchSku(@Param("productId")String productId); + @Query("SELECT sku FROM TbProductSku sku WHERE sku.shopId = :shopId and sku.isDel=0") + List searchSkuByShopId(@Param("shopId")String shopId); + + @Modifying + @Query("delete FROM TbProductSku sku WHERE sku.shopId = :shopId ") + void clearShopSku(@Param("shopId")String shopId); @Transactional @Modifying diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductSkuResultRepository.java b/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductSkuResultRepository.java index 0f818a00..a78d774a 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductSkuResultRepository.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductSkuResultRepository.java @@ -1,18 +1,3 @@ -/* -* Copyright 2019-2020 Zheng Jie -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ package cn.ysk.cashier.repository.product; import cn.ysk.cashier.pojo.product.TbProductSkuResult; diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductSpecRepository.java b/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductSpecRepository.java index b801a505..7be7e20b 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductSpecRepository.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbProductSpecRepository.java @@ -1,41 +1,50 @@ /* -* Copyright 2019-2020 Zheng Jie -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package cn.ysk.cashier.repository.product; import cn.ysk.cashier.pojo.product.TbProductSpec; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import java.util.List; /** -* @website https://eladmin.vip -* @author lyf -* @date 2024-01-03 -**/ + * @author lyf + * @website https://eladmin.vip + * @date 2024-01-03 + **/ public interface TbProductSpecRepository extends JpaRepository, JpaSpecificationExecutor { @Query("SELECT spec FROM TbProductSpec spec WHERE spec.id IN :ids") - List searchSpec(@Param("ids")List ids); + List searchSpec(@Param("ids") List ids); @Query("SELECT spec FROM TbProductSpec spec WHERE spec.id = :ids") - TbProductSpec searchSpec(@Param("ids")Integer ids); + TbProductSpec searchSpec(@Param("ids") Integer ids); @Query("SELECT spec FROM TbProductSpec spec WHERE spec.shopId = :shopId and spec.name = :name") - TbProductSpec findAllByName(@Param("shopId")String shopId, @Param("name")String name); + TbProductSpec findAllByName(@Param("shopId") String shopId, @Param("name") String name); + + + @Query("SELECT spec FROM TbProductSpec spec WHERE spec.shopId = :shopId") + List searchSpecByShopId(@Param("shopId") String shopId); + + @Modifying + @Query("delete FROM TbProductSpec spec WHERE spec.shopId = :shopId") + void clearShopSpec(@Param("shopId") String shopId); } \ No newline at end of file diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbShopCategoryRepository.java b/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbShopCategoryRepository.java index 5e29938e..a74e1e88 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbShopCategoryRepository.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/repository/product/TbShopCategoryRepository.java @@ -20,6 +20,7 @@ import org.apache.ibatis.annotations.Param; import org.springframework.data.domain.Page; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.domain.Pageable; @@ -44,4 +45,10 @@ public interface TbShopCategoryRepository extends JpaRepository searchCategory(@Param("ids")List ids); + @Query("SELECT category FROM TbShopCategory category where category.shopId = :shopId and (category.pid is null or category.pid = '')") + List searchCategoryByShopId(@Param("shopId") String shopId); + + @Modifying + @Query("delete FROM TbShopCategory category where category.shopId = :shopId") + void clearShopCategory(@Param("shopId") String shopId); } \ No newline at end of file diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/repository/shop/TbShopUnitRepository.java b/eladmin-system/src/main/java/cn/ysk/cashier/repository/shop/TbShopUnitRepository.java index 06ff650c..2e791e25 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/repository/shop/TbShopUnitRepository.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/repository/shop/TbShopUnitRepository.java @@ -1,23 +1,9 @@ -/* -* Copyright 2019-2020 Zheng Jie -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ package cn.ysk.cashier.repository.shop; import cn.ysk.cashier.pojo.shop.TbShopUnit; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -37,4 +23,11 @@ public interface TbShopUnitRepository extends JpaRepository @Query("SELECT unit from TbShopUnit unit where unit.name = :name and unit.shopId = :shopId") TbShopUnit findName(@Param("name")String name,@Param("shopId")String shopId); + + @Query("SELECT unit FROM TbShopUnit unit WHERE unit.shopId = :shopId") + List searchUnitByShopId(@Param("shopId")String shopId); + + @Modifying + @Query("delete FROM TbShopUnit unit WHERE unit.shopId = :shopId") + void clearShopUnit(@Param("shopId")String shopId); } \ No newline at end of file