package com.by4cloud.platformx.business.service.impl;
|
|
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.lang.tree.Tree;
|
import cn.hutool.core.lang.tree.TreeNode;
|
import cn.hutool.core.lang.tree.TreeUtil;
|
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.http.HttpRequest;
|
import cn.hutool.http.HttpResponse;
|
import cn.hutool.http.HttpUtil;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.by4cloud.platformx.business.dto.ProductAddDTO;
|
import com.by4cloud.platformx.business.dto.ProductQueryDTO;
|
import com.by4cloud.platformx.business.dto.SyncProductDTO;
|
import com.by4cloud.platformx.business.entity.BusinessCustomer;
|
import com.by4cloud.platformx.business.entity.Product;
|
import com.by4cloud.platformx.business.entity.TaxCode;
|
import com.by4cloud.platformx.business.mapper.ProductMapper;
|
import com.by4cloud.platformx.business.mapper.TaxCodeMapper;
|
import com.by4cloud.platformx.business.service.ProductService;
|
import com.by4cloud.platformx.business.vo.ProductExcelVO;
|
import com.by4cloud.platformx.business.vo.ProductSelectVo;
|
import com.by4cloud.platformx.common.core.util.R;
|
import com.by4cloud.platformx.common.data.datascope.DataScope;
|
import com.by4cloud.platformx.common.excel.vo.ErrorMessage;
|
import com.by4cloud.platformx.common.security.util.SecurityUtils;
|
import jakarta.validation.constraints.NotNull;
|
import lombok.RequiredArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.stereotype.Service;
|
import org.springframework.validation.BindingResult;
|
|
import java.util.*;
|
import java.util.function.Function;
|
import java.util.stream.Collectors;
|
import java.util.stream.IntStream;
|
|
;
|
|
/**
|
* 产品信息
|
*
|
* @author platformx
|
* @date 2026-05-07 10:17:52
|
*/
|
@Slf4j
|
@Service
|
@RequiredArgsConstructor
|
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
|
|
private final TaxCodeMapper taxCodeMapper;
|
|
private final StringRedisTemplate redisTemplate;
|
|
@Value("${erp.smj}")
|
private String smjErp;
|
|
@Value("${erp.smjsc}")
|
private String smjscErp;
|
|
@Value("${erp.smjzt}")
|
private String smjztErp;
|
|
@Value("${dept.smj}")
|
private String smj;
|
|
@Value("${dept.smjsc}")
|
private String smjsc;
|
|
@Value("${dept.smjzt}")
|
private String smjzt;
|
|
@Value("${dept.smjhw}")
|
private String smjhw;
|
|
|
@Override
|
public Page pageScope(Page page, Product product) {
|
if (StrUtil.equals(SecurityUtils.getUser().getCompId() + "", smj) || StrUtil.equals(SecurityUtils.getUser().getCompId() + "", smjhw)) {
|
List<String> smjList = new ArrayList<>();
|
smjList.add(smj);
|
smjList.add(smjhw);
|
return baseMapper.page(page,product,smjList);
|
}
|
return baseMapper.pageScope(page,product,DataScope.of("comp_id"));
|
}
|
|
@Override
|
public List<Tree<Long>> treeList() {
|
List<TreeNode<Long>> collect = baseMapper
|
.selectListByScope(Wrappers.<Product>lambdaQuery()
|
.orderByAsc(Product::getCreateTime), DataScope.of("comp_id"))
|
.stream().map(getNodeFunction()).collect(Collectors.toList());
|
|
// 模糊查询 不组装树结构 直接返回 表格方便编辑
|
// if (StrUtil.isNotBlank(productName)) {
|
// return collect.stream().map(node -> {
|
// Tree<Long> tree = new Tree<>();
|
// tree.putAll(node.getExtra());
|
// BeanUtils.copyProperties(node, tree);
|
// return tree;
|
// }).collect(Collectors.toList());
|
// }
|
TreeNode<Long> parent = new TreeNode<>();
|
parent.setId(0L);
|
parent.setName("目录");
|
parent.setParentId(-1L);
|
collect.add(parent);
|
return TreeUtil.build(collect, 0L);
|
}
|
|
@Override
|
public List<ProductSelectVo> getProductList(Product product) {
|
return baseMapper.getProductListByScope(product,DataScope.of("comp_id"));
|
}
|
|
|
@NotNull
|
private Function<Product, TreeNode<Long>> getNodeFunction() {
|
return product -> {
|
TreeNode<Long> node = new TreeNode<>();
|
node.setId(product.getId());
|
node.setName(product.getProductName());
|
node.setParentId(product.getParentId());
|
//node.setWeight(product.getParentId());
|
// 扩展属性
|
// Map<String, Object> extra = new HashMap<>();
|
// extra.put("picPath", category.getPicPath());
|
// extra.put("Type", category.getType());
|
// extra.put("isShow", category.getIsShow());
|
// extra.put("iconPicPath", category.getIconPath());
|
// extra.put("status", category.getStatus());
|
|
// 适配 vue3
|
// Map<String, Object> meta = new HashMap<>();
|
/* meta.put("title", product.getProductName());
|
meta.put("icon", product.getPrice());*/
|
|
//extra.put("meta", meta);
|
//node.setExtra(extra);
|
return node;
|
};
|
}
|
|
@Override
|
public R getProductListByParentId(ProductQueryDTO queryDTO) {
|
String[] erpCodes = new String[]{"house_rental","electricity_bill","water_bill"};
|
// MPJLambdaWrapper<Product> wrapper = new MPJLambdaWrapper<Product>()
|
// .selectAs("( SELECT count(1) FROM product t1 WHERE t1.parent_id = t.id )",Product::getChildNum)
|
// .selectAll(Product.class)
|
// .like(StrUtil.isNotEmpty(queryDTO.getProductName()),Product::getProductName,queryDTO.getProductName())
|
// .eq(StrUtil.isNotEmpty(queryDTO.getParentId()),Product::getParentId,queryDTO.getParentId())
|
// .in(StrUtil.isNotEmpty(queryDTO.getContractCategory())&&StrUtil.equals(queryDTO.getContractCategory(), "water_house"),
|
// Product::getErpCode,erpCodes);
|
if (StrUtil.isNotBlank(queryDTO.getProductIds())){
|
String[] arr = queryDTO.getProductIds().split(",");
|
queryDTO.setProductId(Arrays.stream(arr).collect(Collectors.toList()));
|
}
|
if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"","2089995177814495234")||
|
StrUtil.equals(SecurityUtils.getUser().getCompId()+"","2101966257365045249")){
|
List<ProductSelectVo> selectVos = baseMapper.getProductSMJListByParentId(queryDTO, Arrays.asList(erpCodes));
|
if (selectVos.size()>2000){
|
return R.ok(selectVos.subList(0,1999));
|
}
|
return R.ok(selectVos);
|
}
|
List<ProductSelectVo> selectVos = baseMapper.getProductListByParentId(queryDTO, Arrays.asList(erpCodes),DataScope.of("comp_id"));
|
if (selectVos.size()>2000){
|
return R.ok(selectVos.subList(0,1999));
|
}
|
return R.ok(selectVos);
|
}
|
|
@Override
|
public R saveErpProduct(List<ProductAddDTO> addDTOS) {
|
if (CollUtil.isNotEmpty(addDTOS)){
|
for (ProductAddDTO addDTO:addDTOS
|
) {
|
if (StrUtil.isBlank(addDTO.getErpCode())){
|
return R.failed("erp编码不能为空");
|
}
|
List<Product> classPro = baseMapper.selectListByScope(Wrappers.<Product>lambdaQuery()
|
.eq(StrUtil.isNotEmpty(addDTO.getErpTypeCode()),Product::getErpCode,addDTO.getErpTypeCode())
|
.eq(StrUtil.isNotEmpty(addDTO.getErpTypeName()),Product::getProductName,addDTO.getErpTypeName())
|
, DataScope.of("comp_id"));
|
if (CollUtil.isEmpty(classPro)){
|
Product product = new Product();
|
product.setProductName(addDTO.getErpTypeName());
|
product.setProductType(addDTO.getSpecification());
|
product.setParentId(0L);
|
product.setParentName("根级产品");
|
product.setErpCode(addDTO.getErpTypeCode());
|
TaxCode taxCode = taxCodeMapper.selectOne(Wrappers.<TaxCode>lambdaQuery().eq(TaxCode::getBm,addDTO.getTaxCode()).last("limit 1"));
|
if (ObjUtil.isNotNull(taxCode)){
|
product.setTaxClass(taxCode.getSphwjc());
|
product.setTaxRate(Double.valueOf(taxCode.getSl().replace("%","")));
|
}
|
baseMapper.insert(product);
|
classPro.add(product);
|
}
|
List<Product> productList = baseMapper.selectListByScope(Wrappers.<Product>lambdaQuery()
|
.eq(StrUtil.isNotEmpty(addDTO.getErpCode()),Product::getErpCode,addDTO.getErpCode())
|
, DataScope.of("comp_id"));
|
if (CollUtil.isEmpty(productList)){
|
Product product = new Product();
|
product.setProductName(addDTO.getErpName());
|
product.setProductType(addDTO.getSpecification());
|
product.setParentId(classPro.get(0).getId());
|
product.setParentName(classPro.get(0).getProductName());
|
product.setErpCode(addDTO.getErpCode());
|
TaxCode taxCode = taxCodeMapper.selectOne(Wrappers.<TaxCode>lambdaQuery().eq(TaxCode::getBm,addDTO.getTaxCode()).last("limit 1"));
|
if (ObjUtil.isNotNull(taxCode)){
|
product.setTaxClass(taxCode.getSphwjc());
|
product.setTaxRate(Double.valueOf(taxCode.getSl().replace("%","")));
|
}
|
baseMapper.insert(product);
|
}
|
}
|
}
|
return R.failed("数据为空");
|
}
|
|
@Override
|
public R importProduct(List<ProductExcelVO> excelVOList, BindingResult bindingResult) {
|
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
|
if (CollUtil.isNotEmpty(excelVOList)) {
|
List<List<ProductExcelVO>> groups = splitList(excelVOList, 5000);
|
groups.stream().forEach(group->{
|
for (ProductExcelVO addDTO:group
|
) {
|
Set<String> errorMsg = new HashSet<>();
|
|
if (StrUtil.isEmpty(addDTO.getErpTypeCode())&&StrUtil.isEmpty(addDTO.getErpTypeName())) {
|
errorMsg.add("产品分类信息没有");
|
}
|
List<Product> one = this.listByScope(Wrappers.<Product>lambdaQuery().eq(Product::getErpCode, addDTO.getErpCode()));
|
if (CollUtil.isNotEmpty(one)){
|
errorMsg.add("产品erp编码已存在");
|
}
|
if (CollUtil.isEmpty(errorMsg)){
|
List<Product> classPro = baseMapper.selectListByScope(Wrappers.<Product>lambdaQuery()
|
.eq(StrUtil.isNotEmpty(addDTO.getErpTypeCode()),Product::getErpCode,addDTO.getErpTypeCode())
|
.eq(StrUtil.isNotEmpty(addDTO.getErpTypeName()),Product::getProductName,addDTO.getErpTypeName())
|
, DataScope.of("comp_id"));
|
if (CollUtil.isEmpty(classPro)){
|
Product product = new Product();
|
product.setProductName(addDTO.getErpTypeName());
|
product.setProductType(addDTO.getSpecification());
|
product.setParentId(0L);
|
product.setParentName("根级产品");
|
product.setErpCode(addDTO.getErpTypeCode());
|
TaxCode taxCode = taxCodeMapper.selectOne(Wrappers.<TaxCode>lambdaQuery().eq(TaxCode::getBm,addDTO.getTaxCode()).last("limit 1"));
|
if (ObjUtil.isNotNull(taxCode)){
|
product.setTaxClass(taxCode.getMc());
|
product.setTaxRate(Double.valueOf(taxCode.getSl().replace("%","")));
|
}
|
baseMapper.insert(product);
|
classPro.add(product);
|
}
|
Product product = new Product();
|
product.setProductName(addDTO.getErpName());
|
product.setProductType(addDTO.getSpecification());
|
product.setParentId(classPro.get(0).getId());
|
product.setParentName(classPro.get(0).getProductName());
|
product.setErpCode(addDTO.getErpCode());
|
TaxCode taxCode = taxCodeMapper.selectOne(Wrappers.<TaxCode>lambdaQuery().eq(TaxCode::getBm,addDTO.getTaxCode()).last("limit 1"));
|
if (ObjUtil.isNotNull(taxCode)){
|
product.setTaxClass(taxCode.getMc());
|
product.setTaxRate(Double.valueOf(taxCode.getSl().replace("%","")));
|
}
|
baseMapper.insert(product);
|
}
|
}
|
});
|
}
|
if (CollUtil.isNotEmpty(errorMessageList)) {
|
return R.failed(errorMessageList);
|
}
|
return R.ok();
|
}
|
|
public static <T> List<List<T>> splitList(List<T> list, int batchSize) {
|
if (list == null || list.isEmpty()) {
|
return Collections.emptyList();
|
}
|
|
int totalSize = list.size();
|
// 计算需要分成多少组
|
int batchCount = (totalSize + batchSize - 1) / batchSize;
|
|
return IntStream.range(0, batchCount)
|
.mapToObj(i -> list.subList(i * batchSize,
|
Math.min((i + 1) * batchSize, totalSize)))
|
.collect(Collectors.toList());
|
}
|
|
@Override
|
public R syncSMJByDate(SyncProductDTO dto) {
|
String startDate = "";
|
if (StrUtil.isBlank(dto.getStartDate())){
|
startDate = DateUtil.formatDate(DateUtil.offsetDay(new Date(), -1));
|
}else {
|
startDate = dto.getStartDate();
|
}
|
String token = "";
|
if (redisTemplate.hasKey("SMJ_ERP_TOKEN")) {
|
token = (String) redisTemplate.opsForValue().get("SMJ_ERP_TOKEN");
|
} else {
|
token = getErpToken();
|
}
|
if (StrUtil.isEmpty(token)){
|
return R.failed("石煤机登录获取token失败");
|
}
|
List<String> list = Arrays.asList("tenant1","tenant2","tenant3");
|
for (int i = 0; i < list.size(); i++) {
|
String tan = list.get(i);
|
HttpResponse response = HttpRequest.get(smjErp + "/api/item/v1/byDateCre?startDate=" + startDate+"&tenantId="+tan)
|
.header("token", token) // 添加认证头
|
.execute(); // 执行请求.post(ymjErp,request.toJSONString());
|
log.info("石煤机——"+tan+"产品获取回参:{}", response.body());
|
JSONObject proResult = JSONObject.parseObject(response.body());
|
JSONArray items = proResult.getJSONArray("data");
|
if (CollUtil.isNotEmpty(items)){
|
log.info("石煤机产品获取数量:{}", items.size());
|
items.stream().forEach(item->{
|
JSONObject product = (JSONObject) item;
|
Product productClass = baseMapper.selectOne(Wrappers.<Product>lambdaQuery()
|
.eq(Product::getProductName,product.getString("itemClassName"))
|
// .and(wrapper -> wrapper.eq(Product::getCompId,"2089995177814495234")
|
// .or().eq(Product::getCompId,"2089996921978040321")
|
// .or().eq(Product::getCompId,"2089997578009128962")
|
// )
|
.eq(StrUtil.equals(tan,"tenant1"),Product::getCompId,"2089995177814495234")
|
.eq(StrUtil.equals(tan,"tenant2"),Product::getCompId,"2089996921978040321")
|
.eq(StrUtil.equals(tan,"tenant3"),Product::getCompId,"2089997578009128962")
|
.last("limit 1")
|
);
|
if(ObjUtil.isNull(productClass)){
|
log.info("产品分类:{}不存在",product.getString("itemClassName"));
|
productClass = new Product();
|
productClass.setProductName(product.getString("itemClassName"));
|
productClass.setErpCode(product.getString("itemClassName"));
|
productClass.setParentId(0L);
|
if(StrUtil.equals(tan,"tenant1")){
|
productClass.setCompId(2089995177814495234L);
|
}
|
if(StrUtil.equals(tan,"tenant2")){
|
productClass.setCompId(2089996921978040321L);
|
}
|
if(StrUtil.equals(tan,"tenant3")){
|
productClass.setCompId(2089997578009128962L);
|
}
|
TaxCode taxCode = taxCodeMapper.selectOne(Wrappers.<TaxCode>lambdaQuery().eq(TaxCode::getBm,product.getString("tfTaxClass")).last("limit 1"));
|
if (ObjUtil.isNotNull(taxCode)){
|
productClass.setTaxClass(taxCode.getSphwjc());
|
productClass.setTaxRate(Double.valueOf(taxCode.getSl().replace("%","")));
|
}
|
baseMapper.insert(productClass);
|
log.info("产品分类:{}新增成功",product.getString("itemClassName"));
|
}
|
Product productNew = baseMapper.selectOne(Wrappers.<Product>lambdaQuery()
|
.eq(Product::getErpCode,product.getString("itemNo"))
|
// .and(wrapper -> wrapper.eq(Product::getCompId,"2089995177814495234")
|
// .or().eq(Product::getCompId,"2089996921978040321")
|
// .or().eq(Product::getCompId,"2089997578009128962")
|
// )
|
.eq(StrUtil.equals(tan,"tenant1"),Product::getCompId,"2089995177814495234")
|
.eq(StrUtil.equals(tan,"tenant2"),Product::getCompId,"2089996921978040321")
|
.eq(StrUtil.equals(tan,"tenant3"),Product::getCompId,"2089997578009128962")
|
.last("limit 1")
|
);
|
if(ObjUtil.isNull(productNew)){
|
log.info("产品:{}不存在",product.getString("itemNo"));
|
productNew = new Product();
|
productNew.setProductName(product.getString("note"));
|
productNew.setErpCode(product.getString("itemNo"));
|
productNew.setProductType(product.getString("grade"));
|
if(StrUtil.equals(tan,"tenant1")){
|
productNew.setCompId(2089995177814495234L);
|
}
|
if(StrUtil.equals(tan,"tenant2")){
|
productNew.setCompId(2089996921978040321L);
|
}
|
if(StrUtil.equals(tan,"tenant3")){
|
productNew.setCompId(2089997578009128962L);
|
}
|
productNew.setParentId(productClass.getId());
|
TaxCode taxCode = taxCodeMapper.selectOne(Wrappers.<TaxCode>lambdaQuery().eq(TaxCode::getBm,product.getString("tfTaxClass")).last("limit 1"));
|
if (ObjUtil.isNotNull(taxCode)){
|
productClass.setTaxClass(taxCode.getSphwjc());
|
productClass.setTaxRate(Double.valueOf(taxCode.getSl().replace("%","")));
|
}
|
baseMapper.insert(productNew);
|
log.info("产品:{}新增成功",product.getString("itemNo"));
|
return;
|
}
|
log.info("产品:{}存在",product.getString("itemNo"));
|
});
|
}
|
}
|
|
return R.ok();
|
}
|
|
private String getErpToken() {
|
JSONObject loginJson = new JSONObject();
|
loginJson.put("username", "admin");
|
loginJson.put("password", "Zimafold@2026");
|
log.info("石煤机产品获取token入参:{}", loginJson.toJSONString());
|
String loginResp = HttpUtil.post(smjErp + "/api/account/v1/login", loginJson.toJSONString());
|
log.info("石煤机产品获取token回参:{}", loginResp);
|
JSONObject respJson = JSONObject.parseObject(loginResp);
|
if (respJson.getInteger("code") == 0) {
|
JSONObject dataJson = JSONObject.parseObject(respJson.getString("data"));
|
redisTemplate.opsForValue().set("SMJ_ERP_TOEKN",dataJson.getString("token"));
|
log.info("石煤机erp token为:{}",dataJson.getString("token"));
|
return dataJson.getString("token");
|
}
|
return "";
|
}
|
}
|