修改bbug
This commit is contained in:
@@ -18,8 +18,10 @@ import com.ruoyi.hrm.domain.vo.HrmMyApplyVo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmReimburseReqVo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmSealReqVo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmTravelReqVo;
|
||||
import com.ruoyi.hrm.domain.HrmFlowInstance;
|
||||
import com.ruoyi.hrm.mapper.HrmAppropriationReqMapper;
|
||||
import com.ruoyi.hrm.mapper.HrmEmployeeMapper;
|
||||
import com.ruoyi.hrm.mapper.HrmFlowInstanceMapper;
|
||||
import com.ruoyi.hrm.mapper.HrmLeaveReqMapper;
|
||||
import com.ruoyi.hrm.mapper.HrmReimburseReqMapper;
|
||||
import com.ruoyi.hrm.mapper.HrmSealReqMapper;
|
||||
@@ -32,7 +34,9 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -48,6 +52,7 @@ public class HrmMyApplyController extends BaseController {
|
||||
private final HrmSealReqMapper sealReqMapper;
|
||||
private final HrmReimburseReqMapper reimburseReqMapper;
|
||||
private final HrmAppropriationReqMapper appropriationReqMapper;
|
||||
private final HrmFlowInstanceMapper flowInstanceMapper;
|
||||
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<HrmMyApplyVo> list(String bizType, String status, String keyword, PageQuery pageQuery) {
|
||||
@@ -80,6 +85,9 @@ public class HrmMyApplyController extends BaseController {
|
||||
all.addAll(mapAppropriation(appropriationReqMapper.selectVoWithProjectList(buildAppropriationBo(emp.getEmpId(), status)), nickName));
|
||||
}
|
||||
|
||||
// 用流程实例状态覆盖业务表状态,避免历史数据状态未同步
|
||||
overrideStatusByFlowInstance(all);
|
||||
|
||||
if (keyword != null && !keyword.isEmpty()) {
|
||||
String lower = keyword.toLowerCase();
|
||||
all = all.stream().filter(v -> contains(v, lower)).collect(Collectors.toList());
|
||||
@@ -93,6 +101,34 @@ public class HrmMyApplyController extends BaseController {
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
private void overrideStatusByFlowInstance(List<HrmMyApplyVo> all) {
|
||||
if (all == null || all.isEmpty()) return;
|
||||
Map<String, List<Long>> bizIdsByType = all.stream()
|
||||
.filter(v -> v.getBizType() != null && v.getBizId() != null)
|
||||
.collect(Collectors.groupingBy(
|
||||
HrmMyApplyVo::getBizType,
|
||||
Collectors.mapping(HrmMyApplyVo::getBizId, Collectors.toList())
|
||||
));
|
||||
Map<String, String> statusByKey = new HashMap<>();
|
||||
bizIdsByType.forEach((bizType, bizIds) -> {
|
||||
if (bizIds.isEmpty()) return;
|
||||
List<HrmFlowInstance> insts = flowInstanceMapper.selectList(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<HrmFlowInstance>()
|
||||
.eq(HrmFlowInstance::getBizType, bizType)
|
||||
.in(HrmFlowInstance::getBizId, bizIds)
|
||||
);
|
||||
for (HrmFlowInstance inst : insts) {
|
||||
if (inst.getStatus() == null) continue;
|
||||
statusByKey.merge(bizType + "_" + inst.getBizId(), inst.getStatus(),
|
||||
(oldS, newS) -> oldS);
|
||||
}
|
||||
});
|
||||
for (HrmMyApplyVo v : all) {
|
||||
String s = statusByKey.get(v.getBizType() + "_" + v.getBizId());
|
||||
if (s != null) v.setStatus(s);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean contains(HrmMyApplyVo v, String lower) {
|
||||
return Objects.toString(v.getTitle(), "").toLowerCase().contains(lower)
|
||||
|| Objects.toString(v.getRemark(), "").toLowerCase().contains(lower)
|
||||
@@ -109,7 +145,7 @@ public class HrmMyApplyController extends BaseController {
|
||||
|
||||
private List<HrmMyApplyVo> mapLeave(List<HrmLeaveReqVo> list, String nickName) { return list.stream().map(v -> toVo("leave", v.getBizId(), v.getEmpId(), nickName, v.getReason(), v.getStatus(), v.getCreateTime())).collect(Collectors.toList()); }
|
||||
private List<HrmMyApplyVo> mapTravel(List<HrmTravelReqVo> list, String nickName) { return list.stream().map(v -> toVo("travel", v.getBizId(), v.getEmpId(), nickName, v.getReason(), v.getStatus(), v.getCreateTime())).collect(Collectors.toList()); }
|
||||
private List<HrmMyApplyVo> mapSeal(List<HrmSealReqVo> list, String nickName) { return list.stream().map(v -> toVo("seal", v.getBizId(), v.getEmpId(), nickName, v.getRemark(), v.getStatus(), v.getCreateTime())).collect(Collectors.toList()); }
|
||||
private List<HrmMyApplyVo> mapSeal(List<HrmSealReqVo> list, String nickName) { return list.stream().map(v -> toVo("seal", v.getBizId(), v.getEmpId(), nickName, v.getPurpose() != null ? v.getPurpose() : v.getRemark(), v.getStatus(), v.getCreateTime())).collect(Collectors.toList()); }
|
||||
private List<HrmMyApplyVo> mapReimburse(List<HrmReimburseReqVo> list, String nickName) { return list.stream().map(v -> toVo("reimburse", v.getBizId(), v.getEmpId(), nickName, v.getReason(), v.getStatus(), v.getCreateTime())).collect(Collectors.toList()); }
|
||||
private List<HrmMyApplyVo> mapAppropriation(List<HrmAppropriationReqVo> list, String nickName) { return list.stream().map(v -> toVo("appropriation", v.getBizId(), v.getEmpId(), nickName, v.getReason(), v.getStatus(), v.getCreateTime())).collect(Collectors.toList()); }
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class HrmFlowInstanceVo implements Serializable {
|
||||
@@ -41,4 +42,7 @@ public class HrmFlowInstanceVo implements Serializable {
|
||||
private Date createTime;
|
||||
private String updateBy;
|
||||
private Date updateTime;
|
||||
|
||||
/** 业务表回填的数据,用于列表关键信息展示 */
|
||||
private Map<String, Object> bizData;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.core.service.UserService;
|
||||
@@ -27,7 +28,9 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@@ -42,6 +45,11 @@ public class HrmFlowInstanceServiceImpl implements IHrmFlowInstanceService {
|
||||
private final UserService userService;
|
||||
private final HrmFlowCcMapper ccMapper;
|
||||
private final HrmTravelReqMapper travelReqMapper;
|
||||
private final HrmLeaveReqMapper leaveReqMapper;
|
||||
private final HrmSealReqMapper sealReqMapper;
|
||||
private final HrmReimburseReqMapper reimburseReqMapper;
|
||||
private final HrmAppropriationReqMapper appropriationReqMapper;
|
||||
private final ObjectMapper objectMapper;
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Override
|
||||
@@ -188,9 +196,55 @@ public class HrmFlowInstanceServiceImpl implements IHrmFlowInstanceService {
|
||||
}
|
||||
}
|
||||
}
|
||||
fillInstanceBizData(result.getRecords());
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void fillInstanceBizData(List<HrmFlowInstanceVo> records) {
|
||||
if (records == null || records.isEmpty()) return;
|
||||
Map<String, List<Long>> bizIdsByType = records.stream()
|
||||
.filter(v -> v.getBizType() != null && v.getBizId() != null)
|
||||
.collect(Collectors.groupingBy(
|
||||
HrmFlowInstanceVo::getBizType,
|
||||
Collectors.mapping(HrmFlowInstanceVo::getBizId, Collectors.toList())
|
||||
));
|
||||
Map<String, Object> bizDataMap = new HashMap<>();
|
||||
bizIdsByType.forEach((bizType, bizIds) -> {
|
||||
if (bizIds.isEmpty()) return;
|
||||
switch (bizType) {
|
||||
case "leave":
|
||||
leaveReqMapper.selectBatchIds(bizIds).forEach(d ->
|
||||
bizDataMap.put("leave_" + d.getBizId(), objectMapper.convertValue(d, Map.class)));
|
||||
break;
|
||||
case "travel":
|
||||
travelReqMapper.selectBatchIds(bizIds).forEach(d ->
|
||||
bizDataMap.put("travel_" + d.getBizId(), objectMapper.convertValue(d, Map.class)));
|
||||
break;
|
||||
case "seal":
|
||||
sealReqMapper.selectBatchIds(bizIds).forEach(d ->
|
||||
bizDataMap.put("seal_" + d.getBizId(), objectMapper.convertValue(d, Map.class)));
|
||||
break;
|
||||
case "reimburse":
|
||||
reimburseReqMapper.selectBatchIds(bizIds).forEach(d ->
|
||||
bizDataMap.put("reimburse_" + d.getBizId(), objectMapper.convertValue(d, Map.class)));
|
||||
break;
|
||||
case "appropriation":
|
||||
appropriationReqMapper.selectBatchIds(bizIds).forEach(d ->
|
||||
bizDataMap.put("appropriation_" + d.getBizId(), objectMapper.convertValue(d, Map.class)));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
records.forEach(vo -> {
|
||||
Object data = bizDataMap.get(vo.getBizType() + "_" + vo.getBizId());
|
||||
if (data != null) {
|
||||
vo.setBizData((Map<String, Object>) data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HrmFlowInstanceVo> queryList(HrmFlowInstanceBo bo) {
|
||||
LambdaQueryWrapper<HrmFlowInstance> lqw = buildQueryWrapper(bo);
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
<div slot="header" class="card-header">
|
||||
<span>{{ bizTitle }}</span>
|
||||
<div class="actions">
|
||||
<el-button v-if="!preview" size="mini" icon="el-icon-arrow-left" @click="$router.back()">返回</el-button>
|
||||
<el-button v-if="!isPreview" size="mini" icon="el-icon-arrow-left" @click="$router.back()">返回</el-button>
|
||||
<el-button size="mini" icon="el-icon-refresh" @click="loadDetail">刷新</el-button>
|
||||
|
||||
<el-button v-if="!preview && canApprove" type="success" size="mini" :loading="actionLoading" @click="handleApprove">
|
||||
<el-button v-if="!isPreview && canApprove" type="success" size="mini" :loading="actionLoading" @click="handleApprove">
|
||||
通过
|
||||
</el-button>
|
||||
<el-button v-if="!preview && canApprove" type="danger" size="mini" :loading="actionLoading" @click="handleReject">
|
||||
<el-button v-if="!isPreview && canApprove" type="danger" size="mini" :loading="actionLoading" @click="handleReject">
|
||||
驳回
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -53,7 +53,7 @@
|
||||
<ProjectInfo :info="detail" />
|
||||
</el-card>
|
||||
|
||||
<div v-if="!preview">
|
||||
<div v-if="!isPreview">
|
||||
<div class="block-title">审批操作</div>
|
||||
<el-card class="inner-card" shadow="never">
|
||||
<div v-if="currentTask" class="btn-row">
|
||||
@@ -75,7 +75,7 @@
|
||||
<span>操作汇报</span>
|
||||
</div>
|
||||
|
||||
<div v-if="!preview" class="comment-form">
|
||||
<div v-if="!isPreview" class="comment-form">
|
||||
<editor v-model="commentForm.commentContent" placeholder="填写操作汇报(可选)" />
|
||||
<file-upload v-model="commentForm.attachments" />
|
||||
<div class="form-actions">
|
||||
@@ -89,7 +89,7 @@
|
||||
<div class="comment-meta">
|
||||
<span class="comment-operator">{{ item.createByName }}</span>
|
||||
<span class="comment-time">{{ item.createTime }}</span>
|
||||
<el-button v-if="!preview && isSelf(item)" type="danger" size="mini" @click="handleDeleteComment(item.commentId)"
|
||||
<el-button v-if="!isPreview && isSelf(item)" type="danger" size="mini" @click="handleDeleteComment(item.commentId)"
|
||||
:loading="buttonLoading">删除</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -160,6 +160,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isPreview () {
|
||||
return this.preview || !!this.$route?.query?.preview
|
||||
},
|
||||
currentBizId () {
|
||||
return this.bizId
|
||||
},
|
||||
|
||||
@@ -46,7 +46,7 @@ export default {
|
||||
if (routePath) {
|
||||
this.$router.push({
|
||||
path: routePath,
|
||||
query: { bizId: bizId }
|
||||
query: { bizId: bizId, preview: 1 }
|
||||
})
|
||||
} else {
|
||||
this.$message.warning('无法确定申请类型对应的详情页面')
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
stripe
|
||||
border
|
||||
@row-dblclick="handleRowClick">
|
||||
<el-table-column label="编号" prop="instId" width="80" />
|
||||
<el-table-column label="类型" width="70">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="getTypeTagType(scope.row.bizType)" size="mini">{{ getTypeText(scope.row.bizType) }}</el-tag>
|
||||
@@ -80,6 +79,9 @@
|
||||
<el-table-column label="申请时间" prop="createTime" width="140">
|
||||
<template slot-scope="scope">{{ formatDate(scope.row.createTime) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="结束时间" width="140">
|
||||
<template slot-scope="scope">{{ formatFinishTime(scope.row) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="耗时" width="80">
|
||||
<template slot-scope="scope">{{ formatElapsed(scope.row) }}</template>
|
||||
</el-table-column>
|
||||
@@ -174,7 +176,7 @@ export default {
|
||||
case 'travel':
|
||||
return `${b.travelType || '出差'} · ${b.destination || '未填目的地'}${b.startTime ? ' · ' + this.formatDate(b.startTime) : ''}`
|
||||
case 'seal':
|
||||
return `${b.sealType || '用印'}${b.fileName ? ' · ' + b.fileName : ''}${b.useReason ? ' · ' + b.useReason : ''}`
|
||||
return `${b.sealType || '用印'}${b.purpose ? ' · ' + b.purpose : ''}`
|
||||
case 'reimburse':
|
||||
return `${b.reimburseType || '报销'} · ¥${b.totalAmount != null ? b.totalAmount : 0}${b.reason ? ' · ' + b.reason : ''}`
|
||||
case 'appropriation':
|
||||
@@ -192,9 +194,19 @@ export default {
|
||||
}
|
||||
return '-'
|
||||
},
|
||||
flowEndTime (row) {
|
||||
const finalStatus = ['approved', 'rejected', 'revoked', 'finished', 'complete']
|
||||
if (row.bizType === 'travel' && row.actualEndTime) return row.actualEndTime
|
||||
if (finalStatus.includes(row.status)) return row.updateTime || null
|
||||
return null
|
||||
},
|
||||
formatFinishTime (row) {
|
||||
const end = this.flowEndTime(row)
|
||||
return end ? this.formatDate(end) : '-'
|
||||
},
|
||||
formatElapsed (row) {
|
||||
if (!row.createTime) return '-'
|
||||
const end = row.finishTime || row.endTime || Date.now()
|
||||
const end = this.flowEndTime(row) || Date.now()
|
||||
const ms = new Date(end).getTime() - new Date(row.createTime).getTime()
|
||||
if (ms <= 0) return '-'
|
||||
const h = ms / 3600000
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
</el-card>
|
||||
|
||||
<!-- 盖章操作(审批通过后显示) -->
|
||||
<div v-if="canStamp" class="block-title">盖章操作</div>
|
||||
<el-card v-if="canStamp" class="inner-card" shadow="never">
|
||||
<div v-if="canStamp && !$route.query.preview" class="block-title">盖章操作</div>
|
||||
<el-card v-if="canStamp && !$route.query.preview" class="inner-card" shadow="never">
|
||||
<div class="stamp-section">
|
||||
<div class="stamp-config">
|
||||
<el-form :model="stampForm" label-width="120px" size="small">
|
||||
|
||||
Reference in New Issue
Block a user