update
This commit is contained in:
128
frontend/src/views/approvals/ApprovalInstanceView.vue
Normal file
128
frontend/src/views/approvals/ApprovalInstanceView.vue
Normal file
@@ -0,0 +1,128 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import DataTablePage from '@/components/DataTablePage.vue'
|
||||
import { getApprovalInstances, decideApproval, type ApprovalInstance } from '@/api/modules/approval'
|
||||
import { getUsers, type SystemUser } from '@/api/modules/system'
|
||||
|
||||
const loading = ref(false)
|
||||
const instances = ref<ApprovalInstance[]>([])
|
||||
const users = ref<SystemUser[]>([])
|
||||
const statusFilter = ref<string | undefined>(undefined)
|
||||
const showDecide = ref(false)
|
||||
const current = ref<ApprovalInstance | null>(null)
|
||||
const decision = ref({ step_index: 0, approver_id: '', approved: true, comment: '' })
|
||||
|
||||
const statusOptions = [
|
||||
{ label: '待审批', value: 'pending' },
|
||||
{ label: '已通过', value: 'approved' },
|
||||
{ label: '已拒绝', value: 'rejected' },
|
||||
]
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
instances.value = await getApprovalInstances(statusFilter.value)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function loadUsers() {
|
||||
try {
|
||||
users.value = await getUsers()
|
||||
} catch {
|
||||
users.value = []
|
||||
}
|
||||
}
|
||||
|
||||
function userName(id?: string) {
|
||||
if (!id) return '—'
|
||||
return users.value.find((u) => u.id === id)?.username || id
|
||||
}
|
||||
|
||||
function openDecide(inst: ApprovalInstance) {
|
||||
current.value = inst
|
||||
const step = inst.steps.find((s) => s.status === 'pending')
|
||||
decision.value = { step_index: step ? step.step_index : 0, approver_id: '', approved: true, comment: '' }
|
||||
showDecide.value = true
|
||||
}
|
||||
|
||||
async function submitDecision() {
|
||||
if (!current.value) return
|
||||
if (!decision.value.approver_id) {
|
||||
ElMessage.warning('请选择审批人')
|
||||
return
|
||||
}
|
||||
await decideApproval(current.value.id, decision.value.step_index, {
|
||||
approver_id: decision.value.approver_id,
|
||||
approved: decision.value.approved,
|
||||
comment: decision.value.comment,
|
||||
})
|
||||
ElMessage.success('审批已提交')
|
||||
showDecide.value = false
|
||||
load()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadUsers()
|
||||
load()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page">
|
||||
<DataTablePage title="审批实例" :data="instances" :loading="loading" searchable search-fields="resource_type,resource_id">
|
||||
<template #toolbar-extra>
|
||||
<el-select v-model="statusFilter" placeholder="状态" clearable style="width: 140px" @change="load">
|
||||
<el-option v-for="s in statusOptions" :key="s.value" :label="s.label" :value="s.value" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template #columns>
|
||||
<el-table-column prop="resource_type" label="资源类型" min-width="120" />
|
||||
<el-table-column prop="resource_id" label="资源 ID" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column prop="applicant_id" label="申请人" min-width="120">
|
||||
<template #default="{ row }">{{ userName(row.applicant_id) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="状态" min-width="100" />
|
||||
<el-table-column prop="current_step" label="当前步骤" min-width="100" />
|
||||
<el-table-column prop="create_time" label="创建时间" min-width="180" />
|
||||
</template>
|
||||
<template #actions="{ row }">
|
||||
<el-button v-if="row.status === 'pending'" link type="primary" @click="openDecide(row)">审批</el-button>
|
||||
</template>
|
||||
</DataTablePage>
|
||||
<el-dialog v-model="showDecide" title="审批决策" width="480px">
|
||||
<el-form label-width="80px" v-if="current">
|
||||
<el-form-item label="实例">
|
||||
{{ current.resource_type }} / {{ current.resource_id }}
|
||||
</el-form-item>
|
||||
<el-form-item label="步骤">
|
||||
第 {{ decision.step_index + 1 }} 步
|
||||
</el-form-item>
|
||||
<el-form-item label="审批人" required>
|
||||
<el-select v-model="decision.approver_id" filterable style="width: 100%">
|
||||
<el-option v-for="u in users" :key="u.id" :label="u.username" :value="u.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="结果">
|
||||
<el-radio-group v-model="decision.approved">
|
||||
<el-radio :value="true">通过</el-radio>
|
||||
<el-radio :value="false">拒绝</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="意见">
|
||||
<el-input v-model="decision.comment" type="textarea" :rows="3" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="showDecide = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitDecision">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.page { padding: 16px; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user