chore: 我的待办 & 请假
This commit is contained in:
parent
8f9215ffad
commit
e6e2c84f45
14
apps/web-antd/src/api/workflow/instance/index.ts
Normal file
14
apps/web-antd/src/api/workflow/instance/index.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import type { FlowInfoResponse } from './model';
|
||||||
|
|
||||||
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取流程图,流程记录
|
||||||
|
* @param businessId 业务标识
|
||||||
|
* @returns 流程图,流程记录
|
||||||
|
*/
|
||||||
|
export function flowInfo(businessId: string) {
|
||||||
|
return requestClient.get<FlowInfoResponse>(
|
||||||
|
`/workflow/instance/flowImage/${businessId}`,
|
||||||
|
);
|
||||||
|
}
|
41
apps/web-antd/src/api/workflow/instance/model.d.ts
vendored
Normal file
41
apps/web-antd/src/api/workflow/instance/model.d.ts
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
export interface Flow {
|
||||||
|
id: string;
|
||||||
|
createTime: string;
|
||||||
|
updateTime: string;
|
||||||
|
tenantId: string;
|
||||||
|
delFlag: string;
|
||||||
|
definitionId: string;
|
||||||
|
flowName?: any;
|
||||||
|
instanceId: string;
|
||||||
|
taskId: string;
|
||||||
|
cooperateType: number;
|
||||||
|
cooperateTypeName: string;
|
||||||
|
businessId?: any;
|
||||||
|
nodeCode: string;
|
||||||
|
nodeName: string;
|
||||||
|
nodeType: number;
|
||||||
|
targetNodeCode: string;
|
||||||
|
targetNodeName: string;
|
||||||
|
approver: string;
|
||||||
|
approveName: string;
|
||||||
|
collaborator?: any;
|
||||||
|
permissionList?: any;
|
||||||
|
skipType: string;
|
||||||
|
flowStatus: string;
|
||||||
|
flowTaskStatus?: any;
|
||||||
|
flowStatusName?: any;
|
||||||
|
message: string;
|
||||||
|
ext?: any;
|
||||||
|
createBy?: any;
|
||||||
|
formCustom: string;
|
||||||
|
formPath: string;
|
||||||
|
flowCode?: any;
|
||||||
|
version?: any;
|
||||||
|
runDuration: string;
|
||||||
|
nickName?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FlowInfoResponse {
|
||||||
|
image: string;
|
||||||
|
list: Flow[];
|
||||||
|
}
|
85
apps/web-antd/src/api/workflow/task/index.ts
Normal file
85
apps/web-antd/src/api/workflow/task/index.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import type { TaskInfo } from './model';
|
||||||
|
|
||||||
|
import type { PageQuery, PageResult } from '#/api/common';
|
||||||
|
|
||||||
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启动任务
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export function startWorkFlow(data: any) {
|
||||||
|
return requestClient.postWithMsg<void>('/workflow/task/startWorkFlow', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 办理任务
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export function completeTask(data: any) {
|
||||||
|
return requestClient.postWithMsg<void>('/workflow/task/completeTask', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询当前用户的待办任务
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function pageByTaskWait(params?: PageQuery) {
|
||||||
|
return requestClient.get<PageResult<TaskInfo>>(
|
||||||
|
'/workflow/task/pageByTaskWait',
|
||||||
|
{ params },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询当前用户的已办任务
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function pageByTaskFinish(params?: PageQuery) {
|
||||||
|
return requestClient.get<PageResult<TaskInfo>>(
|
||||||
|
'/workflow/task/pageByTaskFinish',
|
||||||
|
{ params },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有待办任务
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function pageByAllTaskWait(params?: PageQuery) {
|
||||||
|
return requestClient.get<PageResult<TaskInfo>>(
|
||||||
|
'/workflow/task/pageByAllTaskWait',
|
||||||
|
{ params },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询已办任务
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function pageByAllTaskFinish(params?: PageQuery) {
|
||||||
|
return requestClient.get<PageResult<TaskInfo>>(
|
||||||
|
'/workflow/task/pageByAllTaskFinish',
|
||||||
|
{ params },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询当前用户的抄送
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function pageByTaskCopy(params?: PageQuery) {
|
||||||
|
return requestClient.get<PageResult<TaskInfo>>(
|
||||||
|
'/workflow/task/pageByTaskCopy',
|
||||||
|
{ params },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据taskId查询代表任务
|
||||||
|
* @param taskId 任务id
|
||||||
|
* @returns info
|
||||||
|
*/
|
||||||
|
export function getTaskByTaskId(taskId: string) {
|
||||||
|
return requestClient.get<TaskInfo>(`/workflow/task/${taskId}`);
|
||||||
|
}
|
27
apps/web-antd/src/api/workflow/task/model.d.ts
vendored
Normal file
27
apps/web-antd/src/api/workflow/task/model.d.ts
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
export interface TaskInfo {
|
||||||
|
id: string;
|
||||||
|
createTime: string;
|
||||||
|
updateTime: string;
|
||||||
|
tenantId: string;
|
||||||
|
delFlag?: any;
|
||||||
|
definitionId: string;
|
||||||
|
instanceId: string;
|
||||||
|
flowName: string;
|
||||||
|
businessId: string;
|
||||||
|
nodeCode: string;
|
||||||
|
nodeName: string;
|
||||||
|
nodeType: number;
|
||||||
|
permissionList?: any;
|
||||||
|
userList?: any;
|
||||||
|
formCustom: string;
|
||||||
|
formPath: string;
|
||||||
|
flowCode: string;
|
||||||
|
version: string;
|
||||||
|
flowStatus: string;
|
||||||
|
flowStatusName: string;
|
||||||
|
transactorNames: string;
|
||||||
|
processedBy: string;
|
||||||
|
type: string;
|
||||||
|
nodeRatio?: any;
|
||||||
|
nickName: string;
|
||||||
|
}
|
@ -129,6 +129,39 @@ const profileRoute: RouteRecordStringComponent[] = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
component: 'BasicLayout',
|
||||||
|
meta: {
|
||||||
|
hideChildrenInMenu: true,
|
||||||
|
hideInMenu: true,
|
||||||
|
title: '请假申请',
|
||||||
|
},
|
||||||
|
name: 'WorkflowLeave',
|
||||||
|
path: '/',
|
||||||
|
redirect: '/workflow/leave',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
component: 'workflow/leave/leave-form',
|
||||||
|
meta: {
|
||||||
|
icon: 'eos-icons:role-binding-outlined',
|
||||||
|
keepAlive: true,
|
||||||
|
title: '请假申请',
|
||||||
|
},
|
||||||
|
name: 'WorkflowLeaveIndex',
|
||||||
|
path: '/workflow/leave',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'workflow/leave/leave-form',
|
||||||
|
meta: {
|
||||||
|
icon: 'eos-icons:role-binding-outlined',
|
||||||
|
keepAlive: true,
|
||||||
|
title: '请假申请',
|
||||||
|
},
|
||||||
|
name: 'WorkflowLeaveInner',
|
||||||
|
path: '/workflow/leave-inner',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Avatar, Descriptions, DescriptionsItem, Tag } from 'ant-design-vue';
|
import type { TaskInfo } from '#/api/workflow/task/model';
|
||||||
|
|
||||||
interface Props {
|
import { VbenAvatar } from '@vben/common-ui';
|
||||||
id: string;
|
import { DictEnum } from '@vben/constants';
|
||||||
endTime: string;
|
|
||||||
startTime: string;
|
import { Descriptions, DescriptionsItem } from 'ant-design-vue';
|
||||||
title: string;
|
|
||||||
desc: string;
|
import { renderDict } from '#/utils/render';
|
||||||
status: string;
|
|
||||||
|
interface Props extends TaskInfo {
|
||||||
active: boolean;
|
active: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,23 +30,28 @@ function handleClick() {
|
|||||||
class="cursor-pointer rounded-lg border-[1px] border-solid p-3 transition-shadow duration-300 ease-in-out hover:shadow-lg"
|
class="cursor-pointer rounded-lg border-[1px] border-solid p-3 transition-shadow duration-300 ease-in-out hover:shadow-lg"
|
||||||
@click.stop="handleClick"
|
@click.stop="handleClick"
|
||||||
>
|
>
|
||||||
<Descriptions :column="1" :title="info.title" size="middle">
|
<Descriptions :column="1" :title="info.flowName" size="middle">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<Tag color="warning">审批中</Tag>
|
<component
|
||||||
|
:is="renderDict(info.flowStatus, DictEnum.WF_BUSINESS_STATUS)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<DescriptionsItem label="描述">{{ info.desc }}</DescriptionsItem>
|
<DescriptionsItem label="当前节点名称">
|
||||||
<DescriptionsItem label="开始时间">{{ info.startTime }}</DescriptionsItem>
|
<div class="font-bold">{{ info.nodeName }}</div>
|
||||||
<DescriptionsItem label="结束时间">{{ info.endTime }}</DescriptionsItem>
|
</DescriptionsItem>
|
||||||
|
<DescriptionsItem label="开始时间">
|
||||||
|
{{ info.createTime }}
|
||||||
|
</DescriptionsItem>
|
||||||
|
<!-- <DescriptionsItem label="更新时间">
|
||||||
|
{{ info.updateTime }}
|
||||||
|
</DescriptionsItem> -->
|
||||||
</Descriptions>
|
</Descriptions>
|
||||||
<div class="flex items-center justify-between text-[14px]">
|
<div class="flex items-center justify-between text-[14px]">
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
<Avatar
|
<VbenAvatar :alt="info.nickName" class="size-[24px]" src="" />
|
||||||
size="small"
|
<span class="opacity-50">{{ info.nickName }}</span>
|
||||||
src="https://plus.dapdap.top/minio-server/plus/2024/11/21/925ed278e2d441beb7f695b41e13c4dd.jpg"
|
|
||||||
/>
|
|
||||||
<span class="opacity-50">疯狂的牛子Li</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="opacity-50">处理时间: 2022-01-01</div>
|
<div class="opacity-50">更新时间: 2222-22-22</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,21 +1,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { Flow } from '#/api/workflow/instance/model';
|
||||||
|
|
||||||
import { Timeline, TimelineItem } from 'ant-design-vue';
|
import { Timeline, TimelineItem } from 'ant-design-vue';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: 仅为demo 后期会替换
|
* TODO: 仅为demo 后期会替换
|
||||||
*/
|
*/
|
||||||
import { VbenAvatar } from '../../../../../../packages/@core/ui-kit/shadcn-ui/src/components';
|
import { VbenAvatar } from '@vben/common-ui';
|
||||||
|
|
||||||
interface ApprovalItem {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
status: string;
|
|
||||||
remark?: string;
|
|
||||||
time: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
list: ApprovalItem[];
|
list: Flow[];
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -24,10 +18,7 @@ const props = defineProps<{
|
|||||||
<TimelineItem v-for="item in props.list" :key="item.id">
|
<TimelineItem v-for="item in props.list" :key="item.id">
|
||||||
<template #dot>
|
<template #dot>
|
||||||
<div class="relative rounded-full border">
|
<div class="relative rounded-full border">
|
||||||
<VbenAvatar
|
<VbenAvatar :alt="item.approveName" class="size-[36px]" src="" />
|
||||||
class="size-[36px]"
|
|
||||||
src="https://plus.dapdap.top/minio-server/plus/2024/11/21/925ed278e2d441beb7f695b41e13c4dd.jpg"
|
|
||||||
/>
|
|
||||||
<div
|
<div
|
||||||
class="border-background absolute bottom-0 right-0 size-[16px] rounded-full border-2 bg-green-500 content-['']"
|
class="border-background absolute bottom-0 right-0 size-[16px] rounded-full border-2 bg-green-500 content-['']"
|
||||||
>
|
>
|
||||||
@ -37,12 +28,12 @@ const props = defineProps<{
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="ml-2 flex flex-col">
|
<div class="ml-2 flex flex-col gap-0.5">
|
||||||
<div>发起人</div>
|
<div class="font-bold">{{ item.nodeName }}</div>
|
||||||
<div>疯狂的牛子Li</div>
|
<div>{{ item.approveName }}</div>
|
||||||
<div>2022-01-01 12:00:00</div>
|
<div>{{ item.updateTime }}</div>
|
||||||
<div class="rounded-lg border p-1">
|
<div v-if="item.message" class="rounded-lg border p-1">
|
||||||
<span class="opacity-70">这里是备注信息</span>
|
<span class="opacity-70">{{ item.message }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</TimelineItem>
|
</TimelineItem>
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 26 KiB |
62
apps/web-antd/src/views/workflow/leave/api/index.ts
Normal file
62
apps/web-antd/src/views/workflow/leave/api/index.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import type { LeaveForm, LeaveQuery, LeaveVO } from './model';
|
||||||
|
|
||||||
|
import type { ID, IDS, PageResult } from '#/api/common';
|
||||||
|
|
||||||
|
import { commonExport } from '#/api/helper';
|
||||||
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询请假申请列表
|
||||||
|
* @param params
|
||||||
|
* @returns 请假申请列表
|
||||||
|
*/
|
||||||
|
export function leaveList(params?: LeaveQuery) {
|
||||||
|
return requestClient.get<PageResult<LeaveVO>>('/workflow/leave/list', {
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出请假申请列表
|
||||||
|
* @param params
|
||||||
|
* @returns 请假申请列表
|
||||||
|
*/
|
||||||
|
export function leaveExport(params?: LeaveQuery) {
|
||||||
|
return commonExport('/workflow/leave/export', params ?? {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询请假申请详情
|
||||||
|
* @param id id
|
||||||
|
* @returns 请假申请详情
|
||||||
|
*/
|
||||||
|
export function leaveInfo(id: ID) {
|
||||||
|
return requestClient.get<LeaveVO>(`/workflow/leave/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增请假申请
|
||||||
|
* @param data
|
||||||
|
* @returns void
|
||||||
|
*/
|
||||||
|
export function leaveAdd(data: LeaveForm) {
|
||||||
|
return requestClient.postWithMsg<void>('/workflow/leave', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新请假申请
|
||||||
|
* @param data
|
||||||
|
* @returns void
|
||||||
|
*/
|
||||||
|
export function leaveUpdate(data: LeaveForm) {
|
||||||
|
return requestClient.putWithMsg<void>('/workflow/leave', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除请假申请
|
||||||
|
* @param id id
|
||||||
|
* @returns void
|
||||||
|
*/
|
||||||
|
export function leaveRemove(id: ID | IDS) {
|
||||||
|
return requestClient.deleteWithMsg<void>(`/workflow/leave/${id}`);
|
||||||
|
}
|
107
apps/web-antd/src/views/workflow/leave/api/model.d.ts
vendored
Normal file
107
apps/web-antd/src/views/workflow/leave/api/model.d.ts
vendored
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import type { BaseEntity, PageQuery } from '#/api/common';
|
||||||
|
|
||||||
|
export interface LeaveVO {
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
id: number | string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请假类型
|
||||||
|
*/
|
||||||
|
leaveType: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间
|
||||||
|
*/
|
||||||
|
startDate: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束时间
|
||||||
|
*/
|
||||||
|
endDate: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请假天数
|
||||||
|
*/
|
||||||
|
leaveDays: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请假原因
|
||||||
|
*/
|
||||||
|
remark: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
status: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LeaveForm extends BaseEntity {
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
id?: number | string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请假类型
|
||||||
|
*/
|
||||||
|
leaveType?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间
|
||||||
|
*/
|
||||||
|
startDate?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束时间
|
||||||
|
*/
|
||||||
|
endDate?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请假天数
|
||||||
|
*/
|
||||||
|
leaveDays?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请假原因
|
||||||
|
*/
|
||||||
|
remark?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
status?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LeaveQuery extends PageQuery {
|
||||||
|
/**
|
||||||
|
* 请假类型
|
||||||
|
*/
|
||||||
|
leaveType?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间
|
||||||
|
*/
|
||||||
|
startDate?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束时间
|
||||||
|
*/
|
||||||
|
endDate?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请假天数
|
||||||
|
*/
|
||||||
|
leaveDays?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
status?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期范围参数
|
||||||
|
*/
|
||||||
|
params?: any;
|
||||||
|
}
|
135
apps/web-antd/src/views/workflow/leave/data.tsx
Normal file
135
apps/web-antd/src/views/workflow/leave/data.tsx
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import type { FormSchemaGetter } from '#/adapter/form';
|
||||||
|
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||||
|
|
||||||
|
import { DictEnum } from '@vben/constants';
|
||||||
|
import { getPopupContainer } from '@vben/utils';
|
||||||
|
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
import { OptionsTag } from '#/components/table';
|
||||||
|
import { renderDict } from '#/utils/render';
|
||||||
|
|
||||||
|
const leaveTypeOptions = [
|
||||||
|
{ label: '病假', value: '1' },
|
||||||
|
{ label: '事假', value: '2' },
|
||||||
|
{ label: '年假', value: '3' },
|
||||||
|
{ label: '婚假', value: '4' },
|
||||||
|
{ label: '产假', value: '5' },
|
||||||
|
{ label: '其他', value: '7' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const querySchema: FormSchemaGetter = () => [
|
||||||
|
{
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
min: 1,
|
||||||
|
},
|
||||||
|
fieldName: 'startLeaveDays',
|
||||||
|
label: '请假天数',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
min: 1,
|
||||||
|
},
|
||||||
|
fieldName: 'endLeaveDays',
|
||||||
|
label: '至',
|
||||||
|
labelClass: 'justify-center',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const columns: VxeGridProps['columns'] = [
|
||||||
|
{ type: 'checkbox', width: 60 },
|
||||||
|
{
|
||||||
|
title: '请假类型',
|
||||||
|
field: 'leaveType',
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
return <OptionsTag options={leaveTypeOptions} value={row.leaveType} />;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '开始时间',
|
||||||
|
field: 'startDate',
|
||||||
|
formatter: ({ cellValue }) => dayjs(cellValue).format('YYYY-MM-DD'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '结束时间',
|
||||||
|
field: 'endDate',
|
||||||
|
formatter: ({ cellValue }) => dayjs(cellValue).format('YYYY-MM-DD'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '请假天数',
|
||||||
|
field: 'leaveDays',
|
||||||
|
formatter: ({ cellValue }) => `${cellValue}天`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '请假原因',
|
||||||
|
field: 'remark',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '流程状态',
|
||||||
|
field: 'status',
|
||||||
|
slots: {
|
||||||
|
default: ({ row }) => {
|
||||||
|
return renderDict(row.status, DictEnum.WF_BUSINESS_STATUS);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'action',
|
||||||
|
fixed: 'right',
|
||||||
|
slots: { default: 'action' },
|
||||||
|
title: '操作',
|
||||||
|
width: 180,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const modalSchema: FormSchemaGetter = () => [
|
||||||
|
{
|
||||||
|
label: '主键',
|
||||||
|
fieldName: 'id',
|
||||||
|
component: 'Input',
|
||||||
|
dependencies: {
|
||||||
|
show: () => false,
|
||||||
|
triggerFields: [''],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '请假类型',
|
||||||
|
fieldName: 'leaveType',
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: leaveTypeOptions,
|
||||||
|
getPopupContainer,
|
||||||
|
},
|
||||||
|
rules: 'selectRequired',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '开始时间',
|
||||||
|
fieldName: 'dateRange',
|
||||||
|
component: 'RangePicker',
|
||||||
|
componentProps: {
|
||||||
|
showTime: true,
|
||||||
|
format: 'YYYY-MM-DD',
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
},
|
||||||
|
rules: 'required',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '请假天数',
|
||||||
|
fieldName: 'leaveDays',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
rules: 'required',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '请假原因',
|
||||||
|
fieldName: 'remark',
|
||||||
|
component: 'Textarea',
|
||||||
|
formItemClass: 'items-baseline',
|
||||||
|
},
|
||||||
|
];
|
@ -1,9 +1,170 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import CommonSkeleton from '#/views/common';
|
import type { LeaveForm } from './api/model';
|
||||||
|
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
import { Page, useVbenModal, type VbenFormProps } from '@vben/common-ui';
|
||||||
|
import { getVxePopupContainer } from '@vben/utils';
|
||||||
|
|
||||||
|
import { Modal, Popconfirm, Space } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import {
|
||||||
|
useVbenVxeGrid,
|
||||||
|
vxeCheckboxChecked,
|
||||||
|
type VxeGridProps,
|
||||||
|
} from '#/adapter/vxe-table';
|
||||||
|
import { commonDownloadExcel } from '#/utils/file/download';
|
||||||
|
|
||||||
|
import { leaveExport, leaveList, leaveRemove } from './api';
|
||||||
|
import { columns, querySchema } from './data';
|
||||||
|
import leaveModal from './leave-modal.vue';
|
||||||
|
|
||||||
|
const formOptions: VbenFormProps = {
|
||||||
|
commonConfig: {
|
||||||
|
labelWidth: 80,
|
||||||
|
componentProps: {
|
||||||
|
allowClear: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
schema: querySchema(),
|
||||||
|
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4',
|
||||||
|
};
|
||||||
|
|
||||||
|
const gridOptions: VxeGridProps = {
|
||||||
|
checkboxConfig: {
|
||||||
|
// 高亮
|
||||||
|
highlight: true,
|
||||||
|
// 翻页时保留选中状态
|
||||||
|
reserve: true,
|
||||||
|
// 点击行选中
|
||||||
|
// trigger: 'row',
|
||||||
|
},
|
||||||
|
columns,
|
||||||
|
height: 'auto',
|
||||||
|
keepSource: true,
|
||||||
|
pagerConfig: {},
|
||||||
|
proxyConfig: {
|
||||||
|
ajax: {
|
||||||
|
query: async ({ page }, formValues = {}) => {
|
||||||
|
return await leaveList({
|
||||||
|
pageNum: page.currentPage,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
...formValues,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rowConfig: {
|
||||||
|
keyField: 'id',
|
||||||
|
},
|
||||||
|
// 表格全局唯一表示 保存列配置需要用到
|
||||||
|
id: 'workflow-leave-index',
|
||||||
|
};
|
||||||
|
|
||||||
|
const [BasicTable, tableApi] = useVbenVxeGrid({
|
||||||
|
formOptions,
|
||||||
|
gridOptions,
|
||||||
|
});
|
||||||
|
|
||||||
|
const [LeaveModal, modalApi] = useVbenModal({
|
||||||
|
connectedComponent: leaveModal,
|
||||||
|
});
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
function handleAdd() {
|
||||||
|
router.push('/workflow/leave');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleEdit(row: Required<LeaveForm>) {
|
||||||
|
modalApi.setData({ id: row.id });
|
||||||
|
modalApi.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleDelete(row: Required<LeaveForm>) {
|
||||||
|
await leaveRemove(row.id);
|
||||||
|
await tableApi.query();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMultiDelete() {
|
||||||
|
const rows = tableApi.grid.getCheckboxRecords();
|
||||||
|
const ids = rows.map((row: Required<LeaveForm>) => row.id);
|
||||||
|
Modal.confirm({
|
||||||
|
title: '提示',
|
||||||
|
okType: 'danger',
|
||||||
|
content: `确认删除选中的${ids.length}条记录吗?`,
|
||||||
|
onOk: async () => {
|
||||||
|
await leaveRemove(ids);
|
||||||
|
await tableApi.query();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDownloadExcel() {
|
||||||
|
commonDownloadExcel(
|
||||||
|
leaveExport,
|
||||||
|
'请假申请数据',
|
||||||
|
tableApi.formApi.form.values,
|
||||||
|
{
|
||||||
|
fieldMappingTime: formOptions.fieldMappingTime,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<Page :auto-content-height="true">
|
||||||
<CommonSkeleton />
|
<BasicTable table-title="请假申请列表">
|
||||||
</div>
|
<template #toolbar-tools>
|
||||||
|
<Space>
|
||||||
|
<a-button
|
||||||
|
v-access:code="['workflow:leave:export']"
|
||||||
|
@click="handleDownloadExcel"
|
||||||
|
>
|
||||||
|
{{ $t('pages.common.export') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
:disabled="!vxeCheckboxChecked(tableApi)"
|
||||||
|
danger
|
||||||
|
type="primary"
|
||||||
|
v-access:code="['workflow:leave:remove']"
|
||||||
|
@click="handleMultiDelete"
|
||||||
|
>
|
||||||
|
{{ $t('pages.common.delete') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
v-access:code="['workflow:leave:add']"
|
||||||
|
@click="handleAdd"
|
||||||
|
>
|
||||||
|
{{ $t('pages.common.add') }}
|
||||||
|
</a-button>
|
||||||
|
</Space>
|
||||||
|
</template>
|
||||||
|
<template #action="{ row }">
|
||||||
|
<Space>
|
||||||
|
<ghost-button
|
||||||
|
v-access:code="['workflow:leave:edit']"
|
||||||
|
@click.stop="handleEdit(row)"
|
||||||
|
>
|
||||||
|
{{ $t('pages.common.edit') }}
|
||||||
|
</ghost-button>
|
||||||
|
<Popconfirm
|
||||||
|
:get-popup-container="getVxePopupContainer"
|
||||||
|
placement="left"
|
||||||
|
title="确认删除?"
|
||||||
|
@confirm="handleDelete(row)"
|
||||||
|
>
|
||||||
|
<ghost-button
|
||||||
|
danger
|
||||||
|
v-access:code="['workflow:leave:remove']"
|
||||||
|
@click.stop=""
|
||||||
|
>
|
||||||
|
{{ $t('pages.common.delete') }}
|
||||||
|
</ghost-button>
|
||||||
|
</Popconfirm>
|
||||||
|
</Space>
|
||||||
|
</template>
|
||||||
|
</BasicTable>
|
||||||
|
<LeaveModal @reload="tableApi.query()" />
|
||||||
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
56
apps/web-antd/src/views/workflow/leave/leave-form.vue
Normal file
56
apps/web-antd/src/views/workflow/leave/leave-form.vue
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
import { Card } from 'ant-design-vue';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
|
||||||
|
import { leaveInfo } from './api';
|
||||||
|
import { modalSchema } from './data';
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const disabled = route.query?.readonly === 'true';
|
||||||
|
const id = route.query?.id as string;
|
||||||
|
|
||||||
|
const [BasicForm, formApi] = useVbenForm({
|
||||||
|
commonConfig: {
|
||||||
|
// 默认占满两列
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
// 默认label宽度 px
|
||||||
|
labelWidth: 80,
|
||||||
|
// 通用配置项 会影响到所有表单项
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
disabled,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
schema: modalSchema(),
|
||||||
|
showDefaultActions: false,
|
||||||
|
wrapperClass: 'grid-cols-2',
|
||||||
|
fieldMappingTime: [
|
||||||
|
[
|
||||||
|
'dateRange',
|
||||||
|
['startDate', 'endDate'],
|
||||||
|
['YYYY-MM-DD 00:00:00', 'YYYY-MM-DD 23:59:59'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
// 只读 获取信息赋值
|
||||||
|
if (id && disabled) {
|
||||||
|
const resp = await leaveInfo(id);
|
||||||
|
await formApi.setValues(resp);
|
||||||
|
const dateRange = [dayjs(resp.startDate), dayjs(resp.endDate)];
|
||||||
|
await formApi.setFieldValue('dateRange', dateRange);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Card>
|
||||||
|
<BasicForm />
|
||||||
|
</Card>
|
||||||
|
</template>
|
87
apps/web-antd/src/views/workflow/leave/leave-modal.vue
Normal file
87
apps/web-antd/src/views/workflow/leave/leave-modal.vue
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import { $t } from '@vben/locales';
|
||||||
|
import { cloneDeep } from '@vben/utils';
|
||||||
|
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
|
||||||
|
import { leaveAdd, leaveInfo, leaveUpdate } from './api';
|
||||||
|
import { modalSchema } from './data';
|
||||||
|
|
||||||
|
const emit = defineEmits<{ reload: [] }>();
|
||||||
|
|
||||||
|
const isUpdate = ref(false);
|
||||||
|
const title = computed(() => {
|
||||||
|
return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
|
||||||
|
});
|
||||||
|
|
||||||
|
const [BasicForm, formApi] = useVbenForm({
|
||||||
|
commonConfig: {
|
||||||
|
// 默认占满两列
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
// 默认label宽度 px
|
||||||
|
labelWidth: 80,
|
||||||
|
// 通用配置项 会影响到所有表单项
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
schema: modalSchema(),
|
||||||
|
showDefaultActions: false,
|
||||||
|
wrapperClass: 'grid-cols-2',
|
||||||
|
});
|
||||||
|
|
||||||
|
const [BasicModal, modalApi] = useVbenModal({
|
||||||
|
fullscreenButton: false,
|
||||||
|
onCancel: handleCancel,
|
||||||
|
onConfirm: handleConfirm,
|
||||||
|
onOpenChange: async (isOpen) => {
|
||||||
|
if (!isOpen) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
modalApi.modalLoading(true);
|
||||||
|
|
||||||
|
const { id } = modalApi.getData() as { id?: number | string };
|
||||||
|
isUpdate.value = !!id;
|
||||||
|
|
||||||
|
if (isUpdate.value && id) {
|
||||||
|
const record = await leaveInfo(id);
|
||||||
|
await formApi.setValues(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
modalApi.modalLoading(false);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
async function handleConfirm() {
|
||||||
|
try {
|
||||||
|
modalApi.modalLoading(true);
|
||||||
|
const { valid } = await formApi.validate();
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// getValues获取为一个readonly的对象 需要修改必须先深拷贝一次
|
||||||
|
const data = cloneDeep(await formApi.getValues());
|
||||||
|
await (isUpdate.value ? leaveUpdate(data) : leaveAdd(data));
|
||||||
|
emit('reload');
|
||||||
|
await handleCancel();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
} finally {
|
||||||
|
modalApi.modalLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleCancel() {
|
||||||
|
modalApi.close();
|
||||||
|
await formApi.resetForm();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<BasicModal :close-on-click-modal="false" :title="title" class="w-[550px]">
|
||||||
|
<BasicForm />
|
||||||
|
</BasicModal>
|
||||||
|
</template>
|
@ -1,25 +1,52 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref } from 'vue';
|
import type { FlowInfoResponse } from '#/api/workflow/instance/model';
|
||||||
|
import type { TaskInfo } from '#/api/workflow/task/model';
|
||||||
|
|
||||||
import { Page } from '@vben/common-ui';
|
import { computed, onMounted, ref } from 'vue';
|
||||||
|
|
||||||
|
import { Fallback, Page, VbenAvatar } from '@vben/common-ui';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Alert,
|
|
||||||
Avatar,
|
|
||||||
Card,
|
Card,
|
||||||
Divider,
|
Divider,
|
||||||
|
Empty,
|
||||||
InputSearch,
|
InputSearch,
|
||||||
Space,
|
Space,
|
||||||
TabPane,
|
TabPane,
|
||||||
Tabs,
|
Tabs,
|
||||||
Tag,
|
Tag,
|
||||||
} from 'ant-design-vue';
|
} from 'ant-design-vue';
|
||||||
import { debounce, uniqueId } from 'lodash-es';
|
import { debounce } from 'lodash-es';
|
||||||
|
|
||||||
|
import { flowInfo } from '#/api/workflow/instance';
|
||||||
|
import { pageByTaskWait } from '#/api/workflow/task';
|
||||||
|
|
||||||
import { ApprovalCard, ApprovalTimeline } from '../components';
|
import { ApprovalCard, ApprovalTimeline } from '../components';
|
||||||
import RejectionPng from '../components/rejection.png';
|
|
||||||
|
|
||||||
const handleScroll = debounce((e: Event) => {
|
const emptyImage = Empty.PRESENTED_IMAGE_SIMPLE;
|
||||||
|
|
||||||
|
const taskList = ref<({ active: boolean } & TaskInfo)[]>([]);
|
||||||
|
const taskTotal = ref(0);
|
||||||
|
const page = ref(1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已经加载全部数据 即 taskList.length === taskTotal
|
||||||
|
*/
|
||||||
|
const isLoadComplete = computed(
|
||||||
|
() => taskList.value.length === taskTotal.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
/**
|
||||||
|
* 获取待办任务列表
|
||||||
|
*/
|
||||||
|
const resp = await pageByTaskWait({ pageSize: 10, pageNum: page.value });
|
||||||
|
console.log(resp);
|
||||||
|
taskList.value = resp.rows.map((item) => ({ ...item, active: false }));
|
||||||
|
taskTotal.value = resp.total;
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleScroll = debounce(async (e: Event) => {
|
||||||
if (!e.target) {
|
if (!e.target) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -29,117 +56,139 @@ const handleScroll = debounce((e: Event) => {
|
|||||||
const { scrollTop, clientHeight, scrollHeight } = e.target as HTMLElement;
|
const { scrollTop, clientHeight, scrollHeight } = e.target as HTMLElement;
|
||||||
// 判断是否滚动到底部
|
// 判断是否滚动到底部
|
||||||
const isBottom = scrollTop + clientHeight >= scrollHeight;
|
const isBottom = scrollTop + clientHeight >= scrollHeight;
|
||||||
console.log(isBottom);
|
|
||||||
// console.log(scrollTop + clientHeight);
|
// 滚动到底部且没有加载完成
|
||||||
// console.log(scrollHeight);
|
if (isBottom && !isLoadComplete.value) {
|
||||||
|
page.value += 1;
|
||||||
|
const resp = await pageByTaskWait({ pageSize: 10, pageNum: page.value });
|
||||||
|
taskList.value.push(
|
||||||
|
...resp.rows.map((item) => ({ ...item, active: false })),
|
||||||
|
);
|
||||||
|
}
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
const data = reactive(
|
const currentInstance = ref<FlowInfoResponse>();
|
||||||
Array.from({ length: 10 }).map(() => ({
|
|
||||||
id: uniqueId(),
|
|
||||||
startTime: '2022-01-01',
|
|
||||||
endTime: '2022-01-02',
|
|
||||||
title: '审批任务',
|
|
||||||
desc: '审批任务描述',
|
|
||||||
status: '审批中',
|
|
||||||
active: false,
|
|
||||||
})),
|
|
||||||
);
|
|
||||||
|
|
||||||
const timeLine = Array.from({ length: 5 }).map(() => ({
|
|
||||||
id: uniqueId(),
|
|
||||||
name: '张三',
|
|
||||||
status: '审批中',
|
|
||||||
remark: '审批任务描述',
|
|
||||||
time: '2022-01-01',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const lastSelectId = ref('');
|
const lastSelectId = ref('');
|
||||||
function handleCardClick(id: string) {
|
async function handleCardClick(item: TaskInfo) {
|
||||||
|
const { id, businessId } = item;
|
||||||
// 点击的是同一个
|
// 点击的是同一个
|
||||||
if (lastSelectId.value === id) {
|
if (lastSelectId.value === id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 反选状态 & 如果已经点击了 不变 & 保持只能有一个选中
|
// 反选状态 & 如果已经点击了 不变 & 保持只能有一个选中
|
||||||
data.forEach((item) => {
|
taskList.value.forEach((item) => {
|
||||||
item.active = item.id === id;
|
item.active = item.id === id;
|
||||||
});
|
});
|
||||||
lastSelectId.value = id;
|
lastSelectId.value = id;
|
||||||
|
|
||||||
|
const resp = await flowInfo(businessId);
|
||||||
|
currentInstance.value = resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const instanceInfo = computed(() => {
|
||||||
|
if (!currentInstance.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const length = currentInstance.value.list.length;
|
||||||
|
if (length === 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 最末尾为申请人
|
||||||
|
const info = currentInstance.value.list[length - 1]!;
|
||||||
|
return {
|
||||||
|
id: info.instanceId,
|
||||||
|
createTime: info.createTime,
|
||||||
|
approveName: info.approveName,
|
||||||
|
flowName: info.flowName ?? '未知流程',
|
||||||
|
businessId: '1867081791031750658',
|
||||||
|
};
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page :auto-content-height="true">
|
<Page :auto-content-height="true">
|
||||||
<div class="flex h-full gap-2">
|
<div class="flex h-full gap-2">
|
||||||
<div class="bg-background flex h-full w-[320px] flex-col rounded-lg">
|
<div
|
||||||
|
class="bg-background flex h-full min-w-[320px] max-w-[320px] flex-col rounded-lg"
|
||||||
|
>
|
||||||
<!-- 搜索条件 -->
|
<!-- 搜索条件 -->
|
||||||
<div
|
<div
|
||||||
class="bg-background z-100 sticky left-0 top-0 w-full rounded-t-lg border-b-[1px] border-solid p-2"
|
class="bg-background z-100 sticky left-0 top-0 w-full rounded-t-lg border-b-[1px] border-solid p-2"
|
||||||
>
|
>
|
||||||
<InputSearch placeholder="搜索" />
|
<InputSearch placeholder="搜索任务名称" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="thin-scrollbar flex flex-1 flex-col gap-2 overflow-y-auto py-3"
|
class="thin-scrollbar flex flex-1 flex-col gap-2 overflow-y-auto py-3"
|
||||||
@scroll="handleScroll"
|
@scroll="handleScroll"
|
||||||
>
|
>
|
||||||
<ApprovalCard
|
<template v-if="taskList.length > 0">
|
||||||
v-for="item in data"
|
<ApprovalCard
|
||||||
:key="item.id"
|
v-for="item in taskList"
|
||||||
:info="item"
|
:key="item.id"
|
||||||
class="mx-2"
|
:info="item"
|
||||||
@click="handleCardClick"
|
class="mx-2"
|
||||||
/>
|
@click="handleCardClick(item)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<Empty v-else :image="emptyImage" />
|
||||||
</div>
|
</div>
|
||||||
<!-- total显示 -->
|
<!-- total显示 -->
|
||||||
<div
|
<div
|
||||||
class="bg-background sticky bottom-0 w-full rounded-b-lg border-t-[1px] py-2"
|
class="bg-background sticky bottom-0 w-full rounded-b-lg border-t-[1px] py-2"
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-center">
|
<div class="flex items-center justify-center">
|
||||||
共 {{ data.length }} 条记录
|
共 {{ taskList.length }} 条记录
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Card
|
<Card
|
||||||
|
v-if="currentInstance && instanceInfo"
|
||||||
:body-style="{ overflowY: 'auto', height: '100%' }"
|
:body-style="{ overflowY: 'auto', height: '100%' }"
|
||||||
|
:title="`编号: ${instanceInfo.id}`"
|
||||||
class="thin-scrollbar flex-1 overflow-y-hidden"
|
class="thin-scrollbar flex-1 overflow-y-hidden"
|
||||||
size="small"
|
size="small"
|
||||||
title="编号: 1234567890123456789012"
|
|
||||||
>
|
>
|
||||||
<div class="flex flex-col gap-5 p-4">
|
<div class="flex flex-col gap-5 p-4">
|
||||||
<div class="flex flex-col gap-3">
|
<div class="flex flex-col gap-3">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<div class="text-2xl font-bold">报销申请</div>
|
<div class="text-2xl font-bold">{{ instanceInfo.flowName }}</div>
|
||||||
<div>
|
<div>
|
||||||
<Tag color="warning">申请中</Tag>
|
<Tag color="warning">申请中</Tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<Avatar
|
<VbenAvatar
|
||||||
size="small"
|
:alt="instanceInfo.approveName"
|
||||||
src="https://plus.dapdap.top/minio-server/plus/2024/11/21/925ed278e2d441beb7f695b41e13c4dd.jpg"
|
class="size-[24px]"
|
||||||
|
src=""
|
||||||
/>
|
/>
|
||||||
<span>疯狂的牛子Li</span>
|
<span>{{ instanceInfo.approveName }}</span>
|
||||||
<div class="flex items-center opacity-50">
|
<div class="flex items-center opacity-50">
|
||||||
<span>XXXX有限公司</span>
|
<span>XXXX有限公司</span>
|
||||||
<Divider type="vertical" />
|
<Divider type="vertical" />
|
||||||
<span>提交于: 2022-01-01 12:00:00</span>
|
<span>提交于: {{ instanceInfo.createTime }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 右侧图标 -->
|
|
||||||
<div class="z-100 absolute right-3 top-3">
|
|
||||||
<img :src="RejectionPng" class="size-[96px]" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<Tabs class="flex-1">
|
<Tabs class="flex-1">
|
||||||
<TabPane key="1" tab="审批详情">
|
<TabPane key="1" tab="审批详情">
|
||||||
<div class="h-fulloverflow-y-auto">
|
<div class="h-fulloverflow-y-auto">
|
||||||
<Alert message="该页面仅为静态页 后期可能会用到!" type="info" />
|
<!-- <Alert message="该页面仅为静态页 后期可能会用到!" type="info" /> -->
|
||||||
|
<iframe
|
||||||
|
:src="`/workflow/leave-inner?readonly=true&id=${instanceInfo.businessId}`"
|
||||||
|
class="h-[300px] w-full"
|
||||||
|
></iframe>
|
||||||
<Divider />
|
<Divider />
|
||||||
<ApprovalTimeline :list="timeLine" />
|
<ApprovalTimeline :list="currentInstance.list" />
|
||||||
</div>
|
</div>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<TabPane key="2" tab="审批记录">审批记录</TabPane>
|
<TabPane key="2" tab="审批流程图">
|
||||||
<TabPane key="3" tab="全文评论(999+)">全文评论</TabPane>
|
<img
|
||||||
|
:src="`data:image/png;base64,${currentInstance.image}`"
|
||||||
|
class="rounded-lg border"
|
||||||
|
/>
|
||||||
|
</TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
<!-- 固定底部 -->
|
<!-- 固定底部 -->
|
||||||
@ -155,6 +204,7 @@ function handleCardClick(id: string) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
<Fallback v-else title="点击左侧选择" />
|
||||||
</div>
|
</div>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
export * from './components';
|
export * from './components';
|
||||||
export * from './ui';
|
export * from './ui';
|
||||||
|
export { VbenAvatar } from '@vben-core/shadcn-ui';
|
||||||
|
Loading…
Reference in New Issue
Block a user