evoToK3Cloud/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomVariableController.java
tzy 5a3739b2bc *企业微信推送
*bom Jiaoyan日志
2025-11-05 16:43:57 +08:00

550 lines
27 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.ruoyi.system.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.controller.BaseController;
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.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.JdUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.BomDetails;
import com.ruoyi.system.domain.BomVariable;
import com.ruoyi.system.domain.MaterialProperties;
import com.ruoyi.system.domain.bo.BomVariableBo;
import com.ruoyi.system.domain.vo.BomVariableVo;
import com.ruoyi.system.mapper.BomDetailsMapper;
import com.ruoyi.system.service.IBomVariableService;
import com.ruoyi.system.service.IMaterialPropertiesService;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import static org.aspectj.bridge.MessageUtil.fail;
/**
* bom变量
*
* @author tzy
* @date 2024-04-08
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/variable")
public class BomVariableController extends BaseController {
private final IMaterialPropertiesService iMaterialPropertiesService;
private final IBomVariableService iBomVariableService;
@Resource
private BomDetailsMapper iBomDetailsmapper;
// 错误消息定义为常量
private static final String ERROR_INVALID_PARAMETERS = "参数错误";
private static final String ERROR_MATERIAL_NOT_FOUND = "物料不存在";
private static final String MESSAGE_MATERIAL_FOUND = "物料存在";
private static final Logger log = LoggerFactory.getLogger(BomVariableController.class);
/**
* 查询bom变量列表
*/
@SaCheckPermission("system:variable:list")
@GetMapping("/list")
public TableDataInfo<BomVariableVo> list(BomVariableBo bo, PageQuery pageQuery) {
return iBomVariableService.queryPageList(bo, pageQuery);
}
/**
* 导出bom变量列表
*/
@SaCheckPermission("system:variable:export")
@Log(title = "bom变量", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(BomVariableBo bo, HttpServletResponse response) {
List<BomVariableVo> list = iBomVariableService.queryList(bo);
ExcelUtil.exportExcel(list, "bom变量", BomVariableVo.class, response);
}
/**
* 获取bom变量详细信息
*
* @param id 主键
*/
@SaCheckPermission("system:variable:query")
@GetMapping("/{id}")
public R<BomVariableVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iBomVariableService.queryById(id));
}
/**
* 新增bom变量
*/
@SaCheckPermission("system:variable:add")
@Log(title = "bom变量", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BomVariableBo bo) {
return toAjax(iBomVariableService.insertByBo(bo));
}
/**
* 修改bom变量
*/
@SaCheckPermission("system:variable:edit")
@Log(title = "bom变量", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BomVariableBo bo) {
return toAjax(iBomVariableService.updateByBo(bo));
}
/**
* 删除bom变量
*
* @param ids 主键串
*/
@SaCheckPermission("system:variable:remove")
@Log(title = "bom变量", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iBomVariableService.deleteWithValidByIds(Arrays.asList(ids), true));
}
/**
* 导入数据
*
* @param file 导入文件
*/
@Log(title = "明细导入", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:variable:import")
@PostMapping(value = "/importData/{ids}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importData(@RequestPart("file") MultipartFile file, @PathVariable String ids) throws Exception {
String outputFilePath = null;
// 生成不重复的FNumber集合
Set<String> uniqueFNumbers = new HashSet<>();
String[] split = ids.split(",");
for (String id : split) {
BomVariable bo = iBomVariableService.selectById(Long.parseLong(id));
// 使用try-with-resources确保Workbook资源被正确关闭
log.info("开始处理Excel文件");
try (Workbook detailsSheet = WorkbookFactory.create(file.getInputStream())) {
Sheet sheet = detailsSheet.getSheetAt(0);
List<List<String>> data = new ArrayList<>();
// 遍历每一行
for (Row row : sheet) {
List<String> rowData = new ArrayList<>();
// 遍历当前行的每一列
for (Cell cell : row) {
switch (cell.getCellType()) {
case STRING:
String cellValue = cell.getStringCellValue()
.replace("{V1}", bo.getV1())
.replace("{V2}", bo.getV2())
//.replace("{V22}", bo.getV22())
.replace("{V3}", bo.getV3())
// .replace("{V23}", bo.getV23())
.replace("{V5}", bo.getV5())
.replace("{V6}", bo.getV6())
.replace("{V8}", bo.getV8())
.replace("{G1}", bo.getG1())
.replace("{V9}", bo.getV9())
.replace("{G2}", bo.getG2())
//.replace("{G1}", bo.getG1())
.replace("{V10}", bo.getV10())
.replace("{G5}", bo.getG5())
/* .replace("{G8}", bo.getG8())*/
.replace("{V12}", bo.getV12())
.replace("{G6}", bo.getG6())
.replace("{G7}", bo.getG7())
.replace("{V14}", bo.getV14())
// .replace("{V15}", bo.getV15())
/* .replace("{G9}", bo.getG9())*/
.replace("{V41}", bo.getV41())
.replace("{V42}", bo.getV42())
.replace("{V43}", bo.getV43())
.replace("{V44}", bo.getV44())
.replace("{V45}", bo.getV45())
.replace("{V46}", bo.getV46())
.replace("{V47}", bo.getV47())
.replace("{V48}", bo.getV48())
.replace("{V49}", bo.getV49())
.replace("{V50}", bo.getV50());
//.replace("{V11}", bo.getV11());
//.replace("{V13}", bo.getV13())
//.replace("{V51}", bo.getV51());
rowData.add(cellValue);
break;
case NUMERIC:
rowData.add(String.valueOf(cell.getNumericCellValue()));
break;
default:
break;
}
}
data.add(rowData);
}
// 创建新的Workbook和Sheet
//使用导入文件名和这个拼接 设置生成的文件名称
String originalFilename = file.getOriginalFilename();
if (originalFilename.contains("{V1}")) {
//将v1替换成 bo.getV1()
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String currentTime = dateFormat.format(new Date());
String replace = originalFilename.replace("{V1}", bo.getV1()).replace(".xlsx", "");
outputFilePath = "D:\\30Dbom\\" + replace + currentTime + ".xlsx";
} else {
String newName = originalFilename.replace(".xlsx", "");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String currentTime = dateFormat.format(new Date());
outputFilePath = "D:\\30Dbom\\" + bo.getV1() + "_" + newName + currentTime + ".xlsx";
}
try (Workbook newWorkbook = new XSSFWorkbook();
FileOutputStream outputStream = new FileOutputStream(outputFilePath)) {
Sheet newSheet = newWorkbook.createSheet("New Sheet");
// 将数据写入新的Sheet
int rowNum = 0;
for (List<String> rowData : data) {
Row newRow = newSheet.createRow(rowNum++);
int cellNum = 0;
for (String cellData : rowData) {
Cell newCell = newRow.createCell(cellNum++);
newCell.setCellValue(cellData);
}
}
// 导出数据到新的Excel文件
newWorkbook.write(outputStream);
log.info("数据写入完成新的Excel文件已保存为 {}");
// 获取第一行数据
List<String> firstRow = data.get(2);
if (!firstRow.isEmpty()) {
// 获取父级图号和父级物料名称 标题在第一行
String parentFNumber = firstRow.get(1);
String parentFName =firstRow.get(2);
System.out.println("第一行第一列的值(父级图号): " + parentFNumber);
//跳过第一行
int rowsToSkip = 3;
for (int i = rowsToSkip; i < data.size(); i++) {
List<String> rowData = data.get(i);
BomDetails bomDetails = new BomDetails();
System.out.println("Row Data: " + rowData); // 添加日志输出
// 设置父级图号属性
bomDetails.setFNumber(parentFNumber);
bomDetails.setStats(String.valueOf(rowData.get(rowData.size() - 1)));
uniqueFNumbers.add(parentFNumber);
//设置父级物料名称
bomDetails.setFName(parentFName);
// 检查并转换数量
bomDetails.setPartNumber(rowData.get(1));
bomDetails.setName(rowData.get(2));
String quantityStr = rowData.get(3);
if (!quantityStr.isEmpty()) {
int decimalIndex = quantityStr.indexOf(".");
if (decimalIndex != -1) {
quantityStr = quantityStr.substring(0, decimalIndex);
}
bomDetails.setQuantity(quantityStr);
}
// 检查并转换单重
if (!rowData.get(5).isEmpty()) {
bomDetails.setUnitWeight(rowData.get(5));
}
// 检查并转换总重
/* if (!rowData.get(6).isEmpty()) {
bomDetails.setTotalWeight(rowData.get(6));
}*/
bomDetails.setMaterial(rowData.get(4));
//查询物料是否存在
String materialVerification = isMaterialVerification(rowData.get(1), rowData.get(2));
if (materialVerification.equals("物料存在")) {
bomDetails.setRemarks("物料存在");
} else {
// 获取rowData列表的最后一个元素
String lastElement = rowData.get(rowData.size() - 1);
//调用金蝶保存接口
if (lastElement == null || lastElement.isEmpty() || lastElement.equals("外购")) {
String states = "1";
//调用金蝶物料保存接口
log.info("开始新增不存在的物料==>" + " 物料图号:" + rowData.get(1) + " 物料名称:" + rowData.get(2));
int result = loadMaterialPreservation(rowData.get(1), rowData.get(2), states,rowData.get(4));
if (result == 1) {
log.info("新增物料成功==>" + " 物料图号:" + rowData.get(1) + " 物料名称:" + rowData.get(2));
} else {
log.error("新增物料失败==>" + " 物料图号:" + rowData.get(1) + " 物料名称:" + rowData.get(2));
}
} else if(lastElement.equals("自制") || lastElement.startsWith("009")){
String states = "2";
//调用金蝶物料保存接口
log.info("开始新增不存在的物料==>" + " 物料图号:" + rowData.get(1) + " 物料名称:" + rowData.get(2));
int result = loadMaterialPreservation(rowData.get(1), rowData.get(2), states,rowData.get(4));
if (result == 1) {
log.info("新增物料成功==>" + " 物料图号:" + rowData.get(1) + " 物料名称:" + rowData.get(2));
} else {
log.error("新增物料失败==>" + " 物料图号:" + rowData.get(1) + " 物料名称:" + rowData.get(2));
}
}else if(lastElement == null || lastElement.isEmpty() || lastElement.equals("委外")){
String states = "3";
//调用金蝶物料保存接口
log.info("开始新增不存在的物料==>" + " 物料图号:" + rowData.get(1) + " 物料名称:" + rowData.get(2));
int result = loadMaterialPreservation(rowData.get(1), rowData.get(2), states,rowData.get(4));
if (result == 1) {
log.info("新增物料成功==>" + " 物料图号:" + rowData.get(1) + " 物料名称:" + rowData.get(2));
} else {
log.error("新增物料失败==>" + " 物料图号:" + rowData.get(1) + " 物料名称:" + rowData.get(2));
}
}
bomDetails.setRemarks("物料已添加");
}
int insert = iBomDetailsmapper.insert(bomDetails);
if (insert == 0) {
log.error("插入明细数据失败");
} else {
log.info("插入明细数据成功");
}
}
} else {
log.error("数据集合为空或第一行数据为空");
}
}
} catch (Exception e) {
log.error("写入新的Excel文件时发生错误: {}", e);
return R.fail("处理Excel文件时发生错误");
}
}
// 将不重复的FNumber集合转换为JSON数组并打印出来
ObjectMapper objectMapper = new ObjectMapper();
String jsonOutput = objectMapper.writeValueAsString(uniqueFNumbers);
log.info("不重复的FNumbers:=====================================》 " + jsonOutput);
return R.ok("文件输出路径为:" + outputFilePath);
}
/**
* 物料验证
* 验证物料在金蝶中是否存在
*/
public String isMaterialVerification(String drawingNumber, String name) {
if (Objects.isNull(drawingNumber) || drawingNumber.isEmpty() || Objects.isNull(name) || name.isEmpty()) {
return ERROR_INVALID_PARAMETERS;
}
JsonArray jsonArray;
try {
jsonArray = JdUtils.loadMaterialQuery(drawingNumber, name);
} catch (Exception e) {
log.error("查询物料信息时发生异常", e);
return "查询物料信息时发生异常"; // 捕获异常并返回通用错误消息,具体实现中可进一步细化异常处理
}
if (Objects.isNull(jsonArray)) {
return ERROR_MATERIAL_NOT_FOUND;
} else {
for (JsonElement jsonElement : jsonArray) {
if (jsonElement.isJsonObject()) {
JsonObject jsonObject = jsonElement.getAsJsonObject();
String FNumber = getSafeString(jsonObject, "FNumber");
String FName = getSafeString(jsonObject, "FName");
if (FNumber != null && FName != null) {
log.info("图号为: " + FNumber);
log.info("物料为: " + FName);
}
}
}
return MESSAGE_MATERIAL_FOUND;
}
}
// 安全获取JSON字符串字段值
private String getSafeString(JsonObject jsonObject, String key) {
if (jsonObject.has(key) && !jsonObject.get(key).isJsonNull()) {
return jsonObject.get(key).getAsString();
}
return null;
}
/* 获取生成的明细中的bom 明细在前端勾选上对应的父级物料图号
* 得到对应的集合
* */
public int loadMaterialPreservation(String partNumber, String name, String states,String cailiao) {
K3CloudApi client = new K3CloudApi();
// 创建一个空的JsonObject
JsonObject json = new JsonObject();
// 添加IsAutoSubmitAndAudit字段
json.addProperty("IsAutoSubmitAndAudit", "true");
// 创建Model对象并加入JsonObject
JsonObject model = new JsonObject();
json.add("Model", model);
// 添加Model字段
model.addProperty("FMATERIALID", 0);
model.addProperty("FNumber", partNumber);
model.addProperty("FName", name);
// 创建FMaterialGroup对象并加入Model
JsonObject fMaterialGroup = new JsonObject();
fMaterialGroup.addProperty("FNumber", "A000106");
model.add("FMaterialGroup", fMaterialGroup);
model.addProperty("FIsHandleReserve", true);
// 创建SubHeadEntity对象并加入Model
JsonObject subHeadEntity = new JsonObject();
model.add("SubHeadEntity", subHeadEntity);
subHeadEntity.addProperty("FErpClsID", states);
subHeadEntity.addProperty("FFeatureItem", "1");
MaterialProperties materialProperties = iMaterialPropertiesService.selectByAttribute(cailiao);
if (materialProperties!=null){
JsonObject FSVRIAssistant = new JsonObject();
FSVRIAssistant.addProperty("FNumber", materialProperties.getMaterialAttributeId());
model.add("F_SVRI_Assistant",FSVRIAssistant);
}
// 创建FCategoryID对象并加入SubHeadEntity
JsonObject fCategoryID = new JsonObject();
fCategoryID.addProperty("FNumber", "007");
subHeadEntity.add("FCategoryID", fCategoryID);
// 创建FTaxRateId对象并加入SubHeadEntity
JsonObject fTaxRateId = new JsonObject();
fTaxRateId.addProperty("FNUMBER", "SL02_SYS");
subHeadEntity.add("FTaxRateId", fTaxRateId);
// 创建FBaseUnitId对象并加入SubHeadEntity
JsonObject fBaseUnitId = new JsonObject();
fBaseUnitId.addProperty("FNumber", "jian");
subHeadEntity.add("FBaseUnitId", fBaseUnitId);
subHeadEntity.addProperty("FIsPurchase", true);
subHeadEntity.addProperty("FIsInventory", true);
subHeadEntity.addProperty("FIsSubContract", true);
subHeadEntity.addProperty("FIsSale", true);
subHeadEntity.addProperty("FIsProduce", true);
// 创建SubHeadEntity1对象并加入Model
JsonObject subHeadEntity1 = new JsonObject();
model.add("SubHeadEntity1", subHeadEntity1);
JsonObject fStoreUnitId = new JsonObject();
fStoreUnitId.addProperty("FNumber", "jian");
subHeadEntity1.add("FStoreUnitID", fStoreUnitId);
subHeadEntity1.addProperty("FUnitConvertDir", "1");
// 创建FStockId对象并加入SubHeadEntity1
//仓库代码为 半成品库007
JsonObject fStockId = new JsonObject();
fStockId.addProperty("FNumber", "007");
subHeadEntity1.add("FStockId", fStockId);
// 创建FCurrencyId对象并加入SubHeadEntity1
JsonObject fCurrencyId = new JsonObject();
fCurrencyId.addProperty("FNumber", "PRE001");
subHeadEntity1.add("FCurrencyId", fCurrencyId);
subHeadEntity1.addProperty("FIsSNPRDTracy", false);
subHeadEntity1.addProperty("FSNManageType", "1");
subHeadEntity1.addProperty("FSNGenerateTime", "1");
subHeadEntity1.addProperty("FBoxStandardQty", 0.0);
// 创建FPurchaseUnitId对象并加入SubHeadEntity1
JsonObject fPurchaseUnitId = new JsonObject();
fPurchaseUnitId.addProperty("FNumber", "jian");
subHeadEntity1.add("FPurchaseUnitId", fPurchaseUnitId);
// 创建SubHeadEntity3对象并加入Model
JsonObject subHeadEntity3 = new JsonObject();
model.add("SubHeadEntity3", subHeadEntity3);
// 创建FPurchasePriceUnitId对象并加入SubHeadEntity3
JsonObject fPurchasePriceUnitId = new JsonObject();
fPurchasePriceUnitId.addProperty("FNumber", "jian");
subHeadEntity3.add("FPurchasePriceUnitId", fPurchasePriceUnitId);
subHeadEntity3.addProperty("FIsQuota", false);
subHeadEntity3.addProperty("FQuotaType", "1");
JsonObject subHeadEntity6 = new JsonObject();
model.add("SubHeadEntity6", subHeadEntity6);
subHeadEntity6.addProperty("FCheckProduct", true);
subHeadEntity6.addProperty("FCheckReturn", true);
// 创建SubHeadEntity5对象并加入Model
JsonObject subHeadEntity5 = new JsonObject();
model.add("SubHeadEntity5", subHeadEntity5);
// 创建FProduceUnitId对象并加入SubHeadEntity5
JsonObject fProduceUnitId = new JsonObject();
fProduceUnitId.addProperty("FNumber", "jian");
subHeadEntity5.add("FProduceUnitId", fProduceUnitId);
// 创建FProduceBillType对象并加入SubHeadEntity5
JsonObject fProduceBillType = new JsonObject();
fProduceBillType.addProperty("FNUMBER", "SCDD01_SYS");
subHeadEntity5.add("FProduceBillType", fProduceBillType);
// 创建FBOMUnitId对象并加入SubHeadEntity5
JsonObject fBOMUnitId = new JsonObject();
fBOMUnitId.addProperty("FNumber", "jian");
subHeadEntity5.add("FBOMUnitId", fBOMUnitId);
subHeadEntity5.addProperty("FIsMainPrd", true);
subHeadEntity5.addProperty("FIssueType", "1");
// 创建FPickStockId对象并加入SubHeadEntity5
JsonObject fPickStockId = new JsonObject();
fPickStockId.addProperty("FNumber", "CK010");
subHeadEntity1.add("FPickStockId", fPickStockId);
subHeadEntity5.addProperty("FOverControlMode", "1");
subHeadEntity5.addProperty("FStandHourUnitId", "3600");
subHeadEntity5.addProperty("FBackFlushType", "1");
String jsonData = json.toString();
System.out.println(jsonData);
try {
//业务对象标识
String formId = "BD_MATERIAL";
//调用接口
String resultJson = client.save(formId, jsonData);
//用于记录结果
Gson gson = new Gson();
//对返回结果进行解析和校验
RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
if (repoRet.getResult().getResponseStatus().isIsSuccess()) {
System.out.printf("接口返回结果: %s%n", gson.toJson(repoRet.getResult()));
log.info("接口返回结果: %s%n" + gson.toJson(repoRet.getResult()));
return 1;
} else {
fail("接口返回结果: " + gson.toJson(repoRet.getResult().getResponseStatus()));
log.error("接口返回结果: 失败 " + gson.toJson(repoRet.getResult().getResponseStatus()));
return 0;
}
} catch (Exception e) {
fail(e.getMessage());
}
return 1;
}
}