feat(web): show color images in PDD product list (#168)
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
<el-table-column label="goods_id" prop="goodsId" min-width="150" />
|
||||
<el-table-column label="商品 / 店铺" min-width="240"><template #default="{ row }"><div class="primary">{{ row.title || '资料待完善' }}</div><div class="muted">{{ row.shopName || '尚未填写店铺' }}</div></template></el-table-column>
|
||||
<el-table-column label="状态 / 采集任务" min-width="190"><template #default="{ row }"><el-tag :type="statusMeta(row.status).type">{{ statusMeta(row.status).label }}</el-tag><div :class="row.collectionSelectable ? 'collection-ready' : 'muted'">{{ collectionStateText(row) }}</div></template></el-table-column>
|
||||
<el-table-column label="销量 / 评价" width="140"><template #default="{ row }"><div>销量 {{ countText(row.salesCount) }}</div><div class="muted">评价 {{ countText(row.reviewCount) }}</div></template></el-table-column>
|
||||
<el-table-column label="颜色图" width="100" align="center"><template #default="{ row }"><el-image v-if="row.colorImages?.[0]?.imagePath" class="list-color-thumb" :src="row.colorImages[0].imagePath" :alt="`${row.colorImages[0].color || ''}颜色图`" fit="cover" lazy><template #error><span class="list-color-placeholder">暂无图片</span></template></el-image><span v-else class="list-color-placeholder">暂无图片</span></template></el-table-column>
|
||||
<el-table-column label="规格" min-width="180"><template #default="{ row }">{{ specsSummary(row.specs) }}</template></el-table-column>
|
||||
<el-table-column label="颜色价格" min-width="130"><template #default="{ row }">{{ priceSummary(row.specs) }}</template></el-table-column>
|
||||
<el-table-column label="更新时间" width="170"><template #default="{ row }">{{ parseTime(row.updatedAt) }}</template></el-table-column>
|
||||
@@ -279,4 +279,5 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-card { min-height: calc(100vh - 124px); }.page-heading { display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:24px;h1{margin:0 0 6px;font-size:24px;color:#1f2937}p{margin:0;color:#606266;line-height:1.5}}.search-form{padding:16px 16px 0;margin-bottom:16px;border:1px solid #e5e7eb;border-radius:8px;background:#f8fafc}.location-notice{margin-bottom:12px}.batch-toolbar{display:flex;align-items:center;gap:12px;min-height:48px;padding:8px 12px;margin-bottom:12px;border:1px solid #dbeafe;border-radius:8px;background:#f8fafc}.batch-toolbar strong{font-variant-numeric:tabular-nums;color:#1e40af}.primary{font-weight:600;color:#1f2937}.muted{font-size:12px;color:#909399}.collection-ready{margin-top:4px;font-size:12px;color:#1677ff}.notice{margin-bottom:20px}.batch-summary{display:flex;align-items:center;gap:12px;margin-bottom:16px;color:#606266}.batch-form{display:grid;grid-template-columns:1fr 1fr;gap:20px}.drawer-body{padding:0 4px 24px}.drawer-actions,.section-heading,.dimension-header{display:flex;align-items:center;gap:12px}.drawer-actions,.section-heading{justify-content:space-between}.drawer-actions>div{display:flex;gap:8px}.section-title{margin:28px 0 14px}.spec-block{margin-bottom:20px}.spec-title{display:flex;align-items:center;gap:8px;margin-bottom:8px;font-weight:600}.color-thumb,.color-image-placeholder{display:inline-flex;width:64px;height:64px;border-radius:6px}.color-thumb{cursor:zoom-in}.color-image-placeholder{align-items:center;justify-content:center;box-sizing:border-box;border:1px dashed #dcdfe6;background:#f5f7fa;color:#909399;font-size:12px}.color-image-note{margin:8px 0 0;color:#909399;font-size:12px;line-height:1.5}.link{color:#1677ff;overflow-wrap:anywhere}.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 20px}.stock-help{margin:0 0 14px;color:#606266;font-size:13px;line-height:1.6}.stock-boundary{margin-bottom:0}.section-heading{margin:12px 0;h3{margin:0}}.dimension-card{margin-bottom:16px}.dimension-header{margin-bottom:14px}.dimension-header .el-input{flex:1}.add-value{margin-top:12px}@media(max-width:768px){.page-heading,.dimension-header{align-items:stretch;flex-direction:column}.batch-toolbar,.batch-summary{align-items:flex-start;flex-direction:column}.batch-form,.form-grid{grid-template-columns:1fr}}
|
||||
.list-color-thumb{display:block;width:56px;height:56px;margin:auto;border-radius:4px}.list-color-placeholder{display:flex;align-items:center;justify-content:center;width:56px;height:56px;margin:auto;border-radius:4px;background:#f1f5f9;color:#909399;font-size:11px}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
const pddProductRoute = [{ path: '/goauto-order-workbench', component: 'Layout', menuName: 'GoAutoOrderWorkbench', title: '订单工作台', visible: '0', children: [{ path: '/pdd-products', component: '/goauto/pdd-products/index', menuName: 'GoAutoPddProducts', title: 'PDD 商品', visible: '0' }] }];
|
||||
|
||||
const product = {
|
||||
id: 1,
|
||||
goodsId: '972800403573',
|
||||
@@ -15,6 +17,7 @@ const product = {
|
||||
{ name: '尺码', role: 'size', values: [{ name: 'XL', selectable: true }] },
|
||||
],
|
||||
updatedAt: '2026-08-17T08:00:00Z',
|
||||
colorImages: [{ color: '黑色', imagePath: '/static/uploadfile/goauto-color/test.jpg' }],
|
||||
};
|
||||
|
||||
test('PDD 商品列表、详情和编辑流程符合已确认原型', async ({ page, context }) => {
|
||||
@@ -22,6 +25,7 @@ test('PDD 商品列表、详情和编辑流程符合已确认原型', async ({ p
|
||||
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.endsWith('/api/v1/menurole')) return route.fulfill({ json: { code: 200, data: pddProductRoute } });
|
||||
if (url.pathname.startsWith('/src/api/')) {
|
||||
await route.continue();
|
||||
return;
|
||||
@@ -46,22 +50,31 @@ test('PDD 商品列表、详情和编辑流程符合已确认原型', async ({ p
|
||||
await route.fulfill({ json: { code: 200, data: [] } });
|
||||
});
|
||||
|
||||
await page.goto('http://localhost:9527/#/pdd-products/index');
|
||||
await page.goto('/#/pdd-products');
|
||||
await expect(page.getByRole('button', { name: '添加', exact: true })).toBeVisible();
|
||||
await expect(page.getByText('夏季防晒冰丝袖套')).toBeVisible();
|
||||
await expect(page.getByText('¥25.90')).toBeVisible();
|
||||
await expect(page.getByRole('columnheader', { name: '颜色图' })).toBeVisible();
|
||||
await expect(page.getByRole('columnheader', { name: '销量 / 评价' })).toHaveCount(0);
|
||||
await expect(page.getByText('暂无图片', { exact: true })).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: '查看' }).click();
|
||||
await expect(page.getByText('PDD 商品详情')).toBeVisible();
|
||||
await expect(page.locator('.spec-title').filter({ hasText: '颜色分类' })).toBeVisible();
|
||||
await expect(page.getByText('XL')).toBeVisible();
|
||||
await expect(page.getByLabel('PDD 商品详情').getByText('1,200', { exact: true })).toBeVisible();
|
||||
await expect(page.getByLabel('PDD 商品详情').getByText('36', { exact: true })).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: '编辑商品' }).click();
|
||||
await expect(page.getByText('编辑 PDD 商品')).toBeVisible();
|
||||
await page.getByLabel('商品标题').fill('夏季防晒袖套(人工确认)');
|
||||
await page.getByLabel('销量').fill('1300');
|
||||
await page.getByLabel('评价数量').fill('40');
|
||||
await page.getByRole('button', { name: '保存修改' }).click();
|
||||
await expect.poll(() => updatePayload?.title).toBe('夏季防晒袖套(人工确认)');
|
||||
expect(updatePayload.specs[0].values[0].priceCent).toBe(2590);
|
||||
expect(updatePayload.salesCount).toBe(1300);
|
||||
expect(updatePayload.reviewCount).toBe(40);
|
||||
});
|
||||
|
||||
test('带 productId 的 PDD 商品路由进入单商品定位并可通过查询退出', async ({ page, context }) => {
|
||||
@@ -71,6 +84,7 @@ test('带 productId 的 PDD 商品路由进入单商品定位并可通过查询
|
||||
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.endsWith('/api/v1/menurole')) return route.fulfill({ json: { code: 200, data: pddProductRoute } });
|
||||
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')) {
|
||||
@@ -84,7 +98,7 @@ test('带 productId 的 PDD 商品路由进入单商品定位并可通过查询
|
||||
return route.fulfill({ json: { code: 200, data: [] } });
|
||||
});
|
||||
|
||||
await page.goto('http://localhost:9527/#/pdd-products/index?productId=1');
|
||||
await page.goto('/#/pdd-products?productId=1');
|
||||
await expect(page.getByText('PDD 商品详情')).toBeVisible();
|
||||
await expect(page.locator('.el-drawer').getByText('夏季防晒冰丝袖套', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('当前定位:PDD-1 / goods_id 972800403573', { exact: true })).toBeVisible();
|
||||
@@ -103,7 +117,7 @@ test('带 productId 的 PDD 商品路由进入单商品定位并可通过查询
|
||||
await expect(page.getByRole('button', { name: '创建采集 (1)', exact: true })).toBeEnabled();
|
||||
await page.getByRole('button', { name: '查询', exact: true }).click();
|
||||
await expect.poll(() => listCalls).toBe(1);
|
||||
await expect(page).toHaveURL('http://localhost:9527/#/pdd-products/index');
|
||||
await expect(page).toHaveURL(/#\/pdd-products$/);
|
||||
await expect(page.getByText('第二件商品', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('共 2 条', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('当前定位:PDD-1 / goods_id 972800403573', { exact: true })).toHaveCount(0);
|
||||
@@ -115,6 +129,7 @@ test('单商品定位的重置和无效编号不会误显示其他商品', async
|
||||
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.endsWith('/api/v1/menurole')) return route.fulfill({ json: { code: 200, data: pddProductRoute } });
|
||||
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')) return route.fulfill({ json: { code: 200, data: { product } } });
|
||||
@@ -125,7 +140,7 @@ test('单商品定位的重置和无效编号不会误显示其他商品', async
|
||||
return route.fulfill({ json: { code: 200, data: [] } });
|
||||
});
|
||||
|
||||
await page.goto('http://localhost:9527/#/pdd-products/index?productId=invalid');
|
||||
await page.goto('/#/pdd-products?productId=invalid');
|
||||
await expect(page.getByText('PDD 商品编号无效', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('972800403573', { exact: true })).toHaveCount(0);
|
||||
expect(listURL).toBeUndefined();
|
||||
@@ -135,7 +150,7 @@ test('单商品定位的重置和无效编号不会误显示其他商品', async
|
||||
await expect(page.getByText('第二件商品', { exact: true })).toBeVisible();
|
||||
|
||||
listURL = undefined;
|
||||
await page.goto('http://localhost:9527/#/pdd-products/index?productId=1');
|
||||
await page.goto('/#/pdd-products?productId=1');
|
||||
await page.reload();
|
||||
await page.getByLabel('PDD 商品详情').getByLabel('关闭此对话框').click();
|
||||
await expect(page.getByLabel('PDD 商品详情')).toBeHidden();
|
||||
@@ -145,7 +160,7 @@ test('单商品定位的重置和无效编号不会误显示其他商品', async
|
||||
await page.getByRole('button', { name: '重置', exact: true }).click();
|
||||
await expect.poll(() => listURL?.searchParams.get('keyword')).toBe('');
|
||||
expect(listURL?.searchParams.get('status')).toBe('');
|
||||
await expect(page).toHaveURL('http://localhost:9527/#/pdd-products/index');
|
||||
await expect(page).toHaveURL(/#\/pdd-products$/);
|
||||
});
|
||||
|
||||
test('单商品定位对不可采集商品禁用勾选并显示原因', async ({ page, context }) => {
|
||||
@@ -154,12 +169,13 @@ test('单商品定位对不可采集商品禁用勾选并显示原因', async ({
|
||||
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/menurole')) return route.fulfill({ json: { code: 200, data: pddProductRoute } });
|
||||
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')) return route.fulfill({ json: { code: 200, data: { product: disabled } } });
|
||||
return route.fulfill({ json: { code: 200, data: [] } });
|
||||
});
|
||||
|
||||
await page.goto('http://localhost:9527/#/pdd-products/index?productId=1');
|
||||
await page.goto('/#/pdd-products?productId=1');
|
||||
await page.getByLabel('PDD 商品详情').getByLabel('关闭此对话框').click();
|
||||
await expect(page.getByLabel('PDD 商品详情')).toBeHidden();
|
||||
await expect(page.locator('.el-table__body-wrapper tbody tr').getByRole('checkbox')).toBeDisabled();
|
||||
@@ -175,6 +191,7 @@ test('PDD 商品当前页多选并批量创建独立采集任务', async ({ page
|
||||
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/menurole')) return route.fulfill({ json: { code: 200, data: pddProductRoute } });
|
||||
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')) return route.fulfill({ json: { code: 200, data: { items: [product, second, disabled], total: 3, page: 1, pageSize: 20 } } });
|
||||
if (url.pathname.endsWith('/api/admin/v1/collection-rules')) return route.fulfill({ json: { code: 200, data: { items: [{ id: 9, name: 'PDD 商品详情采集' }], total: 1 } } });
|
||||
@@ -186,7 +203,7 @@ test('PDD 商品当前页多选并批量创建独立采集任务', async ({ page
|
||||
return route.fulfill({ json: { code: 200, data: [] } });
|
||||
});
|
||||
|
||||
await page.goto('http://localhost:9527/#/pdd-products/index');
|
||||
await page.goto('/#/pdd-products');
|
||||
const rows = page.locator('.el-table__body-wrapper tbody tr');
|
||||
await rows.nth(0).locator('.el-checkbox').click();
|
||||
await rows.nth(1).locator('.el-checkbox').click();
|
||||
|
||||
Reference in New Issue
Block a user