后端返回里没有 applicant 键。model.ApplyOrder 确实有 Applicant 字段,但那是 另一张旧表的模型;审批页走的 MaterialApplication 只 SELECT u.username 并扫进 &app.Username(json tag 为 username)。列显示一直正常,全靠 || 后半段兜住, 左分支是死代码,去掉以免误导成还有第二个数据来源。 改为 row.username || '-'。
167 lines
5.5 KiB
Vue
167 lines
5.5 KiB
Vue
<template>
|
||
<div class="approval-page">
|
||
<div class="page-header">
|
||
<h2>申请审批</h2>
|
||
<el-select v-model="statusFilter" placeholder="状态筛选" style="width: 150px" @change="handleFilter">
|
||
<el-option label="全部" value="" />
|
||
<el-option label="待处理" value="pending" />
|
||
<el-option label="已通过" value="approved" />
|
||
<el-option label="已拒绝" value="rejected" />
|
||
</el-select>
|
||
</div>
|
||
|
||
<BaseTable
|
||
:data="approvalStore.applications"
|
||
:loading="approvalStore.loading"
|
||
:current-page="approvalStore.page.currentPage"
|
||
:page-size="approvalStore.page.pageSize"
|
||
:total="approvalStore.page.total"
|
||
@page-change="handlePageChange"
|
||
>
|
||
<el-table-column prop="application_no" label="申请单号" />
|
||
<el-table-column label="申请人" width="100">
|
||
<template #default="{ row }">
|
||
{{ row.username || '-' }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="items" label="物料明细" width="200">
|
||
<template #default="{ row }">
|
||
<template v-if="row.items && row.items.length > 0">
|
||
<span v-for="(item, idx) in row.items" :key="idx" class="text-wrap">
|
||
{{ item.material_code }} - {{ item.material_name }} × {{ item.quantity }}<br/>
|
||
</span>
|
||
</template>
|
||
<span v-else>-</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="status" label="状态">
|
||
<template #default="{ row }">
|
||
<StatusBadge :status="row.status" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="purpose" label="用途" />
|
||
<el-table-column prop="created_at" label="申请时间" width="160">
|
||
<template #default="{ row }">
|
||
{{ formatDate(row.created_at) }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="200" fixed="right">
|
||
<template #default="{ row }">
|
||
<template v-if="row.status === 'pending'">
|
||
<el-button size="small" type="success" @click="showApproveModal(row)">通过</el-button>
|
||
<el-button size="small" type="danger" @click="showRejectModal(row)">拒绝</el-button>
|
||
</template>
|
||
<span v-else>-</span>
|
||
</template>
|
||
</el-table-column>
|
||
</BaseTable>
|
||
|
||
<el-dialog v-model="approveDialogVisible" title="审批通过" width="400px">
|
||
<el-form :model="approveForm" label-width="100px">
|
||
<el-form-item label="自动出库">
|
||
<el-switch v-model="approveForm.autoOutbound" />
|
||
</el-form-item>
|
||
</el-form>
|
||
<template #footer>
|
||
<el-button @click="approveDialogVisible = false">取消</el-button>
|
||
<el-button type="success" @click="handleApprove">确认通过</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<el-dialog v-model="rejectDialogVisible" title="拒绝申请" width="400px">
|
||
<el-form :model="rejectForm" label-width="100px">
|
||
<el-form-item label="拒绝原因" required>
|
||
<el-input v-model="rejectForm.reason" type="textarea" rows="3" />
|
||
</el-form-item>
|
||
</el-form>
|
||
<template #footer>
|
||
<el-button @click="rejectDialogVisible = false">取消</el-button>
|
||
<el-button type="danger" @click="handleReject">确认拒绝</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, reactive, onMounted } from 'vue'
|
||
import { useApprovalStore } from '../stores/approval'
|
||
import BaseTable from '../components/business/BaseTable.vue'
|
||
import StatusBadge from '../components/business/StatusBadge.vue'
|
||
import { ElMessage } from 'element-plus'
|
||
import { formatDate } from '../utils/datetime'
|
||
|
||
const approvalStore = useApprovalStore()
|
||
|
||
const statusFilter = ref('')
|
||
const approveDialogVisible = ref(false)
|
||
const rejectDialogVisible = ref(false)
|
||
const currentApplication = ref(null)
|
||
|
||
// 审批默认勾选自动出库:通过即扣减库存并生成出库单,省去再去出库页手工建单。
|
||
// 初始值和每次打开弹窗时的重置都引用它,避免默认值改动时只改一处。
|
||
const AUTO_OUTBOUND_DEFAULT = true
|
||
|
||
const approveForm = reactive({ autoOutbound: AUTO_OUTBOUND_DEFAULT })
|
||
const rejectForm = reactive({ reason: '' })
|
||
|
||
onMounted(() => {
|
||
approvalStore.fetchPendingApplications()
|
||
})
|
||
|
||
function handleFilter() {
|
||
approvalStore.fetchPendingApplications(statusFilter.value)
|
||
}
|
||
|
||
function handlePageChange(page) {
|
||
approvalStore.fetchPendingApplications(statusFilter.value, page)
|
||
}
|
||
|
||
function showApproveModal(row) {
|
||
currentApplication.value = row
|
||
approveForm.autoOutbound = AUTO_OUTBOUND_DEFAULT
|
||
approveDialogVisible.value = true
|
||
}
|
||
|
||
async function handleApprove() {
|
||
await approvalStore.approveApplication(currentApplication.value.id, {
|
||
auto_outbound: approveForm.autoOutbound
|
||
})
|
||
ElMessage.success('审批通过')
|
||
approveDialogVisible.value = false
|
||
}
|
||
|
||
function showRejectModal(row) {
|
||
currentApplication.value = row
|
||
rejectForm.reason = ''
|
||
rejectDialogVisible.value = true
|
||
}
|
||
|
||
async function handleReject() {
|
||
if (!rejectForm.reason.trim()) {
|
||
ElMessage.warning('请填写拒绝原因')
|
||
return
|
||
}
|
||
await approvalStore.rejectApplication(currentApplication.value.id, {
|
||
reason: rejectForm.reason
|
||
})
|
||
ElMessage.success('已拒绝')
|
||
rejectDialogVisible.value = false
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.approval-page {
|
||
padding: 20px;
|
||
}
|
||
.page-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 20px;
|
||
}
|
||
.text-wrap {
|
||
word-break: break-word;
|
||
font-size: 0.85rem;
|
||
}
|
||
</style>
|