Merge branch 'ww-多门店-数据同步' into test

This commit is contained in:
wangw 2024-11-26 15:35:05 +08:00
commit 8ed0eddde9
16 changed files with 769 additions and 60 deletions

View File

@ -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<TbConsInfo, Integer>
" where conPro.con_info_id = :conInfoId " +
" group by conPro.product_id ",nativeQuery = true)
List<Map<Integer, Object>> 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<TbConsInfo> searchConsInfoByShopId(Integer shopId);
@Modifying
@Query(value = "delete FROM tb_prosku_con conPro where conPro.shop_id = :shopId ",nativeQuery = true)
void clearShopCons(Integer shopId);
}

View File

@ -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, Integer>
TbConsType findByConTypeCode(String conTypeCode);
@Query("SELECT c FROM TbProskuCon c WHERE c.shopId = :shopId")
List<TbConsType> 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);
}

View File

@ -30,4 +30,11 @@ public interface TbProskuConRepository extends JpaRepository<TbProskuCon, Intege
List<TbProskuCon> searchAllByProductId(Integer productId);
@Query(value = "select * from tb_prosku_con where shop_id=?1 ",nativeQuery = true)
List<TbProskuCon> searchConsProByShopId(Integer shopId);
@Modifying
@Query(value = "delete from tb_prosku_con where shop_id=?1 ",nativeQuery = true)
void clearShopConPro(Integer shopId);
}

View File

@ -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<Object> selectAll(TbShopSyncInfoQueryCriteria criteria) {
return new ResponseEntity<>(tbShopSyncInfoService.queryByShopId(criteria), HttpStatus.OK);
}
@PostMapping("/sync")
@ApiOperation("同步")
public ResponseEntity<Object> 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<Object> 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);
}
}

View File

@ -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;
}

View File

@ -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<TbShopSyncInfo> {
@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;
}

View File

@ -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<TbShopSyncInfo> {
}

View File

@ -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> {
TbShopSyncInfo queryByShopId(TbShopSyncInfoQueryCriteria criteria);
void sync(TbShopSyncInfo tbShopSyncInfo);
void clear(TbShopSyncInfo tbShopSyncInfo);
}

View File

@ -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<TbShopSyncInfoMapper, TbShopSyncInfo> 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<TbShopSyncInfo> 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<Integer, Integer> units;
Map<Integer, Integer> specs;
Map<Integer, Integer> cateGorys;
Map<Integer, Integer> groups;
Map<Integer, Integer> pros = new HashMap<>();
Map<Integer, Integer> skus = new HashMap<>();
Map<Integer, Integer> conTypes;
Map<Integer, Integer> consInfos = new HashMap<>();
Map<Integer, Integer> consPros = new HashMap<>();
Integer skuResults = 0;
TbShopSyncInfoServiceImpl self = applicationContext.getBean(TbShopSyncInfoServiceImpl.class);
try {
List<CompletableFuture<?>> futures = new ArrayList<>();
List<CompletableFuture<?>> futures2 = new ArrayList<>();
if (tbShopSyncInfo.getProduct() != null && tbShopSyncInfo.getProduct() > 0) {
CompletableFuture<Map<Integer, Integer>> futureUnit = self.syncUnit(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId());
CompletableFuture<Map<Integer, Integer>> futureSpec = self.syncSpec(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId());
CompletableFuture<Map<Integer, Integer>> 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<Map<Integer, Integer>> futurePros = self.syncProduct(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId(), units, specs, cateGorys);
pros = futurePros.get();
tbShopSyncInfo.setProduct(pros.size());
self.syncGroupPackage(tbShopSyncInfo.getPointShopId(), pros, skus);
CompletableFuture<Map<Integer, Integer>> futureGroup = self.syncGroup(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId(), pros);
CompletableFuture<Map<Integer, Integer>> futureSkus = self.syncSku(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId(), pros);
CompletableFuture<Integer> 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<Map<Integer, Integer>> futureUnit = self.syncUnit(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId());
units = futureUnit.get();
tbShopSyncInfo.setProUnit(units.size());
}
if (tbShopSyncInfo.getProCategory() != null && tbShopSyncInfo.getProCategory() > 0) {
CompletableFuture<Map<Integer, Integer>> futureCate = self.syncCategory(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId());
cateGorys = futureCate.get();
tbShopSyncInfo.setProCategory(cateGorys.size());
}
if (tbShopSyncInfo.getProSpec() != null && tbShopSyncInfo.getProSpec() > 0) {
CompletableFuture<Map<Integer, Integer>> futureSpec = self.syncSpec(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId());
specs = futureSpec.get();
tbShopSyncInfo.setProSpec(specs.size());
}
}
if (tbShopSyncInfo.getConsInfo() != null && tbShopSyncInfo.getConsInfo() > 0) {
CompletableFuture<Map<Integer, Integer>> futureConTypes = self.syncConsType(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId());
conTypes = futureConTypes.get();
tbShopSyncInfo.setConsType(conTypes.size());
CompletableFuture<Map<Integer, Integer>> futureConsInfos = self.syncCons(tbShopSyncInfo.getSourceShopId(), tbShopSyncInfo.getPointShopId(), conTypes);
consInfos = futureConsInfos.get();
tbShopSyncInfo.setConsInfo(consInfos.size());
} else if (tbShopSyncInfo.getConsType() != null && tbShopSyncInfo.getConsType() > 0) {
CompletableFuture<Map<Integer, Integer>> 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<Map<Integer, Integer>> 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<TbProduct> 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<TbShopSyncInfo> wrapper = new QueryWrapper<>();
wrapper.eq("point_shop_id", tbShopSyncInfo.getPointShopId());
tbShopSyncInfomapper.delete(wrapper);
}
//单位
@Async
public CompletableFuture<Map<Integer, Integer>> syncUnit(Integer sourceShopId, Integer pointShopId) {
CompletableFuture<Map<Integer, Integer>> future = new CompletableFuture<>();
Map<Integer, Integer> 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<Map<Integer, Integer>> syncSpec(Integer sourceShopId, Integer pointShopId) {
CompletableFuture<Map<Integer, Integer>> future = new CompletableFuture<>();
Map<Integer, Integer> 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<Map<Integer, Integer>> syncCategory(Integer sourceShopId, Integer pointShopId) {
CompletableFuture<Map<Integer, Integer>> future = new CompletableFuture<>();
Map<Integer, Integer> categoryMap = new HashMap<>();
List<TbShopCategory> tbShopCategories = categoryRepository.searchCategoryByShopId(sourceShopId.toString());
List<Integer> 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<TbShopCategory> 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<Map<Integer, Integer>> syncProduct(Integer sourceShopId, Integer pointShopId, Map<Integer, Integer> units,
Map<Integer, Integer> specs, Map<Integer, Integer> cateGorys) {
CompletableFuture<Map<Integer, Integer>> future = new CompletableFuture<>();
Map<Integer, Integer> 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<Map<Integer, Integer>> syncGroup(Integer sourceShopId, Integer pointShopId, Map<Integer, Integer> pros) {
CompletableFuture<Map<Integer, Integer>> future = new CompletableFuture<>();
Map<Integer, Integer> 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<Integer, Integer> pros, Map<Integer, Integer> 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<Map<Integer, Integer>> syncSku(Integer sourceShopId, Integer pointShopId, Map<Integer, Integer> pros) {
CompletableFuture<Map<Integer, Integer>> future = new CompletableFuture<>();
Map<Integer, Integer> 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<Integer> syncSkuResult(Map<Integer, Integer> pros) {
CompletableFuture<Integer> future = new CompletableFuture<>();
List<TbProductSkuResult> 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<Map<Integer, Integer>> syncConsType(Integer sourceShopId, Integer pointShopId) {
CompletableFuture<Map<Integer, Integer>> future = new CompletableFuture<>();
Map<Integer, Integer> consTypeMap = new HashMap<>();
List<TbConsType> 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<Map<Integer, Integer>> syncCons(Integer sourceShopId, Integer pointShopId, Map<Integer, Integer> conTypes) {
CompletableFuture<Map<Integer, Integer>> future = new CompletableFuture<>();
Map<Integer, Integer> consMap = new HashMap<>();
List<TbConsInfo> 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<Map<Integer, Integer>> syncConsPro(Integer sourceShopId, Integer pointShopId, Map<Integer, Integer> consMap, Map<Integer, Integer> proMap, Map<Integer, Integer> skuMap) {
CompletableFuture<Map<Integer, Integer>> future = new CompletableFuture<>();
Map<Integer, Integer> 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<Integer, Integer> 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 "[]";
}
}

View File

@ -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<TbProductGroup,
@Query("SELECT groups from TbProductGroup groups where groups.id in :productIds order by groups.sort")
List<TbProductGroup> findByIds(List<Integer> productIds);
@Query("SELECT groups from TbProductGroup groups where groups.shopId = :shopId")
List<TbProductGroup> searchGroupByShopId(@Param("shopId") Integer shopId);
@Modifying
@Query("delete from TbProductGroup groups where groups.shopId = :shopId")
void clearShopGroup(@Param("shopId") Integer shopId);
}

View File

@ -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<TbProduct, Integer>, JpaSpecificationExecutor<TbProduct> {
@Query("SELECT product from TbProduct product where product.id in :productIds order by product.sort")
List<TbProduct> findByIds(List<Integer> 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<TbProduct> findPackageByShopId(@Param("shopId") String shopId);
@Query("SELECT product from TbProduct product where product.shopId = :shopId and product.status=1 and product.isDel=0")
List<TbProduct> 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<Integer> 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<TbProduct, Integer>,
@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<TbProduct, Integer>,
@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);
}

View File

@ -22,6 +22,12 @@ public interface TbProductSkuRepository extends JpaRepository<TbProductSku, Inte
@Query("SELECT sku FROM TbProductSku sku WHERE sku.productId = :productId and sku.isDel=0")
List<TbProductSku> searchSku(@Param("productId")String productId);
@Query("SELECT sku FROM TbProductSku sku WHERE sku.shopId = :shopId and sku.isDel=0")
List<TbProductSku> searchSkuByShopId(@Param("shopId")String shopId);
@Modifying
@Query("delete FROM TbProductSku sku WHERE sku.shopId = :shopId ")
void clearShopSku(@Param("shopId")String shopId);
@Transactional
@Modifying

View File

@ -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;

View File

@ -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<TbProductSpec, Integer>, JpaSpecificationExecutor<TbProductSpec> {
@Query("SELECT spec FROM TbProductSpec spec WHERE spec.id IN :ids")
List<TbProductSpec> searchSpec(@Param("ids")List<Integer> ids);
List<TbProductSpec> searchSpec(@Param("ids") List<Integer> 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<TbProductSpec> searchSpecByShopId(@Param("shopId") String shopId);
@Modifying
@Query("delete FROM TbProductSpec spec WHERE spec.shopId = :shopId")
void clearShopSpec(@Param("shopId") String shopId);
}

View File

@ -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<TbShopCategory,
@Query("SELECT category FROM TbShopCategory category where category.id IN :ids ")
List<TbShopCategory> searchCategory(@Param("ids")List<Integer> ids);
@Query("SELECT category FROM TbShopCategory category where category.shopId = :shopId and (category.pid is null or category.pid = '')")
List<TbShopCategory> searchCategoryByShopId(@Param("shopId") String shopId);
@Modifying
@Query("delete FROM TbShopCategory category where category.shopId = :shopId")
void clearShopCategory(@Param("shopId") String shopId);
}

View File

@ -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<TbShopUnit, Integer>
@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<TbShopUnit> searchUnitByShopId(@Param("shopId")String shopId);
@Modifying
@Query("delete FROM TbShopUnit unit WHERE unit.shopId = :shopId")
void clearShopUnit(@Param("shopId")String shopId);
}