feat(projects): 新增减签功能
This commit is contained in:
parent
55dceca28b
commit
f1d7b9733f
@ -10,6 +10,7 @@ defineOptions({
|
|||||||
const { loading, startLoading, endLoading } = useLoading();
|
const { loading, startLoading, endLoading } = useLoading();
|
||||||
const { bool: addSignatureVisible, setTrue: openAddSignatureModal } = useBoolean();
|
const { bool: addSignatureVisible, setTrue: openAddSignatureModal } = useBoolean();
|
||||||
const { bool: transferVisible, setTrue: openTransferModal } = useBoolean();
|
const { bool: transferVisible, setTrue: openTransferModal } = useBoolean();
|
||||||
|
const { bool: reduceSignatureVisible, setTrue: openReduceSignatureModal } = useBoolean();
|
||||||
interface Props {
|
interface Props {
|
||||||
taskId: CommonType.IdType;
|
taskId: CommonType.IdType;
|
||||||
assigneeIds: CommonType.IdType[];
|
assigneeIds: CommonType.IdType[];
|
||||||
@ -124,6 +125,11 @@ function handleTerminate() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleReduceSubmit() {
|
||||||
|
visible.value = false;
|
||||||
|
emit('refresh');
|
||||||
|
}
|
||||||
|
|
||||||
async function getTaskInfo() {
|
async function getTaskInfo() {
|
||||||
startLoading();
|
startLoading();
|
||||||
const { error, data } = await fetchGetTask(props.taskId);
|
const { error, data } = await fetchGetTask(props.taskId);
|
||||||
@ -178,7 +184,9 @@ watch(visible, () => {
|
|||||||
<NSpace justify="end" :size="16">
|
<NSpace justify="end" :size="16">
|
||||||
<NButton v-if="isWaiting" type="primary" @click="openTransferModal">转办</NButton>
|
<NButton v-if="isWaiting" type="primary" @click="openTransferModal">转办</NButton>
|
||||||
<NButton v-if="isWaiting && isTicketOrSignInstance" type="primary" @click="openAddSignatureModal">加签</NButton>
|
<NButton v-if="isWaiting && isTicketOrSignInstance" type="primary" @click="openAddSignatureModal">加签</NButton>
|
||||||
<NButton v-if="isWaiting && isTicketOrSignInstance" type="primary">减签</NButton>
|
<NButton v-if="isWaiting && isTicketOrSignInstance" type="primary" @click="openReduceSignatureModal">
|
||||||
|
减签
|
||||||
|
</NButton>
|
||||||
<NButton v-if="isWaiting" type="error" @click="handleTerminate">中止</NButton>
|
<NButton v-if="isWaiting" type="error" @click="handleTerminate">中止</NButton>
|
||||||
</NSpace>
|
</NSpace>
|
||||||
</template>
|
</template>
|
||||||
@ -191,5 +199,11 @@ watch(visible, () => {
|
|||||||
:disabled-ids="assigneeIds"
|
:disabled-ids="assigneeIds"
|
||||||
@confirm="handleAddSignatureConfirm"
|
@confirm="handleAddSignatureConfirm"
|
||||||
/>
|
/>
|
||||||
|
<!-- 减签用户 -->
|
||||||
|
<ReduceSignatureDrawer
|
||||||
|
v-model:visible="reduceSignatureVisible"
|
||||||
|
:task="taskInfo!"
|
||||||
|
@reduce-submit="handleReduceSubmit"
|
||||||
|
/>
|
||||||
</NModal>
|
</NModal>
|
||||||
</template>
|
</template>
|
||||||
|
154
src/components/custom/workflow/reduce-signature-drawer.vue
Normal file
154
src/components/custom/workflow/reduce-signature-drawer.vue
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
<script lang="tsx" setup>
|
||||||
|
import { reactive, ref, watch } from 'vue';
|
||||||
|
import { useLoading } from '@sa/hooks';
|
||||||
|
import { fetchGetCurrentTaskAllUser, fetchTaskOperate } from '@/service/api/workflow/task';
|
||||||
|
import { $t } from '@/locales';
|
||||||
|
import ButtonIcon from '@/components/custom/button-icon.vue';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'ReduceSignatureDrawer'
|
||||||
|
});
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
task: Api.Workflow.Task;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
|
const visible = defineModel<boolean>('visible', {
|
||||||
|
default: false
|
||||||
|
});
|
||||||
|
|
||||||
|
interface Emits {
|
||||||
|
(e: 'reduceSubmit'): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
|
const { loading, startLoading, endLoading } = useLoading();
|
||||||
|
type UserTaskModel = Api.System.User & { nodeName: string };
|
||||||
|
|
||||||
|
const userData = ref<UserTaskModel[]>([]);
|
||||||
|
|
||||||
|
type Model = Api.Workflow.TaskOperateParams;
|
||||||
|
const model: Model = reactive(createDefaultModel());
|
||||||
|
|
||||||
|
const checkedRowKeys = ref<CommonType.IdType[]>([]);
|
||||||
|
|
||||||
|
function createDefaultModel(): Model {
|
||||||
|
return {
|
||||||
|
taskId: null,
|
||||||
|
userId: undefined,
|
||||||
|
userIds: undefined,
|
||||||
|
message: ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const columns = ref<NaiveUI.TableColumn<UserTaskModel>[]>([
|
||||||
|
{
|
||||||
|
type: 'selection',
|
||||||
|
align: 'center',
|
||||||
|
width: 50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '节点名称',
|
||||||
|
key: 'nodeName',
|
||||||
|
align: 'center',
|
||||||
|
minWidth: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '办理人员',
|
||||||
|
key: 'nickName',
|
||||||
|
align: 'center',
|
||||||
|
minWidth: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'operate',
|
||||||
|
title: $t('common.operate'),
|
||||||
|
align: 'center',
|
||||||
|
width: 130,
|
||||||
|
render(row) {
|
||||||
|
return (
|
||||||
|
<ButtonIcon
|
||||||
|
text
|
||||||
|
type="error"
|
||||||
|
icon="material-symbols:delete-outline"
|
||||||
|
tooltipContent={$t('common.delete')}
|
||||||
|
popconfirmContent={$t('common.confirmDelete')}
|
||||||
|
onPositiveClick={() => handleReduceSignature([row.userId])}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
async function handleReduceSignature(userIds: CommonType.IdType[]) {
|
||||||
|
model.taskId = props.task.id;
|
||||||
|
model.userIds = userIds;
|
||||||
|
const { error } = await fetchTaskOperate(model, 'reductionSignature');
|
||||||
|
if (error) return;
|
||||||
|
window.$message?.success('减签成功');
|
||||||
|
handleCloseDrawer();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getTaskAllUser() {
|
||||||
|
startLoading();
|
||||||
|
const { error, data } = await fetchGetCurrentTaskAllUser(props.task.id);
|
||||||
|
if (error) return;
|
||||||
|
userData.value = data.map(item => ({
|
||||||
|
...item,
|
||||||
|
nodeName: props.task.nodeName
|
||||||
|
}));
|
||||||
|
endLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCloseDrawer() {
|
||||||
|
visible.value = false;
|
||||||
|
emit('reduceSubmit');
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(visible, async () => {
|
||||||
|
if (visible.value) {
|
||||||
|
await getTaskAllUser();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NModal v-model:show="visible" class="w-700px" preset="card" title="待减签人员">
|
||||||
|
<NCard class="h-full card-wrapper">
|
||||||
|
<NSpace wrap justify="space-between" class="mb-16px lt-sm:w-200px">
|
||||||
|
<TableRowCheckAlert v-model:checked-row-keys="checkedRowKeys" />
|
||||||
|
<NButton
|
||||||
|
size="small"
|
||||||
|
ghost
|
||||||
|
type="error"
|
||||||
|
:disabled="checkedRowKeys.length === 0"
|
||||||
|
@click="handleReduceSignature(checkedRowKeys)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<icon-material-symbols:delete-outline class="text-icon" />
|
||||||
|
</template>
|
||||||
|
删除
|
||||||
|
</NButton>
|
||||||
|
</NSpace>
|
||||||
|
<NDataTable
|
||||||
|
v-model:checked-row-keys="checkedRowKeys"
|
||||||
|
class="h-400px"
|
||||||
|
flex-height
|
||||||
|
:row-key="row => row.userId"
|
||||||
|
size="small"
|
||||||
|
:columns="columns"
|
||||||
|
:data="userData"
|
||||||
|
:loading="loading"
|
||||||
|
/>
|
||||||
|
</NCard>
|
||||||
|
</NModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.n-alert {
|
||||||
|
--n-padding: 5px 13px !important;
|
||||||
|
--n-icon-margin: 6px 8px 0 12px !important;
|
||||||
|
--n-icon-size: 20px !important;
|
||||||
|
}
|
||||||
|
</style>
|
@ -61,3 +61,11 @@ export function fetchTerminateTask(data: Api.Workflow.TerminateTaskOperateParams
|
|||||||
data
|
data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 获取当前任务所有人员 */
|
||||||
|
export function fetchGetCurrentTaskAllUser(taskId: CommonType.IdType) {
|
||||||
|
return request<Api.System.User[]>({
|
||||||
|
url: `/workflow/task/currentTaskAllUser/${taskId}`,
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
3
src/typings/components.d.ts
vendored
3
src/typings/components.d.ts
vendored
@ -13,7 +13,6 @@ declare module 'vue' {
|
|||||||
BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
|
BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
|
||||||
BooleanTag: typeof import('./../components/custom/boolean-tag.vue')['default']
|
BooleanTag: typeof import('./../components/custom/boolean-tag.vue')['default']
|
||||||
ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default']
|
ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default']
|
||||||
copy: typeof import('./../components/custom/dept-tree-select copy.vue')['default']
|
|
||||||
CountTo: typeof import('./../components/custom/count-to.vue')['default']
|
CountTo: typeof import('./../components/custom/count-to.vue')['default']
|
||||||
DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
|
DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
|
||||||
DataTable: typeof import('./../components/common/data-table.vue')['default']
|
DataTable: typeof import('./../components/common/data-table.vue')['default']
|
||||||
@ -81,6 +80,7 @@ declare module 'vue' {
|
|||||||
NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
|
NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
|
||||||
NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
|
NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
|
||||||
NButton: typeof import('naive-ui')['NButton']
|
NButton: typeof import('naive-ui')['NButton']
|
||||||
|
NCar: typeof import('naive-ui')['NCar']
|
||||||
NCard: typeof import('naive-ui')['NCard']
|
NCard: typeof import('naive-ui')['NCard']
|
||||||
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||||
NCheckboxGroup: typeof import('naive-ui')['NCheckboxGroup']
|
NCheckboxGroup: typeof import('naive-ui')['NCheckboxGroup']
|
||||||
@ -153,6 +153,7 @@ declare module 'vue' {
|
|||||||
OssUpload: typeof import('./../components/custom/oss-upload.vue')['default']
|
OssUpload: typeof import('./../components/custom/oss-upload.vue')['default']
|
||||||
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
|
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
|
||||||
PostSelect: typeof import('./../components/custom/post-select.vue')['default']
|
PostSelect: typeof import('./../components/custom/post-select.vue')['default']
|
||||||
|
ReduceSignatureDrawer: typeof import('./../components/custom/workflow/reduce-signature-drawer.vue')['default']
|
||||||
ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
|
ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
|
||||||
RoleSelect: typeof import('./../components/custom/role-select.vue')['default']
|
RoleSelect: typeof import('./../components/custom/role-select.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
@ -106,7 +106,7 @@ watch(visible, () => {
|
|||||||
<NDrawerContent :title="title" :native-scrollbar="false" closable>
|
<NDrawerContent :title="title" :native-scrollbar="false" closable>
|
||||||
<NForm ref="formRef" :model="model" :rules="rules">
|
<NForm ref="formRef" :model="model" :rules="rules">
|
||||||
<NFormItem label="上级分类" path="parentId">
|
<NFormItem label="上级分类" path="parentId">
|
||||||
<WorkflowCategorySelect v-model:value="model.parentId" />
|
<FlowCategorySelect v-model:value="model.parentId" />
|
||||||
</NFormItem>
|
</NFormItem>
|
||||||
<NFormItem label="分类名称" path="categoryName">
|
<NFormItem label="分类名称" path="categoryName">
|
||||||
<NInput v-model:value="model.categoryName" placeholder="请输入分类名称" />
|
<NInput v-model:value="model.categoryName" placeholder="请输入分类名称" />
|
||||||
|
@ -115,7 +115,7 @@ watch(visible, () => {
|
|||||||
>
|
>
|
||||||
<NForm ref="formRef" label-placement="left" :model="data" :rules="rules">
|
<NForm ref="formRef" label-placement="left" :model="data" :rules="rules">
|
||||||
<NFormItem label="流程分类" path="category">
|
<NFormItem label="流程分类" path="category">
|
||||||
<WorkflowCategorySelect v-model:value="data.category" />
|
<FlowCategorySelect v-model:value="data.category" />
|
||||||
</NFormItem>
|
</NFormItem>
|
||||||
</NForm>
|
</NForm>
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ watch(visible, () => {
|
|||||||
<NDrawerContent :title="title" :native-scrollbar="false" closable>
|
<NDrawerContent :title="title" :native-scrollbar="false" closable>
|
||||||
<NForm ref="formRef" :model="model" :rules="rules">
|
<NForm ref="formRef" :model="model" :rules="rules">
|
||||||
<NFormItem label="流程类别" path="category">
|
<NFormItem label="流程类别" path="category">
|
||||||
<WorkflowCategorySelect v-model:value="model.category" placeholder="请选择流程类别" />
|
<FlowCategorySelect v-model:value="model.category" placeholder="请选择流程类别" />
|
||||||
</NFormItem>
|
</NFormItem>
|
||||||
<NFormItem label="流程编码" path="flowCode">
|
<NFormItem label="流程编码" path="flowCode">
|
||||||
<NInput v-model:value="model.flowCode" placeholder="请输入流程编码" />
|
<NInput v-model:value="model.flowCode" placeholder="请输入流程编码" />
|
||||||
|
Loading…
Reference in New Issue
Block a user