From 9922d20141a98ae4fccd100c89ac029c005a78d9 Mon Sep 17 00:00:00 2001 From: zzh <1368735060@qq.com> Date: Wed, 7 Oct 2026 15:08:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=BB=98=E8=AE=A4=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E8=83=8C=E6=99=AF=E8=81=94=E5=8A=A8=E5=8A=A0=E8=BD=BD=E9=A1=B5?= =?UTF-8?q?=EF=BC=8C=E5=AE=98=E7=BD=91=E5=85=A5=E5=8F=A3=E4=B8=8E=E7=BA=BF?= =?UTF-8?q?=E8=B7=AF=E9=9D=A2=E6=9D=BF=E4=BD=93=E9=AA=8C=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 页面背景默认改为默认灰并同步启动屏;顶栏/登录头可回官网;线路卡片与话题面板顾问入口改为图标。 Co-authored-by: Cursor --- index.html | 24 +- src/api/channel/salesProduct.ts | 32 +- src/api/channel/serviceChannel.ts | 36 +- src/assets/style/global.less | 2 +- src/components/ApiTest/index.vue | 6 +- src/components/CustomLeftMenu/index.vue | 19 +- src/components/HandsontablePro/index.vue | 83 +- src/components/top-nav/index.vue | 90 +- src/config/settings.json | 2 +- src/locale/en-US.ts | 17 + src/locale/zh-CN.ts | 21 +- src/styles/dark-mode.less | 2 +- src/utils/auditFields.ts | 50 + src/utils/pageBackground.ts | 2 +- src/utils/publishSnapshotDiff.ts | 17 + src/views/api/downstreamInterface/index.vue | 38 +- src/views/api/requestLog/index.vue | 40 +- src/views/api/upstreamInterface/index.vue | 135 +- .../components/BillingConditionEditor.vue | 90 +- .../components/BillingSimulateDrawer.vue | 2 +- .../components/PriceListHotTable.vue | 590 ++++ src/views/channel/salesProducts/index.vue | 2861 +++++++++++------ src/views/channel/serviceChannels/index.vue | 2327 +++++++++----- src/views/channel/weightRounding/index.vue | 28 +- src/views/channel/weightRules/index.vue | 24 +- .../login/components/pwd-login/index.vue | 18 +- src/views/login/index.vue | 10 + src/views/order/customs9610Order/index.vue | 3 +- src/views/order/myOrders/index.vue | 141 +- src/views/order/pickupOrder/index.vue | 67 +- src/views/order/platformStoreOrder/index.vue | 54 +- src/views/order/waybillManage/index.vue | 131 +- src/views/site/SiteHeader.vue | 1 + src/views/site/SiteRoutesPanel.vue | 34 +- src/views/site/SiteTopicPanel.vue | 58 +- src/views/site/index.vue | 2 +- src/views/site/styles/ai-advisor.css | 258 +- src/views/site/styles/main.css | 2 +- src/views/track/trackOrder/index.vue | 52 +- 39 files changed, 5304 insertions(+), 2065 deletions(-) create mode 100644 src/utils/auditFields.ts create mode 100644 src/views/channel/salesProducts/components/PriceListHotTable.vue diff --git a/index.html b/index.html index 62b8e66..3f1593d 100644 --- a/index.html +++ b/index.html @@ -56,14 +56,24 @@ var isH5 = isH5Path; var isEn = false; + var pageBg = '#f0f3f4'; try { var locale = localStorage.getItem('arco-locale') || localStorage.getItem('locale') || ''; isEn = /^en/i.test(locale); + var storedBg = localStorage.getItem('app-page-background-color'); + if (storedBg && /^#?[0-9a-fA-F]{6}$/.test(storedBg)) { + pageBg = storedBg.charAt(0) === '#' ? storedBg : '#' + storedBg; + } } catch (e) {} var root = document.documentElement; if (isH5) root.classList.add('app-boot-h5'); if (isEn) root.classList.add('app-boot-en'); + /* 加载页与 OMS/官网共用页面背景配置,首屏前写入避免闪色 */ + root.style.setProperty('--app-page-bg', pageBg); + root.style.setProperty('--kc-page-bg', pageBg); + root.style.setProperty('--ai-bg', pageBg); + root.style.setProperty('--ai-canvas', pageBg); try { document.title = isH5 ? isEn @@ -100,7 +110,7 @@ * 常驻 stable 会在右侧留出约 15px 空缝,贯穿 fixed 顶栏。 */ html { - background: #f5f4f1; + background: var(--app-page-bg, #f0f3f4); } html.app-boot-site #app-boot { display: none !important; @@ -118,7 +128,7 @@ #app { margin: 0; min-height: 100%; - background: #f5f4f1; + background: var(--app-page-bg, #f0f3f4); } #app-boot { position: fixed; @@ -133,7 +143,7 @@ display: flex; align-items: center; justify-content: center; - background: #f5f4f1; + background: var(--app-page-bg, #f0f3f4); /* * 必须与 global.less 首屏后状态一致: * Vue 加载后 html 会带上 antialiased,若 boot 首帧没有,中文会突然变细像「字号缩小」。 @@ -272,9 +282,9 @@ #app-boot.is-timeout .boot-sub { color: #86909c; } - /* H5:样式挂在 html.app-boot-h5 上,首屏即正确,不再二次改字号/Logo */ + /* H5:样式挂在 html.app-boot-h5 上,首屏即正确,不再二次改字号/Logo;背景随页面背景配置 */ html.app-boot-h5 { - background: #f5f6f8; + background: var(--app-page-bg, #f0f3f4); } html.app-boot-h5.app-booting { scrollbar-gutter: stable; @@ -282,10 +292,10 @@ html.app-boot-h5, html.app-boot-h5 body, html.app-boot-h5 #app { - background: #f5f6f8; + background: var(--app-page-bg, #f0f3f4); } html.app-boot-h5 #app-boot { - background: #f5f6f8; + background: var(--app-page-bg, #f0f3f4); padding: env(safe-area-inset-top, 0) 24px env(safe-area-inset-bottom, 0); } html.app-boot-h5 #app-boot .boot-panel { diff --git a/src/api/channel/salesProduct.ts b/src/api/channel/salesProduct.ts index 09d9ebe..09c096c 100644 --- a/src/api/channel/salesProduct.ts +++ b/src/api/channel/salesProduct.ts @@ -81,15 +81,29 @@ export async function saveSalesProductCustomerGuide(body: { assertBusinessOk(res.data) } -/** 卖价 */ -export async function getSalesProductPriceList(salesProductId: number | string) { +/** 卖价列表;列表页请传 includeDetails:false,避免拉回整张价格矩阵导致卡顿 */ +export async function getSalesProductPriceList( + salesProductId: number | string, + opts?: { includeDetails?: boolean }, +) { const res = await axiosInstance.get(omsUrl('/channel/sales-product/price/list'), { - params: { salesProductId }, + params: { + salesProductId, + includeDetails: opts?.includeDetails ?? true, + }, }) const { items } = parseListPayload(res.data) return items ?? [] } +/** 单条卖价(含 factors/details),编辑弹窗按需加载 */ +export async function getSalesProductPrice(id: number | string) { + const res = await axiosInstance.get(omsUrl('/channel/sales-product/price/get'), { + params: { id }, + }) + return unwrapData(res.data) ?? res.data?.data ?? res.data +} + export async function createSalesProductPrice(body: Record) { const res = await axiosInstance.post(omsUrl('/channel/sales-product/price/create'), body) assertBusinessOk(res.data) @@ -150,6 +164,8 @@ export async function getSalesProductPublishPriceList(params: { salesProductId: number | string page?: number pageSize?: number + /** false 时后端不返回快照正文,用于版本头展示 */ + includeContent?: boolean }) { const res = await axiosInstance.get(omsUrl('/channel/sales-product/publish/price/list'), { params }) return parseListPayload(res.data) @@ -159,11 +175,21 @@ export async function getSalesProductPublishRulesList(params: { salesProductId: number | string page?: number pageSize?: number + /** false 时只返回版本头,不带快照正文 */ + includeContent?: boolean }) { const res = await axiosInstance.get(omsUrl('/channel/sales-product/publish/rules/list'), { params }) return parseListPayload(res.data) } +/** 单条发布记录(含快照正文) */ +export async function getSalesProductPublishRecord(id: number | string) { + const res = await axiosInstance.get(omsUrl('/channel/sales-product/publish/get'), { + params: { id }, + }) + return unwrapData(res.data) ?? res.data?.data ?? res.data +} + /** 预览即将发布的快照(不落库),用于发布弹窗与发布记录核对 */ export async function getSalesProductPublishPreview(params: { salesProductId: number | string diff --git a/src/api/channel/serviceChannel.ts b/src/api/channel/serviceChannel.ts index 9e4d9c5..b6ceffc 100644 --- a/src/api/channel/serviceChannel.ts +++ b/src/api/channel/serviceChannel.ts @@ -1,7 +1,22 @@ import { axiosInstance } from '@/api/rbac' -import { assertBusinessOk, omsUrl, parseListPayload } from '@/api/oms/common' +import { assertBusinessOk, omsUrl, parseListPayload, unwrapData } from '@/api/oms/common' import { ENABLE_STATUS, isEnableStatusEnabled, toEnableStatus } from '@/utils/enableStatus' +/** 渠道下拉:全部名称,不分页 */ +export async function getServiceChannelOptions() { + const res = await axiosInstance.get(omsUrl('/channel/service-channel/options')) + const body = res.data + if (Array.isArray(body)) return body + assertBusinessOk(body) + const raw = body?.data ?? body?.Data ?? body?.result ?? body?.Result ?? body + if (Array.isArray(raw)) return raw + if (raw && typeof raw === 'object') { + const items = (raw as any).items ?? (raw as any).Items ?? (raw as any).list ?? (raw as any).List + if (Array.isArray(items)) return items + } + return [] +} + export async function getServiceChannelList(params: { page?: number pageSize?: number @@ -181,15 +196,30 @@ export async function deleteServiceChannelGroup(id: number | string) { assertBusinessOk(res.data) } -export async function getServiceChannelPriceList(serviceChannelId: number | string) { +/** 买价列表;列表页请传 includeDetails:false,避免拉回整张价格矩阵导致卡顿 */ +export async function getServiceChannelPriceList( + serviceChannelId: number | string, + opts?: { includeDetails?: boolean }, +) { const res = await axiosInstance.get(omsUrl('/channel/service-channel/price/list'), { - params: { serviceChannelId }, + params: { + serviceChannelId, + includeDetails: opts?.includeDetails ?? true, + }, }) // 与 parseListPayload 一致:兼容 data 为数组、{ items }、{ list } 等 const { items } = parseListPayload(res.data) return items } +/** 单条买价(含 factors/details),编辑弹窗按需加载 */ +export async function getServiceChannelPrice(id: number | string) { + const res = await axiosInstance.get(omsUrl('/channel/service-channel/price/get'), { + params: { id }, + }) + return unwrapData(res.data) ?? res.data?.data ?? res.data +} + export async function createServiceChannelPrice(body: Record) { const res = await axiosInstance.post(omsUrl('/channel/service-channel/price/create'), body) assertBusinessOk(res.data) diff --git a/src/assets/style/global.less b/src/assets/style/global.less index 5f7f059..a0a43cf 100644 --- a/src/assets/style/global.less +++ b/src/assets/style/global.less @@ -5,7 +5,7 @@ --app-primary-color-light: #eef3f6; --app-navbar-bg: #054f74; --app-sidebar-bg: #054f74; - --app-page-bg: #f5f4f1; + --app-page-bg: #f0f3f4; --app-card-bg: #ffffff; --app-card-border: #e5e6eb; --app-elevated-bg: #ffffff; diff --git a/src/components/ApiTest/index.vue b/src/components/ApiTest/index.vue index c220514..049e8a9 100644 --- a/src/components/ApiTest/index.vue +++ b/src/components/ApiTest/index.vue @@ -1,5 +1,5 @@