<script lang="ts" setup>
|
import type { TreeActionType } from '@jnpf/ui';
|
|
import { computed, nextTick, reactive, ref, toRefs, unref, watch } from 'vue';
|
|
import { useMessage } from '@jnpf/hooks';
|
import { BasicTree, ScrollContainer } from '@jnpf/ui';
|
import { BasicForm, useForm } from '@jnpf/ui/form';
|
import { BasicModal, useModalInner } from '@jnpf/ui/modal';
|
|
import { getSamePosUser, getWorkByUser, workHandover } from '#/api/permission/user';
|
import { getDevUser } from '#/api/system/system';
|
import { QueryUserSelect } from '#/components/CommonModal';
|
|
interface State {
|
activeKey: string;
|
userInfo: any;
|
loading: boolean;
|
key: number;
|
flowTaskList: any[];
|
flowList: any[];
|
appList: any[];
|
flowTaskIds: any[];
|
flowIds: any[];
|
appIds: any[];
|
isAppShow: boolean;
|
}
|
|
const emit = defineEmits(['register', 'reload']);
|
const { createMessage } = useMessage();
|
const state = reactive<State>({
|
activeKey: '',
|
userInfo: {},
|
loading: false,
|
key: Date.now(),
|
flowTaskList: [],
|
flowList: [],
|
appList: [],
|
flowTaskIds: [],
|
flowIds: [],
|
appIds: [],
|
isAppShow: false,
|
});
|
const { activeKey, key, loading } = toRefs(state);
|
const treeRef = ref<Nullable<TreeActionType>>(null);
|
const [registerModal, { closeModal, changeOkLoading }] = useModalInner(init);
|
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
|
labelWidth: 100,
|
schemas: [
|
{
|
field: 'transferUser',
|
label: '工作移交人',
|
component: 'Input',
|
componentProps: { disabled: true },
|
},
|
{
|
field: 'content',
|
label: '交接内容',
|
component: 'Select',
|
slot: 'content',
|
},
|
{
|
field: 'handoverUser',
|
label: '交接人',
|
component: 'UserSelect',
|
slot: 'handoverUser',
|
rules: [{ required: true, trigger: 'change', message: '必填' }],
|
},
|
{
|
ifShow: () => state.isAppShow,
|
field: 'appHandoverUser',
|
label: '应用交接人',
|
component: 'UserSelect',
|
slot: 'appHandoverUser',
|
rules: [{ required: true, trigger: 'change', message: '必填' }],
|
},
|
],
|
});
|
const tabList = [
|
{ fullName: '流程列表', id: 'flow' },
|
{ fullName: '流程实例', id: 'flowTask' },
|
{ fullName: '我的应用', id: 'app' },
|
];
|
|
const getTips = computed(() => {
|
if (state.activeKey === 'flowTask') return '转交内容:包含移交人未处理的待签、待办、在办列表数据';
|
if (state.activeKey === 'flow') return '转交内容:审批节点、抄送人是移交人的流程';
|
return '转交内容:授权给移交人或移交人创建的应用';
|
});
|
const getTreeData = computed(() => state[`${state.activeKey}List`] || []);
|
const getTabList = computed(() => (state.isAppShow ? tabList : tabList.filter((o) => o.id !== 'app')));
|
|
watch(
|
() => state.activeKey,
|
() => {
|
setTreeCheckedKeys();
|
},
|
);
|
|
function init(data) {
|
resetFields();
|
state.flowTaskList = [];
|
state.flowList = [];
|
state.appList = [];
|
state.isAppShow = false;
|
state.flowTaskIds = [];
|
state.flowIds = [];
|
state.appIds = [];
|
state.userInfo = data.userInfo || '';
|
state.activeKey = 'flow';
|
setFieldsValue({ transferUser: `${state.userInfo.realName}/${state.userInfo.account}` });
|
state.loading = true;
|
getWorkByUser({ fromId: state.userInfo.id })
|
.then((res) => {
|
state.loading = false;
|
state.key = Date.now();
|
state.flowTaskList = res.data.flowTask || [];
|
state.flowList = res.data.flow || [];
|
state.appList = res.data.app || [];
|
state.isAppShow = !!res.data.isAppShow;
|
})
|
.catch(() => {
|
state.loading = false;
|
});
|
}
|
function getTree() {
|
const tree = unref(treeRef);
|
if (!tree) throw new Error('tree is null!');
|
return tree;
|
}
|
function handleTreeCheck() {
|
const childrenIds: any[] = (getTree().getCheckedKeys() as any[]) || [];
|
const parentIds: any[] = (getTree().getHalfCheckedKeys() as any[]) || [];
|
const ids = [...parentIds, ...childrenIds];
|
state[`${state.activeKey}Ids`] = ids;
|
}
|
function setTreeCheckedKeys() {
|
state.key = Date.now();
|
nextTick(() => {
|
const list = getTree().getParentKeys();
|
const keys = state[`${state.activeKey}Ids`].filter((id) => !list.includes(id));
|
getTree().setCheckedKeys(keys);
|
});
|
}
|
async function handleSubmit() {
|
const values = await validate();
|
if (!values) return;
|
// if (!state.flowTaskIds.length && !state.flowIds.length && !state.appIds.length) return createMessage.warning('请先选择交接内容');
|
const query = {
|
...values,
|
flowTaskList: state.flowTaskIds,
|
flowList: state.flowIds,
|
appList: state.appIds,
|
fromId: state.userInfo.id,
|
};
|
changeOkLoading(true);
|
workHandover(query)
|
.then((res) => {
|
changeOkLoading(false);
|
createMessage.success(res.msg);
|
emit('reload');
|
closeModal();
|
})
|
.catch(() => {
|
changeOkLoading(false);
|
});
|
}
|
</script>
|
<template>
|
<BasicModal v-bind="$attrs" @register="registerModal" title="工作交接" :width="800" class="work-handover-modal" destroy-on-close @ok="handleSubmit">
|
<BasicForm @register="registerForm">
|
<template #content>
|
<div class="tabs-box">
|
<a-tabs v-model:active-key="activeKey">
|
<a-tab-pane v-for="item in getTabList" :key="item.id" :tab="item.fullName" />
|
</a-tabs>
|
<ScrollContainer class="px-[20px]">
|
<div class="pb-[10px]">
|
<JnpfAlert :message="getTips" type="warning" />
|
</div>
|
<BasicTree ref="treeRef" checkable default-expand-all :loading="loading" :key="key" :tree-data="getTreeData" @check="handleTreeCheck" />
|
</ScrollContainer>
|
</div>
|
</template>
|
<template #handoverUser="{ model, field }">
|
<QueryUserSelect v-model:value="model[field]" :api="getSamePosUser" :query="{ id: state.userInfo.id }" />
|
</template>
|
<template #appHandoverUser="{ model, field }">
|
<QueryUserSelect v-model:value="model[field]" :api="getDevUser" />
|
</template>
|
</BasicForm>
|
</BasicModal>
|
</template>
|
<style lang="scss">
|
.work-handover-modal {
|
.tabs-box {
|
border: 1px solid var(--border-color-base);
|
border-radius: 2px;
|
|
.ant-tabs-tab:first-child {
|
margin-left: 20px;
|
}
|
|
.scroll-container .jnpf-tree {
|
height: 290px;
|
overflow: auto;
|
}
|
}
|
}
|
</style>
|