211 lines
9.4 KiB
Java
211 lines
9.4 KiB
Java
package com.ruoyi.system.controller;
|
||
|
||
import com.google.gson.JsonArray;
|
||
import com.google.gson.JsonObject;
|
||
import com.kingdee.bos.webapi.sdk.K3CloudApi;
|
||
import com.ruoyi.common.annotation.Log;
|
||
import com.ruoyi.common.core.domain.PageQuery;
|
||
import com.ruoyi.common.core.domain.R;
|
||
import com.ruoyi.common.core.page.TableDataInfo;
|
||
import com.ruoyi.common.utils.StringUtils;
|
||
import com.ruoyi.system.domain.bo.ImMaterialBo;
|
||
import com.ruoyi.system.domain.bo.ImProductionPlanBo;
|
||
import com.ruoyi.system.domain.dto.*;
|
||
import com.ruoyi.system.domain.vo.ImMaterialVo;
|
||
import com.ruoyi.system.domain.vo.InventoryInfoVO;
|
||
import com.ruoyi.system.runner.JdUtil;
|
||
import com.ruoyi.system.service.IImMaterialService;
|
||
import com.ruoyi.system.service.IImProductionPlanService;
|
||
import lombok.RequiredArgsConstructor;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.web.bind.annotation.*;
|
||
|
||
import java.text.SimpleDateFormat;
|
||
import java.util.*;
|
||
import java.util.concurrent.*;
|
||
|
||
@RequiredArgsConstructor
|
||
@RestController
|
||
@RequestMapping("/index")
|
||
@Slf4j
|
||
public class IndexController {
|
||
private static final int MAX_MATERIAL_CODES = 50;
|
||
|
||
private final IImMaterialService iImMaterialService;
|
||
private final IImProductionPlanService imProductionPlanService;
|
||
|
||
@GetMapping("/list")
|
||
public TableDataInfo<ImMaterialVo> list(ImMaterialBo bo, PageQuery pageQuery) {
|
||
return iImMaterialService.queryPageList(bo, pageQuery);
|
||
}
|
||
|
||
/**
|
||
* 金蝶库存查询(支持单个或多个物料编码)
|
||
* <p>
|
||
* 前端一次传入多个编码;后端对每个物料按原逻辑精确查询后汇总返回(金蝶侧不支持可靠的多码 IN 拼接)。
|
||
* 参数任选其一:
|
||
* - materialCode:单个物料编码(兼容旧调用)
|
||
* - materialCodes:多个物料编码,逗号分隔
|
||
*/
|
||
@GetMapping("/inventory")
|
||
public R<List<InventoryInfoVO>> handleData(
|
||
@RequestParam(value = "materialCode", required = false) String materialCode,
|
||
@RequestParam(value = "materialCodes", required = false) String materialCodes) {
|
||
List<String> codes = parseMaterialCodes(materialCode, materialCodes);
|
||
if (codes.isEmpty()) {
|
||
return R.fail("请指定物料编码");
|
||
}
|
||
if (codes.size() > MAX_MATERIAL_CODES) {
|
||
return R.fail("单次最多查询 " + MAX_MATERIAL_CODES + " 个物料");
|
||
}
|
||
|
||
int poolSize = Math.min(Math.max(codes.size(), 4), 10);
|
||
ExecutorService executorService = new ThreadPoolExecutor(
|
||
poolSize,
|
||
poolSize,
|
||
0L,
|
||
TimeUnit.MILLISECONDS,
|
||
new LinkedBlockingQueue<>(Math.max(codes.size() * 2, 10)),
|
||
new ThreadPoolExecutor.CallerRunsPolicy()
|
||
);
|
||
try {
|
||
List<CompletableFuture<InventoryInfoVO>> futures = new ArrayList<>(codes.size());
|
||
for (String code : codes) {
|
||
futures.add(CompletableFuture.supplyAsync(() -> queryOne(code), executorService));
|
||
}
|
||
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
|
||
.get(Math.max(30, codes.size() * 10L), TimeUnit.SECONDS);
|
||
|
||
List<InventoryInfoVO> result = new ArrayList<>(codes.size());
|
||
for (CompletableFuture<InventoryInfoVO> future : futures) {
|
||
result.add(future.get());
|
||
}
|
||
return R.ok(result);
|
||
} catch (Exception e) {
|
||
log.error("查询库存信息失败", e);
|
||
return R.fail("查询库存信息失败:" + e.getMessage());
|
||
} finally {
|
||
executorService.shutdown();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 单个物料精确查询(与原先单码接口同一套金蝶条件),供多码并行汇总。
|
||
*/
|
||
private InventoryInfoVO queryOne(String materialCode) {
|
||
try {
|
||
double inventoryQty = Optional.ofNullable(JdUtil.getKuCun(materialCode))
|
||
.map(list -> list.stream().mapToDouble(JDInventoryDTO::getFBaseQty).sum())
|
||
.orElse(0.0);
|
||
double fNoPickedQty = Optional.ofNullable(JdUtil.getWeiLingliao(materialCode))
|
||
.map(list -> list.stream().mapToDouble(JDProductionDTO::getFNoPickedQty).sum())
|
||
.orElse(0.0);
|
||
double productionQty = Optional.ofNullable(JdUtil.getProMoList(materialCode))
|
||
.map(list -> list.stream().mapToDouble(ProMoDTO::getFQty).sum())
|
||
.orElse(0.0);
|
||
double purchaseQty = Optional.ofNullable(JdUtil.getPurchaseOrderList(materialCode))
|
||
.map(list -> list.stream().mapToDouble(PurchaseOrderDTO::getFRemainStockINQty).sum())
|
||
.orElse(0.0);
|
||
double salesOrder = Optional.ofNullable(JdUtil.getSalesOrderList(materialCode))
|
||
.map(list -> list.stream().mapToDouble(SalesOrderDTO::getFBaseRemainOutQty).sum())
|
||
.orElse(0.0);
|
||
double keyong = inventoryQty + productionQty + purchaseQty - fNoPickedQty - salesOrder;
|
||
|
||
InventoryInfoVO vo = new InventoryInfoVO();
|
||
vo.setMaterialCode(materialCode);
|
||
vo.setKucun(String.valueOf(inventoryQty));
|
||
vo.setQuantity(String.valueOf(fNoPickedQty));
|
||
vo.setMaterialName(String.valueOf(purchaseQty));
|
||
vo.setStockName(String.valueOf(productionQty));
|
||
vo.setStockUnit(String.valueOf(keyong));
|
||
vo.setSalesOrder(String.valueOf(salesOrder));
|
||
return vo;
|
||
} catch (Exception e) {
|
||
log.error("查询单个物料库存失败: {}", materialCode, e);
|
||
InventoryInfoVO vo = new InventoryInfoVO();
|
||
vo.setMaterialCode(materialCode);
|
||
vo.setKucun("0.0");
|
||
vo.setQuantity("0.0");
|
||
vo.setMaterialName("0.0");
|
||
vo.setStockName("0.0");
|
||
vo.setStockUnit("0.0");
|
||
vo.setSalesOrder("0.0");
|
||
return vo;
|
||
}
|
||
}
|
||
|
||
private static List<String> parseMaterialCodes(String materialCode, String materialCodes) {
|
||
LinkedHashSet<String> set = new LinkedHashSet<>();
|
||
addCodes(set, materialCodes);
|
||
addCodes(set, materialCode);
|
||
return new ArrayList<>(set);
|
||
}
|
||
|
||
private static void addCodes(Set<String> set, String raw) {
|
||
if (StringUtils.isBlank(raw)) {
|
||
return;
|
||
}
|
||
for (String part : raw.split(",")) {
|
||
if (StringUtils.isNotBlank(part)) {
|
||
set.add(part.trim());
|
||
}
|
||
}
|
||
}
|
||
|
||
@Log(title = "生产计划")
|
||
@PostMapping("/JDList")
|
||
public void synchronize_lists() {
|
||
K3CloudApi client = new K3CloudApi();
|
||
|
||
JsonObject json = new JsonObject();
|
||
json.addProperty("FormId", "PRD_MO");
|
||
json.addProperty("FieldKeys", "FID,F_UCHN_Text,FBillType.FNUMBER,FMaterialId.FNumber,FMaterialName,FQty,FBillType.FNUMBER,FWorkShopID.FNumber,FDate,FProductType,FPickMtrlStatus");
|
||
JsonArray filterString = new JsonArray();
|
||
JsonObject filterObject = new JsonObject();
|
||
filterObject.addProperty("FieldName", "F_UCHN_Text");
|
||
filterObject.addProperty("Compare", "17");
|
||
filterObject.addProperty("Value", "QB");
|
||
filterObject.addProperty("Left", "");
|
||
filterObject.addProperty("Right", "");
|
||
filterObject.addProperty("Logic", 0);
|
||
filterString.add(filterObject);
|
||
json.add("FilterString", filterString);
|
||
json.addProperty("OrderString", "");
|
||
json.addProperty("TopRowCount", 0);
|
||
json.addProperty("StartRow", 0);
|
||
json.addProperty("Limit", 2000);
|
||
json.addProperty("SubSystemId", "");
|
||
|
||
String jsonData = json.toString();
|
||
try {
|
||
String input = String.valueOf(client.executeBillQuery(jsonData));
|
||
input = input.substring(2, input.length() - 2);
|
||
String[] split = input.split("]\\, \\[");
|
||
for (String imProductionn : split) {
|
||
ImProductionPlanBo imProductionPlan = new ImProductionPlanBo();
|
||
String[] imPro = imProductionn.split(",");
|
||
imProductionPlan.setFID(Long.valueOf(imPro[0]));
|
||
imProductionPlan.setProductionCode(imPro[1]);
|
||
imProductionPlan.setTypeName(imPro[2]);
|
||
imProductionPlan.setWorkShop(imPro[7]);
|
||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||
Date parse = simpleDateFormat.parse(imPro[8]);
|
||
imProductionPlan.setDateF(parse);
|
||
imProductionPlan.setUnit(imPro[9]);
|
||
imProductionPlan.setProductTyp(imPro[10]);
|
||
imProductionPlan.setFigureNumber(imPro[3]);
|
||
imProductionPlan.setFigureName(imPro[4]);
|
||
imProductionPlan.setPickmtrlStatus(imPro[10]);
|
||
imProductionPlan.setUpdateTime(new Date());
|
||
imProductionPlan.setSearchValue("1");
|
||
imProductionPlan.setUpdateBy("admin");
|
||
imProductionPlan.setCreateTime(new Date());
|
||
imProductionPlan.setCreateBy("admin");
|
||
imProductionPlanService.insertByBo(imProductionPlan);
|
||
}
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
}
|