diff --git a/web/src/views/goauto/pdd-products/index.vue b/web/src/views/goauto/pdd-products/index.vue index 87978e3..fd3bc88 100644 --- a/web/src/views/goauto/pdd-products/index.vue +++ b/web/src/views/goauto/pdd-products/index.vue @@ -106,7 +106,11 @@ let uid = 0 export default { name: 'GoAutoPddProducts', setup() { return { Plus, RefreshLeft, Search } }, data() { return { loading: false, products: [], selectedProducts: [], total: 0, query: { page: 1, pageSize: 20, keyword: '', status: '' }, createDialog: { open: false, saving: false }, createData: { url: '' }, batch: this.emptyBatch(), batchData: { ruleId: null, deviceId: null }, batchRules: { ruleId: [{ required: true, message: '请选择采集规则', trigger: 'change' }] }, detail: { open: false, loading: false, product: null }, edit: { open: false, loading: false, saving: false, productId: null }, editData: this.emptyEdit(), urlRules: { url: [{ required: true, message: '请输入 PDD 商品链接', trigger: 'blur' }, { max: 4096, message: '链接不能超过 4096 个字符', trigger: 'blur' }] }} }, - created() { this.load() }, + created() { + this.load() + const productId = Number(this.$route.query.productId) + if (Number.isInteger(productId) && productId > 0) this.openDetail(productId) + }, methods: { emptyEdit() { return { url: '', title: '', shopName: '', salesCount: null, reviewCount: null, status: 'active', specs: [] } }, emptyBatch() { return { open: false, saving: false, step: 'confirm', products: [], options: { rules: [], devices: [] }, results: [], successCount: 0, failureCount: 0 } }, diff --git a/web/src/views/goauto/syb-products/index.vue b/web/src/views/goauto/syb-products/index.vue index c6568b4..d5e9866 100644 --- a/web/src/views/goauto/syb-products/index.vue +++ b/web/src/views/goauto/syb-products/index.vue @@ -233,10 +233,15 @@ export default { const route = this.$router.resolve({ path: '/shopee-products/index', query }) window.open(route.href, '_blank', 'noopener') }, + openPddDetail(pddProductId) { + if (!pddProductId) { ElMessage.warning('该明细尚未关联 PDD 商品'); return } + const route = this.$router.resolve({ path: '/pdd-products/index', query: { productId: pddProductId }}) + window.open(route.href, '_blank', 'noopener') + }, openPurchaseTask(taskId) { this.$router.push({ path: '/purchase-tasks/index', query: { taskId }}) }, runPurchaseNextAction(row, readiness) { if (readiness.nextAction === 'open_mapping' || readiness.nextAction === 'open_shopee') return this.openShopeeDetail(row.shopeeProductId, row.targetColor) - if (readiness.nextAction === 'open_pdd') return this.openShopeeDetail(row.shopeeProductId, row.targetColor) + if (readiness.nextAction === 'open_pdd') return this.openPddDetail(readiness.pddProductId) if (readiness.nextAction === 'open_task' && readiness.activeTaskId) return this.openPurchaseTask(readiness.activeTaskId) if (readiness.nextAction === 'reparse') return this.openDetail(row.sybProductId || row.id) if (readiness.nextAction === 'select_device') { this.purchaseResult.open = false; return this.load() } diff --git a/web/tests/e2e/pdd-product-module.spec.ts b/web/tests/e2e/pdd-product-module.spec.ts index 2b5abc6..ea81be2 100644 --- a/web/tests/e2e/pdd-product-module.spec.ts +++ b/web/tests/e2e/pdd-product-module.spec.ts @@ -64,6 +64,27 @@ test('PDD 商品列表、详情和编辑流程符合已确认原型', async ({ p expect(updatePayload.specs[0].values[0].priceCent).toBe(2590); }); +test('带 productId 的 PDD 商品路由自动打开对应详情', async ({ page, context }) => { + let requestedProductId = ''; + await context.addCookies([{ name: 'Admin-Token', value: 'prototype-test-token', domain: 'localhost', path: '/' }]); + await page.route('**/api/**', async route => { + const url = new URL(route.request().url()); + if (url.pathname.startsWith('/src/api/')) return route.continue(); + if (url.pathname.endsWith('/api/v1/getinfo')) return route.fulfill({ json: { code: 200, data: { roles: ['admin'], name: '管理员', avatar: '', introduction: '', permissions: [] } } }); + if (url.pathname.endsWith('/api/admin/v1/pdd-products/1')) { + requestedProductId = '1'; + return route.fulfill({ json: { code: 200, data: { product } } }); + } + if (url.pathname.endsWith('/api/admin/v1/pdd-products')) return route.fulfill({ json: { code: 200, data: { items: [product], total: 1, page: 1, pageSize: 20 } } }); + return route.fulfill({ json: { code: 200, data: [] } }); + }); + + await page.goto('http://localhost:9527/#/pdd-products/index?productId=1'); + await expect(page.getByText('PDD 商品详情')).toBeVisible(); + await expect(page.locator('.el-drawer').getByText('夏季防晒冰丝袖套', { exact: true })).toBeVisible(); + expect(requestedProductId).toBe('1'); +}); + test('PDD 商品当前页多选并批量创建独立采集任务', async ({ page, context }) => { const second = { ...product, id: 2, goodsId: '719834019024', title: '第二件商品' }; const disabled = { ...product, id: 3, goodsId: '731370706977', title: '已停用商品', status: 'disabled', collectionSelectable: false, collectionDisabledReason: '商品已停用' }; diff --git a/web/tests/e2e/syb-product-layout.spec.ts b/web/tests/e2e/syb-product-layout.spec.ts index 03e503d..0c47b9a 100644 --- a/web/tests/e2e/syb-product-layout.spec.ts +++ b/web/tests/e2e/syb-product-layout.spec.ts @@ -96,6 +96,25 @@ test('店铺选项加载失败时仍可输入历史店铺查询', async({ page, expect(listURLs.at(-1)?.searchParams.get('shopName')).toBe('已删除店铺') }) +test('PDD 待采集的下一步打开对应 PDD 商品而不是蝦皮商品', async({ page, context }) => { + await context.addCookies([{ name: 'Admin-Token', value: 'prototype-test-token', domain: 'localhost', path: '/' }]) + await page.route('**/api/**', async route => { + const url = new URL(route.request().url()) + if (url.pathname.startsWith('/src/api/')) return route.continue() + if (url.pathname.endsWith('/api/v1/getinfo')) return route.fulfill({ json: { code: 200, data: { roles: ['admin'], name: '管理员', avatar: '', introduction: '', permissions: [] }}}) + if (url.pathname.endsWith('/api/admin/v1/syb-products')) return route.fulfill({ json: { code: 200, data: { items: [{ id: 31, orderCode: 'SYB-PDD-31', shopeeItemId: '26154802794', shopeeProductId: 9, productTitle: '待采集商品', shopName: '大碼臻選', targetColor: '黑色', targetSize: 'XL', quantity: 1, unitPriceCent: 1000, parseStatus: 'success' }], total: 1, page: 1, pageSize: 20 }}}) + if (url.pathname.endsWith('/api/admin/v1/purchase-tasks/batch-preview')) return route.fulfill({ json: { code: 200, data: { items: [{ sybProductId: 31, pddProductId: 17, eligible: false, reason: 'PDD 商品待采集', processStage: 'pdd_pending', processStageLabel: 'PDD 待采集', processStageReason: 'PDD 商品待采集', processNextAction: 'open_pdd' }], eligibleCount: 0, skippedCount: 1 }}}) + return route.fulfill({ json: { code: 200, data: [] }}) + }) + + await page.goto('http://localhost:9527/#/syb-products/index') + const popupPromise = page.waitForEvent('popup') + await page.getByRole('button', { name: '查看 PDD 商品' }).click() + const popup = await popupPromise + await expect.poll(() => popup.url()).toContain('/#/pdd-products/index?productId=17') + expect(popup.url()).not.toContain('/shopee-products/index') +}) + test('SYB 商品页不读取或展示后台同步状态', async({ page, context }) => { await context.addCookies([{ name: 'Admin-Token', value: 'prototype-test-token', domain: 'localhost', path: '/' }]) let syncRunCalls = 0