Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
		| @ -124,4 +124,10 @@ public interface UserService { | ||||
|      */ | ||||
|     Map<Long, String> selectPostNamesByIds(List<Long> postIds); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 通过用户id查询头像 | ||||
|      */ | ||||
|     String selectAvatarById(Long userId); | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -90,6 +90,27 @@ public class SubConstructionUserController extends BaseController { | ||||
|         return constructionUserService.queryPageList(req, pageQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 新人池 | ||||
|      */ | ||||
|     @SaCheckPermission("contractor:constructionUser:newUserList") | ||||
|     @GetMapping("/newUserList") | ||||
|     public TableDataInfo<SubConstructionUserVo> newUserList(SubConstructionUserQueryReq req, PageQuery pageQuery) { | ||||
|         return constructionUserService.queryNewUserPageList(req, pageQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 分配 | ||||
|      */ | ||||
|     @SaCheckPermission("contractor:constructionUser:allocate") | ||||
|     @PutMapping("/allocate") | ||||
|     @RepeatSubmit() | ||||
|     public R<Boolean> allocate(@RequestBody @Validated AllocateDto dto) { | ||||
|         return R.ok(constructionUserService.allocate(dto)); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 查询每个施工人员总的考勤列表 | ||||
|      */ | ||||
|  | ||||
| @ -0,0 +1,60 @@ | ||||
| package org.dromara.contractor.domain.dto.constructionuser; | ||||
|  | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025/3/5 14:31 | ||||
|  */ | ||||
|  | ||||
| @Data | ||||
| public class AllocateDto implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 3252651952758479341L; | ||||
|  | ||||
|  | ||||
|     @NotNull(message = "数据Id") | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 项目id | ||||
|      */ | ||||
|     @NotNull(message = "项目不能为空") | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
|      * 分包公司id | ||||
|      */ | ||||
|     @NotNull(message = "分包不能为空") | ||||
|     private Long contractorId; | ||||
|  | ||||
|     /** | ||||
|      * 班组id | ||||
|      */ | ||||
|     @NotNull(message = "班组不能为空") | ||||
|     private Long teamId; | ||||
|  | ||||
|     /** | ||||
|      * 部门id | ||||
|      */ | ||||
|     @NotNull(message = "部门不能为空") | ||||
|     private Long deptId; | ||||
|  | ||||
|     /** | ||||
|      * 工种(字典type_of_work) | ||||
|      */ | ||||
|     @NotNull(message = "工种不能为空") | ||||
|     private String typeOfWork; | ||||
|  | ||||
|     /** | ||||
|      * 岗位(默认为0普通员工,1组长) | ||||
|      */ | ||||
|     @NotNull(message = "岗位不能为空") | ||||
|     private String postId; | ||||
|  | ||||
| } | ||||
| @ -41,6 +41,9 @@ public interface ISubConstructionUserService extends IService<SubConstructionUse | ||||
|      */ | ||||
|     TableDataInfo<SubConstructionUserVo> queryPageList(SubConstructionUserQueryReq req, PageQuery pageQuery); | ||||
|  | ||||
|     TableDataInfo<SubConstructionUserVo> queryNewUserPageList(SubConstructionUserQueryReq req, PageQuery pageQuery); | ||||
|  | ||||
|     Boolean allocate(AllocateDto dto); | ||||
|     /** | ||||
|      * 分页查询施工人员考勤列表 | ||||
|      * | ||||
|  | ||||
| @ -45,20 +45,20 @@ import org.dromara.contractor.mapper.SubConstructionUserMapper; | ||||
| import org.dromara.contractor.service.ISubConstructionUserFileService; | ||||
| import org.dromara.contractor.service.ISubConstructionUserService; | ||||
| import org.dromara.contractor.service.ISubContractorService; | ||||
| import org.dromara.project.domain.BusAttendance; | ||||
| import org.dromara.project.domain.BusProject; | ||||
| import org.dromara.project.domain.BusProjectTeamMember; | ||||
| import org.dromara.project.domain.BusWorkWage; | ||||
| import org.dromara.project.domain.*; | ||||
| import org.dromara.project.domain.enums.BusAttendanceClockStatusEnum; | ||||
| import org.dromara.project.domain.enums.BusAttendanceCommuterEnum; | ||||
| import org.dromara.project.domain.enums.BusConstructionUserAttendanceStatusEnum; | ||||
| import org.dromara.project.service.*; | ||||
| import org.dromara.system.domain.SysUser; | ||||
| import org.dromara.system.domain.SysUserRole; | ||||
| import org.dromara.system.domain.bo.SysUserBo; | ||||
| import org.dromara.system.domain.vo.SysOssVo; | ||||
| import org.dromara.system.domain.vo.SysUserVo; | ||||
| import org.dromara.system.mapper.SysUserRoleMapper; | ||||
| import org.dromara.system.service.ISysDictTypeService; | ||||
| import org.dromara.system.service.ISysOssService; | ||||
| import org.dromara.system.service.ISysRoleService; | ||||
| import org.dromara.system.service.ISysUserService; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| import org.springframework.beans.BeanUtils; | ||||
| @ -92,6 +92,10 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU | ||||
|     @Resource | ||||
|     private ISubContractorService contractorService; | ||||
|  | ||||
|     @Lazy | ||||
|     @Resource | ||||
|     private IBusProjectTeamService projectTeamService; | ||||
|  | ||||
|     @Lazy | ||||
|     @Resource | ||||
|     private IBusProjectTeamMemberService projectTeamMemberService; | ||||
| @ -131,6 +135,18 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU | ||||
|     @Resource | ||||
|     private ISysUserService userService; | ||||
|  | ||||
|     @Lazy | ||||
|     @Resource | ||||
|     private IBusUserProjectRelevancyService userProjectRelevancyService; | ||||
|  | ||||
|     @Lazy | ||||
|     @Resource | ||||
|     private SysUserRoleMapper userRoleMapper; | ||||
|  | ||||
|     @Lazy | ||||
|     @Resource | ||||
|     private ISysRoleService roleService; | ||||
|  | ||||
|     /** | ||||
|      * 查询施工人员 | ||||
|      * | ||||
| @ -161,6 +177,100 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU | ||||
|         return TableDataInfo.build(getVoPage(result)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public TableDataInfo<SubConstructionUserVo> queryNewUserPageList(SubConstructionUserQueryReq req, PageQuery pageQuery) { | ||||
|         LambdaQueryWrapper<SubConstructionUser> lqw = Wrappers.lambdaQuery(); | ||||
|         // 从对象中取值 | ||||
|         String userName = req.getUserName(); | ||||
|  | ||||
|         // 模糊查询 | ||||
|         lqw.like(StringUtils.isNotBlank(userName), SubConstructionUser::getUserName, userName); | ||||
|         lqw.isNull(SubConstructionUser::getProjectId); | ||||
|         lqw.isNull(SubConstructionUser::getTeamId); | ||||
|         // 添加关联查询条件:sys_user的dept_id为null | ||||
|         // 另一种写法,使用表别名 | ||||
|         lqw.apply("exists (select 1 from sys_user where user_id = sys_user_id and dept_id is null)"); | ||||
|  | ||||
|         Page<SubConstructionUser> result = this.page(pageQuery.build(), lqw); | ||||
|         List<SubConstructionUserVo> list = result.getRecords().stream().map(vo -> { | ||||
|             SubConstructionUserVo subConstructionUserVo = new SubConstructionUserVo(); | ||||
|             BeanUtils.copyProperties(vo, subConstructionUserVo); | ||||
|             // 解密身份证号码 | ||||
|             String decrypt = vo.getSfzNumber(); | ||||
|             try { | ||||
|                 decrypt = idCardEncryptorUtil.decrypt(decrypt); | ||||
|             } catch (Exception e) { | ||||
|                 log.warn("身份证解密失败"); | ||||
|             } | ||||
|             subConstructionUserVo.setSfzNumber(decrypt); | ||||
|             return subConstructionUserVo; | ||||
|         }).collect(Collectors.toList()); | ||||
|         return new TableDataInfo<>(list, result.getTotal()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public Boolean allocate(AllocateDto dto) { | ||||
|         SubConstructionUser constructionUser = baseMapper.selectById(dto.getId()); | ||||
|         if(constructionUser == null){ | ||||
|             throw new ServiceException("施工人员信息不存在", HttpStatus.ERROR); | ||||
|         } | ||||
|         constructionUser.setProjectId(dto.getProjectId()); | ||||
|         constructionUser.setContractorId(dto.getContractorId()); | ||||
|  | ||||
|         BusProjectTeam team = projectTeamService.getById(dto.getTeamId()); | ||||
|         if(team == null){ | ||||
|             throw new ServiceException("班组信息不存在", HttpStatus.ERROR); | ||||
|         } | ||||
|         constructionUser.setTeamId(dto.getTeamId()); | ||||
|         constructionUser.setTeamName(team.getTeamName()); | ||||
|         constructionUser.setTypeOfWork(dto.getTypeOfWork()); | ||||
|         constructionUser.setEntryDate(new Date()); | ||||
|         constructionUser.setFirstDate(LocalDate.now()); | ||||
|  | ||||
|         int i = baseMapper.updateById(constructionUser); | ||||
|  | ||||
|         //人员信息 | ||||
|         Long sysUserId = constructionUser.getSysUserId(); | ||||
|         SysUserBo sysUserBo = new SysUserBo(); | ||||
|         sysUserBo.setUserId(sysUserId); | ||||
|         sysUserBo.setDeptId(dto.getDeptId()); | ||||
|         userService.updateUser(sysUserBo); | ||||
|  | ||||
|         //人员与班组关联表 | ||||
|         BusProjectTeamMember projectTeamMember = new BusProjectTeamMember(); | ||||
|         projectTeamMember.setMemberId(sysUserId); | ||||
|         projectTeamMember.setTeamId(dto.getTeamId()); | ||||
|         projectTeamMember.setProjectId(dto.getProjectId()); | ||||
|         projectTeamMember.setPostId(dto.getPostId()); | ||||
|         projectTeamMemberService.save(projectTeamMember); | ||||
|  | ||||
|         //人员与项目关联表 | ||||
|         BusUserProjectRelevancy relevancy = new BusUserProjectRelevancy(); | ||||
|         relevancy.setUserId(constructionUser.getSysUserId()); | ||||
|         relevancy.setProjectId(dto.getProjectId()); | ||||
|         userProjectRelevancyService.save(relevancy); | ||||
|  | ||||
|         //设置基础角色 先清空已有角色 | ||||
|         userRoleMapper.delete(Wrappers.<SysUserRole>lambdaQuery() | ||||
|             .eq(SysUserRole::getUserId, constructionUser.getSysUserId()) | ||||
|             .eq(SysUserRole::getProjectId, dto.getProjectId()) | ||||
|             .in(SysUserRole::getRoleId, Arrays.asList(2L, 3L)) | ||||
|         ); | ||||
|         //再添加分配角色 | ||||
|         Long roleId = "0".equals(dto.getPostId()) ? 2L : 3L; | ||||
|         SysUserRole sysUserRole = new SysUserRole(); | ||||
|         sysUserRole.setUserId(constructionUser.getSysUserId()); | ||||
|         sysUserRole.setRoleId(roleId); | ||||
|         sysUserRole.setProjectId(dto.getProjectId()); | ||||
|         userRoleMapper.insert(sysUserRole); | ||||
|  | ||||
|         //强退 | ||||
|         roleService.cleanOnlineUser(Collections.singletonList(constructionUser.getSysUserId())); | ||||
|  | ||||
|         return i>0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 分页查询施工人员考勤列表 | ||||
|      * | ||||
| @ -1356,9 +1466,10 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU | ||||
|         lqw.like(StringUtils.isNotBlank(userName), SubConstructionUser::getUserName, userName); | ||||
|         lqw.eq(ObjectUtils.isNotEmpty(typeOfWork), SubConstructionUser::getTypeOfWork, typeOfWork); | ||||
|  | ||||
|         lqw.isNull(SubConstructionUser::getProjectId); | ||||
|         lqw.isNull(SubConstructionUser::getTeamId); | ||||
|  | ||||
|         lqw.and(wrapper -> wrapper.isNull(SubConstructionUser::getProjectId) | ||||
|             .or().eq(SubConstructionUser::getProjectId, req.getProjectId()) | ||||
|         ); | ||||
|         Page<SubConstructionUser> result = this.page(pageQuery.build(), lqw); | ||||
|  | ||||
|         ArrayList<SubConstructionUserAppVo> list = new ArrayList<>(); | ||||
|  | ||||
| @ -67,4 +67,15 @@ public class BusContactnoticeAppController extends BaseController { | ||||
|         return R.ok(busContactnoticeService.insertByBo(bo)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改联系单 | ||||
|      */ | ||||
|     @Log(title = "联系单", businessType = BusinessType.UPDATE) | ||||
|     @RepeatSubmit() | ||||
|     @PutMapping() | ||||
|     public R<BusContactnoticeVo> edit(@Validated(EditGroup.class) @RequestBody BusContactnoticeBo bo) { | ||||
|         return R.ok(busContactnoticeService.updateByBo(bo)); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,81 @@ | ||||
| package org.dromara.design.controller.app; | ||||
|  | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.dromara.common.core.domain.R; | ||||
| import org.dromara.common.core.enums.BusinessStatusEnum; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| import org.dromara.common.log.annotation.Log; | ||||
| import org.dromara.common.log.enums.BusinessType; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.common.web.core.BaseController; | ||||
| import org.dromara.design.domain.bo.*; | ||||
| import org.dromara.design.domain.vo.*; | ||||
| import org.dromara.design.service.IBusBillofquantitiesVersionsService; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.multipart.MultipartFile; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 工程量清单版本 | ||||
|  * | ||||
|  * @author Lion Li | ||||
|  * @date 2025-08-11 | ||||
|  */ | ||||
| @Validated | ||||
| @RequiredArgsConstructor | ||||
| @RestController | ||||
| @RequestMapping("/app/design/billofquantitiesVersions") | ||||
| public class BusBillofquantitiesVersionsAppController extends BaseController { | ||||
|  | ||||
|     private final IBusBillofquantitiesVersionsService busBillofquantitiesVersionsService; | ||||
|  | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 获取所有版本号 | ||||
|      */ | ||||
|     @GetMapping("/obtainAllVersionNumbers") | ||||
|     public TableDataInfo<BusBillofquantitiesVersionsVo> obtainAllVersionNumbers(ObtainAllVersionNumbersReq bo, PageQuery pageQuery) { | ||||
|         bo.setStatus(BusinessStatusEnum.FINISH.getStatus()); | ||||
|         return busBillofquantitiesVersionsService.obtainAllVersionNumbers(bo, pageQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取物资设备清单总数据 | ||||
|      */ | ||||
|     @GetMapping("/materialTotal/{projectId}") | ||||
|     public R<List<BusBillofquantitiesMaterialTotalVo>> queryMaterialTotalListByProject(@NotNull(message = "项目主键不能为空") | ||||
|                                                                                        @PathVariable Long projectId) { | ||||
|         return R.ok(busBillofquantitiesVersionsService.queryMaterialTotalListByProject(projectId)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取指定版本的sheet | ||||
|      */ | ||||
|     @GetMapping("/sheetList") | ||||
|     public R<List<String>> sheetList(SheetListReq bo) { | ||||
|         return R.ok(busBillofquantitiesVersionsService.sheetList(bo)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取工程量清单列表 | ||||
|      */ | ||||
|     @GetMapping("/obtainTheList") | ||||
|     public R<List<ObtainTheListRes>> obtainTheList(CoryObtainTheListReq bo, PageQuery pageQuery) { | ||||
|         return R.ok(busBillofquantitiesVersionsService.obtainTheList(bo)); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 查询工程量清单版本列表 | ||||
|      */ | ||||
|     @GetMapping("/list") | ||||
|     public TableDataInfo<BusBillofquantitiesVersionsVo> list(PageQuery pageQuery) { | ||||
|         return busBillofquantitiesVersionsService.queryPageList(new BusBillofquantitiesVersionsBo(), pageQuery); | ||||
|     } | ||||
| } | ||||
| @ -53,29 +53,17 @@ public class DesDesignChangeAppController extends BaseController { | ||||
|     /** | ||||
|      * 查询设计变更管理列表 | ||||
|      */ | ||||
|     @SaCheckPermission("design:designChange:list") | ||||
|     @GetMapping("/list") | ||||
|     public TableDataInfo<DesDesignChangeVo> list(DesDesignChangeQueryReq req, PageQuery pageQuery) { | ||||
|         return desDesignChangeService.queryPageList(req, pageQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 根据主键导出设计变更单 | ||||
|      */ | ||||
|     @SaCheckPermission("design:designChange:exportWord") | ||||
|     @Log(title = "设计变更管理", businessType = BusinessType.EXPORT) | ||||
|     @PostMapping("/export/word") | ||||
|     public void exportWordById(@NotNull(message = "主键不能为空") Long id, | ||||
|                                HttpServletResponse response) { | ||||
|         desDesignChangeService.exportWordById(id, response); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取设计变更管理详细信息 | ||||
|      * | ||||
|      * @param id 主键 | ||||
|      */ | ||||
|     @SaCheckPermission("design:designChange:query") | ||||
|     @GetMapping("/{id}") | ||||
|     public R<DesDesignChangeVo> getInfo(@NotNull(message = "主键不能为空") | ||||
|                                         @PathVariable Long id) { | ||||
| @ -85,7 +73,6 @@ public class DesDesignChangeAppController extends BaseController { | ||||
|     /** | ||||
|      * 新增设计变更管理 | ||||
|      */ | ||||
|     @SaCheckPermission("design:designChange:add") | ||||
|     @Log(title = "设计变更管理", businessType = BusinessType.INSERT) | ||||
|     @RepeatSubmit() | ||||
|     @PostMapping() | ||||
| @ -96,7 +83,6 @@ public class DesDesignChangeAppController extends BaseController { | ||||
|     /** | ||||
|      * 修改设计变更管理 | ||||
|      */ | ||||
|     @SaCheckPermission("design:designChange:edit") | ||||
|     @Log(title = "设计变更管理", businessType = BusinessType.UPDATE) | ||||
|     @RepeatSubmit() | ||||
|     @PutMapping() | ||||
| @ -104,40 +90,15 @@ public class DesDesignChangeAppController extends BaseController { | ||||
|         return R.ok(desDesignChangeService.updateByBo(req)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 删除设计变更管理 | ||||
|      * | ||||
|      * @param ids 主键串 | ||||
|      */ | ||||
|     @SaCheckPermission("design:designChange:remove") | ||||
|     @Log(title = "设计变更管理", businessType = BusinessType.DELETE) | ||||
|     @DeleteMapping("/{ids}") | ||||
|     public R<Void> remove(@NotEmpty(message = "主键不能为空") | ||||
|                           @PathVariable Long[] ids) { | ||||
|         return toAjax(desDesignChangeService.deleteByIds(List.of(ids))); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 查询选择卷册目录 | ||||
|      */ | ||||
|     @SaCheckPermission("design:designChange:catalogList") | ||||
|     @GetMapping("/catalogList/{projectId}") | ||||
|     public R<List<DesVolumeCatalogVo>> catalogList(@PathVariable("projectId") Long projectId) { | ||||
|         return R.ok(desVolumeCatalogService.catalogList(projectId)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询选择目录下的蓝图 | ||||
|      */ | ||||
|     @SaCheckPermission("design:designChange:blueprint") | ||||
|     @GetMapping("/blueprint/{volumeCatalogId}") | ||||
|     public R<List<DesVolumeFile>> blueprint(@PathVariable("volumeCatalogId") Long volumeCatalogId) { | ||||
|         List<DesVolumeFile> list = desVolumeFileService.list(Wrappers.lambdaQuery(DesVolumeFile.class) | ||||
|             .eq(DesVolumeFile::getVolumeCatalogId, volumeCatalogId) | ||||
|             .eq(DesVolumeFile::getType, DesVolumeFile.BLUEPRINT) | ||||
|             .eq(DesVolumeFile::getAuditStatus, BusinessStatusEnum.FINISH.getStatus())); | ||||
|         return R.ok(list); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| package org.dromara.design.domain.bo; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.Hidden; | ||||
| import jakarta.validation.constraints.NotBlank; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.Data; | ||||
| @ -28,4 +29,7 @@ public class ObtainAllVersionNumbersReq implements Serializable { | ||||
|     @NotNull(message = "项目ID不能为空") | ||||
|     private Long projectId; | ||||
|  | ||||
|     @Hidden() | ||||
|     private String status; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| package org.dromara.design.domain.vo; | ||||
|  | ||||
| import org.dromara.common.translation.annotation.Translation; | ||||
| import org.dromara.common.translation.constant.TransConstant; | ||||
| import org.dromara.design.domain.BusBillofquantitiesVersions; | ||||
| import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
| @ -67,4 +69,16 @@ public class BusBillofquantitiesVersionsVo implements Serializable { | ||||
|     @ExcelProperty(value = "审核状态") | ||||
|     private String status; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 项目ID | ||||
|      */ | ||||
|     private Long projectId; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 项目名称 | ||||
|      */ | ||||
|     @Translation(type = TransConstant.PROJECT_ID_TO_NAME, mapper = "projectId") | ||||
|     private String projectName; | ||||
| } | ||||
|  | ||||
| @ -495,10 +495,11 @@ public class BusBillofquantitiesVersionsServiceImpl extends ServiceImpl<BusBillo | ||||
|         lqw.eq(bo.getProjectId() != null, BusBillofquantitiesVersions::getProjectId, bo.getProjectId()); | ||||
|         lqw.eq(StringUtils.isNotBlank(bo.getWorkOrderType()), BusBillofquantitiesVersions::getWorkOrderType, bo.getWorkOrderType()); | ||||
|         lqw.orderByDesc(BusBillofquantitiesVersions::getCreateTime); | ||||
|         lqw.eq(StringUtils.isNotBlank(bo.getStatus()), BusBillofquantitiesVersions::getStatus, bo.getStatus()); | ||||
|         Page<BusBillofquantitiesVersionsVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); | ||||
|         result.getRecords().forEach(item -> { | ||||
|             System.out.println("1          " + item.getStatus()); | ||||
|         }); | ||||
| //        result.getRecords().forEach(item -> { | ||||
| //            System.out.println("1          " + item.getStatus()); | ||||
| //        }); | ||||
|         return TableDataInfo.build(result); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -11,6 +11,7 @@ import jakarta.validation.constraints.NotNull; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.dromara.common.core.domain.R; | ||||
| import org.dromara.common.core.domain.model.LoginUser; | ||||
| import org.dromara.common.core.exception.ServiceException; | ||||
| import org.dromara.common.core.utils.StreamUtils; | ||||
| import org.dromara.common.core.utils.StringUtils; | ||||
| import org.dromara.common.encrypt.annotation.ApiEncrypt; | ||||
| @ -167,7 +168,13 @@ public class SysUserController extends BaseController { | ||||
|     @Log(title = "用户管理", businessType = BusinessType.INSERT) | ||||
|     @PostMapping | ||||
|     public R<Void> add(@Validated @RequestBody SysUserBo user) { | ||||
|         if(user.getDeptId() == null){ | ||||
|             throw new ServiceException("请选择部门!"); | ||||
|         } | ||||
|         deptService.checkDeptDataScope(user.getDeptId()); | ||||
|         //web端新增默认为管理员 | ||||
|         user.setAppUserType("1"); | ||||
|  | ||||
|         // 去重后的所有 roleId | ||||
|         List<Long> roleList = user.getProjectRoles().stream() | ||||
|             .filter(dto -> dto.getRoleIds() != null) | ||||
|  | ||||
| @ -35,6 +35,7 @@ import org.dromara.system.domain.vo.SysRoleVo; | ||||
| import org.dromara.system.domain.vo.SysUserExportVo; | ||||
| import org.dromara.system.domain.vo.SysUserVo; | ||||
| import org.dromara.system.mapper.*; | ||||
| import org.dromara.system.service.ISysOssService; | ||||
| import org.dromara.system.service.ISysUserFileService; | ||||
| import org.dromara.system.service.ISysUserService; | ||||
| import org.springframework.cache.annotation.CacheEvict; | ||||
| @ -65,6 +66,8 @@ public class SysUserServiceImpl implements ISysUserService, UserService { | ||||
|     private final SysUserPostMapper userPostMapper; | ||||
|     private final IBusUserProjectRelevancyService userProjectRelevancyService; | ||||
|  | ||||
|     private final SysOssMapper ossMapper; | ||||
|  | ||||
|     private final ISubConstructionUserService constructionUserService; | ||||
|  | ||||
|     @Lazy | ||||
| @ -110,6 +113,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService { | ||||
|     private Wrapper<SysUser> buildQueryWrapper(SysUserBo user) { | ||||
|         Map<String, Object> params = user.getParams(); | ||||
|         QueryWrapper<SysUser> wrapper = Wrappers.query(); | ||||
|         wrapper.isNotNull("u.dept_id"); | ||||
|         wrapper.eq("u.del_flag", SystemConstants.NORMAL) | ||||
|             .eq(StringUtils.isNotBlank(user.getUserType()),"u.user_type",user.getUserType()) | ||||
|             .eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId()) | ||||
| @ -1074,4 +1078,16 @@ public class SysUserServiceImpl implements ISysUserService, UserService { | ||||
|             .collect(Collectors.toMap(SysPost::getPostId, SysPost::getPostName)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String selectAvatarById(Long userId) { | ||||
|         SysUser sysUsers = baseMapper.selectById(userId); | ||||
|        if(sysUsers == null || sysUsers.getAvatar() == null){ | ||||
|            return null; | ||||
|        } | ||||
|         SysOss sysOss = ossMapper.selectById(sysUsers.getAvatar()); | ||||
|         if(sysOss == null){ | ||||
|             return null; | ||||
|         } | ||||
|         return sysOss.getUrl(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -30,6 +30,7 @@ import org.dromara.tender.domain.bo.BusBiddingPlanBo; | ||||
| import org.dromara.tender.domain.vo.BusBiddingPlanVo; | ||||
| import org.dromara.tender.mapper.BusBiddingPlanMapper; | ||||
| import org.dromara.tender.service.IBusBiddingPlanService; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
| import org.springframework.web.multipart.MultipartFile; | ||||
|  | ||||
| import java.math.BigDecimal; | ||||
| @ -130,6 +131,7 @@ public class BusBiddingPlanServiceImpl extends ServiceImpl<BusBiddingPlanMapper, | ||||
|      * @return 是否新增成功 | ||||
|      */ | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public Boolean insertByBo(BusBiddingPlanBo bo) { | ||||
|         BusBiddingPlan add = MapstructUtils.convert(bo, BusBiddingPlan.class); | ||||
|         validEntityBeforeSave(add); | ||||
| @ -177,6 +179,7 @@ public class BusBiddingPlanServiceImpl extends ServiceImpl<BusBiddingPlanMapper, | ||||
|      * @return 是否修改成功 | ||||
|      */ | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public Boolean updateByBo(BusBiddingPlanBo bo) { | ||||
|         if (bo.getBidStatus() == 1){ | ||||
|             throw new ServiceException("数据已锁定,不允许继续上传附件"); | ||||
|  | ||||
| @ -223,7 +223,7 @@ public class BusBillofquantitiesLimitListServiceImpl extends ServiceImpl<BusBill | ||||
|         BusBLimitListVersionsBo listVersions = new BusBLimitListVersionsBo(); | ||||
|         listVersions.setProjectId(bo.getProjectId()); | ||||
|         listVersions.setWorkOrderType(bo.getWorkOrderType()); | ||||
|         listVersions.setStatus(BusinessStatusEnum.FINISH.getStatus()); | ||||
| //        listVersions.setStatus(BusinessStatusEnum.FINISH.getStatus()); | ||||
|         return busBLimitListVersionsService.queryList(listVersions); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -0,0 +1,182 @@ | ||||
| package org.dromara.workflow.controller.app; | ||||
|  | ||||
| import cn.hutool.core.util.StrUtil; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.dromara.common.core.domain.R; | ||||
| import org.dromara.common.core.domain.dto.UserDTO; | ||||
| import org.dromara.common.core.enums.BusinessStatusEnum; | ||||
| import org.dromara.common.core.service.UserService; | ||||
| import org.dromara.warm.flow.core.FlowEngine; | ||||
| import org.dromara.warm.flow.core.dto.DefJson; | ||||
| import org.dromara.warm.flow.core.dto.NodeJson; | ||||
| import org.dromara.warm.flow.core.entity.Instance; | ||||
| import org.dromara.warm.flow.core.invoker.FrameInvoker; | ||||
| import org.dromara.warm.flow.ui.service.ChartExtService; | ||||
| import org.dromara.workflow.common.ConditionalOnEnable; | ||||
| import org.dromara.workflow.domain.bo.FlowCategoryBo; | ||||
| import org.dromara.workflow.domain.vo.FlowAppVo; | ||||
| import org.dromara.workflow.domain.vo.FlowCategoryVo; | ||||
| import org.dromara.workflow.domain.vo.FlowHisTaskVo; | ||||
| import org.dromara.workflow.service.IFlwInstanceService; | ||||
| import org.dromara.workflow.service.IFlwTaskAssigneeService; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import java.util.*; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| @ConditionalOnEnable | ||||
| @Validated | ||||
| @RequiredArgsConstructor | ||||
| @RestController | ||||
| @RequestMapping("/app/workflow/") | ||||
| public class FlowAppController { | ||||
|  | ||||
|     private final IFlwInstanceService flwInstanceService; | ||||
|  | ||||
|     private final UserService userService; | ||||
|  | ||||
|     private final IFlwTaskAssigneeService flwTaskAssigneeService; | ||||
|  | ||||
|     @GetMapping("/{businessId}") | ||||
|     public R<List<FlowAppVo>> list(@PathVariable("businessId") String businessId,Long projectId) { | ||||
|         Map<String, Object> stringObjectMap; | ||||
|         try { | ||||
|             stringObjectMap = flwInstanceService.flowHisTaskList(businessId); | ||||
|         } catch (Exception e) { | ||||
|             return R.ok(null,null); | ||||
|         } | ||||
|  | ||||
|         List<FlowHisTaskVo>  list= (List<FlowHisTaskVo>) stringObjectMap.get("list"); | ||||
|         Map<String, FlowHisTaskVo> map = list.stream().collect(Collectors.toMap(FlowHisTaskVo::getNodeCode, vo -> vo)); | ||||
|  | ||||
|  | ||||
|         String instanceId = (String) stringObjectMap.get("instanceId"); | ||||
|         String defJsonStr = ((Instance) FlowEngine.insService().getById(instanceId)).getDefJson(); | ||||
|         DefJson defJson = (DefJson)FlowEngine.jsonConvert.strToBean(defJsonStr, DefJson.class); | ||||
|         ChartExtService chartExtService = (ChartExtService) FrameInvoker.getBean(ChartExtService.class); | ||||
|         if (chartExtService != null) { | ||||
|             chartExtService.initPromptContent(defJson); | ||||
|             chartExtService.execute(defJson); | ||||
|         } | ||||
|  | ||||
|         List<NodeJson> nodeList = defJson.getNodeList(); | ||||
|         List<NodeJson> nodeJsons = sortNodeList(nodeList); | ||||
|         List<FlowAppVo> appVoList =  new ArrayList<>(); | ||||
|         for (NodeJson nodeJson : nodeJsons ){ | ||||
|             FlowAppVo appVo = new FlowAppVo(); | ||||
|  | ||||
|             appVo.setNodeName(nodeJson.getNodeName()); | ||||
|             appVo.setStatus(nodeJson.getStatus()); | ||||
|             appVo.setNodeType(nodeJson.getNodeType()); | ||||
|             String nodeCode = nodeJson.getNodeCode(); | ||||
|             FlowHisTaskVo flowHisTaskVo = map.get(nodeCode); | ||||
|             if(flowHisTaskVo != null){ | ||||
|                 appVo.setFlowStatus(flowHisTaskVo.getFlowStatus()); | ||||
|                 if(BusinessStatusEnum.WAITING.getStatus().equals(flowHisTaskVo.getFlowStatus())){ | ||||
|                     appVo.setAuditName(flowHisTaskVo.getApproveName()); | ||||
|                 }else { | ||||
|                     appVo.setApproveName(flowHisTaskVo.getApproveName()); | ||||
|                     if(StrUtil.isNotBlank(flowHisTaskVo.getApprover())){ | ||||
|                         appVo.setApproveAvatar(userService.selectAvatarById(Long.valueOf(flowHisTaskVo.getApprover()))); | ||||
|                     } | ||||
|                 } | ||||
|             }else { | ||||
|                 appVo.setFlowStatus(BusinessStatusEnum.WAITING.getStatus()); | ||||
|                 if(nodeJson.getNodeType()==1){ | ||||
|                     String permissionFlag = nodeJson.getPermissionFlag(); | ||||
|                     List<UserDTO> userDTOS = flwTaskAssigneeService.fetchUsersByStorageIds(permissionFlag, projectId); | ||||
|                     String auditName = userDTOS.stream().map(UserDTO::getNickName).collect(Collectors.joining(",")); | ||||
|                     appVo.setAuditName(auditName); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return R.ok(appVoList); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public List<NodeJson> sortNodeList(List<NodeJson> nodeList) { | ||||
|         // 1. 分离不同类型的节点 | ||||
|         NodeJson startNode = null;          // nodeType=0 | ||||
|         NodeJson endNode = null;            // nodeType=2 | ||||
|         List<NodeJson> approvalNodes = new ArrayList<>();  // nodeType=1 | ||||
|  | ||||
|         for (NodeJson node : nodeList) { | ||||
|             if (node.getNodeType() == 0) { | ||||
|                 startNode = node; | ||||
|             } else if (node.getNodeType() == 2) { | ||||
|                 endNode = node; | ||||
|             } else if (node.getNodeType() == 1) { | ||||
|                 approvalNodes.add(node); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // 2. 对审批节点(nodeType=1)按流程顺序排序 | ||||
|         List<NodeJson> sortedApprovalNodes = sortApprovalNodes(approvalNodes, startNode); | ||||
|  | ||||
|         // 3. 组合最终排序结果:开始节点 → 排序后的审批节点 → 结束节点 | ||||
|         List<NodeJson> result = new ArrayList<>(); | ||||
|         if (startNode != null) { | ||||
|             result.add(startNode); | ||||
|         } | ||||
|         result.addAll(sortedApprovalNodes); | ||||
|         if (endNode != null) { | ||||
|             result.add(endNode); | ||||
|         } | ||||
|  | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 对审批节点按流程流转顺序排序 | ||||
|      */ | ||||
|     private List<NodeJson> sortApprovalNodes(List<NodeJson> approvalNodes, NodeJson startNode) { | ||||
|         // 创建节点编码到节点对象的映射,方便快速查找 | ||||
|         Map<String, NodeJson> nodeMap = approvalNodes.stream() | ||||
|             .collect(Collectors.toMap(NodeJson::getNodeCode, node -> node)); | ||||
|  | ||||
|         List<NodeJson> sortedList = new ArrayList<>(); | ||||
|  | ||||
|         // 从开始节点的下一个节点开始 | ||||
|         String currentNodeCode = getFirstApprovalNodeCode(startNode); | ||||
|         if (currentNodeCode == null) { | ||||
|             return sortedList; // 没有找到起始审批节点,返回空列表 | ||||
|         } | ||||
|  | ||||
|         // 循环查找下一个节点,直到找不到或形成闭环 | ||||
|         Set<String> visited = new HashSet<>(); | ||||
|         while (currentNodeCode != null && nodeMap.containsKey(currentNodeCode) && !visited.contains(currentNodeCode)) { | ||||
|             visited.add(currentNodeCode); | ||||
|             NodeJson currentNode = nodeMap.get(currentNodeCode); | ||||
|             sortedList.add(currentNode); | ||||
|  | ||||
|             // 获取下一个节点编码 | ||||
|             currentNodeCode = getNextNodeCode(currentNode); | ||||
|         } | ||||
|  | ||||
|         return sortedList; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取开始节点指向的第一个审批节点编码 | ||||
|      */ | ||||
|     private String getFirstApprovalNodeCode(NodeJson startNode) { | ||||
|         if (startNode == null || startNode.getSkipList() == null || startNode.getSkipList().isEmpty()) { | ||||
|             return null; | ||||
|         } | ||||
|         // 取第一个流转关系的下一个节点编码 | ||||
|         return startNode.getSkipList().getFirst().getNextNodeCode(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取当前节点指向的下一个节点编码 | ||||
|      */ | ||||
|     private String getNextNodeCode(NodeJson currentNode) { | ||||
|         if (currentNode == null || currentNode.getSkipList() == null || currentNode.getSkipList().isEmpty()) { | ||||
|             return null; | ||||
|         } | ||||
|         // 取第一个流转关系的下一个节点编码 | ||||
|         return currentNode.getSkipList().getFirst().getNextNodeCode(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,50 @@ | ||||
| package org.dromara.workflow.domain.vo; | ||||
|  | ||||
|  | ||||
| import lombok.Data; | ||||
| import org.dromara.common.core.domain.dto.UserDTO; | ||||
|  | ||||
| import java.security.PrivilegedAction; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| @Data | ||||
| public class FlowAppVo { | ||||
|  | ||||
|     /** | ||||
|      * 节点类型 0-开始 1-中间 2-结束 | ||||
|      */ | ||||
|     private Integer nodeType; | ||||
|  | ||||
|     /** | ||||
|      * 节点名称 | ||||
|      */ | ||||
|     private String nodeName; | ||||
|  | ||||
|     /** | ||||
|      * 审核状态 | ||||
|      */ | ||||
|     private String flowStatus; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 审核人 | ||||
|      */ | ||||
|     private String auditName; | ||||
|  | ||||
|     /** | ||||
|      * 审批操作人 | ||||
|      */ | ||||
|     private String approveName; | ||||
|  | ||||
|     /** | ||||
|      * 审批操作人头像 | ||||
|      */ | ||||
|     private String approveAvatar; | ||||
|  | ||||
|     /** | ||||
|      * 节点状态 0-未开始 1-进行中  2-已完成 | ||||
|      */ | ||||
|     private Integer status; | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user