diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..56536ea --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +# 镜像只需要 dist/ 与 nginx-docker.conf,其余一律不进构建上下文 +* +!dist/ +!dist/** +!nginx-docker.conf diff --git a/index.html b/index.html index ca665ec..2fbdb39 100644 --- a/index.html +++ b/index.html @@ -13,9 +13,104 @@ + -
+
+
+ +

加载中…

+

网络较忙时请稍候,请勿关闭页面

+ +
+
+ diff --git a/src/api/customer/index.ts b/src/api/customer/index.ts index 72f162d..5b4ec98 100644 --- a/src/api/customer/index.ts +++ b/src/api/customer/index.ts @@ -37,6 +37,7 @@ export interface CustomerDto { customerGroup?: CustomerGroup memberLevelId?: number | null memberLevelName?: string + priceTierKey?: string | null lastLoginIp?: string lastOnlineIp?: string lastLoginTime?: string @@ -87,6 +88,7 @@ function mapUpdateBody(id: string | number, data: Partial) { customerService: data.customerService, customerGroup: data.customerGroup, memberLevelId: data.memberLevelId, + priceTierKey: data.priceTierKey, } } @@ -132,6 +134,7 @@ export const CustomerService = { customerService: data.customerService, customerGroup: data.customerGroup ?? 0, memberLevelId: data.memberLevelId, + priceTierKey: data.priceTierKey, permissions: data.permissions ?? [], } const r = await axiosInstance.post(omsUrl('/customer/sub/create'), body) @@ -157,6 +160,7 @@ export const CustomerService = { customerService: data.customerService, customerGroup: data.customerGroup ?? 0, memberLevelId: data.memberLevelId, + priceTierKey: data.priceTierKey, inviteCode: data.inviteCode?.trim() || undefined, } const r = await axiosInstance.post(omsUrl('/customer/create'), body) diff --git a/src/api/system/otherConfig.ts b/src/api/system/otherConfig.ts index 15839ab..502c7ec 100644 --- a/src/api/system/otherConfig.ts +++ b/src/api/system/otherConfig.ts @@ -58,6 +58,9 @@ export const TRACK_SERVICE_CONFIG_CODE = 'track_service' /** 微信公众号 */ export const WECHAT_MP_CONFIG_CODE = 'wechat_mp' +/** 微信公众号关注跳转链接 */ +export const WECHAT_MP_FOLLOW_CONFIG_CODE = 'wechat_mp_follow' + /** 店铺授权平台配置编码 */ export const PLATFORM_SHOP_CONFIG_CODES = { common: 'platform_shop', diff --git a/src/api/wechat/index.ts b/src/api/wechat/index.ts index 6d5a592..6507f03 100644 --- a/src/api/wechat/index.ts +++ b/src/api/wechat/index.ts @@ -6,6 +6,7 @@ import type { WeChatCustomerRegisterInput, WeChatCustomerRegisterResult, WeChatOAuthUserInfo, + WxFollowQrcodeResult, WxLoginQrcodeResult, WxLoginResult, } from './types'; @@ -17,7 +18,12 @@ function unwrapOrSelf(body: unknown): T { return body as T; } const record = body as Record; - if ('qrCodeUrl' in record || 'accessToken' in record || 'openid' in record) { + if ( + 'qrCodeUrl' in record || + 'jumpUrl' in record || + 'accessToken' in record || + 'openid' in record + ) { return body as T; } return unwrapData(body); @@ -31,6 +37,12 @@ export async function getLoginQrcode(loginUuid?: string): Promise(res.data); } +/** 获取注册成功后跳转的公众号链接 */ +export async function getFollowQrcode(): Promise { + const res = await axiosInstance.get(omsUrl('/wechat/mp/follow-qrcode')); + return unwrapOrSelf(res.data); +} + /** 查询扫码 key 是否已关联账号(轮询用,无值时不抛错) */ export async function getWxLoginStatus(loginUuid: string): Promise { const res = await axiosInstance.get('/rbac/auth/wx-login/status', { diff --git a/src/api/wechat/types.ts b/src/api/wechat/types.ts index d09f859..679033d 100644 --- a/src/api/wechat/types.ts +++ b/src/api/wechat/types.ts @@ -7,6 +7,14 @@ export interface WxLoginQrcodeResult { expiresIn?: number; } +/** 引导关注公众号跳转 */ +export interface WxFollowQrcodeResult { + /** 微信内直接打开的公众号链接 */ + jumpUrl?: string; + qrCodeUrl?: string; + scene?: string; +} + export interface WxLoginStatusResult { ready: boolean; account?: string; diff --git a/src/components/InvitePoster.vue b/src/components/InvitePoster.vue index 695d5f5..e56fd9a 100644 --- a/src/components/InvitePoster.vue +++ b/src/components/InvitePoster.vue @@ -1,5 +1,5 @@ @@ -1033,7 +1035,7 @@ onMounted(() => { .h5-me-services__label { min-width: 0; flex: 1; - font-size: 12px; + font-size: 10px; font-weight: 700; color: var(--me-ink); line-height: 1.2; diff --git a/src/views/h5/customer-center/price/index.vue b/src/views/h5/customer-center/price/index.vue index 93f6bce..d19fd73 100644 --- a/src/views/h5/customer-center/price/index.vue +++ b/src/views/h5/customer-center/price/index.vue @@ -30,7 +30,7 @@ -
+
{{ t('h5.price.postalCode') }} {{ summaryText }} -

{{ t('h5.price.referenceTip') }}

-
- {{ t('h5.price.ai.title') }} -
-
- - -
+ +
-
- {{ t('h5.price.accuracy.postalCta') }} -
- - -
-
-
-

+

{{ queryHintSummary }}

-

+

{{ t('h5.price.referenceBanner') }}

@@ -238,53 +212,49 @@

{{ item.shippingMethod || item.productCode || '-' }}

-

- - {{ item.productGroupName }} - - - {{ item.cargoTypeName || item.cargoType || '-' }} - - - {{ item.tradeTerms }} - - - {{ t('h5.price.tag.priceOptimal') }} - - - {{ t('h5.price.tag.timeOptimal') }} - - - {{ item.chargeableWeight }}kg - -

+ + {{ t('h5.price.tag.best') }} + {{ item.deliveryTime || '-' }} {{ t('h5.price.workingDays') }}
+ + {{ t('h5.price.tag.best') }} +
¥{{ formatMoney(item.totalCost) }}
- {{ t('h5.price.referencePrice') }} + + {{ tradeTermsLabel(item.tradeTerms) || t('h5.price.referencePrice') }} +
- - {{ item.warehouse || '-' }} - +
+ + {{ item.productGroupName }} + + + {{ item.cargoTypeName || item.cargoType || '-' }} + + + {{ item.warehouse || '-' }} + +
-
-
+
-

{{ detailItem.tradeTerms }}

+

{{ tradeTermsLabel(detailItem.tradeTerms) }}

@@ -557,7 +527,6 @@ const form = reactive({ }); const showDimensions = ref(false); -const postalFieldRef = ref(null); const quoteElMap = new Map(); type Opt = { value: string; label: string; name?: string }; @@ -573,7 +542,6 @@ const queried = ref(false); const queryFailureText = ref(''); const results = ref([]); const queryHint = ref(null); -const hintBannerDismissed = ref(false); const sortMode = ref<'recommend' | 'price' | 'time'>('recommend'); const sortModes = ['recommend', 'price', 'time'] as const; @@ -736,17 +704,6 @@ const detailTitle = computed(() => { return name ? t('h5.price.detailTitleNamed', { name }) : t('h5.price.detailTitle'); }); -const needPostalHint = computed(() => { - if (!queried.value) return false; - if (String(form.postalCode || '').trim()) return false; - const missing = queryHint.value?.missingFieldCodes ?? []; - return ( - queryHint.value?.quoteLevel === 'estimated' || - missing.includes('postalCode') || - missing.includes('PostalCode') - ); -}); - const showQueryHintBanner = computed( () => Boolean(queryHint.value?.disclaimers?.length) || @@ -764,6 +721,15 @@ function formatMoney(val: unknown) { return n.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }); } +function tradeTermsLabel(raw: unknown) { + const value = String(raw ?? '') + .trim() + .toUpperCase(); + if (value === 'DDP') return t('h5.price.tradeTerms.ddp'); + if (value === 'DDU') return t('h5.price.tradeTerms.ddu'); + return ''; +} + function parseTotalCost(cost: unknown) { if (cost == null || cost === '') return Infinity; if (typeof cost === 'number') return cost; @@ -899,13 +865,6 @@ function onPickCargo(code: string) { pickerVisible.value = false; } -function focusPostal() { - hintBannerDismissed.value = false; - postalFieldRef.value?.scrollIntoView?.({ behavior: 'smooth', block: 'center' }); - const input = postalFieldRef.value?.querySelector?.('input') as HTMLInputElement | null; - input?.focus?.(); -} - async function loadOptions() { optionsLoading.value = true; try { @@ -979,7 +938,6 @@ async function handleQuery() { queryLoading.value = true; queried.value = true; queryFailureText.value = ''; - hintBannerDismissed.value = false; clearRecommendInsight(); try { const length = parseOptionalDimension(form.length); @@ -1407,32 +1365,20 @@ onMounted(() => { } .h5-ai-bar { + display: flex; + align-items: center; + gap: 8px; margin-bottom: 10px; - padding: 12px; + padding: 10px 12px; border-radius: 14px; background: #fff; box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04); } -.h5-ai-bar__head { - margin-bottom: 8px; - - strong { - font-size: 13px; - font-weight: 700; - color: #1d2129; - } -} - -.h5-ai-bar__row { - display: flex; - gap: 8px; -} - .h5-ai-bar__input { flex: 1; min-width: 0; - height: 40px; + height: 36px; border: 1px solid #e5e6eb; border-radius: 10px; padding: 0 12px; @@ -1448,7 +1394,7 @@ onMounted(() => { .h5-ai-bar__btn { flex-shrink: 0; - height: 40px; + height: 36px; padding: 0 14px; border: none; border-radius: 10px; @@ -1553,50 +1499,6 @@ onMounted(() => { white-space: nowrap; } -.h5-accuracy { - display: flex; - align-items: flex-start; - justify-content: space-between; - gap: 10px; - margin-bottom: 10px; - padding: 10px 12px; - border-radius: 12px; - background: #fff7e8; - color: #ad6800; - font-size: 12px; - line-height: 1.45; - text-align: left; -} - -.h5-accuracy__actions { - display: flex; - align-items: center; - gap: 4px; - flex-shrink: 0; -} - -.h5-accuracy__fill { - border: none; - border-radius: 8px; - padding: 6px 10px; - background: var(--app-primary-color); - color: #fff; - font-size: 12px; - font-weight: 600; - white-space: nowrap; - cursor: pointer; -} - -.h5-accuracy__dismiss { - border: none; - background: transparent; - color: #86909c; - font-size: 18px; - line-height: 1; - padding: 2px 4px; - cursor: pointer; -} - .picker-shortcuts { display: flex; flex-wrap: wrap; @@ -1833,13 +1735,6 @@ onMounted(() => { text-align: center; } -.quote-ref { - margin: 0; - font-size: 12px; - color: #86909c; - text-align: center; -} - .picker { padding: 0 4px 16px; } @@ -2055,15 +1950,6 @@ onMounted(() => { } } -.h5-quote__sub { - margin: 6px 0 0; - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 5px; - min-width: 0; -} - .h5-quote__chip { display: inline-flex; align-items: center; @@ -2078,54 +1964,59 @@ onMounted(() => { overflow: hidden; text-overflow: ellipsis; + &--group { + color: #4e5969; + background: #f2f3f5; + } + &--cargo { - color: var(--app-primary-color); - background: color-mix(in srgb, var(--app-primary-color) 12%, #fff); + color: #86909c; + background: #f7f8fa; } &--wh { - color: #ff7d00; - background: rgba(255, 125, 0, 0.1); + color: #86909c; + background: #f7f8fa; } } -.h5-quote__weight { - font-size: 11px; - color: #86909c; - line-height: 1.3; - white-space: nowrap; -} - -.h5-quote__tag { - display: inline-flex; - align-items: center; - height: 18px; - padding: 0 6px; - border-radius: 4px; - font-size: 10px; +.h5-quote__corner-tag { + position: absolute; + z-index: 2; + top: 0; + right: 0; + max-width: calc(100% - 2px); + padding: 1px 4px; + border-radius: 3px; + font-size: 9px; font-weight: 700; - line-height: 1; + line-height: 1.2; white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + pointer-events: none; + + &.is-time { + color: #007979; + background: rgba(0, 121, 121, 0.1); + } &.is-price { color: #f53f3f; background: rgba(245, 63, 63, 0.1); } - - &.is-time { - color: #165dff; - background: rgba(22, 93, 255, 0.1); - } } .h5-quote__eta { + position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-width: 56px; - padding: 0 6px; + min-height: 42px; + padding: 10px 6px 0; text-align: center; justify-self: center; } @@ -2133,7 +2024,7 @@ onMounted(() => { .h5-quote__eta-value { font-size: 18px; font-weight: 800; - color: var(--app-primary-color); + color: #007979; line-height: 1.1; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; @@ -2147,9 +2038,12 @@ onMounted(() => { } .h5-quote__price-block { + position: relative; text-align: right; justify-self: end; min-width: 0; + min-height: 42px; + padding-top: 10px; } .ref-label { @@ -2181,11 +2075,15 @@ onMounted(() => { margin-top: 10px; padding-top: 8px; border-top: 1px solid rgba(242, 243, 245, 0.85); +} - .h5-quote__chip--wh { - flex-shrink: 1; - min-width: 0; - } +.h5-quote__meta { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 5px; + min-width: 0; + flex: 1; } .h5-quote__action-btns { diff --git a/src/views/marketing/memberLevel/index.vue b/src/views/marketing/memberLevel/index.vue index b958930..c9b360d 100644 --- a/src/views/marketing/memberLevel/index.vue +++ b/src/views/marketing/memberLevel/index.vue @@ -113,10 +113,6 @@ {{ t('marketing.memberLevel.form.minPoints') }} {{ formState.minPoints ?? 0 }}
-
- {{ t('marketing.memberLevel.form.priceTierKey') }} - {{ formState.priceTierKey || '—' }} -
{{ t('marketing.memberLevel.form.extraDiscountRate') }} {{ previewDiscountText }} @@ -234,22 +230,6 @@ /> - - - - -
@@ -326,7 +306,6 @@ interface MemberLevelRow { levelCode: string levelName: string minPoints: number - priceTierKey: string extraDiscountRate: number sort: number iconUrl: string @@ -340,7 +319,6 @@ interface MemberLevelFormState { levelCode: string levelName: string minPoints: number - priceTierKey: string extraDiscountRate: number sort: number iconUrl: string @@ -360,20 +338,12 @@ const drawerLoading = ref(false) const editingId = ref(undefined) const formRef = ref() -const priceTierOptions = [ - { label: '普通客户', value: '普通客户' }, - { label: 'VIP1', value: 'VIP1' }, - { label: 'VIP2', value: 'VIP2' }, - { label: 'VIP3', value: 'VIP3' }, -] - const formState = reactive(createEmptyForm()) const formRules = computed(() => ({ levelCode: [{ required: true, message: t('marketing.memberLevel.form.levelCodePlaceholder') }], levelName: [{ required: true, message: t('marketing.memberLevel.form.levelNamePlaceholder') }], minPoints: [{ required: true, message: t('marketing.memberLevel.form.minPointsExtra') }], - priceTierKey: [{ required: true, message: t('marketing.memberLevel.form.priceTierKeyPlaceholder') }], status: [{ required: true, message: t('marketing.memberLevel.form.status') }], })) @@ -394,7 +364,6 @@ function createEmptyForm(): MemberLevelFormState { levelCode: '', levelName: '', minPoints: 0, - priceTierKey: '普通客户', extraDiscountRate: 0, sort: 0, iconUrl: '', @@ -419,7 +388,6 @@ function mapRow(item: any): MemberLevelRow { levelCode: item.levelCode ?? item.LevelCode ?? '', levelName: item.levelName ?? item.LevelName ?? '', minPoints: Number(item.minPoints ?? item.MinPoints ?? 0), - priceTierKey: item.priceTierKey ?? item.PriceTierKey ?? '', extraDiscountRate: Number(item.extraDiscountRate ?? item.ExtraDiscountRate ?? 0), sort: Number(item.sort ?? item.Sort ?? 0), iconUrl: String(item.iconUrl ?? item.IconUrl ?? ''), @@ -434,7 +402,6 @@ const hotColumns = computed(() => [ { key: 'levelCode', label: t('marketing.memberLevel.form.levelCode'), width: 100 }, { key: 'levelName', label: t('marketing.memberLevel.form.levelName'), width: 120 }, { key: 'minPoints', label: t('marketing.memberLevel.form.minPoints'), width: 100 }, - { key: 'priceTierKey', label: t('marketing.memberLevel.form.priceTierKey'), width: 120 }, { key: 'extraDiscountRate', label: t('marketing.memberLevel.form.extraDiscountRate'), @@ -493,7 +460,6 @@ function openDrawer(row?: MemberLevelRow) { levelCode: row.levelCode, levelName: row.levelName, minPoints: row.minPoints, - priceTierKey: row.priceTierKey, extraDiscountRate: row.extraDiscountRate, sort: row.sort, iconUrl: row.iconUrl || '', @@ -540,8 +506,7 @@ async function handleDrawerOk() { } const levelCode = String(formState.levelCode || '').trim() const levelName = String(formState.levelName || '').trim() - const priceTierKey = String(formState.priceTierKey || '').trim() - if (!levelCode || !levelName || !priceTierKey) { + if (!levelCode || !levelName) { Message.warning(t('marketing.memberLevel.form.requiredHint')) return } @@ -552,7 +517,6 @@ async function handleDrawerOk() { levelCode, levelName, minPoints: Number(formState.minPoints ?? 0), - priceTierKey, extraDiscountRate: Number(formState.extraDiscountRate ?? 0), sort: Number(formState.sort ?? 0), iconUrl: String(formState.iconUrl || '').trim() || undefined, diff --git a/src/views/order/myOrders/index.vue b/src/views/order/myOrders/index.vue index 750680a..0e13f72 100644 --- a/src/views/order/myOrders/index.vue +++ b/src/views/order/myOrders/index.vue @@ -18,20 +18,14 @@ postOrderDelete, postOrderPrint, postOrderExport, - postOrderTrackUpsertSmallBag, - postOrderDownstreamForwardCreateOne, postOrderBatchJob, waitOrderBatchJob, - formatBatchJobTrackUpsertResultText, - formatBatchJobDownstreamForwardResultText, isOrderBatchQueueDisabledError, formatBatchJobFailureMessage, formatBatchJobSummaryMessage, resolveBatchJobItemRowLabel, parseBatchJobPrintUrl, postOrderHandleStatusUpdate, - type OrderTrackUpsertResult, - type OrderDownstreamForwardResult, } from '@/api/order'; import { notifyCustomerBalanceChanged } from '@/api/customer/accountFlow'; import { buildFailGuideFromReason } from '@/utils/parcelCreateFailGuide'; @@ -227,17 +221,6 @@ /** 按当前状态收敛工具栏,避免客户在无关 Tab 看到一排无效按钮 */ const showPayAction = computed(() => isActiveTab('all', 'pendingPayment')); const showPredeclareAction = computed(() => isActiveTab('all', 'draft', 'predeclared')); - const showDownstreamAction = computed(() => - isActiveTab( - 'all', - 'draft', - 'predeclared', - 'received', - 'pendingPayment', - 'pendingShip', - 'pendingOnline', - ), - ); const showPrintAction = computed(() => isActiveTab( 'all', @@ -258,9 +241,6 @@ isActiveTab('all', 'pendingShip', 'pendingOnline', 'shipping'), ); const showDeleteAction = computed(() => isActiveTab('all', 'draft', 'predeclared')); - const showCreateTrackAction = computed(() => - isActiveTab('all', 'pendingOnline', 'shipping', 'deliverySuccess', 'deliveryFailed'), - ); const problematicModalVisible = ref(false); const claimedModalVisible = ref(false); @@ -394,31 +374,6 @@ const batchPrintVisible = ref(false); const singlePrintItems = ref>([]); const batchPrintItems = ref>([]); - const trackUpsertModalVisible = ref(false); - const trackUpsertResultText = ref(''); - const downstreamForwardModalVisible = ref(false); - const downstreamForwardResultText = ref(''); - - function formatTrackUpsertResult(waybillNo: string, result: OrderTrackUpsertResult): string { - const lines = [`【${waybillNo || '-'}】`]; - if (result.skipped) { - lines.push(`跳过:${result.skipReason || '未知原因'}`); - return lines.join('\n'); - } - lines.push(`HTTP:${result.statusCode ?? '-'}`); - lines.push(`成功:${result.success ? '是' : '否'}`); - if (result.responseBody) { - lines.push(`响应:${result.responseBody}`); - } - if (result.curlCommand) { - lines.push('curl:'); - lines.push(result.curlCommand); - } else if (result.requestJson) { - lines.push(`请求:${result.requestJson}`); - } - return lines.join('\n'); - } - async function runSelectedOrderBatch(options: { action: string; rows: any[]; @@ -466,121 +421,6 @@ await options.syncRunner(); } - async function runTrackUpsertBatch(rows: any[]) { - const orderIds = rows.map((row) => Number(getOrderRowId(row)!)); - try { - const job = await postOrderBatchJob({ action: 'track-upsert-small-bag', orderIds }); - const result = await waitOrderBatchJob(job.jobId); - if (result.timedOut) { - trackUpsertResultText.value = `${formatBatchJobSummaryMessage(result.job, { timedOut: true, jobId: job.jobId })}\n\n${formatBatchJobTrackUpsertResultText('创建轨迹', result.job, result.items, rows)}`; - trackUpsertModalVisible.value = true; - return; - } - const { job: finishedJob, items } = result; - trackUpsertResultText.value = formatBatchJobTrackUpsertResultText('创建轨迹', finishedJob, items, rows); - trackUpsertModalVisible.value = true; - return; - } catch (e: any) { - if (!isOrderBatchQueueDisabledError(e)) { - throw e; - } - } - - const resultBlocks: string[] = []; - for (const row of rows) { - const id = getOrderRowId(row)!; - const waybillNo = row.waybillNo || row.serviceNo || String(id); - try { - const result = await postOrderTrackUpsertSmallBag({ id }); - resultBlocks.push(formatTrackUpsertResult(waybillNo, result)); - } catch (err: any) { - resultBlocks.push(`【${waybillNo}】失败:${err?.message || '请求异常'}`); - } - } - trackUpsertResultText.value = resultBlocks.join('\n\n'); - trackUpsertModalVisible.value = true; - } - - const handleCreateTrackOrder = async () => { - const rows = requireSelectedRows(); - if (!rows.length) return; - await withOrderActionLoading('track', async () => { - await runTrackUpsertBatch(rows); - }).catch(() => undefined); - }; - - function formatDownstreamForwardResult( - waybillNo: string, - result: OrderDownstreamForwardResult - ): string { - const lines = [ - `【${waybillNo || '-'}】`, - result.success ? '成功' : '失败', - `standardCode:createOrderOne`, - ]; - if (result.supplierCode) { - lines.push(`supplierCode:${result.supplierCode}`); - } - if (result.downstreamServiceNo) { - lines.push(`服务商单号:${result.downstreamServiceNo}`); - } - if (result.trackNo) { - lines.push(`跟踪号:${result.trackNo}`); - } - lines.push(`请求:${result.url || '-'}`); - if (result.requestJson) { - lines.push(`请求体:\n${result.requestJson}`); - } - lines.push(`HTTP:${result.statusCode ?? '-'}`); - if (result.responseBody) { - lines.push(`响应:\n${result.responseBody}`); - } - return lines.join('\n'); - } - - async function runDownstreamForwardBatch(rows: any[]) { - const orderIds = rows.map((row) => Number(getOrderRowId(row)!)); - try { - const job = await postOrderBatchJob({ action: 'downstream-forward-create-one', orderIds }); - const result = await waitOrderBatchJob(job.jobId); - if (result.timedOut) { - downstreamForwardResultText.value = `${formatBatchJobSummaryMessage(result.job, { timedOut: true, jobId: job.jobId })}\n\n${formatBatchJobDownstreamForwardResultText('预报下游', result.job, result.items, rows)}`; - downstreamForwardModalVisible.value = true; - return; - } - const { job: finishedJob, items } = result; - downstreamForwardResultText.value = formatBatchJobDownstreamForwardResultText('预报下游', finishedJob, items, rows); - downstreamForwardModalVisible.value = true; - return; - } catch (e: any) { - if (!isOrderBatchQueueDisabledError(e)) { - throw e; - } - } - - const resultBlocks: string[] = []; - for (const row of rows) { - const id = getOrderRowId(row)!; - const waybillNo = row.waybillNo || row.serviceNo || String(id); - try { - const result = await postOrderDownstreamForwardCreateOne({ id }); - resultBlocks.push(formatDownstreamForwardResult(waybillNo, result)); - } catch (err: any) { - resultBlocks.push(`【${waybillNo}】失败:${err?.message || '请求异常'}`); - } - } - downstreamForwardResultText.value = resultBlocks.join('\n\n'); - downstreamForwardModalVisible.value = true; - } - - const handleForwardDownstreamCreate = async () => { - const rows = requireSelectedRows(); - if (!rows.length) return; - await withOrderActionLoading('downstream', async () => { - await runDownstreamForwardBatch(rows); - }).catch(() => undefined); - }; - function getOrderRowId(row: any): number | string | undefined { if (row == null) return undefined; const id = row.id ?? row.Id; @@ -1053,7 +893,6 @@ if (key === 'stockBind') return openStockBindModal(); if (key === 'createProblematic') return openProblematicModal(); if (key === 'createClaimed') return openClaimedModal(); - if (key === 'createTrackOrder') return handleCreateTrackOrder(); if (key === 'intercept') return handleIntercept(); if (key === 'cancelIntercept') return handleCancelIntercept(); if (key === 'delete') return handleDelete(); @@ -1331,13 +1170,6 @@ :disabled="isActionBusy('predeclare')" @click="handlePreDeclare" >{{ t('order.myOrders.actions.predeclare') }} - {{ t('order.myOrders.actions.forwardDownstreamCreate') }} {{ t('order.myOrders.actions.createClaimed') }} - {{ t('order.myOrders.actions.createTrackOrder') }} - -
{{ trackUpsertResultText }}
-
- - -
{{ downstreamForwardResultText }}
-
- \ No newline at end of file diff --git a/src/views/order/priceCheck/components/AiRecommendCard.vue b/src/views/order/priceCheck/components/AiRecommendCard.vue index eb8b79f..d404240 100644 --- a/src/views/order/priceCheck/components/AiRecommendCard.vue +++ b/src/views/order/priceCheck/components/AiRecommendCard.vue @@ -1,10 +1,6 @@