liyong
2026-05-15 0578c6c76f13e367b5dc7d0882efe3c69ca4cb0e
feat(customer): 添加客户银行代码字段并实现批量删除功能

- 在Customer实体中添加bank_code字段映射
- 实现批量删除客户时同步清理关联的客户联系人关系
- 添加removeCustomerContactsByCustomerIds方法处理联系人关联删除逻辑
- 添加parseCustomerId辅助方法进行安全的ID解析
- 优化客户批量删除流程确保数据一致性
已修改17个文件
154 ■■■■ 文件已修改
src/main/java/com/ruoyi/basic/mapper/ProductModelMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/ProductServiceImpl.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/utils/OrderUtils.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/Workshop.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/domain/SysRole.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/pojo/StockInventoryCheckItem.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/pojo/StockInventoryCheckProduct.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/basic/CustomerMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/basic/ProductModelMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockInventoryMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/system/SysDeptMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/system/SysRoleMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/system/SysUserMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/mapper/ProductModelMapper.java
@@ -34,4 +34,6 @@
    IPage<ProductModelVo> pageModelAndQua(Page<ProductModelVo> page, @Param("c") ProductModel productModel);
    List<Map<String, Object>> selectBatchNoQtyByProductModelIds(@Param("list") List<Long> productModelIds);
    List<Map<String, Object>> selectUnqualifiedBatchNoQtyByProductModelIds(@Param("list") List<Long> productModelIds);
}
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -364,11 +364,55 @@
                    .eq(CustomerUser::getCustomerId, id)
            );
        }
        // 删除客户对应的联系人关联
        removeCustomerContactsByCustomerIds(idList);
        // 删除客户主表数据
        return customerMapper.deleteBatchIds(idList);
    }
    private void removeCustomerContactsByCustomerIds(List<Long> customerIds) {
        if (CollectionUtils.isEmpty(customerIds)) {
            return;
        }
        List<CustomerContact> customerContacts = customerContactMapper.selectList(new QueryWrapper<>());
        if (CollectionUtils.isEmpty(customerContacts)) {
            return;
        }
        Set<Long> customerIdSet = customerIds.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        for (CustomerContact customerContact : customerContacts) {
            String contactCustomerIds = customerContact.getCustomerId();
            if (StringUtils.isEmpty(contactCustomerIds)) {
                continue;
            }
            String updatedCustomerIds = Arrays.stream(contactCustomerIds.split(","))
                    .map(String::trim)
                    .filter(StringUtils::isNotEmpty)
                    .filter(id -> {
                        Long parsedId = parseCustomerId(id);
                        return parsedId == null || !customerIdSet.contains(parsedId);
                    })
                    .distinct()
                    .collect(Collectors.joining(","));
            if (StringUtils.isEmpty(updatedCustomerIds)) {
                customerContactMapper.deleteById(customerContact.getId());
            } else if (!updatedCustomerIds.equals(contactCustomerIds)) {
                customerContact.setCustomerId(updatedCustomerIds);
                customerContactMapper.updateById(customerContact);
            }
        }
    }
    private Long parseCustomerId(String customerId) {
        try {
            return Long.valueOf(customerId);
        } catch (NumberFormatException e) {
            return null;
        }
    }
    @Override
    public List<Customer> selectCustomerListByIds(Long[] ids) {
        LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();
src/main/java/com/ruoyi/basic/service/impl/ProductServiceImpl.java
@@ -86,6 +86,19 @@
        }
        List<Map<String, Object>> batchRows = productModelMapper.selectBatchNoQtyByProductModelIds(productModelIds);
        List<Map<String, Object>> unqualifiedBatchRows =
                productModelMapper.selectUnqualifiedBatchNoQtyByProductModelIds(productModelIds);
        batchRows.addAll(unqualifiedBatchRows);
        Map<Long, HashMap<String, HashMap<String, BigDecimal>>> batchNoQtyMapsByProductModelId =
                buildBatchNoQtyMaps(batchRows);
        for (ProductModelVo record : records) {
            record.setBatchNoMaps(toBatchNoMaps(
                    batchNoQtyMapsByProductModelId.getOrDefault(record.getId(), new HashMap<>())));
        }
    }
    private Map<Long, HashMap<String, HashMap<String, BigDecimal>>> buildBatchNoQtyMaps(
            List<Map<String, Object>> batchRows) {
        Map<Long, HashMap<String, HashMap<String, BigDecimal>>> batchNoQtyMapsByProductModelId = new HashMap<>();
        for (Map<String, Object> batchRow : batchRows) {
            Long productModelId = toLong(batchRow.get("productModelId"));
@@ -100,12 +113,12 @@
                    .computeIfAbsent(String.valueOf(warehouseId), key -> new HashMap<>())
                    .merge(batchNo, toBigDecimal(batchRow.get("qty")), BigDecimal::add);
        }
        return batchNoQtyMapsByProductModelId;
    }
        for (ProductModelVo record : records) {
    private HashMap<String, List<Map<String, BigDecimal>>> toBatchNoMaps(
            HashMap<String, HashMap<String, BigDecimal>> stockBatchNoQtyMaps) {
            HashMap<String, List<Map<String, BigDecimal>>> batchNoMaps = new HashMap<>();
            HashMap<String, HashMap<String, BigDecimal>> stockBatchNoQtyMaps =
                    batchNoQtyMapsByProductModelId.getOrDefault(record.getId(), new HashMap<>());
            for (Map.Entry<String, HashMap<String, BigDecimal>> entry : stockBatchNoQtyMaps.entrySet()) {
                List<Map<String, BigDecimal>> batchList = new ArrayList<>();
                for (Map.Entry<String, BigDecimal> batchEntry : entry.getValue().entrySet()) {
@@ -115,9 +128,7 @@
                }
                batchNoMaps.put(entry.getKey(), batchList);
            }
            record.setBatchNoMaps(batchNoMaps);
        }
        return batchNoMaps;
    }
    private Long toLong(Object value) {
src/main/java/com/ruoyi/common/utils/OrderUtils.java
@@ -78,6 +78,7 @@
        long nextSeq = 1;
        List<Map<String, Object>> records = mapper.selectMaps(wrapper);
        if (!records.isEmpty()) {
            Object lastCode = records.get(0).get(code);
            if (lastCode != null) {
src/main/java/com/ruoyi/production/pojo/Workshop.java
@@ -1,10 +1,10 @@
package com.ruoyi.production.pojo;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Data;
/**
 * 车间表
@@ -85,6 +85,9 @@
    @TableField(value = "update_user_name",fill = FieldFill.INSERT_UPDATE)
    private String updateUserName;
    @TableField(value = "dept_id",fill = FieldFill.INSERT)
    private Long deptId;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
src/main/java/com/ruoyi/project/system/domain/SysRole.java
@@ -1,14 +1,17 @@
package com.ruoyi.project.system.domain;
import java.util.Set;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
import com.ruoyi.framework.web.domain.BaseEntity;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
import com.ruoyi.framework.web.domain.BaseEntity;
import java.util.Set;
/**
 * 角色表 sys_role
@@ -64,6 +67,8 @@
    /** 角色菜单权限 */
    private Set<String> permissions;
    @TableField(fill = FieldFill.INSERT)
    private Long deptId;
    public SysRole()
    {
@@ -169,6 +174,16 @@
        this.status = status;
    }
    public Long getDeptId()
    {
        return deptId;
    }
    public void setDeptId(Long deptId)
    {
        this.deptId = deptId;
    }
    public String getDelFlag()
    {
        return delFlag;
src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java
@@ -1,9 +1,9 @@
package com.ruoyi.project.system.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.framework.aspectj.lang.annotation.DataScope;
import com.ruoyi.project.system.domain.SysRole;
import java.util.List;
/**
 * 角色表 数据层
@@ -18,6 +18,7 @@
     * @param role 角色信息
     * @return 角色数据集合信息
     */
    @DataScope(deptAlias = "r")
    public List<SysRole> selectRoleList(SysRole role);
    /**
src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java
@@ -1,6 +1,7 @@
package com.ruoyi.project.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.framework.aspectj.lang.annotation.DataScope;
import com.ruoyi.project.system.domain.SysUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -21,6 +22,7 @@
     * @param sysUser 用户信息
     * @return 用户信息集合信息
     */
    @DataScope(deptAlias = "u", userAlias = "u")
    public List<SysUser> selectUserList(SysUser sysUser);
    /**
src/main/java/com/ruoyi/stock/pojo/StockInventoryCheckItem.java
@@ -103,8 +103,6 @@
    /**
     * 备注
     */
@@ -127,5 +125,6 @@
    @TableField(exist = false)
    private String warehouseName;
    @TableField(fill = FieldFill.INSERT)
    private Long deptId;
}
src/main/java/com/ruoyi/stock/pojo/StockInventoryCheckProduct.java
@@ -71,5 +71,5 @@
    @TableField(fill = FieldFill.INSERT)
    private int createUser;
    @TableField(fill = FieldFill.INSERT)
    private int deptId;
    private Long deptId;
}
src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
@@ -25,7 +25,10 @@
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
/**
 * <p>
@@ -60,6 +63,11 @@
        } else {
            wrapper.eq(StockUninventory::getBatchNo, stockUninventoryDto.getBatchNo());
        }
        if (ObjectUtils.isEmpty(stockUninventoryDto.getBatchNo())) {
            String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmm"));
            int suffix = ThreadLocalRandom.current().nextInt(100, 1000);
            stockUninventoryDto.setBatchNo("PY" + time + suffix);
        }
        //新增入库记录再添加库存
        StockInRecordDto stockInRecordDto = new StockInRecordDto();
        stockInRecordDto.setRecordId(stockUninventoryDto.getRecordId());
src/main/resources/mapper/basic/CustomerMapper.xml
@@ -28,6 +28,7 @@
        c.maintenance_time,
        c.tenant_id,
        c.type,
        c.bank_code,
        c.is_assigned,
        c.usage_user,
        c.basic_bank_account,
src/main/resources/mapper/basic/ProductModelMapper.xml
@@ -203,4 +203,20 @@
        order by si.product_model_id, si.warehouse_info_id, si.batch_no, si.id
    </select>
    <select id="selectUnqualifiedBatchNoQtyByProductModelIds" resultType="java.util.Map">
        select su.product_model_id as productModelId,
               su.warehouse_info_id as warehouseId,
               su.batch_no as batchNo,
               su.qualitity as qty
        from stock_uninventory su
        where su.product_model_id in
        <foreach collection="list" item="productModelId" separator="," open="(" close=")">
            #{productModelId}
        </foreach>
          and su.warehouse_info_id is not null
          and su.batch_no is not null
          and su.batch_no != ''
        order by su.product_model_id, su.warehouse_info_id, su.batch_no, su.id
    </select>
</mapper>
src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -203,8 +203,8 @@
            0 as qualifiedLockedQuantity,
            COALESCE(su.locked_quantity, 0) as unQualifiedLockedQuantity,
            su.product_model_id,
            null as warehouse_info_id,
            null as warehouse_name,
            su.warehouse_info_id,
            siw.warehouse_name,
            su.create_time,
            su.update_time,
            0 as warn_num,
@@ -227,6 +227,7 @@
            from stock_uninventory su
            left join product_model pm on su.product_model_id = pm.id
            left join product p on pm.product_id = p.id
            left join stock_warehouse_info siw on su.warehouse_info_id = siw.id
        ) as combined
        <where>
            <if test="ew.productName != null and ew.productName !=''">
src/main/resources/mapper/system/SysDeptMapper.xml
@@ -47,7 +47,7 @@
            AND d.status = #{status}
        </if>
        <!-- 数据范围过滤 -->
        ${params.dataScope}
--         ${params.dataScope}
        group by d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time
        order by d.parent_id, d.order_num
    </select>
src/main/resources/mapper/system/SysRoleMapper.xml
@@ -51,7 +51,7 @@
            and date_format(r.create_time,'%Y%m%d') &lt;= date_format(#{params.endTime},'%Y%m%d')
        </if>
        <!-- 数据范围过滤 -->
        ${params.dataScope}
--         ${params.dataScope}
        order by r.role_sort
    </select>
    
src/main/resources/mapper/system/SysUserMapper.xml
@@ -96,7 +96,7 @@
            )
        </if>
        <!-- 数据范围过滤 -->
        ${params.dataScope}
--         ${params.dataScope}
    </select>
    <select id="selectAllocatedList" parameterType="com.ruoyi.project.system.domain.SysUser" resultMap="SysUserResult">
@@ -112,7 +112,7 @@
            AND u.phonenumber like concat('%', #{phonenumber}, '%')
        </if>
        <!-- 数据范围过滤 -->
        ${params.dataScope}
--         ${params.dataScope}
    </select>
    <select id="selectUnallocatedList" parameterType="com.ruoyi.project.system.domain.SysUser" resultMap="SysUserResult">
@@ -129,7 +129,7 @@
            AND u.phonenumber like concat('%', #{phonenumber}, '%')
        </if>
        <!-- 数据范围过滤 -->
        ${params.dataScope}
--         ${params.dataScope}
    </select>
    <select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">