Explorar o código

feat(web-admin): add mp CRM product card query helpers.

Co-authored-by: Cursor <cursoragent@cursor.com>
wuzilong hai 2 semanas
pai
achega
2f72c29ee7

+ 70 - 0
web-admin/src/utils/mp-crm-product-card.test.ts

@@ -0,0 +1,70 @@
+import assert from 'node:assert/strict'
+import { describe, it } from 'node:test'
+import {
+  MP_PRODUCT_STATUS_FILTERS,
+  buildProductListQuery,
+  buildProductCard,
+  productStatusLabel,
+  productStatusTagType
+} from './mp-crm-product-card'
+
+describe('MP_PRODUCT_STATUS_FILTERS', () => {
+  it('defaults on first and includes all/off', () => {
+    assert.equal(MP_PRODUCT_STATUS_FILTERS[0].value, 'on')
+    assert.deepEqual(
+      MP_PRODUCT_STATUS_FILTERS.map((x) => x.value),
+      ['on', 'all', 'off']
+    )
+  })
+})
+
+describe('buildProductListQuery', () => {
+  it('defaults statusIn on and passes keyword/page', () => {
+    assert.deepEqual(
+      buildProductListQuery({ page: 1, pageSize: 20, statusFilter: 'on', keyword: ' 酸 ' }),
+      { page: 1, pageSize: 20, statusIn: 'on', keyword: '酸' }
+    )
+  })
+  it('omits statusIn when filter is all', () => {
+    const q = buildProductListQuery({ page: 2, pageSize: 10, statusFilter: 'all', keyword: '' })
+    assert.equal(q.page, 2)
+    assert.equal(q.statusIn, undefined)
+    assert.equal('keyword' in q, false)
+  })
+  it('sets statusIn off', () => {
+    assert.equal(
+      buildProductListQuery({ page: 1, pageSize: 20, statusFilter: 'off', keyword: '' }).statusIn,
+      'off'
+    )
+  })
+})
+
+describe('buildProductCard', () => {
+  it('maps fields and tags', () => {
+    const card = buildProductCard({
+      id: 'p1',
+      productNo: 'SX001',
+      productName: '硫酸',
+      categoryPath: '化工 / 酸类',
+      model: '98%',
+      status: 'on',
+      isToxic: 1,
+      isExplosive: 0
+    })
+    assert.equal(card.id, 'p1')
+    assert.equal(card.productNo, 'SX001')
+    assert.equal(card.statusLabel, '上架')
+    assert.equal(card.statusTagType, 'success')
+    assert.equal(card.showToxic, true)
+    assert.equal(card.showExplosive, false)
+  })
+})
+
+describe('productStatusTagType', () => {
+  it('maps on→success off→info', () => {
+    assert.equal(productStatusTagType('on'), 'success')
+    assert.equal(productStatusTagType('off'), 'info')
+    assert.equal(productStatusLabel('on'), '上架')
+    assert.equal(productStatusLabel('off'), '下架')
+  })
+})

+ 62 - 0
web-admin/src/utils/mp-crm-product-card.ts

@@ -0,0 +1,62 @@
+export type MpProductStatusFilter = 'on' | 'all' | 'off'
+
+export const MP_PRODUCT_STATUS_FILTERS: Array<{ value: MpProductStatusFilter; label: string }> = [
+  { value: 'on', label: '上架' },
+  { value: 'all', label: '全部' },
+  { value: 'off', label: '下架' }
+]
+
+export function productStatusLabel(status?: string): string {
+  if (status === 'off') return '下架'
+  if (status === 'on') return '上架'
+  return status || '—'
+}
+
+export function productStatusTagType(status?: string): 'success' | 'info' | 'warning' {
+  if (status === 'on') return 'success'
+  if (status === 'off') return 'info'
+  return 'warning'
+}
+
+export function buildProductListQuery(input: {
+  page: number
+  pageSize: number
+  statusFilter: MpProductStatusFilter
+  keyword: string
+}): Record<string, unknown> {
+  const params: Record<string, unknown> = {
+    page: input.page,
+    pageSize: input.pageSize
+  }
+  if (input.statusFilter === 'on' || input.statusFilter === 'off') {
+    params.statusIn = input.statusFilter
+  }
+  const kw = String(input.keyword || '').trim()
+  if (kw) params.keyword = kw
+  return params
+}
+
+export function buildProductCard(row: {
+  id: string
+  productNo?: string
+  productName?: string
+  categoryPath?: string
+  categoryName?: string
+  model?: string
+  status?: string
+  isToxic?: number
+  isExplosive?: number
+}) {
+  return {
+    id: row.id,
+    productNo: row.productNo || '—',
+    productName: row.productName || '—',
+    categoryPath: row.categoryPath || row.categoryName || '—',
+    model: row.model || '—',
+    status: row.status || '',
+    statusLabel: productStatusLabel(row.status),
+    statusTagType: productStatusTagType(row.status),
+    showToxic: Number(row.isToxic) === 1,
+    showExplosive: Number(row.isExplosive) === 1
+  }
+}