[add] 添加部门和分包关联

This commit is contained in:
lcj
2025-07-18 19:32:34 +08:00
parent aade077977
commit ccfe6b8f3e
25 changed files with 435 additions and 289 deletions

View File

@ -36,7 +36,7 @@ import java.util.List;
@Validated @Validated
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@RequestMapping("/project/constructionUser") @RequestMapping("/contractor/constructionUser")
public class SubConstructionUserController extends BaseController { public class SubConstructionUserController extends BaseController {
private final ISubConstructionUserService constructionUserService; private final ISubConstructionUserService constructionUserService;
@ -53,7 +53,7 @@ public class SubConstructionUserController extends BaseController {
/** /**
* 查询每个施工人员总的考勤列表 * 查询每个施工人员总的考勤列表
*/ */
@SaCheckPermission("contractor:attendance:list") @SaCheckPermission(value = {"contractor:constructionUser:list", "project:attendance:list"})
@GetMapping("/list/attendance/total") @GetMapping("/list/attendance/total")
public TableDataInfo<SubConstructionUserAttendanceTotalVo> listAttendanceTotal(SubConstructionUserAttendanceQueryReq req, public TableDataInfo<SubConstructionUserAttendanceTotalVo> listAttendanceTotal(SubConstructionUserAttendanceQueryReq req,
PageQuery pageQuery) { PageQuery pageQuery) {

View File

@ -1,6 +1,7 @@
package org.dromara.contractor.controller; package org.dromara.contractor.controller;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -30,7 +31,7 @@ import java.util.List;
@Validated @Validated
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@RequestMapping("/project/constructionUserFile") @RequestMapping("/contractor/constructionUserFile")
public class SubConstructionUserFileController extends BaseController { public class SubConstructionUserFileController extends BaseController {
private final ISubConstructionUserFileService constructionUserFileService; private final ISubConstructionUserFileService constructionUserFileService;
@ -38,7 +39,7 @@ public class SubConstructionUserFileController extends BaseController {
/** /**
* 查询施工人员文件存储列表 * 查询施工人员文件存储列表
*/ */
@SaCheckPermission("contractor:constructionUserFile:list") @SaCheckPermission(value = {"project:constructionUserFile:list", "contractor:constructionUserFile:list"}, mode = SaMode.OR)
@GetMapping("/list") @GetMapping("/list")
public R<List<SubConstructionUserFileVo>> list(SubConstructionUserFileQueryReq req) { public R<List<SubConstructionUserFileVo>> list(SubConstructionUserFileQueryReq req) {
return R.ok(constructionUserFileService.queryList(req)); return R.ok(constructionUserFileService.queryList(req));
@ -47,7 +48,7 @@ public class SubConstructionUserFileController extends BaseController {
/** /**
* 导出施工人员文件存储列表 * 导出施工人员文件存储列表
*/ */
@SaCheckPermission("contractor:constructionUserFile:export") @SaCheckPermission(value = {"project:constructionUserFile:export", "contractor:constructionUserFile:export"}, mode = SaMode.OR)
@Log(title = "施工人员文件存储", businessType = BusinessType.EXPORT) @Log(title = "施工人员文件存储", businessType = BusinessType.EXPORT)
@PostMapping("/export") @PostMapping("/export")
public void export(SubConstructionUserFileQueryReq req, HttpServletResponse response) { public void export(SubConstructionUserFileQueryReq req, HttpServletResponse response) {
@ -58,7 +59,7 @@ public class SubConstructionUserFileController extends BaseController {
/** /**
* 下载施工人员文件存储模板 * 下载施工人员文件存储模板
*/ */
@SaCheckPermission("contractor:constructionUserFile:export") @SaCheckPermission(value = {"project:constructionUserFile:download", "contractor:constructionUserFile:download"}, mode = SaMode.OR)
@Log(title = "施工人员文件存储", businessType = BusinessType.EXPORT) @Log(title = "施工人员文件存储", businessType = BusinessType.EXPORT)
@RepeatSubmit() @RepeatSubmit()
@PostMapping("/exportFileTemplate") @PostMapping("/exportFileTemplate")
@ -69,7 +70,7 @@ public class SubConstructionUserFileController extends BaseController {
/** /**
* 上传施工人员文件压缩包,批量导入存储施工人员文件 * 上传施工人员文件压缩包,批量导入存储施工人员文件
*/ */
@SaCheckPermission("contractor:constructionUserFile:edit") @SaCheckPermission(value = {"project:constructionUserFile:upload", "contractor:constructionUserFile:upload"}, mode = SaMode.OR)
@Log(title = "施工人员文件存储", businessType = BusinessType.INSERT) @Log(title = "施工人员文件存储", businessType = BusinessType.INSERT)
@RepeatSubmit() @RepeatSubmit()
@PostMapping("/upload/zip") @PostMapping("/upload/zip")
@ -83,7 +84,7 @@ public class SubConstructionUserFileController extends BaseController {
* *
* @param id 主键 * @param id 主键
*/ */
@SaCheckPermission("contractor:constructionUserFile:query") @SaCheckPermission(value = {"project:constructionUserFile:query", "contractor:constructionUserFile:query"}, mode = SaMode.OR)
@GetMapping("/{id}") @GetMapping("/{id}")
public R<SubConstructionUserFileVo> getInfo(@NotNull(message = "主键不能为空") public R<SubConstructionUserFileVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) { @PathVariable Long id) {
@ -93,7 +94,7 @@ public class SubConstructionUserFileController extends BaseController {
/** /**
* 保存施工人员文件存储详情信息 * 保存施工人员文件存储详情信息
*/ */
@SaCheckPermission("contractor:constructionUserFile:edit") @SaCheckPermission(value = {"project:constructionUserFile:save", "contractor:constructionUserFile:save"}, mode = SaMode.OR)
@Log(title = "施工人员文件存储", businessType = BusinessType.INSERT) @Log(title = "施工人员文件存储", businessType = BusinessType.INSERT)
@PostMapping("/save") @PostMapping("/save")
public R<Boolean> save(@RequestBody SubConstructionUserFileSaveReq req) { public R<Boolean> save(@RequestBody SubConstructionUserFileSaveReq req) {

View File

@ -34,7 +34,7 @@ import java.util.List;
@Validated @Validated
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@RequestMapping("/project/contractor") @RequestMapping("/contractor/contractor")
public class SubContractorController extends BaseController { public class SubContractorController extends BaseController {
private final ISubContractorService contractorService; private final ISubContractorService contractorService;
@ -48,6 +48,16 @@ public class SubContractorController extends BaseController {
return contractorService.queryPageList(req, pageQuery); return contractorService.queryPageList(req, pageQuery);
} }
/**
* 查询没有绑定部门的分包单位列表
*/
@SaCheckPermission("contractor:contractor:listNoDept")
@GetMapping("/listNoDept/{projectId}")
public List<SubContractorVo> listNoDept(@NotNull(message = "项目主键不能为空")
@PathVariable Long projectId) {
return contractorService.queryListNoDept(projectId);
}
/** /**
* 导出分包单位列表 * 导出分包单位列表
*/ */

View File

@ -33,7 +33,7 @@ import java.util.List;
*/ */
@Validated @Validated
@RestController @RestController
@RequestMapping("/project/contractorTool") @RequestMapping("/contractor/contractorTool")
public class SubContractorToolController extends BaseController { public class SubContractorToolController extends BaseController {
@Resource @Resource

View File

@ -31,7 +31,7 @@ import java.util.List;
*/ */
@Validated @Validated
@RestController @RestController
@RequestMapping("/project/subcontract") @RequestMapping("/contractor/subcontract")
public class SubSubcontractController extends BaseController { public class SubSubcontractController extends BaseController {
@Resource @Resource

View File

@ -47,6 +47,14 @@ public interface ISubContractorService extends IService<SubContractor> {
*/ */
List<SubContractorVo> queryList(SubContractorQueryReq req); List<SubContractorVo> queryList(SubContractorQueryReq req);
/**
* 查询未绑定部门的分包单位列表
*
* @param projectId 项目id
* @return 分包单位列表
*/
List<SubContractorVo> queryListNoDept(Long projectId);
/** /**
* 新增分包单位 * 新增分包单位
* *

View File

@ -5,7 +5,6 @@ import cn.hutool.core.util.PhoneUtil;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -23,21 +22,21 @@ import org.dromara.contractor.domain.dto.contractor.SubContractorQueryReq;
import org.dromara.contractor.domain.dto.contractor.SubContractorUpdateReq; import org.dromara.contractor.domain.dto.contractor.SubContractorUpdateReq;
import org.dromara.contractor.domain.vo.contractor.SubContractorVo; import org.dromara.contractor.domain.vo.contractor.SubContractorVo;
import org.dromara.contractor.mapper.SubContractorMapper; import org.dromara.contractor.mapper.SubContractorMapper;
import org.dromara.contractor.service.ISubConstructionUserService;
import org.dromara.contractor.service.ISubContractorService; import org.dromara.contractor.service.ISubContractorService;
import org.dromara.project.domain.BusProject; import org.dromara.project.domain.BusProject;
import org.dromara.contractor.service.ISubConstructionUserService;
import org.dromara.project.service.IBusProjectService; import org.dromara.project.service.IBusProjectService;
import org.dromara.system.domain.bo.SysDeptBo; import org.dromara.system.domain.SysDept;
import org.dromara.system.service.ISysDeptService; import org.dromara.system.domain.enums.SysDeptTypeEnum;
import org.dromara.system.service.ISysPostService; import org.dromara.system.mapper.SysDeptMapper;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Collection; import java.util.*;
import java.util.HashMap; import java.util.function.Function;
import java.util.List; import java.util.stream.Collectors;
import java.util.Map;
/** /**
* 分包单位Service业务层处理 * 分包单位Service业务层处理
@ -55,11 +54,9 @@ public class SubContractorServiceImpl extends ServiceImpl<SubContractorMapper, S
@Resource @Resource
private IBusProjectService projectService; private IBusProjectService projectService;
@Lazy
@Resource @Resource
private ISysDeptService deptService; private SysDeptMapper deptMapper;
@Resource
private ISysPostService postService;
/** /**
* 查询分包单位 * 查询分包单位
@ -103,6 +100,31 @@ public class SubContractorServiceImpl extends ServiceImpl<SubContractorMapper, S
return list.stream().map(this::getVo).toList(); return list.stream().map(this::getVo).toList();
} }
/**
* 查询未绑定部门的分包单位列表
*
* @param projectId 项目id
* @return 分包单位列表
*/
@Override
public List<SubContractorVo> queryListNoDept(Long projectId) {
LambdaQueryWrapper<SysDept> lqw = new LambdaQueryWrapper<>();
lqw.eq(SysDept::getDeptType, SysDeptTypeEnum.CONTRACT.getCode());
lqw.isNotNull(SysDept::getContractorId);
List<SysDept> depts = deptMapper.selectList(lqw);
List<Long> idList = depts.stream().map(SysDept::getContractorId).toList();
List<SubContractor> contractorList = this.lambdaQuery()
.eq(SubContractor::getProjectId, projectId)
.notIn(CollUtil.isNotEmpty(idList), SubContractor::getId, idList)
.list();
return contractorList.stream().map(contractor -> {
// 对象转封装类
SubContractorVo contractorVo = new SubContractorVo();
BeanUtils.copyProperties(contractor, contractorVo);
return contractorVo;
}).toList();
}
/** /**
* 新增分包单位 * 新增分包单位
* *
@ -131,26 +153,6 @@ public class SubContractorServiceImpl extends ServiceImpl<SubContractorMapper, S
if (project == null) { if (project == null) {
throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND); throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND);
} }
// 创建部门
/* Long deptId = project.getDeptId();
SysDeptBo createBo = new SysDeptBo();
createBo.setParentId(deptId);
createBo.setDeptName(name);
if (!deptService.checkDeptNameUnique(createBo)) {
throw new ServiceException("新增项目部门'" + createBo.getDeptName() + "'失败,项目名称已存在");
}
// 新增部门
int dept = deptService.insertDept(createBo);
if (dept <= 0) {
throw new ServiceException("新增项目部门'" + createBo.getDeptName() + "'失败");
}
Long newDeptId = deptService.selectIdByDeptName(createBo.getDeptName());
contractor.setDeptId(newDeptId);
// 新增岗位
Boolean result = postService.insertPostByDeptId(newDeptId);
if (!result) {
throw new ServiceException("对应岗位类型保存失败");
}*/
// 操作数据库 // 操作数据库
boolean save = this.save(contractor); boolean save = this.save(contractor);
if (!save) { if (!save) {
@ -238,11 +240,31 @@ public class SubContractorServiceImpl extends ServiceImpl<SubContractorMapper, S
List<Long> projectIdList = contractorList.stream().map(SubContractor::getProjectId).toList(); List<Long> projectIdList = contractorList.stream().map(SubContractor::getProjectId).toList();
projectService.validAuth(projectIdList, userId); projectService.validAuth(projectIdList, userId);
// 判断当前分包公司下是否还包含施工人员 // 判断当前分包公司下是否还包含施工人员
QueryWrapper<SubConstructionUser> queryWrapper = new QueryWrapper<>(); LambdaQueryWrapper<SubConstructionUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in("contractor_id", ids); queryWrapper.in(SubConstructionUser::getContractorId, ids);
if (constructionUserService.count(queryWrapper) > 0) { if (constructionUserService.count(queryWrapper) > 0) {
throw new ServiceException("删除分包单位失败,删除分包单位下存在施工人员", HttpStatus.BAD_REQUEST); throw new ServiceException("删除分包单位失败,删除分包单位下存在施工人员", HttpStatus.BAD_REQUEST);
} }
// 判断当前分包公司是否绑定了部门
LambdaQueryWrapper<SysDept> lqw = new LambdaQueryWrapper<>();
lqw.in(SysDept::getContractorId, ids);
List<SysDept> deptList = deptMapper.selectList(lqw);
if (CollUtil.isNotEmpty(deptList)) {
Map<Long, SubContractor> contractorMap = contractorList.stream()
.collect(Collectors.toMap(SubContractor::getId, Function.identity()));
Set<String> contractorNames = new HashSet<>();
for (SysDept dept : deptList) {
Long contractorId = dept.getContractorId();
SubContractor contractor = contractorMap.get(contractorId);
if (contractor != null) {
contractorNames.add(contractor.getName());
}
}
if (CollUtil.isNotEmpty(contractorNames)) {
String joinedNames = String.join("", contractorNames);
throw new ServiceException("删除分包单位失败,以下单位已绑定部门:" + joinedNames, HttpStatus.BAD_REQUEST);
}
}
} }
// 判断对应数据是否都存在 // 判断对应数据是否都存在
if (contractorList.size() != ids.size()) { if (contractorList.size() != ids.size()) {

View File

@ -12,6 +12,12 @@ import org.springframework.stereotype.Component;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
/**
* 清理项目缓存
*
* @author lcj
* @date 2025/5/14 10:23
*/
@Slf4j @Slf4j
@Component @Component
public class DeleteProjectCache { public class DeleteProjectCache {

View File

@ -11,6 +11,8 @@ import java.time.LocalDateTime;
import java.util.Date; import java.util.Date;
/** /**
* 清理萤石设备抓拍图片数据
*
* @author lcj * @author lcj
* @date 2025/6/19 10:23 * @date 2025/6/19 10:23
*/ */

View File

@ -7,6 +7,8 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* 判断施工进度是否延期
*
* @author lcj * @author lcj
* @date 2025/5/29 9:38 * @date 2025/5/29 9:38
*/ */

View File

@ -6,11 +6,12 @@ import org.dromara.manager.ys7manager.Ys7Manager;
import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo; import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo;
import org.dromara.other.service.IOthYs7DeviceService; import org.dromara.other.service.IOthYs7DeviceService;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
/** /**
* 定时同步摄像头设备数据
*
* @author lcj * @author lcj
* @date 2025/6/17 9:33 * @date 2025/6/17 9:33
*/ */

View File

@ -11,6 +11,8 @@ import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
/** /**
* 同步摄像头设备数据
*
* @author lcj * @author lcj
* @date 2025/6/13 11:08 * @date 2025/6/13 11:08
*/ */

View File

@ -161,11 +161,6 @@ public class BusProjectVo implements Serializable {
@ExcelProperty(value = "安全协议书") @ExcelProperty(value = "安全协议书")
private String securityAgreement; private String securityAgreement;
/**
* 设计文件id
*/
private Long designId;
/** /**
* 显示隐藏0显示 1隐藏 * 显示隐藏0显示 1隐藏
*/ */

View File

@ -26,6 +26,11 @@ public class BusSubProjectVo implements Serializable {
*/ */
private String projectName; private String projectName;
/**
* 设计文件id
*/
private Long designId;
/** /**
* 创建时间 * 创建时间
*/ */

View File

@ -9,7 +9,6 @@ import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -51,7 +50,7 @@ import org.dromara.project.service.IBusUserProjectRelevancyService;
import org.dromara.quality.service.IQltKnowledgeDocumentService; import org.dromara.quality.service.IQltKnowledgeDocumentService;
import org.dromara.safety.service.IHseKnowledgeDocumentService; import org.dromara.safety.service.IHseKnowledgeDocumentService;
import org.dromara.system.domain.SysDept; import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.enums.SysDeptIsSubsetEnum; import org.dromara.system.domain.enums.SysDeptTypeEnum;
import org.dromara.system.mapper.SysDeptMapper; import org.dromara.system.mapper.SysDeptMapper;
import org.dromara.workflow.service.IFlwDefinitionService; import org.dromara.workflow.service.IFlwDefinitionService;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -154,19 +153,7 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
*/ */
@Override @Override
public TableDataInfo<BusProjectVo> queryPageList(BusProjectQueryReq req, PageQuery pageQuery) { public TableDataInfo<BusProjectVo> queryPageList(BusProjectQueryReq req, PageQuery pageQuery) {
// 获取当前登录用户项目列表
Long userId = LoginHelper.getUserId();
List<Long> projectIdList = userProjectRelevancyService.lambdaQuery()
.select(BusUserProjectRelevancy::getProjectId)
.eq(BusUserProjectRelevancy::getUserId, userId)
.list()
.stream().map(BusUserProjectRelevancy::getProjectId).toList();
LambdaQueryWrapper<BusProject> lqw = this.buildQueryWrapper(req); LambdaQueryWrapper<BusProject> lqw = this.buildQueryWrapper(req);
if (CollUtil.isEmpty(projectIdList)) {
return TableDataInfo.build(new Page<>());
} else {
lqw.in(BusProject::getId, projectIdList);
}
// 查询数据库 // 查询数据库
Page<BusProject> result = this.page(pageQuery.build(), lqw); Page<BusProject> result = this.page(pageQuery.build(), lqw);
return TableDataInfo.build(this.getVoPage(result)); return TableDataInfo.build(this.getVoPage(result));
@ -192,16 +179,14 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
@Override @Override
public List<BusProjectVo> queryListNoDept() { public List<BusProjectVo> queryListNoDept() {
LambdaQueryWrapper<SysDept> lqw = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysDept> lqw = new LambdaQueryWrapper<>();
lqw.eq(SysDept::getIsSubset, SysDeptIsSubsetEnum.NO.getCode()); lqw.eq(SysDept::getDeptType, SysDeptTypeEnum.PROJECT.getCode());
lqw.isNotNull(SysDept::getProjectId); lqw.isNotNull(SysDept::getProjectId);
List<SysDept> depts = deptMapper.selectList(lqw); List<SysDept> depts = deptMapper.selectList(lqw);
List<Long> idList = depts.stream().map(SysDept::getProjectId).toList(); List<Long> idList = depts.stream().map(SysDept::getProjectId).toList();
List<BusProject> allProjectList = this.lambdaQuery() List<BusProject> projectList = this.lambdaQuery()
.notIn(CollUtil.isNotEmpty(idList), BusProject::getId, idList)
.eq(BusProject::getPId, BusProjectConstant.PARENT_ID) .eq(BusProject::getPId, BusProjectConstant.PARENT_ID)
.list(); .list();
List<BusProject> projectList = allProjectList.stream()
.filter(project -> !idList.contains(project.getId()))
.toList();
return projectList.stream().map(this::getVo).toList(); return projectList.stream().map(this::getVo).toList();
} }
@ -351,16 +336,11 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
throw new ServiceException("新增项目失败,数据库异常", HttpStatus.ERROR); throw new ServiceException("新增项目失败,数据库异常", HttpStatus.ERROR);
} }
Long projectId = project.getId(); Long projectId = project.getId();
Long userId = LoginHelper.getUserId(); // 保存管理员与项目关联
// 同步保存用户与项目关联
Set<Long> userIdList = new HashSet<>(List.of(userId, SystemConstants.SUPER_ADMIN_ID));
List<BusUserProjectRelevancy> userProjectRelevancyList = userIdList.stream().map(id -> {
BusUserProjectRelevancy userProjectRelevancy = new BusUserProjectRelevancy(); BusUserProjectRelevancy userProjectRelevancy = new BusUserProjectRelevancy();
userProjectRelevancy.setUserId(id); userProjectRelevancy.setUserId(SystemConstants.SUPER_ADMIN_ID);
userProjectRelevancy.setProjectId(projectId); userProjectRelevancy.setProjectId(projectId);
return userProjectRelevancy; boolean saveRelevancy = userProjectRelevancyService.save(userProjectRelevancy);
}).toList();
boolean saveRelevancy = userProjectRelevancyService.saveBatch(userProjectRelevancyList);
if (!saveRelevancy) { if (!saveRelevancy) {
throw new ServiceException("新增用户与项目关联失败,数据库异常", HttpStatus.ERROR); throw new ServiceException("新增用户与项目关联失败,数据库异常", HttpStatus.ERROR);
} }
@ -446,6 +426,7 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
if (!saveTechnicalStandard) { if (!saveTechnicalStandard) {
log.error("同步数据失败,项目[{}]新增技术标准管理文件夹模版失败", id); log.error("同步数据失败,项目[{}]新增技术标准管理文件夹模版失败", id);
} }
// 流程定义模版
flwDefinitionService.insertDefByProjectId(id); flwDefinitionService.insertDefByProjectId(id);
return CompletableFuture.completedFuture(true); return CompletableFuture.completedFuture(true);
} }
@ -537,9 +518,9 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
throw new ServiceException("删除项目失败,数据库异常", HttpStatus.ERROR); throw new ServiceException("删除项目失败,数据库异常", HttpStatus.ERROR);
} }
// 删除用户与项目关联表 // 删除用户与项目关联表
QueryWrapper<BusUserProjectRelevancy> queryWrapper = new QueryWrapper<>(); LambdaQueryWrapper<BusUserProjectRelevancy> lqw = new LambdaQueryWrapper<>();
queryWrapper.in("project_id", ids); lqw.in(BusUserProjectRelevancy::getProjectId, ids);
boolean removeRelevancyList = userProjectRelevancyService.remove(queryWrapper); boolean removeRelevancyList = userProjectRelevancyService.remove(lqw);
if (!removeRelevancyList) { if (!removeRelevancyList) {
throw new ServiceException("删除项目与用户关联失败,数据库异常", HttpStatus.ERROR); throw new ServiceException("删除项目与用户关联失败,数据库异常", HttpStatus.ERROR);
} }
@ -566,24 +547,29 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
projectVo.setPlayCardStart(split[0]); projectVo.setPlayCardStart(split[0]);
projectVo.setPlayCardEnd(split[1]); projectVo.setPlayCardEnd(split[1]);
} }
// 关联设计id
BusProjectFile projectFile = projectFileService.lambdaQuery()
.eq(BusProjectFile::getProjectId, project.getId())
.one();
if (projectFile != null) {
projectVo.setDesignId(projectFile.getId());
}
// 关联子项目列表 // 关联子项目列表
List<BusProject> subProjectList = this.lambdaQuery() List<BusProject> subProjectList = this.lambdaQuery()
.select(BusProject::getId, BusProject::getProjectName, BusProject::getCreateTime) .select(BusProject::getId, BusProject::getProjectName, BusProject::getCreateTime)
.eq(BusProject::getPId, project.getId()) .eq(BusProject::getPId, project.getId())
.list(); .list();
if (CollUtil.isNotEmpty(subProjectList)) {
List<Long> subIdList = subProjectList.stream().map(BusProject::getId).toList();
// 关联设计id
List<BusProjectFile> projectFileList = projectFileService.lambdaQuery()
.in(BusProjectFile::getProjectId, subIdList)
.list();
Map<Long, List<BusProjectFile>> map = projectFileList.stream().collect(Collectors.groupingBy(BusProjectFile::getProjectId));
List<BusSubProjectVo> subProjectVoList = subProjectList.stream().map(subProject -> { List<BusSubProjectVo> subProjectVoList = subProjectList.stream().map(subProject -> {
BusSubProjectVo subProjectVo = new BusSubProjectVo(); BusSubProjectVo subProjectVo = new BusSubProjectVo();
BeanUtils.copyProperties(subProject, subProjectVo); BeanUtils.copyProperties(subProject, subProjectVo);
Long id = subProject.getId();
if (map.containsKey(id)) {
subProjectVo.setDesignId(map.get(id).getFirst().getId());
}
return subProjectVo; return subProjectVo;
}).toList(); }).toList();
projectVo.setChildren(subProjectVoList); projectVo.setChildren(subProjectVoList);
}
return projectVo; return projectVo;
} }
@ -654,15 +640,17 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
} }
// 获取项目文件id // 获取项目文件id
Set<Long> projectIdList = projectList.stream().map(BusProject::getId).collect(Collectors.toSet()); Set<Long> projectIdList = projectList.stream().map(BusProject::getId).collect(Collectors.toSet());
Map<Long, List<BusProjectFile>> projectFileMap = projectFileService.lambdaQuery()
.in(BusProjectFile::getProjectId, projectIdList).list()
.stream().collect(Collectors.groupingBy(BusProjectFile::getProjectId));
// 获取子项目列表 // 获取子项目列表
List<BusProject> subProjectList = this.lambdaQuery() List<BusProject> subProjectList = this.lambdaQuery()
.select(BusProject::getId, BusProject::getPId, BusProject::getProjectName, BusProject::getCreateTime) .select(BusProject::getId, BusProject::getPId, BusProject::getProjectName, BusProject::getCreateTime)
.in(BusProject::getPId, projectIdList) .in(BusProject::getPId, projectIdList)
.list(); .list();
Set<Long> subIdList = subProjectList.stream().map(BusProject::getId).collect(Collectors.toSet());
Map<Long, List<BusProject>> subProjectMap = subProjectList.stream().collect(Collectors.groupingBy(BusProject::getPId)); Map<Long, List<BusProject>> subProjectMap = subProjectList.stream().collect(Collectors.groupingBy(BusProject::getPId));
Map<Long, List<BusProjectFile>> projectFileMap = projectFileService.lambdaQuery()
.in(CollUtil.isNotEmpty(subIdList), BusProjectFile::getProjectId, subIdList).list()
.stream().collect(Collectors.groupingBy(BusProjectFile::getProjectId));
// 对象列表 => 封装对象列表 // 对象列表 => 封装对象列表
List<BusProjectVo> projectVoList = projectList.stream().map(project -> { List<BusProjectVo> projectVoList = projectList.stream().map(project -> {
// 对象转封装类 // 对象转封装类
@ -674,17 +662,17 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
projectVo.setPlayCardStart(split[0]); projectVo.setPlayCardStart(split[0]);
projectVo.setPlayCardEnd(split[1]); projectVo.setPlayCardEnd(split[1]);
} }
// 关联设计id
List<BusProjectFile> projectFileList = projectFileMap.get(project.getId());
if (CollUtil.isNotEmpty(projectFileList)) {
projectVo.setDesignId(projectFileList.getFirst().getId());
}
// 关联子项目 // 关联子项目
List<BusSubProjectVo> subProjectVoList = new ArrayList<>(); List<BusSubProjectVo> subProjectVoList = new ArrayList<>();
if (subProjectMap.containsKey(project.getId())) { if (subProjectMap.containsKey(project.getId())) {
subProjectVoList = subProjectMap.get(project.getId()).stream().map(subProject -> { subProjectVoList = subProjectMap.get(project.getId()).stream().map(subProject -> {
BusSubProjectVo subProjectVo = new BusSubProjectVo(); BusSubProjectVo subProjectVo = new BusSubProjectVo();
BeanUtils.copyProperties(subProject, subProjectVo); BeanUtils.copyProperties(subProject, subProjectVo);
Long id = subProject.getId();
// 关联设计id
if (projectFileMap.containsKey(id)) {
subProjectVo.setDesignId(projectFileMap.get(id).getFirst().getId());
}
return subProjectVo; return subProjectVo;
}).toList(); }).toList();
} }

View File

@ -299,6 +299,9 @@ public class BusUserProjectRelevancyServiceImpl extends ServiceImpl<BusUserProje
// 查询数据库,获取数据 // 查询数据库,获取数据
List<BusUserProjectRelevancy> list = this.list(queryWrapper); List<BusUserProjectRelevancy> list = this.list(queryWrapper);
List<Long> projectIdList = list.stream().map(BusUserProjectRelevancy::getProjectId).toList(); List<Long> projectIdList = list.stream().map(BusUserProjectRelevancy::getProjectId).toList();
if (CollUtil.isEmpty(projectIdList)) {
return new ArrayList<>();
}
Map<Long, List<BusProject>> projectMap = projectService.lambdaQuery() Map<Long, List<BusProject>> projectMap = projectService.lambdaQuery()
.select(BusProject::getId, BusProject::getPId, BusProject::getProjectName, BusProject::getShortName) .select(BusProject::getId, BusProject::getPId, BusProject::getProjectName, BusProject::getShortName)
.in(BusProject::getId, projectIdList) .in(BusProject::getId, projectIdList)

View File

@ -169,6 +169,8 @@ public class SysUserController extends BaseController {
deptService.checkDeptMatchRole(user.getUserId(), List.of(user.getRoleIds())); deptService.checkDeptMatchRole(user.getUserId(), List.of(user.getRoleIds()));
if (!userService.checkUserNameUnique(user)) { if (!userService.checkUserNameUnique(user)) {
return R.fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); return R.fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
} else if (StringUtils.isEmpty(user.getPhonenumber())) {
return R.fail("新增用户'" + user.getUserName() + "'失败,手机号不能为空");
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) { } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
return R.fail("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); return R.fail("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
} else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
@ -196,6 +198,8 @@ public class SysUserController extends BaseController {
deptService.checkDeptMatchRole(user.getUserId(), List.of(user.getRoleIds())); deptService.checkDeptMatchRole(user.getUserId(), List.of(user.getRoleIds()));
if (!userService.checkUserNameUnique(user)) { if (!userService.checkUserNameUnique(user)) {
return R.fail("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); return R.fail("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
} else if (StringUtils.isEmpty(user.getPhonenumber())) {
return R.fail("修改用户'" + user.getUserName() + "'失败,手机号不能为空");
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) { } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
} else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {

View File

@ -14,7 +14,6 @@ import java.io.Serial;
* *
* @author Lion Li * @author Lion Li
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@TableName("sys_dept") @TableName("sys_dept")
@ -39,6 +38,11 @@ public class SysDept extends TenantEntity {
*/ */
private Long projectId; private Long projectId;
/**
* 分包公司ID
*/
private Long contractorId;
/** /**
* 部门名称 * 部门名称
*/ */
@ -91,8 +95,8 @@ public class SysDept extends TenantEntity {
private String isShow; private String isShow;
/** /**
* 是否子集0否 1是 * 部门类型
*/ */
private String isSubset; private String deptType;
} }

View File

@ -7,6 +7,8 @@ import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity; import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.system.domain.SysDept; import org.dromara.system.domain.SysDept;
import java.io.Serial;
/** /**
* 部门业务对象 sys_dept * 部门业务对象 sys_dept
* *
@ -18,6 +20,9 @@ import org.dromara.system.domain.SysDept;
@AutoMapper(target = SysDept.class, reverseConvertGenerate = false) @AutoMapper(target = SysDept.class, reverseConvertGenerate = false)
public class SysDeptBo extends BaseEntity { public class SysDeptBo extends BaseEntity {
@Serial
private static final long serialVersionUID = -7462841004330805895L;
/** /**
* 部门id * 部门id
*/ */
@ -33,6 +38,16 @@ public class SysDeptBo extends BaseEntity {
*/ */
private Long projectId; private Long projectId;
/**
* 项目部门项目id
*/
private Long rowProjectId;
/**
* 分包公司ID
*/
private Long contractorId;
/** /**
* 部门名称 * 部门名称
*/ */
@ -82,10 +97,10 @@ public class SysDeptBo extends BaseEntity {
private String isShow; private String isShow;
/** /**
* 是否子集0否 1是 * 部门类型
*/ */
@Pattern(regexp = "^[01]$", message = "isSubset字段值必须是0或1") @NotBlank(message = "部门类型不能为空")
private String isSubset; private String deptType;
// /** // /**

View File

@ -4,21 +4,23 @@ import lombok.Getter;
/** /**
* @author lcj * @author lcj
* @date 2025/7/10 9:25 * @date 2025/7/18 9:41
*/ */
@Getter @Getter
public enum SysDeptIsSubsetEnum { public enum SysDeptTypeEnum {
YES("1", ""), NORMAL("1", "正常"),
SPECIAL("2", "特殊"),
NO("0", ""); PROJECT("3", "项目"),
CONTRACT("4", "分包");
private final String code; private final String code;
private final String message; private final String message;
SysDeptIsSubsetEnum(String code, String message) { SysDeptTypeEnum(String code, String message) {
this.code = code; this.code = code;
this.message = message; this.message = message;
} }
} }

View File

@ -1,23 +0,0 @@
package org.dromara.system.domain.enums;
import lombok.Getter;
/**
* @author lcj
* @date 2025/7/10 9:26
*/
@Getter
public enum SysRoleIsSpecialEnum {
YES("1", ""),
NO("0", "");
private final String code;
private final String message;
SysRoleIsSpecialEnum(String code, String message) {
this.code = code;
this.message = message;
}
}

View File

@ -6,6 +6,7 @@ import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data; import lombok.Data;
import org.dromara.common.excel.annotation.ExcelDictFormat; import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert; import org.dromara.common.excel.convert.ExcelDictConvert;
import org.dromara.contractor.domain.vo.contractor.SubContractorVo;
import org.dromara.project.domain.vo.project.BusProjectVo; import org.dromara.project.domain.vo.project.BusProjectVo;
import org.dromara.system.domain.SysDept; import org.dromara.system.domain.SysDept;
@ -43,17 +44,31 @@ public class SysDeptVo implements Serializable {
*/ */
private String parentName; private String parentName;
/**
* 父部门信息
*/
private SysDeptVo parent;
/** /**
* 项目id * 项目id
*/ */
private Long projectId; private Long projectId;
/**
* 分包公司ID
*/
private Long contractorId;
/** /**
* 未绑定项目信息 * 未绑定项目信息
*/ */
private List<BusProjectVo> projectList; private List<BusProjectVo> projectList;
/**
* 未绑定分包信息
*/
private List<SubContractorVo> contractorList;
/** /**
* 祖级列表 * 祖级列表
*/ */
@ -107,9 +122,11 @@ public class SysDeptVo implements Serializable {
private String status; private String status;
/** /**
* 是否子集0否 1是 * 部门类型
*/ */
private String isSubset; @ExcelProperty(value = "部门类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_dept_type")
private String deptType;
/** /**
* 创建时间 * 创建时间

View File

@ -78,19 +78,19 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
@Select(""" @Select("""
WITH RECURSIVE dept_tree AS ( WITH RECURSIVE dept_tree AS (
SELECT dept_id, parent_id, project_id, is_subset SELECT dept_id, parent_id, project_id, dept_type
FROM sys_dept FROM sys_dept
WHERE dept_id = #{deptId} WHERE dept_id = #{deptId}
UNION ALL UNION ALL
SELECT d.dept_id, d.parent_id, d.project_id, d.is_subset SELECT d.dept_id, d.parent_id, d.project_id, d.dept_type
FROM sys_dept d FROM sys_dept d
INNER JOIN dept_tree dt ON d.parent_id = dt.dept_id INNER JOIN dept_tree dt ON d.parent_id = dt.dept_id
) )
SELECT DISTINCT project_id SELECT DISTINCT project_id
FROM dept_tree FROM dept_tree
WHERE is_subset = '0' AND project_id IS NOT NULL WHERE dept_type = '3' AND project_id IS NOT NULL
""") """)
List<Long> getProjectIdsByDept(@Param("deptId") Long deptId); List<Long> getProjectIdsByDept(@Param("deptId") Long deptId);

View File

@ -20,6 +20,9 @@ import org.dromara.common.core.utils.*;
import org.dromara.common.mybatis.helper.DataBaseHelper; import org.dromara.common.mybatis.helper.DataBaseHelper;
import org.dromara.common.redis.utils.CacheUtils; import org.dromara.common.redis.utils.CacheUtils;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.contractor.domain.SubContractor;
import org.dromara.contractor.domain.vo.contractor.SubContractorVo;
import org.dromara.contractor.service.ISubContractorService;
import org.dromara.project.domain.BusProject; import org.dromara.project.domain.BusProject;
import org.dromara.project.domain.vo.project.BusProjectVo; import org.dromara.project.domain.vo.project.BusProjectVo;
import org.dromara.project.service.IBusProjectService; import org.dromara.project.service.IBusProjectService;
@ -28,7 +31,7 @@ import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.SysRole; import org.dromara.system.domain.SysRole;
import org.dromara.system.domain.SysUser; import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.SysDeptBo; import org.dromara.system.domain.bo.SysDeptBo;
import org.dromara.system.domain.enums.SysDeptIsSubsetEnum; import org.dromara.system.domain.enums.SysDeptTypeEnum;
import org.dromara.system.domain.vo.SysDeptVo; import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.mapper.SysDeptMapper; import org.dromara.system.mapper.SysDeptMapper;
import org.dromara.system.mapper.SysRoleMapper; import org.dromara.system.mapper.SysRoleMapper;
@ -40,10 +43,7 @@ import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/** /**
* 部门管理 服务实现 * 部门管理 服务实现
@ -59,6 +59,7 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
private final SysRoleMapper roleMapper; private final SysRoleMapper roleMapper;
private final SysUserMapper userMapper; private final SysUserMapper userMapper;
private final IBusProjectService projectService; private final IBusProjectService projectService;
private final ISubContractorService contractorService;
private final IBusUserProjectRelevancyService userProjectRelevancyService; private final IBusUserProjectRelevancyService userProjectRelevancyService;
/** /**
@ -96,7 +97,7 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDept::getStatus, bo.getStatus()); lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDept::getStatus, bo.getStatus());
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDept::getStatus, bo.getStatus()); lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDept::getStatus, bo.getStatus());
lqw.eq(StringUtils.isNotBlank(bo.getIsShow()), SysDept::getIsShow, bo.getIsShow()); lqw.eq(StringUtils.isNotBlank(bo.getIsShow()), SysDept::getIsShow, bo.getIsShow());
lqw.eq(StringUtils.isNotBlank(bo.getIsSubset()), SysDept::getIsSubset, bo.getIsSubset()); lqw.eq(StringUtils.isNotBlank(bo.getDeptType()), SysDept::getDeptType, bo.getDeptType());
lqw.orderByAsc(SysDept::getAncestors); lqw.orderByAsc(SysDept::getAncestors);
lqw.orderByAsc(SysDept::getParentId); lqw.orderByAsc(SysDept::getParentId);
lqw.orderByAsc(SysDept::getOrderNum); lqw.orderByAsc(SysDept::getOrderNum);
@ -127,7 +128,7 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
.setName(dept.getDeptName()) .setName(dept.getDeptName())
.setWeight(dept.getOrderNum()) .setWeight(dept.getOrderNum())
.putExtra("disabled", SystemConstants.DISABLE.equals(dept.getStatus())); .putExtra("disabled", SystemConstants.DISABLE.equals(dept.getStatus()));
tree.putExtra("isSubset", dept.getIsSubset()); tree.putExtra("deptType", dept.getDeptType());
} }
); );
Tree<Long> tree = StreamUtils.findFirst(trees, it -> it.getId().longValue() == d.getDeptId()); Tree<Long> tree = StreamUtils.findFirst(trees, it -> it.getId().longValue() == d.getDeptId());
@ -165,12 +166,23 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
SysDeptVo parentDept = baseMapper.selectVoOne(new LambdaQueryWrapper<SysDept>() SysDeptVo parentDept = baseMapper.selectVoOne(new LambdaQueryWrapper<SysDept>()
.select(SysDept::getDeptName).eq(SysDept::getDeptId, dept.getParentId())); .select(SysDept::getDeptName).eq(SysDept::getDeptId, dept.getParentId()));
dept.setParentName(ObjectUtils.notNullGetter(parentDept, SysDeptVo::getDeptName)); dept.setParentName(ObjectUtils.notNullGetter(parentDept, SysDeptVo::getDeptName));
dept.setParent(parentDept);
String deptType = dept.getDeptType();
// 获取未绑定项目信息
List<BusProjectVo> projectVos = new ArrayList<>(projectService.queryListNoDept()); List<BusProjectVo> projectVos = new ArrayList<>(projectService.queryListNoDept());
if (dept.getIsSubset().equals(SysDeptIsSubsetEnum.NO.getCode()) && dept.getProjectId() != null) { // 获取项目部门绑定的项目信息
if (deptType.equals(SysDeptTypeEnum.PROJECT.getCode()) && dept.getProjectId() != null) {
BusProjectVo vo = projectService.getVo(projectService.getById(dept.getProjectId())); BusProjectVo vo = projectService.getVo(projectService.getById(dept.getProjectId()));
projectVos.add(vo); projectVos.add(vo);
} }
dept.setProjectList(projectVos); dept.setProjectList(projectVos);
// 如果为分包部门,获取分包部门信息
if (deptType.equals(SysDeptTypeEnum.CONTRACT.getCode())) {
List<SubContractorVo> contractorVos = new ArrayList<>(contractorService.queryListNoDept(dept.getProjectId()));
SubContractorVo vo = contractorService.getVo(contractorService.getById(dept.getContractorId()));
contractorVos.add(vo);
dept.setContractorList(contractorVos);
}
return dept; return dept;
} }
@ -386,18 +398,23 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
if (!SystemConstants.NORMAL.equals(info.getStatus())) { if (!SystemConstants.NORMAL.equals(info.getStatus())) {
throw new ServiceException("部门停用,不允许新增"); throw new ServiceException("部门停用,不允许新增");
} }
if (SysDeptIsSubsetEnum.NO.getCode().equals(info.getIsSubset())) { String pDeptType = info.getDeptType();
String deptType = bo.getDeptType();
if (SysDeptTypeEnum.SPECIAL.getCode().equals(pDeptType) || SysDeptTypeEnum.CONTRACT.getCode().equals(pDeptType)) {
// 父部门为特殊部门或者项目部门,不允许新增子部门
throw new ServiceException("当前部门不允许有子部门"); throw new ServiceException("当前部门不允许有子部门");
} else if (SysDeptTypeEnum.PROJECT.getCode().equals(pDeptType) && !SysDeptTypeEnum.CONTRACT.getCode().equals(deptType)) {
// 父部门为项目部门,只能新增分包部门
throw new ServiceException("项目部门只能新增分包部门");
} }
SysDept dept = MapstructUtils.convert(bo, SysDept.class); SysDept dept = MapstructUtils.convert(bo, SysDept.class);
if (dept == null) { if (dept == null) {
throw new ServiceException("新增部门参数异常", HttpStatus.BAD_REQUEST); throw new ServiceException("新增部门参数异常", HttpStatus.BAD_REQUEST);
} }
dept.setAncestors(info.getAncestors() + StringUtils.SEPARATOR + dept.getParentId()); dept.setAncestors(info.getAncestors() + StringUtils.SEPARATOR + dept.getParentId());
String isSubset = bo.getIsSubset(); if (SysDeptTypeEnum.PROJECT.getCode().equals(deptType)) {
if (SysDeptIsSubsetEnum.NO.getCode().equals(isSubset)) { // 项目部门
Long projectId = bo.getProjectId(); Long projectId = bo.getProjectId();
if (projectId != null) {
BusProject project = projectService.getById(projectId); BusProject project = projectService.getById(projectId);
if (project == null) { if (project == null) {
throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND); throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND);
@ -411,53 +428,54 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
} }
dept.setProjectId(projectId); dept.setProjectId(projectId);
// 判断是否有需要新增项目关联的用户 // 判断是否有需要新增项目关联的用户
List<Long> deptIds = this.getParentDeptIds(dept); List<Long> deptIds = this.getParentAndSiblingDeptIds(dept);
LambdaQueryWrapper<SysUser> lqw = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysUser> lqw = new LambdaQueryWrapper<>();
lqw.select(SysUser::getUserId); lqw.select(SysUser::getUserId);
lqw.in(SysUser::getDeptId, deptIds); lqw.in(SysUser::getDeptId, deptIds);
List<Long> userIds = userMapper.selectList(lqw).stream().map(SysUser::getUserId).toList(); List<Long> userIds = userMapper.selectList(lqw).stream()
.map(SysUser::getUserId)
.filter(userId -> !LoginHelper.isSuperAdmin(userId))
.toList();
if (CollUtil.isNotEmpty(userIds)) { if (CollUtil.isNotEmpty(userIds)) {
userProjectRelevancyService.saveBatchByUserList(projectId, userIds); userProjectRelevancyService.saveBatchByUserList(projectId, userIds);
} }
} else if (SysDeptTypeEnum.CONTRACT.getCode().equals(deptType)) {
// 分包部门
Long projectId = bo.getRowProjectId();
BusProject project = projectService.getById(projectId);
if (project == null) {
throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND);
} }
Long contractorId = bo.getContractorId();
SubContractor contractor = contractorService.getById(contractorId);
if (contractor == null) {
throw new ServiceException("分包方不存在", HttpStatus.NOT_FOUND);
}
if (!contractor.getProjectId().equals(projectId)) {
throw new ServiceException("分包方不属于当前项目,请重新选择", HttpStatus.BAD_REQUEST);
}
// 判断该项目是否被绑定
Long projectCount = baseMapper.selectCount(
new LambdaQueryWrapper<SysDept>()
.eq(SysDept::getProjectId, projectId)
);
if (projectCount <= 0) {
throw new ServiceException("所选项目未绑定部门,请先将项目绑定部门", HttpStatus.BAD_REQUEST);
}
// 判断该分包方是否被绑定
Long contractorCount = baseMapper.selectCount(
new LambdaQueryWrapper<SysDept>()
.eq(SysDept::getContractorId, contractorId)
);
if (contractorCount > 0) {
throw new ServiceException("该分包方已被其他部门绑定", HttpStatus.CONFLICT);
}
dept.setProjectId(projectId);
dept.setContractorId(contractorId);
} }
return baseMapper.insert(dept); return baseMapper.insert(dept);
// // cory 判断是否需要直接新增角色
// SysRoleBo role = getSysRoleBo(bo);
// roleService.checkRoleAllowed(role);
// if (!roleService.checkRoleNameUnique(role)) {
// throw new ServiceException("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
// } else if (!roleService.checkRoleKeyUnique(role)) {
// throw new ServiceException("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
// }
// roleService.insertRole(role);
// SysDept sysDept = new SysDept();
// sysDept.setDeptId(dept.getDeptId());
// sysDept.setRoleId(role.getRoleId());
// baseMapper.updateById(sysDept);
// return insert;
} }
// @NotNull
// private static SysRoleBo getSysRoleBo(SysDeptBo bo) {
// SysRoleBo role = new SysRoleBo();
// role.setRoleName(bo.getDeptName());
// role.setRoleKey(bo.getRoleKey());
// role.setRoleSort(bo.getRoleSort());
// role.setDataScope(bo.getDataScope());
// role.setMenuCheckStrictly(bo.getMenuCheckStrictly());
// role.setDeptCheckStrictly(bo.getDeptCheckStrictly());
// role.setStatus(bo.getRoleStatus());
// role.setRemark(bo.getRemark());
// role.setMenuIds(bo.getMenuIds());
// role.setDeptIds(bo.getDeptIds());
// role.setIsSpecial("1"); //特殊角色(部门无子集标识特殊角色)
// if (bo.getRoleId() != null) {
// role.setRoleId(bo.getRoleId());
// }
// return role;
// }
/** /**
* 修改保存部门信息 * 修改保存部门信息
* *
@ -489,11 +507,12 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
} else { } else {
dept.setAncestors(oldDept.getAncestors()); dept.setAncestors(oldDept.getAncestors());
} }
// 新增逻辑:判断是否需要更新用户与项目的关联 String deptType = dept.getDeptType();
String isSubset = dept.getIsSubset(); if (SysDeptTypeEnum.PROJECT.getCode().equals(deptType)) {
// 判断是否需要更新用户与项目的关联
Long oldProjectId = oldDept.getProjectId(); Long oldProjectId = oldDept.getProjectId();
Long newProjectId = dept.getProjectId(); Long newProjectId = dept.getProjectId();
if (SysDeptIsSubsetEnum.NO.getCode().equals(isSubset) && newProjectId != null) { if (newProjectId != null && !Objects.equals(oldProjectId, newProjectId)) {
// 检查新项目是否存在 // 检查新项目是否存在
BusProject project = projectService.getById(newProjectId); BusProject project = projectService.getById(newProjectId);
if (project == null) { if (project == null) {
@ -507,25 +526,53 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
throw new ServiceException("该项目已被其他部门绑定", HttpStatus.CONFLICT); throw new ServiceException("该项目已被其他部门绑定", HttpStatus.CONFLICT);
} }
// 获取当前部门及其上级部门 ID 列表 // 获取当前部门及其上级部门 ID 列表
List<Long> deptIds = this.getParentDeptIds(dept); List<Long> deptIds = this.getParentAndSiblingDeptIds(dept);
// 获取部门用户 ID // 获取部门用户 ID
LambdaQueryWrapper<SysUser> lqw = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysUser> lqw = new LambdaQueryWrapper<>();
lqw.select(SysUser::getUserId); lqw.select(SysUser::getUserId);
lqw.in(SysUser::getDeptId, deptIds); lqw.in(SysUser::getDeptId, deptIds);
List<Long> userIds = userMapper.selectList(lqw).stream() List<Long> userIds = userMapper.selectList(lqw).stream()
.map(SysUser::getUserId) .map(SysUser::getUserId)
.filter(userId -> !LoginHelper.isSuperAdmin(userId))
.toList(); .toList();
if (CollUtil.isNotEmpty(userIds)) { if (CollUtil.isNotEmpty(userIds)) {
// 情况 1原本有项目且项目 ID 改变 → 删除旧的,添加新的 // 情况 1原本有项目且项目 ID 改变 → 删除旧的,添加新的
if (oldProjectId != null && !Objects.equals(oldProjectId, newProjectId)) { if (oldProjectId != null) {
userProjectRelevancyService.deleteByProjectAndUserIds(oldProjectId, userIds); userProjectRelevancyService.deleteByProjectAndUserIds(oldProjectId, userIds);
userProjectRelevancyService.saveBatchByUserList(newProjectId, userIds); userProjectRelevancyService.saveBatchByUserList(newProjectId, userIds);
} } else {
// 情况 2原本没有项目现在新增了 → 直接添加 // 情况 2原本没有项目现在新增了 → 直接添加
if (oldProjectId == null) {
userProjectRelevancyService.saveBatchByUserList(newProjectId, userIds); userProjectRelevancyService.saveBatchByUserList(newProjectId, userIds);
} }
} }
dept.setProjectId(newProjectId);
}
} else if (SysDeptTypeEnum.CONTRACT.getCode().equals(deptType)) {
Long oldContractorId = oldDept.getContractorId();
Long newContractorId = dept.getContractorId();
if (!oldDept.getProjectId().equals(dept.getProjectId())) {
throw new ServiceException("分包方不属于当前项目,请重新选择", HttpStatus.BAD_REQUEST);
}
if (newContractorId != null && !Objects.equals(oldContractorId, newContractorId)) {
SubContractor contractor = contractorService.getById(newContractorId);
// 检查分包方是否存在
if (contractor == null) {
throw new ServiceException("关联分包方不存在", HttpStatus.NOT_FOUND);
}
// 检查分包方所属项目是否与当前部门所属项目一致
if (!contractor.getProjectId().equals(dept.getProjectId())) {
throw new ServiceException("分包方不属于当前项目,请重新选择", HttpStatus.BAD_REQUEST);
}
// 判断新选择分包方是否被绑定
Long contractorCount = baseMapper.selectCount(
new LambdaQueryWrapper<SysDept>()
.eq(SysDept::getContractorId, newContractorId)
);
if (contractorCount > 0) {
throw new ServiceException("该分包方已被其他部门绑定", HttpStatus.CONFLICT);
}
dept.setContractorId(newContractorId);
}
} }
int result = baseMapper.updateById(dept); int result = baseMapper.updateById(dept);
if (SystemConstants.NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors()) if (SystemConstants.NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors())
@ -534,23 +581,6 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
updateParentDeptStatusNormal(dept); updateParentDeptStatusNormal(dept);
} }
return result; return result;
// if (bo.getIsSubset().equals("1")) {
// return result;
// }
// // cory 角色修改
// SysRoleBo role = getSysRoleBo(bo);
// roleService.checkRoleAllowed(role);
// roleService.checkRoleDataScope(role.getRoleId());
// if (!roleService.checkRoleNameUnique(role)) {
// throw new ServiceException("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
// } else if (!roleService.checkRoleKeyUnique(role)) {
// throw new ServiceException("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
// }
// if (roleService.updateRole(role) > 0) {
// roleService.cleanOnlineUserByRole(role.getRoleId());
// return result;
// }
// throw new ServiceException("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
} }
/** /**
@ -606,26 +636,51 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
} }
/** /**
* 获取部门以及父部门ID列表 * 获取当前部门的祖先ID、自己ID、以及所有祖先的“同级部门ID
* *
* @param dept 部门 * @param dept 当前部门
* @return 部门ID列表 * @return 部门ID列表(祖先、自身、父级的同级)
*/ */
public List<Long> getParentDeptIds(SysDept dept) { public List<Long> getParentAndSiblingDeptIds(SysDept dept) {
List<Long> deptIds = new ArrayList<>(); Set<Long> deptIds = new LinkedHashSet<>();
// 同级是否有特殊部门
Long parentId = dept.getParentId();
if (parentId != null) {
// 获取父级部门同级特殊部门(不包括它自己)
List<SysDept> siblingDepts = baseMapper.selectList(
new LambdaQueryWrapper<SysDept>()
.eq(SysDept::getParentId, parentId)
.eq(SysDept::getDeptType, SysDeptTypeEnum.SPECIAL.getCode())
.ne(SysDept::getDeptId, dept.getDeptId())
);
if (CollUtil.isNotEmpty(siblingDepts)) {
for (SysDept sibling : siblingDepts) {
deptIds.add(sibling.getDeptId());
}
}
}
// 祖先ID列表
if (StringUtils.isNotBlank(dept.getAncestors())) { if (StringUtils.isNotBlank(dept.getAncestors())) {
String[] ids = dept.getAncestors().split(","); String[] ancestorIds = dept.getAncestors().split(",");
for (String id : ids) { for (String ancestorIdStr : ancestorIds) {
if (!"0".equals(id)) { if (!"0".equals(ancestorIdStr)) {
deptIds.add(Long.parseLong(id)); Long ancestorId = Long.parseLong(ancestorIdStr);
deptIds.add(ancestorId);
// 获取该父级的同级部门(不包括它自己)
List<SysDept> siblingDepts = baseMapper.selectList(
new LambdaQueryWrapper<SysDept>()
.eq(SysDept::getParentId, baseMapper.selectById(ancestorId).getParentId())
.ne(SysDept::getDeptId, ancestorId)
);
for (SysDept sibling : siblingDepts) {
deptIds.add(sibling.getDeptId());
}
} }
} }
} }
// 加上自己 // 加上自己
deptIds.add(dept.getDeptId()); deptIds.add(dept.getDeptId());
return deptIds; return new ArrayList<>(deptIds);
} }
} }

View File

@ -23,13 +23,12 @@ import org.dromara.common.core.utils.*;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.project.domain.dto.userprojectrelevancy.BusUserProjectRelevancyCreateReq;
import org.dromara.project.service.IBusUserProjectRelevancyService; import org.dromara.project.service.IBusUserProjectRelevancyService;
import org.dromara.system.domain.*; import org.dromara.system.domain.*;
import org.dromara.system.domain.bo.SysUserBo; import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.domain.vo.SysPostVo; import org.dromara.system.domain.enums.SysDeptTypeEnum;
import org.dromara.system.domain.vo.SysRoleVo; import org.dromara.system.domain.vo.*;
import org.dromara.system.domain.vo.SysUserExportVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.*; import org.dromara.system.mapper.*;
import org.dromara.system.service.ISysDeptService; import org.dromara.system.service.ISysDeptService;
import org.dromara.system.service.ISysUserFileService; import org.dromara.system.service.ISysUserFileService;
@ -334,9 +333,19 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
insertUserPost(user, false); insertUserPost(user, false);
// 新增用户与角色管理 // 新增用户与角色管理
insertUserRole(user, false); insertUserRole(user, false);
Long deptId = user.getDeptId();
SysDeptVo deptVo = deptService.selectDeptById(deptId);
if (deptVo.getDeptType().equals(SysDeptTypeEnum.CONTRACT.getCode())) {
// 关联分包部门所属项目
BusUserProjectRelevancyCreateReq req = new BusUserProjectRelevancyCreateReq();
req.setUserId(user.getUserId());
req.setProjectId(deptVo.getProjectId());
userProjectRelevancyService.insertByBo(req);
} else {
// 关联部门所属项目 // 关联部门所属项目
List<Long> projectIds = deptService.selectProjectIdById(user.getDeptId()); List<Long> projectIds = deptService.selectProjectIdById(deptId);
userProjectRelevancyService.saveBatchByProjectList(projectIds, user.getUserId()); userProjectRelevancyService.saveBatchByProjectList(projectIds, user.getUserId());
}
return rows; return rows;
} }
@ -369,17 +378,35 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
insertUserRole(user, true); insertUserRole(user, true);
// 新增用户与岗位管理 // 新增用户与岗位管理
insertUserPost(user, true); insertUserPost(user, true);
// 获取旧的系统用户
SysUser oldUser = baseMapper.selectById(user.getUserId());
SysUser sysUser = MapstructUtils.convert(user, SysUser.class); SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
// 防止错误更新后导致的数据误删除 // 防止错误更新后导致的数据误删除
int flag = baseMapper.updateById(sysUser); int flag = baseMapper.updateById(sysUser);
if (flag < 1) { if (flag < 1) {
throw new ServiceException("修改用户" + user.getUserName() + "信息失败"); throw new ServiceException("修改用户" + user.getUserName() + "信息失败");
} }
// 没有修改部门则不需要修改用户与项目的关联
if (oldUser.getDeptId().equals(user.getDeptId())) {
return flag;
}
Long deptId = user.getDeptId();
SysDeptVo deptVo = deptService.selectDeptById(deptId);
if (deptVo.getDeptType().equals(SysDeptTypeEnum.CONTRACT.getCode())) {
// 先删除旧关联
userProjectRelevancyService.deleteByUserId(user.getUserId());
// 添加新关联
BusUserProjectRelevancyCreateReq req = new BusUserProjectRelevancyCreateReq();
req.setUserId(user.getUserId());
req.setProjectId(deptVo.getProjectId());
userProjectRelevancyService.insertByBo(req);
} else {
// 先删除旧关联 // 先删除旧关联
userProjectRelevancyService.deleteByUserId(user.getUserId()); userProjectRelevancyService.deleteByUserId(user.getUserId());
// 添加新关联 // 添加新关联
List<Long> projectIds = deptService.selectProjectIdById(user.getDeptId()); List<Long> projectIds = deptService.selectProjectIdById(user.getDeptId());
userProjectRelevancyService.saveBatchByProjectList(projectIds, user.getUserId()); userProjectRelevancyService.saveBatchByProjectList(projectIds, user.getUserId());
}
return flag; return flag;
} }