This commit is contained in:
2026-08-12 17:29:35 +08:00
parent 16c5ed6301
commit d2a246b122
25 changed files with 238 additions and 69 deletions
@@ -92,6 +92,20 @@ enableAutoUnmount(afterEach)
afterAll(() => vi.unstubAllGlobals())
describe('PartnersView real API integration', () => {
it('keeps operation first and separates the prototype contact columns', () => {
const actionsIndex = source.indexOf("{ key: 'actions', label: '操作'")
const nameIndex = source.indexOf("{ key: 'partner', label: '单位名称'")
const typeIndex = source.indexOf("{ key: 'type', label: '类型'")
const contactIndex = source.indexOf("{ key: 'contact', prop: 'contactName', label: '联系人'")
const phoneIndex = source.indexOf("{ key: 'contactPhone', prop: 'contactPhone', label: '电话'")
expect([actionsIndex, nameIndex, typeIndex, contactIndex, phoneIndex].every((index) => index >= 0)).toBe(true)
expect(actionsIndex).toBeLessThan(nameIndex)
expect(nameIndex).toBeLessThan(typeIndex)
expect(typeIndex).toBeLessThan(contactIndex)
expect(contactIndex).toBeLessThan(phoneIndex)
expect(source).toContain("{ key: 'partnerCode', prop: 'partnerCode', label: '单位编码', minWidth: 130, defaultVisible: false }")
expect(source).toContain("{ key: 'contactEmail', prop: 'contactEmail', label: '邮箱', minWidth: 190, defaultVisible: false")
})
beforeEach(() => {
vi.stubGlobal('ResizeObserver', ResizeObserverStub)
document.body.innerHTML = ''
@@ -110,8 +124,9 @@ describe('PartnersView real API integration', () => {
expect(wrapper.find('input[aria-label="所属企业"]').exists()).toBe(false)
expect(wrapper.text()).toContain('平台公共数据 · 共 1 个往来单位')
expect(wrapper.text()).toContain('深圳示例贸易有限公司')
expect(wrapper.text()).toContain('CUS-001')
expect(wrapper.text()).toContain('contact@example.com')
expect(wrapper.find('.data-table').text()).toContain('13800138000')
expect(wrapper.find('.data-table').text()).not.toContain('CUS-001')
expect(wrapper.find('.data-table').text()).not.toContain('contact@example.com')
expect(wrapper.find('.data-table').text()).not.toContain('广东省 深圳市 宝安区 航城街道示例路 1 号')
expect(wrapper.text()).not.toContain('往来单位总数')
expect(wrapper.text()).not.toContain('往来单位档案')
@@ -151,9 +151,12 @@ function partnerTypeLabel(type: PlatformPartnerLegacyType) {
}
const partnerColumns: DataTableColumn[] = [
{ key: 'actions', label: '操作', width: 210, fixed: 'left', slotName: 'actions' },
{ key: 'partner', label: '往来单位', minWidth: 210, slotName: 'partner' },
{ key: 'partner', label: '单位名称', minWidth: 210, slotName: 'partner' },
{ key: 'partnerCode', prop: 'partnerCode', label: '单位编码', minWidth: 130, defaultVisible: false },
{ key: 'type', label: '类型', minWidth: 115, slotName: 'type' },
{ key: 'contact', label: '联系人', minWidth: 165, slotName: 'contact' },
{ key: 'contact', prop: 'contactName', label: '联系人', minWidth: 130 },
{ key: 'contactPhone', prop: 'contactPhone', label: '电话', minWidth: 145 },
{ key: 'contactEmail', prop: 'contactEmail', label: '邮箱', minWidth: 190, defaultVisible: false, formatter: (row: PlatformPartnerResource) => row.contactEmail || '—' },
{ key: 'address', label: '地址', minWidth: 240, slotName: 'address', defaultVisible: false },
{ key: 'status', label: '状态', width: 90, slotName: 'status' },
{ key: 'updatedAt', prop: 'updatedAt', label: '更新时间', minWidth: 140, defaultVisible: false, formatter: (row: PlatformPartnerResource) => formatUpdatedAt(row.updatedAt) },
@@ -397,9 +400,8 @@ onMounted(() => {
<el-button v-if="access.can('platform:counterparty:status')" link :disabled="loading" :type="(row as PlatformPartnerResource).status === 'ACTIVE' ? 'danger' : 'success'" :loading="statusLoadingIds.has(String((row as PlatformPartnerResource).id))" @click="toggleStatus(row as PlatformPartnerResource)"><Power :size="15" />{{ (row as PlatformPartnerResource).status === 'ACTIVE' ? '停用' : '启用' }}</el-button>
</div>
</template>
<template #partner="{ row }"><div class="partner-cell"><span><Building2 :size="18" /></span><div><strong>{{ (row as PlatformPartnerResource).partnerName }}</strong><small>{{ (row as PlatformPartnerResource).partnerCode }}</small></div></div></template>
<template #partner="{ row }"><div class="partner-cell"><span><Building2 :size="18" /></span><div><strong>{{ (row as PlatformPartnerResource).partnerName }}</strong></div></div></template>
<template #type="{ row }"><div class="partner-types"><el-tag v-for="type in (row as PlatformPartnerResource).types" :key="type" effect="plain">{{ partnerTypeLabel(type) }}</el-tag></div></template>
<template #contact="{ row }"><strong>{{ (row as PlatformPartnerResource).contactName }}</strong><span class="partner-subline">{{ (row as PlatformPartnerResource).contactPhone }}</span><span v-if="(row as PlatformPartnerResource).contactEmail" class="partner-subline">{{ (row as PlatformPartnerResource).contactEmail }}</span></template>
<template #address="{ row }"><div class="partner-address"><MapPin :size="15" /><span>{{ [(row as PlatformPartnerResource).province, (row as PlatformPartnerResource).city, (row as PlatformPartnerResource).district, (row as PlatformPartnerResource).addressLine].filter(Boolean).join(' ') }}</span></div></template>
<template #status="{ row }"><el-tag :type="(row as PlatformPartnerResource).status === 'ACTIVE' ? 'success' : 'info'" effect="light">{{ (row as PlatformPartnerResource).status === 'ACTIVE' ? '启用' : '停用' }}</el-tag></template>
<template #pagination-left>平台公共数据 · 共 {{ total }} 个往来单位</template>
@@ -484,7 +486,6 @@ onMounted(() => {
.partner-cell > span { display: grid; width: 34px; height: 34px; flex: 0 0 34px; place-items: center; border-radius: 7px; background: #eef3fa; color: var(--cc-primary); }
.partner-cell > div { display: flex; min-width: 0; flex-direction: column; gap: 3px; }
.partner-cell strong { overflow-wrap: anywhere; }
.partner-cell small, .partner-subline { display: block; color: var(--cc-muted); font-size: 11px; line-height: 1.45; overflow-wrap: anywhere; }
.partner-address { display: flex; align-items: flex-start; gap: 7px; line-height: 1.55; overflow-wrap: anywhere; }
.partner-address svg { flex: 0 0 15px; margin-top: 3px; color: var(--cc-muted); }
.partner-detail { min-height: 180px; padding: 20px 24px 28px; box-sizing: border-box; }
@@ -1,4 +1,6 @@
import ElementPlus from 'element-plus'
import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
import { createPinia, setActivePinia } from 'pinia'
import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils'
import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
@@ -7,6 +9,8 @@ import { useAccessPreviewStore } from '@/core/access/accessPreview'
import { useAuthStore } from '@/core/auth/auth'
import ExpressCompaniesView from './ExpressCompaniesView.vue'
const expressCompaniesSource = readFileSync(resolve(process.cwd(), 'src/modules/master-data/express-companies/pages/ExpressCompaniesView.vue'), 'utf8')
vi.mock('@/modules/master-data/express-companies/api/platformExpressCompanies', () => ({
listPlatformExpressCompanies: vi.fn(),
getPlatformExpressCompany: vi.fn(),
@@ -69,6 +73,19 @@ enableAutoUnmount(afterEach)
afterAll(() => vi.unstubAllGlobals())
describe('ExpressCompaniesView query and table migration', () => {
it('keeps operation first and exposes the prototype business columns separately', () => {
const actionsIndex = expressCompaniesSource.indexOf("{ key: 'actions', label: '操作'")
const nameIndex = expressCompaniesSource.indexOf("{ key: 'company', label: '公司名称'")
const codeIndex = expressCompaniesSource.indexOf("{ key: 'companyCode', prop: 'companyCode', label: '编码'")
const websiteIndex = expressCompaniesSource.indexOf("{ key: 'website', label: '官方网站'")
const phoneIndex = expressCompaniesSource.indexOf("{ key: 'servicePhone', prop: 'servicePhone', label: '客服电话'")
expect([actionsIndex, nameIndex, codeIndex, websiteIndex, phoneIndex].every((index) => index >= 0)).toBe(true)
expect(actionsIndex).toBeLessThan(nameIndex)
expect(nameIndex).toBeLessThan(codeIndex)
expect(codeIndex).toBeLessThan(websiteIndex)
expect(websiteIndex).toBeLessThan(phoneIndex)
expect(expressCompaniesSource).toContain("label: '更新时间', minWidth: 150, defaultVisible: false")
})
beforeEach(() => {
vi.stubGlobal('ResizeObserver', ResizeObserverStub)
document.body.innerHTML = ''
@@ -119,11 +119,12 @@ function formatUpdatedAt(value?: string | null) {
const expressCompanyColumns: DataTableColumn[] = [
{ key: 'actions', label: '操作', width: 170, fixed: 'left', slotName: 'actions' },
{ key: 'company', label: '快递公司', minWidth: 210, slotName: 'company' },
{ key: 'servicePhone', prop: 'servicePhone', label: '客服电话', minWidth: 130, formatter: (row: PlatformExpressCompanyResource) => row.servicePhone || '—' },
{ key: 'company', label: '公司名称', minWidth: 210, slotName: 'company' },
{ key: 'companyCode', prop: 'companyCode', label: '编码', minWidth: 120 },
{ key: 'website', label: '官方网站', minWidth: 210, slotName: 'website' },
{ key: 'updatedAt', prop: 'updatedAt', label: '更新时间', minWidth: 150, defaultVisible: false, formatter: (row: PlatformExpressCompanyResource) => formatUpdatedAt(row.updatedAt) },
{ key: 'servicePhone', prop: 'servicePhone', label: '客服电话', minWidth: 130, formatter: (row: PlatformExpressCompanyResource) => row.servicePhone || '—' },
{ key: 'status', label: '状态', width: 100, slotName: 'status' },
{ key: 'updatedAt', prop: 'updatedAt', label: '更新时间', minWidth: 150, defaultVisible: false, formatter: (row: PlatformExpressCompanyResource) => formatUpdatedAt(row.updatedAt) },
]
async function loadExpressCompanies() {
@@ -330,7 +331,7 @@ onMounted(() => {
</div>
<span v-else class="muted-value">仅查看</span>
</template>
<template #company="{ row }"><div class="express-company-cell"><span><Truck :size="17" /></span><div><strong>{{ (row as PlatformExpressCompanyResource).companyName }}</strong><small>{{ (row as PlatformExpressCompanyResource).companyCode }}</small></div></div></template>
<template #company="{ row }"><div class="express-company-cell"><span><Truck :size="17" /></span><div><strong>{{ (row as PlatformExpressCompanyResource).companyName }}</strong></div></div></template>
<template #website="{ row }">
<a v-if="safeHttpUrl((row as PlatformExpressCompanyResource).website)" class="external-link" :href="safeHttpUrl((row as PlatformExpressCompanyResource).website)!" target="_blank" rel="noopener noreferrer">访问官网<ExternalLink :size="13" /></a>
<span v-else class="muted-value">{{ (row as PlatformExpressCompanyResource).website || '—' }}</span>
@@ -393,7 +394,6 @@ onMounted(() => {
.express-company-cell > span { display: grid; width: 34px; height: 34px; flex: 0 0 34px; place-items: center; border: 1px solid var(--cc-border); border-radius: 7px; background: #f8fafc; color: var(--cc-primary); }
.express-company-cell > div { display: flex; min-width: 0; flex-direction: column; gap: 3px; }
.express-company-cell strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.express-company-cell small { color: var(--cc-muted); font-size: 11px; }
.external-link { display: inline-flex; align-items: center; gap: 5px; color: var(--cc-primary); font-size: 12px; text-decoration: none; }
.external-link:hover { text-decoration: underline; }
.tracking-template { display: block; max-width: 100%; color: #475467; font-family: "Cascadia Code", Consolas, monospace; font-size: 11px; overflow-wrap: anywhere; }