feat: 官网海洋蓝波浪首页与指南分受众,并同步业务页优化 #9
@ -1058,6 +1058,8 @@ export default {
|
||||
'order.platformStoreOrder.createLogistics.tip': 'Review recipient and line items for each order, then confirm the shipping product before submitting.',
|
||||
'order.platformStoreOrder.createLogistics.product': 'Shipping Product',
|
||||
'order.platformStoreOrder.createLogistics.productRequired': 'Please select a shipping product',
|
||||
'order.platformStoreOrder.createLogistics.basicRequired':
|
||||
'Please complete waybill basic info (warehouse, cargo type, weight, dimensions, inbound method, etc.)',
|
||||
'order.platformStoreOrder.createLogistics.orderList': 'Selected Orders',
|
||||
'order.platformStoreOrder.createLogistics.receiverTitle': 'Recipient Check',
|
||||
'order.platformStoreOrder.createLogistics.linesTitle': 'Line Items',
|
||||
|
||||
@ -1047,6 +1047,7 @@ export default {
|
||||
'order.platformStoreOrder.createLogistics.tip': '请逐单核对收件人与商品明细,确认运输方式后再提交,避免下错单。',
|
||||
'order.platformStoreOrder.createLogistics.product': '运输方式',
|
||||
'order.platformStoreOrder.createLogistics.productRequired': '请选择运输方式',
|
||||
'order.platformStoreOrder.createLogistics.basicRequired': '请完整填写运单基本信息(仓库、货物属性、实重、长宽高、到仓方式等)',
|
||||
'order.platformStoreOrder.createLogistics.orderList': '待创建清单',
|
||||
'order.platformStoreOrder.createLogistics.receiverTitle': '收件人校对',
|
||||
'order.platformStoreOrder.createLogistics.linesTitle': '商品明细',
|
||||
|
||||
@ -13,13 +13,33 @@ import {
|
||||
postOrderStockBindInventoryCandidates,
|
||||
postOrderStockBindParcelCandidates,
|
||||
} from '@/api/order'
|
||||
import { getSenderAddressList } from '@/api/order/senderAddress'
|
||||
import { getExportQualificationList } from '@/api/customer/exportQualification'
|
||||
import { getDictListAll } from '@/api/system/dict'
|
||||
import { resolveOmsAssetUrl } from '@/api/oms/common'
|
||||
import SlidingTabs from '@/components/SlidingTabs/index.vue'
|
||||
import { $baseMessage } from '@/utils'
|
||||
import { normalizeCargoAttributeCode } from '@/utils/cargoAttribute'
|
||||
import { normalizeListRow, pickField } from '@/utils/warehouseListMapper'
|
||||
|
||||
import type { CreateLogisticsMode } from './constants'
|
||||
|
||||
type SelectOption = { label: string; value: string }
|
||||
type QualOption = { id: number; label: string; isDefault: boolean }
|
||||
|
||||
const SAMPLE_EXPORT_CUSTOMS_MODE_CODE = '9610Simple'
|
||||
const EXPORT_CUSTOMS_MODE_9610_SUMMARY = '9610Summary'
|
||||
const AGREEMENT_TEXT = `《物流下单用户协议》及《物流服务赔偿协议》
|
||||
|
||||
一、服务说明
|
||||
您确认通过本系统创建的运单/代发订单,将按所选运输方式、仓库与件重尺计费并履约。
|
||||
|
||||
二、责任与理赔
|
||||
请以正式协议文本为准;勾选即视为已阅读并同意全部条款。
|
||||
|
||||
三、勾选确认
|
||||
本人已仔细阅读并充分理解全部条款,自愿接受本协议所有约定。`
|
||||
|
||||
export type { CreateLogisticsMode }
|
||||
|
||||
export type BindDraftItem = {
|
||||
@ -43,6 +63,8 @@ type OrderDraft = {
|
||||
customerId?: number
|
||||
warehouseId?: number
|
||||
platformOrderNo: string
|
||||
/** 可编辑客户单号,默认平台订单号 */
|
||||
clientNo: string
|
||||
orderCountry: string
|
||||
recipientName: string
|
||||
recipientPhone: string
|
||||
@ -103,6 +125,28 @@ const batchMatchDeclaration = ref(false)
|
||||
const batchQtyPerOrder = ref(1)
|
||||
let searchTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
/** 运单基本信息(对齐下单页) */
|
||||
const cargoAttribute = ref('general')
|
||||
const actualWeight = ref<number | undefined>(undefined)
|
||||
const quantity = ref<number>(1)
|
||||
const lengthCm = ref<number | undefined>(10)
|
||||
const widthCm = ref<number | undefined>(10)
|
||||
const heightCm = ref<number | undefined>(10)
|
||||
const exportCustomsMode = ref(SAMPLE_EXPORT_CUSTOMS_MODE_CODE)
|
||||
const exportQualificationId = ref<number | undefined>()
|
||||
const platformCode = ref<string>()
|
||||
const inboundMethod = ref<'selfShip' | 'doorPickup'>('selfShip')
|
||||
const senderAddressId = ref<number | undefined>()
|
||||
const expectPickupTime = ref<string>()
|
||||
const agreementChecked = ref(false)
|
||||
const agreementModalVisible = ref(false)
|
||||
const dictLoading = ref(false)
|
||||
const cargoAttributeOptions = ref<SelectOption[]>([])
|
||||
const exportCustomsModeOptions = ref<SelectOption[]>([])
|
||||
const ecommercePlatformOptions = ref<SelectOption[]>([])
|
||||
const exportQualificationOptions = ref<QualOption[]>([])
|
||||
const pickupAddressOptions = ref<Array<{ label: string; value: number }>>([])
|
||||
|
||||
const modalVisible = computed({
|
||||
get: () => props.visible,
|
||||
set: (v: boolean) => emit('update:visible', v),
|
||||
@ -167,17 +211,172 @@ const warehouseLabel = computed(() => {
|
||||
return opt?.label || '-'
|
||||
})
|
||||
|
||||
const canSubmit = computed(() => {
|
||||
const needExportQualification = computed(
|
||||
() =>
|
||||
String(exportCustomsMode.value ?? '').trim().toLowerCase() ===
|
||||
EXPORT_CUSTOMS_MODE_9610_SUMMARY.toLowerCase(),
|
||||
)
|
||||
|
||||
const basicInfoReady = computed(() => {
|
||||
if (!productCode.value) return false
|
||||
if (!warehouseId.value) return false
|
||||
if (!String(cargoAttribute.value || '').trim()) return false
|
||||
if (!(Number(actualWeight.value) > 0)) return false
|
||||
if (!(Number(quantity.value) > 0)) return false
|
||||
if (!(Number(lengthCm.value) > 0) || !(Number(widthCm.value) > 0) || !(Number(heightCm.value) > 0)) {
|
||||
return false
|
||||
}
|
||||
if (needExportQualification.value) {
|
||||
if (!(Number(exportQualificationId.value) > 0)) return false
|
||||
if (!String(platformCode.value || '').trim()) return false
|
||||
}
|
||||
if (inboundMethod.value === 'doorPickup') {
|
||||
if (!(Number(senderAddressId.value) > 0)) return false
|
||||
if (!expectPickupTime.value) return false
|
||||
}
|
||||
if (drafts.value.some((d) => !String(d.clientNo || '').trim())) return false
|
||||
return true
|
||||
})
|
||||
|
||||
const canSubmit = computed(() => {
|
||||
if (!basicInfoReady.value) return false
|
||||
if (!agreementChecked.value) return false
|
||||
if (drafts.value.length === 0) return false
|
||||
if (drafts.value.some((d) => d.receiverMissing || d.linesMissing)) return false
|
||||
if (isFulfill.value) {
|
||||
if (!warehouseId.value) return false
|
||||
if (drafts.value.some((d) => d.bindItems.length === 0)) return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
function resolveExportCustomsMode9610Simple() {
|
||||
const opts = exportCustomsModeOptions.value
|
||||
const byCode = opts.find(
|
||||
(o) => o.value === SAMPLE_EXPORT_CUSTOMS_MODE_CODE || o.value.toLowerCase() === '9610simple',
|
||||
)
|
||||
if (byCode) return byCode.value
|
||||
const byLabel = opts.find((o) => /9610.*简易|简易.*9610/i.test(o.label))
|
||||
if (byLabel) return byLabel.value
|
||||
return SAMPLE_EXPORT_CUSTOMS_MODE_CODE
|
||||
}
|
||||
|
||||
function mapDictOptions(rows: any[]): SelectOption[] {
|
||||
return (rows || [])
|
||||
.map((row) => {
|
||||
const value = String(row?.dictCode ?? row?.DictCode ?? '').trim()
|
||||
const label = String(row?.dictName ?? row?.DictName ?? value).trim()
|
||||
if (!value) return null
|
||||
return { label: label || value, value }
|
||||
})
|
||||
.filter((x): x is SelectOption => !!x)
|
||||
}
|
||||
|
||||
async function loadBasicDicts() {
|
||||
dictLoading.value = true
|
||||
try {
|
||||
const [cargoRows, exportRows, platformRows] = await Promise.all([
|
||||
getDictListAll({ dictType: 'cargo_attribute' }),
|
||||
getDictListAll({ dictType: 'export_customs_mode' }),
|
||||
getDictListAll({ dictType: 'e-commerce_platform' }),
|
||||
])
|
||||
cargoAttributeOptions.value = mapDictOptions(cargoRows as any[])
|
||||
exportCustomsModeOptions.value = mapDictOptions(exportRows as any[])
|
||||
ecommercePlatformOptions.value = mapDictOptions(platformRows as any[])
|
||||
if (!cargoAttribute.value && cargoAttributeOptions.value[0]) {
|
||||
cargoAttribute.value = normalizeCargoAttributeCode(cargoAttributeOptions.value[0].value)
|
||||
} else {
|
||||
cargoAttribute.value = normalizeCargoAttributeCode(cargoAttribute.value)
|
||||
}
|
||||
exportCustomsMode.value = resolveExportCustomsMode9610Simple()
|
||||
} catch {
|
||||
cargoAttributeOptions.value = [
|
||||
{ label: '普货', value: 'general' },
|
||||
{ label: '带电', value: 'electronics' },
|
||||
{ label: '敏感', value: 'sensitive' },
|
||||
]
|
||||
exportCustomsModeOptions.value = [
|
||||
{ label: '9610 简易申报', value: SAMPLE_EXPORT_CUSTOMS_MODE_CODE },
|
||||
{ label: '9610 汇总申报', value: EXPORT_CUSTOMS_MODE_9610_SUMMARY },
|
||||
]
|
||||
} finally {
|
||||
dictLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function loadExportQualifications() {
|
||||
const customerId = resolveCandidatesCustomerId()
|
||||
try {
|
||||
const res = await getExportQualificationList({
|
||||
page: 1,
|
||||
pageSize: 100,
|
||||
customerId,
|
||||
})
|
||||
exportQualificationOptions.value = (res.items || [])
|
||||
.map((item: Record<string, unknown>) => {
|
||||
const id = Number(pickField(item, 'id', 'Id') ?? 0)
|
||||
if (!id) return null
|
||||
const companyName = String(pickField(item, 'companyName', 'CompanyName') ?? '').trim()
|
||||
const creditCode = String(pickField(item, 'socialCreditCode', 'SocialCreditCode') ?? '').trim()
|
||||
const isDefault = Boolean(pickField(item, 'isDefault', 'IsDefault'))
|
||||
const base = companyName || creditCode || `#${id}`
|
||||
return { id, label: isDefault ? `${base}(默认)` : base, isDefault }
|
||||
})
|
||||
.filter((x): x is QualOption => !!x)
|
||||
if (!exportQualificationId.value) {
|
||||
const def =
|
||||
exportQualificationOptions.value.find((x) => x.isDefault) || exportQualificationOptions.value[0]
|
||||
exportQualificationId.value = def?.id
|
||||
}
|
||||
} catch {
|
||||
exportQualificationOptions.value = []
|
||||
}
|
||||
}
|
||||
|
||||
async function loadPickupAddresses() {
|
||||
const customerId = resolveCandidatesCustomerId()
|
||||
try {
|
||||
const res = await getSenderAddressList({
|
||||
page: 1,
|
||||
pageSize: 200,
|
||||
addressType: 'pickup',
|
||||
customerId,
|
||||
})
|
||||
pickupAddressOptions.value = (res.items || [])
|
||||
.map((item: Record<string, unknown>) => {
|
||||
const id = Number(pickField(item, 'id', 'Id') ?? 0)
|
||||
if (!id) return null
|
||||
const name = String(pickField(item, 'contactName', 'ContactName', 'name', 'Name') ?? '').trim()
|
||||
const phone = String(pickField(item, 'phone', 'Phone') ?? '').trim()
|
||||
const label = [name, phone].filter(Boolean).join(' · ') || `#${id}`
|
||||
return { label, value: id }
|
||||
})
|
||||
.filter((x): x is { label: string; value: number } => !!x)
|
||||
} catch {
|
||||
pickupAddressOptions.value = []
|
||||
}
|
||||
}
|
||||
|
||||
function openAgreementModal() {
|
||||
agreementModalVisible.value = true
|
||||
}
|
||||
|
||||
function buildParcelBasicPayload() {
|
||||
return {
|
||||
cargoAttribute: normalizeCargoAttributeCode(cargoAttribute.value),
|
||||
actualWeight: Number(actualWeight.value),
|
||||
quantity: Number(quantity.value),
|
||||
length: Number(lengthCm.value),
|
||||
width: Number(widthCm.value),
|
||||
height: Number(heightCm.value),
|
||||
exportCustomsMode: String(exportCustomsMode.value || '').trim() || resolveExportCustomsMode9610Simple(),
|
||||
exportQualificationId: needExportQualification.value ? exportQualificationId.value : undefined,
|
||||
platformCode: needExportQualification.value ? platformCode.value : undefined,
|
||||
inboundMethod: inboundMethod.value,
|
||||
senderAddressId: inboundMethod.value === 'doorPickup' ? senderAddressId.value : undefined,
|
||||
expectPickupTime: inboundMethod.value === 'doorPickup' ? expectPickupTime.value : undefined,
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
emit('update:visible', false)
|
||||
}
|
||||
@ -208,11 +407,13 @@ function mapDetail(raw: Record<string, unknown>): OrderDraft {
|
||||
const shipLines = lines
|
||||
const customerIdRaw = Number(pickField(row, 'customerId', 'CustomerId') ?? 0)
|
||||
const warehouseIdRaw = Number(pickField(row, 'warehouseId', 'WarehouseId') ?? 0)
|
||||
const platformOrderNo = String(pickField(row, 'platformOrderNo', 'PlatformOrderNo') ?? '')
|
||||
return {
|
||||
storeOrderId: Number(pickField(row, 'id', 'Id')),
|
||||
customerId: Number.isFinite(customerIdRaw) && customerIdRaw > 0 ? customerIdRaw : undefined,
|
||||
warehouseId: Number.isFinite(warehouseIdRaw) && warehouseIdRaw > 0 ? warehouseIdRaw : undefined,
|
||||
platformOrderNo: String(pickField(row, 'platformOrderNo', 'PlatformOrderNo') ?? ''),
|
||||
platformOrderNo,
|
||||
clientNo: platformOrderNo,
|
||||
orderCountry: String(pickField(row, 'orderCountry', 'OrderCountry') ?? ''),
|
||||
recipientName,
|
||||
recipientPhone: String(pickField(row, 'recipientPhone', 'RecipientPhone') ?? ''),
|
||||
@ -525,6 +726,10 @@ function buildBindPayload(items: BindDraftItem[]) {
|
||||
|
||||
async function handleSubmit(): Promise<boolean> {
|
||||
if (!canSubmit.value) {
|
||||
if (!agreementChecked.value) {
|
||||
$baseMessage(t('order.placeOrder.agreement.required'), 'warning')
|
||||
return false
|
||||
}
|
||||
if (!productCode.value) {
|
||||
$baseMessage(
|
||||
isFulfillWms.value
|
||||
@ -534,10 +739,14 @@ async function handleSubmit(): Promise<boolean> {
|
||||
)
|
||||
return false
|
||||
}
|
||||
if (isFulfill.value && !warehouseId.value) {
|
||||
if (!warehouseId.value) {
|
||||
$baseMessage(t('order.platformStoreOrder.message.warehouseRequired'), 'warning')
|
||||
return false
|
||||
}
|
||||
if (!basicInfoReady.value) {
|
||||
$baseMessage(t('order.platformStoreOrder.createLogistics.basicRequired'), 'warning')
|
||||
return false
|
||||
}
|
||||
const bad = drafts.value.find(
|
||||
(d) => d.receiverMissing || d.linesMissing || (isFulfill.value && d.bindItems.length === 0),
|
||||
)
|
||||
@ -579,12 +788,14 @@ async function handleSubmit(): Promise<boolean> {
|
||||
try {
|
||||
const items = drafts.value.map((d) => ({
|
||||
storeOrderId: d.storeOrderId,
|
||||
clientNo: String(d.clientNo || '').trim() || undefined,
|
||||
bindItems: isFulfill.value ? buildBindPayload(d.bindItems) : undefined,
|
||||
}))
|
||||
const body = {
|
||||
productCode: productCode.value,
|
||||
warehouseId: warehouseId.value,
|
||||
customerId: props.customerId,
|
||||
parcelBasic: buildParcelBasicPayload(),
|
||||
items,
|
||||
}
|
||||
const result = isFulfillWms.value
|
||||
@ -636,7 +847,29 @@ watch(
|
||||
batchMode.value = props.storeOrderIds.length > 1
|
||||
batchMatchDeclaration.value = false
|
||||
batchQtyPerOrder.value = 1
|
||||
cargoAttribute.value = 'general'
|
||||
actualWeight.value = undefined
|
||||
quantity.value = 1
|
||||
lengthCm.value = 10
|
||||
widthCm.value = 10
|
||||
heightCm.value = 10
|
||||
exportCustomsMode.value = SAMPLE_EXPORT_CUSTOMS_MODE_CODE
|
||||
exportQualificationId.value = undefined
|
||||
platformCode.value = undefined
|
||||
inboundMethod.value = 'selfShip'
|
||||
senderAddressId.value = undefined
|
||||
expectPickupTime.value = undefined
|
||||
agreementChecked.value = false
|
||||
await loadBasicDicts()
|
||||
await loadDrafts()
|
||||
// 实重默认按订单申报行估算(取首单)
|
||||
const first = drafts.value[0]
|
||||
if (first && !(Number(actualWeight.value) > 0)) {
|
||||
const est = first.lines.reduce((s, x) => s + Math.max(1, Number(x.quantity) || 0) * 0.01, 0)
|
||||
actualWeight.value = Number(est.toFixed(3)) || 0.01
|
||||
}
|
||||
await loadExportQualifications()
|
||||
await loadPickupAddresses()
|
||||
if (isFulfill.value) await loadCandidates()
|
||||
},
|
||||
{ immediate: true },
|
||||
@ -652,14 +885,24 @@ watch(leftTab, () => {
|
||||
if (!props.visible || !isFulfill.value) return
|
||||
void loadCandidates()
|
||||
})
|
||||
|
||||
watch(needExportQualification, (need) => {
|
||||
if (!props.visible || !need) return
|
||||
void loadExportQualifications()
|
||||
})
|
||||
|
||||
watch(inboundMethod, (method) => {
|
||||
if (!props.visible || method !== 'doorPickup') return
|
||||
void loadPickupAddresses()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:visible="modalVisible"
|
||||
:title="title"
|
||||
:width="isFulfill ? '1360px' : 960"
|
||||
:top="isFulfill ? '20px' : '10vh'"
|
||||
:width="isFulfill ? '1360px' : '1080px'"
|
||||
:top="isFulfill ? '20px' : '6vh'"
|
||||
:ok-loading="submitting"
|
||||
:ok-text="
|
||||
isFulfillWms
|
||||
@ -670,7 +913,11 @@ watch(leftTab, () => {
|
||||
"
|
||||
:ok-button-props="{ disabled: !canSubmit || loading }"
|
||||
unmount-on-close
|
||||
:body-style="isFulfill ? { padding: '12px 16px', maxHeight: 'calc(100vh - 140px)', overflow: 'hidden' } : undefined"
|
||||
:body-style="{
|
||||
padding: '12px 16px',
|
||||
maxHeight: isFulfill ? 'calc(100vh - 140px)' : 'calc(100vh - 160px)',
|
||||
overflow: isFulfill ? 'hidden' : 'auto',
|
||||
}"
|
||||
:on-before-ok="handleSubmit"
|
||||
@cancel="close"
|
||||
>
|
||||
@ -686,49 +933,146 @@ watch(leftTab, () => {
|
||||
}}
|
||||
</p>
|
||||
|
||||
<div class="psc-config">
|
||||
<div class="psc-config__item">
|
||||
<span class="psc-config__label">
|
||||
<section class="psc-basic">
|
||||
<header class="psc-basic__head">
|
||||
<strong>{{ t('order.placeOrder.single.stepBasic') }}</strong>
|
||||
<span class="psc-config__meta">
|
||||
{{
|
||||
isFulfillWms
|
||||
? t('order.platformStoreOrder.createFulfillWms.product')
|
||||
: t('order.platformStoreOrder.createLogistics.product')
|
||||
t('order.platformStoreOrder.createLogistics.readyMeta', {
|
||||
total: drafts.length,
|
||||
ready: readyCount,
|
||||
})
|
||||
}}
|
||||
</span>
|
||||
<a-select
|
||||
v-model="productCode"
|
||||
allow-search
|
||||
:options="productOptions"
|
||||
:placeholder="
|
||||
isFulfillWms
|
||||
? t('order.platformStoreOrder.createFulfillWms.product')
|
||||
: t('order.platformStoreOrder.form.product')
|
||||
"
|
||||
style="width: 260px"
|
||||
/>
|
||||
</header>
|
||||
<div class="psc-basic__grid">
|
||||
<div class="psc-basic__item">
|
||||
<span class="psc-basic__label">
|
||||
{{
|
||||
isFulfillWms
|
||||
? t('order.platformStoreOrder.createFulfillWms.product')
|
||||
: t('order.platformStoreOrder.createLogistics.product')
|
||||
}}
|
||||
<em>*</em>
|
||||
</span>
|
||||
<a-select
|
||||
v-model="productCode"
|
||||
allow-search
|
||||
:options="productOptions"
|
||||
:loading="dictLoading"
|
||||
:placeholder="t('order.platformStoreOrder.form.product')"
|
||||
/>
|
||||
</div>
|
||||
<div class="psc-basic__item">
|
||||
<span class="psc-basic__label">客户单号 <em>*</em></span>
|
||||
<a-input
|
||||
v-if="activeDraft"
|
||||
v-model="activeDraft.clientNo"
|
||||
:placeholder="activeDraft.platformOrderNo || '客户单号'"
|
||||
/>
|
||||
<a-input v-else disabled placeholder="—" />
|
||||
</div>
|
||||
<div class="psc-basic__item">
|
||||
<span class="psc-basic__label">货物属性 <em>*</em></span>
|
||||
<a-select
|
||||
v-model="cargoAttribute"
|
||||
allow-search
|
||||
:options="cargoAttributeOptions"
|
||||
:loading="dictLoading"
|
||||
placeholder="请选择"
|
||||
/>
|
||||
</div>
|
||||
<div class="psc-basic__item">
|
||||
<span class="psc-basic__label">仓库 <em>*</em></span>
|
||||
<a-select
|
||||
v-model="warehouseId"
|
||||
allow-search
|
||||
:options="warehouseOptions"
|
||||
:placeholder="t('warehouse.common.warehouse')"
|
||||
/>
|
||||
</div>
|
||||
<div class="psc-basic__item">
|
||||
<span class="psc-basic__label">实重(kg) <em>*</em></span>
|
||||
<a-input-number v-model="actualWeight" :min="0.01" :precision="3" hide-button style="width: 100%" />
|
||||
</div>
|
||||
<div class="psc-basic__item">
|
||||
<span class="psc-basic__label">包裹数量 <em>*</em></span>
|
||||
<a-input-number v-model="quantity" :min="1" :precision="0" hide-button style="width: 100%" />
|
||||
</div>
|
||||
<div class="psc-basic__item">
|
||||
<span class="psc-basic__label">出口报关方式</span>
|
||||
<a-select
|
||||
v-model="exportCustomsMode"
|
||||
allow-search
|
||||
:options="exportCustomsModeOptions"
|
||||
:loading="dictLoading"
|
||||
placeholder="请选择"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="needExportQualification" class="psc-basic__item">
|
||||
<span class="psc-basic__label">出口资质备案 <em>*</em></span>
|
||||
<a-select
|
||||
v-model="exportQualificationId"
|
||||
allow-search
|
||||
:options="exportQualificationOptions.map((x) => ({ label: x.label, value: x.id }))"
|
||||
placeholder="请选择"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="needExportQualification" class="psc-basic__item">
|
||||
<span class="psc-basic__label">电商平台 <em>*</em></span>
|
||||
<a-select
|
||||
v-model="platformCode"
|
||||
allow-search
|
||||
:options="ecommercePlatformOptions"
|
||||
placeholder="请选择"
|
||||
/>
|
||||
</div>
|
||||
<div class="psc-basic__item psc-basic__item--dims">
|
||||
<span class="psc-basic__label">长宽高(cm) <em>*</em></span>
|
||||
<div class="psc-dims">
|
||||
<a-input-number v-model="lengthCm" :min="0.1" :precision="1" hide-button placeholder="长" />
|
||||
<span>×</span>
|
||||
<a-input-number v-model="widthCm" :min="0.1" :precision="1" hide-button placeholder="宽" />
|
||||
<span>×</span>
|
||||
<a-input-number v-model="heightCm" :min="0.1" :precision="1" hide-button placeholder="高" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="psc-basic__item psc-basic__item--inbound">
|
||||
<span class="psc-basic__label">到仓方式 <em>*</em></span>
|
||||
<a-radio-group v-model="inboundMethod" type="button" size="small">
|
||||
<a-radio value="selfShip">自寄到仓</a-radio>
|
||||
<a-radio value="doorPickup">上门揽收</a-radio>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
<template v-if="inboundMethod === 'doorPickup'">
|
||||
<div class="psc-basic__item">
|
||||
<span class="psc-basic__label">揽收地址 <em>*</em></span>
|
||||
<a-select
|
||||
v-model="senderAddressId"
|
||||
allow-search
|
||||
:options="pickupAddressOptions"
|
||||
placeholder="请选择揽收地址"
|
||||
/>
|
||||
</div>
|
||||
<div class="psc-basic__item">
|
||||
<span class="psc-basic__label">期望揽收时间 <em>*</em></span>
|
||||
<a-date-picker
|
||||
v-model="expectPickupTime"
|
||||
show-time
|
||||
format="YYYY-MM-DD HH:mm"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="psc-config__item">
|
||||
<span class="psc-config__label">
|
||||
{{ t('warehouse.common.warehouse') }}
|
||||
<em v-if="isFulfill">*</em>
|
||||
<div class="psc-agreement">
|
||||
<a-checkbox v-model="agreementChecked" />
|
||||
<span class="psc-agreement__link" @click="openAgreementModal">
|
||||
{{ t('order.placeOrder.agreement.label') }}
|
||||
</span>
|
||||
<a-select
|
||||
v-model="warehouseId"
|
||||
allow-clear
|
||||
:options="warehouseOptions"
|
||||
:placeholder="t('warehouse.common.warehouse')"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</div>
|
||||
<div class="psc-config__meta">
|
||||
{{
|
||||
t('order.platformStoreOrder.createLogistics.readyMeta', {
|
||||
total: drafts.length,
|
||||
ready: readyCount,
|
||||
})
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div v-if="showBatchBar" class="psc-batch-bar">
|
||||
<div class="psc-batch-bar__left">
|
||||
@ -1067,6 +1411,16 @@ watch(leftTab, () => {
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<a-modal
|
||||
v-model:visible="agreementModalVisible"
|
||||
:title="t('order.placeOrder.agreement.label')"
|
||||
:footer="false"
|
||||
:width="560"
|
||||
unmount-on-close
|
||||
>
|
||||
<pre class="psc-agreement-body">{{ AGREEMENT_TEXT }}</pre>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
@ -1094,28 +1448,42 @@ watch(leftTab, () => {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.psc-config {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 12px 16px;
|
||||
padding: 10px 12px;
|
||||
.psc-basic {
|
||||
margin-bottom: 10px;
|
||||
padding: 12px;
|
||||
background: var(--color-fill-2);
|
||||
border-radius: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.psc-config__item {
|
||||
.psc-basic__head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
gap: 12px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
strong {
|
||||
font-size: 14px;
|
||||
color: var(--color-text-1);
|
||||
}
|
||||
}
|
||||
|
||||
.psc-config__label {
|
||||
font-size: 13px;
|
||||
.psc-basic__grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 10px 12px;
|
||||
}
|
||||
|
||||
.psc-basic__item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.psc-basic__label {
|
||||
font-size: 12px;
|
||||
color: var(--color-text-2);
|
||||
white-space: nowrap;
|
||||
|
||||
em {
|
||||
color: #f53f3f;
|
||||
@ -1124,6 +1492,54 @@ watch(leftTab, () => {
|
||||
}
|
||||
}
|
||||
|
||||
.psc-basic__item--dims,
|
||||
.psc-basic__item--inbound {
|
||||
grid-column: span 1;
|
||||
}
|
||||
|
||||
.psc-dims {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
|
||||
.arco-input-number {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.psc-agreement {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 12px;
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid var(--color-border-2);
|
||||
}
|
||||
|
||||
.psc-agreement__link {
|
||||
color: var(--app-primary-color);
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
user-select: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.psc-agreement-body {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
font-family: inherit;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
color: var(--color-text-2);
|
||||
max-height: 50vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.psc-config__meta {
|
||||
margin-left: auto;
|
||||
font-size: 12px;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user