This commit is contained in:
zc
2026-03-20 18:06:45 +08:00
parent 18dbf7a042
commit 3b8d01b673
14 changed files with 578 additions and 73 deletions

View File

@@ -5,7 +5,10 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.*;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.validation.ValidationUtil;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONUtil;
@@ -17,15 +20,12 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.result.R;
import org.dromara.x.file.storage.core.FileInfo;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import top.continew.starter.cache.redisson.util.RedisUtils;
@@ -61,8 +61,6 @@ import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -70,7 +68,6 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static top.wms.admin.system.enums.ImportPolicyEnum.*;
import static top.wms.admin.system.enums.ImportPolicyEnum.SKIP;
/**
* 物料信息业务实现

View File

@@ -1,9 +1,12 @@
package top.wms.admin.materialProcess.mapper;
import org.apache.ibatis.annotations.Param;
import top.continew.starter.data.mp.base.BaseMapper;
import top.wms.admin.materialProcess.model.entity.MaterialProcessDO;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 海康物料流程 Mapper
*
@@ -13,4 +16,7 @@ import org.springframework.stereotype.Repository;
@Repository
public interface MaterialProcessMapper extends BaseMapper<MaterialProcessDO> {
void updateByName(@Param("list") List<MaterialProcessDO> updateByNameList);
void updateByCode(@Param("list") List<MaterialProcessDO> updateByCodeList);
}

View File

@@ -0,0 +1,37 @@
package top.wms.admin.materialProcess.model.req;
import lombok.Data;
import lombok.experimental.Accessors;
import top.wms.admin.system.enums.ImportPolicyEnum;
import java.io.Serial;
import java.io.Serializable;
/**
* 物料流程导入请求
*
* @author zc
* @since 2026/03/20
*/
@Data
public class MaterialProcessImportReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 导入key
*/
private String importKey;
/**
* 重复流程名称处理策略: 0-跳过 1-更新 2-退出
*/
private ImportPolicyEnum duplicateName;
/**
* 重复流程编码处理策略: 0-跳过 1-更新 2-退出
*/
private ImportPolicyEnum duplicateCode;
}

View File

@@ -0,0 +1,35 @@
package top.wms.admin.materialProcess.model.req;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
/**
* 物料流程导入行数据
*
* @author zc
* @since 2026/03/20
*/
@Data
public class MaterialProcessImportRowReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 流程名称
*/
@NotBlank(message = "流程名称不能为空")
private String processName;
/**
* 流程编码
*/
@NotBlank(message = "流程编码不能为空")
private String processCode;
}

View File

@@ -0,0 +1,49 @@
package top.wms.admin.materialProcess.model.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "用户导入解析结果")
public class MaterialProcessImportParseResp implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 导入会话 Key
*/
@Schema(description = "导入会话Key", example = "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed")
private String importKey;
/**
* 总计行数
*/
@Schema(description = "总计行数", example = "100")
private Integer totalRows;
/**
* 有效行数
*/
@Schema(description = "有效行数", example = "100")
private Integer validRows;
/**
* 重复名称行数
*/
@Schema(description = "重复名称行数", example = "100")
private Integer duplicateNameRows;
/**
* 重复编码行数
*/
@Schema(description = "重复编码行数", example = "100")
private Integer duplicateCodeRows;
}

View File

@@ -0,0 +1,42 @@
package top.wms.admin.materialProcess.model.resp;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
/**
* 物料流程导入响应
*
* @author zc
* @since 2026/03/20
*/
@Data
public class MaterialProcessImportResp implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 总处理数
*/
private Integer totalHandleCount;
/**
* 新增数
*/
private Integer insertCount;
/**
* 更新数
*/
private Integer updateCount;
public MaterialProcessImportResp(Integer totalHandleCount, Integer insertCount, Integer updateCount) {
this.totalHandleCount = totalHandleCount;
this.insertCount = insertCount;
this.updateCount = updateCount;
}
}

View File

@@ -1,5 +1,6 @@
package top.wms.admin.materialProcess.model.resp;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -26,11 +27,13 @@ public class MaterialProcessResp extends BaseDetailResp {
* 流程名称
*/
@Schema(description = "流程名称")
@ExcelProperty(value = "流程名称", order = 1)
private String processName;
/**
* 流程编码
*/
@Schema(description = "流程编码")
@ExcelProperty(value = "流程编码", order = 2)
private String processCode;
}

View File

@@ -4,11 +4,11 @@ import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
import top.continew.starter.extension.crud.model.resp.LabelValueResp;
import top.continew.starter.extension.crud.service.BaseService;
import top.wms.admin.material.model.req.MaterialInfoImportReq;
import top.wms.admin.material.model.resp.MaterialImportParseResp;
import top.wms.admin.material.model.resp.MaterialInfoImportResp;
import top.wms.admin.materialProcess.model.query.MaterialProcessQuery;
import top.wms.admin.materialProcess.model.req.MaterialProcessImportReq;
import top.wms.admin.materialProcess.model.req.MaterialProcessReq;
import top.wms.admin.materialProcess.model.resp.MaterialProcessImportParseResp;
import top.wms.admin.materialProcess.model.resp.MaterialProcessImportResp;
import top.wms.admin.materialProcess.model.resp.MaterialProcessResp;
import java.util.List;
@@ -36,14 +36,14 @@ public interface MaterialProcessService extends BaseService<MaterialProcessResp,
/**
* 解析导入文件
* @param file 导入文件
* @param file 导入文件
* @return 解析响应
*/
MaterialImportParseResp parseImport(MultipartFile file);
MaterialProcessImportParseResp parseImport(MultipartFile file);
/**
* 导入物料信息
* 导入物料流程
* @param req 导入请求
* @return 导入响应
*/
MaterialInfoImportResp importMaterial(MaterialInfoImportReq req);
MaterialProcessImportResp importMaterialProcess(MaterialProcessImportReq req);
}

View File

@@ -2,29 +2,47 @@ package top.wms.admin.materialProcess.service.impl;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.validation.ValidationUtil;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import net.dreamlu.mica.core.result.R;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import top.continew.starter.cache.redisson.util.RedisUtils;
import top.continew.starter.core.exception.BusinessException;
import top.continew.starter.core.validation.CheckUtils;
import top.continew.starter.extension.crud.model.query.SortQuery;
import top.continew.starter.extension.crud.model.resp.LabelValueResp;
import top.continew.starter.extension.crud.service.BaseServiceImpl;
import top.continew.starter.file.excel.util.ExcelUtils;
import top.continew.starter.web.util.FileUploadUtils;
import top.wms.admin.material.model.req.MaterialInfoImportReq;
import top.wms.admin.material.model.resp.MaterialImportParseResp;
import top.wms.admin.material.model.resp.MaterialInfoImportResp;
import top.wms.admin.common.constant.CacheConstants;
import top.wms.admin.common.context.UserContextHolder;
import top.wms.admin.material.model.resp.MaterialInfoResp;
import top.wms.admin.materialProcess.mapper.MaterialProcessMapper;
import top.wms.admin.materialProcess.mapstruct.MaterialProcessConvert;
import top.wms.admin.materialProcess.model.entity.MaterialProcessDO;
import top.wms.admin.materialProcess.model.query.MaterialProcessQuery;
import top.wms.admin.materialProcess.model.req.MaterialProcessImportReq;
import top.wms.admin.materialProcess.model.req.MaterialProcessImportRowReq;
import top.wms.admin.materialProcess.model.req.MaterialProcessReq;
import top.wms.admin.materialProcess.model.resp.MaterialProcessImportParseResp;
import top.wms.admin.materialProcess.model.resp.MaterialProcessImportResp;
import top.wms.admin.materialProcess.model.resp.MaterialProcessResp;
import top.wms.admin.materialProcess.service.MaterialProcessService;
import java.util.List;
import java.time.Duration;
import java.util.*;
import java.util.function.Function;
import static top.wms.admin.system.enums.ImportPolicyEnum.*;
/**
* 海康物料流程业务实现
@@ -38,6 +56,39 @@ public class MaterialProcessServiceImpl extends BaseServiceImpl<MaterialProcessM
private final MaterialProcessConvert materialProcessConvert;
@Override
public void beforeAdd(MaterialProcessReq req) {
// 校验流程名称是否重复
MaterialProcessDO processDO = baseMapper.selectOne(Wrappers.lambdaQuery(MaterialProcessDO.class)
.eq(MaterialProcessDO::getProcessName, req.getProcessName()));
CheckUtils.throwIf(ObjectUtil.isNotEmpty(processDO), "流程名称已存在");
// 校验流程编码是否重复
processDO = baseMapper.selectOne(Wrappers.lambdaQuery(MaterialProcessDO.class)
.eq(MaterialProcessDO::getProcessCode, req.getProcessCode()));
CheckUtils.throwIf(ObjectUtil.isNotEmpty(processDO), "流程编码已存在");
}
@Override
public void beforeUpdate(MaterialProcessReq req, Long id) {
// 校验流程名称是否重复
MaterialProcessDO processDO = baseMapper.selectOne(Wrappers.lambdaQuery(MaterialProcessDO.class)
.eq(MaterialProcessDO::getProcessName, req.getProcessName()).ne(MaterialProcessDO::getId, id));
CheckUtils.throwIf(ObjectUtil.isNotEmpty(processDO), "流程名称已存在");
// 校验流程编码是否重复
processDO = baseMapper.selectOne(Wrappers.lambdaQuery(MaterialProcessDO.class)
.eq(MaterialProcessDO::getProcessCode, req.getProcessCode()).ne(MaterialProcessDO::getId, id));
CheckUtils.throwIf(ObjectUtil.isNotEmpty(processDO), "流程编码已存在");
}
@Override
public void export(MaterialProcessQuery query, SortQuery sortQuery, HttpServletResponse response) {
List<MaterialProcessResp> list = super.list(query, sortQuery, this.getDetailClass());
list.forEach(super::fill);
ExcelUtils.export(list, "物料流程导出", MaterialProcessResp.class, response);
}
@Override
public List<LabelValueResp> getSelectList() {
List<MaterialProcessDO> materialProcessDOS = baseMapper.selectList(new QueryWrapper<>());
@@ -58,12 +109,210 @@ public class MaterialProcessServiceImpl extends BaseServiceImpl<MaterialProcessM
}
@Override
public MaterialImportParseResp parseImport(MultipartFile file) {
return null;
public MaterialProcessImportParseResp parseImport(MultipartFile file) {
MaterialProcessImportParseResp importResp = new MaterialProcessImportParseResp();
List<MaterialProcessImportRowReq> importRowList;
// 读取表格数据
try {
importRowList = com.alibaba.excel.EasyExcel.read(file.getInputStream())
.head(MaterialProcessImportRowReq.class)
.sheet()
.headRowNumber(1)
.doReadSync();
} catch (Exception e) {
log.error("物料流程导入数据文件解析异常:", e);
throw new BusinessException("数据文件解析异常");
}
// 总计行数
importResp.setTotalRows(importRowList.size());
CheckUtils.throwIfEmpty(importRowList, "数据文件格式错误");
// 有效行数:过滤无效数据
List<MaterialProcessImportRowReq> validRowList = this.filterImportData(importRowList);
importResp.setValidRows(validRowList.size());
CheckUtils.throwIfEmpty(validRowList, "数据文件格式错误");
// 检测表格内数据是否合法
Set<String> seenCode = new HashSet<>();
boolean hasDuplicateCode = validRowList.stream()
.map(MaterialProcessImportRowReq::getProcessCode)
.anyMatch(code -> code != null && !seenCode.add(code));
CheckUtils.throwIf(hasDuplicateCode, "存在重复流程编码,请检测数据");
// 查询重复流程名称
importResp
.setDuplicateNameRows(countExistByField(validRowList, MaterialProcessImportRowReq::getProcessName, MaterialProcessDO::getProcessName));
// 查询重复流程编码
importResp
.setDuplicateCodeRows(countExistByField(validRowList, MaterialProcessImportRowReq::getProcessCode, MaterialProcessDO::getProcessCode));
// 设置导入会话并缓存数据有效期10分钟
String importKey = java.util.UUID.randomUUID().toString().replace("-", "");
RedisUtils.set(CacheConstants.DATA_IMPORT_KEY + importKey, JSONUtil.toJsonStr(validRowList), Duration
.ofMinutes(10));
importResp.setImportKey(importKey);
return importResp;
}
@Override
public MaterialInfoImportResp importMaterial(MaterialInfoImportReq req) {
return null;
@Transactional(rollbackFor = Exception.class)
public MaterialProcessImportResp importMaterialProcess(MaterialProcessImportReq req) {
// 校验导入会话是否过期
List<MaterialProcessImportRowReq> importMaterialList;
try {
String data = RedisUtils.get(CacheConstants.DATA_IMPORT_KEY + req.getImportKey());
importMaterialList = JSONUtil.toList(data, MaterialProcessImportRowReq.class);
CheckUtils.throwIf(ObjectUtil.isEmpty(importMaterialList), "导入已过期,请重新上传");
} catch (Exception e) {
log.error("导入异常:", e);
throw new BusinessException("导入已过期,请重新上传");
}
// 已存在数据查询
List<String> existName = listExistByField(importMaterialList, MaterialProcessImportRowReq::getProcessName, MaterialProcessDO::getProcessName);
List<String> existCode = listExistByField(importMaterialList, MaterialProcessImportRowReq::getProcessCode, MaterialProcessDO::getProcessCode);
CheckUtils.throwIf(isExitImportMaterial(req, importMaterialList, existName, existCode), "数据不符合导入策略,已退出导入");
// 批量操作数据库集合
List<MaterialProcessDO> insertList = new ArrayList<>();
List<MaterialProcessDO> updateByNameList = new ArrayList<>();
List<MaterialProcessDO> updateByCodeList = new ArrayList<>();
// 处理导入数据
for (MaterialProcessImportRowReq row : importMaterialList) {
if (isSkipMaterialImport(req, row, existName, existCode)) {
continue;
}
MaterialProcessDO materialProcessDO = new MaterialProcessDO();
materialProcessDO.setProcessName(row.getProcessName());
materialProcessDO.setProcessCode(row.getProcessCode());
// 修改 or 新增
if (UPDATE.validate(req.getDuplicateName(), row.getProcessName(), existName)) {
materialProcessDO.setProcessCode(row.getProcessCode());
materialProcessDO.setUpdateUser(UserContextHolder.getUserId());
updateByNameList.add(materialProcessDO);
} else if (UPDATE.validate(req.getDuplicateCode(), row.getProcessCode(), existCode)) {
materialProcessDO.setProcessCode(row.getProcessCode());
materialProcessDO.setUpdateUser(UserContextHolder.getUserId());
updateByCodeList.add(materialProcessDO);
} else {
insertList.add(materialProcessDO);
}
}
doImportMaterial(insertList, updateByNameList, updateByCodeList);
RedisUtils.delete(CacheConstants.DATA_IMPORT_KEY + req.getImportKey());
int insertCount = insertList.size();
int updateByNameCount = updateByNameList.size();
int updateByCodeCount = updateByCodeList.size();
int totalUpdateCount = updateByNameCount + updateByCodeCount;
int totalHandleCount = insertCount + totalUpdateCount;
return new MaterialProcessImportResp(totalHandleCount, // 总处理数
insertCount, // 新增数
totalUpdateCount // 更新总数
);
}
/**
* 按指定数据集获取数据库已存在的数量
*
* @param materialRowList 导入的数据源
* @param rowField 导入数据的字段
* @param dbField 对比数据库的字段
* @return 存在的数量
*/
private int countExistByField(List<MaterialProcessImportRowReq> materialRowList,
Function<MaterialProcessImportRowReq, String> rowField,
SFunction<MaterialProcessDO, ?> dbField) {
List<String> fieldValues = materialRowList.stream().map(rowField).filter(Objects::nonNull).toList();
if (fieldValues.isEmpty()) {
return 0;
}
return (int)this.count(Wrappers.<MaterialProcessDO>lambdaQuery()
.in(dbField, fieldValues));
}
/**
* 过滤无效的导入数据
*
* @param importRowList 导入数据
*/
private List<MaterialProcessImportRowReq> filterImportData(List<MaterialProcessImportRowReq> importRowList) {
// 校验过滤
return importRowList.stream()
.filter(row -> ValidationUtil.validate(row).isEmpty())
.toList();
}
/**
* 按指定数据集获取数据库已存在内容
*
* @param materialRowList 导入的数据源
* @param rowField 导入数据的字段
* @param dbField 对比数据库的字段
* @return 存在的内容
*/
private List<String> listExistByField(List<MaterialProcessImportRowReq> materialRowList,
Function<MaterialProcessImportRowReq, String> rowField,
SFunction<MaterialProcessDO, String> dbField) {
List<String> fieldValues = materialRowList.stream().map(rowField).filter(Objects::nonNull).toList();
if (fieldValues.isEmpty()) {
return Collections.emptyList();
}
List<MaterialProcessDO> materialProcessDOList = baseMapper.selectList(Wrappers.<MaterialProcessDO>lambdaQuery()
.in(dbField, fieldValues)
.select(dbField));
return materialProcessDOList.stream().map(dbField).filter(Objects::nonNull).toList();
}
/**
* 判断是否退出导入
*
* @param req 导入参数
* @param list 导入数据
* @param existName 导入数据中已存在的流程名称
* @param existCode 导入数据中已存在的流程编码
* @return 是否退出
*/
private boolean isExitImportMaterial(MaterialProcessImportReq req,
List<MaterialProcessImportRowReq> list,
List<String> existName,
List<String> existCode) {
return list.stream()
.anyMatch(row -> EXIT.validate(req.getDuplicateName(), row.getProcessName(), existName) || EXIT
.validate(req.getDuplicateCode(), row.getProcessCode(), existCode));
}
/**
* 判断是否跳过导入
*
* @param req 导入参数
* @param row 导入数据
* @param existName 导入数据中已存在的流程名称
* @param existCode 导入数据中已存在的流程编码
* @return 是否跳过
*/
private boolean isSkipMaterialImport(MaterialProcessImportReq req,
MaterialProcessImportRowReq row,
List<String> existName,
List<String> existCode) {
return SKIP.validate(req.getDuplicateName(), row.getProcessName(), existName) || SKIP.validate(req
.getDuplicateCode(), row.getProcessCode(), existCode);
}
/**
* 导入物料流程
*
* @param insertList 新增流程
* @param updateByNameList 根据名称修改流程
* @param updateByCodeList 根据编码修改流程
*/
private void doImportMaterial(List<MaterialProcessDO> insertList,
List<MaterialProcessDO> updateByNameList,
List<MaterialProcessDO> updateByCodeList) {
if (insertList != null && !insertList.isEmpty()) {
baseMapper.insertBatch(insertList);
}
if (updateByNameList != null && !updateByNameList.isEmpty()) {
baseMapper.updateByName(updateByNameList);
}
if (updateByCodeList != null && !updateByCodeList.isEmpty()) {
baseMapper.updateByCode(updateByCodeList);
}
}
}

View File

@@ -1,4 +1,62 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="top.wms.admin.materialProcess.mapper.MaterialProcessMapper">
<!-- 按流程名称批量更新 -->
<update id="updateByName">
UPDATE sys_material_process
<trim prefix="SET" suffixOverrides=",">
<if test="list != null and list.size() > 0">
process_code = CASE
<foreach collection="list" item="item" separator="">
<if test="item.processCode != null and item.processCode != ''">
WHEN process_name = #{item.processName} THEN #{item.processCode}
</if>
</foreach>
ELSE process_code
END,
update_user = CASE
<foreach collection="list" item="item" separator="">
<if test="item.updateUser != null">
WHEN process_name = #{item.processName} THEN #{item.updateUser}
</if>
</foreach>
ELSE update_user
END,
update_time = NOW()
</if>
</trim>
WHERE process_name IN
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item.processName}
</foreach>
</update>
<update id="updateByCode">
UPDATE sys_material_process
<trim prefix="SET" suffixOverrides=",">
<if test="list != null and list.size() > 0">
process_name = CASE
<foreach collection="list" item="item" separator="">
<if test="item.processName != null and item.processName != ''">
WHEN process_code = #{item.processCode} THEN #{item.processName}
</if>
</foreach>
ELSE process_name
END,
update_user = CASE
<foreach collection="list" item="item" separator="">
<if test="item.updateUser != null">
WHEN process_code = #{item.processCode} THEN #{item.updateUser}
</if>
</foreach>
ELSE update_user
END,
update_time = NOW()
</if>
</trim>
WHERE process_code IN
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item.processCode}
</foreach>
</update>
</mapper>

View File

@@ -4,46 +4,76 @@
<!-- 按物料名称批量更新 -->
<update id="updateByName">
<foreach collection="list" item="item" separator=";">
UPDATE sys_material_info
<set>
<if test="item.encoding != null and item.encoding != ''" >
encoding = #{item.encoding},
</if>
<if test="item.unitWeight != null">
unit_weight = #{item.unitWeight},
</if>
<if test="item.materialSpec != null and item.materialSpec != ''">
material_spec = #{item.materialSpec},
</if>
<if test="item.updateUser != null">
update_user = #{item.updateUser},
</if>
UPDATE sys_material_info
<trim prefix="SET" suffixOverrides=",">
<if test="list != null and list.size() > 0">
encoding = CASE
<foreach collection="list" item="item" separator="">
<if test="item.encoding != null and item.encoding != ''">
WHEN material_name = #{item.materialName} THEN #{item.encoding}
</if>
</foreach>
ELSE encoding
END,
unit_weight = CASE
<foreach collection="list" item="item" separator="">
<if test="item.unitWeight != null">
WHEN material_name = #{item.materialName} THEN #{item.unitWeight}
</if>
</foreach>
ELSE unit_weight
END,
update_user = CASE
<foreach collection="list" item="item" separator="">
<if test="item.updateUser != null">
WHEN material_name = #{item.materialName} THEN #{item.updateUser}
</if>
</foreach>
ELSE update_user
END,
update_time = NOW()
</set>
WHERE material_name = #{item.materialName}
</if>
</trim>
WHERE material_name IN
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item.materialName}
</foreach>
</update>
<update id="updateByCode">
<foreach collection="list" item="item" separator=";">
UPDATE sys_material_info
<set>
<if test="item.materialName != null and item.materialName != ''">
material_name = #{item.materialName},
</if>
<if test="item.unitWeight != null">
unit_weight = #{item.unitWeight},
</if>
<if test="item.materialSpec != null and item.materialSpec != ''">
material_spec = #{item.materialSpec},
</if>
<if test="item.updateUser != null ">
update_user = #{item.updateUser},
</if>
UPDATE sys_material_info
<trim prefix="SET" suffixOverrides=",">
<if test="list != null and list.size() > 0">
material_name = CASE
<foreach collection="list" item="item" separator="">
<if test="item.materialName != null and item.materialName != ''">
WHEN encoding = #{item.encoding} THEN #{item.materialName}
</if>
</foreach>
ELSE material_name
END,
unit_weight = CASE
<foreach collection="list" item="item" separator="">
<if test="item.unitWeight != null">
WHEN encoding = #{item.encoding} THEN #{item.unitWeight}
</if>
</foreach>
ELSE unit_weight
END,
update_user = CASE
<foreach collection="list" item="item" separator="">
<if test="item.updateUser != null">
WHEN encoding = #{item.encoding} THEN #{item.updateUser}
</if>
</foreach>
ELSE update_user
END,
update_time = NOW()
</set>
WHERE encoding = #{item.encoding}
</if>
</trim>
WHERE encoding IN
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item.encoding}
</foreach>
</update>
@@ -70,4 +100,4 @@
${ew.customSqlSegment}
</select>
</mapper>
</mapper>

View File

@@ -2,32 +2,31 @@ package top.wms.admin.controller.materialProcess;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import top.continew.starter.core.validation.ValidationUtils;
import top.continew.starter.extension.crud.enums.Api;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import lombok.RequiredArgsConstructor;
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
import top.continew.starter.extension.crud.enums.Api;
import top.continew.starter.extension.crud.model.resp.LabelValueResp;
import top.continew.starter.log.annotation.Log;
import top.wms.admin.common.controller.BaseController;
import top.wms.admin.material.model.req.MaterialInfoImportReq;
import top.wms.admin.material.model.resp.MaterialImportParseResp;
import top.wms.admin.material.model.resp.MaterialInfoImportResp;
import top.wms.admin.materialProcess.model.query.MaterialProcessQuery;
import top.wms.admin.materialProcess.model.req.MaterialProcessImportReq;
import top.wms.admin.materialProcess.model.req.MaterialProcessReq;
import top.wms.admin.materialProcess.model.resp.MaterialProcessImportParseResp;
import top.wms.admin.materialProcess.model.resp.MaterialProcessImportResp;
import top.wms.admin.materialProcess.model.resp.MaterialProcessResp;
import top.wms.admin.materialProcess.service.MaterialProcessService;
import java.io.IOException;
import java.util.List;
/**
@@ -61,7 +60,7 @@ public class MaterialProcessController extends BaseController<MaterialProcessSer
@Operation(summary = "解析导入数据", description = "解析导入数据")
@SaCheckPermission("materialProcess:materialProcess:import")
@PostMapping("/import/parse")
public MaterialImportParseResp parseImport(@NotNull(message = "文件不能为空") MultipartFile file) {
public MaterialProcessImportParseResp parseImport(@NotNull(message = "文件不能为空") MultipartFile file) {
ValidationUtils.throwIf(file::isEmpty, "文件不能为空");
return baseService.parseImport(file);
}
@@ -69,8 +68,8 @@ public class MaterialProcessController extends BaseController<MaterialProcessSer
@Operation(summary = "导入数据", description = "导入数据")
@SaCheckPermission("materialProcess:materialProcess:import")
@PostMapping(value = "/import")
public MaterialInfoImportResp importUser(@Validated @RequestBody MaterialInfoImportReq req) {
return baseService.importMaterial(req);
public MaterialProcessImportResp importUser(@Validated @RequestBody MaterialProcessImportReq req) {
return baseService.importMaterialProcess(req);
}
}

View File

@@ -18,7 +18,7 @@ spring:
spring.datasource:
type: com.zaxxer.hikari.HikariDataSource
# 请务必提前创建好名为 wms_admin 的数据库,如果使用其他数据库名请注意同步修改 DB_NAME 配置
url: jdbc:p6spy:mysql://127.0.0.1:3306/wms?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&autoReconnect=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&allowMultiQueries=true
url: jdbc:p6spy:mysql://127.0.0.1:3306/wms?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&autoReconnect=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root
password: root
# PostgreSQL 配置

View File

@@ -14,7 +14,7 @@ server:
spring.datasource:
type: com.zaxxer.hikari.HikariDataSource
# 请务必提前创建好名为 wms_admin 的数据库,如果使用其他数据库名请注意同步修改 DB_NAME 配置
url: jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:wms_admin}?serverTimezone=Asia/Shanghai&useSSL=true&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&autoReconnect=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&allowMultiQueries=true
url: jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:wms_admin}?serverTimezone=Asia/Shanghai&useSSL=true&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&autoReconnect=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: ${DB_USER:root}
password: ${DB_PWD:123456}
driver-class-name: com.mysql.cj.jdbc.Driver