fix: 创建运单到仓方式对齐下单页(仓库地址 Popover/上门揽收字段)
Some checks failed
Build and Deploy Front / deploy (push) Has been cancelled
Some checks failed
Build and Deploy Front / deploy (push) Has been cancelled
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
5f6496c661
commit
209a6e1c2a
@ -3,7 +3,7 @@ import { computed, ref, watch } from 'vue'
|
|||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { Modal } from '@arco-design/web-vue'
|
import { Modal } from '@arco-design/web-vue'
|
||||||
import { IconPlus, IconDelete, IconQuestionCircle } from '@arco-design/web-vue/es/icon'
|
import { IconPlus, IconDelete, IconQuestionCircle, IconCopy } from '@arco-design/web-vue/es/icon'
|
||||||
import {
|
import {
|
||||||
batchCreatePlatformStoreFulfill,
|
batchCreatePlatformStoreFulfill,
|
||||||
batchCreatePlatformStoreFulfillWms,
|
batchCreatePlatformStoreFulfillWms,
|
||||||
@ -16,6 +16,7 @@ import {
|
|||||||
} from '@/api/order'
|
} from '@/api/order'
|
||||||
import { getSenderAddressList } from '@/api/order/senderAddress'
|
import { getSenderAddressList } from '@/api/order/senderAddress'
|
||||||
import { getExportQualificationList } from '@/api/customer/exportQualification'
|
import { getExportQualificationList } from '@/api/customer/exportQualification'
|
||||||
|
import { getSalesProductList } from '@/api/channel/salesProduct'
|
||||||
import { getDictListAll } from '@/api/system/dict'
|
import { getDictListAll } from '@/api/system/dict'
|
||||||
import { resolveOmsAssetUrl } from '@/api/oms/common'
|
import { resolveOmsAssetUrl } from '@/api/oms/common'
|
||||||
import SlidingTabs from '@/components/SlidingTabs/index.vue'
|
import SlidingTabs from '@/components/SlidingTabs/index.vue'
|
||||||
@ -23,6 +24,19 @@ import ExportCustoms9610GuideModal from '@/views/order/placeOrder/components/Exp
|
|||||||
import { $baseMessage } from '@/utils'
|
import { $baseMessage } from '@/utils'
|
||||||
import { normalizeCargoAttributeCode } from '@/utils/cargoAttribute'
|
import { normalizeCargoAttributeCode } from '@/utils/cargoAttribute'
|
||||||
import { normalizeListRow, pickField } from '@/utils/warehouseListMapper'
|
import { normalizeListRow, pickField } from '@/utils/warehouseListMapper'
|
||||||
|
import {
|
||||||
|
formatWarehouseShipAddress,
|
||||||
|
formatWarehouseShipRecipient,
|
||||||
|
} from '@/utils/warehouseShipAddress'
|
||||||
|
|
||||||
|
type WarehouseOption = {
|
||||||
|
label: string
|
||||||
|
value: number
|
||||||
|
recipient?: string
|
||||||
|
contactPhone?: string
|
||||||
|
shippingAddress?: string
|
||||||
|
remark?: string
|
||||||
|
}
|
||||||
|
|
||||||
import type { CreateLogisticsMode } from './constants'
|
import type { CreateLogisticsMode } from './constants'
|
||||||
|
|
||||||
@ -92,7 +106,7 @@ const props = defineProps<{
|
|||||||
mode: CreateLogisticsMode
|
mode: CreateLogisticsMode
|
||||||
storeOrderIds: number[]
|
storeOrderIds: number[]
|
||||||
productOptions: Array<{ label: string; value: string }>
|
productOptions: Array<{ label: string; value: string }>
|
||||||
warehouseOptions: Array<{ label: string; value: number }>
|
warehouseOptions: WarehouseOption[]
|
||||||
defaultProductCode?: string
|
defaultProductCode?: string
|
||||||
defaultWarehouseId?: number
|
defaultWarehouseId?: number
|
||||||
customerId?: number
|
customerId?: number
|
||||||
@ -141,6 +155,7 @@ const platformCode = ref<string>()
|
|||||||
const inboundMethod = ref<'selfShip' | 'doorPickup'>('selfShip')
|
const inboundMethod = ref<'selfShip' | 'doorPickup'>('selfShip')
|
||||||
const senderAddressId = ref<number | undefined>()
|
const senderAddressId = ref<number | undefined>()
|
||||||
const expectPickupTime = ref<string>()
|
const expectPickupTime = ref<string>()
|
||||||
|
const carrierService = ref<string>()
|
||||||
const agreementChecked = ref(false)
|
const agreementChecked = ref(false)
|
||||||
const agreementModalVisible = ref(false)
|
const agreementModalVisible = ref(false)
|
||||||
const exportCustomsGuideVisible = ref(false)
|
const exportCustomsGuideVisible = ref(false)
|
||||||
@ -150,11 +165,70 @@ const exportCustomsModeOptions = ref<SelectOption[]>([])
|
|||||||
const ecommercePlatformOptions = ref<SelectOption[]>([])
|
const ecommercePlatformOptions = ref<SelectOption[]>([])
|
||||||
const exportQualificationOptions = ref<QualOption[]>([])
|
const exportQualificationOptions = ref<QualOption[]>([])
|
||||||
const pickupAddressOptions = ref<Array<{ label: string; value: number }>>([])
|
const pickupAddressOptions = ref<Array<{ label: string; value: number }>>([])
|
||||||
|
const domesticPickupProductOptions = ref<SelectOption[]>([])
|
||||||
|
const pickupAddressLoading = ref(false)
|
||||||
|
|
||||||
function goToExportQualificationManage() {
|
function goToExportQualificationManage() {
|
||||||
router.push({ path: '/user/exportQualification' })
|
router.push({ path: '/user/exportQualification' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const warehouseShipAddressList = computed(() => props.warehouseOptions || [])
|
||||||
|
const warehousesWithShipAddress = computed(() =>
|
||||||
|
warehouseShipAddressList.value.filter((opt) => warehouseHasAddress(opt)),
|
||||||
|
)
|
||||||
|
|
||||||
|
function warehouseHasAddress(opt?: WarehouseOption) {
|
||||||
|
if (!opt) return false
|
||||||
|
return Boolean(opt.recipient || opt.contactPhone || opt.shippingAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayWarehouseRecipient(opt?: WarehouseOption) {
|
||||||
|
return formatWarehouseShipRecipient(opt?.recipient, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayWarehouseShippingAddress(opt?: WarehouseOption) {
|
||||||
|
return formatWarehouseShipAddress(opt?.shippingAddress, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildWarehouseShipCopyText(opt?: WarehouseOption) {
|
||||||
|
if (!opt) return ''
|
||||||
|
const lines = [
|
||||||
|
opt.label || '',
|
||||||
|
`收件人:${displayWarehouseRecipient(opt)}`,
|
||||||
|
`电话:${opt.contactPhone || '-'}`,
|
||||||
|
`地址:${displayWarehouseShippingAddress(opt)}`,
|
||||||
|
]
|
||||||
|
const clientNo = String(activeDraft.value?.clientNo ?? '').trim()
|
||||||
|
if (clientNo) lines.push(`客户单号:${clientNo}`)
|
||||||
|
return lines.filter(Boolean).join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
async function copyWarehouseShipAddress(opt?: WarehouseOption) {
|
||||||
|
const text = buildWarehouseShipCopyText(opt)
|
||||||
|
if (!text.trim()) {
|
||||||
|
$baseMessage('该仓库暂未配置收货地址', 'warning')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(text)
|
||||||
|
$baseMessage('仓库寄件信息已复制', 'success')
|
||||||
|
} catch {
|
||||||
|
const area = document.createElement('textarea')
|
||||||
|
area.value = text
|
||||||
|
area.style.position = 'fixed'
|
||||||
|
area.style.left = '-9999px'
|
||||||
|
document.body.appendChild(area)
|
||||||
|
area.select()
|
||||||
|
try {
|
||||||
|
document.execCommand('copy')
|
||||||
|
$baseMessage('仓库寄件信息已复制', 'success')
|
||||||
|
} catch {
|
||||||
|
$baseMessage('复制失败', 'error')
|
||||||
|
}
|
||||||
|
document.body.removeChild(area)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const modalVisible = computed({
|
const modalVisible = computed({
|
||||||
get: () => props.visible,
|
get: () => props.visible,
|
||||||
set: (v: boolean) => emit('update:visible', v),
|
set: (v: boolean) => emit('update:visible', v),
|
||||||
@ -347,6 +421,7 @@ async function loadExportQualifications() {
|
|||||||
|
|
||||||
async function loadPickupAddresses() {
|
async function loadPickupAddresses() {
|
||||||
const customerId = resolveCandidatesCustomerId()
|
const customerId = resolveCandidatesCustomerId()
|
||||||
|
pickupAddressLoading.value = true
|
||||||
try {
|
try {
|
||||||
const res = await getSenderAddressList({
|
const res = await getSenderAddressList({
|
||||||
page: 1,
|
page: 1,
|
||||||
@ -366,6 +441,38 @@ async function loadPickupAddresses() {
|
|||||||
.filter((x): x is { label: string; value: number } => !!x)
|
.filter((x): x is { label: string; value: number } => !!x)
|
||||||
} catch {
|
} catch {
|
||||||
pickupAddressOptions.value = []
|
pickupAddressOptions.value = []
|
||||||
|
} finally {
|
||||||
|
pickupAddressLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadDomesticPickupProducts() {
|
||||||
|
try {
|
||||||
|
const [groupRows, productRes] = await Promise.all([
|
||||||
|
getDictListAll({ dictType: 'sales_product_group' }),
|
||||||
|
getSalesProductList({ page: 1, pageSize: 200, isActive: 2 }),
|
||||||
|
])
|
||||||
|
const domesticPickupGroupCodes = new Set(
|
||||||
|
(groupRows || [])
|
||||||
|
.filter((d: any) => String(d?.dictName ?? d?.DictName ?? '').includes('国内揽收'))
|
||||||
|
.map((d: any) => String(d?.dictCode ?? d?.DictCode ?? '').trim())
|
||||||
|
.filter(Boolean),
|
||||||
|
)
|
||||||
|
const items = (productRes as any)?.items || []
|
||||||
|
domesticPickupProductOptions.value = items
|
||||||
|
.filter((row: any) => {
|
||||||
|
const groupCode = String(row?.productGroup ?? row?.ProductGroup ?? '').trim()
|
||||||
|
return domesticPickupGroupCodes.size > 0 && domesticPickupGroupCodes.has(groupCode)
|
||||||
|
})
|
||||||
|
.map((row: any) => {
|
||||||
|
const code = String(row?.productCode ?? row?.ProductCode ?? '').trim()
|
||||||
|
const name = String(row?.productName ?? row?.ProductName ?? '').trim()
|
||||||
|
if (!code) return null
|
||||||
|
return { value: code, label: name ? `${name} (${code})` : code }
|
||||||
|
})
|
||||||
|
.filter((x: SelectOption | null): x is SelectOption => !!x)
|
||||||
|
} catch {
|
||||||
|
domesticPickupProductOptions.value = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,6 +496,10 @@ function buildParcelBasicPayload() {
|
|||||||
inboundMethod: inboundMethod.value,
|
inboundMethod: inboundMethod.value,
|
||||||
senderAddressId: inboundMethod.value === 'doorPickup' ? senderAddressId.value : undefined,
|
senderAddressId: inboundMethod.value === 'doorPickup' ? senderAddressId.value : undefined,
|
||||||
expectPickupTime: inboundMethod.value === 'doorPickup' ? expectPickupTime.value : undefined,
|
expectPickupTime: inboundMethod.value === 'doorPickup' ? expectPickupTime.value : undefined,
|
||||||
|
carrierService:
|
||||||
|
inboundMethod.value === 'doorPickup' && String(carrierService.value || '').trim()
|
||||||
|
? String(carrierService.value).trim()
|
||||||
|
: undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -874,6 +985,7 @@ watch(
|
|||||||
inboundMethod.value = 'selfShip'
|
inboundMethod.value = 'selfShip'
|
||||||
senderAddressId.value = undefined
|
senderAddressId.value = undefined
|
||||||
expectPickupTime.value = undefined
|
expectPickupTime.value = undefined
|
||||||
|
carrierService.value = undefined
|
||||||
agreementChecked.value = false
|
agreementChecked.value = false
|
||||||
await loadBasicDicts()
|
await loadBasicDicts()
|
||||||
await loadDrafts()
|
await loadDrafts()
|
||||||
@ -883,8 +995,11 @@ watch(
|
|||||||
const est = first.lines.reduce((s, x) => s + Math.max(1, Number(x.quantity) || 0) * 0.01, 0)
|
const est = first.lines.reduce((s, x) => s + Math.max(1, Number(x.quantity) || 0) * 0.01, 0)
|
||||||
actualWeight.value = String(Number(est.toFixed(3)) || 0.01)
|
actualWeight.value = String(Number(est.toFixed(3)) || 0.01)
|
||||||
}
|
}
|
||||||
await loadExportQualifications()
|
await Promise.all([
|
||||||
await loadPickupAddresses()
|
loadExportQualifications(),
|
||||||
|
loadPickupAddresses(),
|
||||||
|
loadDomesticPickupProducts(),
|
||||||
|
])
|
||||||
if (isFulfill.value) await loadCandidates()
|
if (isFulfill.value) await loadCandidates()
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
@ -909,6 +1024,7 @@ watch(needExportQualification, (need) => {
|
|||||||
watch(inboundMethod, (method) => {
|
watch(inboundMethod, (method) => {
|
||||||
if (!props.visible || method !== 'doorPickup') return
|
if (!props.visible || method !== 'doorPickup') return
|
||||||
void loadPickupAddresses()
|
void loadPickupAddresses()
|
||||||
|
if (!domesticPickupProductOptions.value.length) void loadDomesticPickupProducts()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -1117,11 +1233,106 @@ watch(inboundMethod, (method) => {
|
|||||||
size="small"
|
size="small"
|
||||||
class="inbound-method-radios"
|
class="inbound-method-radios"
|
||||||
>
|
>
|
||||||
<a-radio value="selfShip">自寄到仓</a-radio>
|
<a-radio value="selfShip">
|
||||||
|
<span class="inbound-method-pickup-label">
|
||||||
|
自寄到仓
|
||||||
|
<a-popover
|
||||||
|
position="bl"
|
||||||
|
trigger="hover"
|
||||||
|
content-class="warehouse-ship-popover"
|
||||||
|
>
|
||||||
|
<IconQuestionCircle class="inbound-method-help" @click.stop />
|
||||||
|
<template #content>
|
||||||
|
<div class="warehouse-ship-popover__body">
|
||||||
|
<div class="warehouse-ship-popover__head">
|
||||||
|
<strong>寄往仓库</strong>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
v-if="!warehouseShipAddressList.length"
|
||||||
|
class="warehouse-ship-popover__empty"
|
||||||
|
>
|
||||||
|
暂无仓库信息,请稍后重试或联系客服
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
v-else-if="!warehousesWithShipAddress.length"
|
||||||
|
class="warehouse-ship-popover__empty"
|
||||||
|
>
|
||||||
|
暂无已配置收货地址的仓库,请联系客服
|
||||||
|
</p>
|
||||||
|
<template v-else>
|
||||||
|
<div class="warehouse-ship-popover__list">
|
||||||
|
<div
|
||||||
|
v-for="opt in warehouseShipAddressList"
|
||||||
|
:key="opt.value"
|
||||||
|
class="warehouse-ship-popover__item"
|
||||||
|
:class="{
|
||||||
|
'is-selected': String(opt.value) === String(warehouseId ?? ''),
|
||||||
|
'is-empty': !warehouseHasAddress(opt),
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div class="warehouse-ship-popover__item-head">
|
||||||
|
<strong>
|
||||||
|
{{ opt.label || opt.value }}
|
||||||
|
<span
|
||||||
|
v-if="String(opt.value) === String(warehouseId ?? '')"
|
||||||
|
class="warehouse-ship-popover__badge"
|
||||||
|
>
|
||||||
|
当前
|
||||||
|
</span>
|
||||||
|
</strong>
|
||||||
|
<a-button
|
||||||
|
v-if="warehouseHasAddress(opt)"
|
||||||
|
type="text"
|
||||||
|
size="mini"
|
||||||
|
class="warehouse-ship-popover__copy"
|
||||||
|
@click="copyWarehouseShipAddress(opt)"
|
||||||
|
>
|
||||||
|
<template #icon><IconCopy /></template>
|
||||||
|
复制
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
v-if="!warehouseHasAddress(opt)"
|
||||||
|
class="warehouse-ship-popover__empty"
|
||||||
|
>
|
||||||
|
暂未配置收货地址
|
||||||
|
</p>
|
||||||
|
<dl v-else class="warehouse-ship-popover__rows">
|
||||||
|
<div>
|
||||||
|
<dt>收件人</dt>
|
||||||
|
<dd>{{ displayWarehouseRecipient(opt) }}</dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt>电话</dt>
|
||||||
|
<dd>{{ opt.contactPhone || '-' }}</dd>
|
||||||
|
</div>
|
||||||
|
<div class="is-addr">
|
||||||
|
<dt>地址</dt>
|
||||||
|
<dd>{{ displayWarehouseShippingAddress(opt) }}</dd>
|
||||||
|
</div>
|
||||||
|
<div v-if="opt.remark">
|
||||||
|
<dt>备注</dt>
|
||||||
|
<dd>{{ opt.remark }}</dd>
|
||||||
|
</div>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="warehouse-ship-popover__hint">
|
||||||
|
按所选仓库地址自行寄出。快递面单建议备注客户单号,方便仓库认领。
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-popover>
|
||||||
|
</span>
|
||||||
|
</a-radio>
|
||||||
<a-radio value="doorPickup">
|
<a-radio value="doorPickup">
|
||||||
<span class="inbound-method-pickup-label">
|
<span class="inbound-method-pickup-label">
|
||||||
上门揽收
|
上门揽收
|
||||||
<a-tooltip content="上门揽收为付费服务,费用通常低于市场价。" position="top">
|
<a-tooltip
|
||||||
|
content="上门揽收为付费服务,费用通常低于市场价。"
|
||||||
|
position="top"
|
||||||
|
>
|
||||||
<IconQuestionCircle class="inbound-method-help" @click.stop.prevent />
|
<IconQuestionCircle class="inbound-method-help" @click.stop.prevent />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</span>
|
</span>
|
||||||
@ -1129,12 +1340,24 @@ watch(inboundMethod, (method) => {
|
|||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<template v-if="inboundMethod === 'doorPickup'">
|
<template v-if="inboundMethod === 'doorPickup'">
|
||||||
|
<a-form-item label="仓库地址" required>
|
||||||
|
<a-select v-model="warehouseId" allow-search placeholder="请选择仓库">
|
||||||
|
<a-option
|
||||||
|
v-for="opt in warehouseOptions"
|
||||||
|
:key="opt.value"
|
||||||
|
:value="opt.value"
|
||||||
|
>
|
||||||
|
{{ opt.label }}
|
||||||
|
</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
<a-form-item label="揽收地址" required>
|
<a-form-item label="揽收地址" required>
|
||||||
<a-select
|
<a-select
|
||||||
v-model="senderAddressId"
|
v-model="senderAddressId"
|
||||||
allow-search
|
allow-search
|
||||||
allow-clear
|
allow-clear
|
||||||
placeholder="请选择国内揽收地址"
|
placeholder="请选择国内揽收地址"
|
||||||
|
:loading="pickupAddressLoading"
|
||||||
@focus="loadPickupAddresses"
|
@focus="loadPickupAddresses"
|
||||||
>
|
>
|
||||||
<a-option
|
<a-option
|
||||||
@ -1155,6 +1378,25 @@ watch(inboundMethod, (method) => {
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label="承运服务">
|
||||||
|
<a-select
|
||||||
|
v-model="carrierService"
|
||||||
|
allow-search
|
||||||
|
allow-clear
|
||||||
|
placeholder="选择国内揽收销售产品(可后补)"
|
||||||
|
>
|
||||||
|
<a-option
|
||||||
|
v-for="opt in domesticPickupProductOptions"
|
||||||
|
:key="opt.value"
|
||||||
|
:value="opt.value"
|
||||||
|
>
|
||||||
|
{{ opt.label }}
|
||||||
|
</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<p class="inbound-pickup-batch-hint">
|
||||||
|
{{ t('order.placeOrder.single.doorPickupBatchHint') }}
|
||||||
|
</p>
|
||||||
</template>
|
</template>
|
||||||
</a-form>
|
</a-form>
|
||||||
</section>
|
</section>
|
||||||
@ -1708,6 +1950,14 @@ watch(inboundMethod, (method) => {
|
|||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inbound-pickup-batch-hint {
|
||||||
|
margin: -4px 0 8px;
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.45;
|
||||||
|
color: var(--color-text-3, #86909c);
|
||||||
|
}
|
||||||
|
|
||||||
.inbound-method-radios {
|
.inbound-method-radios {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@ -2474,3 +2724,136 @@ watch(inboundMethod, (method) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
/* Popover 挂载到 body,需非 scoped(与下单页一致) */
|
||||||
|
.warehouse-ship-popover {
|
||||||
|
max-width: 400px;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.arco-popover-content {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.warehouse-ship-popover__body {
|
||||||
|
min-width: 260px;
|
||||||
|
max-width: 360px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warehouse-ship-popover__head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-1);
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.warehouse-ship-popover__copy {
|
||||||
|
height: 24px;
|
||||||
|
padding: 0 8px;
|
||||||
|
color: var(--app-primary-color);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warehouse-ship-popover__list {
|
||||||
|
margin-top: 8px;
|
||||||
|
max-height: 320px;
|
||||||
|
overflow-y: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warehouse-ship-popover__item {
|
||||||
|
padding: 8px;
|
||||||
|
border: 1px solid var(--color-border-2);
|
||||||
|
border-radius: 4px;
|
||||||
|
background: var(--color-fill-1);
|
||||||
|
|
||||||
|
&.is-selected {
|
||||||
|
border-color: var(--app-primary-color);
|
||||||
|
background: color-mix(in srgb, var(--app-primary-color) 8%, #fff);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-empty {
|
||||||
|
opacity: 0.72;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.warehouse-ship-popover__item-head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-1);
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.warehouse-ship-popover__badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 18px;
|
||||||
|
padding: 0 6px;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--app-primary-color);
|
||||||
|
background: color-mix(in srgb, var(--app-primary-color) 14%, #fff);
|
||||||
|
}
|
||||||
|
|
||||||
|
.warehouse-ship-popover__rows {
|
||||||
|
margin: 6px 0 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 48px minmax(0, 1fr);
|
||||||
|
gap: 8px;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--color-text-3);
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--color-text-1);
|
||||||
|
line-height: 20px;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.warehouse-ship-popover__hint,
|
||||||
|
.warehouse-ship-popover__empty {
|
||||||
|
margin: 8px 0 0;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
color: var(--color-text-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.warehouse-ship-popover__item .warehouse-ship-popover__empty {
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -82,7 +82,15 @@ const fulfillStatus = ref<string>(resolveFulfillStatusFromQuery())
|
|||||||
const platformCode = ref<string>(resolvePlatformFromQuery())
|
const platformCode = ref<string>(resolvePlatformFromQuery())
|
||||||
const keyword = ref('')
|
const keyword = ref('')
|
||||||
const summary = ref<Record<string, number>>({})
|
const summary = ref<Record<string, number>>({})
|
||||||
const warehouseOptions = ref<Array<{ label: string; value: number }>>([])
|
type WarehouseOption = {
|
||||||
|
label: string
|
||||||
|
value: number
|
||||||
|
recipient?: string
|
||||||
|
contactPhone?: string
|
||||||
|
shippingAddress?: string
|
||||||
|
remark?: string
|
||||||
|
}
|
||||||
|
const warehouseOptions = ref<WarehouseOption[]>([])
|
||||||
const warehouseNameMap = computed(() => buildWarehouseNameMap(warehouseOptions.value))
|
const warehouseNameMap = computed(() => buildWarehouseNameMap(warehouseOptions.value))
|
||||||
const productOptions = ref<Array<{ label: string; value: string }>>([])
|
const productOptions = ref<Array<{ label: string; value: string }>>([])
|
||||||
const wmsProductOptions = ref<Array<{ label: string; value: string }>>([])
|
const wmsProductOptions = ref<Array<{ label: string; value: string }>>([])
|
||||||
@ -728,8 +736,12 @@ onMounted(async () => {
|
|||||||
const warehouseTask = getWarehouseList({ page: 1, pageSize: 200 })
|
const warehouseTask = getWarehouseList({ page: 1, pageSize: 200 })
|
||||||
.then(({ items }) => {
|
.then(({ items }) => {
|
||||||
warehouseOptions.value = (items || []).map((w: any) => ({
|
warehouseOptions.value = (items || []).map((w: any) => ({
|
||||||
label: w.warehouseName || `#${w.id}`,
|
label: w.warehouseName || w.WarehouseName || `#${w.id ?? w.Id}`,
|
||||||
value: Number(w.id),
|
value: Number(w.id ?? w.Id),
|
||||||
|
recipient: String(w.recipient ?? w.Recipient ?? '').trim() || undefined,
|
||||||
|
contactPhone: String(w.contactPhone ?? w.ContactPhone ?? '').trim() || undefined,
|
||||||
|
shippingAddress: String(w.shippingAddress ?? w.ShippingAddress ?? '').trim() || undefined,
|
||||||
|
remark: String(w.remark ?? w.Remark ?? '').trim() || undefined,
|
||||||
}))
|
}))
|
||||||
if (warehouseOptions.value.length) matchWarehouseId.value = warehouseOptions.value[0].value
|
if (warehouseOptions.value.length) matchWarehouseId.value = warehouseOptions.value[0].value
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user