This commit is contained in:
zt
2025-09-25 15:17:53 +08:00
parent af83c40d98
commit a34c07c64e
15 changed files with 567 additions and 49 deletions

View File

@ -124,4 +124,10 @@ public interface UserService {
*/
Map<Long, String> selectPostNamesByIds(List<Long> postIds);
/**
* 通过用户id查询头像
*/
String selectAvatarById(Long userId);
}

View File

@ -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));
}
/**
* 查询每个施工人员总的考勤列表
*/

View File

@ -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;
}

View File

@ -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);
/**
* 分页查询施工人员考勤列表
*

View File

@ -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,92 @@ 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
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);
//人员与班组关联表
BusProjectTeamMember projectTeamMember = new BusProjectTeamMember();
projectTeamMember.setMemberId(constructionUser.getSysUserId());
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 +1458,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<>();

View File

@ -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));
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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,11 @@ 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());
// 去重后的所有 roleId
List<Long> roleList = user.getProjectRoles().stream()
.filter(dto -> dto.getRoleIds() != null)

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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;
}