From 370a3926d70fd757aeb607226731681b3fc375a6 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Mon, 3 Aug 2026 17:44:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PlatformFirstLegOrdersPanel.vue | 238 +++++++++++---- src/views/CustomersView.test.ts | 81 ++++++ src/views/CustomersView.vue | 271 ++++++++++++++++-- 3 files changed, 499 insertions(+), 91 deletions(-) diff --git a/src/components/PlatformFirstLegOrdersPanel.vue b/src/components/PlatformFirstLegOrdersPanel.vue index 92c8819e..bcf542c5 100644 --- a/src/components/PlatformFirstLegOrdersPanel.vue +++ b/src/components/PlatformFirstLegOrdersPanel.vue @@ -1,8 +1,9 @@ diff --git a/src/views/CustomersView.test.ts b/src/views/CustomersView.test.ts index 0d2cbbe4..ce456614 100644 --- a/src/views/CustomersView.test.ts +++ b/src/views/CustomersView.test.ts @@ -3,9 +3,12 @@ import { createPinia, setActivePinia } from 'pinia' import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { + downloadTenantQualification, getPlatformTenant, listPlatformTenants, listTenantQualifications, + updatePlatformTenant, + uploadPlatformTenantQualification, type PlatformTenantResource, } from '@/api/platformIam' import { useAccessPreviewStore } from '@/stores/accessPreview' @@ -15,10 +18,12 @@ import CustomersView from './CustomersView.vue' vi.mock('@/api/platformIam', () => ({ changePlatformTenantStatus: vi.fn(), createPlatformTenant: vi.fn(), + downloadTenantQualification: vi.fn(), getPlatformTenant: vi.fn(), listPlatformTenantOrderCounts: vi.fn(), listPlatformTenants: vi.fn(), listTenantQualifications: vi.fn(), + qualificationFileName: vi.fn((documentUrl: string) => documentUrl.split('/').at(-1) || '资质文件'), submitPlatformTenantReview: vi.fn(), updatePlatformTenant: vi.fn(), uploadPlatformTenantQualification: vi.fn(), @@ -51,7 +56,10 @@ describe('CustomersView', () => { let pinia: ReturnType beforeEach(() => { + vi.clearAllMocks() vi.stubGlobal('ResizeObserver', ResizeObserverStub) + Object.defineProperty(URL, 'createObjectURL', { configurable: true, value: vi.fn(() => 'blob:qualification-preview') }) + Object.defineProperty(URL, 'revokeObjectURL', { configurable: true, value: vi.fn() }) document.body.innerHTML = '' pinia = createPinia() setActivePinia(pinia) @@ -65,6 +73,10 @@ describe('CustomersView', () => { }) vi.mocked(getPlatformTenant).mockResolvedValue(fullTenant) vi.mocked(listTenantQualifications).mockResolvedValue([]) + vi.mocked(updatePlatformTenant).mockResolvedValue(fullTenant) + vi.mocked(uploadPlatformTenantQualification).mockResolvedValue({ + qualificationId: 'qualification-1', reviewId: null, tenantStatus: 'PROFILE_REQUIRED', documentUrl: '/files/license.png', + }) }) it('loads the complete customer detail before editing masked list fields', async () => { @@ -80,4 +92,73 @@ describe('CustomersView', () => { expect(phone?.value).toBe(fullTenant.contactPhone) expect(email?.value).toBe(fullTenant.contactEmail) }) + + it('shows an authenticated image preview for an uploaded qualification', async () => { + vi.mocked(listTenantQualifications).mockResolvedValue([{ + id: 'qualification-1', tenantId: fullTenant.id, qualificationType: 'BUSINESS_LICENSE', + certificateNo: fullTenant.unifiedSocialCreditCode, documentUrl: '/files/license.png', + status: 'PENDING', reviewComment: null, validTo: null, + }]) + vi.mocked(downloadTenantQualification).mockResolvedValue(new Blob(['image'], { type: 'image/png' })) + + mount(CustomersView, { attachTo: document.body, global: { plugins: [pinia, ElementPlus] } }) + await flushPromises() + tableButtonByText('编辑')?.click() + await flushPromises() + await flushPromises() + + expect(downloadTenantQualification).toHaveBeenCalledWith(fullTenant.id, '/files/license.png') + const preview = document.querySelector('img[alt="营业执照预览"]') + expect(preview?.src).toBe('blob:qualification-preview') + }) + + it('shows uploaded qualifications in customer detail and opens the full preview', async () => { + vi.mocked(listTenantQualifications).mockResolvedValue([{ + id: 'qualification-1', tenantId: fullTenant.id, qualificationType: 'BUSINESS_LICENSE', + certificateNo: fullTenant.unifiedSocialCreditCode, documentUrl: '/files/license.png', + status: 'PENDING', reviewComment: null, validTo: null, + }]) + vi.mocked(downloadTenantQualification).mockResolvedValue(new Blob(['image'], { type: 'image/png' })) + + mount(CustomersView, { attachTo: document.body, global: { plugins: [pinia, ElementPlus] } }) + await flushPromises() + tableButtonByText('详情')?.click() + await flushPromises() + await flushPromises() + + const detailPreview = document.querySelector('button[aria-label="查看营业执照:license.png"]') + expect(detailPreview?.querySelector('img[alt="营业执照缩略图"]')).not.toBeNull() + detailPreview?.click() + await flushPromises() + + expect(document.querySelector('.qualification-preview img[alt="license.png预览"]')).not.toBeNull() + }) + + it('saves customer data and selected qualifications with one action', async () => { + mount(CustomersView, { attachTo: document.body, global: { plugins: [pinia, ElementPlus] } }) + await flushPromises() + tableButtonByText('编辑')?.click() + await flushPromises() + + const licenseFile = new File(['license'], 'license.png', { type: 'image/png' }) + const licenseInput = document.querySelector('.qualification-file input[type="file"]') + Object.defineProperty(licenseInput, 'files', { configurable: true, value: [licenseFile] }) + licenseInput?.dispatchEvent(new Event('change', { bubbles: true })) + await flushPromises() + + const buttons = [...document.querySelectorAll('button')] + expect(buttons.some((button) => button.textContent?.trim() === '上传已选资质')).toBe(false) + buttons.find((button) => button.textContent?.trim() === '保存资料和资质')?.click() + await flushPromises() + + expect(updatePlatformTenant).toHaveBeenCalledWith(fullTenant.id, expect.objectContaining({ tenantName: fullTenant.tenantName })) + expect(uploadPlatformTenantQualification).toHaveBeenCalledWith( + fullTenant.id, + 'BUSINESS_LICENSE', + licenseFile, + undefined, + fullTenant.unifiedSocialCreditCode, + false, + ) + }) }) diff --git a/src/views/CustomersView.vue b/src/views/CustomersView.vue index d0528da8..cc4d988b 100644 --- a/src/views/CustomersView.vue +++ b/src/views/CustomersView.vue @@ -1,15 +1,17 @@ @@ -356,16 +529,31 @@ onMounted(loadCustomers)
文件类型上传文件有效期
{{ draft.label }}
-
{{ draft.file?.name || draft.uploadedName || '未选择文件' }}{{ draft.error }}
+
+ +
{{ draft.file?.name || draft.uploadedName || '未选择文件' }}{{ draft.error }}
+

支持 PDF、JPG、PNG,单个文件不超过 10MB;* 为提交审核必填项。

- + + +
+ +