瀏覽代碼

产品库

24282 2 年之前
父節點
當前提交
676c9ec363

+ 66 - 0
hx-item/src/main/java/com/fjhx/item/controller/product/ProductClassifyController.java

@@ -0,0 +1,66 @@
+package com.fjhx.item.controller.product;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fjhx.item.entity.product.dto.ProductClassifyDto;
+import com.fjhx.item.entity.product.po.ProductClassify;
+import com.fjhx.item.service.product.ProductClassifyService;
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+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 java.util.List;
+
+
+/**
+ * <p>
+ * 产品分类 前端控制器
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-03-15
+ */
+@RestController
+@RequestMapping("/productClassify")
+public class ProductClassifyController {
+
+    @Autowired
+    private ProductClassifyService productClassifyService;
+
+    /**
+     * 产品分类树形
+     */
+    @PostMapping("/tree")
+    public List<JSONObject> tree(@Validated @RequestBody ProductClassify productClassify) {
+        List<JSONObject> tree = productClassifyService.tree(productClassify);
+        return tree;
+    }
+
+    /**
+     * 产品分类新增
+     */
+    @PostMapping("/add")
+    public void add(@Validated @RequestBody ProductClassifyDto productClassifyDto) {
+        productClassifyService.add(productClassifyDto);
+    }
+
+    /**
+     * 产品分类编辑
+     */
+    @PostMapping("/edit")
+    public void edit(@Validated @RequestBody ProductClassifyDto productClassifyDto) {
+        productClassifyService.edit(productClassifyDto);
+    }
+
+    /**
+     * 产品分类删除
+     */
+    @PostMapping("/delete")
+    public void delete(@RequestBody BaseSelectDto dto) {
+        productClassifyService.delete(dto.getId());
+    }
+
+}

+ 71 - 0
hx-item/src/main/java/com/fjhx/item/controller/product/ProductInfoController.java

@@ -0,0 +1,71 @@
+package com.fjhx.item.controller.product;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.item.entity.product.dto.ProductInfoDto;
+import com.fjhx.item.entity.product.dto.ProductInfoSelectDto;
+import com.fjhx.item.entity.product.vo.ProductInfoVo;
+import com.fjhx.item.service.product.ProductInfoService;
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import org.springframework.beans.factory.annotation.Autowired;
+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;
+
+
+/**
+ * <p>
+ * 产品库 前端控制器
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-03-17
+ */
+@RestController
+@RequestMapping("/productInfo")
+public class ProductInfoController {
+
+    @Autowired
+    private ProductInfoService productInfoService;
+
+    /**
+     * 产品库分页
+     */
+    @PostMapping("/page")
+    public Page<ProductInfoVo> page(@RequestBody ProductInfoSelectDto dto) {
+        return productInfoService.getPage(dto);
+    }
+
+    /**
+     * 产品库明细
+     */
+    @PostMapping("/detail")
+    public ProductInfoVo detail(@RequestBody BaseSelectDto dto) {
+        return productInfoService.detail(dto.getId());
+    }
+
+    /**
+     * 产品库新增
+     */
+    @PostMapping("/add")
+    public void add(@RequestBody ProductInfoDto productInfoDto) {
+        productInfoService.add(productInfoDto);
+    }
+
+    /**
+     * 产品库编辑
+     */
+    @PostMapping("/edit")
+    public void edit(@RequestBody ProductInfoDto productInfoDto) {
+        productInfoService.edit(productInfoDto);
+    }
+
+    /**
+     * 产品库删除
+     */
+    @PostMapping("/delete")
+    public void delete(@RequestBody BaseSelectDto dto) {
+        productInfoService.delete(dto.getId());
+    }
+
+}

+ 17 - 0
hx-item/src/main/java/com/fjhx/item/entity/product/dto/ProductClassifyDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.item.entity.product.dto;
+
+import com.fjhx.item.entity.product.po.ProductClassify;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 产品分类新增编辑入参实体
+ *
+ * @author zlj
+ * @since 2023-03-15
+ */
+@Getter
+@Setter
+public class ProductClassifyDto extends ProductClassify {
+
+}

+ 22 - 0
hx-item/src/main/java/com/fjhx/item/entity/product/dto/ProductInfoDto.java

@@ -0,0 +1,22 @@
+package com.fjhx.item.entity.product.dto;
+
+import com.fjhx.file.entity.ObsFile;
+import com.fjhx.item.entity.product.po.ProductInfo;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * 产品库新增编辑入参实体
+ *
+ * @author zlj
+ * @since 2023-03-17
+ */
+@Getter
+@Setter
+public class ProductInfoDto extends ProductInfo {
+
+    private List<ObsFile> fileList;
+
+}

+ 27 - 0
hx-item/src/main/java/com/fjhx/item/entity/product/dto/ProductInfoSelectDto.java

@@ -0,0 +1,27 @@
+package com.fjhx.item.entity.product.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 产品库列表查询入参实体
+ *
+ * @author zlj
+ * @since 2023-03-17
+ */
+@Getter
+@Setter
+public class ProductInfoSelectDto extends BaseSelectDto {
+
+    /**
+     * 产品类型
+     */
+    private Integer type;
+
+    /**
+     * 产品分类id
+     */
+    private Long productClassifyId;
+
+}

+ 44 - 0
hx-item/src/main/java/com/fjhx/item/entity/product/po/ProductClassify.java

@@ -0,0 +1,44 @@
+package com.fjhx.item.entity.product.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * <p>
+ * 产品分类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-03-15
+ */
+@Getter
+@Setter
+@TableName("product_classify")
+public class ProductClassify extends BasePo {
+
+    /**
+     * 定义 1产品 2物料
+     */
+    @NotNull(message = "定义不能为空")
+    private Integer definition;
+
+    /**
+     * 父级分类id
+     */
+    private Long parentId;
+
+    /**
+     * 父级分类id集合,用,拼接
+     */
+    private String parentIdSet;
+
+    /**
+     * 分类名称
+     */
+    private String name;
+
+}

+ 66 - 0
hx-item/src/main/java/com/fjhx/item/entity/product/po/ProductInfo.java

@@ -0,0 +1,66 @@
+package com.fjhx.item.entity.product.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 产品库
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-03-17
+ */
+@Getter
+@Setter
+@TableName("product_info")
+public class ProductInfo extends BasePo {
+
+    /**
+     * 定义 1产品 2物料
+     */
+    private Integer definition;
+
+    /**
+     * 产品分类id
+     */
+    private Long productClassifyId;
+
+    /**
+     * 产品编码
+     */
+    private String code;
+
+    /**
+     * 自定义编码
+     */
+    private String customCode;
+
+    /**
+     * 产品类型
+     */
+    private Integer type;
+
+    /**
+     * 产品名称
+     */
+    private String name;
+
+    /**
+     * 规格型号
+     */
+    private String spec;
+
+    /**
+     * 单位
+     */
+    private String unit;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+}

+ 17 - 0
hx-item/src/main/java/com/fjhx/item/entity/product/vo/ProductInfoVo.java

@@ -0,0 +1,17 @@
+package com.fjhx.item.entity.product.vo;
+
+import com.fjhx.item.entity.product.po.ProductInfo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 产品库列表查询返回值实体
+ *
+ * @author zlj
+ * @since 2023-03-17
+ */
+@Getter
+@Setter
+public class ProductInfoVo extends ProductInfo {
+
+}

+ 16 - 0
hx-item/src/main/java/com/fjhx/item/mapper/product/ProductClassifyMapper.java

@@ -0,0 +1,16 @@
+package com.fjhx.item.mapper.product;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fjhx.item.entity.product.po.ProductClassify;
+
+/**
+ * <p>
+ * 产品分类 Mapper 接口
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-03-15
+ */
+public interface ProductClassifyMapper extends BaseMapper<ProductClassify> {
+
+}

+ 26 - 0
hx-item/src/main/java/com/fjhx/item/mapper/product/ProductInfoMapper.java

@@ -0,0 +1,26 @@
+package com.fjhx.item.mapper.product;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.item.entity.product.po.ProductInfo;
+import com.fjhx.item.entity.product.vo.ProductInfoVo;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.apache.ibatis.annotations.Param;
+
+
+/**
+ * <p>
+ * 产品库 Mapper 接口
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-03-17
+ */
+public interface ProductInfoMapper extends BaseMapper<ProductInfo> {
+
+    /**
+     * 产品库分页
+     */
+    Page<ProductInfoVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<ProductInfo> wrapper);
+
+}

+ 42 - 0
hx-item/src/main/java/com/fjhx/item/service/product/ProductClassifyService.java

@@ -0,0 +1,42 @@
+package com.fjhx.item.service.product;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fjhx.item.entity.product.dto.ProductClassifyDto;
+import com.fjhx.item.entity.product.po.ProductClassify;
+import com.ruoyi.common.core.service.BaseService;
+
+import java.util.List;
+
+
+/**
+ * <p>
+ * 产品分类 服务类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-03-15
+ */
+public interface ProductClassifyService extends BaseService<ProductClassify> {
+
+    /**
+     * 产品分类树形
+     */
+    List<JSONObject> tree(ProductClassify productClassify);
+
+    /**
+     * 产品分类新增
+     */
+    void add(ProductClassifyDto productClassifyDto);
+
+    /**
+     * 产品分类编辑
+     */
+    void edit(ProductClassifyDto productClassifyDto);
+
+    /**
+     * 产品分类删除
+     */
+    void delete(Long id);
+
+
+}

+ 46 - 0
hx-item/src/main/java/com/fjhx/item/service/product/ProductInfoService.java

@@ -0,0 +1,46 @@
+package com.fjhx.item.service.product;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.item.entity.product.dto.ProductInfoDto;
+import com.fjhx.item.entity.product.dto.ProductInfoSelectDto;
+import com.fjhx.item.entity.product.po.ProductInfo;
+import com.fjhx.item.entity.product.vo.ProductInfoVo;
+import com.ruoyi.common.core.service.BaseService;
+
+
+/**
+ * <p>
+ * 产品库 服务类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-03-17
+ */
+public interface ProductInfoService extends BaseService<ProductInfo> {
+
+    /**
+     * 产品库分页
+     */
+    Page<ProductInfoVo> getPage(ProductInfoSelectDto dto);
+
+    /**
+     * 产品库明细
+     */
+    ProductInfoVo detail(Long id);
+
+    /**
+     * 产品库新增
+     */
+    void add(ProductInfoDto productInfoDto);
+
+    /**
+     * 产品库编辑
+     */
+    void edit(ProductInfoDto productInfoDto);
+
+    /**
+     * 产品库删除
+     */
+    void delete(Long id);
+
+}

+ 98 - 0
hx-item/src/main/java/com/fjhx/item/service/product/impl/ProductClassifyServiceImpl.java

@@ -0,0 +1,98 @@
+package com.fjhx.item.service.product.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.item.entity.product.dto.ProductClassifyDto;
+import com.fjhx.item.entity.product.po.ProductClassify;
+import com.fjhx.item.mapper.product.ProductClassifyMapper;
+import com.fjhx.item.service.product.ProductClassifyService;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.TreeUtil;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+
+/**
+ * <p>
+ * 产品分类 服务实现类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-03-15
+ */
+@Service
+public class ProductClassifyServiceImpl extends ServiceImpl<ProductClassifyMapper, ProductClassify> implements ProductClassifyService {
+
+    @Override
+    public List<JSONObject> tree(ProductClassify productClassify) {
+        // 分类名称
+        String name = productClassify.getName();
+
+        List<ProductClassify> list = lambdaQuery()
+                .select(ProductClassify::getId, ProductClassify::getName, ProductClassify::getParentId)
+                .eq(ProductClassify::getDefinition, productClassify.getDefinition())
+                .like(ObjectUtil.isNotEmpty(name), ProductClassify::getName, name)
+                .list();
+
+        // 构建树形
+        return TreeUtil.buildTree("name", list);
+    }
+
+    @Override
+    public void add(ProductClassifyDto productClassifyDto) {
+
+        Long parentId = productClassifyDto.getParentId();
+        if (parentId == null) {
+            productClassifyDto.setParentId(0L);
+            productClassifyDto.setParentIdSet(null);
+        } else if (parentId == 0L) {
+            productClassifyDto.setParentIdSet(null);
+        } else {
+            // 查询父级分类
+            ProductClassify parentClassify = getById(parentId);
+            if (parentClassify == null) {
+                throw new ServiceException("没有找到父级分类");
+            }
+
+            // 赋值父级id集合
+            String parentIdSet = parentClassify.getParentIdSet();
+            productClassifyDto.setParentIdSet((ObjectUtil.isEmpty(parentIdSet) ? "" : parentIdSet + ",") + parentId);
+        }
+
+        peerNameOnly(productClassifyDto.getDefinition(), productClassifyDto.getParentId(), productClassifyDto.getName(), null);
+
+        this.save(productClassifyDto);
+    }
+
+    @Override
+    public void edit(ProductClassifyDto productClassifyDto) {
+        peerNameOnly(productClassifyDto.getDefinition(), productClassifyDto.getParentId(), productClassifyDto.getName(), productClassifyDto.getId());
+        this.updateById(productClassifyDto);
+    }
+
+    @Override
+    public void delete(Long id) {
+        this.removeById(id);
+    }
+
+    /**
+     * 保证同级名称不重复
+     */
+    private void peerNameOnly(Integer type, Long parentId, String classifyName, Long excludeId) {
+
+        Long count = lambdaQuery()
+                .eq(ProductClassify::getParentId, parentId)
+                .eq(ProductClassify::getName, classifyName)
+                .eq(ProductClassify::getDefinition, type)
+                .ne(ObjectUtil.isNotEmpty(excludeId), ProductClassify::getId, excludeId)
+                .count();
+
+        if (count != 0) {
+            throw new ServiceException("存在相同分类名称");
+        }
+
+    }
+
+}

+ 82 - 0
hx-item/src/main/java/com/fjhx/item/service/product/impl/ProductInfoServiceImpl.java

@@ -0,0 +1,82 @@
+package com.fjhx.item.service.product.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.file.utils.ObsFileUtil;
+import com.fjhx.item.entity.product.dto.ProductInfoDto;
+import com.fjhx.item.entity.product.dto.ProductInfoSelectDto;
+import com.fjhx.item.entity.product.po.ProductInfo;
+import com.fjhx.item.entity.product.vo.ProductInfoVo;
+import com.fjhx.item.mapper.product.ProductInfoMapper;
+import com.fjhx.item.service.product.ProductInfoService;
+import com.fjhx.item.util.CodeEnum;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import com.ruoyi.common.utils.wrapper.SqlField;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+
+/**
+ * <p>
+ * 产品库 服务实现类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-03-17
+ */
+@Service
+public class ProductInfoServiceImpl extends ServiceImpl<ProductInfoMapper, ProductInfo> implements ProductInfoService {
+
+    @Override
+    public Page<ProductInfoVo> getPage(ProductInfoSelectDto dto) {
+        IWrapper<ProductInfo> wrapper = getWrapper();
+        wrapper.orderByDesc("pi", ProductInfo::getId);
+        wrapper.eq("pi", ProductInfo::getType, dto.getType());
+        wrapper.eq("pi", ProductInfo::getProductClassifyId, dto.getProductClassifyId());
+        wrapper.keyword(dto,
+                new SqlField("pi", ProductInfo::getName),
+                new SqlField("pi", ProductInfo::getCode),
+                new SqlField("pi", ProductInfo::getCustomCode)
+        );
+        Page<ProductInfoVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
+        return page;
+    }
+
+    @Override
+    public ProductInfoVo detail(Long id) {
+        ProductInfo ProductInfo = this.getById(id);
+        ProductInfoVo result = BeanUtil.toBean(ProductInfo, ProductInfoVo.class);
+        return result;
+    }
+
+    @Transactional
+    @Override
+    public void add(ProductInfoDto productInfoDto) {
+        // 赋值产品编号
+        productInfoDto.setCode(CodeEnum.PRODUCT.getCode());
+        // 排除名称重复
+        this.nameDuplication(ProductInfo::getName, productInfoDto.getName(), "产品名称重复");
+        this.save(productInfoDto);
+        ObsFileUtil.saveFile(productInfoDto.getFileList(), productInfoDto.getId());
+    }
+
+    @Transactional
+    @Override
+    public void edit(ProductInfoDto productInfoDto) {
+        // 禁止产品编号修改
+        productInfoDto.setCode(null);
+        // 排除名称重复
+        this.nameDuplication(ProductInfo::getName, productInfoDto.getName(), productInfoDto.getId(), "产品名称重复");
+        this.updateById(productInfoDto);
+        ObsFileUtil.editFile(productInfoDto.getFileList(), productInfoDto.getId());
+    }
+
+    @Transactional
+    @Override
+    public void delete(Long id) {
+        this.removeById(id);
+        ObsFileUtil.removeFile(id);
+    }
+
+}

+ 99 - 0
hx-item/src/main/java/com/fjhx/item/util/CodeEnum.java

@@ -0,0 +1,99 @@
+package com.fjhx.item.util;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fjhx.item.service.product.ProductInfoService;
+import com.ruoyi.common.exception.ServiceException;
+import lombok.Getter;
+
+import java.util.Date;
+import java.util.Map;
+
+@Getter
+public enum CodeEnum {
+
+    // 产品编码
+    PRODUCT("P", null, "code", 5, ProductInfoService.class),
+    ;
+
+    CodeEnum(String prefix, String dateFormat, String codeFieldName, Integer length, Class<? extends IService<?>> serviceCls) {
+        this.prefix = prefix;
+        this.dateFormat = dateFormat;
+        this.length = length;
+        this.codeFieldName = codeFieldName;
+        this.service = SpringUtil.getBean(serviceCls);
+    }
+
+    // 编码前缀
+    private final String prefix;
+    // 编码加日期规则
+    private final String dateFormat;
+    // 长度
+    private final Integer length;
+    // 编码字段名
+    private final String codeFieldName;
+    // service
+    private final IService<?> service;
+
+    /**
+     * 获取键值对
+     */
+    public String getCode() {
+        String itemPrefix;
+
+        if (ObjectUtil.isNotEmpty(dateFormat)) {
+            Date date = new Date();
+            String format = DateUtil.format(date, dateFormat);
+            itemPrefix = prefix + format;
+        } else {
+            itemPrefix = prefix;
+        }
+
+        Object obj = service.query()
+                .likeRight(codeFieldName, itemPrefix)
+                .orderByDesc(codeFieldName)
+                .last("limit 1")
+                .one();
+
+        if (obj == null) {
+            return itemPrefix + autoGenericCode(length, 0);
+        }
+
+        Map<String, Object> map = Convert.toMap(String.class, Object.class, obj);
+
+        String code = Convert.toStr(map.get(CharSequenceUtil.toCamelCase(codeFieldName)));
+        Integer codeNum = Convert.toInt(code.substring(itemPrefix.length()));
+        if (codeNum == null) {
+            throw new ServiceException("自定义编码与系统编码生成规则冲突,暂时无法生成编码,请联系管理员");
+        }
+
+        return itemPrefix + autoGenericCode(length, codeNum);
+    }
+
+    /**
+     * 获取键值对
+     */
+    public String getCode(String code) {
+        if (ObjectUtil.isNotEmpty(code)) {
+            Long count = service.query().eq(codeFieldName, code).count();
+            if (count != 0) {
+                throw new ServiceException("编码已存在");
+            }
+            return code;
+        } else {
+            return getCode();
+        }
+    }
+
+    /**
+     * 不够位数的在前面补0,保留num的长度位数字
+     */
+    private static String autoGenericCode(int length, Integer codeNum) {
+        return String.format("%0" + length + "d", codeNum + 1);
+    }
+
+}