优化
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import '@/styles/adminWorkbench.css'
|
||||
import '@/styles/adminDensity.css'
|
||||
import { computed, onActivated, onMounted, onBeforeUnmount, ref, watch } from 'vue'
|
||||
import { computed, onActivated, onMounted, onBeforeUnmount, reactive, ref, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useAuthStore } from '@/core/auth/auth'
|
||||
import { procurementStatuses, statusLabel, statusTone, money } from '../procurementPresentation'
|
||||
@@ -11,9 +12,11 @@ import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.v
|
||||
import ListPageLayout from '@/shared/components/ListPageLayout.vue'
|
||||
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
|
||||
import QueryToolbar, { type QueryField, type QueryModel } from '@/shared/components/QueryToolbar.vue'
|
||||
import AppDialog from '@/shared/components/AppDialog.vue'
|
||||
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import { listOverseasPurchaseCustomerOptions, listOverseasPurchases } from '../api/platformOverseasBusiness'
|
||||
import { listOverseasPurchaseCustomerOptions, listOverseasPurchaseWarehouseOptions, listOverseasPurchases } from '../api/platformOverseasBusiness'
|
||||
import { submitProcurementCommand } from '../api/procurementCommands'
|
||||
import { overseasBusinessPermissions } from '../permissions'
|
||||
import type { OverseasPurchaseCustomerOption, OverseasPurchaseQuery, OverseasPurchaseStatus, OverseasPurchaseSummary } from '../types'
|
||||
|
||||
@@ -23,6 +26,10 @@ const rows = ref<OverseasPurchaseSummary[]>([]); const loading = ref(false); con
|
||||
const page = ref(1); const pageSize = ref(20); const total = ref(0)
|
||||
const filters = ref<QueryModel>({ orderNo: '', customerId: '', purchaseCategory: '', productName: '', status: '' }); const applied = ref({ ...filters.value })
|
||||
const customerOptions = ref<OverseasPurchaseCustomerOption[]>([]); const customersLoading = ref(false)
|
||||
const reviewOpen = ref(false), reviewSaving = ref(false), reviewLoading = ref(false)
|
||||
const reviewRow = ref<OverseasPurchaseSummary | null>(null), reviewWarehouses = ref<Awaited<ReturnType<typeof listOverseasPurchaseWarehouseOptions>>>([])
|
||||
const reviewRequestKey = ref('')
|
||||
const reviewForm = reactive({ decision: 'APPROVE' as 'APPROVE' | 'REJECT', purchaseWarehouseId: '', remark: '' })
|
||||
const fields = computed<QueryField[]>(() => [
|
||||
{ key: 'orderNo', type: 'input', label: '订单编号', placeholder: '请输入订单编号', width: 210 },
|
||||
{ key: 'customerId', type: 'select', label: '客户', placeholder: '全部客户', width: 210, options: customerOptions.value.map((item) => ({ label: item.customerName, value: item.customerId })), props: { filterable: true, loading: customersLoading.value } },
|
||||
@@ -31,7 +38,7 @@ const fields = computed<QueryField[]>(() => [
|
||||
{ key: 'status', type: 'select', label: '履约状态', placeholder: '全部状态', width: 190, options: Object.entries(procurementStatuses).map(([value, label]) => ({ value, label })) },
|
||||
])
|
||||
const columns: DataTableColumn[] = [
|
||||
{ key: 'actions', label: '操作', width: 120, fixed: 'left', slotName: 'actions' },
|
||||
{ key: 'actions', label: '操作', width: 170, fixed: 'left', slotName: 'actions' },
|
||||
{ key: 'orderNo', prop: 'orderNo', label: '订单编号', minWidth: 220, singleLine: false },
|
||||
{ key: 'status', label: '状态', minWidth: 145, slotName: 'status', afterColumn: 'orderNo' },
|
||||
{ key: 'customerName', prop: 'customerName', label: '客户名称', minWidth: 220, singleLine: false, formatter: (row: OverseasPurchaseSummary) => row.customerName || '—' },
|
||||
@@ -64,7 +71,26 @@ function load() {
|
||||
}
|
||||
watch(() => auth.user?.id, () => { rows.value = []; total.value = 0; void load() })
|
||||
function search(model: QueryModel) { applied.value = { ...model }; if (page.value === 1) void load(); else page.value = 1 }
|
||||
function open(row: OverseasPurchaseSummary, edit = false) { void router.push({ name: edit ? 'overseas-business-purchase-edit' : 'overseas-business-purchase-detail', params: { purchaseId: row.orderNo }, query: { customerId: row.customerId } }) }
|
||||
function open(row: OverseasPurchaseSummary) { void router.push({ name: 'overseas-business-purchase-detail', params: { purchaseId: row.orderNo }, query: { customerId: row.customerId } }) }
|
||||
async function beginReview(row: OverseasPurchaseSummary) {
|
||||
reviewRow.value = row; reviewWarehouses.value = []; reviewRequestKey.value = crypto.randomUUID(); Object.assign(reviewForm, { decision: 'APPROVE', purchaseWarehouseId: '', remark: '' }); reviewOpen.value = true
|
||||
reviewLoading.value = true
|
||||
try { reviewWarehouses.value = await listOverseasPurchaseWarehouseOptions(row.procurementDirection) }
|
||||
catch (error) { ElMessage.error(getApiErrorDetails(error, '仓库加载失败').message) }
|
||||
finally { reviewLoading.value = false }
|
||||
}
|
||||
async function submitReview() {
|
||||
const row = reviewRow.value
|
||||
if (!row || reviewSaving.value) return
|
||||
if (reviewForm.decision === 'APPROVE' && !reviewForm.purchaseWarehouseId) { ElMessage.warning('请选择采购仓库'); return }
|
||||
if (reviewForm.decision === 'REJECT' && !reviewForm.remark.trim()) { ElMessage.warning('请填写驳回原因'); return }
|
||||
reviewSaving.value = true
|
||||
try {
|
||||
await submitProcurementCommand(row.orderNo, row.customerId, 'review', { version: row.version, idempotencyKey: reviewRequestKey.value, decision: reviewForm.decision, ...(reviewForm.decision === 'APPROVE' ? { purchaseWarehouseId: reviewForm.purchaseWarehouseId } : { remark: reviewForm.remark.trim() }) })
|
||||
reviewOpen.value = false; ElMessage.success('审核完成'); await load()
|
||||
} catch (error) { ElMessage.error(getApiErrorDetails(error, '审核失败').message) }
|
||||
finally { reviewSaving.value = false }
|
||||
}
|
||||
async function loadCustomerOptions() { customersLoading.value = true; try { customerOptions.value = await listOverseasPurchaseCustomerOptions() } catch { customerOptions.value = [] } finally { customersLoading.value = false } }
|
||||
let activatedOnce = false
|
||||
watch([page, pageSize], () => { void load() }); onMounted(() => { void load(); void loadCustomerOptions() })
|
||||
@@ -81,10 +107,17 @@ onActivated(() => { if (activatedOnce) void load(); else activatedOnce = true })
|
||||
<template #notices><template v-if="loadError"><LoadErrorState title="海外采购订单暂时无法加载" :message="loadError.message" :loading="loading" @retry="load"><template #details><ApiErrorMeta :details="loadError" /></template></LoadErrorState></template></template>
|
||||
|
||||
|
||||
<template #actions="{ row }"><div class="density-actions row-actions admin-text-actions"><el-button class="density-action" data-tone="neutral" size="small" @click="open(row as OverseasPurchaseSummary)">详情</el-button><el-button class="density-action" data-tone="neutral" v-if="access.can(overseasBusinessPermissions.purchaseEdit)" size="small" @click="open(row as OverseasPurchaseSummary, true)">编辑</el-button></div></template>
|
||||
<template #actions="{ row }"><div class="density-actions row-actions admin-text-actions"><el-button class="density-action" data-tone="neutral" size="small" @click="open(row as OverseasPurchaseSummary)">详情</el-button><el-button v-if="(row as OverseasPurchaseSummary).status === 'PENDING_REVIEW' && access.can(overseasBusinessPermissions.purchaseReview)" class="density-action" type="primary" size="small" @click="beginReview(row as OverseasPurchaseSummary)">审核</el-button></div></template>
|
||||
<template #status="{ row }"><el-tag :type="statusTone(row.status)" size="small" effect="light">{{ statusLabel(row.status, row.procurementDirection) }}</el-tag></template>
|
||||
<template #pagination-left>共 {{ total }} 条海外采购订单</template>
|
||||
</DataTable></div></section>
|
||||
<AppDialog v-model="reviewOpen" class="admin-density-dialog admin-workbench is-dialog" title="采购审核" width="560px" confirm-text="提交审核" :confirm-loading="reviewSaving" :confirm-disabled="reviewLoading" @confirm="submitReview">
|
||||
<el-form :model="reviewForm" label-position="top" class="density-form density-form--outlined">
|
||||
<el-form-item label="审核结果"><el-radio-group v-model="reviewForm.decision"><el-radio value="APPROVE">通过</el-radio><el-radio value="REJECT">驳回</el-radio></el-radio-group></el-form-item>
|
||||
<el-form-item v-if="reviewForm.decision === 'APPROVE'" label="采购仓库" required><el-select v-model="reviewForm.purchaseWarehouseId" filterable :loading="reviewLoading" placeholder="请选择采购仓库"><el-option v-for="warehouse in reviewWarehouses" :key="warehouse.warehouseId" :label="`${warehouse.warehouseName}(${warehouse.warehouseCode})`" :value="warehouse.warehouseId" /></el-select></el-form-item>
|
||||
<el-form-item v-else label="驳回原因" required><el-input v-model="reviewForm.remark" type="textarea" :rows="4" maxlength="1000" show-word-limit /></el-form-item>
|
||||
</el-form>
|
||||
</AppDialog>
|
||||
</ListPageLayout></AdminPage>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user