Files
admin-web/src/modules/overseas-business/pages/PurchaseOrderEditView.vue
T

91 lines
6.2 KiB
Vue

<script setup lang="ts">
import '@/styles/adminDensity.css'
import '../overseasBusinessDensity.css'
import { computed, reactive, ref, watch, onBeforeUnmount } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ArrowLeft, Save } from '@lucide/vue'
import { ElMessage } from 'element-plus'
import AdminPage from '@/shared/components/AdminPage.vue'
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
import DetailPageLayout from '@/shared/components/DetailPageLayout.vue'
import FormSection from '@/shared/components/FormSection.vue'
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
import OperationErrorToast from '@/shared/components/OperationErrorToast.vue'
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
import { useUnsavedWorkRegistration } from '@/core/unsaved-work/useUnsavedWorkRegistration'
import { useAccessPreviewStore } from '@/core/access/accessPreview'
import { getOverseasPurchaseEditor, updateOverseasPurchase } from '../api/platformOverseasBusiness'
import { overseasBusinessPermissions } from '../permissions'
const route = useRoute(); const router = useRouter(); const access = useAccessPreviewStore()
const purchaseId = computed(() => typeof route.params.purchaseId === 'string' ? route.params.purchaseId : '')
const customerId = computed(() => typeof route.query.customerId === 'string' ? route.query.customerId : '')
const loading = ref(false); const saving = ref(false); const loaded = ref(false)
const loadError = ref<ApiErrorDetails | null>(null); const submitError = ref<ApiErrorDetails | null>(null)
const initial = () => ({ orderNo: '', productName: '', purchaseQuantity: 0, remark: '', version: 0 })
const form = reactive(initial())
const canSave = computed(() => loaded.value && !loading.value && !saving.value && access.can(overseasBusinessPermissions.purchaseEdit))
const { captureBaseline } = useUnsavedWorkRegistration({ key: 'overseas-purchase-editor', label: computed(() => '编辑采购内部备注'), isOpen: computed(() => true), model: form, requiredPermission: computed(() => overseasBusinessPermissions.purchaseEdit) })
let generation = 0
onBeforeUnmount(() => { generation++ })
function back() { return router.push({ name: 'overseas-business-purchase-detail', params: { purchaseId: purchaseId.value }, query: { customerId: customerId.value } }) }
async function load() {
const current = ++generation; const orderNo = purchaseId.value; const customer = customerId.value
loaded.value = false; loading.value = false; Object.assign(form, initial()); captureBaseline()
loadError.value = null; submitError.value = null
if (!orderNo || !customer) { loadError.value = { message: '缺少采购订单号或客户标识,请从采购订单列表重新进入' }; return }
loading.value = true
try {
const detail = await getOverseasPurchaseEditor(orderNo, customer)
if (current !== generation) return
const order = detail.customerView.order
Object.assign(form, { orderNo: order.orderNo, productName: order.productName, purchaseQuantity: order.purchaseQuantity, version: order.version, remark: detail.internalRemark ?? '' })
loaded.value = true; captureBaseline()
} catch (error) { if (current === generation) loadError.value = getApiErrorDetails(error, '采购订单加载失败') }
finally { if (current === generation) loading.value = false }
}
async function save() {
if (!canSave.value) return
saving.value = true; submitError.value = null
const current = generation; const orderNo = purchaseId.value; const customer = customerId.value
try {
const updated = await updateOverseasPurchase(orderNo, customer, { version: form.version, remark: form.remark.trim() || null })
if (current !== generation) return
form.version = updated.version; captureBaseline(); ElMessage.success('内部备注已保存')
await back()
} catch (error) { if (current === generation) submitError.value = getApiErrorDetails(error, '内部备注保存失败') }
finally { saving.value = false }
}
watch([purchaseId, customerId], () => { void load() }, { immediate: true })
</script>
<template>
<AdminPage class="admin-density overseas-business-editor">
<OperationErrorToast :details="submitError" />
<DetailPageLayout class="overseas-business-form-layout" aria-label="编辑采购内部备注">
<template #header><div class="density-detail-header"><div class="density-detail-heading">
<el-button link class="density-back" @click="back"><ArrowLeft :size="16" />返回详情</el-button>
<h1 class="density-detail-title">编辑采购内部备注</h1><span class="form-reference">{{ form.orderNo || '—' }}</span>
</div></div></template>
<LoadErrorState v-if="loadError" title="采购订单暂时无法编辑" :message="loadError.message" :loading="loading" @retry="load"><template #details><ApiErrorMeta :details="loadError" /></template></LoadErrorState>
<section v-else v-loading="loading" class="form-panel">
<el-form class="density-form" :model="form" label-position="top" :disabled="!canSave">
<FormSection class="density-form-section" title="采购订单"><div class="form-grid">
<el-form-item label="订单编号"><el-input :model-value="form.orderNo || '—'" readonly /></el-form-item>
<el-form-item label="商品名称"><el-input :model-value="form.productName || '—'" readonly /></el-form-item>
<el-form-item label="采购数量"><el-input :model-value="loaded ? form.purchaseQuantity : '—'" readonly /></el-form-item>
<el-form-item class="span-3" label="内部备注"><el-input v-model="form.remark" type="textarea" :rows="4" maxlength="1000" show-word-limit placeholder="仅供平台内部使用" /></el-form-item>
</div></FormSection>
</el-form>
<footer class="form-actions"><el-button type="primary" :disabled="!canSave" :loading="saving" @click="save"><Save :size="16" />保存</el-button><el-button :disabled="saving" @click="back">取消</el-button></footer>
</section>
</DetailPageLayout>
</AdminPage>
</template>
<style scoped>
.form-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.span-3 { grid-column: 1 / -1; }
@media (max-width: 760px) { .form-grid { grid-template-columns: 1fr; } }
</style>