feat: 添加审批历史页面,处于办公中心下
This commit is contained in:
@@ -6,6 +6,7 @@ import com.ruoyi.common.core.domain.PageQuery;
|
|||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.common.helper.LoginHelper;
|
||||||
import com.ruoyi.hrm.domain.bo.HrmFlowTaskBo;
|
import com.ruoyi.hrm.domain.bo.HrmFlowTaskBo;
|
||||||
import com.ruoyi.hrm.domain.bo.HrmFlowTaskApproveBo;
|
import com.ruoyi.hrm.domain.bo.HrmFlowTaskApproveBo;
|
||||||
import com.ruoyi.hrm.domain.bo.HrmSealStampBo;
|
import com.ruoyi.hrm.domain.bo.HrmSealStampBo;
|
||||||
@@ -112,4 +113,14 @@ public class HrmFlowTaskController extends BaseController {
|
|||||||
@RequestParam(required = false) String remark) {
|
@RequestParam(required = false) String remark) {
|
||||||
return toAjax(service.transfer(taskId, newAssigneeUserId, actionUserId, remark));
|
return toAjax(service.transfer(taskId, newAssigneeUserId, actionUserId, remark));
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 审批历史列表:查询当前用户的审批历史,包含分页
|
||||||
|
*/
|
||||||
|
@GetMapping("/historyList")
|
||||||
|
public TableDataInfo<HrmFlowTaskVo> historyList(PageQuery pageQuery) {
|
||||||
|
// 使用若依自带的 LoginHelper 获取当前登录用户的 ID (类型是 Long)
|
||||||
|
Long userId = LoginHelper.getUserId();
|
||||||
|
// 调用 Service
|
||||||
|
return service.selectHistoryTaskList(userId, pageQuery);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.ruoyi.hrm.service;
|
|||||||
|
|
||||||
import com.ruoyi.common.core.domain.PageQuery;
|
import com.ruoyi.common.core.domain.PageQuery;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.hrm.domain.HrmFlowTask;
|
||||||
import com.ruoyi.hrm.domain.bo.HrmFlowTaskBo;
|
import com.ruoyi.hrm.domain.bo.HrmFlowTaskBo;
|
||||||
import com.ruoyi.hrm.domain.vo.HrmFlowTaskVo;
|
import com.ruoyi.hrm.domain.vo.HrmFlowTaskVo;
|
||||||
|
|
||||||
@@ -42,6 +43,10 @@ public interface IHrmFlowTaskService {
|
|||||||
*/
|
*/
|
||||||
Boolean transfer(Long taskId, Long newAssigneeUserId, Long actionUserId, String remark);
|
Boolean transfer(Long taskId, Long newAssigneeUserId, Long actionUserId, String remark);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询当前用户的审批历史,并回填业务数据
|
||||||
|
*/
|
||||||
|
TableDataInfo<HrmFlowTaskVo> selectHistoryTaskList(Long userId, PageQuery pageQuery);
|
||||||
/**
|
/**
|
||||||
* 根据业务类型 + 业务ID 查询当前待办任务(pending),用于详情页自动带出 currentTaskId
|
* 根据业务类型 + 业务ID 查询当前待办任务(pending),用于详情页自动带出 currentTaskId
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class HrmFlowTaskServiceImpl implements IHrmFlowTaskService {
|
|||||||
private final FlowAssigneeHelper assigneeHelper;
|
private final FlowAssigneeHelper assigneeHelper;
|
||||||
private final BizStatusSyncHelper bizStatusSyncHelper;
|
private final BizStatusSyncHelper bizStatusSyncHelper;
|
||||||
|
|
||||||
|
private final HrmFlowTaskMapper hrmFlowTaskMapper;
|
||||||
// 注入五个业务Mapper
|
// 注入五个业务Mapper
|
||||||
private final HrmLeaveReqMapper leaveReqMapper;
|
private final HrmLeaveReqMapper leaveReqMapper;
|
||||||
private final HrmTravelReqMapper travelReqMapper;
|
private final HrmTravelReqMapper travelReqMapper;
|
||||||
@@ -397,4 +398,27 @@ public class HrmFlowTaskServiceImpl implements IHrmFlowTaskService {
|
|||||||
lqw.orderByDesc(HrmFlowTask::getCreateTime);
|
lqw.orderByDesc(HrmFlowTask::getCreateTime);
|
||||||
return lqw;
|
return lqw;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 查询当前用户的审批历史,回填业务数据以便前端复用页面
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TableDataInfo<HrmFlowTaskVo> selectHistoryTaskList(Long userId, PageQuery pageQuery) {
|
||||||
|
|
||||||
|
LambdaQueryWrapper<HrmFlowTask> lqw = Wrappers.lambdaQuery();
|
||||||
|
|
||||||
|
lqw.eq(HrmFlowTask::getAssigneeUserId, userId);
|
||||||
|
|
||||||
|
lqw.ne(HrmFlowTask::getStatus, "pending");
|
||||||
|
|
||||||
|
lqw.orderByDesc(HrmFlowTask::getCreateTime);
|
||||||
|
|
||||||
|
Page<HrmFlowTaskVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||||
|
|
||||||
|
if (result.getRecords() != null && !result.getRecords().isEmpty()) {
|
||||||
|
fillBizData(result.getRecords());
|
||||||
|
}
|
||||||
|
|
||||||
|
return TableDataInfo.build(result);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,12 +174,4 @@ public class WfTaskController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 审批历史列表
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("workflow:task:historyList")
|
|
||||||
@GetMapping("/historyList")
|
|
||||||
public R historyList() {
|
|
||||||
return R.ok(flowTaskService.selectHistoryTaskList());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.workflow.service;
|
package com.ruoyi.workflow.service;
|
||||||
|
|
||||||
|
|
||||||
import com.ruoyi.workflow.domain.FlowRecord;
|
import com.ruoyi.workflow.domain.FlowRecord;
|
||||||
import com.ruoyi.workflow.domain.bo.WfTaskBo;
|
import com.ruoyi.workflow.domain.bo.WfTaskBo;
|
||||||
import org.flowable.bpmn.model.FlowElement;
|
import org.flowable.bpmn.model.FlowElement;
|
||||||
@@ -126,8 +127,4 @@ public interface IWfTaskService {
|
|||||||
*/
|
*/
|
||||||
Map<String, Boolean> checkTaskNodeType(String taskId);
|
Map<String, Boolean> checkTaskNodeType(String taskId);
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询当前用户的审批历史(排除待审批状态)
|
|
||||||
*/
|
|
||||||
List<HistoricTaskInstance> selectHistoryTaskList();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.ruoyi.common.core.service.UserService;
|
import com.ruoyi.common.core.service.UserService;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
import com.ruoyi.common.helper.LoginHelper;
|
import com.ruoyi.common.helper.LoginHelper;
|
||||||
@@ -790,20 +792,6 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询当前用户的审批历史(排除待办任务)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<HistoricTaskInstance> selectHistoryTaskList() {
|
|
||||||
// 获取当前登录用户ID
|
|
||||||
String userId = TaskUtils.getUserId();
|
|
||||||
|
|
||||||
// Flowable 原生查询:当前用户 + 已完成(排除待办pending)
|
|
||||||
return historyService.createHistoricTaskInstanceQuery()
|
|
||||||
.taskAssignee(userId) // 审批人是当前用户
|
|
||||||
.finished() // 已完成(排除待办)
|
|
||||||
.orderByHistoricTaskInstanceEndTime()
|
|
||||||
.desc() // 按完成时间倒序,最新的在最前面
|
|
||||||
.list();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,6 +238,13 @@ export function delFlowInstance (instId) {
|
|||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
export function listHistoryFlowTask(query) {
|
||||||
|
return request({
|
||||||
|
url: '/hrm/flow/task/historyList',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询实例对应的所有审批任务
|
* 查询实例对应的所有审批任务
|
||||||
@@ -247,4 +254,9 @@ export function listAssignTask (instId) {
|
|||||||
url: `/hrm/flow/instance/tasks/${instId}`,
|
url: `/hrm/flow/instance/tasks/${instId}`,
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询当前用户的审批历史
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,34 +29,29 @@ const permission = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
// 生成路由
|
|
||||||
GenerateRoutes({ commit }) {
|
GenerateRoutes({ commit }) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
// 向后端请求路由数据
|
|
||||||
getRouters().then(res => {
|
getRouters().then(res => {
|
||||||
|
|
||||||
// ================= 新增拦截代码:将页面注入到办公中心开始 =================
|
|
||||||
// 寻找后端传来的“办公中心”节点(根据路径或标题匹配)
|
|
||||||
const oaMenu = res.data.find(item => item.path === '/oa' || (item.meta && item.meta.title === '办公中心'));
|
const oaMenu = res.data.find(item => item.path === '/oa' || (item.meta && item.meta.title === '办公中心'));
|
||||||
|
|
||||||
if (oaMenu) {
|
if (oaMenu) {
|
||||||
if (!oaMenu.children) oaMenu.children = [];
|
if (!oaMenu.children) oaMenu.children = [];
|
||||||
|
|
||||||
// 防重判断,避免代码热更新时重复添加导致菜单重复
|
|
||||||
const hasHistory = oaMenu.children.some(child => child.path === 'flowHistory');
|
const hasHistory = oaMenu.children.some(child => child.path === 'flowHistory');
|
||||||
|
|
||||||
if (!hasHistory) {
|
if (!hasHistory) {
|
||||||
oaMenu.children.push({
|
oaMenu.children.push({
|
||||||
name: 'FlowHistory',
|
name: 'HrmFlowHistory',
|
||||||
path: 'flowHistory', // 浏览器地址后缀,点击后地址变为 /oa/flowHistory
|
path: 'flowHistory',
|
||||||
hidden: false, // 确保在左侧菜单显示
|
hidden: false,
|
||||||
// 【特别注意】:这里对应的是你存放 vue 文件的真实相对路径
|
component: 'hrm/flow/taskHistory',
|
||||||
// 根据你最初的代码,我推测在 hrm/flow 文件夹下。
|
|
||||||
// 如果你的文件名叫 taskHistory.vue,请把下面的 flowHistory 改成 taskHistory
|
|
||||||
component: 'hrm/flow/flowHistory',
|
|
||||||
meta: {
|
meta: {
|
||||||
title: '审批历史',
|
title: '审批历史',
|
||||||
icon: 'date-range', // 菜单图标,支持 element 图标
|
icon: 'date-range',
|
||||||
noCache: false
|
noCache: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -108,8 +108,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { listHistoryFlowTask, listFlowAction, listFlowFormData } from '@/api/hrm/flow'
|
||||||
import { getTodoTaskByBiz, listFlowAction, listFlowFormData, listHistoryFlowTask } from '@/views/hrm/js/History'
|
|
||||||
|
|
||||||
import { listByIds } from '@/api/system/oss'
|
import { listByIds } from '@/api/system/oss'
|
||||||
import { listUser } from '@/api/system/user'
|
import { listUser } from '@/api/system/user'
|
||||||
@@ -127,6 +126,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
query: { status: undefined, pageNum: 1, pageSize: 50 },
|
query: { status: undefined, pageNum: 1, pageSize: 50 },
|
||||||
list: [],
|
list: [],
|
||||||
|
total: 0,
|
||||||
loading: false,
|
loading: false,
|
||||||
detailTask: null,
|
detailTask: null,
|
||||||
actionList: [],
|
actionList: [],
|
||||||
@@ -152,10 +152,18 @@ export default {
|
|||||||
|
|
||||||
fetchList() {
|
fetchList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
listHistoryFlowTask().then(res => {
|
|
||||||
this.list = res.data || res.rows || []
|
listHistoryFlowTask(this.query).then(res => {
|
||||||
if (!this.detailTask && this.list.length) this.openDetail(this.list[0])
|
|
||||||
}).finally(() => { this.loading = false })
|
this.list = res.rows || []
|
||||||
|
this.total = res.total || 0
|
||||||
|
|
||||||
|
if (!this.detailTask && this.list.length) {
|
||||||
|
this.openDetail(this.list[0])
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async openDetail(row) {
|
async openDetail(row) {
|
||||||
@@ -165,9 +173,32 @@ export default {
|
|||||||
this.loadFormData(row)
|
this.loadFormData(row)
|
||||||
},
|
},
|
||||||
|
|
||||||
loadActions(row) { if (!row || !row.instId) return; this.actionLoading = true; listFlowAction({ instId: row.instId }).then(res => { this.actionList = res.rows || [] }).finally(() => { this.actionLoading = false }) },
|
loadActions(row) {
|
||||||
loadFormData(row) { if (!row || !row.instId) return; this.formLoading = true; listFlowFormData({ instId: row.instId }).then(res => { this.formData = res.rows || [] }).finally(() => { this.formLoading = false }) },
|
if (!row || !row.instId) return;
|
||||||
copyTaskInfo() { if (!this.detailTask) return; const t = this.detailTask; const text = `任务ID:${t.taskId}\n实例:${t.instId}\n业务:${t.bizType}${t.bizId ? `#${t.bizId}` : ''}\n节点:${t.nodeId}\n状态:${t.status}`; navigator.clipboard.writeText(text).then(() => this.$message.success('已复制')) }
|
this.actionLoading = true;
|
||||||
|
listFlowAction({ instId: row.instId }).then(res => {
|
||||||
|
this.actionList = res.rows || []
|
||||||
|
}).finally(() => {
|
||||||
|
this.actionLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
loadFormData(row) {
|
||||||
|
if (!row || !row.instId) return;
|
||||||
|
this.formLoading = true;
|
||||||
|
listFlowFormData({ instId: row.instId }).then(res => {
|
||||||
|
this.formData = res.rows || []
|
||||||
|
}).finally(() => {
|
||||||
|
this.formLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
copyTaskInfo() {
|
||||||
|
if (!this.detailTask) return;
|
||||||
|
const t = this.detailTask;
|
||||||
|
const text = `任务ID:${t.taskId}\n实例:${t.instId}\n业务:${t.bizType}${t.bizId ? `#${t.bizId}` : ''}\n节点:${t.nodeId}\n状态:${t.status}`;
|
||||||
|
navigator.clipboard.writeText(text).then(() => this.$message.success('已复制'))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user