fix: complete admin input hints
This commit is contained in:
@@ -421,7 +421,7 @@ onMounted(async () => { await load(); if (route.query.action === 'documents') op
|
||||
</template>
|
||||
|
||||
<AppDialog v-model="documentOpen" :title="documentTitle" width="min(520px, calc(100vw - 28px))" confirm-text="上传资料" :confirm-loading="documentSaving" :confirm-disabled="!documentFile" @confirm="saveDocument"><el-form label-position="top"><el-form-item :label="documentTitle"><el-upload :key="documentUploadKey" :auto-upload="false" :limit="1" :on-change="selectDocumentFile" :on-remove="removeDocumentFile"><el-button><FileUp :size="16" />选择文件</el-button><template #tip><div class="el-upload__tip">{{ selectedDocument ? '上传新文件将替换当前资料并保留历史。' : `请选择需要提交的${documentTitle}。` }}</div></template></el-upload></el-form-item></el-form><LoadErrorState v-if="documentError" compact title="资料上传失败" :message="documentError.message" :show-retry="false"><template #details><ApiErrorMeta :details="documentError" /></template></LoadErrorState></AppDialog>
|
||||
<AppDialog v-model="exceptionOpen" :title="exceptionTitle" width="min(520px, calc(100vw - 28px))" :confirm-text="overview?.exception.active ? '确认取消' : '确认标记'" :confirm-loading="exceptionSaving" :confirm-disabled="!exceptionReason.trim()" @confirm="saveException"><el-alert :title="overview?.exception.active ? '取消备注为必填项,提交后将保留历史记录。' : '异常原因将同步记录在货柜详情和操作日志中。'" :type="overview?.exception.active ? 'warning' : 'error'" :closable="false" /><el-form label-position="top"><el-form-item :label="overview?.exception.active ? '取消备注' : '异常原因'" required><el-input v-model="exceptionReason" type="textarea" :rows="4" maxlength="500" show-word-limit /></el-form-item></el-form><LoadErrorState v-if="exceptionError" compact title="异常处理失败" :message="exceptionError.message" :show-retry="false" /></AppDialog>
|
||||
<AppDialog v-model="exceptionOpen" :title="exceptionTitle" width="min(520px, calc(100vw - 28px))" :confirm-text="overview?.exception.active ? '确认取消' : '确认标记'" :confirm-loading="exceptionSaving" :confirm-disabled="!exceptionReason.trim()" @confirm="saveException"><el-alert :title="overview?.exception.active ? '取消备注为必填项,提交后将保留历史记录。' : '异常原因将同步记录在货柜详情和操作日志中。'" :type="overview?.exception.active ? 'warning' : 'error'" :closable="false" /><el-form label-position="top"><el-form-item :label="overview?.exception.active ? '取消备注' : '异常原因'" required><el-input v-model="exceptionReason" type="textarea" :rows="4" maxlength="500" show-word-limit placeholder="请输入异常原因或取消备注" /></el-form-item></el-form><LoadErrorState v-if="exceptionError" compact title="异常处理失败" :message="exceptionError.message" :show-retry="false" /></AppDialog>
|
||||
<AppDialog v-model="clearanceOpen" title="目的港清关资料" width="min(520px, calc(100vw - 28px))" :loading="clearanceLoading" :show-confirm="!clearanceDocument?.completedAt" confirm-text="上传资料" :confirm-loading="clearanceSaving" :confirm-disabled="!clearanceFile" @confirm="uploadClearance"><el-alert v-if="clearanceDocument?.completedAt" type="success" :closable="false" :title="`目的港清关已完成:${clearanceDocument.fileName}`" /><template v-else><el-form label-position="top"><el-form-item label="目的港清关资料"><el-upload :auto-upload="false" :limit="1" :on-change="selectClearanceFile" :on-remove="removeClearanceFile"><el-button><FileUp :size="16" />选择文件</el-button></el-upload></el-form-item></el-form><el-button v-if="clearanceDocument" type="success" plain :loading="clearanceSaving" @click="completeClearance">确认目的港清关完成</el-button></template><LoadErrorState v-if="clearanceError" compact title="目的港清关资料操作失败" :message="clearanceError.message" :show-retry="false"><template #details><ApiErrorMeta :details="clearanceError" /></template></LoadErrorState></AppDialog>
|
||||
</AdminPage>
|
||||
</template>
|
||||
|
||||
@@ -740,7 +740,7 @@ onMounted(() => { void load(); void loadCustomers() })
|
||||
<DataTable :data="displayedPlanItems" :columns="itemColumns" :loading="selectionLoading || mutating" stripe preference-key="global-smart-loading-items" column-settings-mode="hide" empty-text="当前柜次暂无装柜明细">
|
||||
<template #actions="{ row }"><div class="row-actions"><el-button v-if="canDelete && editable && row.canRemove" size="small" type="danger" plain @click="remove(row)"><Trash2 :size="15" />删除</el-button></div></template>
|
||||
<template #coLoadGroup="{ row }"><div v-if="row.coLoadGroup" class="candidate-group"><el-tag size="small" type="warning">{{ row.coLoadGroup.groupNo }} · {{ groupMemberLabel(row.coLoadGroup) }}</el-tag><span v-for="summary in row.memberOrderSummaries" :key="summary">{{ summary }}</span><span>固定 {{ row.coLoadGroup.fullPackageCount }} 箱 · {{ row.coLoadGroup.lockedPlanId ? '已锁定' : '未锁定' }}</span></div><span v-else>普通单票</span></template>
|
||||
<template #packageCount="{ row }"><strong v-if="row.coLoadGroup">{{ row.packageCount }} 箱(整组固定)</strong><div v-else class="package-count-editor"><el-input-number v-model="quantityDrafts[row.id]" :min="row.minPackageCount" :max="adjustmentMax(row)" :step="1" :disabled="mutating || !canAssign || !editable || !row.canAdjust" controls-position="right" @change="adjust(row)" /><small v-if="row.detailCount > 1 && editable">多规格,需删除后重加</small><small v-if="row.pickedPackageCount > 0">已拣 {{ row.pickedPackageCount }} 箱</small></div></template>
|
||||
<template #packageCount="{ row }"><strong v-if="row.coLoadGroup">{{ row.packageCount }} 箱(整组固定)</strong><div v-else class="package-count-editor"><el-input-number v-model="quantityDrafts[row.id]" :min="row.minPackageCount" :max="adjustmentMax(row)" :step="1" :disabled="mutating || !canAssign || !editable || !row.canAdjust" controls-position="right" @change="adjust(row)" placeholder="请输入调整箱数" /><small v-if="row.detailCount > 1 && editable">多规格,需删除后重加</small><small v-if="row.pickedPackageCount > 0">已拣 {{ row.pickedPackageCount }} 箱</small></div></template>
|
||||
<template #weight="{ row }">{{ formatNumber(Number(row.grossWeightKg || 0), 1) }} kg</template>
|
||||
<template #volume="{ row }">{{ formatNumber(Number(row.volumeCbm || 0)) }} m³</template>
|
||||
</DataTable>
|
||||
@@ -759,7 +759,7 @@ onMounted(() => { void load(); void loadCustomers() })
|
||||
<template v-else>
|
||||
<p>入仓码 {{ selectedCandidate.inboundCode || '—' }} · 可用 {{ selectedCandidate.availablePackageCount }} 箱 · 平均单箱毛重 {{ formatNumber(Number(selectedCandidate.unitGrossWeightKg || 0), 1) }} kg · 平均单箱体积 {{ formatNumber(Number(selectedCandidate.averageUnitVolumeCbm || 0)) }} m³</p>
|
||||
<small>本次只记录该入仓码的计划装柜箱数,具体箱号归属为未核验。</small>
|
||||
<el-form label-position="top"><el-form-item label="本次分配箱数" required><el-input-number v-model="assignForm.packageCount" :min="1" :max="selectedCandidate.availablePackageCount" :step="1" controls-position="right" /></el-form-item></el-form>
|
||||
<el-form label-position="top"><el-form-item label="本次分配箱数" required><el-input-number v-model="assignForm.packageCount" :min="1" :max="selectedCandidate.availablePackageCount" :step="1" controls-position="right" placeholder="请输入本次分配箱数" /></el-form-item></el-form>
|
||||
</template>
|
||||
</div>
|
||||
</AppDialog>
|
||||
|
||||
@@ -358,7 +358,7 @@ onMounted(load)
|
||||
<template #order="{ row }"><strong>{{ row.inboundCode || '—' }}</strong></template>
|
||||
<template #coLoadGroup="{ row }"><div v-if="row.coLoadGroup" class="candidate-group"><el-tag size="small" type="warning">{{ row.coLoadGroup.groupNo }} · {{ groupMemberLabel(row.coLoadGroup) }}</el-tag><span v-for="summary in row.memberOrderSummaries" :key="summary">{{ summary }}</span><span>全部入仓片段联动,固定 {{ row.coLoadGroup.fullPackageCount }} 箱</span></div><span v-else>普通单票</span></template>
|
||||
<template #goods="{ row }"><strong>{{ row.productNameZh || '未命名货物' }}</strong><small>{{ row.skuCode || '无 SKU' }}</small></template>
|
||||
<template #packageCount="{ row }"><strong v-if="row.coLoadGroup">{{ row.packageCount }} 箱(整组固定)</strong><div v-else class="package-count-editor"><el-input-number v-model="quantityDrafts[row.id]" :min="row.minPackageCount" :step="1" :disabled="mutating || !canAssign || !editable || !row.canAdjust" controls-position="right" @change="adjust(row)" /><small v-if="row.detailCount > 1 && editable">含 {{ row.detailCount }} 个规格,需删除后重加</small><small v-if="row.pickedPackageCount > 0">已拣 {{ row.pickedPackageCount }} 箱</small></div></template>
|
||||
<template #packageCount="{ row }"><strong v-if="row.coLoadGroup">{{ row.packageCount }} 箱(整组固定)</strong><div v-else class="package-count-editor"><el-input-number v-model="quantityDrafts[row.id]" :min="row.minPackageCount" :step="1" :disabled="mutating || !canAssign || !editable || !row.canAdjust" controls-position="right" @change="adjust(row)" placeholder="请输入调整箱数" /><small v-if="row.detailCount > 1 && editable">含 {{ row.detailCount }} 个规格,需删除后重加</small><small v-if="row.pickedPackageCount > 0">已拣 {{ row.pickedPackageCount }} 箱</small></div></template>
|
||||
<template #volume="{ row }">{{ formatNumber(Number(row.volumeCbm || 0)) }} m³</template><template #weight="{ row }">{{ formatNumber(Number(row.grossWeightKg || 0),1) }} kg</template>
|
||||
</DataTable>
|
||||
<DataTable :data="displayedCandidates" :columns="candidateColumns" :loading="loading || mutating" stripe preference-key="smart-loading-candidates" column-settings-mode="hide" empty-text="当前仓库暂无可排柜货物">
|
||||
@@ -371,7 +371,7 @@ onMounted(load)
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
<AppDialog v-model="assignOpen" :title="selectedCandidate?.coLoadGroupId ? '整组加入当前柜次' : '按入仓码分配箱数'" :confirm-loading="mutating" :confirm-disabled="Boolean(selectedCandidate?.blockReason || selectedCandidate?.locked)" :confirm-text="selectedCandidate?.coLoadGroupId ? '确认整组分配' : '确认分配'" @confirm="assign"><div v-if="selectedCandidate" class="assign-dialog"><p><strong>{{ selectedCandidate.groupNo || selectedCandidate.inboundCode || '入仓码暂缺' }}</strong></p><template v-if="selectedCandidate.coLoadGroupId"><p>组内 {{ selectedCandidate.memberOrderCount }} 票、{{ selectedCandidate.inboundFragmentCount }} 个入仓片段,共 {{ selectedCandidate.groupTotalBoxes }} 箱</p><p v-for="summary in selectedCandidate.memberOrderSummaries" :key="summary">{{ summary }}</p><el-alert :title="selectedCandidate.blockReason || '同柜且不可拆:全部订单及其入仓片段按完整箱数一次加入,不能部分输入或单独移除。'" :type="selectedCandidate.blockReason ? 'error' : 'warning'" :closable="false" /></template><template v-else><p>{{ selectedCandidate.goodsSummary || '货物摘要暂缺' }} · 可用 {{ selectedCandidate.availablePackageCount }} 箱</p><el-form label-position="top"><el-form-item label="本次计划装柜箱数" required><el-input-number v-model="assignForm.packageCount" :min="1" :max="selectedCandidate.availablePackageCount" :step="1" controls-position="right" /></el-form-item></el-form><el-alert :title="explainCandidate(selectedCandidate)" type="info" :closable="false" /><small>只记录数量,具体上柜箱号未核验。</small></template></div></AppDialog>
|
||||
<AppDialog v-model="assignOpen" :title="selectedCandidate?.coLoadGroupId ? '整组加入当前柜次' : '按入仓码分配箱数'" :confirm-loading="mutating" :confirm-disabled="Boolean(selectedCandidate?.blockReason || selectedCandidate?.locked)" :confirm-text="selectedCandidate?.coLoadGroupId ? '确认整组分配' : '确认分配'" @confirm="assign"><div v-if="selectedCandidate" class="assign-dialog"><p><strong>{{ selectedCandidate.groupNo || selectedCandidate.inboundCode || '入仓码暂缺' }}</strong></p><template v-if="selectedCandidate.coLoadGroupId"><p>组内 {{ selectedCandidate.memberOrderCount }} 票、{{ selectedCandidate.inboundFragmentCount }} 个入仓片段,共 {{ selectedCandidate.groupTotalBoxes }} 箱</p><p v-for="summary in selectedCandidate.memberOrderSummaries" :key="summary">{{ summary }}</p><el-alert :title="selectedCandidate.blockReason || '同柜且不可拆:全部订单及其入仓片段按完整箱数一次加入,不能部分输入或单独移除。'" :type="selectedCandidate.blockReason ? 'error' : 'warning'" :closable="false" /></template><template v-else><p>{{ selectedCandidate.goodsSummary || '货物摘要暂缺' }} · 可用 {{ selectedCandidate.availablePackageCount }} 箱</p><el-form label-position="top"><el-form-item label="本次计划装柜箱数" required><el-input-number v-model="assignForm.packageCount" :min="1" :max="selectedCandidate.availablePackageCount" :step="1" controls-position="right" placeholder="请输入本次分配箱数" /></el-form-item></el-form><el-alert :title="explainCandidate(selectedCandidate)" type="info" :closable="false" /><small>只记录数量,具体上柜箱号未核验。</small></template></div></AppDialog>
|
||||
</section>
|
||||
</AdminPage>
|
||||
</template>
|
||||
|
||||
@@ -79,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"><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 size="small" plain 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>
|
||||
<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 size="small" plain 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" placeholder="请输入开始天数" /></td><td><el-input-number v-if="tier.endDay !== null" v-model="tier.endDay" :min="1" :max="36500" :controls="false" placeholder="请输入结束天数" /><span v-else>以上</span></td><td><el-input-number v-model="tier.unitPrice" :min="0" :precision="6" :controls="false" placeholder="请输入价格" /></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>
|
||||
|
||||
@@ -337,11 +337,11 @@ onMounted(() => { void loadConfig(); void loadChargeRules() })
|
||||
<el-form ref="editorForm" :model="form" label-position="top">
|
||||
<div class="editor-table-wrap">
|
||||
<table class="editor-table"><thead><tr><th>箱规类型</th><th>内径长(cm)</th><th>内径宽(cm)</th><th>内径高(cm)</th><th>单边加宽(cm)</th><th>备注</th></tr></thead><tbody>
|
||||
<tr v-for="row in form.rules" :key="row.boxType"><th scope="row">{{ row.boxTypeName }}</th><td><el-input-number v-model="row.innerLengthCm" :min="0.001" :precision="3" :controls="false" /></td><td><el-input-number v-model="row.innerWidthCm" :min="0.001" :precision="3" :controls="false" /></td><td><el-input-number v-model="row.innerHeightCm" :min="0.001" :precision="3" :controls="false" /></td><td><el-input-number v-model="row.edgeAdditionCm" :min="0.001" :max="100" :precision="3" :controls="false" /></td><td><el-input v-model="row.remark" maxlength="500" /></td></tr>
|
||||
<tr v-for="row in form.rules" :key="row.boxType"><th scope="row">{{ row.boxTypeName }}</th><td><el-input-number v-model="row.innerLengthCm" :min="0.001" :precision="3" :controls="false" placeholder="请输入内径长" /></td><td><el-input-number v-model="row.innerWidthCm" :min="0.001" :precision="3" :controls="false" placeholder="请输入内径宽" /></td><td><el-input-number v-model="row.innerHeightCm" :min="0.001" :precision="3" :controls="false" placeholder="请输入内径高" /></td><td><el-input-number v-model="row.edgeAdditionCm" :min="0.001" :max="100" :precision="3" :controls="false" placeholder="请输入边长加值" /></td><td><el-input v-model="row.remark" maxlength="500" placeholder="请输入备注(选填)" /></td></tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
<div class="rule-save-row"><el-button type="primary" :loading="editorSaving" @click="saveConfig"><Save :size="16" />保存规则</el-button></div>
|
||||
<section v-if="canChargeView" class="combined-charge-editor"><h3>箱规按权重系数计算</h3><p class="editor-formula">长、宽、高任一项超出当前挡位时进入下一挡;命中规格的一个系数统一应用于长、宽、高。</p><div class="charge-rule-editor-wrap"><table class="charge-rule-editor"><thead><tr><th>箱规类型</th><th>内径长(cm)</th><th>内径宽(cm)</th><th>内径高(cm)</th><th>权重系数</th><th>重量(kg)</th><th>备注</th></tr></thead><tbody><tr v-for="row in chargeRows" :key="`combined-${row.boxType}`"><th>{{ BOX_NAMES[row.boxType] }}</th><td><el-input-number v-model="row.length" :min="0.001" :precision="3" :controls="false" /></td><td><el-input-number v-model="row.width" :min="0.001" :precision="3" :controls="false" /></td><td><el-input-number v-model="row.height" :min="0.001" :precision="3" :controls="false" /></td><td><el-input-number v-model="row.coefficient" :min="0.001" :precision="3" :controls="false" /></td><td><el-input-number v-model="row.weight" :min="0.001" :precision="3" :controls="false" /></td><td><el-input v-model="row.remark" maxlength="500" /></td></tr></tbody></table></div><div class="rule-save-row"><el-button type="primary" :loading="chargeSaving" @click="saveChargeConfig"><Save :size="16" />保存系数规则</el-button></div></section>
|
||||
<section v-if="canChargeView" class="combined-charge-editor"><h3>箱规按权重系数计算</h3><p class="editor-formula">长、宽、高任一项超出当前挡位时进入下一挡;命中规格的一个系数统一应用于长、宽、高。</p><div class="charge-rule-editor-wrap"><table class="charge-rule-editor"><thead><tr><th>箱规类型</th><th>内径长(cm)</th><th>内径宽(cm)</th><th>内径高(cm)</th><th>权重系数</th><th>重量(kg)</th><th>备注</th></tr></thead><tbody><tr v-for="row in chargeRows" :key="`combined-${row.boxType}`"><th>{{ BOX_NAMES[row.boxType] }}</th><td><el-input-number v-model="row.length" :min="0.001" :precision="3" :controls="false" placeholder="请输入内径长" /></td><td><el-input-number v-model="row.width" :min="0.001" :precision="3" :controls="false" placeholder="请输入内径宽" /></td><td><el-input-number v-model="row.height" :min="0.001" :precision="3" :controls="false" placeholder="请输入内径高" /></td><td><el-input-number v-model="row.coefficient" :min="0.001" :precision="3" :controls="false" placeholder="请输入权重系数" /></td><td><el-input-number v-model="row.weight" :min="0.001" :precision="3" :controls="false" placeholder="请输入重量" /></td><td><el-input v-model="row.remark" maxlength="500" placeholder="请输入备注(选填)" /></td></tr></tbody></table></div><div class="rule-save-row"><el-button type="primary" :loading="chargeSaving" @click="saveChargeConfig"><Save :size="16" />保存系数规则</el-button></div></section>
|
||||
</el-form>
|
||||
</div>
|
||||
<template #footer><div class="dialog-actions"><el-button :disabled="editorSaving || chargeSaving" @click="closeEditor">取消</el-button></div></template>
|
||||
|
||||
@@ -1077,7 +1077,7 @@ onMounted(() => { void loadCustomers() })
|
||||
<el-form-item label="法定代表人" prop="legalRepresentative" required><el-input v-model="form.legalRepresentative" placeholder="请输入法定代表人姓名" maxlength="64" /></el-form-item>
|
||||
<el-form-item label="企业类型" prop="enterpriseType"><el-input v-model="form.enterpriseType" placeholder="如:有限责任公司" maxlength="64" /></el-form-item>
|
||||
<el-form-item label="成立日期" prop="establishedDate"><el-date-picker style="width: 100%;" v-model="form.establishedDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择成立日期" :disabled-date="(date: Date) => date.getTime() > Date.now()" /></el-form-item>
|
||||
<el-form-item label="注册资本" prop="registeredCapital"><div class="capital-input"><el-input-number v-model="form.registeredCapital" :min="0" :precision="2" controls-position="right" /><el-select v-model="form.registeredCapitalCurrency" aria-label="注册资本币种"><el-option label="人民币 CNY" value="CNY" /><el-option label="美元 USD" value="USD" /><el-option label="港币 HKD" value="HKD" /></el-select></div></el-form-item>
|
||||
<el-form-item label="注册资本" prop="registeredCapital"><div class="capital-input"><el-input-number v-model="form.registeredCapital" :min="0" :precision="2" controls-position="right" placeholder="请输入注册资本(选填)" /><el-select v-model="form.registeredCapitalCurrency" aria-label="注册资本币种"><el-option label="人民币 CNY" value="CNY" /><el-option label="美元 USD" value="USD" /><el-option label="港币 HKD" value="HKD" /></el-select></div></el-form-item>
|
||||
</div><el-form-item label="注册地址" prop="registeredAddress"><el-input v-model="form.registeredAddress" placeholder="请输入省市区、街道及门牌信息" maxlength="500" /></el-form-item></FormSection>
|
||||
|
||||
<FormSection title="联系与商务" description="维护客户联系人、账期和内部跟进信息。"><div class="form-grid two-cols">
|
||||
@@ -1087,7 +1087,7 @@ onMounted(() => { void loadCustomers() })
|
||||
<el-form-item label="联系微信" prop="contactWechat"><el-input v-model="form.contactWechat" placeholder="请输入联系人微信号" maxlength="64" /></el-form-item>
|
||||
<!-- <el-form-item label="客户套餐" prop="servicePackage" required><el-select v-model="form.servicePackage"><el-option label="基础版" value="基础版" /><el-option label="专业版" value="专业版" /><el-option label="企业版" value="企业版" /></el-select></el-form-item> -->
|
||||
<el-form-item label="销售人员" prop="salesOwnerName"><el-input v-model="form.salesOwnerName" placeholder="请输入负责销售人员" maxlength="64" /></el-form-item>
|
||||
<el-form-item label="账期(天)" prop="paymentTermDays" required><el-input-number v-model="form.paymentTermDays" :min="0" :max="365" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="账期(天)" prop="paymentTermDays" required><el-input-number v-model="form.paymentTermDays" :min="0" :max="365" controls-position="right" placeholder="请输入账期天数" /></el-form-item>
|
||||
</div><el-form-item label="内部备注" prop="internalRemark"><el-input v-model="form.internalRemark" type="textarea" :rows="3" placeholder="请输入仅平台人员可见的客户备注" maxlength="1000" show-word-limit /></el-form-item></FormSection>
|
||||
|
||||
<FormSection class="qualification-section" title="企业认证资料" description="营业执照和18位统一社会信用代码为必填业务项;法人身份证、货代资质证书和银行开户许可证均为选填。"><div v-if="editorStatus" class="qualification-heading"><el-tag :type="statusMeta(editorStatus).type" effect="light">{{ statusMeta(editorStatus).label }}</el-tag></div>
|
||||
|
||||
@@ -79,7 +79,7 @@ onMounted(() => { void load() })
|
||||
</section>
|
||||
</ListPageLayout>
|
||||
<AppDialog v-model="dialogOpen" title="编辑海外仓阶梯费用" width="min(1120px, calc(100vw - 28px))" :confirm-loading="saving" @confirm="save">
|
||||
<el-form label-position="top"><el-form-item label="币种"><el-select v-model="form.currency" style="width:180px"><el-option label="USD" value="USD" /><el-option label="CNY" value="CNY" /><el-option label="EUR" value="EUR" /></el-select></el-form-item><div class="groups"><div v-for="(group, index) in [storageTiers, returnTiers]" :key="index"><div class="group-heading"><h3>{{ index === 0 ? '仓租(CBM/天)' : '退货仓储费(托/天)' }} · {{ group.length }}档</h3><el-button type="primary" plain size="small" :disabled="form.tiers.length >= 100" @click="addTier(index === 0 ? 'STORAGE' : 'RETURN_STORAGE')"><Plus :size="15" />新增阶梯</el-button></div><el-table :data="group" size="small" border stripe><el-table-column label="操作" width="88" fixed="left"><template #default="{ row }"><el-button size="small" plain type="danger" :disabled="group.length <= 1" @click="removeTier(row as OverseasStorageFeeTier)"><Trash2 :size="15" />删除</el-button></template></el-table-column><el-table-column label="开始天数"><template #default="{ row }"><el-input-number v-model="row.startDay" :min="1" :max="36500" :controls="false" /></template></el-table-column><el-table-column label="结束天数"><template #default="{ row }"><el-input-number v-if="row.endDay !== null" v-model="row.endDay" :min="1" :max="36500" :controls="false" /><span v-else>以上</span></template></el-table-column><el-table-column label="价格"><template #default="{ row }"><el-input-number v-model="row.unitPrice" :min="0" :precision="6" :controls="false" /></template></el-table-column></el-table></div></div></el-form>
|
||||
<el-form label-position="top"><el-form-item label="币种"><el-select v-model="form.currency" style="width:180px"><el-option label="USD" value="USD" /><el-option label="CNY" value="CNY" /><el-option label="EUR" value="EUR" /></el-select></el-form-item><div class="groups"><div v-for="(group, index) in [storageTiers, returnTiers]" :key="index"><div class="group-heading"><h3>{{ index === 0 ? '仓租(CBM/天)' : '退货仓储费(托/天)' }} · {{ group.length }}档</h3><el-button type="primary" plain size="small" :disabled="form.tiers.length >= 100" @click="addTier(index === 0 ? 'STORAGE' : 'RETURN_STORAGE')"><Plus :size="15" />新增阶梯</el-button></div><el-table :data="group" size="small" border stripe><el-table-column label="操作" width="88" fixed="left"><template #default="{ row }"><el-button size="small" plain type="danger" :disabled="group.length <= 1" @click="removeTier(row as OverseasStorageFeeTier)"><Trash2 :size="15" />删除</el-button></template></el-table-column><el-table-column label="开始天数"><template #default="{ row }"><el-input-number v-model="row.startDay" :min="1" :max="36500" :controls="false" placeholder="请输入开始天数" /></template></el-table-column><el-table-column label="结束天数"><template #default="{ row }"><el-input-number v-if="row.endDay !== null" v-model="row.endDay" :min="1" :max="36500" :controls="false" placeholder="请输入结束天数" /><span v-else>以上</span></template></el-table-column><el-table-column label="价格"><template #default="{ row }"><el-input-number v-model="row.unitPrice" :min="0" :precision="6" :controls="false" placeholder="请输入单价" /></template></el-table-column></el-table></div></div></el-form>
|
||||
</AppDialog>
|
||||
</div>
|
||||
</AdminPage>
|
||||
|
||||
@@ -73,6 +73,6 @@ watch([page, pageSize], load); onMounted(async () => { await Promise.all([loadWa
|
||||
<template><AdminPage as="div" class="domestic-containers-page">
|
||||
<LoadErrorState v-if="warehouseError" compact title="国内仓候选加载失败" :message="warehouseError.message" :loading="warehouseLoading" @retry="loadWarehouses"><template #details><ApiErrorMeta :details="warehouseError" /></template></LoadErrorState>
|
||||
<ListPageLayout :aria-label="`${activeTab === 'inbound' ? '整柜入库单' : activeTab === 'outbound' ? '整柜出库单' : '整柜库存'}列表`"><template #toolbar><div class="business-query-panel"><div class="status-tabs" role="tablist" aria-label="整柜业务类型"><button v-for="(tab, index) in businessTabs" :key="tab.value" type="button" role="tab" :aria-selected="activeTab === tab.value" aria-controls="domestic-container-results" :tabindex="activeTab === tab.value ? 0 : -1" :class="['status-tab', { 'is-active': activeTab === tab.value }]" @click="switchTab(tab.value)" @keydown="handleTabKeydown($event, index)">{{ tab.label }}</button></div><QueryToolbar v-model="filters" class="business-query-toolbar" ariaLabel="整柜业务筛选" :fields="queryFields" :preference-key="`domestic-containers-${activeTab}-query`" @search="search" /></div></template><template v-if="loadError" #state><LoadErrorState title="整柜业务加载失败" :message="loadError.message" :loading="loading" @retry="load"><template #details><ApiErrorMeta :details="loadError" /></template></LoadErrorState></template><section v-if="!loadError" id="domestic-container-results" class="surface-panel table-panel"><div v-if="activeTab === 'inventory'" class="inventory-summary"><div><span>入库箱数</span><strong>{{ summary.inboundBoxes }}</strong></div><div><span>已出库箱数</span><strong>{{ summary.outboundBoxes }}</strong></div><div><span>当前库存</span><strong>{{ summary.availableBoxes }}</strong></div><div><span>累计入库体积</span><strong>{{ summary.inboundVolumeCbm.toFixed(2) }} m³</strong></div></div><DataTable v-model:page="page" v-model:page-size="pageSize" :data="rows" :columns="columns" :loading="loading" :total="total" stripe row-key="id" :preference-key="`domestic-containers-${activeTab}-table`" :empty-text="activeTab === 'inbound' ? '暂无整柜入库单' : activeTab === 'outbound' ? '暂无整柜出库单' : '暂无整柜库存'"><template #toolbar-actions><el-button v-if="activeTab === 'inbound' && access.can('platform:domestic-container:inbound:create')" type="primary" @click="openInbound"><Plus :size="16" />新建入库单</el-button><el-button v-if="activeTab === 'outbound' && access.can('platform:domestic-container:outbound:create')" type="primary" @click="openOutbound"><Plus :size="16" />新建出库单</el-button></template><template #actions="{ row }"><el-button size="small" type="primary" plain @click="viewInventory(row as ContainerOrder | InventoryRecord)"><Eye :size="15" />查看</el-button></template><template #status="{ row }"><StatusBadge :status="statusLabel(row as ContainerOrder | InventoryRecord)" /></template></DataTable></section></ListPageLayout>
|
||||
<AppDialog v-model="dialogOpen" class="domestic-container-create-dialog" :title="dialogType === 'inbound' ? '新建整柜入库单' : '新建整柜出库单'" width="min(720px, calc(100vw - 28px))" :confirm-loading="saving" :close-on-click-modal="false" :confirm-text="dialogType === 'inbound' ? '创建入库单' : '创建出库单'" @confirm="submit"><LoadErrorState v-if="submitError" compact title="创建失败" :message="submitError.message" :show-retry="false"><template #details><ApiErrorMeta :details="submitError" /></template></LoadErrorState><el-form ref="formRef" :model="currentForm" :rules="rules" label-position="top"><el-row :gutter="16"><template v-if="dialogType === 'inbound'"><el-col :xs="24" :sm="12"><el-form-item label="国内仓" prop="warehouseId"><el-select v-model="inboundForm.warehouseId" :loading="warehouseLoading" :disabled="Boolean(warehouseError)" placeholder="请选择启用的国内仓"><el-option v-for="item in warehouseOptions" :key="String(item.value)" :label="item.label" :value="String(item.value)" /></el-select></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="货物名称" prop="cargoName"><el-input v-model="inboundForm.cargoName" maxlength="128" placeholder="请输入货物名称" /></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="集装箱号" prop="containerNo"><el-input v-model="inboundForm.containerNo" maxlength="32" placeholder="如 MSCU1234567" /></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="箱子数量" prop="boxCount"><el-input-number v-model="inboundForm.boxCount" :min="1" :precision="0" controls-position="right" /></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="体积(m³)" prop="volumeCbm"><el-input-number v-model="inboundForm.volumeCbm" :min="0.0001" :precision="4" controls-position="right" /></el-form-item></el-col></template><template v-else><el-col :xs="24" :sm="12"><el-form-item label="国内仓" prop="warehouseId"><el-select v-model="outboundForm.warehouseId" :loading="warehouseLoading" :disabled="Boolean(warehouseError)" placeholder="请选择启用的国内仓" @change="loadCandidates"><el-option v-for="item in warehouseOptions" :key="String(item.value)" :label="item.label" :value="String(item.value)" /></el-select></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="绑定集装箱号" prop="containerNo"><el-select v-model="outboundForm.inventoryId" :loading="candidateLoading" :disabled="!outboundForm.warehouseId || Boolean(candidateError)" placeholder="请选择已有集装箱号" @change="selectInventory"><el-option v-for="item in inventoryCandidates" :key="String(item.id)" :label="`${item.containerNo} · 可用 ${item.availableBoxes} 箱`" :value="String(item.id)" /></el-select><input v-model="outboundForm.containerNo" class="sr-only" tabindex="-1"></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="货物名称"><el-input v-model="outboundForm.cargoName" readonly /></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="出库箱数" prop="boxCount"><el-input-number v-model="outboundForm.boxCount" :min="1" :precision="0" controls-position="right" /></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="可用库存"><el-input :model-value="`${outboundForm.availableBoxes} 箱`" readonly /></el-form-item></el-col><el-col v-if="candidateError" :xs="24"><LoadErrorState compact title="可出库库存加载失败" :message="candidateError.message" @retry="loadCandidates"><template #details><ApiErrorMeta :details="candidateError" /></template></LoadErrorState></el-col></template><el-col :xs="24" :sm="12"><el-form-item :label="dialogType === 'inbound' ? '入库时间' : '出库时间'" prop="operationTime"><el-date-picker v-model="currentForm.operationTime" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" format="YYYY-MM-DD HH:mm" /></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="状态" prop="status"><el-select v-model="currentForm.status"><el-option :label="dialogType === 'inbound' ? '已入库' : '已出库'" value="COMPLETED" /><el-option :label="dialogType === 'inbound' ? '待入库' : '待出库'" value="PENDING" /></el-select></el-form-item></el-col><el-col :xs="24"><el-form-item label="备注"><el-input v-model="currentForm.remark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请输入备注" /></el-form-item></el-col></el-row></el-form></AppDialog></AdminPage></template>
|
||||
<AppDialog v-model="dialogOpen" class="domestic-container-create-dialog" :title="dialogType === 'inbound' ? '新建整柜入库单' : '新建整柜出库单'" width="min(720px, calc(100vw - 28px))" :confirm-loading="saving" :close-on-click-modal="false" :confirm-text="dialogType === 'inbound' ? '创建入库单' : '创建出库单'" @confirm="submit"><LoadErrorState v-if="submitError" compact title="创建失败" :message="submitError.message" :show-retry="false"><template #details><ApiErrorMeta :details="submitError" /></template></LoadErrorState><el-form ref="formRef" :model="currentForm" :rules="rules" label-position="top"><el-row :gutter="16"><template v-if="dialogType === 'inbound'"><el-col :xs="24" :sm="12"><el-form-item label="国内仓" prop="warehouseId"><el-select v-model="inboundForm.warehouseId" :loading="warehouseLoading" :disabled="Boolean(warehouseError)" placeholder="请选择启用的国内仓"><el-option v-for="item in warehouseOptions" :key="String(item.value)" :label="item.label" :value="String(item.value)" /></el-select></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="货物名称" prop="cargoName"><el-input v-model="inboundForm.cargoName" maxlength="128" placeholder="请输入货物名称" /></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="集装箱号" prop="containerNo"><el-input v-model="inboundForm.containerNo" maxlength="32" placeholder="如 MSCU1234567" /></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="箱子数量" prop="boxCount"><el-input-number v-model="inboundForm.boxCount" :min="1" :precision="0" controls-position="right" placeholder="请输入入库箱数" /></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="体积(m³)" prop="volumeCbm"><el-input-number v-model="inboundForm.volumeCbm" :min="0.0001" :precision="4" controls-position="right" placeholder="请输入体积" /></el-form-item></el-col></template><template v-else><el-col :xs="24" :sm="12"><el-form-item label="国内仓" prop="warehouseId"><el-select v-model="outboundForm.warehouseId" :loading="warehouseLoading" :disabled="Boolean(warehouseError)" placeholder="请选择启用的国内仓" @change="loadCandidates"><el-option v-for="item in warehouseOptions" :key="String(item.value)" :label="item.label" :value="String(item.value)" /></el-select></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="绑定集装箱号" prop="containerNo"><el-select v-model="outboundForm.inventoryId" :loading="candidateLoading" :disabled="!outboundForm.warehouseId || Boolean(candidateError)" placeholder="请选择已有集装箱号" @change="selectInventory"><el-option v-for="item in inventoryCandidates" :key="String(item.id)" :label="`${item.containerNo} · 可用 ${item.availableBoxes} 箱`" :value="String(item.id)" /></el-select><input v-model="outboundForm.containerNo" class="sr-only" tabindex="-1"></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="货物名称"><el-input v-model="outboundForm.cargoName" readonly /></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="出库箱数" prop="boxCount"><el-input-number v-model="outboundForm.boxCount" :min="1" :precision="0" controls-position="right" placeholder="请输入出库箱数" /></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="可用库存"><el-input :model-value="`${outboundForm.availableBoxes} 箱`" readonly /></el-form-item></el-col><el-col v-if="candidateError" :xs="24"><LoadErrorState compact title="可出库库存加载失败" :message="candidateError.message" @retry="loadCandidates"><template #details><ApiErrorMeta :details="candidateError" /></template></LoadErrorState></el-col></template><el-col :xs="24" :sm="12"><el-form-item :label="dialogType === 'inbound' ? '入库时间' : '出库时间'" prop="operationTime"><el-date-picker v-model="currentForm.operationTime" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" format="YYYY-MM-DD HH:mm" /></el-form-item></el-col><el-col :xs="24" :sm="12"><el-form-item label="状态" prop="status"><el-select v-model="currentForm.status"><el-option :label="dialogType === 'inbound' ? '已入库' : '已出库'" value="COMPLETED" /><el-option :label="dialogType === 'inbound' ? '待入库' : '待出库'" value="PENDING" /></el-select></el-form-item></el-col><el-col :xs="24"><el-form-item label="备注"><el-input v-model="currentForm.remark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请输入备注" /></el-form-item></el-col></el-row></el-form></AppDialog></AdminPage></template>
|
||||
|
||||
<style scoped>.domestic-containers-page{min-width:0}.business-query-panel{overflow:hidden;border:1px solid var(--cc-border);border-radius:8px;background:#fff}.status-tabs{display:flex;max-width:100%;overflow-x:auto;margin-bottom:0;border-bottom:1px solid #e5e7eb;background:#f9fafb;scrollbar-width:thin}.status-tab{position:relative;flex:0 0 auto;min-height:44px;padding:0 18px;border:0;background:transparent;color:var(--cc-muted);font:inherit;font-size:14px;cursor:pointer}.status-tab::after{position:absolute;right:12px;bottom:0;left:12px;height:3px;background:transparent;content:''}.status-tab:hover{color:var(--cc-primary);background:#f6f9fd}.status-tab:focus-visible{outline:2px solid var(--cc-primary);outline-offset:-2px}.status-tab.is-active{color:var(--cc-primary);font-weight:600}.status-tab.is-active::after{background:var(--cc-primary)}.business-query-toolbar{border:0}.inventory-summary{display:flex;align-items:center;gap:0;margin:0 16px 12px;border:1px solid var(--cc-border);background:#f8fafc}.inventory-summary>div{display:flex;align-items:baseline;gap:8px;min-width:0;padding:9px 16px;border-right:1px solid var(--cc-border)}.inventory-summary>div:last-child{border-right:0}.inventory-summary span{color:var(--cc-muted);font-size:12px}.inventory-summary strong{font-size:15px}.domestic-container-create-dialog :deep(.el-select),.domestic-container-create-dialog :deep(.el-date-editor),.domestic-container-create-dialog :deep(.el-input-number){width:100%}.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}@media(max-width:720px){.status-tab{min-height:46px;padding:0 14px}.inventory-summary{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}.inventory-summary>div:nth-child(2){border-right:0}.inventory-summary>div:nth-child(-n+2){border-bottom:1px solid var(--cc-border)}}@media(max-width:360px){.status-tab{padding:0 10px;font-size:13px}.inventory-summary{grid-template-columns:1fr}.inventory-summary>div{border-right:0;border-bottom:1px solid var(--cc-border)}.inventory-summary>div:last-child{border-bottom:0}}</style>
|
||||
|
||||
@@ -282,7 +282,7 @@ watch(() => [route.name, String(route.params.customerId || '')], ([name, custome
|
||||
<QueryToolbar v-model="ledgerFilters" class="ledger-query" :fields="ledgerQueryFields" ariaLabel="账户流水筛选" preference-key="finance-account-ledger-query" @search="ledgerPage = 1; void loadLedger($event)" />
|
||||
<div class="detail-table-scroll"><DataTable v-model:page="ledgerPage" v-model:page-size="ledgerPageSize" class="ledger-table" :data="ledger" :columns="ledgerColumns" :loading="ledgerLoading" :total="ledgerTotal" row-key="ledgerId" empty-text="暂无账户流水" @update:page="loadLedger()" @update:page-size="ledgerPage = 1; loadLedger()"><template #toolbar-actions><el-button v-if="canExport" :loading="ledgerExportBusy" :disabled="ledgerLoading || ledgerExportBusy" @click="exportLedger"><Download :size="16" />导出流水</el-button></template><template #pagination-left>共 {{ ledgerTotal }} 条</template><template #ledgerId="{ row }"><span class="ledger-identifier" :title="displayLedgerId(row.ledgerId)">{{ displayLedgerId(row.ledgerId) }}</span></template><template #occurredAt="{ row }">{{ formatDateTime(row.occurredAt) }}</template><template #businessType="{ row }">{{ ledgerBusinessType(row.businessType) }}</template><template #documentNo="{ row }"><span class="ledger-document" :title="displayDocumentNo(row.documentNo)">{{ displayDocumentNo(row.documentNo) }}</span></template><template #operatorName="{ row }">{{ displayOperator(row.operatorName) }}</template></DataTable></div>
|
||||
</FormSection>
|
||||
<FormSection v-else class="term-section" title="账期设置" :bordered="false"><div class="term-editor"><span class="term-label">账期天数</span><div class="term-control"><el-input-number v-model="creditDays" :min="0" :max="3650" :step="1" /><span class="term-unit">天</span></div></div></FormSection>
|
||||
<FormSection v-else class="term-section" title="账期设置" :bordered="false"><div class="term-editor"><span class="term-label">账期天数</span><div class="term-control"><el-input-number v-model="creditDays" :min="0" :max="3650" :step="1" placeholder="请输入账期天数" /><span class="term-unit">天</span></div></div></FormSection>
|
||||
</template>
|
||||
<template v-if="editing && selected && !ledgerError" #footer><div class="detail-footer"><el-button @click="closeDetail">关闭</el-button><el-button v-if="canUpdateTerms" type="primary" :loading="saving" @click="saveTerms"><Save :size="16" />保存账期</el-button></div></template>
|
||||
</DetailPageLayout>
|
||||
|
||||
@@ -394,7 +394,7 @@ watch(() => [route.name, String(route.params.feeSourceId || '')], ([name, feeSou
|
||||
<el-form label-position="top"><el-form-item label="审核结论"><el-segmented v-model="reviewForm.action" :options="[{ label: '通过', value: 'APPROVE' }, { label: '驳回', value: 'REJECT' }]" /></el-form-item><el-form-item :label="reviewForm.action === 'REJECT' ? '驳回原因' : '审核说明(可选)'"><el-input v-model="reviewForm.reason" type="textarea" :rows="3" maxlength="500" :placeholder="reviewForm.action === 'REJECT' ? '请填写驳回原因' : '请输入审核说明(可选)'" show-word-limit /></el-form-item></el-form>
|
||||
</AppDialog>
|
||||
<AppDialog v-model="mutationOpen" :title="mutationTitle" :confirm-text="mutationMode === 'VOID' ? '确认作废' : '确认'" :confirm-loading="mutationSaving" @confirm="submitMutation">
|
||||
<el-form label-position="top"><el-form-item v-if="mutationMode === 'EDIT' || mutationMode === 'ADJUST'" label="金额(CNY)"><el-input-number v-model="mutationForm.amount" :min="0.01" :precision="2" :controls="false" style="width:100%" /></el-form-item><el-form-item label="操作原因"><el-input v-model="mutationForm.reason" type="textarea" :rows="3" maxlength="500" placeholder="请填写操作原因" show-word-limit /></el-form-item></el-form>
|
||||
<el-form label-position="top"><el-form-item v-if="mutationMode === 'EDIT' || mutationMode === 'ADJUST'" label="金额(CNY)"><el-input-number v-model="mutationForm.amount" :min="0.01" :precision="2" :controls="false" style="width:100%" placeholder="请输入调整金额" /></el-form-item><el-form-item label="操作原因"><el-input v-model="mutationForm.reason" type="textarea" :rows="3" maxlength="500" placeholder="请填写操作原因" show-word-limit /></el-form-item></el-form>
|
||||
</AppDialog>
|
||||
</AdminPage>
|
||||
</template>
|
||||
|
||||
@@ -713,13 +713,13 @@ watch(detailRouteId, (statementId) => {
|
||||
<div class="selected-source-summary">已选 {{ createForm.feeSourceIds.length }} 笔,合计 {{ selectedCreateAmount.toFixed(2) }} CNY</div>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item label="备注"><el-input v-model="createForm.remark" type="textarea" :rows="3" maxlength="500" show-word-limit /></el-form-item>
|
||||
<el-form-item label="备注"><el-input v-model="createForm.remark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请输入备注(选填)" /></el-form-item>
|
||||
</el-form>
|
||||
</AppDialog>
|
||||
|
||||
<AppDialog v-model="adjustOpen" title="调整客户对账单" width="min(900px, 96vw)" :confirm-loading="adjustBusy" @confirm="submitAdjustment">
|
||||
<el-form label-position="top"><el-form-item label="整体调整原因"><el-input v-model="adjustReason" type="textarea" maxlength="500" show-word-limit /></el-form-item></el-form>
|
||||
<el-table :data="adjustLines" size="small" max-height="420" border stripe><el-table-column label="选择" width="64"><template #default="{ row }"><el-checkbox v-model="row.selected" /></template></el-table-column><el-table-column prop="feeItemName" label="费用项目" min-width="150" /><el-table-column prop="originalAmount" label="原金额(CNY)" width="130" /><el-table-column label="新金额(CNY)" width="180"><template #default="{ row }"><el-input-number v-model="row.adjustedAmount" :min="0.01" :precision="2" /></template></el-table-column><el-table-column label="明细说明" min-width="220"><template #default="{ row }"><el-input v-model="row.reason" maxlength="500" /></template></el-table-column></el-table>
|
||||
<el-form label-position="top"><el-form-item label="整体调整原因"><el-input v-model="adjustReason" type="textarea" maxlength="500" show-word-limit placeholder="请输入整体调整原因" /></el-form-item></el-form>
|
||||
<el-table :data="adjustLines" size="small" max-height="420" border stripe><el-table-column label="选择" width="64"><template #default="{ row }"><el-checkbox v-model="row.selected" /></template></el-table-column><el-table-column prop="feeItemName" label="费用项目" min-width="150" /><el-table-column prop="originalAmount" label="原金额(CNY)" width="130" /><el-table-column label="新金额(CNY)" width="180"><template #default="{ row }"><el-input-number v-model="row.adjustedAmount" :min="0.01" :precision="2" placeholder="请输入新金额" /></template></el-table-column><el-table-column label="明细说明" min-width="220"><template #default="{ row }"><el-input v-model="row.reason" maxlength="500" placeholder="请输入明细说明" /></template></el-table-column></el-table>
|
||||
</AppDialog>
|
||||
</AdminPage>
|
||||
</template>
|
||||
|
||||
@@ -654,13 +654,13 @@ onMounted(() => {
|
||||
|
||||
<AppDialog v-model="paymentOpen" title="登记付款" width="min(760px, 94vw)" :confirm-loading="paymentBusy" @confirm="submitPayment">
|
||||
<div v-if="detail" class="partial-summary"><div><span>结算单号</span><strong>{{ detail.settlementNo }}</strong></div><div><span>供应商</span><strong>{{ detailPartyName() }}</strong></div><div><span>应付金额</span><strong>{{ money(detail.amount) }}</strong></div><div><span>已付金额</span><strong class="is-success">{{ money(detail.paidAmount) }}</strong></div><div><span>当前余额</span><strong class="is-danger">{{ money(detail.outstandingAmount) }}</strong></div></div>
|
||||
<el-form class="settlement-operation-form" label-position="top"><el-form-item label="付款日期"><el-date-picker v-model="paymentForm.transactionDate" type="date" value-format="YYYY-MM-DD" /></el-form-item><el-form-item label="本次付款金额(CNY)"><el-input-number v-model="paymentForm.amount" :min="0.01" :max="detail?.outstandingAmount || 0.01" :precision="2" /></el-form-item><el-form-item label="付款方式"><el-select v-model="paymentForm.method"><el-option label="银行转账" value="BANK_TRANSFER" /><el-option label="现金" value="CASH" /><el-option label="其他" value="OTHER" /></el-select></el-form-item><el-form-item label="银行流水号/凭证号"><el-input v-model="paymentForm.referenceNo" /></el-form-item><el-form-item label="付款凭证"><el-upload :auto-upload="false" :limit="1" accept="image/*" :on-change="selectPaymentFile"><el-button>选择图片</el-button></el-upload></el-form-item><el-form-item label="备注"><el-input v-model="paymentForm.remark" type="textarea" /></el-form-item></el-form>
|
||||
<el-form class="settlement-operation-form" label-position="top"><el-form-item label="付款日期"><el-date-picker v-model="paymentForm.transactionDate" type="date" value-format="YYYY-MM-DD" /></el-form-item><el-form-item label="本次付款金额(CNY)"><el-input-number v-model="paymentForm.amount" :min="0.01" :max="detail?.outstandingAmount || 0.01" :precision="2" placeholder="请输入付款金额" /></el-form-item><el-form-item label="付款方式"><el-select v-model="paymentForm.method"><el-option label="银行转账" value="BANK_TRANSFER" /><el-option label="现金" value="CASH" /><el-option label="其他" value="OTHER" /></el-select></el-form-item><el-form-item label="银行流水号/凭证号"><el-input v-model="paymentForm.referenceNo" placeholder="请输入付款流水号" /></el-form-item><el-form-item label="付款凭证"><el-upload :auto-upload="false" :limit="1" accept="image/*" :on-change="selectPaymentFile"><el-button>选择图片</el-button></el-upload></el-form-item><el-form-item label="备注"><el-input v-model="paymentForm.remark" type="textarea" placeholder="请输入付款备注(选填)" /></el-form-item></el-form>
|
||||
<div v-if="detail" class="remaining-preview"><span>登记后剩余余额</span><strong>{{ remainingAfter(paymentForm.amount) }}</strong></div>
|
||||
</AppDialog>
|
||||
|
||||
<AppDialog v-model="receiptOpen" title="登记收款" width="min(760px, 94vw)" :confirm-loading="receiptBusy" @confirm="submitReceipt">
|
||||
<div v-if="detail" class="partial-summary"><div><span>结算单号</span><strong>{{ detail.settlementNo }}</strong></div><div><span>客户公司</span><strong>{{ detailPartyName() }}</strong></div><div><span>应收金额</span><strong>{{ money(detail.amount) }}</strong></div><div><span>已收金额</span><strong class="is-success">{{ money(detail.paidAmount) }}</strong></div><div><span>当前余额</span><strong class="is-danger">{{ money(detail.outstandingAmount) }}</strong></div></div>
|
||||
<el-form class="settlement-operation-form" label-position="top"><el-form-item label="收款日期"><el-date-picker v-model="receiptForm.receivedDate" type="date" value-format="YYYY-MM-DD" /></el-form-item><el-form-item label="本次收款金额(CNY)"><el-input-number v-model="receiptForm.amount" :min="0.01" :max="detail?.outstandingAmount || 0.01" :precision="2" /></el-form-item><el-form-item label="收款方式"><el-select v-model="receiptForm.paymentMethod"><el-option label="银行转账" value="BANK_TRANSFER" /><el-option label="现金" value="CASH" /><el-option label="其他" value="OTHER" /></el-select></el-form-item><el-form-item label="收款凭证"><el-upload :key="receiptUploadKey" :auto-upload="false" :limit="1" accept="image/*" :on-change="selectReceiptFile"><el-button>选择图片</el-button></el-upload></el-form-item><el-form-item label="备注"><el-input v-model="receiptForm.remark" type="textarea" /></el-form-item></el-form>
|
||||
<el-form class="settlement-operation-form" label-position="top"><el-form-item label="收款日期"><el-date-picker v-model="receiptForm.receivedDate" type="date" value-format="YYYY-MM-DD" /></el-form-item><el-form-item label="本次收款金额(CNY)"><el-input-number v-model="receiptForm.amount" :min="0.01" :max="detail?.outstandingAmount || 0.01" :precision="2" placeholder="请输入收款金额" /></el-form-item><el-form-item label="收款方式"><el-select v-model="receiptForm.paymentMethod"><el-option label="银行转账" value="BANK_TRANSFER" /><el-option label="现金" value="CASH" /><el-option label="其他" value="OTHER" /></el-select></el-form-item><el-form-item label="收款凭证"><el-upload :key="receiptUploadKey" :auto-upload="false" :limit="1" accept="image/*" :on-change="selectReceiptFile"><el-button>选择图片</el-button></el-upload></el-form-item><el-form-item label="备注"><el-input v-model="receiptForm.remark" type="textarea" placeholder="请输入收款备注(选填)" /></el-form-item></el-form>
|
||||
<div v-if="detail" class="remaining-preview"><span>登记后剩余余额</span><strong>{{ remainingAfter(receiptForm.amount) }}</strong></div>
|
||||
</AppDialog>
|
||||
</AdminPage>
|
||||
|
||||
@@ -313,7 +313,7 @@ onMounted(loadPermissions)
|
||||
<el-form-item label="上级资源" prop="parentId" :required="['按钮', '页面', '接口'].includes(form.type)"><el-select v-model="form.parentId" clearable placeholder="作为一级资源"><el-option v-for="item in parentOptions" :key="item.id" :label="`${item.name} (${item.code})`" :value="item.id" /></el-select></el-form-item>
|
||||
<el-form-item v-if="['菜单', '页面'].includes(form.type)" label="路由路径" prop="path" required><el-input v-model="form.path" placeholder="如:/customers" /></el-form-item>
|
||||
<el-form-item v-if="form.type === '接口'" label="HTTP 方法" prop="method" required><el-select v-model="form.method"><el-option v-for="method in ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']" :key="method" :label="method" :value="method" /></el-select></el-form-item>
|
||||
<el-form-item label="显示排序" prop="sort" required><el-input-number v-model="form.sort" :min="0" :max="999" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="显示排序" prop="sort" required><el-input-number v-model="form.sort" :min="0" :max="999" controls-position="right" placeholder="请输入排序值" /></el-form-item>
|
||||
</div>
|
||||
</FormSection>
|
||||
<div class="form-callout"><Braces :size="18" /><div><strong>权限编码约定</strong><p>使用稳定的“业务域:资源:动作”编码;资源类型与后端 MENU、PAGE、BUTTON、API 契约一致。</p></div></div>
|
||||
|
||||
@@ -523,15 +523,15 @@ defineExpose({ reload: loadFee })
|
||||
<el-form ref="adjustFormRef" :model="adjustmentForm" :rules="adjustmentRules" label-position="top" class="adjustment-form" :disabled="adjusting">
|
||||
<div class="adjustment-amounts">
|
||||
<el-form-item label="调整后计费量" prop="chargeableQuantity" required>
|
||||
<el-input-number v-model="adjustmentForm.chargeableQuantity" aria-label="调整后计费量" :min="0.0001" :max="999999999999.9999" :precision="4" :step="1" controls-position="right" />
|
||||
<el-input-number v-model="adjustmentForm.chargeableQuantity" aria-label="调整后计费量" :min="0.0001" :max="999999999999.9999" :precision="4" :step="1" controls-position="right" placeholder="请输入调整后计费量" />
|
||||
<span class="adjustment-unit">{{ chargeUnitLabel }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="调整后单价" prop="unitPrice" required>
|
||||
<el-input-number v-model="adjustmentForm.unitPrice" aria-label="调整后单价" :min="0" :max="999999999999.9999" :precision="4" :step="0.1" controls-position="right" />
|
||||
<el-input-number v-model="adjustmentForm.unitPrice" aria-label="调整后单价" :min="0" :max="999999999999.9999" :precision="4" :step="0.1" controls-position="right" placeholder="请输入调整后单价" />
|
||||
<span class="adjustment-unit">{{ snapshot?.currency }} / {{ chargeUnitLabel }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="调整后附加费" prop="additionalAmount" required>
|
||||
<el-input-number v-model="adjustmentForm.additionalAmount" aria-label="调整后附加费" :min="0" :max="999999999999.99" :precision="2" :step="10" controls-position="right" />
|
||||
<el-input-number v-model="adjustmentForm.additionalAmount" aria-label="调整后附加费" :min="0" :max="999999999999.99" :precision="2" :step="10" controls-position="right" placeholder="请输入调整后附加费" />
|
||||
<span class="adjustment-unit">{{ snapshot?.currency }}</span>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
@@ -726,8 +726,7 @@ defineExpose({ saveDraft, submitForReview, updateActualWeights, mayMaintain, may
|
||||
:max="1000000"
|
||||
:step="1"
|
||||
step-strictly
|
||||
controls-position="right"
|
||||
/>
|
||||
controls-position="right" placeholder="请输入箱数" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总体积(m³)" width="108" align="right">
|
||||
@@ -775,13 +774,13 @@ defineExpose({ saveDraft, submitForReview, updateActualWeights, mayMaintain, may
|
||||
<el-form label-position="top" class="manual-entry-form" @submit.prevent="submitManualEntry">
|
||||
<div class="measurement-form-grid">
|
||||
<el-form-item label="箱号 *"><el-input v-model="manualForm.boxCode" placeholder="请输入已打印箱唛上的箱号" /></el-form-item>
|
||||
<el-form-item label="测量长(cm) *"><el-input-number v-model="manualForm.length" :min="0.001" :precision="3" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="测量宽(cm) *"><el-input-number v-model="manualForm.width" :min="0.001" :precision="3" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="测量高(cm) *"><el-input-number v-model="manualForm.height" :min="0.001" :precision="3" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="单箱毛重(kg) *"><el-input-number v-model="manualForm.weight" :min="0.001" :precision="3" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="测量长(cm) *"><el-input-number v-model="manualForm.length" :min="0.001" :precision="3" controls-position="right" placeholder="请输入测量长" /></el-form-item>
|
||||
<el-form-item label="测量宽(cm) *"><el-input-number v-model="manualForm.width" :min="0.001" :precision="3" controls-position="right" placeholder="请输入测量宽" /></el-form-item>
|
||||
<el-form-item label="测量高(cm) *"><el-input-number v-model="manualForm.height" :min="0.001" :precision="3" controls-position="right" placeholder="请输入测量高" /></el-form-item>
|
||||
<el-form-item label="单箱毛重(kg) *"><el-input-number v-model="manualForm.weight" :min="0.001" :precision="3" controls-position="right" placeholder="请输入单箱毛重" /></el-form-item>
|
||||
<el-form-item label="测量时间 *"><el-date-picker v-model="manualForm.measuredAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" format="YYYY-MM-DD HH:mm:ss" /></el-form-item>
|
||||
<el-form-item label="设备/来源编号"><el-input v-model="manualForm.machineNo" maxlength="64" /></el-form-item>
|
||||
<el-form-item label="Shipment ID"><el-input v-model="manualForm.scannedShipmentId" maxlength="64" /></el-form-item>
|
||||
<el-form-item label="设备/来源编号"><el-input v-model="manualForm.machineNo" maxlength="64" placeholder="请输入设备编号(选填)" /></el-form-item>
|
||||
<el-form-item label="Shipment ID"><el-input v-model="manualForm.scannedShipmentId" maxlength="64" placeholder="请输入扫描运单号(选填)" /></el-form-item>
|
||||
</div>
|
||||
<el-form-item label="当前箱测量图片 *">
|
||||
<el-upload class="manual-entry-upload" :auto-upload="false" :limit="1" accept="image/*" :on-change="selectManualImage" :on-remove="() => { manualEntryImage = null }">
|
||||
|
||||
@@ -644,8 +644,7 @@ defineExpose({ reload: loadWorkspace })
|
||||
:max="maximumSafeWeight"
|
||||
:precision="3"
|
||||
:controls="false"
|
||||
:disabled="Boolean(activeAction) || !previewInputEditable"
|
||||
/>
|
||||
:disabled="Boolean(activeAction) || !previewInputEditable" placeholder="请输入确认重量" />
|
||||
</label>
|
||||
<el-segmented
|
||||
v-model="weightDrafts[previewResult.id].unit"
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import { readFileSync, readdirSync } from 'node:fs'
|
||||
import { extname, join, relative } from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
const modulesRoot = join(process.cwd(), 'src/modules')
|
||||
|
||||
function vueFiles(directory: string): string[] {
|
||||
return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
|
||||
const path = join(directory, entry.name)
|
||||
if (entry.isDirectory()) return vueFiles(path)
|
||||
return extname(entry.name) === '.vue' ? [path] : []
|
||||
})
|
||||
}
|
||||
|
||||
function isPermanentlyReadOnly(tag: string): boolean {
|
||||
return (
|
||||
/\s(?:disabled|readonly)(?=\s|\/>|>)/.test(tag) ||
|
||||
/\s(?:disabled|readonly)=(?:""|'')/.test(tag) ||
|
||||
/\s(?::|v-bind:)(?:disabled|readonly)=(?:"true"|'true')/.test(tag)
|
||||
)
|
||||
}
|
||||
|
||||
function hasMeaningfulPlaceholder(tag: string): boolean {
|
||||
const value = tag.match(/\s(?::|v-bind:)?placeholder\s*=\s*(["'])(.*?)\1/)?.[2]
|
||||
return Boolean(value?.trim())
|
||||
}
|
||||
|
||||
describe('正式业务模块输入提示合同', () => {
|
||||
it('所有可编辑 el-input 与 el-input-number 都提供 placeholder', () => {
|
||||
const violations: string[] = []
|
||||
|
||||
for (const file of vueFiles(modulesRoot)) {
|
||||
const source = readFileSync(file, 'utf8').replace(/<!--[\s\S]*?-->/g, (comment) =>
|
||||
comment.replace(/[^\n]/g, ' '),
|
||||
)
|
||||
const openingTag = /<el-input(?:-number)?\b(?:"[^"]*"|'[^']*'|[^'">])*>/g
|
||||
|
||||
for (const match of source.matchAll(openingTag)) {
|
||||
const tag = match[0]
|
||||
if (isPermanentlyReadOnly(tag)) continue
|
||||
if (hasMeaningfulPlaceholder(tag)) continue
|
||||
|
||||
const line = source.slice(0, match.index).split('\n').length
|
||||
violations.push(
|
||||
`${relative(modulesRoot, file).replaceAll('\\', '/')}:${line} ${tag.replace(/\s+/g, ' ')}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
expect(violations, `缺少 placeholder:\n${violations.join('\n')}`).toEqual([])
|
||||
})
|
||||
})
|
||||
@@ -412,19 +412,19 @@ onMounted(() => void load())
|
||||
</template>
|
||||
</template>
|
||||
<el-form-item label="业务日期" prop="businessDate"><el-date-picker v-model="form.businessDate" type="date" value-format="YYYY-MM-DD" /></el-form-item>
|
||||
<el-form-item label="金额(CNY)" prop="amount"><el-input-number v-model="form.amount" :min="0" :precision="2" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="金额(CNY)" prop="amount"><el-input-number v-model="form.amount" :min="0" :precision="2" controls-position="right" placeholder="请输入金额" /></el-form-item>
|
||||
<el-form-item v-if="allocationMode" label="业务归属分摊" class="allocation-editor" required>
|
||||
<el-alert type="info" :closable="false" show-icon title="客户必须明确;入仓码没有时按订单归属,分摊合计必须等于费用总额。" />
|
||||
<div class="allocation-editor__rows">
|
||||
<div v-for="(row, index) in allocationDraft" :key="`${row.customerId}-${row.orderId}-${row.inboundId || 'none'}`" class="allocation-editor__row">
|
||||
<span><strong>{{ customerLabel(row.customerId || targetGroupRows[index]?.customerId || '') }}</strong><small>{{ row.orderNo }} · {{ row.inboundCode || '无入仓码' }}</small></span>
|
||||
<el-input-number v-model="row.amount" :min="0" :precision="2" controls-position="right" />
|
||||
<el-input-number v-model="row.amount" :min="0" :precision="2" controls-position="right" placeholder="请输入分摊金额" />
|
||||
</div>
|
||||
</div>
|
||||
<p class="allocation-editor__sum" :class="{ 'is-error': Math.abs(allocationSum - form.amount) > 0.001 }">已分摊 ¥{{ money(allocationSum) }} / 总额 ¥{{ money(form.amount) }}</p>
|
||||
</el-form-item>
|
||||
<template v-if="!target">
|
||||
<el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="500" show-word-limit /></el-form-item>
|
||||
<el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请输入备注(选填)" /></el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
<LoadErrorState v-if="editorError" compact title="费用保存失败" :message="editorError.message" :show-retry="false"><template #details><ApiErrorMeta :details="editorError" /></template></LoadErrorState>
|
||||
|
||||
@@ -68,7 +68,7 @@ async function submit() {
|
||||
<el-form-item label="消息模板" required><el-select v-model="form.templateCode" filterable placeholder="请选择已激活模板"><el-option v-for="item in templates" :key="item.id" :label="`${item.templateName}(${item.templateCode})`" :value="item.templateCode" /></el-select></el-form-item>
|
||||
<div class="form-grid"><el-form-item label="接收对象" required><el-select v-model="form.recipientType"><el-option v-for="item in allowedRecipients" :key="item.value" :label="item.label" :value="item.value" /></el-select></el-form-item><el-form-item v-if="needsRole" label="角色编码" required><el-input v-model="form.roleCode" maxlength="64" placeholder="请输入服务端角色编码" /></el-form-item></div>
|
||||
<el-form-item v-if="needsIds" label="接收人用户 ID" required><el-input v-model="recipientIdsText" type="textarea" :rows="2" placeholder="多个用户 ID 使用逗号或换行分隔,最多 1000 个" /></el-form-item>
|
||||
<section v-if="selectedTemplate?.variableWhitelist.length" class="variables"><strong>模板变量</strong><el-form-item v-for="key in selectedTemplate.variableWhitelist" :key="key" :label="key" required><el-input v-model="variables[key]" maxlength="2000" /></el-form-item></section>
|
||||
<section v-if="selectedTemplate?.variableWhitelist.length" class="variables"><strong>模板变量</strong><el-form-item v-for="key in selectedTemplate.variableWhitelist" :key="key" :label="key" required><el-input v-model="variables[key]" maxlength="2000" placeholder="请输入变量值" /></el-form-item></section>
|
||||
<el-form-item label="定时发送"><div class="schedule-row"><el-switch v-model="scheduled" aria-label="启用定时发送" /><span>启用</span><el-date-picker v-model="form.scheduledAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="选择发送时间" :disabled="!scheduled" /></div></el-form-item>
|
||||
</el-form>
|
||||
<template #footer="{ close }"><div class="dialog-actions"><el-button :disabled="submitting" @click="close">取消</el-button><el-button type="primary" :loading="submitting" @click="submit">{{ scheduled ? '确认定时发送' : '立即发送' }}</el-button></div></template>
|
||||
|
||||
@@ -37,7 +37,7 @@ async function submit() {
|
||||
<AppDialog v-model="open" :title="editing ? '编辑消息模板' : '新增消息模板'" width="min(760px, calc(100vw - 28px))" :show-confirm="false" destroy-on-close>
|
||||
<OperationErrorToast :details="error" />
|
||||
<el-alert title="首期仅支持站内信;新模板保存为草稿,草稿激活后不可再编辑。" type="info" :closable="false" show-icon />
|
||||
<el-form class="template-form" label-position="top"><div class="form-grid"><el-form-item label="模板CODE" required><el-input :model-value="form.code" maxlength="64" :disabled="editing" placeholder="如:ORDER_SHIPPED_NOTICE" @update:model-value="normalizeCode(String($event))" /></el-form-item><el-form-item label="模板名称" required><el-input v-model="form.name" maxlength="128" /></el-form-item></div><div class="form-grid"><el-form-item label="业务分类" required><el-input v-model="form.category" maxlength="64" /></el-form-item><el-form-item label="模板类型"><el-input model-value="站内信" disabled /></el-form-item></div><el-form-item label="消息标题模板" required><el-input v-model="form.title" maxlength="256" show-word-limit /></el-form-item><el-form-item label="消息正文模板" required><el-input ref="contentInput" v-model="form.content" type="textarea" :rows="6" maxlength="10000" show-word-limit /></el-form-item><el-form-item label="变量白名单"><el-input v-model="whitelistText" placeholder="多个变量使用逗号分隔,如 customer_name, order_no" /></el-form-item><div class="variable-row"><span>常用变量</span><el-button v-for="name in ['customer_name','order_no','container_no','amount','date']" :key="name" size="small" @click="insertVariable(name)">{{ name }}</el-button></div><section class="template-preview"><strong>内容预览</strong><p>{{ preview }}</p></section></el-form>
|
||||
<el-form class="template-form" label-position="top"><div class="form-grid"><el-form-item label="模板CODE" required><el-input :model-value="form.code" maxlength="64" :disabled="editing" placeholder="如:ORDER_SHIPPED_NOTICE" @update:model-value="normalizeCode(String($event))" /></el-form-item><el-form-item label="模板名称" required><el-input v-model="form.name" maxlength="128" placeholder="请输入模板名称" /></el-form-item></div><div class="form-grid"><el-form-item label="业务分类" required><el-input v-model="form.category" maxlength="64" placeholder="请输入业务分类" /></el-form-item><el-form-item label="模板类型"><el-input model-value="站内信" disabled /></el-form-item></div><el-form-item label="消息标题模板" required><el-input v-model="form.title" maxlength="256" show-word-limit placeholder="请输入消息标题模板" /></el-form-item><el-form-item label="消息正文模板" required><el-input ref="contentInput" v-model="form.content" type="textarea" :rows="6" maxlength="10000" show-word-limit placeholder="请输入消息正文模板" /></el-form-item><el-form-item label="变量白名单"><el-input v-model="whitelistText" placeholder="多个变量使用逗号分隔,如 customer_name, order_no" /></el-form-item><div class="variable-row"><span>常用变量</span><el-button v-for="name in ['customer_name','order_no','container_no','amount','date']" :key="name" size="small" @click="insertVariable(name)">{{ name }}</el-button></div><section class="template-preview"><strong>内容预览</strong><p>{{ preview }}</p></section></el-form>
|
||||
<template #footer="{ close }"><div class="dialog-actions"><el-button :disabled="submitting" @click="close">取消</el-button><el-button type="primary" :loading="submitting" @click="submit">保存模板</el-button></div></template>
|
||||
</AppDialog>
|
||||
</template>
|
||||
|
||||
@@ -437,7 +437,7 @@ onMounted(() => { void load(); void loadOptions() })
|
||||
</td>
|
||||
<td><el-select :model-value="requirement.containerType" :disabled="!formWritable" placeholder="请选择柜型" @update:model-value="selectContainerRequirementType(requirement, String($event || ''))"><el-option v-for="item in containerTypeOptions" :key="item.type" :label="item.type" :value="item.type" /></el-select></td>
|
||||
<td><el-select v-model="requirement.containerKind" :disabled="!formWritable" placeholder="请选择箱种"><el-option v-for="item in containerKindOptions" :key="item.value" :label="item.label" :value="item.value" /></el-select></td>
|
||||
<td><el-input-number v-model="requirement.quantity" :disabled="!formWritable" :min="1" :max="99" controls-position="right" /></td>
|
||||
<td><el-input-number v-model="requirement.quantity" :disabled="!formWritable" :min="1" :max="99" controls-position="right" placeholder="请输入柜量" /></td>
|
||||
<td class="container-table__specification"><span>{{ requirement.capacityCbm }} m³</span></td>
|
||||
<td class="container-table__specification"><span>{{ requirement.maxWeightKg }} kg</span></td>
|
||||
<td v-if="detail?.status === 'RELEASED'"><span>{{ requirement.remainingQuantity ?? requirement.quantity }}</span></td>
|
||||
|
||||
@@ -76,9 +76,9 @@ watch([purchaseId, customerId], () => { void loadWarehouses().then(load) }, { im
|
||||
<template #header><div class="form-header"><div><h2>编辑海外采购订单</h2><span>订单编号:{{ form.orderNo || purchaseId || '—' }}</span></div><el-button @click="router.push({ name: 'overseas-business-purchase-detail', params: { purchaseId }, query: { customerId } })"><ArrowLeft :size="16" />返回</el-button></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="surface-panel form-panel"><el-form ref="formRef" :model="form" :rules="rules" label-position="top" :disabled="saving">
|
||||
<FormSection title="商品信息"><div class="form-grid three"><el-form-item label="订单编号"><el-input v-model="form.orderNo" disabled /></el-form-item><el-form-item label="采购品类" prop="purchaseCategory"><el-input v-model="form.purchaseCategory" maxlength="128" /></el-form-item><el-form-item label="商品名称" prop="productName"><el-input v-model="form.productName" maxlength="255" /></el-form-item><el-form-item class="span-2" label="商品规格"><el-input v-model="form.productSpecification" maxlength="500" /></el-form-item><el-form-item class="span-3" label="商品链接"><el-input v-model="form.productUrl" maxlength="2000" /></el-form-item></div></FormSection>
|
||||
<FormSection title="库存与快递信息"><div class="form-grid three"><el-form-item label="入库量"><el-input-number v-model="form.inboundQuantity" :min="0" :disabled="!inboundEditable" controls-position="right" /><small v-if="!inboundEditable">服务端仅允许已通过订单修改入库量</small></el-form-item><el-form-item label="出库量"><el-input :model-value="outboundQuantity" disabled /></el-form-item><el-form-item label="状态"><el-input :model-value="statusLabels[form.status]" disabled /></el-form-item><el-form-item label="采购仓库"><el-select v-model="form.purchaseWarehouseId" clearable filterable :loading="warehousesLoading" :disabled="Boolean(warehousesError)" placeholder="请选择采购仓"><el-option v-for="item in warehouses" :key="item.warehouseId" :label="`${item.warehouseName}${item.warehouseCode ? ` · ${item.warehouseCode}` : ''}`" :value="item.warehouseId" /></el-select><small v-if="warehousesError" class="field-error">{{ warehousesError }}</small></el-form-item><el-form-item label="预计到达时间"><el-date-picker v-model="form.estimatedArrivalAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" clearable /></el-form-item><el-form-item label="国内承运商"><el-input v-model="form.domesticCarrier" maxlength="128" /></el-form-item><el-form-item label="国内运单号"><el-input v-model="form.domesticTrackingNo" maxlength="128" /></el-form-item><el-form-item label="海外承运商"><el-input v-model="form.overseasCarrier" maxlength="128" /></el-form-item><el-form-item label="海外运单号"><el-input v-model="form.overseasTrackingNo" maxlength="128" /></el-form-item><el-form-item class="span-3" label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="1000" show-word-limit /></el-form-item></div></FormSection>
|
||||
<FormSection title="出库明细"><div class="outbound-head"><span>出库总量:<b>{{ outboundQuantity }}</b> / {{ form.inboundQuantity }}</span><el-button type="primary" plain size="small" @click="addOutbound"><Plus :size="14" />添加出库明细</el-button></div><div v-if="!form.outboundDetails.length" class="empty-outbound">暂无出库明细,可添加多条出库记录</div><div v-for="(item, index) in form.outboundDetails" :key="item.id" class="outbound-row"><el-form-item label="出库数量"><el-input-number v-model="item.quantity" :min="0" :max="form.inboundQuantity" controls-position="right" /></el-form-item><el-form-item label="承运商"><el-input v-model="item.carrier" maxlength="128" placeholder="快递/物流名称" /></el-form-item><el-form-item label="运单号"><el-input v-model="item.trackingNo" maxlength="128" /></el-form-item><el-form-item label="出库时间"><el-date-picker v-model="item.shippedAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" clearable /></el-form-item><el-form-item class="outbound-remark" label="备注"><el-input v-model="item.remark" maxlength="500" /></el-form-item><el-button class="remove-outbound" type="danger" link @click="removeOutbound(index)" :aria-label="`删除第 ${index + 1} 条出库明细`"><Trash2 :size="16" /></el-button></div></FormSection>
|
||||
<FormSection title="商品信息"><div class="form-grid three"><el-form-item label="订单编号"><el-input v-model="form.orderNo" disabled /></el-form-item><el-form-item label="采购品类" prop="purchaseCategory"><el-input v-model="form.purchaseCategory" maxlength="128" placeholder="请输入采购品类" /></el-form-item><el-form-item label="商品名称" prop="productName"><el-input v-model="form.productName" maxlength="255" placeholder="请输入商品名称" /></el-form-item><el-form-item class="span-2" label="商品规格"><el-input v-model="form.productSpecification" maxlength="500" placeholder="请输入商品规格" /></el-form-item><el-form-item class="span-3" label="商品链接"><el-input v-model="form.productUrl" maxlength="2000" placeholder="请输入商品链接" /></el-form-item></div></FormSection>
|
||||
<FormSection title="库存与快递信息"><div class="form-grid three"><el-form-item label="入库量"><el-input-number v-model="form.inboundQuantity" :min="0" :disabled="!inboundEditable" controls-position="right" placeholder="请输入入库数量" /><small v-if="!inboundEditable">服务端仅允许已通过订单修改入库量</small></el-form-item><el-form-item label="出库量"><el-input :model-value="outboundQuantity" disabled /></el-form-item><el-form-item label="状态"><el-input :model-value="statusLabels[form.status]" disabled /></el-form-item><el-form-item label="采购仓库"><el-select v-model="form.purchaseWarehouseId" clearable filterable :loading="warehousesLoading" :disabled="Boolean(warehousesError)" placeholder="请选择采购仓"><el-option v-for="item in warehouses" :key="item.warehouseId" :label="`${item.warehouseName}${item.warehouseCode ? ` · ${item.warehouseCode}` : ''}`" :value="item.warehouseId" /></el-select><small v-if="warehousesError" class="field-error">{{ warehousesError }}</small></el-form-item><el-form-item label="预计到达时间"><el-date-picker v-model="form.estimatedArrivalAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" clearable /></el-form-item><el-form-item label="国内承运商"><el-input v-model="form.domesticCarrier" maxlength="128" placeholder="请输入国内承运商" /></el-form-item><el-form-item label="国内运单号"><el-input v-model="form.domesticTrackingNo" maxlength="128" placeholder="请输入国内物流单号" /></el-form-item><el-form-item label="海外承运商"><el-input v-model="form.overseasCarrier" maxlength="128" placeholder="请输入海外承运商" /></el-form-item><el-form-item label="海外运单号"><el-input v-model="form.overseasTrackingNo" maxlength="128" placeholder="请输入海外物流单号" /></el-form-item><el-form-item class="span-3" label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="1000" show-word-limit placeholder="请输入备注(选填)" /></el-form-item></div></FormSection>
|
||||
<FormSection title="出库明细"><div class="outbound-head"><span>出库总量:<b>{{ outboundQuantity }}</b> / {{ form.inboundQuantity }}</span><el-button type="primary" plain size="small" @click="addOutbound"><Plus :size="14" />添加出库明细</el-button></div><div v-if="!form.outboundDetails.length" class="empty-outbound">暂无出库明细,可添加多条出库记录</div><div v-for="(item, index) in form.outboundDetails" :key="item.id" class="outbound-row"><el-form-item label="出库数量"><el-input-number v-model="item.quantity" :min="0" :max="form.inboundQuantity" controls-position="right" placeholder="请输入出库数量" /></el-form-item><el-form-item label="承运商"><el-input v-model="item.carrier" maxlength="128" placeholder="请输入快递或物流名称" /></el-form-item><el-form-item label="运单号"><el-input v-model="item.trackingNo" maxlength="128" placeholder="请输入物流单号" /></el-form-item><el-form-item label="出库时间"><el-date-picker v-model="item.shippedAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" clearable /></el-form-item><el-form-item class="outbound-remark" label="备注"><el-input v-model="item.remark" maxlength="500" placeholder="请输入本次出库备注(选填)" /></el-form-item><el-button class="remove-outbound" type="danger" link @click="removeOutbound(index)" :aria-label="`删除第 ${index + 1} 条出库明细`"><Trash2 :size="16" /></el-button></div></FormSection>
|
||||
</el-form><footer class="form-actions"><el-button type="primary" :loading="saving" @click="save"><Save :size="16" />保存</el-button><el-button :disabled="saving" @click="router.push({ name: 'overseas-business-purchase-detail', params: { purchaseId }, query: { customerId } })">取消</el-button></footer></section>
|
||||
</DetailPageLayout></AdminPage>
|
||||
</template>
|
||||
|
||||
@@ -111,9 +111,9 @@ watch([orderId, routeCustomerId, isLooseboard], () => { void load(); void loadCu
|
||||
<FormSection v-if="!editing" title="客户信息"><el-form-item label="客户"><el-select v-model="form.customerId" filterable :loading="customersLoading" :disabled="Boolean(customersError)" placeholder="请选择客户" style="width:100%"><el-option v-for="item in customers" :key="String(item.id)" :label="item.tenantName" :value="String(item.id)" /></el-select><small v-if="customersError" class="field-error">{{ customersError }}</small></el-form-item></FormSection>
|
||||
<el-alert v-if="editing && !editableStatus" type="warning" :closable="false" show-icon title="当前状态不可普通编辑,请返回列表查看" />
|
||||
<FormSection v-if="isLooseboard" title="散板方式"><div class="choice-block"><el-form-item label="运输方式" prop="transportMode"><el-radio-group v-model="form.transportMode"><el-radio-button v-for="item in transportModes" :key="item.value" :value="item.value">{{ item.label }}</el-radio-button></el-radio-group></el-form-item><el-form-item label="是否打盘" prop="palletRequired"><el-radio-group v-model="form.palletRequired"><el-radio-button value="YES">是</el-radio-button><el-radio-button value="NO">否</el-radio-button></el-radio-group></el-form-item></div></FormSection>
|
||||
<FormSection title="运输信息"><el-form-item label="运输类型" prop="transportType"><el-radio-group v-model="form.transportType"><el-radio-button v-for="item in transportTypes" :key="item.value" :value="item.value">{{ item.label }}</el-radio-button></el-radio-group></el-form-item><div class="form-grid two"><el-form-item label="起运地" prop="origin"><el-input v-model="form.origin" maxlength="255" placeholder="城市 / 港口 / 州" /></el-form-item><el-form-item label="目的地" prop="destination"><el-input v-model="form.destination" maxlength="255" placeholder="城市 / 州" /></el-form-item><el-form-item label="详细地址"><el-input v-model="form.originAddress" maxlength="500" placeholder="街道 / 门牌" /></el-form-item><el-form-item label="详细地址 / 码头 / 仓号"><el-input v-model="form.destinationAddress" maxlength="500" placeholder="地址 / 码头 / 仓号" /></el-form-item><el-form-item label="联系人" prop="contactName"><el-input v-model="form.contactName" maxlength="128" /></el-form-item><el-form-item label="联系方式" prop="contactInfo"><el-input v-model="form.contactInfo" maxlength="128" /></el-form-item></div></FormSection>
|
||||
<FormSection title="📦 货物信息"><div class="form-grid" :class="isLooseboard ? 'four' : 'five'"><el-form-item label="柜型"><el-select v-model="form.containerType" clearable><el-option v-for="value in ['20GP','40GP','40HQ','45HQ']" :key="value" :label="value" :value="value" /></el-select></el-form-item><el-form-item v-if="!isLooseboard" label="托数" prop="palletCount"><el-input-number v-model="form.palletCount" :min="1" controls-position="right" /></el-form-item><el-form-item label="件数" prop="packageCount"><el-input-number v-model="form.packageCount" :min="0" controls-position="right" /></el-form-item><el-form-item label="总重量 (kg)" prop="totalWeightKg"><el-input v-model="form.totalWeightKg" inputmode="decimal" /></el-form-item><el-form-item label="总体积 (m³)" prop="totalVolumeCbm"><el-input v-model="form.totalVolumeCbm" inputmode="decimal" /></el-form-item></div></FormSection>
|
||||
<FormSection title="费用与时效"><div class="form-grid two"><el-form-item label="预算总价" prop="budgetAmount"><el-input v-model="form.budgetAmount" inputmode="decimal"><template #append>{{ form.currency }}</template></el-input></el-form-item><el-form-item label="要求时间" prop="requestedDate"><el-date-picker v-model="form.requestedDate" type="date" value-format="YYYY-MM-DD" clearable /></el-form-item><el-form-item v-if="editing" label="状态"><el-input :model-value="statusLabel" disabled /></el-form-item><el-form-item class="span-2" label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="1000" show-word-limit /></el-form-item></div></FormSection>
|
||||
<FormSection title="运输信息"><el-form-item label="运输类型" prop="transportType"><el-radio-group v-model="form.transportType"><el-radio-button v-for="item in transportTypes" :key="item.value" :value="item.value">{{ item.label }}</el-radio-button></el-radio-group></el-form-item><div class="form-grid two"><el-form-item label="起运地" prop="origin"><el-input v-model="form.origin" maxlength="255" placeholder="城市 / 港口 / 州" /></el-form-item><el-form-item label="目的地" prop="destination"><el-input v-model="form.destination" maxlength="255" placeholder="城市 / 州" /></el-form-item><el-form-item label="详细地址"><el-input v-model="form.originAddress" maxlength="500" placeholder="街道 / 门牌" /></el-form-item><el-form-item label="详细地址 / 码头 / 仓号"><el-input v-model="form.destinationAddress" maxlength="500" placeholder="地址 / 码头 / 仓号" /></el-form-item><el-form-item label="联系人" prop="contactName"><el-input v-model="form.contactName" maxlength="128" placeholder="请输入联系人姓名" /></el-form-item><el-form-item label="联系方式" prop="contactInfo"><el-input v-model="form.contactInfo" maxlength="128" placeholder="请输入联系方式" /></el-form-item></div></FormSection>
|
||||
<FormSection title="📦 货物信息"><div class="form-grid" :class="isLooseboard ? 'four' : 'five'"><el-form-item label="柜型"><el-select v-model="form.containerType" clearable><el-option v-for="value in ['20GP','40GP','40HQ','45HQ']" :key="value" :label="value" :value="value" /></el-select></el-form-item><el-form-item v-if="!isLooseboard" label="托数" prop="palletCount"><el-input-number v-model="form.palletCount" :min="1" controls-position="right" placeholder="请输入托盘数" /></el-form-item><el-form-item label="件数" prop="packageCount"><el-input-number v-model="form.packageCount" :min="0" controls-position="right" placeholder="请输入件数" /></el-form-item><el-form-item label="总重量 (kg)" prop="totalWeightKg"><el-input v-model="form.totalWeightKg" inputmode="decimal" placeholder="请输入总重量" /></el-form-item><el-form-item label="总体积 (m³)" prop="totalVolumeCbm"><el-input v-model="form.totalVolumeCbm" inputmode="decimal" placeholder="请输入总体积" /></el-form-item></div></FormSection>
|
||||
<FormSection title="费用与时效"><div class="form-grid two"><el-form-item label="预算总价" prop="budgetAmount"><el-input v-model="form.budgetAmount" inputmode="decimal" placeholder="请输入预算金额" ><template #append>{{ form.currency }}</template></el-input></el-form-item><el-form-item label="要求时间" prop="requestedDate"><el-date-picker v-model="form.requestedDate" type="date" value-format="YYYY-MM-DD" clearable /></el-form-item><el-form-item v-if="editing" label="状态"><el-input :model-value="statusLabel" disabled /></el-form-item><el-form-item class="span-2" label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="1000" show-word-limit placeholder="请输入备注(选填)" /></el-form-item></div></FormSection>
|
||||
</el-form><footer class="form-actions"><el-button @click="back">取消</el-button><el-button type="primary" :loading="saving" :disabled="!editableStatus" @click="save"><Save :size="16" />{{ editing ? '保存修改' : '提交订单' }}</el-button></footer></section>
|
||||
</DetailPageLayout></AdminPage>
|
||||
</template>
|
||||
|
||||
@@ -53,6 +53,6 @@ watch([page, pageSize], load); onMounted(load)
|
||||
<template #actions="{ row }"><el-button v-if="access.can(permission.exchangeRateEdit)" link type="primary" @click="openEdit(row as MonthlyExchangeRate)"><Pencil :size="15" />编辑</el-button><el-button v-if="access.can(permission.exchangeRateStatus)" link :type="(row as MonthlyExchangeRate).status === 'ACTIVE' ? 'danger' : 'success'" @click="toggle(row as MonthlyExchangeRate)"><Power :size="15" />{{ (row as MonthlyExchangeRate).status === 'ACTIVE' ? '停用' : '启用' }}</el-button></template>
|
||||
<template #conversion="{ row }">1 USD = {{ (row as MonthlyExchangeRate).usdToCnyAverage }} CNY</template><template #status="{ row }"><el-tag :type="(row as MonthlyExchangeRate).status === 'ACTIVE' ? 'success' : 'info'">{{ (row as MonthlyExchangeRate).status === 'ACTIVE' ? '启用' : '停用' }}</el-tag></template>
|
||||
</DataTable></section>
|
||||
<AppDialog v-model="editorOpen" :title="editingMonth ? '编辑月度汇率' : '更新月度汇率'" width="min(560px, calc(100vw - 28px))" :confirm-loading="saving" @confirm="save"><el-form label-position="top"><el-form-item label="汇率月份"><el-date-picker v-model="form.month" type="month" value-format="YYYY-MM" :disabled="!!editingMonth" /></el-form-item><el-form-item label="美元兑人民币平均汇率"><el-input-number v-model="form.usdToCnyAverage" :min="0.00000001" :precision="8" /><p>汇率方向:1 USD = X CNY</p></el-form-item><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="1000" /></el-form-item></el-form></AppDialog>
|
||||
<AppDialog v-model="editorOpen" :title="editingMonth ? '编辑月度汇率' : '更新月度汇率'" width="min(560px, calc(100vw - 28px))" :confirm-loading="saving" @confirm="save"><el-form label-position="top"><el-form-item label="汇率月份"><el-date-picker v-model="form.month" type="month" value-format="YYYY-MM" :disabled="!!editingMonth" /></el-form-item><el-form-item label="美元兑人民币平均汇率"><el-input-number v-model="form.usdToCnyAverage" :min="0.00000001" :precision="8" placeholder="请输入美元兑人民币月均汇率" /><p>汇率方向:1 USD = X CNY</p></el-form-item><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="1000" placeholder="请输入备注(选填)" /></el-form-item></el-form></AppDialog>
|
||||
</ListPageLayout></AdminPage></template>
|
||||
<style scoped>.rate-summary{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}.rate-summary article{padding:16px 18px}.rate-summary span{display:block;color:var(--cc-muted);font-size:12px}.rate-summary strong{display:block;margin-top:8px;font-size:22px}.table-panel{min-width:0;overflow:hidden}</style>
|
||||
|
||||
@@ -61,6 +61,6 @@ watch([page,pageSize],load);onMounted(()=>{void Promise.all([load(),loadOptions(
|
||||
<template #status="{row}"><el-tag :type="(row as OverseasWarehouseQuote).status==='ACTIVE'?'success':'info'">{{(row as OverseasWarehouseQuote).status==='ACTIVE'?'启用':'停用'}}</el-tag></template>
|
||||
</DataTable></section>
|
||||
<AppDialog v-model="detailOpen" title="海外仓报价详情" width="min(980px, calc(100vw - 28px))" :show-confirm="false"><div v-if="detail" class="detail-grid"><div v-for="item in [['报价名称',detail.summary.name],['海外仓',detail.summary.warehouseName],['服务商',detail.summary.providerName],['币种',detail.summary.currency],['生效日期',detail.summary.effectiveStart],['失效日期',detail.summary.effectiveEnd],['版本',detail.summary.versionCode],['状态',detail.summary.status]]" :key="item[0]"><span>{{item[0]}}</span><strong>{{item[1]}}</strong></div></div><h3>仓储作业费用</h3><el-table :data="detail?.warehouseFees||[]" border><el-table-column prop="item" label="费用项目"/><el-table-column prop="billingUnit" label="计费单位"/><el-table-column prop="unitPrice" label="单价"/><el-table-column prop="minimumCharge" label="最低收费"/><el-table-column prop="remark" label="备注"/></el-table><h3>中转派送价格</h3><el-table :data="detail?.transitPrices||[]" border><el-table-column prop="fbaWarehouseCode" label="目的FBA仓"/><el-table-column prop="deliveryMethod" label="车型/提货方式"/><el-table-column prop="estimatedMiles" label="预估迈数"/><el-table-column prop="price" label="报价"/><el-table-column prop="minimumCharge" label="最低收费"/></el-table></AppDialog>
|
||||
<AppDialog v-model="editorOpen" :title="editingId?'编辑海外仓报价':'新增海外仓报价'" width="min(1180px, calc(100vw - 28px))" :confirm-loading="saving" confirm-text="保存报价" @confirm="save"><el-form label-position="top"><div class="form-grid"><el-form-item label="报价名称"><el-input v-model="form.name"/></el-form-item><el-form-item label="海外仓"><el-select v-model="form.warehouseId" :disabled="!!editingId"><el-option v-for="o in options" :key="o.warehouseId" :label="`${o.warehouseName} · ${o.warehouseCode}`" :value="o.warehouseId"/></el-select></el-form-item><el-form-item label="服务商"><el-input v-model="form.providerName"/></el-form-item><el-form-item label="币种"><el-select v-model="form.currency"><el-option label="USD" value="USD"/><el-option label="CNY" value="CNY"/></el-select></el-form-item><el-form-item label="生效日期"><el-date-picker v-model="form.effectiveStart" type="date" value-format="YYYY-MM-DD"/></el-form-item><el-form-item label="失效日期"><el-date-picker v-model="form.effectiveEnd" type="date" value-format="YYYY-MM-DD"/></el-form-item><el-form-item label="报价版本"><el-input v-model="form.versionCode" :disabled="!!editingId"/></el-form-item><el-form-item label="备注"><el-input v-model="form.remark"/></el-form-item></div><h3>仓储作业费用 <el-button @click="form.warehouseFees.push({item:'',billingUnit:'',unitPrice:0,minimumCharge:null,remark:null})">+ 添加费用</el-button></h3><div v-for="(f,i) in form.warehouseFees" :key="i" class="line-grid"><el-input v-model="f.item" placeholder="费用项目"/><el-input v-model="f.billingUnit" placeholder="计费单位"/><el-input-number v-model="f.unitPrice" :min="0"/><el-input-number v-model="f.minimumCharge" :min="0"/><el-button type="danger" plain @click="form.warehouseFees.splice(i,1)">删除</el-button></div><h3>中转派送价格 <el-button @click="form.transitPrices.push({fbaWarehouseCode:'',deliveryMethod:'',estimatedMiles:null,price:0,minimumCharge:null,remark:null})">+ 添加派送价格</el-button></h3><div v-for="(t,i) in form.transitPrices" :key="i" class="line-grid"><el-input v-model="t.fbaWarehouseCode" placeholder="FBA仓"/><el-input v-model="t.deliveryMethod" placeholder="车型/提货方式"/><el-input-number v-model="t.price" :min="0"/><el-input-number v-model="t.minimumCharge" :min="0"/><el-button type="danger" plain @click="form.transitPrices.splice(i,1)">删除</el-button></div></el-form></AppDialog>
|
||||
<AppDialog v-model="editorOpen" :title="editingId?'编辑海外仓报价':'新增海外仓报价'" width="min(1180px, calc(100vw - 28px))" :confirm-loading="saving" confirm-text="保存报价" @confirm="save"><el-form label-position="top"><div class="form-grid"><el-form-item label="报价名称"><el-input v-model="form.name" placeholder="请输入报价名称" /></el-form-item><el-form-item label="海外仓"><el-select v-model="form.warehouseId" :disabled="!!editingId"><el-option v-for="o in options" :key="o.warehouseId" :label="`${o.warehouseName} · ${o.warehouseCode}`" :value="o.warehouseId"/></el-select></el-form-item><el-form-item label="服务商"><el-input v-model="form.providerName" placeholder="请输入服务商名称" /></el-form-item><el-form-item label="币种"><el-select v-model="form.currency"><el-option label="USD" value="USD"/><el-option label="CNY" value="CNY"/></el-select></el-form-item><el-form-item label="生效日期"><el-date-picker v-model="form.effectiveStart" type="date" value-format="YYYY-MM-DD"/></el-form-item><el-form-item label="失效日期"><el-date-picker v-model="form.effectiveEnd" type="date" value-format="YYYY-MM-DD"/></el-form-item><el-form-item label="报价版本"><el-input v-model="form.versionCode" :disabled="!!editingId" placeholder="请输入版本号" /></el-form-item><el-form-item label="备注"><el-input v-model="form.remark" placeholder="请输入备注(选填)" /></el-form-item></div><h3>仓储作业费用 <el-button @click="form.warehouseFees.push({item:'',billingUnit:'',unitPrice:0,minimumCharge:null,remark:null})">+ 添加费用</el-button></h3><div v-for="(f,i) in form.warehouseFees" :key="i" class="line-grid"><el-input v-model="f.item" placeholder="请输入费用项目"/><el-input v-model="f.billingUnit" placeholder="请输入计费单位"/><el-input-number v-model="f.unitPrice" :min="0" placeholder="请输入单价" /><el-input-number v-model="f.minimumCharge" :min="0" placeholder="请输入最低收费" /><el-button type="danger" plain @click="form.warehouseFees.splice(i,1)">删除</el-button></div><h3>中转派送价格 <el-button @click="form.transitPrices.push({fbaWarehouseCode:'',deliveryMethod:'',estimatedMiles:null,price:0,minimumCharge:null,remark:null})">+ 添加派送价格</el-button></h3><div v-for="(t,i) in form.transitPrices" :key="i" class="line-grid"><el-input v-model="t.fbaWarehouseCode" placeholder="请输入目的 FBA 仓"/><el-input v-model="t.deliveryMethod" placeholder="请输入车型或提货方式"/><el-input-number v-model="t.price" :min="0" placeholder="请输入报价" /><el-input-number v-model="t.minimumCharge" :min="0" placeholder="请输入最低收费" /><el-button type="danger" plain @click="form.transitPrices.splice(i,1)">删除</el-button></div></el-form></AppDialog>
|
||||
</ListPageLayout></AdminPage></template>
|
||||
<style scoped>.table-panel{min-width:0;overflow:hidden}.form-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px 16px}.line-grid{display:grid;grid-template-columns:2fr 1.2fr 1fr 1fr auto;gap:8px;margin:8px 0}.detail-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1px;background:var(--cc-border);border:1px solid var(--cc-border)}.detail-grid>div{padding:12px;background:#fff}.detail-grid span{display:block;color:var(--cc-muted);font-size:12px}.detail-grid strong{display:block;margin-top:4px}h3{margin:18px 0 10px;font-size:14px}</style>
|
||||
|
||||
@@ -23,5 +23,5 @@ async function exportCsv(){exporting.value=true;try{const{page:_,size:__,...q}=p
|
||||
watch([page,pageSize],load);onMounted(load)
|
||||
</script>
|
||||
<template><AdminPage><ListPageLayout aria-label="车辆列表"><template #toolbar><div class="query-panel"><div class="status-tabs" role="tablist" aria-label="车辆归属"><button v-for="tab in tabs" :key="tab[1]" role="tab" :aria-selected="ownership===tab[1]" :class="['status-tab',{'is-active':ownership===tab[1]}]" @click="selectOwnership(tab[1])">{{tab[0]}}</button></div><QueryToolbar v-model="filters" :fields="fields" ariaLabel="车辆筛选" preference-key="overseas-vehicles-query" :loading="loading" @search="search"/></div></template><template #state><LoadErrorState v-if="error" title="车辆加载失败" :message="error.message" @retry="load"/></template><section class="surface-panel vehicle-panel"><DataTable v-model:page="page" v-model:page-size="pageSize" :data="rows" :columns="columns" :total="total" :loading="loading" preference-key="overseas-vehicles-table" row-key="id" empty-text="暂无车辆"><template #toolbar-actions><el-button v-if="access.can(permission.vehicleCreate)" type="primary" @click="openCreate"><Plus :size="16"/>添加车辆</el-button><el-button v-if="access.can(permission.vehicleExport)" :loading="exporting" @click="exportCsv"><Download :size="16"/>导出CSV</el-button></template><template #actions="{row}"><el-button link type="primary" @click="router.push({name:'overseas-master-data-vehicle-detail',params:{vehicleId:(row as VehicleDetail).id}})"><Eye :size="15"/>查看</el-button><el-button v-if="access.can(permission.vehicleEdit)" link type="primary" @click="openEdit(row as VehicleDetail)"><Pencil :size="15"/>编辑</el-button><el-button v-if="access.can(permission.vehicleStatus)" link type="primary" @click="openStatus(row as VehicleDetail)"><Power :size="15"/>状态</el-button></template><template #status="{row}"><el-tag>{{(row as VehicleDetail).status}}</el-tag></template><template #region="{row}">{{(row as VehicleDetail).region==='OVERSEAS'?'海外':'国内'}}</template></DataTable></section>
|
||||
<AppDialog v-model="editorOpen" :title="editingId?'编辑车辆':'添加车辆'" width="min(760px, calc(100vw - 28px))" :confirm-loading="saving" @confirm="save"><el-form label-position="top"><div class="form-grid"><el-form-item label="车辆归属"><el-select v-model="form.ownership"><el-option label="自有车辆" value="OWNED"/><el-option label="外派车辆" value="DISPATCHED"/></el-select></el-form-item><el-form-item label="车牌号"><el-input v-model="form.plateNumber"/></el-form-item><el-form-item label="车型"><el-input v-model="form.model"/></el-form-item><el-form-item label="油耗(L/100km)"><el-input-number v-model="form.fuelConsumptionPer100Km" :min="0.01" :precision="2"/></el-form-item><el-form-item label="当前公里码(km)"><el-input-number v-model="form.mileageKm" :min="0"/></el-form-item><el-form-item label="联系电话"><el-input v-model="form.phone"/></el-form-item><el-form-item label="司机 / 外派单位"><el-input v-model="form.driverOrDispatchCompany"/></el-form-item><el-form-item label="区域"><el-select v-model="form.region"><el-option label="国内" value="DOMESTIC"/><el-option label="海外" value="OVERSEAS"/></el-select></el-form-item><el-form-item v-if="!editingId" label="状态"><el-select v-model="form.status"><el-option v-for="s in ['IN_SERVICE','DISPATCHED','MAINTENANCE','INACTIVE','RETURNED']" :key="s" :label="s" :value="s"/></el-select></el-form-item><el-form-item label="备注"><el-input v-model="form.remark"/></el-form-item></div></el-form></AppDialog><AppDialog v-model="statusOpen" title="变更车辆状态" width="min(480px, calc(100vw - 28px))" :confirm-loading="saving" @confirm="submitStatus"><el-select v-model="statusTarget" style="width:100%"><el-option v-for="s in ['IN_SERVICE','DISPATCHED','MAINTENANCE','INACTIVE','RETURNED']" :key="s" :label="s" :value="s"/></el-select></AppDialog></ListPageLayout></AdminPage></template>
|
||||
<AppDialog v-model="editorOpen" :title="editingId?'编辑车辆':'添加车辆'" width="min(760px, calc(100vw - 28px))" :confirm-loading="saving" @confirm="save"><el-form label-position="top"><div class="form-grid"><el-form-item label="车辆归属"><el-select v-model="form.ownership"><el-option label="自有车辆" value="OWNED"/><el-option label="外派车辆" value="DISPATCHED"/></el-select></el-form-item><el-form-item label="车牌号"><el-input v-model="form.plateNumber" placeholder="请输入车牌号" /></el-form-item><el-form-item label="车型"><el-input v-model="form.model" placeholder="请输入车辆型号" /></el-form-item><el-form-item label="油耗(L/100km)"><el-input-number v-model="form.fuelConsumptionPer100Km" :min="0.01" :precision="2" placeholder="请输入百公里油耗" /></el-form-item><el-form-item label="当前公里码(km)"><el-input-number v-model="form.mileageKm" :min="0" placeholder="请输入当前里程" /></el-form-item><el-form-item label="联系电话"><el-input v-model="form.phone" placeholder="请输入联系电话" /></el-form-item><el-form-item label="司机 / 外派单位"><el-input v-model="form.driverOrDispatchCompany" placeholder="请输入司机或外派单位" /></el-form-item><el-form-item label="区域"><el-select v-model="form.region"><el-option label="国内" value="DOMESTIC"/><el-option label="海外" value="OVERSEAS"/></el-select></el-form-item><el-form-item v-if="!editingId" label="状态"><el-select v-model="form.status"><el-option v-for="s in ['IN_SERVICE','DISPATCHED','MAINTENANCE','INACTIVE','RETURNED']" :key="s" :label="s" :value="s"/></el-select></el-form-item><el-form-item label="备注"><el-input v-model="form.remark" placeholder="请输入备注(选填)" /></el-form-item></div></el-form></AppDialog><AppDialog v-model="statusOpen" title="变更车辆状态" width="min(480px, calc(100vw - 28px))" :confirm-loading="saving" @confirm="submitStatus"><el-select v-model="statusTarget" style="width:100%"><el-option v-for="s in ['IN_SERVICE','DISPATCHED','MAINTENANCE','INACTIVE','RETURNED']" :key="s" :label="s" :value="s"/></el-select></AppDialog></ListPageLayout></AdminPage></template>
|
||||
<style scoped>.vehicle-panel{min-width:0;overflow:hidden}.query-panel{overflow:hidden;border:1px solid var(--cc-border);border-radius:8px;background:#fff}.status-tabs{display:flex;border-bottom:1px solid var(--cc-border);background:#f9fafb}.status-tab{min-height:44px;padding:0 18px;border:0;background:transparent;color:var(--cc-muted)}.status-tab.is-active{border-bottom:3px solid var(--cc-primary);color:var(--cc-primary);font-weight:600}.form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}</style>
|
||||
|
||||
@@ -56,13 +56,13 @@ function openDetail(source: object) { const row = source as CartonListItem; void
|
||||
<el-col :span="12"><el-form-item label="所属 FBA 仓" required><el-select v-model="form.fbaWarehouse" placeholder="FBA仓候选接口待接入" disabled /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="商品 SKU" required><el-input v-model="form.sku" placeholder="请输入商品 SKU" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="中文品名" required><el-input v-model="form.productName" placeholder="请输入中文品名" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="数量" required><el-input-number v-model="form.quantity" :min="1" :precision="0" controls-position="right" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="重量(kg)" required><el-input-number v-model="form.weight" :min="0.01" :precision="2" controls-position="right" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="数量" required><el-input-number v-model="form.quantity" :min="1" :precision="0" controls-position="right" placeholder="请输入数量" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="重量(kg)" required><el-input-number v-model="form.weight" :min="0.01" :precision="2" controls-position="right" placeholder="请输入重量" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="关联托盘"><el-input v-model="form.palletNo" placeholder="请输入关联托盘号" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="关联入库单"><el-input v-model="form.inboundOrderNo" placeholder="请输入关联入库单号" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="关联出库单"><el-input v-model="form.outboundOrderNo" readonly /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="状态"><el-input v-model="form.status" readonly /></el-form-item></el-col>
|
||||
<el-col :span="24"><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="500" show-word-limit /></el-form-item></el-col>
|
||||
<el-col :span="24"><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请输入备注(选填)" /></el-form-item></el-col>
|
||||
</el-row></el-form>
|
||||
</ContractPendingFormDialog>
|
||||
</AdminPage>
|
||||
|
||||
@@ -219,7 +219,7 @@ onMounted(load)
|
||||
<template #status="{ row }"><StatusBadge :status="String((row as DispatchListItem).status || '—')" /></template>
|
||||
<template #pagination-left>共 {{ total }} 条排车记录</template>
|
||||
</DataTable></section>
|
||||
</ListPageLayout></AdminPage><AppDialog v-model="transferOpen" title="转派送" width="min(1120px, calc(100vw - 28px))" confirm-text="确认提交" :confirm-loading="transferSaving" @confirm="submitTransfer"><el-form label-position="top"><h3>派送信息</h3><div class="transfer-grid"><el-form-item label="排车单号"><el-input :model-value="transferRow?.dispatchNo" readonly /></el-form-item><el-form-item label="预计派送时间" required><el-date-picker v-model="transferForm.plannedDeliveryAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="请选择预计派送时间" /></el-form-item><el-form-item label="派送方式" required><el-select v-model="transferForm.deliveryMethod" placeholder="请选择"><el-option v-for="option in deliveryMethodOptions" :key="option.value" v-bind="option" /></el-select></el-form-item><el-form-item label="快递/车队"><el-input v-model="transferForm.carrierName" /></el-form-item><el-form-item label="运单号"><el-input v-model="transferForm.waybillNo" /></el-form-item><el-form-item label="提货方式" required><el-select v-model="transferForm.pickupMethod" placeholder="请选择"><el-option v-for="option in pickupMethodOptions" :key="option.value" v-bind="option" /></el-select></el-form-item><el-form-item label="装车类型" required><el-select v-model="transferForm.loadingType" placeholder="请选择"><el-option v-for="option in loadingTypeOptions" :key="option.value" v-bind="option" /></el-select></el-form-item><el-form-item label="司机/车队名称"><el-input v-model="transferForm.driverName" /></el-form-item><el-form-item label="联系电话"><el-input v-model="transferForm.driverPhone" /></el-form-item><el-form-item label="车牌号"><el-input v-model="transferForm.vehiclePlate" /></el-form-item><el-form-item label="车辆类型"><el-select v-model="transferForm.vehicleType" clearable placeholder="请选择"><el-option v-for="option in vehicleTypeOptions" :key="option.value" v-bind="option" /></el-select></el-form-item><el-form-item label="车辆大小"><el-select v-model="transferForm.vehicleSize" clearable placeholder="请选择"><el-option v-for="option in vehicleSizeOptions" :key="option.value" v-bind="option" /></el-select></el-form-item><el-form-item label="预约账号"><el-select v-model="transferForm.appointmentAccount" clearable placeholder="请选择"><el-option v-for="option in appointmentAccountOptions" :key="option.value" v-bind="option" /></el-select></el-form-item><el-form-item v-if="isBuyAppointment" label="卖家姓名" required><el-input v-model="transferForm.sellerName" placeholder="请输入卖家姓名" /></el-form-item></div><h3>费用信息(USD)</h3><div class="transfer-grid"><el-form-item label="派送费用" required><el-input-number v-model="transferForm.deliveryFee" :min="0" :precision="2" controls-position="right" placeholder="请输入派送费用" /></el-form-item><el-form-item v-if="needsLoadingFee" label="装车费" required><el-input-number v-model="transferForm.loadingFee" :min="0" :precision="2" controls-position="right" placeholder="请输入装车费" /></el-form-item><el-form-item v-if="isBuyAppointment" label="买约费用" required><el-input-number v-model="transferForm.appointmentFee" :min="0" :precision="2" controls-position="right" placeholder="请输入买约费用" /></el-form-item></div><el-form-item label="备注"><el-input v-model="transferForm.remark" type="textarea" :rows="3" /></el-form-item><el-alert title="费用不会自动带出,请手工填写后提交;提交后将生成待出库单、待派送单,并保存费用明细" type="info" :closable="false" /></el-form></AppDialog>
|
||||
<AppDialog v-model="editOpen" title="编辑排车" width="min(900px, calc(100vw - 48px))" confirm-text="保存" :confirm-loading="editSaving" @confirm="submitEdit"><el-alert :title="`当前状态:${editRow?.status || '—'};普通编辑不会修改排车状态。`" type="info" :closable="false" /><el-form label-position="top"><div class="edit-grid"><el-form-item label="车牌号"><el-input v-model="editForm.vehiclePlate" /></el-form-item><el-form-item label="司机"><el-input v-model="editForm.driverName" /></el-form-item><el-form-item label="联系电话"><el-input v-model="editForm.driverPhone" /></el-form-item><el-form-item label="拖车公司名称"><el-input v-model="editForm.carrierName" /></el-form-item><el-form-item label="路线"><el-input v-model="editForm.route" /></el-form-item><el-form-item label="发车时间"><el-date-picker v-model="editForm.departAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" /></el-form-item><el-form-item label="预计到达时间"><el-date-picker v-model="editForm.estimatedArrivalAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" /></el-form-item><el-form-item label="FBA预约号"><el-input v-model="editForm.fbaAppointmentNo" /></el-form-item><el-form-item label="FBA预约状态"><el-select v-model="editForm.fbaAppointmentStatus" clearable><el-option label="待预约" value="PENDING" /><el-option label="已预约" value="BOOKED" /><el-option label="已确认" value="CONFIRMED" /><el-option label="已取消" value="CANCELLED" /></el-select></el-form-item><el-form-item label="车辆预约状态"><el-select v-model="editForm.vehicleAppointmentStatus" clearable><el-option label="待预约" value="PENDING" /><el-option label="已预约" value="BOOKED" /><el-option label="已确认" value="CONFIRMED" /><el-option label="已取消" value="CANCELLED" /></el-select></el-form-item></div></el-form></AppDialog>
|
||||
</ListPageLayout></AdminPage><AppDialog v-model="transferOpen" title="转派送" width="min(1120px, calc(100vw - 28px))" confirm-text="确认提交" :confirm-loading="transferSaving" @confirm="submitTransfer"><el-form label-position="top"><h3>派送信息</h3><div class="transfer-grid"><el-form-item label="排车单号"><el-input :model-value="transferRow?.dispatchNo" readonly /></el-form-item><el-form-item label="预计派送时间" required><el-date-picker v-model="transferForm.plannedDeliveryAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="请选择预计派送时间" /></el-form-item><el-form-item label="派送方式" required><el-select v-model="transferForm.deliveryMethod" placeholder="请选择"><el-option v-for="option in deliveryMethodOptions" :key="option.value" v-bind="option" /></el-select></el-form-item><el-form-item label="快递/车队"><el-input v-model="transferForm.carrierName" placeholder="请输入快递或车队名称" /></el-form-item><el-form-item label="运单号"><el-input v-model="transferForm.waybillNo" placeholder="请输入运单号" /></el-form-item><el-form-item label="提货方式" required><el-select v-model="transferForm.pickupMethod" placeholder="请选择"><el-option v-for="option in pickupMethodOptions" :key="option.value" v-bind="option" /></el-select></el-form-item><el-form-item label="装车类型" required><el-select v-model="transferForm.loadingType" placeholder="请选择"><el-option v-for="option in loadingTypeOptions" :key="option.value" v-bind="option" /></el-select></el-form-item><el-form-item label="司机/车队名称"><el-input v-model="transferForm.driverName" placeholder="请输入司机或车队名称" /></el-form-item><el-form-item label="联系电话"><el-input v-model="transferForm.driverPhone" placeholder="请输入联系电话" /></el-form-item><el-form-item label="车牌号"><el-input v-model="transferForm.vehiclePlate" placeholder="请输入车牌号" /></el-form-item><el-form-item label="车辆类型"><el-select v-model="transferForm.vehicleType" clearable placeholder="请选择"><el-option v-for="option in vehicleTypeOptions" :key="option.value" v-bind="option" /></el-select></el-form-item><el-form-item label="车辆大小"><el-select v-model="transferForm.vehicleSize" clearable placeholder="请选择"><el-option v-for="option in vehicleSizeOptions" :key="option.value" v-bind="option" /></el-select></el-form-item><el-form-item label="预约账号"><el-select v-model="transferForm.appointmentAccount" clearable placeholder="请选择"><el-option v-for="option in appointmentAccountOptions" :key="option.value" v-bind="option" /></el-select></el-form-item><el-form-item v-if="isBuyAppointment" label="卖家姓名" required><el-input v-model="transferForm.sellerName" placeholder="请输入卖家姓名" /></el-form-item></div><h3>费用信息(USD)</h3><div class="transfer-grid"><el-form-item label="派送费用" required><el-input-number v-model="transferForm.deliveryFee" :min="0" :precision="2" controls-position="right" placeholder="请输入派送费用" /></el-form-item><el-form-item v-if="needsLoadingFee" label="装车费" required><el-input-number v-model="transferForm.loadingFee" :min="0" :precision="2" controls-position="right" placeholder="请输入装车费" /></el-form-item><el-form-item v-if="isBuyAppointment" label="买约费用" required><el-input-number v-model="transferForm.appointmentFee" :min="0" :precision="2" controls-position="right" placeholder="请输入买约费用" /></el-form-item></div><el-form-item label="备注"><el-input v-model="transferForm.remark" type="textarea" :rows="3" placeholder="请输入派送备注(选填)" /></el-form-item><el-alert title="费用不会自动带出,请手工填写后提交;提交后将生成待出库单、待派送单,并保存费用明细" type="info" :closable="false" /></el-form></AppDialog>
|
||||
<AppDialog v-model="editOpen" title="编辑排车" width="min(900px, calc(100vw - 48px))" confirm-text="保存" :confirm-loading="editSaving" @confirm="submitEdit"><el-alert :title="`当前状态:${editRow?.status || '—'};普通编辑不会修改排车状态。`" type="info" :closable="false" /><el-form label-position="top"><div class="edit-grid"><el-form-item label="车牌号"><el-input v-model="editForm.vehiclePlate" placeholder="请输入车牌号" /></el-form-item><el-form-item label="司机"><el-input v-model="editForm.driverName" placeholder="请输入司机姓名" /></el-form-item><el-form-item label="联系电话"><el-input v-model="editForm.driverPhone" placeholder="请输入联系电话" /></el-form-item><el-form-item label="拖车公司名称"><el-input v-model="editForm.carrierName" placeholder="请输入拖车公司名称" /></el-form-item><el-form-item label="路线"><el-input v-model="editForm.route" placeholder="请输入运输路线" /></el-form-item><el-form-item label="发车时间"><el-date-picker v-model="editForm.departAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" /></el-form-item><el-form-item label="预计到达时间"><el-date-picker v-model="editForm.estimatedArrivalAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" /></el-form-item><el-form-item label="FBA预约号"><el-input v-model="editForm.fbaAppointmentNo" placeholder="请输入 FBA 预约号" /></el-form-item><el-form-item label="FBA预约状态"><el-select v-model="editForm.fbaAppointmentStatus" clearable><el-option label="待预约" value="PENDING" /><el-option label="已预约" value="BOOKED" /><el-option label="已确认" value="CONFIRMED" /><el-option label="已取消" value="CANCELLED" /></el-select></el-form-item><el-form-item label="车辆预约状态"><el-select v-model="editForm.vehicleAppointmentStatus" clearable><el-option label="待预约" value="PENDING" /><el-option label="已预约" value="BOOKED" /><el-option label="已确认" value="CONFIRMED" /><el-option label="已取消" value="CANCELLED" /></el-select></el-form-item></div></el-form></AppDialog>
|
||||
</template>
|
||||
<style scoped>.transfer-grid,.edit-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0 16px}.transfer-grid :deep(.el-select),.transfer-grid :deep(.el-date-editor),.transfer-grid :deep(.el-input-number),.edit-grid :deep(.el-select),.edit-grid :deep(.el-date-editor){width:100%}h3{margin:4px 0 12px}@media(max-width:900px){.transfer-grid,.edit-grid{grid-template-columns:1fr}}</style>
|
||||
|
||||
@@ -94,9 +94,9 @@ onMounted(load)
|
||||
<el-form-item label="尾程订单号"><el-input v-model="form.lastMileOrderNo" placeholder="请输入尾程订单号" @blur="resolveRelation" /></el-form-item>
|
||||
<el-form-item label="异常类型" required><el-select v-model="form.exceptionType" placeholder="请选择异常类型"><el-option v-for="(label, value) in typeLabels" :key="value" :label="label" :value="value" /></el-select></el-form-item>
|
||||
<el-form-item label="处理状态"><el-input model-value="待处理" readonly /></el-form-item>
|
||||
<el-form-item label="箱数"><el-input-number v-model="form.packageCount" :min="1" :max="relation?.availablePackages || 999999" /></el-form-item>
|
||||
<el-form-item label="SKU(可自由填写)"><el-input v-model="form.skuCode" maxlength="128" /></el-form-item>
|
||||
</div><el-form-item label="异常原因" required><el-input v-model="form.reason" type="textarea" :rows="4" maxlength="1000" show-word-limit /></el-form-item>
|
||||
<el-form-item label="箱数"><el-input-number v-model="form.packageCount" :min="1" :max="relation?.availablePackages || 999999" placeholder="请输入箱数" /></el-form-item>
|
||||
<el-form-item label="SKU(可自由填写)"><el-input v-model="form.skuCode" maxlength="128" placeholder="请输入 SKU(选填)" /></el-form-item>
|
||||
</div><el-form-item label="异常原因" required><el-input v-model="form.reason" type="textarea" :rows="4" maxlength="1000" show-word-limit placeholder="请输入异常原因" /></el-form-item>
|
||||
<el-alert v-if="relation" type="success" :closable="false"><template #title><span class="relation-alert-title">已关联:<OrderReferenceText :value="relation.lastMileOrderNo || '无尾程单'" /> / {{ relation.inboundCode || '无入仓单' }},客户 {{ relation.customerName || '客户信息待补充' }}</span></template></el-alert>
|
||||
<el-alert v-else-if="relationError" :title="relationError" type="error" :closable="false" />
|
||||
</el-form>
|
||||
|
||||
@@ -176,7 +176,7 @@ onMounted(load)
|
||||
<el-col :span="12"><el-form-item label="费用项目" required><el-input v-model="feeForm.item" maxlength="128" placeholder="如 派送费" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="供应商/说明"><el-input v-model="feeForm.description" maxlength="500" placeholder="请输入供应商或费用说明" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="币种" required><el-select v-model="feeForm.currency"><el-option v-for="currency in ['USD', 'CNY', 'EUR', 'GBP', 'CAD', 'MXN']" :key="currency" :label="currency" :value="currency" /></el-select></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="金额" required><el-input-number v-model="feeForm.amount" :min="0" :precision="2" :step="10" controls-position="right" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="金额" required><el-input-number v-model="feeForm.amount" :min="0" :precision="2" :step="10" controls-position="right" placeholder="请输入费用金额" /></el-form-item></el-col>
|
||||
<el-col :span="24"><el-form-item label="状态" required><el-select v-model="feeForm.status"><el-option label="待审核" value="PENDING_REVIEW" /><el-option label="审核通过" value="APPROVED" /><el-option label="已驳回" value="REJECTED" /></el-select></el-form-item></el-col>
|
||||
</el-row></el-form>
|
||||
</AppDialog>
|
||||
|
||||
@@ -55,10 +55,10 @@ function openDetail(source: object) { const row = source as ProductListItem; voi
|
||||
<el-form-item label="中文品名" required><el-input v-model="form.productName" placeholder="请输入中文品名" /></el-form-item>
|
||||
<el-form-item label="英文品名"><el-input v-model="form.englishName" placeholder="请输入英文品名" /></el-form-item>
|
||||
<el-form-item label="品类" required><el-select v-model="form.category" placeholder="请选择品类"><el-option v-for="value in ['电子', '家居', '服饰', '户外']" :key="value" :label="value" :value="value" /></el-select></el-form-item>
|
||||
<el-form-item label="长(cm)"><el-input-number v-model="form.length" :min="0" :precision="2" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="宽(cm)"><el-input-number v-model="form.width" :min="0" :precision="2" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="高(cm)"><el-input-number v-model="form.height" :min="0" :precision="2" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="重量(kg)"><el-input-number v-model="form.weight" :min="0" :precision="3" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="长(cm)"><el-input-number v-model="form.length" :min="0" :precision="2" controls-position="right" placeholder="请输入长度" /></el-form-item>
|
||||
<el-form-item label="宽(cm)"><el-input-number v-model="form.width" :min="0" :precision="2" controls-position="right" placeholder="请输入宽度" /></el-form-item>
|
||||
<el-form-item label="高(cm)"><el-input-number v-model="form.height" :min="0" :precision="2" controls-position="right" placeholder="请输入高度" /></el-form-item>
|
||||
<el-form-item label="重量(kg)"><el-input-number v-model="form.weight" :min="0" :precision="3" controls-position="right" placeholder="请输入重量" /></el-form-item>
|
||||
</el-form>
|
||||
</ContractPendingFormDialog>
|
||||
</AdminPage>
|
||||
|
||||
@@ -336,14 +336,14 @@ onMounted(() => void load())
|
||||
</template>
|
||||
<el-form-item label="业务发生日" prop="businessDate"><el-date-picker v-model="form.businessDate" type="date" value-format="YYYY-MM-DD" /></el-form-item>
|
||||
<el-form-item label="货币" prop="currency"><el-input model-value="CNY" readonly aria-label="货币 CNY" /></el-form-item>
|
||||
<el-form-item label="单价" prop="unitPrice"><el-input-number v-model="form.unitPrice" :min="0" :precision="4" /></el-form-item>
|
||||
<el-form-item label="金额" prop="amount"><el-input-number v-model="form.amount" :min="0" :precision="2" /></el-form-item>
|
||||
<el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="500" show-word-limit /></el-form-item>
|
||||
<el-form-item label="单价" prop="unitPrice"><el-input-number v-model="form.unitPrice" :min="0" :precision="4" placeholder="请输入单价" /></el-form-item>
|
||||
<el-form-item label="金额" prop="amount"><el-input-number v-model="form.amount" :min="0" :precision="2" placeholder="请输入金额" /></el-form-item>
|
||||
<el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请输入备注(选填)" /></el-form-item>
|
||||
</el-form>
|
||||
</AppDialog>
|
||||
<AppDialog v-model="rejectOpen" title="驳回费用" :confirm-loading="saving" confirm-text="确认驳回" confirm-type="warning" @confirm="reject">
|
||||
<el-alert v-if="actionError" type="error" :closable="true" @close="actionError = null"><template #title>{{ actionError.message }}</template><ApiErrorMeta :details="actionError" /></el-alert>
|
||||
<el-form label-position="top"><el-form-item label="驳回原因" required><el-input v-model="rejectReason" type="textarea" :rows="4" maxlength="500" show-word-limit /></el-form-item></el-form>
|
||||
<el-form label-position="top"><el-form-item label="驳回原因" required><el-input v-model="rejectReason" type="textarea" :rows="4" maxlength="500" show-word-limit placeholder="请输入驳回原因" /></el-form-item></el-form>
|
||||
</AppDialog>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -250,9 +250,9 @@ async function save() {
|
||||
<el-row :gutter="14">
|
||||
<el-col :span="7"><el-form-item label="渠道名称" required><el-select v-model="form.channelCode" aria-label="渠道名称" filterable clearable :loading="channelsLoading" placeholder="请选择正式渠道" @change="selectChannel"><el-option v-for="channel in channels" :key="channel.channelCode" :label="`${channel.channelName} · ${channel.channelCode}`" :value="channel.channelCode" /></el-select></el-form-item></el-col>
|
||||
<el-col :span="4"><el-form-item label="渠道编码"><el-input :model-value="form.channelCode" readonly aria-label="渠道编码" /></el-form-item></el-col>
|
||||
<el-col :span="4"><el-form-item label="预估体积(m³)"><el-input-number v-model="form.estimatedVolumeCbm" :min="0.0001" :precision="4" :controls="false" /></el-form-item></el-col>
|
||||
<el-col :span="4"><el-form-item label="预估体积(m³)"><el-input-number v-model="form.estimatedVolumeCbm" :min="0.0001" :precision="4" :controls="false" placeholder="请输入预估体积(选填)" /></el-form-item></el-col>
|
||||
<el-col :span="5"><el-form-item label="预计到货时间"><el-date-picker v-model="form.expectedArrivalAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" format="YYYY-MM-DD HH:mm" clearable /></el-form-item></el-col>
|
||||
<el-col :span="4"><el-form-item label="客户备注"><el-input v-model="form.customerRemark" maxlength="1000" show-word-limit /></el-form-item></el-col>
|
||||
<el-col :span="4"><el-form-item label="客户备注"><el-input v-model="form.customerRemark" maxlength="1000" show-word-limit placeholder="请输入客户备注(选填)" /></el-form-item></el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
@@ -273,28 +273,28 @@ async function save() {
|
||||
|
||||
<AppDialog v-model="cargoEditorOpen" title="编辑货品申报" width="min(980px, calc(100vw - 36px))" confirm-text="应用本项" :close-on-click-modal="false" @confirm="applyCargo">
|
||||
<div v-if="cargoDraft" class="cargo-editor-grid">
|
||||
<label><span>中文品名 *</span><el-input v-model="cargoDraft.cargoName" maxlength="128" /></label>
|
||||
<label><span>英文品名</span><el-input v-model="cargoDraft.cargoNameEn" maxlength="128" /></label>
|
||||
<label><span>SKU NO.</span><el-input v-model="cargoDraft.skuNo" maxlength="64" /></label>
|
||||
<label><span>型号</span><el-input v-model="cargoDraft.model" maxlength="64" /></label>
|
||||
<label><span>箱数 *</span><el-input-number v-model="cargoDraft.packageCount" :min="1" :precision="0" controls-position="right" /></label>
|
||||
<label><span>总数量 *</span><el-input-number v-model="cargoDraft.totalQuantity" :min="1" :precision="0" controls-position="right" /></label>
|
||||
<label><span>每箱数量</span><el-input-number v-model="cargoDraft.unitsPerPackage" :min="1" :precision="0" controls-position="right" /></label>
|
||||
<label><span>中文品名 *</span><el-input v-model="cargoDraft.cargoName" maxlength="128" placeholder="请输入中文品名" /></label>
|
||||
<label><span>英文品名</span><el-input v-model="cargoDraft.cargoNameEn" maxlength="128" placeholder="请输入英文品名(选填)" /></label>
|
||||
<label><span>SKU NO.</span><el-input v-model="cargoDraft.skuNo" maxlength="64" placeholder="请输入 SKU(选填)" /></label>
|
||||
<label><span>型号</span><el-input v-model="cargoDraft.model" maxlength="64" placeholder="请输入型号(选填)" /></label>
|
||||
<label><span>箱数 *</span><el-input-number v-model="cargoDraft.packageCount" :min="1" :precision="0" controls-position="right" placeholder="请输入箱数" /></label>
|
||||
<label><span>总数量 *</span><el-input-number v-model="cargoDraft.totalQuantity" :min="1" :precision="0" controls-position="right" placeholder="请输入总数量" /></label>
|
||||
<label><span>每箱数量</span><el-input-number v-model="cargoDraft.unitsPerPackage" :min="1" :precision="0" controls-position="right" placeholder="请输入每箱数量(选填)" /></label>
|
||||
<label><span>币种</span><el-input :model-value="cargoDraft.currency || '—'" readonly aria-label="币种" /></label>
|
||||
<label><span>长(cm) *</span><el-input-number v-model="cargoDraft.lengthCm" :min="0.01" :precision="2" controls-position="right" /></label>
|
||||
<label><span>宽(cm) *</span><el-input-number v-model="cargoDraft.widthCm" :min="0.01" :precision="2" controls-position="right" /></label>
|
||||
<label><span>高(cm) *</span><el-input-number v-model="cargoDraft.heightCm" :min="0.01" :precision="2" controls-position="right" /></label>
|
||||
<label><span>体积(m³) *</span><el-input-number v-model="cargoDraft.volumeCbm" :min="0.0001" :precision="4" controls-position="right" /></label>
|
||||
<label><span>毛重(kg) *</span><el-input-number v-model="cargoDraft.grossWeightKg" :min="0.001" :precision="3" controls-position="right" /></label>
|
||||
<label><span>净重(kg)</span><el-input-number v-model="cargoDraft.netWeightKg" :min="0.001" :precision="3" controls-position="right" /></label>
|
||||
<label><span>单价</span><el-input-number v-model="cargoDraft.unitDeclaredValue" :min="0" :precision="2" controls-position="right" /></label>
|
||||
<label><span>申报总价</span><el-input-number v-model="cargoDraft.declaredValue" :min="0" :precision="2" controls-position="right" /></label>
|
||||
<label><span>报关 HS CODE</span><el-input v-model="cargoDraft.hsCode" maxlength="20" /></label>
|
||||
<label><span>清关 HS CODE</span><el-input v-model="cargoDraft.customsHsCode" maxlength="20" /></label>
|
||||
<label><span>材质</span><el-input v-model="cargoDraft.material" maxlength="128" /></label>
|
||||
<label><span>用途</span><el-input v-model="cargoDraft.usage" maxlength="128" /></label>
|
||||
<label><span>品牌</span><el-input v-model="cargoDraft.brand" maxlength="64" /></label>
|
||||
<label class="wide"><span>货品备注</span><el-input v-model="cargoDraft.cargoRemark" maxlength="500" /></label>
|
||||
<label><span>长(cm) *</span><el-input-number v-model="cargoDraft.lengthCm" :min="0.01" :precision="2" controls-position="right" placeholder="请输入长度" /></label>
|
||||
<label><span>宽(cm) *</span><el-input-number v-model="cargoDraft.widthCm" :min="0.01" :precision="2" controls-position="right" placeholder="请输入宽度" /></label>
|
||||
<label><span>高(cm) *</span><el-input-number v-model="cargoDraft.heightCm" :min="0.01" :precision="2" controls-position="right" placeholder="请输入高度" /></label>
|
||||
<label><span>体积(m³) *</span><el-input-number v-model="cargoDraft.volumeCbm" :min="0.0001" :precision="4" controls-position="right" placeholder="请输入体积" /></label>
|
||||
<label><span>毛重(kg) *</span><el-input-number v-model="cargoDraft.grossWeightKg" :min="0.001" :precision="3" controls-position="right" placeholder="请输入毛重" /></label>
|
||||
<label><span>净重(kg)</span><el-input-number v-model="cargoDraft.netWeightKg" :min="0.001" :precision="3" controls-position="right" placeholder="请输入净重(选填)" /></label>
|
||||
<label><span>单价</span><el-input-number v-model="cargoDraft.unitDeclaredValue" :min="0" :precision="2" controls-position="right" placeholder="请输入申报单价(选填)" /></label>
|
||||
<label><span>申报总价</span><el-input-number v-model="cargoDraft.declaredValue" :min="0" :precision="2" controls-position="right" placeholder="请输入申报总价(选填)" /></label>
|
||||
<label><span>报关 HS CODE</span><el-input v-model="cargoDraft.hsCode" maxlength="20" placeholder="请输入报关 HS CODE(选填)" /></label>
|
||||
<label><span>清关 HS CODE</span><el-input v-model="cargoDraft.customsHsCode" maxlength="20" placeholder="请输入清关 HS CODE(选填)" /></label>
|
||||
<label><span>材质</span><el-input v-model="cargoDraft.material" maxlength="128" placeholder="请输入材质(选填)" /></label>
|
||||
<label><span>用途</span><el-input v-model="cargoDraft.usage" maxlength="128" placeholder="请输入用途(选填)" /></label>
|
||||
<label><span>品牌</span><el-input v-model="cargoDraft.brand" maxlength="64" placeholder="请输入品牌(选填)" /></label>
|
||||
<label class="wide"><span>货品备注</span><el-input v-model="cargoDraft.cargoRemark" maxlength="500" placeholder="请输入货品备注(选填)" /></label>
|
||||
</div>
|
||||
</AppDialog>
|
||||
</template>
|
||||
|
||||
@@ -1817,8 +1817,8 @@ onBeforeUnmount(() => {
|
||||
<el-form label-position="top" class="fee-confirm-form">
|
||||
<el-form-item label="入仓码"><el-input :model-value="detail?.summary.inboundCode || '—'" disabled /></el-form-item>
|
||||
<el-form-item label="渠道"><el-input :model-value="detail?.summary.channelName || detail?.summary.channelCode || '—'" disabled /></el-form-item>
|
||||
<el-form-item label="计费毛重"><div class="fee-confirm-number-wrap"><el-input-number v-model="feeConfirmWeight" :min="0" :precision="3" :controls="false" class="fee-confirm-number" /><span class="fee-confirm-unit">kg</span></div></el-form-item>
|
||||
<el-form-item label="计费体积"><div class="fee-confirm-number-wrap"><el-input-number v-model="feeConfirmVolume" :min="0" :precision="6" :controls="false" class="fee-confirm-number" /><span class="fee-confirm-unit">m³</span></div></el-form-item>
|
||||
<el-form-item label="计费毛重"><div class="fee-confirm-number-wrap"><el-input-number v-model="feeConfirmWeight" :min="0" :precision="3" :controls="false" class="fee-confirm-number" placeholder="请输入计费毛重" /><span class="fee-confirm-unit">kg</span></div></el-form-item>
|
||||
<el-form-item label="计费体积"><div class="fee-confirm-number-wrap"><el-input-number v-model="feeConfirmVolume" :min="0" :precision="6" :controls="false" class="fee-confirm-number" placeholder="请输入计费体积" /><span class="fee-confirm-unit">m³</span></div></el-form-item>
|
||||
</el-form>
|
||||
<h4 class="fee-confirm-reference-title">参考数据</h4>
|
||||
<el-table :data="feeConfirmRows" border size="small">
|
||||
|
||||
@@ -321,13 +321,13 @@ onMounted(() => { void load() })
|
||||
|
||||
<AppDialog v-model="assignOpen" title="加入装柜方案" :confirm-loading="action === 'assign'" :confirm-disabled="packageCount < 1 || packageCount > (selectedCandidate ? fittingCount(selectedCandidate) : 0)" confirm-text="确认加入" @confirm="confirmAssign">
|
||||
<p>{{ selectedCandidate?.inboundCode || '入仓码暂缺' }} · 最多可加入 {{ selectedCandidate ? fittingCount(selectedCandidate) : 0 }} 箱</p>
|
||||
<el-input-number v-model="packageCount" :min="1" :max="selectedCandidate ? fittingCount(selectedCandidate) : 1" controls-position="right" aria-label="加入箱数" />
|
||||
<el-input-number v-model="packageCount" :min="1" :max="selectedCandidate ? fittingCount(selectedCandidate) : 1" controls-position="right" aria-label="加入箱数" placeholder="请输入箱数" />
|
||||
<ApiErrorMeta v-if="actionError" :details="actionError" />
|
||||
</AppDialog>
|
||||
|
||||
<AppDialog v-model="adjustOpen" title="调整装柜箱数" :confirm-loading="action === 'adjust'" :confirm-disabled="packageCount < 1" confirm-text="保存调整" @confirm="confirmAdjust">
|
||||
<p>{{ selectedItem?.inboundCode || '入仓码暂缺' }} · 当前 {{ selectedItem?.packageCount || 0 }} 箱</p>
|
||||
<el-input-number v-model="packageCount" :min="1" controls-position="right" aria-label="调整后箱数" />
|
||||
<el-input-number v-model="packageCount" :min="1" controls-position="right" aria-label="调整后箱数" placeholder="请输入箱数" />
|
||||
<ApiErrorMeta v-if="actionError" :details="actionError" />
|
||||
</AppDialog>
|
||||
|
||||
|
||||
@@ -545,10 +545,10 @@ onMounted(() => { void refresh() })
|
||||
<el-input v-model="preloadDraft.cargoReference" maxlength="128" placeholder="入仓码或业务引用" @input="preloadDraftError = ''" />
|
||||
</el-form-item>
|
||||
<div class="preload-dialog-grid">
|
||||
<el-form-item label="箱数" required><el-input-number v-model="preloadDraft.packageCount" :min="1" :step="1" step-strictly controls-position="right" @change="preloadDraftError = ''" /></el-form-item>
|
||||
<el-form-item label="体积(m³)"><el-input-number v-model="preloadDraft.volumeCbm" :min="0" :precision="3" controls-position="right" @change="preloadDraftError = ''" /></el-form-item>
|
||||
<el-form-item label="箱数" required><el-input-number v-model="preloadDraft.packageCount" :min="1" :step="1" step-strictly controls-position="right" @change="preloadDraftError = ''" placeholder="请输入计划装柜箱数" /></el-form-item>
|
||||
<el-form-item label="体积(m³)"><el-input-number v-model="preloadDraft.volumeCbm" :min="0" :precision="3" controls-position="right" @change="preloadDraftError = ''" placeholder="请输入计划体积(选填)" /></el-form-item>
|
||||
</div>
|
||||
<el-form-item label="明细备注"><el-input v-model="preloadDraft.remark" type="textarea" :rows="3" maxlength="500" show-word-limit /></el-form-item>
|
||||
<el-form-item label="明细备注"><el-input v-model="preloadDraft.remark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请输入明细备注(选填)" /></el-form-item>
|
||||
<el-alert v-if="preloadDraftError" type="error" :closable="false" show-icon>{{ preloadDraftError }}</el-alert>
|
||||
</el-form>
|
||||
</AppDialog>
|
||||
|
||||
@@ -441,10 +441,10 @@ onMounted(() => {
|
||||
</div>
|
||||
<div class="editor-field-grid">
|
||||
<el-form-item label="托盘容积(m³)" prop="capacityCbm" required>
|
||||
<el-input-number v-model="form.capacityCbm" :min="0.000001" :max="999999999999.999999" :precision="6" :step="0.1" controls-position="right" aria-label="托盘容积" />
|
||||
<el-input-number v-model="form.capacityCbm" :min="0.000001" :max="999999999999.999999" :precision="6" :step="0.1" controls-position="right" aria-label="托盘容积" placeholder="请输入托盘容积" />
|
||||
</el-form-item>
|
||||
<el-form-item label="托盘重量(kg)" prop="weightKg" required>
|
||||
<el-input-number v-model="form.weightKg" :min="0.001" :max="999999999999999.999" :precision="3" :step="0.5" controls-position="right" aria-label="托盘重量" />
|
||||
<el-input-number v-model="form.weightKg" :min="0.001" :max="999999999999999.999" :precision="3" :step="0.5" controls-position="right" aria-label="托盘重量" placeholder="请输入托盘重量" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="editor-field-grid">
|
||||
|
||||
Reference in New Issue
Block a user