提交 d4d34603 authored 作者: liuluyu's avatar liuluyu

Merge branch 'master' of http://47.97.51.208/root/zrch-risk-39

<template>
<div class="app-container">
<vxe-grid ref="xGrid" v-bind="gridOptions" @checkbox-change="onSelectChange" @checkbox-all="onSelectChange">
<!-- 搜索表单插槽 -->
<template #flowNameItem="{ data }">
<vxe-input v-model="data.procDefName" placeholder="请输入流程名称" clearable @keyup.enter="searchEvent"></vxe-input>
</template>
<template #taskNameItem="{ data }">
<vxe-input v-model="data.taskName" placeholder="请输入任务名称" clearable @keyup.enter="searchEvent"></vxe-input>
</template>
<template #startTimeItem="{ data }">
<vxe-input type="date" v-model="data.startTime" placeholder="请选择开始时间" clearable></vxe-input>
</template>
<template #actionItem>
<vxe-button status="primary" icon="vxe-icon-search" @click="searchEvent">搜索</vxe-button>
<vxe-button icon="vxe-icon-refresh" @click="resetEvent">重置</vxe-button>
</template>
<!-- 表格列插槽 -->
<template #procDefVersion_default="{ row }">
<span class="version-tag">v{{ row.procDefVersion }}</span>
</template>
<template #startUser_default="{ row }">
<div class="user-info">
<span class="user-name">{{ row.startUserName }}</span>
<span class="dept-tag">{{ row.startDeptName }}</span>
</div>
</template>
<template #action_default="{ row }">
<vxe-button type="text" icon="vxe-icon-edit" status="primary" @click="handleProcess(row)">处理</vxe-button>
</template>
</vxe-grid>
<div v-if="isShowDrawer">
<a-drawer
destroyOnClose
v-model:open="isShowDrawer"
class="custom-class"
root-class-name="root-class-name"
:root-style="{ color: 'blue' }"
title="待办任务"
placement="right"
width="90%"
style="margin: 0px; padding: 0px"
>
<template #extra>
<div style="float: right">
<a-tag style="margin-left: 10px">发起人:{{ startUser }}</a-tag>
<a-tag>任务节点:{{ taskName }}</a-tag>
</div>
</template>
<TodoIndex v-if="isShowDrawer" ref="refTodoIndex" @callback="handleSuccess" />
</a-drawer>
</div>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, onMounted, nextTick } from 'vue';
import { message } from 'ant-design-vue';
import type { VxeGridProps, VxeGridInstance } from 'vxe-table';
import { todoReadList, delDeployment } from '/@/components/Process/api/todo';
import XEUtils from 'xe-utils';
import TodoIndex from './components/TodoIndex.vue';
const loading = ref(false);
const isShowDrawer = ref(false);
const refTodoIndex = ref();
const startUser = ref();
const taskName = ref();
interface QueryParams {
pageNum: number;
pageSize: number;
procDefName?: string;
taskName?: string;
startTime?: string;
}
const queryParams = reactive<QueryParams>({
pageNum: 1,
pageSize: 10,
procDefName: undefined,
taskName: undefined,
startTime: undefined,
});
interface TodoItem {
taskId: string;
procDefName: string;
taskName: string;
procDefVersion: number;
startUserName: string;
startDeptName: string;
createTime: string;
procInsId: string;
executionId: string;
deployId: string;
}
const defaultData = reactive({
procDefName: '',
taskName: '',
startTime: '',
});
const selectedRowKeys = ref<string[]>([]);
const selectRecords = ref<TodoItem[]>([]);
const multiple = ref(true);
const xGrid = ref<VxeGridInstance>();
const gridOptions = reactive<VxeGridProps<any>>({
loading: loading.value,
showOverflow: true,
border: true,
rowConfig: {
keyField: 'taskId',
isHover: true,
},
columnConfig: {
resizable: true,
},
pagerConfig: {
enabled: true,
pageSize: 10,
pageSizes: [10, 20, 50, 100],
layouts: ['PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total'],
},
checkboxConfig: {
highlight: true,
range: true,
},
layouts: ['Top', 'Form', 'Toolbar', 'Table', 'Bottom', 'Pager'],
formConfig: {
data: XEUtils.clone(defaultData, true),
items: [
{ field: 'procDefName', title: '流程名称', span: 6, itemRender: {}, slots: { default: 'flowNameItem' } },
{ field: 'taskName', title: '任务名称', span: 6, itemRender: {}, slots: { default: 'taskNameItem' } },
{ field: 'startTime', title: '开始时间', span: 6, itemRender: {}, slots: { default: 'startTimeItem' } },
{ span: 6, align: 'center', itemRender: {}, slots: { default: 'actionItem' } },
],
},
proxyConfig: {
response: {
result: 'result',
total: 'page.total',
},
ajax: {
query: ({ page }) => {
return findPageList(page.currentPage, page.pageSize);
},
},
},
columns: [
{ type: 'checkbox', width: 60, fixed: 'left' },
{ type: 'seq', width: 70, fixed: 'left' },
{ field: 'taskId', title: '任务编号', minWidth: 120, showOverflow: true },
{ field: 'procDefName', title: '流程名称', minWidth: 160, showOverflow: true },
{ field: 'taskName', title: '当前节点', minWidth: 140, showOverflow: true },
{ field: 'taskType', title: '节点类型', minWidth: 140, showOverflow: true },
{ field: 'procDefVersion', title: '流程版本', width: 100, align: 'center', slots: { default: 'procDefVersion_default' } },
{ field: 'startUser', title: '流程发起人', minWidth: 180, align: 'center', slots: { default: 'startUser_default' } },
{ field: 'createTime', title: '接收时间', width: 180, align: 'center' },
{
title: '操作',
width: 120,
fixed: 'right',
align: 'center',
slots: { default: 'action_default' },
},
],
});
const findPageList = async (currentPage: number, pageSize: number) => {
queryParams.pageNum = currentPage;
queryParams.pageSize = pageSize;
if (gridOptions.formConfig?.data) {
queryParams.procDefName = gridOptions.formConfig.data.procDefName;
queryParams.taskName = gridOptions.formConfig.data.taskName;
queryParams.startTime = gridOptions.formConfig.data.startTime;
}
try {
loading.value = true;
const retData = await todoReadList(queryParams);
return {
page: {
total: retData.total,
},
result: retData.records,
};
} catch (error) {
console.error('查询数据失败:', error);
message.error('查询数据失败');
return {
page: { total: 0 },
result: [],
};
} finally {
loading.value = false;
}
};
const searchEvent = async () => {
queryParams.pageNum = 1;
if (xGrid.value) {
await xGrid.value.commitProxy('query');
}
};
const resetEvent = () => {
if (gridOptions.formConfig) {
gridOptions.formConfig.data = XEUtils.clone(defaultData, true);
}
searchEvent();
};
const onSelectChange = () => {
if (xGrid.value) {
const checkedRecords = xGrid.value.getCheckboxRecords();
selectRecords.value = checkedRecords;
selectedRowKeys.value = checkedRecords.map((item) => item.taskId);
multiple.value = !selectedRowKeys.value.length;
}
};
const handleProcess = async (row) => {
isShowDrawer.value = true;
startUser.value = row.startUserName;
taskName.value = row.taskName;
await nextTick(() => {
if (refTodoIndex.value) {
refTodoIndex.value.iniData(row);
} else {
isShowDrawer.value = false;
}
});
};
const handleSuccess = async () => {
isShowDrawer.value = false;
await searchEvent();
};
</script>
<style scoped>
.app-container {
padding: 16px;
width: 100%;
height: 100%;
}
.user-info {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
flex-wrap: nowrap;
}
.user-name {
font-weight: 500;
white-space: nowrap;
}
.dept-tag {
background: #f0f0f0;
color: #666;
padding: 2px 6px;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
}
.version-tag {
background: #1890ff;
color: white;
padding: 2px 8px;
border-radius: 4px;
font-size: 12px;
}
/* Vxe Grid 样式调整 */
:deep(.vxe-form--wrapper) {
background: #fafafa;
padding: 16px;
border-radius: 4px;
border: 1px solid #e8e8e8;
margin-bottom: 16px;
}
:deep(.vxe-form--item-title) {
font-weight: 500;
color: #333;
}
:deep(.vxe-grid--wrapper) {
font-family: inherit;
}
:deep(.vxe-grid--header) {
background-color: #fafafa;
}
:deep(.vxe-grid--body) {
background-color: #fff;
}
:deep(.vxe-cell) {
padding: 8px 4px;
}
:deep(.vxe-toolbar) {
background: transparent;
padding: 8px 0;
margin-bottom: 8px;
}
:deep(.vxe-table--render-wrapper) {
border-radius: 4px;
}
</style>
......@@ -5,6 +5,10 @@ const { createConfirm } = useMessage();
enum Api {
starlist = '/my/myTaskFlowHis/starlist',
approvelist = '/my/myTaskFlowHis/approvelist',
handlist = '/my/myTaskFlowHis/handlist',
assignlist = '/my/myTaskFlowHis/assignlist',
assignReadlist = '/my/myTaskFlowHis/assignReadlist',
list = '/my/myTaskFlowHis/list',
save='/my/myTaskFlowHis/add',
edit='/my/myTaskFlowHis/edit',
......@@ -70,3 +74,36 @@ export const saveOrUpdate = (params, isUpdate) => {
*/
export const starlist = (params) =>
defHttp.get({url: Api.starlist, params});
/**
* 列表接口
* @param params
*/
export const approvelist = (params) =>
defHttp.get({url: Api.approvelist, params});
/**
* 列表接口
* @param params
*/
export const handlist = (params) =>
defHttp.get({url: Api.handlist, params});
/**
* 列表接口
* @param params
*/
export const assignlist = (params) =>
defHttp.get({url: Api.assignlist, params});
/**
* 列表接口
* @param params
*/
export const assignReadlist = (params) =>
defHttp.get({url: Api.assignReadlist, params});
<template>
<div>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<!--
<a-button type="primary" v-auth="'my:my_task_flow_his:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'my:my_task_flow_his:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'my:my_task_flow_his:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchHandleDelete">
<Icon icon="ant-design:delete-outlined"></Icon>
删除
</a-menu-item>
</a-menu>
</template>
<a-button v-auth="'my:my_task_flow_his:deleteBatch'">批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
-->
<!-- 高级查询 -->
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
</template>
<!--操作栏 -->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
</template>
<!--字段回显插槽-->
<template v-slot:bodyCell="{ column, record, index, text }">
</template>
</BasicTable>
<!-- 表单区域 -->
<MyTaskFlowHisModal @register="registerModal" @success="handleSuccess"></MyTaskFlowHisModal>
<!-- 流程详情抽屉 -->
<div v-if="isShowDetailDrawer">
<a-drawer destroyOnClose v-model:open="isShowDetailDrawer" class="flat-drawer" title="流程详情" placement="right" width="90%">
<template #extra>
<a-button type="text" @click="handleDetailDrawerClose">关闭</a-button>
</template>
<Detail ref="refDetail" />
</a-drawer>
</div>
</div>
</template>
<script lang="ts" name="my-myTaskFlowHis" setup>
import {ref,nextTick, reactive, computed, toRaw,unref} from 'vue';
import {BasicTable, useTable, TableAction} from '/@/components/Table';
import {useModal} from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage'
import MyTaskFlowHisModal from './components/MyTaskFlowHisModal.vue'
import {columns, searchFormSchema, superQuerySchema} from './MyTaskFlowHis.data';
import {approvelist,list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './MyTaskFlowHis.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import { useUserStore } from '/@/store/modules/user';
import { useMessage } from '/@/hooks/web/useMessage';
import { getDateByPicker } from '/@/utils';
import { todoList, getMyTaskFlow } from '/@/components/Process/api/todo';
// 引入详情组件
import Detail from '../flowable/task/myProcess/components/Detail.vue';
const taskCache = new Map<string, any>();
//日期个性化选择
const fieldPickers = reactive({
});
const queryParam = reactive<any>({});
const checkedKeys = ref<Array<string | number>>([]);
const userStore = useUserStore();
const { createMessage } = useMessage();
//注册model
const [registerModal, {openModal}] = useModal();
//注册table数据
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
tableProps:{
title: 'my_task_flow_his',
api: approvelist,
columns,
canResize:true,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter:true,
showAdvancedButton:true,
fieldMapToNumber: [
],
fieldMapToTime: [
],
},
actionColumn: {
width: 120,
fixed:'right'
},
beforeFetch: (params) => {
if (params && fieldPickers) {
for (let key in fieldPickers) {
if (params[key]) {
params[key] = getDateByPicker(params[key], fieldPickers[key]);
}
}
}
return Object.assign(params, queryParam);
},
},
exportConfig: {
name:"my_task_flow_his",
url: getExportUrl,
params: queryParam,
},
importConfig: {
url: getImportUrl,
success: handleSuccess
},
})
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
// 高级查询配置
const superQueryConfig = reactive(superQuerySchema);
// 流程详情抽屉相关
const refDetail = ref();
const isShowDetailDrawer = ref(false);
/**
* 高级查询事件
*/
function handleSuperQuery(params) {
Object.keys(params).map((k) => {
queryParam[k] = params[k];
});
reload();
}
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
isUpdate: false,
showFooter: true,
});
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
/**
* 详情
*/
function handleDetail(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: false,
});
}
/**
* 删除事件
*/
async function handleDelete(record) {
await deleteOne({id: record.id}, handleSuccess);
}
/**
* 批量删除事件
*/
async function batchHandleDelete() {
await batchDelete({ids: selectedRowKeys.value}, handleSuccess);
}
/**
* 成功回调
*/
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
/**
* 操作栏
*/
function getTableAction(record){
return [
{
label: '流转记录',
onClick: handleProgressDetail.bind(null, record),
},
/**
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'my:my_task_flow_his:edit'
}*/
]
}
/**
* 下拉操作栏
*/
function getDropDownAction(record){
return [];
/**
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
}, {
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
},
auth: 'my:my_task_flow_his:delete'
}
]*/
}
function pickStartResult(res: any) {
const base = res?.data ?? res?.result ?? res;
return base || {};
}
/**
* 流转记录
*/
async function handleProgressDetail(record: Recordable) {
const dataId = record.targetId;
const deployId = record.deployId;
//alert(dataId);
if (!dataId || !deployId) {
message.error('未找到业务数据标识');
return;
}
try {
const myTaskFlow = await getMyTaskFlow({ deploymentId: record.deployId, dataId: record.targetId });
const taskData = pickStartResult(myTaskFlow);
if (!taskData || !taskData.taskId) {
message.error('未获取到待办任务信息');
return;
}
if (taskData.nodeisApprove == null) {
taskData.nodeisApprove = true;
}
taskCache.set(String(dataId), taskData);
// alert(taskData);
isShowDetailDrawer.value = true;
await nextTick();
if (refDetail.value) {
refDetail.value.iniData({
...record,
...taskData,
procInsId: taskData.procInsId,
});
} else {
isShowDetailDrawer.value = false;
}
} catch (e) {
console.error('获取流程任务信息失败:', e);
message.error('获取任务信息失败,请重试');
}
}
</script>
<style lang="less" scoped>
:deep(.ant-picker),:deep(.ant-input-number){
width: 100%;
}
</style>
\ No newline at end of file
<template>
<div>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<!--
<a-button type="primary" v-auth="'my:my_task_flow_his:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'my:my_task_flow_his:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'my:my_task_flow_his:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchHandleDelete">
<Icon icon="ant-design:delete-outlined"></Icon>
删除
</a-menu-item>
</a-menu>
</template>
<a-button v-auth="'my:my_task_flow_his:deleteBatch'">批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
-->
<!-- 高级查询 -->
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
</template>
<!--操作栏 -->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
</template>
<!--字段回显插槽-->
<template v-slot:bodyCell="{ column, record, index, text }">
</template>
</BasicTable>
<!-- 表单区域 -->
<MyTaskFlowHisModal @register="registerModal" @success="handleSuccess"></MyTaskFlowHisModal>
<!-- 流程详情抽屉 -->
<div v-if="isShowDetailDrawer">
<a-drawer destroyOnClose v-model:open="isShowDetailDrawer" class="flat-drawer" title="流程详情" placement="right" width="90%">
<template #extra>
<a-button type="text" @click="handleDetailDrawerClose">关闭</a-button>
</template>
<Detail ref="refDetail" />
</a-drawer>
</div>
</div>
</template>
<script lang="ts" name="my-myTaskFlowHis" setup>
import {ref,nextTick, reactive, computed, toRaw,unref} from 'vue';
import {BasicTable, useTable, TableAction} from '/@/components/Table';
import {useModal} from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage'
import MyTaskFlowHisModal from './components/MyTaskFlowHisModal.vue'
import {columns, searchFormSchema, superQuerySchema} from './MyTaskFlowHis.data';
import {assignlist,list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './MyTaskFlowHis.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import { useUserStore } from '/@/store/modules/user';
import { useMessage } from '/@/hooks/web/useMessage';
import { getDateByPicker } from '/@/utils';
import { todoList, getMyTaskFlow } from '/@/components/Process/api/todo';
// 引入详情组件
import Detail from '../flowable/task/myProcess/components/Detail.vue';
const taskCache = new Map<string, any>();
//日期个性化选择
const fieldPickers = reactive({
});
const queryParam = reactive<any>({});
const checkedKeys = ref<Array<string | number>>([]);
const userStore = useUserStore();
const { createMessage } = useMessage();
//注册model
const [registerModal, {openModal}] = useModal();
//注册table数据
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
tableProps:{
title: 'my_task_flow_his',
api: assignlist,
columns,
canResize:true,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter:true,
showAdvancedButton:true,
fieldMapToNumber: [
],
fieldMapToTime: [
],
},
actionColumn: {
width: 120,
fixed:'right'
},
beforeFetch: (params) => {
if (params && fieldPickers) {
for (let key in fieldPickers) {
if (params[key]) {
params[key] = getDateByPicker(params[key], fieldPickers[key]);
}
}
}
return Object.assign(params, queryParam);
},
},
exportConfig: {
name:"my_task_flow_his",
url: getExportUrl,
params: queryParam,
},
importConfig: {
url: getImportUrl,
success: handleSuccess
},
})
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
// 高级查询配置
const superQueryConfig = reactive(superQuerySchema);
// 流程详情抽屉相关
const refDetail = ref();
const isShowDetailDrawer = ref(false);
/**
* 高级查询事件
*/
function handleSuperQuery(params) {
Object.keys(params).map((k) => {
queryParam[k] = params[k];
});
reload();
}
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
isUpdate: false,
showFooter: true,
});
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
/**
* 详情
*/
function handleDetail(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: false,
});
}
/**
* 删除事件
*/
async function handleDelete(record) {
await deleteOne({id: record.id}, handleSuccess);
}
/**
* 批量删除事件
*/
async function batchHandleDelete() {
await batchDelete({ids: selectedRowKeys.value}, handleSuccess);
}
/**
* 成功回调
*/
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
/**
* 操作栏
*/
function getTableAction(record){
return [
{
label: '流转记录',
onClick: handleProgressDetail.bind(null, record),
},
/**
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'my:my_task_flow_his:edit'
}*/
]
}
/**
* 下拉操作栏
*/
function getDropDownAction(record){
return [];
/**
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
}, {
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
},
auth: 'my:my_task_flow_his:delete'
}
]*/
}
function pickStartResult(res: any) {
const base = res?.data ?? res?.result ?? res;
return base || {};
}
/**
* 流转记录
*/
async function handleProgressDetail(record: Recordable) {
const dataId = record.targetId;
const deployId = record.deployId;
//alert(dataId);
if (!dataId || !deployId) {
message.error('未找到业务数据标识');
return;
}
try {
const myTaskFlow = await getMyTaskFlow({ deploymentId: record.deployId, dataId: record.targetId });
const taskData = pickStartResult(myTaskFlow);
if (!taskData || !taskData.taskId) {
message.error('未获取到待办任务信息');
return;
}
if (taskData.nodeisApprove == null) {
taskData.nodeisApprove = true;
}
taskCache.set(String(dataId), taskData);
// alert(taskData);
isShowDetailDrawer.value = true;
await nextTick();
if (refDetail.value) {
refDetail.value.iniData({
...record,
...taskData,
procInsId: taskData.procInsId,
});
} else {
isShowDetailDrawer.value = false;
}
} catch (e) {
console.error('获取流程任务信息失败:', e);
message.error('获取任务信息失败,请重试');
}
}
</script>
<style lang="less" scoped>
:deep(.ant-picker),:deep(.ant-input-number){
width: 100%;
}
</style>
\ No newline at end of file
<template>
<div>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<!--
<a-button type="primary" v-auth="'my:my_task_flow_his:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'my:my_task_flow_his:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'my:my_task_flow_his:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchHandleDelete">
<Icon icon="ant-design:delete-outlined"></Icon>
删除
</a-menu-item>
</a-menu>
</template>
<a-button v-auth="'my:my_task_flow_his:deleteBatch'">批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
-->
<!-- 高级查询 -->
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
</template>
<!--操作栏 -->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
</template>
<!--字段回显插槽-->
<template v-slot:bodyCell="{ column, record, index, text }">
</template>
</BasicTable>
<!-- 表单区域 -->
<MyTaskFlowHisModal @register="registerModal" @success="handleSuccess"></MyTaskFlowHisModal>
<!-- 流程详情抽屉 -->
<div v-if="isShowDetailDrawer">
<a-drawer destroyOnClose v-model:open="isShowDetailDrawer" class="flat-drawer" title="流程详情" placement="right" width="90%">
<template #extra>
<a-button type="text" @click="handleDetailDrawerClose">关闭</a-button>
</template>
<Detail ref="refDetail" />
</a-drawer>
</div>
</div>
</template>
<script lang="ts" name="my-myTaskFlowHis" setup>
import {ref,nextTick, reactive, computed, toRaw,unref} from 'vue';
import {BasicTable, useTable, TableAction} from '/@/components/Table';
import {useModal} from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage'
import MyTaskFlowHisModal from './components/MyTaskFlowHisModal.vue'
import {columns, searchFormSchema, superQuerySchema} from './MyTaskFlowHis.data';
import {assignReadlist,list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './MyTaskFlowHis.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import { useUserStore } from '/@/store/modules/user';
import { useMessage } from '/@/hooks/web/useMessage';
import { getDateByPicker } from '/@/utils';
import { todoList, getMyTaskFlow } from '/@/components/Process/api/todo';
// 引入详情组件
import Detail from '../flowable/task/myProcess/components/Detail.vue';
const taskCache = new Map<string, any>();
//日期个性化选择
const fieldPickers = reactive({
});
const queryParam = reactive<any>({});
const checkedKeys = ref<Array<string | number>>([]);
const userStore = useUserStore();
const { createMessage } = useMessage();
//注册model
const [registerModal, {openModal}] = useModal();
//注册table数据
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
tableProps:{
title: 'my_task_flow_his',
api: assignReadlist,
columns,
canResize:true,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter:true,
showAdvancedButton:true,
fieldMapToNumber: [
],
fieldMapToTime: [
],
},
actionColumn: {
width: 120,
fixed:'right'
},
beforeFetch: (params) => {
if (params && fieldPickers) {
for (let key in fieldPickers) {
if (params[key]) {
params[key] = getDateByPicker(params[key], fieldPickers[key]);
}
}
}
return Object.assign(params, queryParam);
},
},
exportConfig: {
name:"my_task_flow_his",
url: getExportUrl,
params: queryParam,
},
importConfig: {
url: getImportUrl,
success: handleSuccess
},
})
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
// 高级查询配置
const superQueryConfig = reactive(superQuerySchema);
// 流程详情抽屉相关
const refDetail = ref();
const isShowDetailDrawer = ref(false);
/**
* 高级查询事件
*/
function handleSuperQuery(params) {
Object.keys(params).map((k) => {
queryParam[k] = params[k];
});
reload();
}
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
isUpdate: false,
showFooter: true,
});
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
/**
* 详情
*/
function handleDetail(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: false,
});
}
/**
* 删除事件
*/
async function handleDelete(record) {
await deleteOne({id: record.id}, handleSuccess);
}
/**
* 批量删除事件
*/
async function batchHandleDelete() {
await batchDelete({ids: selectedRowKeys.value}, handleSuccess);
}
/**
* 成功回调
*/
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
/**
* 操作栏
*/
function getTableAction(record){
return [
{
label: '流转记录',
onClick: handleProgressDetail.bind(null, record),
},
/**
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'my:my_task_flow_his:edit'
}*/
]
}
/**
* 下拉操作栏
*/
function getDropDownAction(record){
return [];
/**
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
}, {
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
},
auth: 'my:my_task_flow_his:delete'
}
]*/
}
function pickStartResult(res: any) {
const base = res?.data ?? res?.result ?? res;
return base || {};
}
/**
* 流转记录
*/
async function handleProgressDetail(record: Recordable) {
const dataId = record.targetId;
const deployId = record.deployId;
//alert(dataId);
if (!dataId || !deployId) {
message.error('未找到业务数据标识');
return;
}
try {
const myTaskFlow = await getMyTaskFlow({ deploymentId: record.deployId, dataId: record.targetId });
const taskData = pickStartResult(myTaskFlow);
if (!taskData || !taskData.taskId) {
message.error('未获取到待办任务信息');
return;
}
if (taskData.nodeisApprove == null) {
taskData.nodeisApprove = true;
}
taskCache.set(String(dataId), taskData);
// alert(taskData);
isShowDetailDrawer.value = true;
await nextTick();
if (refDetail.value) {
refDetail.value.iniData({
...record,
...taskData,
procInsId: taskData.procInsId,
});
} else {
isShowDetailDrawer.value = false;
}
} catch (e) {
console.error('获取流程任务信息失败:', e);
message.error('获取任务信息失败,请重试');
}
}
</script>
<style lang="less" scoped>
:deep(.ant-picker),:deep(.ant-input-number){
width: 100%;
}
</style>
\ No newline at end of file
<template>
<div>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<!--
<a-button type="primary" v-auth="'my:my_task_flow_his:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'my:my_task_flow_his:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'my:my_task_flow_his:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchHandleDelete">
<Icon icon="ant-design:delete-outlined"></Icon>
删除
</a-menu-item>
</a-menu>
</template>
<a-button v-auth="'my:my_task_flow_his:deleteBatch'">批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
-->
<!-- 高级查询 -->
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
</template>
<!--操作栏 -->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
</template>
<!--字段回显插槽-->
<template v-slot:bodyCell="{ column, record, index, text }">
</template>
</BasicTable>
<!-- 表单区域 -->
<MyTaskFlowHisModal @register="registerModal" @success="handleSuccess"></MyTaskFlowHisModal>
<!-- 流程详情抽屉 -->
<div v-if="isShowDetailDrawer">
<a-drawer destroyOnClose v-model:open="isShowDetailDrawer" class="flat-drawer" title="流程详情" placement="right" width="90%">
<template #extra>
<a-button type="text" @click="handleDetailDrawerClose">关闭</a-button>
</template>
<Detail ref="refDetail" />
</a-drawer>
</div>
</div>
</template>
<script lang="ts" name="my-myTaskFlowHis" setup>
import {ref,nextTick, reactive, computed, toRaw,unref} from 'vue';
import {BasicTable, useTable, TableAction} from '/@/components/Table';
import {useModal} from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage'
import MyTaskFlowHisModal from './components/MyTaskFlowHisModal.vue'
import {columns, searchFormSchema, superQuerySchema} from './MyTaskFlowHis.data';
import {handlist,list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './MyTaskFlowHis.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import { useUserStore } from '/@/store/modules/user';
import { useMessage } from '/@/hooks/web/useMessage';
import { getDateByPicker } from '/@/utils';
import { todoList, getMyTaskFlow } from '/@/components/Process/api/todo';
// 引入详情组件
import Detail from '../flowable/task/myProcess/components/Detail.vue';
const taskCache = new Map<string, any>();
//日期个性化选择
const fieldPickers = reactive({
});
const queryParam = reactive<any>({});
const checkedKeys = ref<Array<string | number>>([]);
const userStore = useUserStore();
const { createMessage } = useMessage();
//注册model
const [registerModal, {openModal}] = useModal();
//注册table数据
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
tableProps:{
title: 'my_task_flow_his',
api: handlist,
columns,
canResize:true,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter:true,
showAdvancedButton:true,
fieldMapToNumber: [
],
fieldMapToTime: [
],
},
actionColumn: {
width: 120,
fixed:'right'
},
beforeFetch: (params) => {
if (params && fieldPickers) {
for (let key in fieldPickers) {
if (params[key]) {
params[key] = getDateByPicker(params[key], fieldPickers[key]);
}
}
}
return Object.assign(params, queryParam);
},
},
exportConfig: {
name:"my_task_flow_his",
url: getExportUrl,
params: queryParam,
},
importConfig: {
url: getImportUrl,
success: handleSuccess
},
})
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
// 高级查询配置
const superQueryConfig = reactive(superQuerySchema);
// 流程详情抽屉相关
const refDetail = ref();
const isShowDetailDrawer = ref(false);
/**
* 高级查询事件
*/
function handleSuperQuery(params) {
Object.keys(params).map((k) => {
queryParam[k] = params[k];
});
reload();
}
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
isUpdate: false,
showFooter: true,
});
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
/**
* 详情
*/
function handleDetail(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: false,
});
}
/**
* 删除事件
*/
async function handleDelete(record) {
await deleteOne({id: record.id}, handleSuccess);
}
/**
* 批量删除事件
*/
async function batchHandleDelete() {
await batchDelete({ids: selectedRowKeys.value}, handleSuccess);
}
/**
* 成功回调
*/
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
/**
* 操作栏
*/
function getTableAction(record){
return [
{
label: '流转记录',
onClick: handleProgressDetail.bind(null, record),
},
/**
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'my:my_task_flow_his:edit'
}*/
]
}
/**
* 下拉操作栏
*/
function getDropDownAction(record){
return [];
/**
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
}, {
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
},
auth: 'my:my_task_flow_his:delete'
}
]*/
}
function pickStartResult(res: any) {
const base = res?.data ?? res?.result ?? res;
return base || {};
}
/**
* 流转记录
*/
async function handleProgressDetail(record: Recordable) {
const dataId = record.targetId;
const deployId = record.deployId;
//alert(dataId);
if (!dataId || !deployId) {
message.error('未找到业务数据标识');
return;
}
try {
const myTaskFlow = await getMyTaskFlow({ deploymentId: record.deployId, dataId: record.targetId });
const taskData = pickStartResult(myTaskFlow);
if (!taskData || !taskData.taskId) {
message.error('未获取到待办任务信息');
return;
}
if (taskData.nodeisApprove == null) {
taskData.nodeisApprove = true;
}
taskCache.set(String(dataId), taskData);
// alert(taskData);
isShowDetailDrawer.value = true;
await nextTick();
if (refDetail.value) {
refDetail.value.iniData({
...record,
...taskData,
procInsId: taskData.procInsId,
});
} else {
isShowDetailDrawer.value = false;
}
} catch (e) {
console.error('获取流程任务信息失败:', e);
message.error('获取任务信息失败,请重试');
}
}
</script>
<style lang="less" scoped>
:deep(.ant-picker),:deep(.ant-input-number){
width: 100%;
}
</style>
\ No newline at end of file
......@@ -109,6 +109,123 @@ public class MyTaskFlowHisController extends JeecgController<MyTaskFlowHis, IMyT
return Result.OK(pageList);
}
@GetMapping(value = "/approvelist")
public Result<IPage<MyTaskFlowHis>> approvelistqueryPageList(MyTaskFlowHis myTaskFlowHis,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
String userId = UserUtil.getUserId();
String roleids="";
List<SysUserRole> userRole = sysUserRoleService.list(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, userId));
for(int u=0;u<userRole.size();u++){
SysUserRole sysUserRole=userRole.get(u);
roleids=roleids+sysUserRole.getRoleId()+",";
}
if(!roleids.equals("")){
roleids=roleids.substring(0,roleids.length()-1);
}
// 创建一个最终变量或实际上的最终变量用于 lambda
final String finalRoleids = roleids;
QueryWrapper<MyTaskFlowHis> queryWrapper = QueryGenerator.initQueryWrapper(myTaskFlowHis, req.getParameterMap());
queryWrapper.eq("option_id", userId)
.eq("task_type","参与")
.eq("option_type","审批")
.orderByDesc("option_time");
Page<MyTaskFlowHis> page = new Page<MyTaskFlowHis>(pageNo, pageSize);
IPage<MyTaskFlowHis> pageList = myTaskFlowHisService.page(page, queryWrapper);
return Result.OK(pageList);
}
@GetMapping(value = "/handlist")
public Result<IPage<MyTaskFlowHis>> handlistqueryPageList(MyTaskFlowHis myTaskFlowHis,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
String userId = UserUtil.getUserId();
String roleids="";
List<SysUserRole> userRole = sysUserRoleService.list(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, userId));
for(int u=0;u<userRole.size();u++){
SysUserRole sysUserRole=userRole.get(u);
roleids=roleids+sysUserRole.getRoleId()+",";
}
if(!roleids.equals("")){
roleids=roleids.substring(0,roleids.length()-1);
}
// 创建一个最终变量或实际上的最终变量用于 lambda
final String finalRoleids = roleids;
QueryWrapper<MyTaskFlowHis> queryWrapper = QueryGenerator.initQueryWrapper(myTaskFlowHis, req.getParameterMap());
queryWrapper.eq("option_id", userId)
.eq("task_type","参与")
.eq("option_type","办理")
.orderByDesc("option_time");
Page<MyTaskFlowHis> page = new Page<MyTaskFlowHis>(pageNo, pageSize);
IPage<MyTaskFlowHis> pageList = myTaskFlowHisService.page(page, queryWrapper);
return Result.OK(pageList);
}
@GetMapping(value = "/assignlist")
public Result<IPage<MyTaskFlowHis>> assignlistqueryPageList(MyTaskFlowHis myTaskFlowHis,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
String userId = UserUtil.getUserId();
String roleids="";
List<SysUserRole> userRole = sysUserRoleService.list(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, userId));
for(int u=0;u<userRole.size();u++){
SysUserRole sysUserRole=userRole.get(u);
roleids=roleids+sysUserRole.getRoleId()+",";
}
if(!roleids.equals("")){
roleids=roleids.substring(0,roleids.length()-1);
}
// 创建一个最终变量或实际上的最终变量用于 lambda
final String finalRoleids = roleids;
QueryWrapper<MyTaskFlowHis> queryWrapper = QueryGenerator.initQueryWrapper(myTaskFlowHis, req.getParameterMap());
queryWrapper.eq("option_id", userId)
.eq("task_type","参与")
.eq("option_type","转办")
.orderByDesc("option_time");
Page<MyTaskFlowHis> page = new Page<MyTaskFlowHis>(pageNo, pageSize);
IPage<MyTaskFlowHis> pageList = myTaskFlowHisService.page(page, queryWrapper);
return Result.OK(pageList);
}
@GetMapping(value = "/assignReadlist")
public Result<IPage<MyTaskFlowHis>> assignReadlistlistqueryPageList(MyTaskFlowHis myTaskFlowHis,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
String userId = UserUtil.getUserId();
String roleids="";
List<SysUserRole> userRole = sysUserRoleService.list(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, userId));
for(int u=0;u<userRole.size();u++){
SysUserRole sysUserRole=userRole.get(u);
roleids=roleids+sysUserRole.getRoleId()+",";
}
if(!roleids.equals("")){
roleids=roleids.substring(0,roleids.length()-1);
}
// 创建一个最终变量或实际上的最终变量用于 lambda
final String finalRoleids = roleids;
QueryWrapper<MyTaskFlowHis> queryWrapper = QueryGenerator.initQueryWrapper(myTaskFlowHis, req.getParameterMap());
queryWrapper.eq("option_id", userId)
.eq("task_type","参与")
.eq("option_type","转阅")
.orderByDesc("option_time");
Page<MyTaskFlowHis> page = new Page<MyTaskFlowHis>(pageNo, pageSize);
IPage<MyTaskFlowHis> pageList = myTaskFlowHisService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
......
......@@ -11,7 +11,12 @@
SELECT t.uid
FROM my_task_flow t
WHERE t.deploy_id=#{taskName} AND t.target_id=#{name}
order by id desc
AND NOT EXISTS (
SELECT USER_ID_
FROM act_ru_identitylink k
WHERE k.TASK_ID_=t.task_id AND k.TYPE_='reader'
)
ORDER BY t.id DESC
LIMIT 1
</select>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论