Browse Source

feat(firm-info): 新增企业信息关联部门选择功能

- 后端新增获取可用部门选项接口,支持编辑时排除指定企业ID
- 服务层实现排除已被企业/渠道占用部门的可用部门过滤逻辑
- 前端新增新增企业弹窗,包含部门选择和类型选择功能
- 部门选择组件支持树结构展示和搜索过滤
- 新增按钮改为自定义工具栏按钮,弹出自定义新增对话框
- 新增表单字段校验和异步提交接口调用
- 移除企业实体及表单中的企业编号相关字段及映射
- 优化列表工具栏配置,移除默认新增按钮,适配新弹窗使用方式
SheepHy 2 ngày trước cách đây
mục cha
commit
6abee92770

+ 11 - 0
src/main/java/com/zsElectric/boot/business/controller/FirmInfoController.java

@@ -14,6 +14,7 @@ import com.zsElectric.boot.business.model.vo.FirmInfoVO;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.zsElectric.boot.core.web.PageResult;
 import com.zsElectric.boot.core.web.Result;
+import com.zsElectric.boot.common.model.Option;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.Operation;
@@ -129,4 +130,14 @@ public class FirmInfoController  {
         boolean result = firmInfoService.changeBalance(form);
         return Result.judge(result);
     }
+
+    @Operation(summary = "获取可用部门选项(用于新增/编辑企业信息时选择关联部门)")
+    @GetMapping("/availableDeptOptions")
+    @PreAuthorize("@ss.hasPerm('business:firmInfo:add') or @ss.hasPerm('business:firmInfo:edit')")
+    public Result<List<Option<Long>>> getAvailableDeptOptions(
+            @Parameter(description = "编辑时排除的企业ID") @RequestParam(required = false) Long excludeId
+    ) {
+        List<Option<Long>> options = firmInfoService.getAvailableDeptOptions(excludeId);
+        return Result.success(options);
+    }
 }

+ 0 - 4
src/main/java/com/zsElectric/boot/business/model/entity/FirmInfo.java

@@ -33,10 +33,6 @@ public class FirmInfo extends BaseEntity {
      * B端企业名称
      */
     private String name;
-    /**
-     * 企业编号
-     */
-    private String number;
     /**
      * 状态 0 已下线  1 上线中
      */

+ 0 - 4
src/main/java/com/zsElectric/boot/business/model/form/FirmInfoForm.java

@@ -36,10 +36,6 @@ public class FirmInfoForm implements Serializable {
     @Size(max=30, message="B端企业名称长度不能超过30个字符")
     private String name;
 
-    @Schema(description = "企业编号")
-    @Size(max=20, message="企业编号长度不能超过20个字符")
-    private String number;
-
     @Schema(description = "状态 0 已下线  1 上线中")
     private Integer status;
 

+ 0 - 2
src/main/java/com/zsElectric/boot/business/model/vo/FirmInfoVO.java

@@ -32,8 +32,6 @@ public class FirmInfoVO implements Serializable {
     private String name;
     @Schema(description = "员工数")
     private Integer empNum;
-    @Schema(description = "企业编号")
-    private String number;
     @Schema(description = "状态 0 已下线  1 上线中")
     private Integer status;
     @Schema(description = "当前余额")

+ 9 - 0
src/main/java/com/zsElectric/boot/business/service/FirmInfoService.java

@@ -9,6 +9,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 
 import java.math.BigDecimal;
+import java.util.List;
+import com.zsElectric.boot.common.model.Option;
 
 /**
  * 企业信息服务类
@@ -86,4 +88,11 @@ public interface FirmInfoService extends IService<FirmInfo> {
      */
     boolean changeBalance(FirmBalanceChangeForm form);
 
+    /**
+     * 获取可用的部门选项(排除已被企业/渠道使用的部门)
+     *
+     * @param excludeId 编辑时排除的企业ID(允许选择自己关联的部门)
+     * @return 可用部门选项列表
+     */
+    List<Option<Long>> getAvailableDeptOptions(Long excludeId);
 }

+ 60 - 0
src/main/java/com/zsElectric/boot/business/service/impl/FirmInfoServiceImpl.java

@@ -4,10 +4,13 @@ import com.zsElectric.boot.business.mapper.FirmAccountLogMapper;
 import com.zsElectric.boot.business.model.entity.FirmAccountLog;
 import com.zsElectric.boot.business.model.form.FirmBalanceChangeForm;
 import com.zsElectric.boot.core.exception.BusinessException;
+import com.zsElectric.boot.common.model.Option;
+import com.zsElectric.boot.system.service.DeptService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -22,12 +25,16 @@ import com.zsElectric.boot.business.converter.FirmInfoConverter;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Set;
 import java.util.UUID;
+import java.util.stream.Collectors;
 
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.collection.CollectionUtil;
 
 /**
  * 企业信息服务实现类
@@ -42,6 +49,7 @@ public class FirmInfoServiceImpl extends ServiceImpl<FirmInfoMapper, FirmInfo> i
 
     private final FirmInfoConverter firmInfoConverter;
     private final FirmAccountLogMapper firmAccountLogMapper;
+    private final DeptService deptService;
 
     /**
     * 获取企业信息分页列表
@@ -208,4 +216,56 @@ public class FirmInfoServiceImpl extends ServiceImpl<FirmInfoMapper, FirmInfo> i
         return "FIRM" + timestamp + uuid;
     }
 
+    /**
+     * 获取可用的部门选项(排除已被企业/渠道使用的部门)
+     *
+     * @param excludeId 编辑时排除的企业ID(允许选择自己关联的部门)
+     * @return 可用部门选项列表
+     */
+    @Override
+    public List<Option<Long>> getAvailableDeptOptions(Long excludeId) {
+        // 1. 获取所有已被使用的deptId
+        LambdaQueryWrapper<FirmInfo> queryWrapper = new LambdaQueryWrapper<FirmInfo>()
+                .select(FirmInfo::getDeptId)
+                .isNotNull(FirmInfo::getDeptId);
+        // 如果是编辑模式,排除当前企业自己
+        if (excludeId != null) {
+            queryWrapper.ne(FirmInfo::getId, excludeId);
+        }
+        List<FirmInfo> usedFirmList = this.list(queryWrapper);
+        Set<Long> usedDeptIds = usedFirmList.stream()
+                .map(FirmInfo::getDeptId)
+                .collect(Collectors.toSet());
+
+        // 2. 获取所有部门选项
+        List<Option<Long>> allDeptOptions = deptService.listDeptOptions();
+
+        // 3. 提取子部门(排除顶级部门parent_id=0)
+        List<Option<Long>> childDeptOptions = new ArrayList<>();
+        for (Option<Long> option : allDeptOptions) {
+            if (CollectionUtil.isNotEmpty(option.getChildren())) {
+                childDeptOptions.addAll(option.getChildren());
+            }
+        }
+
+        // 4. 过滤掉已被使用的部门
+        return filterAvailableOptions(childDeptOptions, usedDeptIds);
+    }
+
+    /**
+     * 递归过滤可用的部门选项
+     */
+    private List<Option<Long>> filterAvailableOptions(List<Option<Long>> options, Set<Long> usedDeptIds) {
+        if (CollectionUtil.isEmpty(options)) {
+            return options;
+        }
+        return options.stream()
+                .filter(option -> !usedDeptIds.contains(option.getValue()))
+                .peek(option -> {
+                    if (CollectionUtil.isNotEmpty(option.getChildren())) {
+                        option.setChildren(filterAvailableOptions(option.getChildren(), usedDeptIds));
+                    }
+                })
+                .collect(Collectors.toList());
+    }
 }

+ 0 - 1
src/main/resources/mapper/business/FirmInfoMapper.xml

@@ -9,7 +9,6 @@
             a.dept_id,
             a.firm_type,
             a.NAME,
-            a.number,
             COUNT( b.id ) AS empNum,
             a.STATUS,
             IFNULL(a.balance, 0.00) AS balance,