Browse Source

2026-01-21

收货入库任务通知页面的入库明细页签,在行操作上加一个【标签导入】
master
fengyuan_yang 1 month ago
parent
commit
1f5a01fb85
  1. 232
      src/main/java/com/gaotao/modules/inboundNotification/controller/InboundNotificationController.java
  2. 17
      src/main/java/com/gaotao/modules/inboundNotification/dao/InboundNotificationHeadMapper.java
  3. 10
      src/main/java/com/gaotao/modules/inboundNotification/service/InboundNotificationService.java
  4. 42
      src/main/java/com/gaotao/modules/inboundNotification/service/impl/InboundNotificationServiceImpl.java
  5. 30
      src/main/resources/mapper/inboundNotification/InboundNotificationHeadMapper.xml

232
src/main/java/com/gaotao/modules/inboundNotification/controller/InboundNotificationController.java

@ -7,9 +7,24 @@ import com.gaotao.modules.inboundNotification.entity.vo.InboundNotificationHeadV
import com.gaotao.modules.inboundNotification.service.InboundNotificationService;
import com.gaotao.modules.sys.controller.AbstractController;
import com.gaotao.modules.trans.entity.TransDetailSub;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -431,6 +446,223 @@ public class InboundNotificationController extends AbstractController {
return R.ok().put("rows", list);
}
/**
* 标签导入
* 将Excel数据插入临时表然后调用存储过程处理
*/
@PostMapping("/labelImport")
public R labelImport(@RequestParam("file") MultipartFile file,
@RequestParam("site") String site,
@RequestParam("buNo") String buNo,
@RequestParam("orderNo") String orderNo,
@RequestParam("orderType") String orderType,
@RequestParam("orderStatus") String orderStatus,
@RequestParam("relatedOrderNo") String relatedOrderNo,
@RequestParam("relatedOrderLineNo") String relatedOrderLineNo,
@RequestParam("partNo") String partNo) {
try {
if (file.isEmpty()) {
return R.error("请选择文件上传");
}
// 检查文件格式
String fileName = file.getOriginalFilename();
if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) {
return R.error("请上传xlsx或xls格式的文件");
}
// 解析Excel文件
List<Map<String, Object>> dataList = new ArrayList<>();
try (InputStream inputStream = file.getInputStream();
Workbook workbook = WorkbookFactory.create(inputStream)) {
Sheet sheet = workbook.getSheetAt(0);
int lastRowNum = sheet.getLastRowNum();
// 从第二行开始读取数据第一行是表头
for (int i = 1; i <= lastRowNum; i++) {
Row row = sheet.getRow(i);
if (row == null) continue;
Map<String, Object> rowData = new HashMap<>();
rowData.put("site", site);
rowData.put("buNo", buNo);
rowData.put("orderNo", orderNo);
rowData.put("orderType", orderType);
rowData.put("relatedOrderNo", relatedOrderNo);
rowData.put("relatedOrderLineNo", relatedOrderLineNo);
rowData.put("partNo", partNo);
// 标签号第一列
Cell rollNoCell = row.getCell(0);
String rollNo = getCellValueAsString(rollNoCell);
if (rollNo == null || rollNo.trim().isEmpty()) {
continue; // 跳过空行
}
rowData.put("rollNo", rollNo.trim());
// 批次号第二列
Cell batchNoCell = row.getCell(1);
String batchNo = getCellValueAsString(batchNoCell);
rowData.put("batchNo", batchNo != null ? batchNo.trim() : "");
// 数量第三列
Cell rollQtyCell = row.getCell(2);
BigDecimal rollQty = getCellValueAsDecimal(rollQtyCell);
rowData.put("rollQty", rollQty);
dataList.add(rowData);
}
}
if (dataList.isEmpty()) {
return R.error("Excel文件中没有有效数据");
}
// 调用Service处理导入
String result = inboundNotificationService.labelImport(site, buNo, orderNo, dataList);
if ("200".equals(result)) {
return R.ok("导入成功,共导入 " + dataList.size() + " 条数据");
} else {
return R.error("导入失败:" + result);
}
} catch (Exception e) {
logger.error("标签导入失败", e);
return R.error("导入失败: " + e.getMessage());
}
}
/**
* 下载标签导入模板
*/
@GetMapping("/downloadLabelTemplate")
public ResponseEntity<byte[]> downloadLabelTemplate() {
try {
// 创建Excel工作簿
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("标签导入模板");
// // 创建表头样式
// CellStyle headerStyle = workbook.createCellStyle();
// headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
// headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
// Font headerFont = workbook.createFont();
// headerFont.setBold(true);
// headerStyle.setFont(headerFont);
// headerStyle.setAlignment(HorizontalAlignment.CENTER);
// 创建表头样式
CellStyle headerStyle = workbook.createCellStyle();
XSSFColor headerColor = new XSSFColor(new byte[]{(byte) 0x17, (byte) 0xb3, (byte) 0xa3}, null);
if (headerStyle instanceof XSSFCellStyle) {
((XSSFCellStyle) headerStyle).setFillForegroundColor(headerColor);
} else {
// 对于HSSFCellStyle只能使用IndexedColors中的颜色
headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
}
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerStyle.setFont(headerFont);
headerStyle.setAlignment(HorizontalAlignment.CENTER);
// 创建表头行
Row headerRow = sheet.createRow(0);
String[] headers = {"标签号", "批次号", "数量"};
for (int i = 0; i < headers.length; i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(headers[i]);
cell.setCellStyle(headerStyle);
}
// 设置列宽
sheet.setColumnWidth(0, 30 * 256); // 标签号
sheet.setColumnWidth(1, 20 * 256); // 批次号
sheet.setColumnWidth(2, 15 * 256); // 数量
// 添加示例数据可选
// Row exampleRow = sheet.createRow(1);
// exampleRow.createCell(0).setCellValue("ROLL001");
// exampleRow.createCell(1).setCellValue("BATCH001");
// exampleRow.createCell(2).setCellValue(100);
// 将工作簿写入字节数组
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
workbook.close();
byte[] bytes = outputStream.toByteArray();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
httpHeaders.setContentDispositionFormData("attachment", "label_import_template.xlsx");
return ResponseEntity.ok()
.headers(httpHeaders)
.body(bytes);
} catch (Exception e) {
logger.error("下载模板失败", e);
return ResponseEntity.badRequest().body(null);
}
}
/**
* 获取单元格字符串值
*/
private String getCellValueAsString(Cell cell) {
if (cell == null) return null;
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
return cell.getDateCellValue().toString();
} else {
// 避免科学计数法
double value = cell.getNumericCellValue();
if (value == Math.floor(value)) {
return String.valueOf((long) value);
}
return String.valueOf(value);
}
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
case FORMULA:
try {
return cell.getStringCellValue();
} catch (Exception e) {
return String.valueOf(cell.getNumericCellValue());
}
default:
return null;
}
}
/**
* 获取单元格数值
*/
private BigDecimal getCellValueAsDecimal(Cell cell) {
if (cell == null) return BigDecimal.ZERO;
switch (cell.getCellType()) {
case NUMERIC:
return BigDecimal.valueOf(cell.getNumericCellValue());
case STRING:
try {
return new BigDecimal(cell.getStringCellValue().trim());
} catch (NumberFormatException e) {
return BigDecimal.ZERO;
}
default:
return BigDecimal.ZERO;
}
}
}

17
src/main/java/com/gaotao/modules/inboundNotification/dao/InboundNotificationHeadMapper.java

@ -122,4 +122,21 @@ public interface InboundNotificationHeadMapper extends BaseMapper<InboundNotific
* 查询部门列表
*/
List<Map<String, Object>> getDepartmentList();
/**
* 删除标签导入临时表数据
*/
void deleteLabelImportTemp(@Param("site") String site,
@Param("buNo") String buNo,
@Param("orderNo") String orderNo);
/**
* 插入标签导入临时表数据
*/
void insertLabelImportTemp(Map<String, Object> data);
/**
* 调用存储过程 UspImportRoll
*/
void callUspImportRoll(Map<String, Object> params);
}

10
src/main/java/com/gaotao/modules/inboundNotification/service/InboundNotificationService.java

@ -129,4 +129,14 @@ public interface InboundNotificationService {
* @return 部门列表
*/
List<Map<String, Object>> getDepartmentList();
/**
* 标签导入
* @param site 站点
* @param buNo 业务单元
* @param orderNo 单据号
* @param dataList 导入的数据列表
* @return 处理结果 "200"成功 "400"失败
*/
String labelImport(String site, String buNo, String orderNo, List<Map<String, Object>> dataList);
}

42
src/main/java/com/gaotao/modules/inboundNotification/service/impl/InboundNotificationServiceImpl.java

@ -840,4 +840,46 @@ public class InboundNotificationServiceImpl implements InboundNotificationServic
return headMapper.getDepartmentList();
}
/**
* 标签导入
* 1. 清空临时表中该单据的数据
* 2. 插入新的数据到临时表
* 3. 调用存储过程处理
*/
@Override
@Transactional
public String labelImport(String site, String buNo, String orderNo, List<Map<String, Object>> dataList) {
try {
// 1. 清空临时表中该单据的数据
headMapper.deleteLabelImportTemp(site, buNo, orderNo);
// 2. 批量插入数据到临时表
for (Map<String, Object> data : dataList) {
headMapper.insertLabelImportTemp(data);
}
// 3. 调用存储过程 UspImportRoll
Map<String, Object> params = new HashMap<>();
params.put("site", site);
params.put("buNo", buNo);
params.put("orderNo", orderNo);
headMapper.callUspImportRoll(params);
// 获取存储过程返回的结果
String resultCode = params.get("resultCode") != null ? params.get("resultCode").toString() : "400";
String resultMsg = params.get("resultMsg") != null ? params.get("resultMsg").toString() : "";
if ("200".equals(resultCode)) {
return "200";
} else {
return resultMsg != null && !resultMsg.isEmpty() ? resultMsg : "400";
}
} catch (Exception e) {
logger.error("标签导入失败", e);
throw new RuntimeException("标签导入失败: " + e.getMessage());
}
}
}

30
src/main/resources/mapper/inboundNotification/InboundNotificationHeadMapper.xml

@ -262,4 +262,34 @@
SELECT department_no AS departmentNo, department_desc AS departmentDesc
FROM erp_department
</select>
<!-- 删除标签导入临时表数据 -->
<delete id="deleteLabelImportTemp">
DELETE FROM label_import_temp
WHERE site = #{site}
AND bu_no = #{buNo}
AND order_no = #{orderNo}
</delete>
<!-- 插入标签导入临时表数据 -->
<insert id="insertLabelImportTemp">
INSERT INTO label_import_temp (
site, bu_no, order_no, order_type, related_order_no,
related_order_line_no, part_no, roll_no, batch_no, roll_qty
) VALUES (
#{site}, #{buNo}, #{orderNo}, #{orderType}, #{relatedOrderNo},
#{relatedOrderLineNo}, #{partNo}, #{rollNo}, #{batchNo}, #{rollQty}
)
</insert>
<!-- 调用存储过程 UspImportRoll -->
<select id="callUspImportRoll" statementType="CALLABLE" parameterType="java.util.Map">
{call UspImportRoll(
#{site, mode=IN, jdbcType=VARCHAR},
#{buNo, mode=IN, jdbcType=VARCHAR},
#{orderNo, mode=IN, jdbcType=VARCHAR},
#{resultCode, mode=OUT, jdbcType=VARCHAR},
#{resultMsg, mode=OUT, jdbcType=VARCHAR}
)}
</select>
</mapper>
Loading…
Cancel
Save