This commit is contained in:
2026-08-14 14:27:03 +08:00
parent 724848feb6
commit a81af4a664
64 changed files with 961 additions and 176 deletions
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { computed, reactive, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
import { ArrowLeft, FileText, Save } from '@lucide/vue'
@@ -40,14 +40,25 @@ function optional(value: string | null) { return value?.trim() || null }
function payload(): SaveSupplierRequest {
return { ...form, name: form.name.trim(), scope: form.category === 'BOOKING' ? form.scope : null, region: form.region.trim(), legalRepresentative: form.legalRepresentative.trim(), contactName: form.contactName.trim(), phone: form.phone.trim(), email: optional(form.email), address: optional(form.address), businessLicenseNo: optional(form.businessLicenseNo), licenseFileId: form.licenseFileId, remark: optional(form.remark) }
}
let loadSequence = 0
function resetForm() { Object.assign(form, initial()) }
async function load() {
if (!editing.value || !access.can(requiredPermission.value)) { captureBaseline(); return }
loading.value = true; loadError.value = null
const requestedId = supplierId.value
const sequence = ++loadSequence
resetForm()
loadError.value = null
submitError.value = null
saving.value = false
if (!requestedId || !access.can(requiredPermission.value)) { loading.value = false; captureBaseline(); return }
loading.value = true
try {
const data = await getSupplier(supplierId.value)
const data = await getSupplier(requestedId)
if (sequence !== loadSequence || requestedId !== supplierId.value) return
Object.assign(form, { name: data.name, category: data.category, scope: data.scope, region: data.region, legalRepresentative: data.legalRepresentative, contactName: data.contactName, phone: data.phone, email: data.email, address: data.address, businessLicenseNo: data.businessLicenseNo, licenseFileId: data.licenseFileId, status: data.status, settlementPeriod: data.settlementPeriod, remark: data.remark })
captureBaseline()
} catch (error) { loadError.value = getApiErrorDetails(error, '供应商详情加载失败') } finally { loading.value = false }
} catch (error) {
if (sequence === loadSequence && requestedId === supplierId.value) loadError.value = getApiErrorDetails(error, '供应商详情加载失败')
} finally { if (sequence === loadSequence) loading.value = false }
}
async function save() {
if (!access.can(requiredPermission.value)) return
@@ -63,7 +74,7 @@ async function save() {
}
watch(() => form.category, (category) => { if (category === 'BOOKING' && !form.scope) form.scope = 'DOMESTIC'; if (category !== 'BOOKING') form.scope = null })
onMounted(load)
watch(supplierId, () => { void load() }, { immediate: true })
</script>
<template>
@@ -109,5 +120,7 @@ onMounted(load)
.supplier-form-panel { padding: 22px; }.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 20px; }.span-2 { grid-column: 1 / -1; }
.form-grid :deep(.el-select) { width: 100%; }.file-placeholder { display: flex; width: 100%; min-height: 96px; align-items: center; justify-content: center; flex-direction: column; gap: 6px; padding: 16px; border: 1px dashed #d9d9d9; border-radius: 6px; background: #fafafa; color: var(--cc-muted); text-align: center; }.file-placeholder small { max-width: 420px; line-height: 1.5; }
.form-actions { display: flex; justify-content: center; gap: 14px; padding: 18px 0 0; border-top: 1px solid var(--cc-border); }.form-actions :deep(.el-button) { min-width: 112px; margin-left: 0; }
@media (min-width: 1600px) { .form-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1280px) and (max-width: 1599px) { .form-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 720px) { .supplier-form-panel { padding: 16px; } .form-grid { grid-template-columns: 1fr; }.span-2 { grid-column: auto; }.form-page-header { align-items: stretch; flex-direction: column; }.form-actions { flex-direction: column; }.form-actions :deep(.el-button) { width: 100%; min-height: 44px; } }
</style>