From 22f0528593e79b534e9227497ccd1bbdf65e6c6d Mon Sep 17 00:00:00 2001 From: wujinliang <2318309077@qq.com> Date: Thu, 27 Aug 2026 21:49:18 +0800 Subject: [PATCH] 1 --- .idea/.gitignore | 8 ++++++++ .idea/client-web.iml | 9 +++++++++ .idea/misc.xml | 6 ++++++ .idea/modules.xml | 8 ++++++++ .idea/vcs.xml | 6 ++++++ docker-compose.test.yml | 2 +- src/deployment/nginxConfig.test.mjs | 1 + src/modules/first-leg/api/firstLeg.ts | 1 + src/modules/first-leg/store/firstLegOrders.test.mjs | 3 ++- src/modules/first-leg/store/firstLegOrders.ts | 2 +- src/modules/notifications/views/NotificationsView.vue | 11 +++++++++++ .../tenant-management/api/merchantIam.test.mjs | 9 +++++++++ src/modules/tenant-management/contracts.ts | 9 +++++++++ src/modules/tenant-management/views/MembersView.vue | 2 +- 14 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/client-web.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/client-web.iml b/.idea/client-web.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/client-web.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..07115cd --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e8c26cd --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/docker-compose.test.yml b/docker-compose.test.yml index 53790ad..c3d40ea 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -4,7 +4,7 @@ services: context: . dockerfile: Dockerfile args: - VITE_ADMIN_WEB_ORIGIN: "${VITE_ADMIN_WEB_ORIGIN:-}" + VITE_ADMIN_WEB_ORIGIN: "${VITE_ADMIN_WEB_ORIGIN:-https://test-admin.buggoglobal.com}" NODE_IMAGE: "${NODE_BASE_IMAGE:-node:22-alpine}" NGINX_IMAGE: "${NGINX_BASE_IMAGE:-nginx:1.27-alpine}" image: client-web-test:local diff --git a/src/deployment/nginxConfig.test.mjs b/src/deployment/nginxConfig.test.mjs index 809f9b8..c8f4703 100644 --- a/src/deployment/nginxConfig.test.mjs +++ b/src/deployment/nginxConfig.test.mjs @@ -14,6 +14,7 @@ test('allows qualification uploads with multipart overhead through the API proxy test('routes domestic and overseas browser APIs to their test gateways without duplicate api prefixes', () => { assert.match(testCompose, /API_UPSTREAM: "http:\/\/test-api-cn\.buggoglobal\.com"/) assert.match(testCompose, /OVERSEAS_API_UPSTREAM: "http:\/\/test-api-global\.buggoglobal\.com"/) + assert.match(testCompose, /VITE_ADMIN_WEB_ORIGIN: "\$\{VITE_ADMIN_WEB_ORIGIN:-https:\/\/test-admin\.buggoglobal\.com\}"/) assert.match(config, /location \/overseas-api\/ \{[\s\S]*?rewrite \^\/overseas-api\/\(\.\*\)\$ \/api\/\$1 break;[\s\S]*?proxy_pass \$\{OVERSEAS_API_UPSTREAM\};/) assert.match(config, /proxy_set_header Host \$proxy_host;/) assert.doesNotMatch(config, /\/api\/api/) diff --git a/src/modules/first-leg/api/firstLeg.ts b/src/modules/first-leg/api/firstLeg.ts index fac2bbb..f11a035 100644 --- a/src/modules/first-leg/api/firstLeg.ts +++ b/src/modules/first-leg/api/firstLeg.ts @@ -238,6 +238,7 @@ export interface MerchantFirstLegOrderRow { inboundCode: string | null channelName: string | null destinationType: ApiDestinationType | null + pickupMethod: ApiPickupMethod | null customerName: string | null receivingCompanyName: string | null specificationModel: string | null diff --git a/src/modules/first-leg/store/firstLegOrders.test.mjs b/src/modules/first-leg/store/firstLegOrders.test.mjs index 17fc525..db004c8 100644 --- a/src/modules/first-leg/store/firstLegOrders.test.mjs +++ b/src/modules/first-leg/store/firstLegOrders.test.mjs @@ -12,13 +12,14 @@ test('maps the first-leg aggregate list fields without loading detail rows', () assert.match(apiSource, /cargoes\?: Array<\{ skuNo\?: string \| null \}>/) assert.match(apiSource, /apiRequest>/) assert.match(storeSource, /function mapFirstLegOrderRow/) - for (const field of ['inboundId', 'inboundCode', 'channelName', 'destinationWarehouseName', 'packageCount', 'expressCompany', 'trackingNo', 'totalGrossWeightKg', 'totalNetWeightKg', 'totalVolumeCbm', 'totalQuantity', 'remark', 'shipmentId', 'referenceId', 'createdAt']) { + for (const field of ['inboundId', 'inboundCode', 'channelName', 'destinationWarehouseName', 'pickupMethod', 'packageCount', 'expressCompany', 'trackingNo', 'totalGrossWeightKg', 'totalNetWeightKg', 'totalVolumeCbm', 'totalQuantity', 'remark', 'shipmentId', 'referenceId', 'createdAt']) { assert.match(storeSource, new RegExp(`row\\.${field}`)) } assert.match(storeSource, /row\.skuNos/) assert.match(storeSource, /row\.cargoes/) assert.match(storeSource, /chargeableWeightKg: null/) assert.match(storeSource, /chargeableVolumeCbm: null/) + assert.match(apiSource, /pickupMethod: ApiPickupMethod \\| null/) assert.match(storeSource, /orderResult\.value\.records\.map\(mapFirstLegOrderRow\)/) assert.match(storeSource, /orderResult\.value\.records\.map\(\(item\) => mapUnifiedOrderRow\(item, warehouses\.value\)\)/) }) diff --git a/src/modules/first-leg/store/firstLegOrders.ts b/src/modules/first-leg/store/firstLegOrders.ts index e6e56de..8fd10d9 100644 --- a/src/modules/first-leg/store/firstLegOrders.ts +++ b/src/modules/first-leg/store/firstLegOrders.ts @@ -398,7 +398,7 @@ function mapFirstLegOrderRow(row: MerchantFirstLegOrderRow): FirstLegOrder { inboundId: row.inboundId == null ? '' : String(row.inboundId), inboundCode: row.inboundCode ?? '', }, createdAt: row.createdAt, updatedAt: row.createdAt, tradeTerm: '', destinationCountryCode: '', destinationWarehouseId: '', - destinationWarehouseName: row.destinationWarehouseName ?? '', pickupMethod: 'SELF_EXPRESS', channelCode: '', + destinationWarehouseName: row.destinationWarehouseName ?? '', pickupMethod: row.pickupMethod ?? 'SELF_EXPRESS', channelCode: '', channelName: row.channelName ?? '', pricingTaxMode: 'TAX_INCLUDED', carrierId: '', carrierName: '', taxMode: 'BUY_DECLARATION', customsInspection: false, destinationType: row.destinationType ?? 'PRIVATE', amazonWarehouseCode: '', shipmentId: row.shipmentId ?? row.internationalOrderNo ?? '', requestedPickupAt: '', receivingTime: '', submittedAt: '', completedAt: '', diff --git a/src/modules/notifications/views/NotificationsView.vue b/src/modules/notifications/views/NotificationsView.vue index 55eada1..bf73626 100644 --- a/src/modules/notifications/views/NotificationsView.vue +++ b/src/modules/notifications/views/NotificationsView.vue @@ -44,4 +44,15 @@ onMounted(() => { void Promise.all([load(), notifications.refreshUnreadCount()]) diff --git a/src/modules/tenant-management/api/merchantIam.test.mjs b/src/modules/tenant-management/api/merchantIam.test.mjs index ab11e9c..c23acc3 100644 --- a/src/modules/tenant-management/api/merchantIam.test.mjs +++ b/src/modules/tenant-management/api/merchantIam.test.mjs @@ -107,3 +107,12 @@ test('keeps client baseline permissions selected when server resources do not de assert.match(permissionsViewSource, /:disabled="isRequiredPermission\(item\.code\)"/) assert.doesNotMatch(permissionsViewSource, /selectedCodes\.value\.unshift\('account:profile:view'\)/) }) + +test('exposes all message-center permissions in the enterprise role editor', () => { + for (const permission of ['merchant:notification:view', 'merchant:notification:read', 'merchant:notification:read-all']) { + assert.match(contractsSource, new RegExp(`code: '${permission}'`)) + assert.match(contractsSource, new RegExp(`'${permission}': \\['${permission}'\\]`)) + } + assert.match(contractsSource, /key: 'notifications'/) + assert.match(storeSource, /const mappedMerchantPermissionCodes = new Set\(Object\.values\(FRONTEND_TO_MERCHANT_PERMISSION_CODES\)\.flat\(\)\)/) +}) diff --git a/src/modules/tenant-management/contracts.ts b/src/modules/tenant-management/contracts.ts index 52a0831..b146221 100644 --- a/src/modules/tenant-management/contracts.ts +++ b/src/modules/tenant-management/contracts.ts @@ -25,6 +25,15 @@ export const TENANT_PERMISSION_GROUPS: readonly TenantPermissionGroup[] = [ label: '业务总览', items: [{ code: 'dashboard:view', label: '查看总览', description: '所有企业成员默认可用,可查看企业统计和最近订单' }], }, + { + key: 'notifications', + label: '消息中心', + items: [ + { code: 'merchant:notification:view', label: '查看我的消息', description: '查看本企业和当前成员可见的站内消息' }, + { code: 'merchant:notification:read', label: '标记消息已读', description: '将已查看的站内消息标记为已读' }, + { code: 'merchant:notification:read-all', label: '全部标记已读', description: '将当前成员的全部站内消息标记为已读' }, + ], + }, { key: 'finance', label: '财务账单', diff --git a/src/modules/tenant-management/views/MembersView.vue b/src/modules/tenant-management/views/MembersView.vue index b49c681..4dc0154 100644 --- a/src/modules/tenant-management/views/MembersView.vue +++ b/src/modules/tenant-management/views/MembersView.vue @@ -200,7 +200,7 @@ async function resetPassword(member: TenantMember) {
- +
请通过安全渠道将初始密码交给成员;前端不会保存或再次展示该密码。