优化
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { ElMessage, ElMessageBox, type FormInstance } from 'element-plus'
|
||||
import { Pencil, RefreshCw, Save } from '@lucide/vue'
|
||||
import { Pencil, Plus, RefreshCw, Save, Trash2 } from '@lucide/vue'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import { useUnsavedWorkRegistration } from '@/core/unsaved-work/useUnsavedWorkRegistration'
|
||||
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
||||
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
|
||||
import AppDialog from '@/shared/components/AppDialog.vue'
|
||||
import { getCustomerOverseasStorageFees, updateCustomerOverseasStorageFees, type OverseasStorageFeeConfig, type OverseasStorageFeeTier } from './overseasStorageFee'
|
||||
import { addFeeTier, removeFeeTier, validateFeeTiers } from './overseasStorageFeeTiers'
|
||||
|
||||
const props = defineProps<{ customerId: string; customerName: string }>()
|
||||
const access = useAccessPreviewStore()
|
||||
@@ -48,19 +49,12 @@ async function closeEditor() {
|
||||
visible.value = false
|
||||
}
|
||||
function validate() {
|
||||
if (storageTiers.value.length !== 5 || returnTiers.value.length !== 4) { ElMessage.error('仓租必须为5档,退货仓储费必须为4档'); return false }
|
||||
for (const [label, tiers] of [['仓租', storageTiers.value], ['退货仓储费', returnTiers.value] ] as const) {
|
||||
let expected = 1
|
||||
for (const [index, tier] of tiers.entries()) {
|
||||
if (!Number.isInteger(tier.startDay) || tier.startDay !== expected || tier.startDay < 1) { ElMessage.error(`${label}第${index + 1}档天数必须连续且从第1天开始`); return false }
|
||||
if (!Number.isFinite(tier.unitPrice) || tier.unitPrice < 0) { ElMessage.error(`${label}第${index + 1}档价格不能小于0`); return false }
|
||||
if (index === tiers.length - 1) { if (tier.endDay !== null) { ElMessage.error(`${label}最后一档必须为“以上”`); return false } }
|
||||
else if (!Number.isInteger(tier.endDay) || tier.endDay! < tier.startDay) { ElMessage.error(`${label}第${index + 1}档结束天数无效`); return false }
|
||||
if (tier.endDay !== null) expected = tier.endDay + 1
|
||||
}
|
||||
}
|
||||
const message = validateFeeTiers(form.tiers)
|
||||
if (message) { ElMessage.error(message); return false }
|
||||
return true
|
||||
}
|
||||
function addTier(feeType: OverseasStorageFeeTier['feeType']) { const message = addFeeTier(form.tiers, feeType); if (message) ElMessage.error(message) }
|
||||
function removeTier(tier: OverseasStorageFeeTier) { const message = removeFeeTier(form.tiers, tier); if (message) ElMessage.error(message) }
|
||||
async function save() {
|
||||
if (!config.value || !validate()) return
|
||||
saving.value = true
|
||||
@@ -85,7 +79,7 @@ onMounted(load)
|
||||
</template>
|
||||
<div v-else class="fee-empty">当前客户暂无海外仓费用配置</div>
|
||||
<AppDialog v-model="visible" title="编辑海外仓费用" width="min(1120px, calc(100vw - 28px))" :confirm-loading="saving" :show-cancel="false" @confirm="save">
|
||||
<el-form ref="formRef" :model="form" label-position="top"><el-form-item label="币种"><el-select v-model="form.currency" style="width:180px"><el-option v-for="currency in currencies" :key="currency" :label="currency" :value="currency" /></el-select></el-form-item><div class="edit-groups"><div v-for="(group, groupIndex) in [storageTiers, returnTiers]" :key="groupIndex"><h3>{{ groupIndex === 0 ? '仓租(CBM/天)' : '退货仓储费(托/天)' }}</h3><table><thead><tr><th>开始天数</th><th>结束天数</th><th>价格</th></tr></thead><tbody><tr v-for="tier in group" :key="tier.id"><td><el-input-number v-model="tier.startDay" :min="1" :max="36500" :controls="false" /></td><td><el-input-number v-if="tier.endDay !== null" v-model="tier.endDay" :min="1" :max="36500" :controls="false" /><span v-else>以上</span></td><td><el-input-number v-model="tier.unitPrice" :min="0" :precision="6" :controls="false" /></td></tr></tbody></table></div></div></el-form>
|
||||
<el-form ref="formRef" :model="form" label-position="top"><el-form-item label="币种"><el-select v-model="form.currency" style="width:180px"><el-option v-for="currency in currencies" :key="currency" :label="currency" :value="currency" /></el-select></el-form-item><div class="edit-groups"><div v-for="(group, groupIndex) in [storageTiers, returnTiers]" :key="groupIndex"><div class="edit-group-heading"><h3>{{ groupIndex === 0 ? '仓租(CBM/天)' : '退货仓储费(托/天)' }} · {{ group.length }}档</h3><el-button type="primary" plain size="small" :disabled="form.tiers.length >= 100" @click="addTier(groupIndex === 0 ? 'STORAGE' : 'RETURN_STORAGE')"><Plus :size="15" />新增阶梯</el-button></div><table><thead><tr><th>操作</th><th>开始天数</th><th>结束天数</th><th>价格</th></tr></thead><tbody><tr v-for="tier in group" :key="tier.id"><td><el-button link type="danger" :disabled="group.length <= 1" @click="removeTier(tier)"><Trash2 :size="15" />删除</el-button></td><td><el-input-number v-model="tier.startDay" :min="1" :max="36500" :controls="false" /></td><td><el-input-number v-if="tier.endDay !== null" v-model="tier.endDay" :min="1" :max="36500" :controls="false" /><span v-else>以上</span></td><td><el-input-number v-model="tier.unitPrice" :min="0" :precision="6" :controls="false" /></td></tr></tbody></table></div></div></el-form>
|
||||
<template #footer><div class="dialog-actions"><el-button :disabled="saving" @click="closeEditor">取消</el-button><el-button type="primary" :loading="saving" @click="save"><Save :size="16" />保存费用</el-button></div></template>
|
||||
</AppDialog>
|
||||
</section>
|
||||
@@ -93,5 +87,6 @@ onMounted(load)
|
||||
|
||||
<style scoped>
|
||||
.overseas-fee-panel { margin-top: 18px; border: 1px solid var(--cc-border); background: #fff; }.panel-heading { display:flex; align-items:center; justify-content:space-between; gap:16px; padding:18px; border-bottom:1px solid var(--cc-border); }.panel-heading h2,.fee-groups h3,.edit-groups h3 { margin:0; color:var(--cc-text); font-size:16px; }.panel-heading p { margin:5px 0 0; color:var(--cc-muted); font-size:12px; }.fee-meta { display:flex; flex-wrap:wrap; gap:24px; padding:12px 18px; color:var(--cc-muted); font-size:12px; background:#f8fafc; }.fee-meta strong { color:var(--cc-text); }.fee-groups,.edit-groups { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:18px; padding:18px; }.fee-groups table,.edit-groups table { width:100%; border-collapse:collapse; font-size:12px; }.fee-groups th,.fee-groups td,.edit-groups th,.edit-groups td { padding:9px 10px; border-bottom:1px solid var(--cc-border); text-align:left; }.fee-groups th,.edit-groups th { color:var(--cc-muted); font-weight:650; }.edit-groups :deep(.el-input-number) { width:130px; }.fee-error { display:flex; align-items:center; justify-content:space-between; gap:16px; padding:20px; background:#fff4f3; }.fee-error p { margin:5px 0; color:#b42318; font-size:12px; }.fee-loading { min-height:220px; }.fee-empty { min-height:160px; display:grid; place-items:center; color:var(--cc-muted); }.dialog-actions { display:flex; justify-content:flex-end; gap:8px; }.dialog-actions :deep(.el-button + .el-button) { margin-left:0; }
|
||||
.edit-group-heading { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px; }
|
||||
@media (max-width:760px) { .panel-heading,.fee-error { align-items:stretch; flex-direction:column; }.fee-groups,.edit-groups { grid-template-columns:1fr; padding:12px; }.edit-groups { overflow:auto; }.edit-groups > div { min-width:620px; }.panel-heading :deep(.el-button) { min-height:44px; } }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user