This commit is contained in:
2026-09-02 10:04:24 +08:00
parent a14e39893c
commit 19eea79836
5 changed files with 49 additions and 39 deletions
+4
View File
@@ -98,6 +98,10 @@ describe('admin auth session', () => {
await auth.login('platform_admin', 'password') await auth.login('platform_admin', 'password')
expect(mocks.post).toHaveBeenCalledWith('/auth/login', {
loginId: 'platform_admin',
password: 'password',
})
expect(auth.isAuthenticated).toBe(true) expect(auth.isAuthenticated).toBe(true)
expect(auth.refreshToken).toBe('refresh-domestic') expect(auth.refreshToken).toBe('refresh-domestic')
}) })
+1 -1
View File
@@ -176,7 +176,7 @@ export const useAuthStore = defineStore('admin-auth', () => {
try { try {
const response = await http.post<ApiEnvelope<LoginResponse>, ApiEnvelope<LoginResponse>>( const response = await http.post<ApiEnvelope<LoginResponse>, ApiEnvelope<LoginResponse>>(
'/auth/login', '/auth/login',
{ username: account, password }, { loginId: account, password },
) )
const result = unwrapApiResponse<LoginResponse>(response) const result = unwrapApiResponse<LoginResponse>(response)
await applySession(result, expectedGeneration) await applySession(result, expectedGeneration)
+39 -33
View File
@@ -9,7 +9,6 @@ import {
approveEnterpriseReview, approveEnterpriseReview,
archivePlatformTenant, archivePlatformTenant,
changePlatformTenantStatus, changePlatformTenantStatus,
checkPlatformTenantContactPhone,
createPlatformTenant, createPlatformTenant,
createPlatformTenantImpersonation, createPlatformTenantImpersonation,
downloadTenantQualification, downloadTenantQualification,
@@ -148,11 +147,14 @@ const rules: FormRules = {
tenantName: [{ required: true, message: '请输入公司名称', trigger: 'blur' }], tenantName: [{ required: true, message: '请输入公司名称', trigger: 'blur' }],
legalName: [{ required: true, message: '请输入营业执照上的企业名称', trigger: 'blur' }], legalName: [{ required: true, message: '请输入营业执照上的企业名称', trigger: 'blur' }],
legalRepresentative: [{ required: true, message: '请输入法定代表人姓名', trigger: 'blur' }], legalRepresentative: [{ required: true, message: '请输入法定代表人姓名', trigger: 'blur' }],
unifiedSocialCreditCode: [{ pattern: /^[0-9A-Z]{18}$/, message: '请输入 18 位大写字母或数字', trigger: 'blur' }], unifiedSocialCreditCode: [
{ required: true, message: '请输入统一社会信用代码', trigger: 'blur' },
{ pattern: /^[0-9A-Z]{18}$/, message: '请输入 18 位大写字母或数字', trigger: 'blur' },
],
contactName: [{ required: true, message: '请输入联系人姓名', trigger: 'blur' }], contactName: [{ required: true, message: '请输入联系人姓名', trigger: 'blur' }],
contactPhone: [ contactPhone: [
{ required: true, message: '请输入联系电话', trigger: 'blur' }, { required: true, message: '请输入公司联系电话', trigger: 'blur' },
{ pattern: /^[0-9-]{4,32}$/, message: '请输入 4-32 位数字或连字符,联系电话将作为登录用户名', trigger: 'blur' }, { pattern: /^[0-9-]{4,32}$/, message: '请输入 4-32 位数字或连字符', trigger: 'blur' },
], ],
contactEmail: [{ type: 'email', message: '请输入有效邮箱地址', trigger: 'blur' }], contactEmail: [{ type: 'email', message: '请输入有效邮箱地址', trigger: 'blur' }],
servicePackage: [{ required: true, message: '请选择客户套餐', trigger: 'change' }], servicePackage: [{ required: true, message: '请选择客户套餐', trigger: 'change' }],
@@ -171,7 +173,7 @@ const decisionRules: FormRules = {
function newQualificationDrafts(): QualificationDraft[] { function newQualificationDrafts(): QualificationDraft[] {
const definitions: Array<Pick<QualificationDraft, 'type' | 'label' | 'required'>> = [ const definitions: Array<Pick<QualificationDraft, 'type' | 'label' | 'required'>> = [
{ type: 'BUSINESS_LICENSE', label: '营业执照', required: true }, { type: 'BUSINESS_LICENSE', label: '营业执照', required: true },
{ type: 'LEGAL_PERSON_ID', label: '法人身份证', required: true }, { type: 'LEGAL_PERSON_ID', label: '法人身份证', required: false },
{ type: 'FREIGHT_FORWARDER_CERTIFICATE', label: '货代资质证书', required: false }, { type: 'FREIGHT_FORWARDER_CERTIFICATE', label: '货代资质证书', required: false },
{ type: 'BANK_ACCOUNT_LICENSE', label: '银行开户许可证', required: false }, { type: 'BANK_ACCOUNT_LICENSE', label: '银行开户许可证', required: false },
] ]
@@ -221,23 +223,16 @@ const uploadingQualifications = computed(() => qualifications.value.some((item)
const hasSelectedQualifications = computed(() => qualifications.value.some((item) => item.file)) const hasSelectedQualifications = computed(() => qualifications.value.some((item) => item.file))
const selectedBusinessLicense = computed(() => qualifications.value.find((item) => item.type === 'BUSINESS_LICENSE')?.file) const selectedBusinessLicense = computed(() => qualifications.value.find((item) => item.type === 'BUSINESS_LICENSE')?.file)
const selectedLegalPersonId = computed(() => qualifications.value.find((item) => item.type === 'LEGAL_PERSON_ID')?.file) const selectedLegalPersonId = computed(() => qualifications.value.find((item) => item.type === 'LEGAL_PERSON_ID')?.file)
const requiredPackageChangeSelected = computed(() => Boolean(selectedBusinessLicense.value || selectedLegalPersonId.value)) const businessLicenseReadyForSave = computed(() => Boolean(selectedBusinessLicense.value
const requiredPackageFilesSelected = computed(() => Boolean(selectedBusinessLicense.value && selectedLegalPersonId.value)) || qualifications.value.find((item) => item.type === 'BUSINESS_LICENSE')?.uploaded))
const creditCodeReadyForSave = computed(() => requiredPackageChangeSelected.value const creditCodeReadyForSave = computed(() => creditCodeEstablished.value
? requiredPackageFilesSelected.value && (creditCodeEstablished.value || unifiedSocialCreditCodePattern.test(form.value.unifiedSocialCreditCode || ''))
|| unifiedSocialCreditCodePattern.test(form.value.unifiedSocialCreditCode || '')) const requiredQualificationPackageComplete = computed(() => businessLicenseReadyForSave.value && creditCodeReadyForSave.value)
: creditCodeEstablished.value)
const requiredQualificationPackageComplete = computed(() => creditCodeReadyForSave.value
&& (requiredPackageChangeSelected.value
? requiredPackageFilesSelected.value
: qualifications.value.filter((item) => item.required).every((item) => item.uploaded)))
const missingQualificationPackageItems = computed(() => { const missingQualificationPackageItems = computed(() => {
const businessLicense = qualifications.value.find((item) => item.type === 'BUSINESS_LICENSE') const businessLicense = qualifications.value.find((item) => item.type === 'BUSINESS_LICENSE')
const legalPersonId = qualifications.value.find((item) => item.type === 'LEGAL_PERSON_ID')
const missing: string[] = [] const missing: string[] = []
if (requiredPackageChangeSelected.value ? !businessLicense?.file : !businessLicense?.uploaded) missing.push('营业执照') if (!businessLicense?.file && !businessLicense?.uploaded) missing.push('营业执照')
if (!creditCodeReadyForSave.value) missing.push('18位统一社会信用代码(需随必填资质包保存)') if (!creditCodeReadyForSave.value) missing.push('18位统一社会信用代码(需随营业执照保存)')
if (requiredPackageChangeSelected.value ? !legalPersonId?.file : !legalPersonId?.uploaded) missing.push('法人身份证')
return missing return missing
}) })
const hasUnsavedChanges = computed(() => Boolean(editingId.value) && JSON.stringify(form.value) !== savedFormSnapshot.value) const hasUnsavedChanges = computed(() => Boolean(editingId.value) && JSON.stringify(form.value) !== savedFormSnapshot.value)
@@ -512,27 +507,38 @@ async function uploadSelectedQualifications(tenantId: string) {
const failures: string[] = [] const failures: string[] = []
const businessLicense = qualifications.value.find((item) => item.type === 'BUSINESS_LICENSE') const businessLicense = qualifications.value.find((item) => item.type === 'BUSINESS_LICENSE')
const legalPersonId = qualifications.value.find((item) => item.type === 'LEGAL_PERSON_ID') const legalPersonId = qualifications.value.find((item) => item.type === 'LEGAL_PERSON_ID')
if (requiredPackageChangeSelected.value && businessLicense?.file && legalPersonId?.file) { const businessLicenseFile = businessLicense?.file || null
businessLicense.uploading = true; legalPersonId.uploading = true const legalPersonIdFile = legalPersonId?.file || null
businessLicense.error = ''; legalPersonId.error = '' if (businessLicense && businessLicenseFile) {
businessLicense.uploading = true
if (legalPersonIdFile && legalPersonId) legalPersonId.uploading = true
businessLicense.error = ''
if (legalPersonId) legalPersonId.error = ''
try { try {
const uploaded = await uploadPlatformTenantRequiredQualificationPackage( const uploaded = await uploadPlatformTenantRequiredQualificationPackage(
tenantId, businessLicense.file, legalPersonId.file, form.value.unifiedSocialCreditCode, tenantId, businessLicenseFile, legalPersonIdFile, form.value.unifiedSocialCreditCode,
businessLicense.uploaded, legalPersonId.uploaded, businessLicense.uploaded, Boolean(legalPersonIdFile && legalPersonId?.uploaded),
) )
businessLicense.uploaded = true; legalPersonId.uploaded = true if (legalPersonIdFile && !uploaded.legalPersonIdDocumentUrl) throw new Error('法人身份证上传结果缺少文件地址')
businessLicense.uploaded = true
creditCodeEstablished.value = true creditCodeEstablished.value = true
businessLicense.uploadedName = businessLicense.file.name businessLicense.uploadedName = businessLicenseFile.name
legalPersonId.uploadedName = legalPersonId.file.name
businessLicense.documentUrl = uploaded.businessLicenseDocumentUrl businessLicense.documentUrl = uploaded.businessLicenseDocumentUrl
legalPersonId.documentUrl = uploaded.legalPersonIdDocumentUrl businessLicense.file = null
businessLicense.file = null; legalPersonId.file = null if (legalPersonIdFile && legalPersonId) {
legalPersonId.uploaded = true
legalPersonId.uploadedName = legalPersonIdFile.name
legalPersonId.documentUrl = uploaded.legalPersonIdDocumentUrl || ''
legalPersonId.file = null
}
} catch (error) { } catch (error) {
const message = getApiErrorMessage(error, '必填资质包上传失败,请重试') const message = getApiErrorMessage(error, '营业执照及统一社会信用代码保存失败,请重试')
businessLicense.error = message; legalPersonId.error = message businessLicense.error = message
failures.push('必填资质包') if (legalPersonIdFile && legalPersonId) legalPersonId.error = message
failures.push('营业执照资质')
} finally { } finally {
businessLicense.uploading = false; legalPersonId.uploading = false businessLicense.uploading = false
if (legalPersonId) legalPersonId.uploading = false
} }
} }
for (const draft of failures.length ? [] : qualifications.value.filter((item) => !item.required && item.file)) { for (const draft of failures.length ? [] : qualifications.value.filter((item) => !item.required && item.file)) {
+4 -4
View File
@@ -128,10 +128,10 @@ export interface PlatformQualificationUploadResponse {
export interface PlatformRequiredQualificationPackageUploadResponse { export interface PlatformRequiredQualificationPackageUploadResponse {
businessLicenseQualificationId: number | string businessLicenseQualificationId: number | string
legalPersonIdQualificationId: number | string legalPersonIdQualificationId: number | string | null
tenantStatus: PlatformTenantStatus tenantStatus: PlatformTenantStatus
businessLicenseDocumentUrl: string businessLicenseDocumentUrl: string
legalPersonIdDocumentUrl: string legalPersonIdDocumentUrl: string | null
} }
export interface EnterpriseApprovalResponse { export interface EnterpriseApprovalResponse {
@@ -429,14 +429,14 @@ export async function uploadPlatformTenantQualification(
export async function uploadPlatformTenantRequiredQualificationPackage( export async function uploadPlatformTenantRequiredQualificationPackage(
tenantId: number | string, tenantId: number | string,
businessLicense: File, businessLicense: File,
legalPersonId: File, legalPersonId: File | null,
unifiedSocialCreditCode: string, unifiedSocialCreditCode: string,
replaceBusinessLicense = false, replaceBusinessLicense = false,
replaceLegalPersonId = false, replaceLegalPersonId = false,
) { ) {
const form = new FormData() const form = new FormData()
form.append('businessLicense', businessLicense) form.append('businessLicense', businessLicense)
form.append('legalPersonId', legalPersonId) if (legalPersonId) form.append('legalPersonId', legalPersonId)
form.append('unifiedSocialCreditCode', unifiedSocialCreditCode) form.append('unifiedSocialCreditCode', unifiedSocialCreditCode)
if (replaceBusinessLicense) form.append('replaceBusinessLicense', 'true') if (replaceBusinessLicense) form.append('replaceBusinessLicense', 'true')
if (replaceLegalPersonId) form.append('replaceLegalPersonId', 'true') if (replaceLegalPersonId) form.append('replaceLegalPersonId', 'true')
+1 -1
View File
@@ -32,7 +32,7 @@ describe('API error diagnostics', () => {
} }
} }
await http.post('/auth/login', { username: 'operator', password: 'secret' }) await http.post('/auth/login', { loginId: 'operator', password: 'secret' })
expect(authorization).toBeUndefined() expect(authorization).toBeUndefined()
localStorage.removeItem('cc-admin-token') localStorage.removeItem('cc-admin-token')