新增供应商类型配置

This commit is contained in:
liuminghui
2026-10-27 11:40:22 +08:00
parent f3fa3e1396
commit 7e53b41a3c
9 changed files with 812 additions and 18 deletions
@@ -0,0 +1,112 @@
package com.bms.system.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.bms.common.annotation.Excel;
import com.bms.common.core.domain.BaseEntity;
/**
* 供应商类型 bms_supplier_type
* 类型编码与字典 bms_supplier_type 的字典键值一致,供供应商档案引用。
*
* @author bms
*/
public class BmsSupplierType extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 类型ID */
private Long typeId;
/** 类型编码(字典键值) */
@Excel(name = "类型编码")
private String typeCode;
/** 类型名称 */
@Excel(name = "类型名称")
private String typeName;
/** 显示排序 */
@Excel(name = "显示排序")
private Integer typeSort;
/** 状态(0正常 1停用) */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 删除标记(0存在 1删除) */
private String delFlag;
public Long getTypeId()
{
return typeId;
}
public void setTypeId(Long typeId)
{
this.typeId = typeId;
}
public String getTypeCode()
{
return typeCode;
}
public void setTypeCode(String typeCode)
{
this.typeCode = typeCode;
}
public String getTypeName()
{
return typeName;
}
public void setTypeName(String typeName)
{
this.typeName = typeName;
}
public Integer getTypeSort()
{
return typeSort;
}
public void setTypeSort(Integer typeSort)
{
this.typeSort = typeSort;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getDelFlag()
{
return delFlag;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
@Override
public String toString()
{
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("typeId", getTypeId())
.append("typeCode", getTypeCode())
.append("typeName", getTypeName())
.append("typeSort", getTypeSort())
.append("status", getStatus())
.append("remark", getRemark())
.toString();
}
}
@@ -0,0 +1,112 @@
package com.bms.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.bms.system.domain.BmsSupplierType;
/**
* 供应商类型数据层
*
* @author bms
*/
public interface BmsSupplierTypeMapper
{
/**
* 按名称、状态查询供应商类型
*
* @param query 查询条件
* @return 类型列表
*/
List<BmsSupplierType> selectList(BmsSupplierType query);
/**
* 按主键查询未删除的类型
*
* @param typeId 类型ID
* @return 类型
*/
BmsSupplierType selectById(Long typeId);
/**
* 统计未删除的同编码数量
*
* @param typeCode 类型编码
* @param excludeId 排除的类型ID,新增时为空
* @return 数量
*/
int countByTypeCode(@Param("typeCode") String typeCode, @Param("excludeId") Long excludeId);
/**
* 统计未删除的同名称数量
*
* @param typeName 类型名称
* @param excludeId 排除的类型ID,新增时为空
* @return 数量
*/
int countByTypeName(@Param("typeName") String typeName, @Param("excludeId") Long excludeId);
/**
* 新增供应商类型
*
* @param row 类型
* @return 影响行数
*/
int insert(BmsSupplierType row);
/**
* 修改供应商类型(不改编码,避免已引用的供应商失联)
*
* @param row 类型
* @return 影响行数
*/
int update(BmsSupplierType row);
/**
* 只更新启用状态
*
* @param row 含 typeId、status、updateBy
* @return 影响行数
*/
int updateStatus(BmsSupplierType row);
/**
* 逻辑删除
*
* @param typeIds 类型ID
* @return 影响行数
*/
int deleteByIds(Long[] typeIds);
/**
* 按字典类型和键值取字典编码
*
* @param dictType 字典类型
* @param dictValue 字典键值
* @return 字典编码,不存在时为空
*/
Long selectDictCode(@Param("dictType") String dictType, @Param("dictValue") String dictValue);
/**
* 写入字典数据
*
* @param row 类型,字典类型由调用方放入 remark 以外的固定值,见 XML
* @return 影响行数
*/
int insertDict(BmsSupplierType row);
/**
* 按类型编码更新字典标签、排序和状态
*
* @param row 类型
* @return 影响行数
*/
int updateDict(BmsSupplierType row);
/**
* 按类型编码删除字典数据
*
* @param typeCode 类型编码
* @return 影响行数
*/
int deleteDictByCode(String typeCode);
}
@@ -0,0 +1,60 @@
package com.bms.system.service;
import java.util.List;
import com.bms.system.domain.BmsSupplierType;
/**
* 供应商类型服务
*
* @author bms
*/
public interface IBmsSupplierTypeService
{
/**
* 分页前的条件查询,分页由调用方开启
*
* @param query 名称、状态
* @return 类型列表
*/
List<BmsSupplierType> selectList(BmsSupplierType query);
/**
* 查询单个类型
*
* @param typeId 类型ID
* @return 类型
*/
BmsSupplierType selectById(Long typeId);
/**
* 新增类型,并同步字典 bms_supplier_type
*
* @param row 类型
* @return 影响行数
*/
int insert(BmsSupplierType row);
/**
* 修改类型名称、排序、状态、备注,并同步字典
*
* @param row 类型
* @return 影响行数
*/
int update(BmsSupplierType row);
/**
* 启用或停用,并同步字典状态
*
* @param row 含 typeId 与 status
* @return 影响行数
*/
int changeStatus(BmsSupplierType row);
/**
* 逻辑删除,并从字典中移除对应键值
*
* @param typeIds 类型ID
* @return 影响行数
*/
int deleteByIds(Long[] typeIds);
}
@@ -0,0 +1,232 @@
package com.bms.system.service.impl;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.bms.common.core.domain.entity.SysDictData;
import com.bms.common.exception.ServiceException;
import com.bms.common.utils.DictUtils;
import com.bms.common.utils.StringUtils;
import com.bms.system.domain.BmsSupplierType;
import com.bms.system.mapper.BmsSupplierTypeMapper;
import com.bms.system.mapper.SysDictDataMapper;
import com.bms.system.service.IBmsSupplierTypeService;
/**
* 供应商类型服务实现。
* 供应商类型服务实现。_DETAIL
*
* @author bms
*/
@Service
public class BmsSupplierTypeServiceImpl implements IBmsSupplierTypeService
{
/** 字典类型,与系统字典管理中的类型编码一致 */
public static final String DICT_TYPE = "bms_supplier_type";
@Autowired
private BmsSupplierTypeMapper supplierTypeMapper;
@Autowired
private SysDictDataMapper dictDataMapper;
@Override
public List<BmsSupplierType> selectList(BmsSupplierType query)
{
return supplierTypeMapper.selectList(query);
}
@Override
public BmsSupplierType selectById(Long typeId)
{
return supplierTypeMapper.selectById(typeId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int insert(BmsSupplierType row)
{
normalize(row);
validate(row, null);
if (row.getTypeSort() == null)
{
row.setTypeSort(0);
}
if (StringUtils.isEmpty(row.getStatus()))
{
row.setStatus("0");
}
int rows = supplierTypeMapper.insert(row);
syncDict(row);
return rows;
}
@Override
@Transactional(rollbackFor = Exception.class)
public int update(BmsSupplierType row)
{
if (row.getTypeId() == null)
{
throw new ServiceException("类型ID不能为空");
}
BmsSupplierType existing = requireActive(row.getTypeId());
normalize(row);
if (StringUtils.isEmpty(row.getTypeName()))
{
row.setTypeName(existing.getTypeName());
}
if (row.getTypeSort() == null)
{
row.setTypeSort(existing.getTypeSort());
}
if (StringUtils.isEmpty(row.getStatus()))
{
row.setStatus(existing.getStatus());
}
validateNameAndStatus(row, row.getTypeId());
row.setTypeCode(existing.getTypeCode());
int rows = supplierTypeMapper.update(row);
syncDict(row);
return rows;
}
@Override
@Transactional(rollbackFor = Exception.class)
public int changeStatus(BmsSupplierType row)
{
if (row.getTypeId() == null)
{
throw new ServiceException("类型ID不能为空");
}
if (!"0".equals(row.getStatus()) && !"1".equals(row.getStatus()))
{
throw new ServiceException("状态只能是正常或停用");
}
BmsSupplierType existing = requireActive(row.getTypeId());
existing.setStatus(row.getStatus());
existing.setUpdateBy(row.getUpdateBy());
int rows = supplierTypeMapper.updateStatus(existing);
syncDict(existing);
return rows;
}
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteByIds(Long[] typeIds)
{
if (typeIds == null || typeIds.length == 0)
{
return 0;
}
for (Long typeId : typeIds)
{
BmsSupplierType existing = supplierTypeMapper.selectById(typeId);
if (existing != null && StringUtils.isNotEmpty(existing.getTypeCode()))
{
supplierTypeMapper.deleteDictByCode(existing.getTypeCode());
}
}
int rows = supplierTypeMapper.deleteByIds(typeIds);
refreshDictCache();
return rows;
}
/**
* 校验编码、名称唯一,并整理状态
*/
private void validate(BmsSupplierType row, Long excludeId)
{
if (StringUtils.isEmpty(row.getTypeCode()))
{
throw new ServiceException("类型编码不能为空");
}
if (!row.getTypeCode().matches("[0-9A-Za-z_-]{1,32}"))
{
throw new ServiceException("类型编码只能是字母、数字、下划线或中划线,最长32位");
}
if (supplierTypeMapper.countByTypeCode(row.getTypeCode(), excludeId) > 0)
{
throw new ServiceException("类型编码已存在:" + row.getTypeCode());
}
validateNameAndStatus(row, excludeId);
}
private void validateNameAndStatus(BmsSupplierType row, Long excludeId)
{
if (StringUtils.isEmpty(row.getTypeName()))
{
throw new ServiceException("类型名称不能为空");
}
if (row.getTypeName().length() > 100)
{
throw new ServiceException("类型名称不能超过100个字符");
}
if (supplierTypeMapper.countByTypeName(row.getTypeName(), excludeId) > 0)
{
throw new ServiceException("类型名称已存在:" + row.getTypeName());
}
if (StringUtils.isNotEmpty(row.getStatus())
&& !"0".equals(row.getStatus()) && !"1".equals(row.getStatus()))
{
throw new ServiceException("状态只能是正常或停用");
}
}
private BmsSupplierType requireActive(Long typeId)
{
BmsSupplierType existing = supplierTypeMapper.selectById(typeId);
if (existing == null)
{
throw new ServiceException("供应商类型不存在或已删除");
}
return existing;
}
private void normalize(BmsSupplierType row)
{
if (row.getTypeCode() != null)
{
row.setTypeCode(row.getTypeCode().trim());
}
if (row.getTypeName() != null)
{
row.setTypeName(row.getTypeName().trim());
}
if (row.getRemark() != null)
{
row.setRemark(row.getRemark().trim());
}
}
/**
* 按类型编码新增或更新字典项,并刷新该字典缓存
*/
private void syncDict(BmsSupplierType row)
{
Long dictCode = supplierTypeMapper.selectDictCode(DICT_TYPE, row.getTypeCode());
if (dictCode == null)
{
if (StringUtils.isEmpty(row.getCreateBy()))
{
row.setCreateBy(row.getUpdateBy());
}
supplierTypeMapper.insertDict(row);
}
else
{
supplierTypeMapper.updateDict(row);
}
refreshDictCache();
}
/**
* 只缓存正常状态的字典项,停用后下拉不再出现
*/
private void refreshDictCache()
{
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(DICT_TYPE);
DictUtils.setDictCache(DICT_TYPE, dictDatas == null ? new ArrayList<SysDictData>() : dictDatas);
}
}
@@ -0,0 +1,130 @@
<?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="com.bms.system.mapper.BmsSupplierTypeMapper">
<resultMap type="BmsSupplierType" id="BmsSupplierTypeResult">
<id property="typeId" column="type_id" />
<result property="typeCode" column="type_code" />
<result property="typeName" column="type_name" />
<result property="typeSort" column="type_sort" />
<result property="status" column="status" />
<result property="remark" column="remark" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="delFlag" column="del_flag" />
</resultMap>
<sql id="selectVo">
select type_id, type_code, type_name, type_sort, status, remark,
create_by, create_time, update_by, update_time, del_flag
from bms_supplier_type
</sql>
<select id="selectList" parameterType="BmsSupplierType" resultMap="BmsSupplierTypeResult">
<include refid="selectVo"/>
<where>
del_flag = '0'
<if test="typeName != null and typeName != ''">
and type_name like concat('%', #{typeName}, '%')
</if>
<if test="status != null and status != ''">
and status = #{status}
</if>
</where>
order by type_sort asc, type_id asc
</select>
<select id="selectById" parameterType="Long" resultMap="BmsSupplierTypeResult">
<include refid="selectVo"/>
where type_id = #{typeId} and del_flag = '0'
</select>
<select id="countByTypeCode" resultType="int">
select count(1) from bms_supplier_type
where del_flag = '0' and type_code = #{typeCode}
<if test="excludeId != null">and type_id != #{excludeId}</if>
</select>
<select id="countByTypeName" resultType="int">
select count(1) from bms_supplier_type
where del_flag = '0' and type_name = #{typeName}
<if test="excludeId != null">and type_id != #{excludeId}</if>
</select>
<insert id="insert" parameterType="BmsSupplierType" useGeneratedKeys="true" keyProperty="typeId">
insert into bms_supplier_type (
type_code, type_name, type_sort, status, remark, create_by, create_time, del_flag
) values (
#{typeCode}, #{typeName}, #{typeSort}, #{status}, #{remark}, #{createBy}, sysdate(), '0'
)
</insert>
<update id="update" parameterType="BmsSupplierType">
update bms_supplier_type
<set>
<if test="typeName != null and typeName != ''">type_name = #{typeName},</if>
<if test="typeSort != null">type_sort = #{typeSort},</if>
<if test="status != null and status != ''">status = #{status},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
update_time = sysdate()
</set>
where type_id = #{typeId} and del_flag = '0'
</update>
<update id="updateStatus" parameterType="BmsSupplierType">
update bms_supplier_type
set status = #{status},
update_by = #{updateBy},
update_time = sysdate()
where type_id = #{typeId} and del_flag = '0'
</update>
<update id="deleteByIds" parameterType="Long">
update bms_supplier_type
set del_flag = '1',
type_code = concat(type_code, '#', type_id),
type_name = concat(type_name, '#', type_id),
update_time = sysdate()
where del_flag = '0' and type_id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</update>
<select id="selectDictCode" resultType="java.lang.Long">
select dict_code from sys_dict_data
where dict_type = #{dictType} and dict_value = #{dictValue}
limit 1
</select>
<insert id="insertDict" parameterType="BmsSupplierType">
insert into sys_dict_data (
dict_sort, dict_label, dict_value, dict_type, css_class, list_class,
is_default, status, create_by, create_time, remark
) values (
#{typeSort}, #{typeName}, #{typeCode}, 'bms_supplier_type', '', 'primary',
'N', #{status}, #{createBy}, sysdate(), #{remark}
)
</insert>
<update id="updateDict" parameterType="BmsSupplierType">
update sys_dict_data
set dict_sort = #{typeSort},
dict_label = #{typeName},
status = #{status},
remark = #{remark},
update_by = #{updateBy},
update_time = sysdate()
where dict_type = 'bms_supplier_type' and dict_value = #{typeCode}
</update>
<delete id="deleteDictByCode">
delete from sys_dict_data
where dict_type = 'bms_supplier_type' and dict_value = #{typeCode}
</delete>
</mapper>