Appearance
BizApprovalActions 审批操作条
同意 / 驳回(弹原因输入,必填与字数校验)/ 转交 / 加签 的统一操作出口。与 BizProcess(流程展示)、BizTimeline(审批记录)组合成完整审批页。
基础用法
点击「驳回」弹出原因输入(必填、默认 100 字内);同意走异步 loading
同意走异步
loading;驳回弹 textarea 原因输入(默认必填、100 字内),确认后 reject 事件携带原因。<script setup lang="ts">
/** 基础用法:同意 / 驳回(必填原因) */
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { BizApprovalActions } from 'vue3-ep-biz-lib'
const loading = ref(false)
const onApprove = (): void => {
loading.value = true
window.setTimeout(() => {
loading.value = false
ElMessage.success('已同意,流转至下一节点')
}, 800)
}
const onReject = (reason: string): void => {
ElMessage.warning(`已驳回,原因:${reason}`)
}
</script>
<template>
<div style="max-width: 560px">
<BizApprovalActions :loading="loading" @approve="onApprove" @reject="onReject" />
<p style="margin: 10px 0 0; font-size: 13px; color: var(--el-text-color-secondary)">
点击「驳回」弹出原因输入(必填、默认 100 字内);同意走异步 loading
</p>
</div>
</template>
显示代码
完整审批页
发起申请处理人:周七09-23 09:05
部门审批处理人:吴总监09-23 09:31
财务复核处理人:郑会计
完成
- 周七 · 发起start采购伺服电机 ×12,金额 ¥86,40009-23 09:05
- 吴总监 · 同意ok「同意,注意验收标准」09-23 09:31
show-transfer / show-add-sign 开启附加动作(选人交给业务侧,常配 BizTablePicker);confirm-approve 让同意也走二次确认(大额/高危审批建议开启)。<script setup lang="ts">
/** 场景:完整审批页——页头 + 流程 + 审批记录 + 操作条联动 */
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { BizApprovalActions, BizProcess, BizTimeline } from 'vue3-ep-biz-lib'
import type { BizProcessNode, BizTimelineRecord } from 'vue3-ep-biz-lib'
const nodes = ref<BizProcessNode[]>([
{ name: '发起申请', status: 'success', operator: '周七', time: '09-23 09:05' },
{ name: '部门审批', status: 'success', operator: '吴总监', time: '09-23 09:31' },
{ name: '财务复核', status: 'running', operator: '郑会计' },
{ name: '完成', status: 'wait' },
])
const records: BizTimelineRecord[] = [
{ title: '吴总监 · 同意', content: '「同意,注意验收标准」', timestamp: '09-23 09:31', status: 'ok' },
{ title: '周七 · 发起', content: '采购伺服电机 ×12,金额 ¥86,400', timestamp: '09-23 09:05', status: 'start' },
]
const onApprove = (): void => {
nodes.value = nodes.value.map((node) => (node.status === 'running' ? { ...node, status: 'success' } : node))
ElMessage.success('已同意,流程完成')
}
const onReject = (reason: string): void => {
ElMessage.warning(`已驳回:${reason}`)
}
</script>
<template>
<div style="max-width: 640px; display: flex; flex-direction: column; gap: 20px">
<BizProcess :nodes="nodes" :node-width="110" />
<BizTimeline :records="records" :status-map="{ ok: { type: 'success' }, start: { type: 'info' } }" reverse />
<BizApprovalActions show-transfer show-add-sign confirm-approve :reject-reason="{ maxLength: 50 }" @approve="onApprove" @reject="onReject" @transfer="ElMessage.info('打开转交选人(配合 BizTablePicker)')" @add-sign="ElMessage.info('打开加签选人(配合 BizTablePicker)')" />
</div>
</template>
显示代码
高危审批(大额放款)
风控场景:confirm-approve 开启同意二次确认(文案写明不可撤回后果),驳回原因限 50 字。
<script setup lang="ts">
/** 场景:高危审批——同意二次确认 + 驳回 50 字内原因 */
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { BizApprovalActions } from 'vue3-ep-biz-lib'
const loading = ref(false)
const result = ref('')
const onApprove = (): void => {
loading.value = true
window.setTimeout(() => {
loading.value = false
result.value = '已同意(高危单据需双人复核,已自动通知复核人)'
ElMessage.success('审批通过')
}, 900)
}
const onReject = (reason: string): void => {
result.value = `已驳回:${reason}`
}
</script>
<template>
<div style="max-width: 560px; display: flex; flex-direction: column; gap: 14px">
<BizApprovalActions
confirm-approve
approve-message="单笔金额超 50 万,同意后立即放款且不可撤回,是否继续?"
:reject-reason="{ placeholder: '请说明驳回依据(条款/预算)', maxLength: 50 }"
:loading="loading"
@approve="onApprove"
@reject="onReject"
/>
<div v-if="result !== ''" style="padding: 10px 12px; background: var(--el-fill-color-light); border-radius: 6px; font-size: 13px">{{ result }}</div>
</div>
</template>
显示代码
转交与加签(选人组合)
流转场景:transfer / add-sign 事件打开 BizTablePicker(tree 形态)单选选人,选择完成即执行流转动作。
<script setup lang="ts">
/** 场景:转交与加签——与 BizTablePicker(tree 形态)组合选人 */
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { BizApprovalActions, BizTablePicker } from 'vue3-ep-biz-lib'
import type { BizTablePickerChangePayload, BizTablePickerColumn, BizTablePickerParams, BizTablePickerResult, BizTablePickerRow } from 'vue3-ep-biz-lib'
const pickerVisibleFor = ref<'transfer' | 'add-sign' | null>(null)
const columns: BizTablePickerColumn[] = [
{ prop: 'name', label: '姓名', width: 120 },
{ prop: 'dept', label: '部门', minWidth: 140 },
]
const candidates: BizTablePickerRow[] = [
{ id: 1, name: '郑会计', dept: '财务部' },
{ id: 2, name: '孙专员', dept: '人事部' },
{ id: 3, name: '周主管', dept: '采购部' },
]
const request = (params: BizTablePickerParams): Promise<BizTablePickerResult> => {
const keyword = params.keyword.trim()
const filtered = keyword === '' ? candidates : candidates.filter((m) => String(m.name).includes(keyword) || String(m.dept ?? '').includes(keyword))
return Promise.resolve({ list: filtered, total: filtered.length })
}
const picked = ref<BizTablePickerRow | null>(null)
const onChange = (payload: BizTablePickerChangePayload): void => {
const target = payload.selected[0]
if (target === undefined) return
if (pickerVisibleFor.value === 'transfer') {
ElMessage.success(`已转交给 ${String(target.name)}(${String(target.dept)})`)
} else if (pickerVisibleFor.value === 'add-sign') {
ElMessage.success(`已加签 ${String(target.name)}(${String(target.dept)})`)
}
pickerVisibleFor.value = null
}
const openPicker = (kind: 'transfer' | 'add-sign'): void => {
pickerVisibleFor.value = kind
picked.value = null
}
</script>
<template>
<div style="max-width: 640px; display: flex; flex-direction: column; gap: 10px">
<BizApprovalActions
show-transfer
show-add-sign
@approve="ElMessage.success('已同意')"
@reject="(reason: string) => ElMessage.warning(`驳回:${reason}`)"
@transfer="openPicker('transfer')"
@add-sign="openPicker('add-sign')"
/>
<BizTablePicker
v-if="pickerVisibleFor !== null"
v-model="picked"
filter-mode="tree"
:multiple="false"
:columns="columns"
:request="request"
label-key="name"
:title="pickerVisibleFor === 'transfer' ? '转交给谁?' : '加签给谁?'"
:trigger-text="pickerVisibleFor === 'transfer' ? '选择转交人' : '选择加签人'"
empty-text="未选择"
@change="onChange"
/>
</div>
</template>
显示代码
终审页
采购单 CG-2088终审金额 ¥86,400 · 三级审批已通过
发起申请处理人:周七
部门审批处理人:吴总监
财务复核处理人:郑会计
总经理终审处理人:当前用户
终审场景:文案改为「终审通过 / 退回发起人」,与 BizProcess 三级完成态联动,只剩最后一环。
<script setup lang="ts">
/** 场景:终审页——仅终审人可操作,流程展示完成态 */
import { ElMessage, ElTag } from 'element-plus'
import { BizApprovalActions, BizProcess } from 'vue3-ep-biz-lib'
import type { BizProcessNode } from 'vue3-ep-biz-lib'
const nodes: BizProcessNode[] = [
{ name: '发起申请', status: 'success', operator: '周七' },
{ name: '部门审批', status: 'success', operator: '吴总监' },
{ name: '财务复核', status: 'success', operator: '郑会计' },
{ name: '总经理终审', status: 'running', operator: '当前用户' },
]
const onApprove = (): void => {
ElMessage.success('终审通过,流程完结')
}
</script>
<template>
<div style="max-width: 640px; display: flex; flex-direction: column; gap: 16px">
<div style="display: flex; align-items: center; gap: 8px">
<span style="font-weight: 600">采购单 CG-2088</span>
<ElTag type="danger" size="small">终审</ElTag>
<span style="font-size: 13px; color: var(--el-text-color-secondary)">金额 ¥86,400 · 三级审批已通过</span>
</div>
<BizProcess :nodes="nodes" :node-width="110" />
<BizApprovalActions approve-text="终审通过" reject-text="退回发起人" :reject-reason="{ maxLength: 200 }" @approve="onApprove" @reject="(reason: string) => ElMessage.warning(`退回:${reason}`)" />
</div>
</template>
显示代码
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| approve-text / reject-text | string | '同意' / '驳回' | 按钮文案 |
| show-transfer / show-add-sign | boolean | false | 显示转交 / 加签 |
| transfer-text / add-sign-text | string | '转交' / '加签' | 附加按钮文案 |
| confirm-approve | boolean | false | 同意前二次确认 |
| approve-message | string | 见类型 | 同意确认文案 |
| reject-reason | { placeholder?, required?, maxLength? } | 必填/100 字 | 驳回原因配置 |
| loading | boolean | false | 提交中(同意/驳回按钮) |
| disabled | boolean | false | 禁用全部 |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| approve | — | 同意 |
| reject | (reason: string) | 驳回(携带原因) |
| transfer / add-sign | — | 转交 / 加签(选人由业务侧接管) |
Slots
| 插槽名 | 说明 |
|---|---|
| — | 无自定义插槽 |
Expose
| 属性/方法 | 说明 |
|---|---|
| — | 无暴露实例 |