免检物料类别的功能开发;免检物料添加一个导入和导出的功能

This commit is contained in:
zhangke 2026-05-08 16:45:50 +08:00
parent 218558aef3
commit 03ed1f1068
17 changed files with 1493 additions and 21 deletions

View File

@ -0,0 +1,370 @@
package com.nflg.qms.admin.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nflg.wms.common.constant.STATE;
import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.dto.QmsExemptCategoryExportDTO;
import com.nflg.wms.common.pojo.dto.QmsExemptCategoryImportDTO;
import com.nflg.wms.common.pojo.qo.*;
import com.nflg.wms.common.pojo.vo.QmsExemptCategoryVO;
import com.nflg.wms.common.pojo.vo.QmsQcMaterialCategoryVO;
import com.nflg.wms.common.util.DateTimeUtil;
import com.nflg.wms.common.util.EecExcelUtil;
import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.common.util.VUtil;
import com.nflg.wms.repository.entity.QmsExemptCategory;
import com.nflg.wms.repository.entity.UserSupplier;
import com.nflg.wms.repository.service.IQmsExemptCategoryService;
import com.nflg.wms.repository.service.IQmsQcMaterialCategoryService;
import com.nflg.wms.repository.service.IUserSupplierService;
import com.nflg.wms.starter.BaseController;
import com.nflg.wms.starter.service.FileUploadService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.ttzero.excel.entity.ListSheet;
import org.ttzero.excel.entity.Workbook;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
/**
* 免检物料类别管理
*/
@RestController
@RequestMapping("/exemptCategory")
public class QmsExemptCategoryController extends BaseController {
@Resource
private IQmsExemptCategoryService exemptCategoryService;
@Resource
private IUserSupplierService userSupplierService;
@Resource
private IQmsQcMaterialCategoryService qcMaterialCategoryService;
@Resource
private FileUploadService fileUploadService;
private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 分页查询免检物料类别列表
*/
@PostMapping("search")
public ApiResult<PageData<QmsExemptCategoryVO>> search(@RequestBody QmsExemptCategorySearchQO request) {
return ApiResult.success(exemptCategoryService.search(request));
}
/**
* 保存免检物料类别新增/编辑
*/
@PostMapping("save")
public ApiResult<Void> save(@RequestBody QmsExemptCategorySaveQO request) {
exemptCategoryService.saveExemptCategory(request);
return ApiResult.success();
}
/**
* 按供应商ID查询免检物料类别明细
*/
@PostMapping("detailBySupplier")
public ApiResult<List<QmsExemptCategoryVO>> detailBySupplier(@RequestBody QmsExemptMaterialDetailBySupplierQO request) {
return ApiResult.success(exemptCategoryService.detailBySupplier(request.getSupplierId()));
}
/**
* 按物料类别编码查询免检明细
*/
@PostMapping("detailByCategory")
public ApiResult<List<QmsExemptCategoryVO>> detailByCategory(@RequestBody QmsExemptCategoryDetailByCategoryQO request) {
return ApiResult.success(exemptCategoryService.detailByCategory(request.getCategoryCode()));
}
/**
* 分页搜索供应商列表供选择弹窗使用
*/
@PostMapping("supplierList")
public ApiResult<PageData<UserSupplier>> supplierList(@RequestBody SupplierListSelectQO request) {
LambdaQueryWrapper<UserSupplier> wrapper = new LambdaQueryWrapper<>();
if (request.getKeyword() != null && !request.getKeyword().isEmpty()) {
wrapper.and(w -> w.like(UserSupplier::getSupplierCode, request.getKeyword())
.or().like(UserSupplier::getSupplierName, request.getKeyword()));
}
wrapper.orderByDesc(UserSupplier::getCreateTime);
IPage<UserSupplier> result = userSupplierService.page(new Page<>(request.getPage(), request.getPageSize()), wrapper);
return ApiResult.success(result);
}
/**
* 获取物料类别树列表
*/
@PostMapping("categoryList")
public ApiResult<List<QmsQcMaterialCategoryVO>> categoryList(@RequestBody(required = false) QmsQcMaterialCategorySearchQO request) {
if (request == null) {
request = new QmsQcMaterialCategorySearchQO();
}
return ApiResult.success(qcMaterialCategoryService.searchTree(request));
}
/**
* 启用/禁用切换
*/
@PostMapping("toggleEnable")
public ApiResult<Void> toggleEnable(@RequestBody ToggleEnableQO request) {
exemptCategoryService.toggleEnable(request.getId(), request.getEnable());
return ApiResult.success();
}
/**
* 审核免检物料类别
*/
@PostMapping("audit")
public ApiResult<Void> audit(@RequestBody QmsExemptMaterialAuditQO request) {
exemptCategoryService.audit(request);
return ApiResult.success();
}
/**
* 删除免检物料类别
*/
@PostMapping("delete")
public ApiResult<Void> delete(@RequestBody @NotNull List<Long> ids) {
boolean hasAudited = exemptCategoryService.listByIds(ids).stream()
.anyMatch(m -> m.getAuditStatus() != null && m.getAuditStatus() == 1);
VUtil.trueThrowBusinessError(hasAudited).throwMessage("此数据已审核,不能删除");
exemptCategoryService.removeByIds(ids);
return ApiResult.success();
}
/**
* 导出免检物料类别
*/
@PostMapping("export")
public void export(@RequestBody QmsExemptCategorySearchQO request, HttpServletResponse response) throws IOException {
// 不分页查询有ids时按ids导出否则按搜索条件导出全部
request.setPage(1);
request.setPageSize(Integer.MAX_VALUE);
IPage<QmsExemptCategoryVO> page = exemptCategoryService.search(request);
List<QmsExemptCategoryVO> list = page.getRecords();
// 转换为导出DTO
List<QmsExemptCategoryExportDTO> exportList = new ArrayList<>();
for (QmsExemptCategoryVO vo : list) {
QmsExemptCategoryExportDTO dto = new QmsExemptCategoryExportDTO();
dto.setSupplierCode(vo.getSupplierCode());
dto.setSupplierName(vo.getSupplierName());
dto.setCategoryCode(vo.getCategoryCode());
dto.setCategoryFullName(vo.getCategoryFullName());
dto.setAuditStatusText(vo.getAuditStatus() == null ? "" :
vo.getAuditStatus() == 0 ? "待审核" :
vo.getAuditStatus() == 1 ? "已审核" : "已驳回");
dto.setExemptModeText(vo.getExemptMode() == null ? "" :
vo.getExemptMode() == 0 ? "永久" : "周期");
dto.setValidStartDate(vo.getValidStartDate() != null ? vo.getValidStartDate().format(DATE_FMT).substring(0, 10) : "");
dto.setValidEndDate(vo.getValidEndDate() != null ? vo.getValidEndDate().format(DATE_FMT).substring(0, 10) : "");
dto.setValidStatusText(vo.getValidStatus() != null && vo.getValidStatus() == 1 ? "有效中" : "已过期");
dto.setAuditorName(vo.getAuditorName());
dto.setAuditTime(vo.getAuditTime() != null ? vo.getAuditTime().format(DATE_FMT) : "");
dto.setCreateByName(vo.getCreateByName());
dto.setCreateTime(vo.getCreateTime() != null ? vo.getCreateTime().format(DATE_FMT) : "");
dto.setUpdateByName(vo.getUpdateByName());
dto.setUpdateTime(vo.getUpdateTime() != null ? vo.getUpdateTime().format(DATE_FMT) : "");
exportList.add(dto);
}
EecExcelUtil.export("免检物料类别", "免检物料类别", exportList, response);
}
/**
* 下载导入模板
*/
@PostMapping("template")
public void template(HttpServletResponse response) throws IOException {
QmsExemptCategoryImportDTO example = new QmsExemptCategoryImportDTO()
.setSupplierCode("示例供应商编码")
.setSupplierName("示例供应商名称(非必填)")
.setCategoryCode("示例物料类别编码")
.setCategoryName("示例物料类别名称(非必填)")
.setExemptMode("永久")
.setValidStartDate("2026-01-01")
.setValidEndDate("2026-12-31");
EecExcelUtil.export("免检物料类别导入模板", "免检物料类别导入模板", List.of(example), response);
}
/**
* 导入免检物料类别
*/
@PostMapping("import")
public ApiResult<?> importExcel(MultipartFile file) throws IOException {
List<QmsExemptCategoryImportDTO> data = EecExcelUtil.getExcelContext(file.getInputStream(), QmsExemptCategoryImportDTO.class);
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(data)).throwMessage("导入文件内容为空");
if (!checkAndImport(data)) {
try (ByteArrayOutputStream osOut = new ByteArrayOutputStream()) {
new Workbook()
.addSheet(new ListSheet<>(data))
.writeTo(osOut);
try (ByteArrayInputStream isIn = new ByteArrayInputStream(osOut.toByteArray())) {
return ApiResult.error(STATE.DataNoCheckPass, "导入文件失败",
fileUploadService.upload("temp/" + DateTimeUtil.format(LocalDate.now(), "yyyyMMdd") + "/" + IdUtil.fastUUID() + ".xlsx", isIn, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
}
} catch (Exception e) {
return ApiResult.error(STATE.BusinessError, "保存文件出错");
}
}
return ApiResult.success();
}
/**
* 校验并导入数据
*/
private boolean checkAndImport(List<QmsExemptCategoryImportDTO> data) {
Long userId = UserUtil.getUserId();
String userName = UserUtil.getUserName();
LocalDateTime now = LocalDateTime.now();
boolean allSuccess = true;
List<QmsExemptCategory> toSave = new ArrayList<>();
for (QmsExemptCategoryImportDTO dto : data) {
StringBuilder sb = new StringBuilder();
// 校验必填字段
if (StrUtil.isBlank(dto.getSupplierCode())) {
sb.append("供应商编码不能为空;");
}
if (StrUtil.isBlank(dto.getCategoryCode())) {
sb.append("物料类别编码不能为空;");
}
if (StrUtil.isBlank(dto.getExemptMode())) {
sb.append("免检模式不能为空;");
}
if (!sb.isEmpty()) {
dto.setError(sb.toString());
allSuccess = false;
continue;
}
// 验证供应商是否存在
LambdaQueryWrapper<UserSupplier> supplierWrapper = new LambdaQueryWrapper<>();
supplierWrapper.eq(UserSupplier::getSupplierCode, dto.getSupplierCode());
UserSupplier supplier = userSupplierService.getOne(supplierWrapper, false);
if (supplier == null) {
dto.setError("供应商编码不存在");
allSuccess = false;
continue;
}
// 验证免检模式
Integer exemptMode;
if ("永久".equals(dto.getExemptMode())) {
exemptMode = 0;
} else if ("周期".equals(dto.getExemptMode())) {
exemptMode = 1;
} else {
dto.setError("免检模式只能为'永久'或'周期'");
allSuccess = false;
continue;
}
// 周期模式时有效开始时间和有效结束时间必填
if (exemptMode == 1) {
if (StrUtil.isBlank(dto.getValidStartDate())) {
sb.append("周期模式下有效开始日期不能为空;");
}
if (StrUtil.isBlank(dto.getValidEndDate())) {
sb.append("周期模式下有效结束日期不能为空;");
}
if (!sb.isEmpty()) {
dto.setError(sb.toString());
allSuccess = false;
continue;
}
}
// 唯一性校验供应商编号+物料类别编号
LambdaQueryWrapper<QmsExemptCategory> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(QmsExemptCategory::getCategoryCode, dto.getCategoryCode())
.eq(QmsExemptCategory::getSupplierId, supplier.getId());
long count = exemptCategoryService.count(wrapper);
if (count > 0) {
dto.setError("该供应商与物料类别的免检记录已存在");
allSuccess = false;
continue;
}
// 构造实体
QmsExemptCategory entity = new QmsExemptCategory();
entity.setSupplierId(supplier.getId());
entity.setCategoryCode(dto.getCategoryCode());
entity.setExemptMode(exemptMode);
entity.setAuditStatus(0);
entity.setEnable(true);
entity.setCreateBy(userId);
entity.setCreateByName(userName);
entity.setCreateTime(now);
entity.setUpdateBy(userId);
entity.setUpdateByName(userName);
entity.setUpdateTime(now);
if (StrUtil.isNotBlank(dto.getValidStartDate())) {
entity.setValidStartDate(parseDate(dto.getValidStartDate()));
}
if (StrUtil.isNotBlank(dto.getValidEndDate())) {
entity.setValidEndDate(parseDate(dto.getValidEndDate()));
}
toSave.add(entity);
}
if (allSuccess && !toSave.isEmpty()) {
exemptCategoryService.saveBatch(toSave);
}
return allSuccess;
}
private LocalDateTime parseDate(String dateStr) {
if (dateStr == null || dateStr.trim().isEmpty()) {
return null;
}
dateStr = dateStr.trim();
// 处理Excel日期序列号纯数字
if (dateStr.matches("\\d+")) {
long serial = Long.parseLong(dateStr);
LocalDate date = LocalDate.of(1900, 1, 1).plusDays(serial - 2);
return date.atStartOfDay();
}
// 处理带小数的Excel日期序列号如46149.0
if (dateStr.matches("\\d+\\.\\d+")) {
long serial = (long) Double.parseDouble(dateStr);
LocalDate date = LocalDate.of(1900, 1, 1).plusDays(serial - 2);
return date.atStartOfDay();
}
if (dateStr.length() == 10) {
dateStr = dateStr + " 00:00:00";
}
return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
}

View File

@ -1,12 +1,21 @@
package com.nflg.qms.admin.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nflg.wms.common.constant.STATE;
import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.dto.QmsExemptMaterialExportDTO;
import com.nflg.wms.common.pojo.dto.QmsExemptMaterialImportDTO;
import com.nflg.wms.common.pojo.qo.*;
import com.nflg.wms.common.pojo.vo.QmsExemptMaterialVO;
import com.nflg.wms.common.util.DateTimeUtil;
import com.nflg.wms.common.util.EecExcelUtil;
import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.common.util.VUtil;
import com.nflg.wms.repository.entity.QmsExemptMaterial;
import com.nflg.wms.repository.entity.QmsQcMaterial;
@ -15,14 +24,26 @@ import com.nflg.wms.repository.service.IQmsExemptMaterialService;
import com.nflg.wms.repository.service.IQmsQcMaterialService;
import com.nflg.wms.repository.service.IUserSupplierService;
import com.nflg.wms.starter.BaseController;
import com.nflg.wms.starter.service.FileUploadService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.ttzero.excel.entity.ListSheet;
import org.ttzero.excel.entity.Workbook;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -42,6 +63,11 @@ public class QmsExemptMaterialController extends BaseController {
@Resource
private IQmsQcMaterialService qcMaterialService;
@Resource
private FileUploadService fileUploadService;
private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 分页查询免检物料列表
*/
@ -135,4 +161,217 @@ public class QmsExemptMaterialController extends BaseController {
exemptMaterialService.removeByIds(ids);
return ApiResult.success();
}
/**
* 导出免检物料
*/
@PostMapping("export")
public void export(@RequestBody QmsExemptMaterialSearchQO request, HttpServletResponse response) throws IOException {
// 不分页查询有ids时按ids导出否则按搜索条件导出全部
request.setPage(1);
request.setPageSize(Integer.MAX_VALUE);
IPage<QmsExemptMaterialVO> page = exemptMaterialService.search(request);
List<QmsExemptMaterialVO> list = page.getRecords();
// 转换为导出DTO
List<QmsExemptMaterialExportDTO> exportList = new ArrayList<>();
for (QmsExemptMaterialVO vo : list) {
QmsExemptMaterialExportDTO dto = new QmsExemptMaterialExportDTO();
dto.setSupplierCode(vo.getSupplierCode());
dto.setSupplierName(vo.getSupplierName());
dto.setMaterialNo(vo.getMaterialNo());
dto.setMaterialDesc(vo.getMaterialDesc());
dto.setAuditStatusText(vo.getAuditStatus() == null ? "" :
vo.getAuditStatus() == 0 ? "待审核" :
vo.getAuditStatus() == 1 ? "已审核" : "已驳回");
dto.setExemptModeText(vo.getExemptMode() == null ? "" :
vo.getExemptMode() == 0 ? "永久" : "周期");
dto.setValidStartDate(vo.getValidStartDate() != null ? vo.getValidStartDate().format(DATE_FMT).substring(0, 10) : "");
dto.setValidEndDate(vo.getValidEndDate() != null ? vo.getValidEndDate().format(DATE_FMT).substring(0, 10) : "");
dto.setValidStatusText(vo.getValidStatus() != null && vo.getValidStatus() == 1 ? "有效中" : "已过期");
dto.setAuditorName(vo.getAuditorName());
dto.setAuditTime(vo.getAuditTime() != null ? vo.getAuditTime().format(DATE_FMT) : "");
dto.setCreateByName(vo.getCreateByName());
dto.setCreateTime(vo.getCreateTime() != null ? vo.getCreateTime().format(DATE_FMT) : "");
dto.setUpdateByName(vo.getUpdateByName());
dto.setUpdateTime(vo.getUpdateTime() != null ? vo.getUpdateTime().format(DATE_FMT) : "");
exportList.add(dto);
}
EecExcelUtil.export("免检物料", "免检物料", exportList, response);
}
/**
* 下载导入模板
*/
@PostMapping("template")
public void template(HttpServletResponse response) throws IOException {
QmsExemptMaterialImportDTO example = new QmsExemptMaterialImportDTO()
.setSupplierCode("示例供应商编码")
.setSupplierName("示例供应商名称(非必填)")
.setMaterialNo("示例物料编号")
.setMaterialDesc("示例物料描述(非必填)")
.setExemptMode("永久")
.setValidStartDate("2026-01-01")
.setValidEndDate("2026-12-31");
EecExcelUtil.export("免检物料导入模板", "免检物料导入模板", List.of(example), response);
}
/**
* 导入免检物料
*/
@PostMapping("import")
public ApiResult<?> importExcel(MultipartFile file) throws IOException {
List<QmsExemptMaterialImportDTO> data = EecExcelUtil.getExcelContext(file.getInputStream(), QmsExemptMaterialImportDTO.class);
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(data)).throwMessage("导入文件内容为空");
if (!checkAndImport(data)) {
try (ByteArrayOutputStream osOut = new ByteArrayOutputStream()) {
new Workbook()
.addSheet(new ListSheet<>(data))
.writeTo(osOut);
try (ByteArrayInputStream isIn = new ByteArrayInputStream(osOut.toByteArray())) {
return ApiResult.error(STATE.DataNoCheckPass, "导入文件失败",
fileUploadService.upload("temp/" + DateTimeUtil.format(LocalDate.now(), "yyyyMMdd") + "/" + IdUtil.fastUUID() + ".xlsx", isIn, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
}
} catch (Exception e) {
return ApiResult.error(STATE.BusinessError, "保存文件出错");
}
}
return ApiResult.success();
}
/**
* 校验并导入数据
*/
private boolean checkAndImport(List<QmsExemptMaterialImportDTO> data) {
Long userId = UserUtil.getUserId();
String userName = UserUtil.getUserName();
LocalDateTime now = LocalDateTime.now();
boolean allSuccess = true;
List<QmsExemptMaterial> toSave = new ArrayList<>();
for (QmsExemptMaterialImportDTO dto : data) {
StringBuilder sb = new StringBuilder();
// 校验必填字段
if (StrUtil.isBlank(dto.getSupplierCode())) {
sb.append("供应商编码不能为空;");
}
if (StrUtil.isBlank(dto.getMaterialNo())) {
sb.append("物料编号不能为空;");
}
if (StrUtil.isBlank(dto.getExemptMode())) {
sb.append("免检模式不能为空;");
}
if (!sb.isEmpty()) {
dto.setError(sb.toString());
allSuccess = false;
continue;
}
// 验证供应商是否存在
LambdaQueryWrapper<UserSupplier> supplierWrapper = new LambdaQueryWrapper<>();
supplierWrapper.eq(UserSupplier::getSupplierCode, dto.getSupplierCode());
UserSupplier supplier = userSupplierService.getOne(supplierWrapper, false);
if (supplier == null) {
dto.setError("供应商编码不存在");
allSuccess = false;
continue;
}
// 验证免检模式
Integer exemptMode;
if ("永久".equals(dto.getExemptMode())) {
exemptMode = 0;
} else if ("周期".equals(dto.getExemptMode())) {
exemptMode = 1;
} else {
dto.setError("免检模式只能为'永久'或'周期'");
allSuccess = false;
continue;
}
// 周期模式时有效开始时间和有效结束时间必填
if (exemptMode == 1) {
if (StrUtil.isBlank(dto.getValidStartDate())) {
sb.append("周期模式下有效开始日期不能为空;");
}
if (StrUtil.isBlank(dto.getValidEndDate())) {
sb.append("周期模式下有效结束日期不能为空;");
}
if (!sb.isEmpty()) {
dto.setError(sb.toString());
allSuccess = false;
continue;
}
}
// 唯一性校验供应商编号+物料编号
LambdaQueryWrapper<QmsExemptMaterial> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(QmsExemptMaterial::getMaterialNo, dto.getMaterialNo())
.eq(QmsExemptMaterial::getSupplierId, supplier.getId());
long count = exemptMaterialService.count(wrapper);
if (count > 0) {
dto.setError("该供应商与物料编号的免检记录已存在");
allSuccess = false;
continue;
}
// 构造实体
QmsExemptMaterial entity = new QmsExemptMaterial();
entity.setSupplierId(supplier.getId());
entity.setMaterialNo(dto.getMaterialNo());
entity.setExemptMode(exemptMode);
entity.setAuditStatus(0);
entity.setEnable(true);
entity.setCreateBy(userId);
entity.setCreateByName(userName);
entity.setCreateTime(now);
entity.setUpdateBy(userId);
entity.setUpdateByName(userName);
entity.setUpdateTime(now);
if (StrUtil.isNotBlank(dto.getValidStartDate())) {
entity.setValidStartDate(parseDate(dto.getValidStartDate()));
}
if (StrUtil.isNotBlank(dto.getValidEndDate())) {
entity.setValidEndDate(parseDate(dto.getValidEndDate()));
}
toSave.add(entity);
}
if (allSuccess && !toSave.isEmpty()) {
exemptMaterialService.saveBatch(toSave);
}
return allSuccess;
}
private LocalDateTime parseDate(String dateStr) {
if (dateStr == null || dateStr.trim().isEmpty()) {
return null;
}
dateStr = dateStr.trim();
// 处理Excel日期序列号纯数字
if (dateStr.matches("\\d+")) {
long serial = Long.parseLong(dateStr);
LocalDate date = LocalDate.of(1900, 1, 1).plusDays(serial - 2);
return date.atStartOfDay();
}
// 处理带小数的Excel日期序列号如46149.0
if (dateStr.matches("\\d+\\.\\d+")) {
long serial = (long) Double.parseDouble(dateStr);
LocalDate date = LocalDate.of(1900, 1, 1).plusDays(serial - 2);
return date.atStartOfDay();
}
if (dateStr.length() == 10) {
dateStr = dateStr + " 00:00:00";
}
return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
}

View File

@ -0,0 +1,58 @@
package com.nflg.wms.common.pojo.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import org.ttzero.excel.annotation.ExcelColumn;
/**
* 免检物料类别导出DTO
*/
@Data
@Accessors(chain = true)
public class QmsExemptCategoryExportDTO {
@ExcelColumn("供应商编码")
private String supplierCode;
@ExcelColumn("供应商名称")
private String supplierName;
@ExcelColumn("物料类别")
private String categoryCode;
@ExcelColumn("物料类别名称")
private String categoryFullName;
@ExcelColumn("审核状态")
private String auditStatusText;
@ExcelColumn("免检模式")
private String exemptModeText;
@ExcelColumn("有效开始日期")
private String validStartDate;
@ExcelColumn("有效结束日期")
private String validEndDate;
@ExcelColumn("是否有效")
private String validStatusText;
@ExcelColumn("审核人")
private String auditorName;
@ExcelColumn("审核时间")
private String auditTime;
@ExcelColumn("创建人")
private String createByName;
@ExcelColumn("创建时间")
private String createTime;
@ExcelColumn("修改人")
private String updateByName;
@ExcelColumn("修改时间")
private String updateTime;
}

View File

@ -0,0 +1,61 @@
package com.nflg.wms.common.pojo.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import org.ttzero.excel.annotation.ExcelColumn;
/**
* 免检物料类别导入DTO
*/
@Data
@Accessors(chain = true)
public class QmsExemptCategoryImportDTO {
/**
* 供应商编码
*/
@ExcelColumn("*供应商编码")
private String supplierCode;
/**
* 供应商名称非必填
*/
@ExcelColumn("供应商名称")
private String supplierName;
/**
* 物料类别编码
*/
@ExcelColumn("*物料类别编码")
private String categoryCode;
/**
* 物料类别名称非必填
*/
@ExcelColumn("物料类别名称")
private String categoryName;
/**
* 免检模式永久/周期
*/
@ExcelColumn("*免检模式")
private String exemptMode;
/**
* 有效开始日期
*/
@ExcelColumn("有效开始日期")
private String validStartDate;
/**
* 有效结束日期
*/
@ExcelColumn("有效结束日期")
private String validEndDate;
/**
* 错误信息
*/
@ExcelColumn("错误信息")
private String error;
}

View File

@ -0,0 +1,58 @@
package com.nflg.wms.common.pojo.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import org.ttzero.excel.annotation.ExcelColumn;
/**
* 免检物料导出DTO
*/
@Data
@Accessors(chain = true)
public class QmsExemptMaterialExportDTO {
@ExcelColumn("供应商编码")
private String supplierCode;
@ExcelColumn("供应商名称")
private String supplierName;
@ExcelColumn("物料编号")
private String materialNo;
@ExcelColumn("物料描述")
private String materialDesc;
@ExcelColumn("审核状态")
private String auditStatusText;
@ExcelColumn("免检模式")
private String exemptModeText;
@ExcelColumn("有效开始日期")
private String validStartDate;
@ExcelColumn("有效结束日期")
private String validEndDate;
@ExcelColumn("是否有效")
private String validStatusText;
@ExcelColumn("审核人")
private String auditorName;
@ExcelColumn("审核时间")
private String auditTime;
@ExcelColumn("创建人")
private String createByName;
@ExcelColumn("创建时间")
private String createTime;
@ExcelColumn("修改人")
private String updateByName;
@ExcelColumn("修改时间")
private String updateTime;
}

View File

@ -0,0 +1,61 @@
package com.nflg.wms.common.pojo.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import org.ttzero.excel.annotation.ExcelColumn;
/**
* 免检物料导入DTO
*/
@Data
@Accessors(chain = true)
public class QmsExemptMaterialImportDTO {
/**
* 供应商编码
*/
@ExcelColumn("*供应商编码")
private String supplierCode;
/**
* 供应商名称非必填
*/
@ExcelColumn("供应商名称")
private String supplierName;
/**
* 物料编号
*/
@ExcelColumn("*物料编号")
private String materialNo;
/**
* 物料描述非必填
*/
@ExcelColumn("物料描述")
private String materialDesc;
/**
* 免检模式永久/周期
*/
@ExcelColumn("*免检模式")
private String exemptMode;
/**
* 有效开始日期
*/
@ExcelColumn("有效开始日期")
private String validStartDate;
/**
* 有效结束日期
*/
@ExcelColumn("有效结束日期")
private String validEndDate;
/**
* 错误信息
*/
@ExcelColumn("错误信息")
private String error;
}

View File

@ -0,0 +1,15 @@
package com.nflg.wms.common.pojo.qo;
import lombok.Data;
/**
* 免检物料类别 - 按物料类别查询明细请求
*/
@Data
public class QmsExemptCategoryDetailByCategoryQO {
/**
* 物料类别编码
*/
private String categoryCode;
}

View File

@ -0,0 +1,76 @@
package com.nflg.wms.common.pojo.qo;
import lombok.Data;
import java.util.List;
/**
* 免检物料类别 保存请求对象
*/
@Data
public class QmsExemptCategorySaveQO {
/**
* 供应商ID按供应商模式时使用
*/
private Long supplierId;
/**
* 物料类别编码按物料类别模式时使用
*/
private String categoryCode;
/**
* 头部免检模式0 永久1 周期
*/
private Integer exemptMode;
/**
* 头部有效期开始日期
*/
private String validStartDate;
/**
* 头部有效期结束日期
*/
private String validEndDate;
/**
* 明细列表
*/
private List<Item> items;
@Data
public static class Item {
/**
* 已有记录ID编辑时使用
*/
private Long id;
/**
* 物料类别编码按供应商模式时每行的物料类别
*/
private String categoryCode;
/**
* 供应商ID按物料类别模式时每行的供应商
*/
private Long supplierId;
/**
* 免检模式0 永久1 周期
*/
private Integer exemptMode;
/**
* 有效期开始日期
*/
private String validStartDate;
/**
* 有效期结束日期
*/
private String validEndDate;
}
}

View File

@ -0,0 +1,68 @@
package com.nflg.wms.common.pojo.qo;
import lombok.Data;
import java.time.LocalDate;
import java.util.List;
/**
* 免检物料类别 列表查询参数
*/
@Data
public class QmsExemptCategorySearchQO extends PageQO {
/**
* 供应商编码或名称模糊搜索
*/
private String supplier;
/**
* 物料类别编码模糊搜索
*/
private String categoryCode;
/**
* 免检模式0 永久1 周期
*/
private Integer exemptMode;
/**
* 审核状态0 待审核1 已审核2 已驳回
*/
private Integer auditStatus;
/**
* 启用状态true=启用false=禁用
*/
private Boolean enable;
/**
* 有效开始日期 - 起始
*/
private LocalDate validStartDateBegin;
/**
* 有效开始日期 - 结束
*/
private LocalDate validStartDateEnd;
/**
* 有效结束日期 - 起始
*/
private LocalDate validEndDateBegin;
/**
* 有效结束日期 - 结束
*/
private LocalDate validEndDateEnd;
/**
* 有效状态0 已过期1 有效中
*/
private Integer validStatus;
/**
* 指定导出的ID列表为空时导出全部
*/
private List<Long> ids;
}

View File

@ -3,6 +3,7 @@ package com.nflg.wms.common.pojo.qo;
import lombok.Data;
import java.time.LocalDate;
import java.util.List;
/**
* 免检物料 列表查询参数
@ -59,4 +60,9 @@ public class QmsExemptMaterialSearchQO extends PageQO {
* 有效状态0 已过期1 有效中
*/
private Integer validStatus;
/**
* 指定导出的ID列表为空时导出全部
*/
private List<Long> ids;
}

View File

@ -0,0 +1,107 @@
package com.nflg.wms.common.pojo.vo;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 免检物料类别 列表VO
*/
@Data
public class QmsExemptCategoryVO {
/**
* 免检物料类别ID
*/
private Long id;
/**
* 供应商ID
*/
private Long supplierId;
/**
* 供应商编码
*/
private String supplierCode;
/**
* 供应商名称
*/
private String supplierName;
/**
* 物料类别编码
*/
private String categoryCode;
/**
* 物料类别全路径名称采购物料/原材料/管材
*/
private String categoryFullName;
/**
* 审核状态0 待审核1 已审核2 已驳回
*/
private Integer auditStatus;
/**
* 驳回原因
*/
private String rejectReason;
/**
* 启用状态true=启用false=禁用
*/
private Boolean enable;
/**
* 免检模式0 永久1 周期
*/
private Integer exemptMode;
/**
* 有效期开始日期
*/
private LocalDateTime validStartDate;
/**
* 有效期结束日期
*/
private LocalDateTime validEndDate;
/**
* 是否有效0 已过期1 有效中
*/
private Integer validStatus;
/**
* 审核人
*/
private String auditorName;
/**
* 审核时间
*/
private LocalDateTime auditTime;
/**
* 创建人名称
*/
private String createByName;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 修改人名称
*/
private String updateByName;
/**
* 修改时间
*/
private LocalDateTime updateTime;
}

View File

@ -13,7 +13,7 @@ import java.time.LocalDateTime;
/**
* <p>
* 免检物料
* 免检物料类别
* </p>
*
* @author 代码生成器生成

View File

@ -1,16 +1,32 @@
package com.nflg.wms.repository.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nflg.wms.common.pojo.qo.QmsExemptCategorySearchQO;
import com.nflg.wms.common.pojo.vo.QmsExemptCategoryVO;
import com.nflg.wms.repository.entity.QmsExemptCategory;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 免检物料 Mapper 接口
* </p>
*
* @author 代码生成器生成
* @since 2026
* 免检物料类别 Mapper 接口
*/
public interface QmsExemptCategoryMapper extends BaseMapper<QmsExemptCategory> {
/**
* 分页查询免检物料类别列表
*/
IPage<QmsExemptCategoryVO> search(@Param("request") QmsExemptCategorySearchQO request, Page<?> page);
/**
* 按供应商查询关联的免检物料类别明细
*/
List<QmsExemptCategoryVO> detailBySupplier(@Param("supplierId") Long supplierId);
/**
* 按物料类别编码查询关联的供应商免检明细
*/
List<QmsExemptCategoryVO> detailByCategory(@Param("categoryCode") String categoryCode);
}

View File

@ -1,16 +1,47 @@
package com.nflg.wms.repository.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.nflg.wms.common.pojo.qo.QmsExemptCategorySearchQO;
import com.nflg.wms.common.pojo.qo.QmsExemptCategorySaveQO;
import com.nflg.wms.common.pojo.qo.QmsExemptMaterialAuditQO;
import com.nflg.wms.common.pojo.vo.QmsExemptCategoryVO;
import com.nflg.wms.repository.entity.QmsExemptCategory;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* 免检物料 服务类
* </p>
*
* @author 代码生成器生成
* @since 2026
* 免检物料类别 服务类
*/
public interface IQmsExemptCategoryService extends IService<QmsExemptCategory> {
/**
* 分页查询
*/
IPage<QmsExemptCategoryVO> search(QmsExemptCategorySearchQO request);
/**
* 保存免检物料类别新增/编辑
*/
void saveExemptCategory(QmsExemptCategorySaveQO request);
/**
* 按供应商查询明细
*/
List<QmsExemptCategoryVO> detailBySupplier(Long supplierId);
/**
* 按物料类别查询明细
*/
List<QmsExemptCategoryVO> detailByCategory(String categoryCode);
/**
* 启用/禁用切换
*/
void toggleEnable(Long id, Boolean enable);
/**
* 审核
*/
void audit(QmsExemptMaterialAuditQO request);
}

View File

@ -1,20 +1,168 @@
package com.nflg.wms.repository.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nflg.wms.common.constant.STATE;
import com.nflg.wms.common.exception.NflgException;
import com.nflg.wms.common.pojo.qo.QmsExemptCategorySearchQO;
import com.nflg.wms.common.pojo.qo.QmsExemptCategorySaveQO;
import com.nflg.wms.common.pojo.qo.QmsExemptMaterialAuditQO;
import com.nflg.wms.common.pojo.vo.QmsExemptCategoryVO;
import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.repository.entity.QmsExemptCategory;
import com.nflg.wms.repository.mapper.QmsExemptCategoryMapper;
import com.nflg.wms.repository.service.IQmsExemptCategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 免检物料 服务实现类
* </p>
*
* @author 代码生成器生成
* @since 2026
* 免检物料类别 服务实现类
*/
@Service
public class QmsExemptCategoryServiceImpl extends ServiceImpl<QmsExemptCategoryMapper, QmsExemptCategory> implements IQmsExemptCategoryService {
public class QmsExemptCategoryServiceImpl extends ServiceImpl<QmsExemptCategoryMapper, QmsExemptCategory>
implements IQmsExemptCategoryService {
private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Override
public IPage<QmsExemptCategoryVO> search(QmsExemptCategorySearchQO request) {
return baseMapper.search(request, new Page<>(request.getPage(), request.getPageSize()));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveExemptCategory(QmsExemptCategorySaveQO request) {
if (request.getItems() == null || request.getItems().isEmpty()) {
throw new NflgException(STATE.BusinessError, "明细列表不能为空");
}
Long userId = UserUtil.getUserId();
String userName = UserUtil.getUserName();
LocalDateTime now = LocalDateTime.now();
List<QmsExemptCategory> toSave = new ArrayList<>();
for (QmsExemptCategorySaveQO.Item item : request.getItems()) {
// 确定 supplierId categoryCode
Long supplierId = item.getSupplierId() != null ? item.getSupplierId() : request.getSupplierId();
String categoryCode = item.getCategoryCode() != null ? item.getCategoryCode() : request.getCategoryCode();
if (supplierId == null || categoryCode == null || categoryCode.isEmpty()) {
throw new NflgException(STATE.BusinessError, "供应商和物料类别编码不能为空");
}
// 唯一性校验(category_code + supplier_id)
LambdaQueryWrapper<QmsExemptCategory> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(QmsExemptCategory::getCategoryCode, categoryCode)
.eq(QmsExemptCategory::getSupplierId, supplierId);
if (item.getId() != null) {
wrapper.ne(QmsExemptCategory::getId, item.getId());
}
long count = this.count(wrapper);
if (count > 0) {
throw new NflgException(STATE.BusinessError, "物料类别编码[" + categoryCode + "]与该供应商的免检记录已存在");
}
QmsExemptCategory entity;
if (item.getId() != null) {
entity = this.getById(item.getId());
if (entity == null) {
throw new NflgException(STATE.BusinessError, "记录不存在ID" + item.getId());
}
entity.setUpdateBy(userId);
entity.setUpdateByName(userName);
entity.setUpdateTime(now);
} else {
entity = new QmsExemptCategory();
entity.setSupplierId(supplierId);
entity.setCategoryCode(categoryCode);
entity.setAuditStatus(0);
entity.setEnable(true);
entity.setCreateBy(userId);
entity.setCreateByName(userName);
entity.setCreateTime(now);
entity.setUpdateBy(userId);
entity.setUpdateByName(userName);
entity.setUpdateTime(now);
}
entity.setExemptMode(item.getExemptMode());
if (item.getValidStartDate() != null && !item.getValidStartDate().isEmpty()) {
entity.setValidStartDate(parseDate(item.getValidStartDate()));
} else {
entity.setValidStartDate(null);
}
if (item.getValidEndDate() != null && !item.getValidEndDate().isEmpty()) {
entity.setValidEndDate(parseDate(item.getValidEndDate()));
} else {
entity.setValidEndDate(null);
}
toSave.add(entity);
}
this.saveOrUpdateBatch(toSave);
}
@Override
public List<QmsExemptCategoryVO> detailBySupplier(Long supplierId) {
return baseMapper.detailBySupplier(supplierId);
}
@Override
public List<QmsExemptCategoryVO> detailByCategory(String categoryCode) {
return baseMapper.detailByCategory(categoryCode);
}
@Override
public void toggleEnable(Long id, Boolean enable) {
QmsExemptCategory entity = this.getById(id);
if (entity == null) {
throw new NflgException(STATE.BusinessError, "记录不存在");
}
entity.setEnable(enable);
entity.setUpdateBy(UserUtil.getUserId());
entity.setUpdateByName(UserUtil.getUserName());
entity.setUpdateTime(LocalDateTime.now());
this.updateById(entity);
}
@Override
public void audit(QmsExemptMaterialAuditQO request) {
QmsExemptCategory entity = this.getById(request.getId());
if (entity == null) {
throw new NflgException(STATE.BusinessError, "记录不存在");
}
if (Boolean.TRUE.equals(request.getPass())) {
entity.setAuditStatus(1);
entity.setRejectReason("");
} else {
if (request.getRejectReason() == null || request.getRejectReason().trim().isEmpty()) {
throw new NflgException(STATE.BusinessError, "驳回时必须填写驳回原因");
}
entity.setAuditStatus(2);
entity.setRejectReason(request.getRejectReason());
}
entity.setAuditorId(UserUtil.getUserId());
entity.setAuditorName(UserUtil.getUserName());
entity.setAuditTime(LocalDateTime.now());
entity.setUpdateBy(UserUtil.getUserId());
entity.setUpdateByName(UserUtil.getUserName());
entity.setUpdateTime(LocalDateTime.now());
this.updateById(entity);
}
private LocalDateTime parseDate(String dateStr) {
if (dateStr.length() == 10) {
dateStr = dateStr + " 00:00:00";
}
return LocalDateTime.parse(dateStr, DATE_FMT);
}
}

View File

@ -2,4 +2,156 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nflg.wms.repository.mapper.QmsExemptCategoryMapper">
<!-- 分页查询免检物料类别列表JOIN 供应商表和物料类别表 -->
<select id="search" resultType="com.nflg.wms.common.pojo.vo.QmsExemptCategoryVO">
SELECT
ec.id,
ec.supplier_id,
us.supplier_code,
us.supplier_name,
ec.category_code,
(SELECT string_agg(mc2.category_name, '/' ORDER BY t.pos)
FROM unnest(string_to_array(mc.parent_tree::text, '.'))
WITH ORDINALITY AS t(node_id, pos)
LEFT JOIN qms_qc_material_category mc2 ON mc2.id::text = t.node_id
WHERE t.node_id != '0') AS category_full_name,
ec.audit_status,
ec.enable,
ec.exempt_mode,
ec.valid_start_date,
ec.valid_end_date,
ec.reject_reason,
CASE
WHEN ec.exempt_mode = 0 THEN 1
WHEN ec.exempt_mode = 1 AND ec.valid_end_date IS NOT NULL AND ec.valid_end_date &gt;= NOW() THEN 1
ELSE 0
END AS valid_status,
ec.auditor_name,
ec.audit_time,
ec.create_by_name,
ec.create_time,
ec.update_by_name,
ec.update_time
FROM qms_exempt_category ec
LEFT JOIN user_supplier us ON us.id = ec.supplier_id
LEFT JOIN qms_qc_material_category mc ON mc.category_code = ec.category_code
<where>
<if test="request.ids != null and request.ids.size() > 0">
AND ec.id IN
<foreach collection="request.ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
<if test="request.supplier != null and request.supplier != ''">
AND (us.supplier_code ILIKE CONCAT('%', #{request.supplier}, '%')
OR us.supplier_name ILIKE CONCAT('%', #{request.supplier}, '%'))
</if>
<if test="request.categoryCode != null and request.categoryCode != ''">
AND ec.category_code ILIKE CONCAT('%', #{request.categoryCode}, '%')
</if>
<if test="request.exemptMode != null">
AND ec.exempt_mode = #{request.exemptMode}
</if>
<if test="request.auditStatus != null">
AND ec.audit_status = #{request.auditStatus}
</if>
<if test="request.enable != null">
AND ec.enable = #{request.enable}
</if>
<if test="request.validStartDateBegin != null">
AND ec.valid_start_date &gt;= #{request.validStartDateBegin}
</if>
<if test="request.validStartDateEnd != null">
AND ec.valid_start_date &lt;= #{request.validStartDateEnd}
</if>
<if test="request.validEndDateBegin != null">
AND ec.valid_end_date &gt;= #{request.validEndDateBegin}
</if>
<if test="request.validEndDateEnd != null">
AND ec.valid_end_date &lt;= #{request.validEndDateEnd}
</if>
<if test="request.validStatus != null and request.validStatus == 1">
AND (ec.exempt_mode = 0 OR (ec.exempt_mode = 1 AND ec.valid_end_date IS NOT NULL AND ec.valid_end_date &gt;= NOW()))
</if>
<if test="request.validStatus != null and request.validStatus == 0">
AND ec.exempt_mode = 1 AND (ec.valid_end_date IS NULL OR ec.valid_end_date &lt; NOW())
</if>
</where>
ORDER BY ec.create_time DESC
</select>
<!-- 按供应商查询关联的免检物料类别明细 -->
<select id="detailBySupplier" resultType="com.nflg.wms.common.pojo.vo.QmsExemptCategoryVO">
SELECT
ec.id,
ec.supplier_id,
us.supplier_code,
us.supplier_name,
ec.category_code,
(SELECT string_agg(mc2.category_name, '/' ORDER BY t.pos)
FROM unnest(string_to_array(mc.parent_tree::text, '.'))
WITH ORDINALITY AS t(node_id, pos)
LEFT JOIN qms_qc_material_category mc2 ON mc2.id::text = t.node_id
WHERE t.node_id != '0') AS category_full_name,
ec.audit_status,
ec.enable,
ec.exempt_mode,
ec.valid_start_date,
ec.valid_end_date,
ec.reject_reason,
CASE
WHEN ec.exempt_mode = 0 THEN 1
WHEN ec.exempt_mode = 1 AND ec.valid_end_date IS NOT NULL AND ec.valid_end_date &gt;= NOW() THEN 1
ELSE 0
END AS valid_status,
ec.auditor_name,
ec.audit_time,
ec.create_by_name,
ec.create_time,
ec.update_by_name,
ec.update_time
FROM qms_exempt_category ec
LEFT JOIN user_supplier us ON us.id = ec.supplier_id
LEFT JOIN qms_qc_material_category mc ON mc.category_code = ec.category_code
WHERE ec.supplier_id = #{supplierId}
ORDER BY ec.create_time DESC
</select>
<!-- 按物料类别查询关联的供应商免检明细 -->
<select id="detailByCategory" resultType="com.nflg.wms.common.pojo.vo.QmsExemptCategoryVO">
SELECT
ec.id,
ec.supplier_id,
us.supplier_code,
us.supplier_name,
ec.category_code,
(SELECT string_agg(mc2.category_name, '/' ORDER BY t.pos)
FROM unnest(string_to_array(mc.parent_tree::text, '.'))
WITH ORDINALITY AS t(node_id, pos)
LEFT JOIN qms_qc_material_category mc2 ON mc2.id::text = t.node_id
WHERE t.node_id != '0') AS category_full_name,
ec.audit_status,
ec.enable,
ec.exempt_mode,
ec.valid_start_date,
ec.valid_end_date,
ec.reject_reason,
CASE
WHEN ec.exempt_mode = 0 THEN 1
WHEN ec.exempt_mode = 1 AND ec.valid_end_date IS NOT NULL AND ec.valid_end_date &gt;= NOW() THEN 1
ELSE 0
END AS valid_status,
ec.auditor_name,
ec.audit_time,
ec.create_by_name,
ec.create_time,
ec.update_by_name,
ec.update_time
FROM qms_exempt_category ec
LEFT JOIN user_supplier us ON us.id = ec.supplier_id
LEFT JOIN qms_qc_material_category mc ON mc.category_code = ec.category_code
WHERE ec.category_code = #{categoryCode}
ORDER BY ec.create_time DESC
</select>
</mapper>

View File

@ -32,6 +32,12 @@
LEFT JOIN user_supplier us ON us.id = em.supplier_id
LEFT JOIN qms_qc_material qm ON qm.material_no = em.material_no
<where>
<if test="request.ids != null and request.ids.size() > 0">
AND em.id IN
<foreach collection="request.ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
<if test="request.supplier != null and request.supplier != ''">
AND (us.supplier_code ILIKE CONCAT('%', #{request.supplier}, '%')
OR us.supplier_name ILIKE CONCAT('%', #{request.supplier}, '%'))