material_manage_system/frontend/src/views/Approval.vue
文睿 张 f0722eed00 fix: 审批页申请人列去掉永远取不到的 row.applicant
后端返回里没有 applicant 键。model.ApplyOrder 确实有 Applicant 字段,但那是
另一张旧表的模型;审批页走的 MaterialApplication 只 SELECT u.username 并扫进
&app.Username(json tag 为 username)。列显示一直正常,全靠 || 后半段兜住,
左分支是死代码,去掉以免误导成还有第二个数据来源。

改为 row.username || '-'。
2026-09-21 16:19:22 +08:00

167 lines
5.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>