Commit aab8480265d8b1bbc2b9e54a65de6b4a45ee836c

Authored by YunaiV
1 parent 0d3d0b85

feat(mes): 新增供应商(md_vendor)模块完整功能

新增供应商管理的全套后端代码,参照客户(md_client)模块风格:
- DO/Mapper/Service/Controller 完整 CRUD
- 供应商导入功能(Excel 解析、逐行校验、创建或更新)
- 导入模板下载接口
- VO:SaveReqVO、RespVO、PageReqVO、ImportExcelVO、ImportRespVO
- 编码/名称/简称唯一性校验
- ErrorCodeConstants 新增供应商相关错误码(1_040_104_000~004)
- 权限:mes:md-vendor:{query,create,update,delete,export,import}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/MesMdVendorController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md;
  2 +
  3 +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  10 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorImportExcelVO;
  11 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorImportRespVO;
  12 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorPageReqVO;
  13 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorRespVO;
  14 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorSaveReqVO;
  15 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.MesMdVendorDO;
  16 +import cn.iocoder.yudao.module.mes.service.md.MesMdVendorService;
  17 +import io.swagger.v3.oas.annotations.Operation;
  18 +import io.swagger.v3.oas.annotations.Parameter;
  19 +import io.swagger.v3.oas.annotations.Parameters;
  20 +import io.swagger.v3.oas.annotations.tags.Tag;
  21 +import jakarta.annotation.Resource;
  22 +import jakarta.servlet.http.HttpServletResponse;
  23 +import jakarta.validation.Valid;
  24 +import org.springframework.security.access.prepost.PreAuthorize;
  25 +import org.springframework.validation.annotation.Validated;
  26 +import org.springframework.web.bind.annotation.*;
  27 +import org.springframework.web.multipart.MultipartFile;
  28 +
  29 +import java.io.IOException;
  30 +import java.util.Collections;
  31 +import java.util.List;
  32 +
  33 +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
  34 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  35 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  36 +
  37 +@Tag(name = "管理后台 - MES 供应商")
  38 +@RestController
  39 +@RequestMapping("/mes/md-vendor")
  40 +@Validated
  41 +public class MesMdVendorController {
  42 +
  43 + @Resource
  44 + private MesMdVendorService vendorService;
  45 +
  46 + @PostMapping("/create")
  47 + @Operation(summary = "创建供应商")
  48 + @PreAuthorize("@ss.hasPermission('mes:md-vendor:create')")
  49 + public CommonResult<Long> createVendor(@Valid @RequestBody MesMdVendorSaveReqVO createReqVO) {
  50 + return success(vendorService.createVendor(createReqVO));
  51 + }
  52 +
  53 + @PutMapping("/update")
  54 + @Operation(summary = "更新供应商")
  55 + @PreAuthorize("@ss.hasPermission('mes:md-vendor:update')")
  56 + public CommonResult<Boolean> updateVendor(@Valid @RequestBody MesMdVendorSaveReqVO updateReqVO) {
  57 + vendorService.updateVendor(updateReqVO);
  58 + return success(true);
  59 + }
  60 +
  61 + @DeleteMapping("/delete")
  62 + @Operation(summary = "删除供应商")
  63 + @Parameter(name = "id", description = "编号", required = true)
  64 + @PreAuthorize("@ss.hasPermission('mes:md-vendor:delete')")
  65 + public CommonResult<Boolean> deleteVendor(@RequestParam("id") Long id) {
  66 + vendorService.deleteVendor(id);
  67 + return success(true);
  68 + }
  69 +
  70 + @GetMapping("/get")
  71 + @Operation(summary = "获得供应商")
  72 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  73 + @PreAuthorize("@ss.hasPermission('mes:md-vendor:query')")
  74 + public CommonResult<MesMdVendorRespVO> getVendor(@RequestParam("id") Long id) {
  75 + MesMdVendorDO vendor = vendorService.getVendor(id);
  76 + return success(BeanUtils.toBean(vendor, MesMdVendorRespVO.class));
  77 + }
  78 +
  79 + @GetMapping("/page")
  80 + @Operation(summary = "获得供应商分页")
  81 + @PreAuthorize("@ss.hasPermission('mes:md-vendor:query')")
  82 + public CommonResult<PageResult<MesMdVendorRespVO>> getVendorPage(@Valid MesMdVendorPageReqVO pageReqVO) {
  83 + PageResult<MesMdVendorDO> pageResult = vendorService.getVendorPage(pageReqVO);
  84 + return success(BeanUtils.toBean(pageResult, MesMdVendorRespVO.class));
  85 + }
  86 +
  87 + @GetMapping("/simple-list")
  88 + @Operation(summary = "获得供应商精简列表", description = "只包含被开启的供应商,主要用于前端的下拉选项")
  89 + public CommonResult<List<MesMdVendorRespVO>> getVendorSimpleList() {
  90 + List<MesMdVendorDO> list = vendorService.getVendorListByStatus(CommonStatusEnum.ENABLE.getStatus());
  91 + return success(convertList(list, vendor -> new MesMdVendorRespVO()
  92 + .setId(vendor.getId()).setName(vendor.getName()).setCode(vendor.getCode())));
  93 + }
  94 +
  95 + @GetMapping("/export-excel")
  96 + @Operation(summary = "导出供应商 Excel")
  97 + @PreAuthorize("@ss.hasPermission('mes:md-vendor:export')")
  98 + @ApiAccessLog(operateType = EXPORT)
  99 + public void exportVendorExcel(@Valid MesMdVendorPageReqVO pageReqVO,
  100 + HttpServletResponse response) throws IOException {
  101 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  102 + List<MesMdVendorDO> list = vendorService.getVendorPage(pageReqVO).getList();
  103 + // 导出 Excel
  104 + ExcelUtils.write(response, "供应商.xls", "数据", MesMdVendorRespVO.class,
  105 + BeanUtils.toBean(list, MesMdVendorRespVO.class));
  106 + }
  107 +
  108 + @GetMapping("/get-import-template")
  109 + @Operation(summary = "获得供应商导入模板")
  110 + public void importTemplate(HttpServletResponse response) throws IOException {
  111 + // 手动创建导出 demo
  112 + List<MesMdVendorImportExcelVO> list = Collections.singletonList(
  113 + MesMdVendorImportExcelVO.builder().code("V001").name("示例供应商").nickname("示例")
  114 + .level("A").telephone("13800138000").status(0).build()
  115 + );
  116 + // 输出
  117 + ExcelUtils.write(response, "供应商导入模板.xls", "供应商列表", MesMdVendorImportExcelVO.class, list);
  118 + }
  119 +
  120 + @PostMapping("/import")
  121 + @Operation(summary = "导入供应商")
  122 + @Parameters({
  123 + @Parameter(name = "file", description = "Excel 文件", required = true),
  124 + @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
  125 + })
  126 + @PreAuthorize("@ss.hasPermission('mes:md-vendor:import')")
  127 + public CommonResult<MesMdVendorImportRespVO> importExcel(@RequestParam("file") MultipartFile file,
  128 + @RequestParam(value = "updateSupport", required = false,
  129 + defaultValue = "false") Boolean updateSupport) throws Exception {
  130 + List<MesMdVendorImportExcelVO> list = ExcelUtils.read(file, MesMdVendorImportExcelVO.class);
  131 + return success(vendorService.importVendorList(list, updateSupport));
  132 + }
  133 +
  134 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/vo/vendor/MesMdVendorImportExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor;
  2 +
  3 +import cn.idev.excel.annotation.ExcelProperty;
  4 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  5 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  6 +import cn.iocoder.yudao.module.mes.enums.DictTypeConstants;
  7 +import lombok.AllArgsConstructor;
  8 +import lombok.Builder;
  9 +import lombok.Data;
  10 +import lombok.NoArgsConstructor;
  11 +
  12 +/**
  13 + * 供应商 Excel 导入 VO
  14 + */
  15 +@Data
  16 +@Builder
  17 +@AllArgsConstructor
  18 +@NoArgsConstructor
  19 +public class MesMdVendorImportExcelVO {
  20 +
  21 + @ExcelProperty("供应商编码")
  22 + private String code;
  23 +
  24 + @ExcelProperty("供应商名称")
  25 + private String name;
  26 +
  27 + @ExcelProperty("供应商简称")
  28 + private String nickname;
  29 +
  30 + @ExcelProperty(value = "供应商等级", converter = DictConvert.class)
  31 + @DictFormat(DictTypeConstants.MES_VENDOR_LEVEL)
  32 + private String level;
  33 +
  34 + @ExcelProperty("供应商电话")
  35 + private String telephone;
  36 +
  37 + @ExcelProperty("供应商邮箱地址")
  38 + private String email;
  39 +
  40 + @ExcelProperty(value = "状态", converter = DictConvert.class)
  41 + @DictFormat(cn.iocoder.yudao.module.system.enums.DictTypeConstants.COMMON_STATUS)
  42 + private Integer status;
  43 +
  44 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/vo/vendor/MesMdVendorImportRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Builder;
  5 +import lombok.Data;
  6 +
  7 +import java.util.List;
  8 +import java.util.Map;
  9 +
  10 +@Schema(description = "管理后台 - MES 供应商导入 Response VO")
  11 +@Data
  12 +@Builder
  13 +public class MesMdVendorImportRespVO {
  14 +
  15 + @Schema(description = "创建成功的供应商编码数组", requiredMode = Schema.RequiredMode.REQUIRED)
  16 + private List<String> createCodes;
  17 +
  18 + @Schema(description = "更新成功的供应商编码数组", requiredMode = Schema.RequiredMode.REQUIRED)
  19 + private List<String> updateCodes;
  20 +
  21 + @Schema(description = "导入失败的供应商集合,key 为供应商编码,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED)
  22 + private Map<String, String> failureCodes;
  23 +
  24 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/vo/vendor/MesMdVendorPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +@Schema(description = "管理后台 - MES 供应商分页 Request VO")
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +@ToString(callSuper = true)
  13 +public class MesMdVendorPageReqVO extends PageParam {
  14 +
  15 + @Schema(description = "供应商编码", example = "V00101")
  16 + private String code;
  17 +
  18 + @Schema(description = "供应商名称", example = "海力德")
  19 + private String name;
  20 +
  21 + @Schema(description = "供应商简称", example = "海力德")
  22 + private String nickname;
  23 +
  24 + @Schema(description = "供应商等级", example = "A")
  25 + private String level;
  26 +
  27 + @Schema(description = "状态", example = "0")
  28 + private Integer status;
  29 +
  30 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/vo/vendor/MesMdVendorRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import cn.iocoder.yudao.module.mes.enums.DictTypeConstants;
  6 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  7 +import cn.idev.excel.annotation.ExcelProperty;
  8 +import io.swagger.v3.oas.annotations.media.Schema;
  9 +import lombok.Data;
  10 +
  11 +import java.time.LocalDateTime;
  12 +
  13 +@Schema(description = "管理后台 - MES 供应商 Response VO")
  14 +@Data
  15 +@ExcelIgnoreUnannotated
  16 +public class MesMdVendorRespVO {
  17 +
  18 + @Schema(description = "供应商编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  19 + @ExcelProperty("供应商编号")
  20 + private Long id;
  21 +
  22 + @Schema(description = "供应商编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "V00101")
  23 + @ExcelProperty("供应商编码")
  24 + private String code;
  25 +
  26 + @Schema(description = "供应商名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "海力德电子")
  27 + @ExcelProperty("供应商名称")
  28 + private String name;
  29 +
  30 + @Schema(description = "供应商简称", example = "海力德")
  31 + @ExcelProperty("供应商简称")
  32 + private String nickname;
  33 +
  34 + @Schema(description = "供应商英文名称", example = "HLD Electronics")
  35 + @ExcelProperty("供应商英文名称")
  36 + private String englishName;
  37 +
  38 + @Schema(description = "供应商简介", example = "专业从事电子元器件生产与销售")
  39 + @ExcelProperty("供应商简介")
  40 + private String description;
  41 +
  42 + @Schema(description = "供应商LOGO地址", example = "https://xxx.com/logo.png")
  43 + private String logo;
  44 +
  45 + @Schema(description = "供应商等级", example = "A")
  46 + @ExcelProperty(value = "供应商等级", converter = DictConvert.class)
  47 + @DictFormat(DictTypeConstants.MES_VENDOR_LEVEL)
  48 + private String level;
  49 +
  50 + @Schema(description = "供应商评分", example = "95")
  51 + @ExcelProperty("供应商评分")
  52 + private Integer score;
  53 +
  54 + @Schema(description = "供应商地址", example = "深圳市宝安区")
  55 + @ExcelProperty("供应商地址")
  56 + private String address;
  57 +
  58 + @Schema(description = "供应商官网地址", example = "https://www.hld-elec.com")
  59 + @ExcelProperty("供应商官网地址")
  60 + private String website;
  61 +
  62 + @Schema(description = "供应商邮箱地址", example = "info@hld-elec.com")
  63 + @ExcelProperty("供应商邮箱地址")
  64 + private String email;
  65 +
  66 + @Schema(description = "供应商电话", example = "0755-12345678")
  67 + @ExcelProperty("供应商电话")
  68 + private String telephone;
  69 +
  70 + @Schema(description = "联系人1", example = "王经理")
  71 + @ExcelProperty("联系人1")
  72 + private String contact1Name;
  73 +
  74 + @Schema(description = "联系人1-电话", example = "13800138001")
  75 + @ExcelProperty("联系人1-电话")
  76 + private String contact1Telephone;
  77 +
  78 + @Schema(description = "联系人1-邮箱", example = "wang@hld-elec.com")
  79 + @ExcelProperty("联系人1-邮箱")
  80 + private String contact1Email;
  81 +
  82 + @Schema(description = "联系人2", example = "赵助理")
  83 + @ExcelProperty("联系人2")
  84 + private String contact2Name;
  85 +
  86 + @Schema(description = "联系人2-电话", example = "13800138002")
  87 + @ExcelProperty("联系人2-电话")
  88 + private String contact2Telephone;
  89 +
  90 + @Schema(description = "联系人2-邮箱", example = "zhao@hld-elec.com")
  91 + @ExcelProperty("联系人2-邮箱")
  92 + private String contact2Email;
  93 +
  94 + @Schema(description = "统一社会信用代码", example = "91440300MA5EXAMPLE")
  95 + @ExcelProperty("统一社会信用代码")
  96 + private String creditCode;
  97 +
  98 + @Schema(description = "预留字段1")
  99 + private String attribute1;
  100 +
  101 + @Schema(description = "预留字段2")
  102 + private String attribute2;
  103 +
  104 + @Schema(description = "预留字段3")
  105 + private Integer attribute3;
  106 +
  107 + @Schema(description = "预留字段4")
  108 + private Integer attribute4;
  109 +
  110 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  111 + @ExcelProperty(value = "状态", converter = DictConvert.class)
  112 + @DictFormat(cn.iocoder.yudao.module.system.enums.DictTypeConstants.COMMON_STATUS)
  113 + private Integer status;
  114 +
  115 + @Schema(description = "备注", example = "备注")
  116 + @ExcelProperty("备注")
  117 + private String remark;
  118 +
  119 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  120 + @ExcelProperty("创建时间")
  121 + private LocalDateTime createTime;
  122 +
  123 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/vo/vendor/MesMdVendorSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotEmpty;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import lombok.Data;
  7 +
  8 +@Schema(description = "管理后台 - MES 供应商新增/修改 Request VO")
  9 +@Data
  10 +public class MesMdVendorSaveReqVO {
  11 +
  12 + @Schema(description = "供应商编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  13 + private Long id;
  14 +
  15 + @Schema(description = "供应商编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "V00101")
  16 + @NotEmpty(message = "供应商编码不能为空")
  17 + private String code;
  18 +
  19 + @Schema(description = "供应商名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "海力德电子")
  20 + @NotEmpty(message = "供应商名称不能为空")
  21 + private String name;
  22 +
  23 + @Schema(description = "供应商简称", example = "海力德")
  24 + private String nickname;
  25 +
  26 + @Schema(description = "供应商英文名称", example = "HLD Electronics")
  27 + private String englishName;
  28 +
  29 + @Schema(description = "供应商简介", example = "专业从事电子元器件生产与销售")
  30 + private String description;
  31 +
  32 + @Schema(description = "供应商LOGO地址", example = "https://xxx.com/logo.png")
  33 + private String logo;
  34 +
  35 + @Schema(description = "供应商等级", example = "A")
  36 + private String level;
  37 +
  38 + @Schema(description = "供应商评分", example = "95")
  39 + private Integer score;
  40 +
  41 + @Schema(description = "供应商地址", example = "深圳市宝安区")
  42 + private String address;
  43 +
  44 + @Schema(description = "供应商官网地址", example = "https://www.hld-elec.com")
  45 + private String website;
  46 +
  47 + @Schema(description = "供应商邮箱地址", example = "info@hld-elec.com")
  48 + private String email;
  49 +
  50 + @Schema(description = "供应商电话", example = "0755-12345678")
  51 + private String telephone;
  52 +
  53 + @Schema(description = "联系人1", example = "王经理")
  54 + private String contact1Name;
  55 +
  56 + @Schema(description = "联系人1-电话", example = "13800138001")
  57 + private String contact1Telephone;
  58 +
  59 + @Schema(description = "联系人1-邮箱", example = "wang@hld-elec.com")
  60 + private String contact1Email;
  61 +
  62 + @Schema(description = "联系人2", example = "赵助理")
  63 + private String contact2Name;
  64 +
  65 + @Schema(description = "联系人2-电话", example = "13800138002")
  66 + private String contact2Telephone;
  67 +
  68 + @Schema(description = "联系人2-邮箱", example = "zhao@hld-elec.com")
  69 + private String contact2Email;
  70 +
  71 + @Schema(description = "统一社会信用代码", example = "91440300MA5EXAMPLE")
  72 + private String creditCode;
  73 +
  74 + @Schema(description = "预留字段1")
  75 + private String attribute1;
  76 +
  77 + @Schema(description = "预留字段2")
  78 + private String attribute2;
  79 +
  80 + @Schema(description = "预留字段3")
  81 + private Integer attribute3;
  82 +
  83 + @Schema(description = "预留字段4")
  84 + private Integer attribute4;
  85 +
  86 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  87 + @NotNull(message = "状态不能为空")
  88 + private Integer status;
  89 +
  90 + @Schema(description = "备注", example = "备注")
  91 + private String remark;
  92 +
  93 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/md/MesMdVendorDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.md;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +/**
  10 + * MES 供应商 DO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@TableName("mes_md_vendor")
  15 +@KeySequence("mes_md_vendor_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
  22 +public class MesMdVendorDO extends BaseDO {
  23 +
  24 + /**
  25 + * 供应商编号
  26 + */
  27 + @TableId
  28 + private Long id;
  29 + /**
  30 + * 供应商编码
  31 + */
  32 + private String code;
  33 + /**
  34 + * 供应商名称
  35 + */
  36 + private String name;
  37 + /**
  38 + * 供应商简称
  39 + */
  40 + private String nickname;
  41 + /**
  42 + * 供应商英文名称
  43 + */
  44 + private String englishName;
  45 + /**
  46 + * 供应商简介
  47 + */
  48 + private String description;
  49 + /**
  50 + * 供应商LOGO地址
  51 + */
  52 + private String logo;
  53 + /**
  54 + * 供应商等级
  55 + *
  56 + * 字典 {@link cn.iocoder.yudao.module.mes.enums.DictTypeConstants#MES_VENDOR_LEVEL}
  57 + */
  58 + private String level;
  59 + /**
  60 + * 供应商评分
  61 + */
  62 + private Integer score;
  63 + /**
  64 + * 供应商地址
  65 + */
  66 + private String address;
  67 + /**
  68 + * 供应商官网地址
  69 + */
  70 + private String website;
  71 + /**
  72 + * 供应商邮箱地址
  73 + */
  74 + private String email;
  75 + /**
  76 + * 供应商电话
  77 + */
  78 + private String telephone;
  79 + /**
  80 + * 联系人1
  81 + */
  82 + private String contact1Name;
  83 + /**
  84 + * 联系人1-电话
  85 + */
  86 + private String contact1Telephone;
  87 + /**
  88 + * 联系人1-邮箱
  89 + */
  90 + private String contact1Email;
  91 + /**
  92 + * 联系人2
  93 + */
  94 + private String contact2Name;
  95 + /**
  96 + * 联系人2-电话
  97 + */
  98 + private String contact2Telephone;
  99 + /**
  100 + * 联系人2-邮箱
  101 + */
  102 + private String contact2Email;
  103 + /**
  104 + * 统一社会信用代码
  105 + */
  106 + private String creditCode;
  107 + /**
  108 + * 预留字段1
  109 + */
  110 + private String attribute1;
  111 + /**
  112 + * 预留字段2
  113 + */
  114 + private String attribute2;
  115 + /**
  116 + * 预留字段3
  117 + */
  118 + private Integer attribute3;
  119 + /**
  120 + * 预留字段4
  121 + */
  122 + private Integer attribute4;
  123 + /**
  124 + * 状态
  125 + *
  126 + * 枚举 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
  127 + */
  128 + private Integer status;
  129 + /**
  130 + * 备注
  131 + */
  132 + private String remark;
  133 +
  134 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/MesMdVendorMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.md;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorPageReqVO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.MesMdVendorDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * MES 供应商 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface MesMdVendorMapper extends BaseMapperX<MesMdVendorDO> {
  19 +
  20 + default PageResult<MesMdVendorDO> selectPage(MesMdVendorPageReqVO reqVO) {
  21 + return selectPage(reqVO, new LambdaQueryWrapperX<MesMdVendorDO>()
  22 + .eqIfPresent(MesMdVendorDO::getCode, reqVO.getCode())
  23 + .likeIfPresent(MesMdVendorDO::getName, reqVO.getName())
  24 + .likeIfPresent(MesMdVendorDO::getNickname, reqVO.getNickname())
  25 + .eqIfPresent(MesMdVendorDO::getLevel, reqVO.getLevel())
  26 + .eqIfPresent(MesMdVendorDO::getStatus, reqVO.getStatus())
  27 + .orderByDesc(MesMdVendorDO::getId));
  28 + }
  29 +
  30 + default MesMdVendorDO selectByCode(String code) {
  31 + return selectOne(MesMdVendorDO::getCode, code);
  32 + }
  33 +
  34 + default MesMdVendorDO selectByName(String name) {
  35 + return selectOne(MesMdVendorDO::getName, name);
  36 + }
  37 +
  38 + default MesMdVendorDO selectByNickname(String nickname) {
  39 + return selectOne(MesMdVendorDO::getNickname, nickname);
  40 + }
  41 +
  42 + default List<MesMdVendorDO> selectListByStatus(Integer status) {
  43 + return selectList(MesMdVendorDO::getStatus, status);
  44 + }
  45 +
  46 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -42,6 +42,7 @@ public interface ErrorCodeConstants { @@ -42,6 +42,7 @@ public interface ErrorCodeConstants {
42 ErrorCode MD_VENDOR_CODE_DUPLICATE = new ErrorCode(1_040_104_001, "供应商编码已存在"); 42 ErrorCode MD_VENDOR_CODE_DUPLICATE = new ErrorCode(1_040_104_001, "供应商编码已存在");
43 ErrorCode MD_VENDOR_NAME_DUPLICATE = new ErrorCode(1_040_104_002, "供应商名称已存在"); 43 ErrorCode MD_VENDOR_NAME_DUPLICATE = new ErrorCode(1_040_104_002, "供应商名称已存在");
44 ErrorCode MD_VENDOR_NICKNAME_DUPLICATE = new ErrorCode(1_040_104_003, "供应商简称已存在"); 44 ErrorCode MD_VENDOR_NICKNAME_DUPLICATE = new ErrorCode(1_040_104_003, "供应商简称已存在");
  45 + ErrorCode MD_VENDOR_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_040_104_004, "导入供应商数据不能为空");
45 46
46 // ========== MES 基础数据-车间(1-040-105-000) ========== 47 // ========== MES 基础数据-车间(1-040-105-000) ==========
47 ErrorCode MD_WORKSHOP_NOT_EXISTS = new ErrorCode(1_040_105_000, "车间不存在"); 48 ErrorCode MD_WORKSHOP_NOT_EXISTS = new ErrorCode(1_040_105_000, "车间不存在");
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/MesMdVendorService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorImportExcelVO;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorImportRespVO;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorPageReqVO;
  7 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorSaveReqVO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.MesMdVendorDO;
  9 +import jakarta.validation.Valid;
  10 +
  11 +import java.util.Collection;
  12 +import java.util.List;
  13 +import java.util.Map;
  14 +
  15 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  16 +
  17 +/**
  18 + * MES 供应商 Service 接口
  19 + *
  20 + * @author 芋道源码
  21 + */
  22 +public interface MesMdVendorService {
  23 +
  24 + /**
  25 + * 创建供应商
  26 + *
  27 + * @param createReqVO 创建信息
  28 + * @return 编号
  29 + */
  30 + Long createVendor(@Valid MesMdVendorSaveReqVO createReqVO);
  31 +
  32 + /**
  33 + * 更新供应商
  34 + *
  35 + * @param updateReqVO 更新信息
  36 + */
  37 + void updateVendor(@Valid MesMdVendorSaveReqVO updateReqVO);
  38 +
  39 + /**
  40 + * 删除供应商
  41 + *
  42 + * @param id 编号
  43 + */
  44 + void deleteVendor(Long id);
  45 +
  46 + /**
  47 + * 获得供应商
  48 + *
  49 + * @param id 编号
  50 + * @return 供应商
  51 + */
  52 + MesMdVendorDO getVendor(Long id);
  53 +
  54 + /**
  55 + * 获得供应商分页
  56 + *
  57 + * @param pageReqVO 分页查询
  58 + * @return 供应商分页
  59 + */
  60 + PageResult<MesMdVendorDO> getVendorPage(MesMdVendorPageReqVO pageReqVO);
  61 +
  62 + /**
  63 + * 获得指定状态的供应商列表
  64 + *
  65 + * @param status 状态
  66 + * @return 供应商列表
  67 + */
  68 + List<MesMdVendorDO> getVendorListByStatus(Integer status);
  69 +
  70 + /**
  71 + * 获得供应商列表
  72 + *
  73 + * @param ids 编号列表
  74 + * @return 供应商列表
  75 + */
  76 + List<MesMdVendorDO> getVendorList(Collection<Long> ids);
  77 +
  78 + /**
  79 + * 获得供应商 Map
  80 + *
  81 + * @param ids 编号列表
  82 + * @return 供应商 Map
  83 + */
  84 + default Map<Long, MesMdVendorDO> getVendorMap(Collection<Long> ids) {
  85 + return convertMap(getVendorList(ids), MesMdVendorDO::getId);
  86 + }
  87 +
  88 + /**
  89 + * 批量导入供应商
  90 + *
  91 + * @param importVendors 导入供应商列表
  92 + * @param updateSupport 是否支持更新
  93 + * @return 导入结果
  94 + */
  95 + MesMdVendorImportRespVO importVendorList(List<MesMdVendorImportExcelVO> importVendors, boolean updateSupport);
  96 +
  97 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/MesMdVendorServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjUtil;
  5 +import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.framework.common.exception.ServiceException;
  7 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorImportExcelVO;
  10 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorImportRespVO;
  11 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorPageReqVO;
  12 +import cn.iocoder.yudao.module.mes.controller.admin.md.vo.vendor.MesMdVendorSaveReqVO;
  13 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.MesMdVendorDO;
  14 +import cn.iocoder.yudao.module.mes.dal.mysql.md.MesMdVendorMapper;
  15 +import jakarta.annotation.Resource;
  16 +import org.springframework.stereotype.Service;
  17 +import org.springframework.transaction.annotation.Transactional;
  18 +import org.springframework.validation.annotation.Validated;
  19 +
  20 +import java.util.ArrayList;
  21 +import java.util.Collection;
  22 +import java.util.LinkedHashMap;
  23 +import java.util.List;
  24 +import java.util.concurrent.atomic.AtomicInteger;
  25 +
  26 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  27 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
  28 +
  29 +/**
  30 + * MES 供应商 Service 实现类
  31 + *
  32 + * @author 芋道源码
  33 + */
  34 +@Service
  35 +@Validated
  36 +public class MesMdVendorServiceImpl implements MesMdVendorService {
  37 +
  38 + @Resource
  39 + private MesMdVendorMapper vendorMapper;
  40 +
  41 + @Override
  42 + public Long createVendor(MesMdVendorSaveReqVO createReqVO) {
  43 + // 校验编码唯一
  44 + validateVendorCodeUnique(null, createReqVO.getCode());
  45 + // 校验名称唯一
  46 + validateVendorNameUnique(null, createReqVO.getName());
  47 + // 校验简称唯一
  48 + validateVendorNicknameUnique(null, createReqVO.getNickname());
  49 +
  50 + // 插入
  51 + MesMdVendorDO vendor = BeanUtils.toBean(createReqVO, MesMdVendorDO.class);
  52 + vendorMapper.insert(vendor);
  53 + return vendor.getId();
  54 + }
  55 +
  56 + @Override
  57 + public void updateVendor(MesMdVendorSaveReqVO updateReqVO) {
  58 + // 校验存在
  59 + validateVendorExists(updateReqVO.getId());
  60 + // 校验编码唯一
  61 + validateVendorCodeUnique(updateReqVO.getId(), updateReqVO.getCode());
  62 + // 校验名称唯一
  63 + validateVendorNameUnique(updateReqVO.getId(), updateReqVO.getName());
  64 + // 校验简称唯一
  65 + validateVendorNicknameUnique(updateReqVO.getId(), updateReqVO.getNickname());
  66 +
  67 + // 更新
  68 + MesMdVendorDO updateObj = BeanUtils.toBean(updateReqVO, MesMdVendorDO.class);
  69 + vendorMapper.updateById(updateObj);
  70 + }
  71 +
  72 + @Override
  73 + public void deleteVendor(Long id) {
  74 + // 校验存在
  75 + validateVendorExists(id);
  76 + // 删除
  77 + vendorMapper.deleteById(id);
  78 + }
  79 +
  80 + private void validateVendorExists(Long id) {
  81 + if (vendorMapper.selectById(id) == null) {
  82 + throw exception(MD_VENDOR_NOT_EXISTS);
  83 + }
  84 + }
  85 +
  86 + private void validateVendorCodeUnique(Long id, String code) {
  87 + MesMdVendorDO vendor = vendorMapper.selectByCode(code);
  88 + if (vendor == null) {
  89 + return;
  90 + }
  91 + if (ObjUtil.notEqual(vendor.getId(), id)) {
  92 + throw exception(MD_VENDOR_CODE_DUPLICATE);
  93 + }
  94 + }
  95 +
  96 + private void validateVendorNameUnique(Long id, String name) {
  97 + MesMdVendorDO vendor = vendorMapper.selectByName(name);
  98 + if (vendor == null) {
  99 + return;
  100 + }
  101 + if (ObjUtil.notEqual(vendor.getId(), id)) {
  102 + throw exception(MD_VENDOR_NAME_DUPLICATE);
  103 + }
  104 + }
  105 +
  106 + private void validateVendorNicknameUnique(Long id, String nickname) {
  107 + if (StrUtil.isEmpty(nickname)) {
  108 + return;
  109 + }
  110 + MesMdVendorDO vendor = vendorMapper.selectByNickname(nickname);
  111 + if (vendor == null) {
  112 + return;
  113 + }
  114 + if (ObjUtil.notEqual(vendor.getId(), id)) {
  115 + throw exception(MD_VENDOR_NICKNAME_DUPLICATE);
  116 + }
  117 + }
  118 +
  119 + @Override
  120 + public MesMdVendorDO getVendor(Long id) {
  121 + return vendorMapper.selectById(id);
  122 + }
  123 +
  124 + @Override
  125 + public PageResult<MesMdVendorDO> getVendorPage(MesMdVendorPageReqVO pageReqVO) {
  126 + return vendorMapper.selectPage(pageReqVO);
  127 + }
  128 +
  129 + @Override
  130 + public List<MesMdVendorDO> getVendorListByStatus(Integer status) {
  131 + return vendorMapper.selectListByStatus(status);
  132 + }
  133 +
  134 + @Override
  135 + public List<MesMdVendorDO> getVendorList(Collection<Long> ids) {
  136 + return vendorMapper.selectByIds(ids);
  137 + }
  138 +
  139 + @Override
  140 + @Transactional(rollbackFor = Exception.class)
  141 + public MesMdVendorImportRespVO importVendorList(List<MesMdVendorImportExcelVO> importVendors, boolean updateSupport) {
  142 + // 1. 参数校验
  143 + if (CollUtil.isEmpty(importVendors)) {
  144 + throw exception(MD_VENDOR_IMPORT_LIST_IS_EMPTY);
  145 + }
  146 +
  147 + // 2. 遍历,逐个创建 or 更新
  148 + MesMdVendorImportRespVO respVO = MesMdVendorImportRespVO.builder()
  149 + .createCodes(new ArrayList<>()).updateCodes(new ArrayList<>())
  150 + .failureCodes(new LinkedHashMap<>()).build();
  151 + AtomicInteger index = new AtomicInteger(1);
  152 + importVendors.forEach(importVendor -> {
  153 + int currentIndex = index.getAndIncrement();
  154 + // 2.1 校验字段
  155 + String key = StrUtil.blankToDefault(importVendor.getCode(), "第 " + currentIndex + " 行");
  156 + if (StrUtil.isBlank(importVendor.getCode())) {
  157 + respVO.getFailureCodes().put(key, "供应商编码不能为空");
  158 + return;
  159 + }
  160 + if (StrUtil.isBlank(importVendor.getName())) {
  161 + respVO.getFailureCodes().put(key, "供应商名称不能为空");
  162 + return;
  163 + }
  164 +
  165 + // 2.2 判断:创建 or 更新
  166 + MesMdVendorDO existVendor = vendorMapper.selectByCode(importVendor.getCode());
  167 + if (existVendor == null) {
  168 + // 2.2.1 创建
  169 + try {
  170 + validateVendorNameUnique(null, importVendor.getName());
  171 + validateVendorNicknameUnique(null, importVendor.getNickname());
  172 + } catch (ServiceException ex) {
  173 + respVO.getFailureCodes().put(key, ex.getMessage());
  174 + return;
  175 + }
  176 + MesMdVendorDO vendor = BeanUtils.toBean(importVendor, MesMdVendorDO.class);
  177 + vendorMapper.insert(vendor);
  178 + respVO.getCreateCodes().add(importVendor.getCode());
  179 + } else if (updateSupport) {
  180 + // 2.2.2 更新
  181 + try {
  182 + validateVendorNameUnique(existVendor.getId(), importVendor.getName());
  183 + validateVendorNicknameUnique(existVendor.getId(), importVendor.getNickname());
  184 + } catch (ServiceException ex) {
  185 + respVO.getFailureCodes().put(key, ex.getMessage());
  186 + return;
  187 + }
  188 + MesMdVendorDO updateObj = BeanUtils.toBean(importVendor, MesMdVendorDO.class);
  189 + updateObj.setId(existVendor.getId());
  190 + vendorMapper.updateById(updateObj);
  191 + respVO.getUpdateCodes().add(importVendor.getCode());
  192 + } else {
  193 + // 不支持更新
  194 + respVO.getFailureCodes().put(key, "供应商编码已存在");
  195 + }
  196 + });
  197 + return respVO;
  198 + }
  199 +
  200 +}