优化
This commit is contained in:
@@ -9,6 +9,7 @@ function normalizeSupplier(raw: Supplier): Supplier {
|
|||||||
return {
|
return {
|
||||||
...raw,
|
...raw,
|
||||||
id: String(raw.id), tenantId: String(raw.tenantId),
|
id: String(raw.id), tenantId: String(raw.tenantId),
|
||||||
|
carrierCode: raw.carrierCode ?? null,
|
||||||
licenseFileId: id(raw.licenseFileId), createdBy: id(raw.createdBy), updatedBy: id(raw.updatedBy),
|
licenseFileId: id(raw.licenseFileId), createdBy: id(raw.createdBy), updatedBy: id(raw.updatedBy),
|
||||||
version: Number(raw.version), deleted: Boolean(raw.deleted),
|
version: Number(raw.version), deleted: Boolean(raw.deleted),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
|||||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||||
import SupplierLicenseDialog from '@/modules/suppliers/components/SupplierLicenseDialog.vue'
|
import SupplierLicenseDialog from '@/modules/suppliers/components/SupplierLicenseDialog.vue'
|
||||||
import { getSupplier } from '@/modules/suppliers/api/platformSuppliers'
|
import { getSupplier } from '@/modules/suppliers/api/platformSuppliers'
|
||||||
import { categoryLabels, settlementLabels, statusLabels, type Supplier } from '@/modules/suppliers/types'
|
import { categoryLabels, formatCarrierCode, settlementLabels, statusLabels, type Supplier } from '@/modules/suppliers/types'
|
||||||
|
|
||||||
const route = useRoute(); const router = useRouter(); const access = useAccessPreviewStore()
|
const route = useRoute(); const router = useRouter(); const access = useAccessPreviewStore()
|
||||||
const canView = computed(() => access.can('platform:supplier:list'))
|
const canView = computed(() => access.can('platform:supplier:list'))
|
||||||
@@ -19,7 +19,7 @@ const supplierId = computed(() => typeof route.params.id === 'string' ? route.pa
|
|||||||
const supplier = ref<Supplier | null>(null); const loading = ref(false); const error = ref<ApiErrorDetails | null>(null); const licenseOpen = ref(false)
|
const supplier = ref<Supplier | null>(null); const loading = ref(false); const error = ref<ApiErrorDetails | null>(null); const licenseOpen = ref(false)
|
||||||
let loadSequence = 0
|
let loadSequence = 0
|
||||||
const items = computed(() => supplier.value ? [
|
const items = computed(() => supplier.value ? [
|
||||||
['供应商名称', supplier.value.name], ['供应商类别', categoryLabels[supplier.value.category]], ['地区', supplier.value.region],
|
['供应商名称', supplier.value.name], ['供应商类别', categoryLabels[supplier.value.category]], ['船司标准编码', formatCarrierCode(supplier.value.carrierCode)], ['地区', supplier.value.region],
|
||||||
['法人代表', supplier.value.legalRepresentative], ['联系人', supplier.value.contactName], ['联系电话', supplier.value.phone], ['电子邮箱', supplier.value.email || '—'],
|
['法人代表', supplier.value.legalRepresentative], ['联系人', supplier.value.contactName], ['联系电话', supplier.value.phone], ['电子邮箱', supplier.value.email || '—'],
|
||||||
['营业执照号', supplier.value.businessLicenseNo || '—'], ['结算周期', settlementLabels[supplier.value.settlementPeriod]], ['公司地址', supplier.value.address || '—'], ['备注', supplier.value.remark || '—'],
|
['营业执照号', supplier.value.businessLicenseNo || '—'], ['结算周期', settlementLabels[supplier.value.settlementPeriod]], ['公司地址', supplier.value.address || '—'], ['备注', supplier.value.remark || '—'],
|
||||||
] : [])
|
] : [])
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
|||||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||||
import { useUnsavedWorkRegistration } from '@/core/unsaved-work/useUnsavedWorkRegistration'
|
import { useUnsavedWorkRegistration } from '@/core/unsaved-work/useUnsavedWorkRegistration'
|
||||||
import { createSupplier, getSupplier, updateSupplier } from '@/modules/suppliers/api/platformSuppliers'
|
import { createSupplier, getSupplier, updateSupplier } from '@/modules/suppliers/api/platformSuppliers'
|
||||||
import { categoryLabels, settlementLabels, statusLabels, type SaveSupplierRequest } from '@/modules/suppliers/types'
|
import { carrierCodeOptions, categoryLabels, settlementLabels, statusLabels, type SaveSupplierRequest } from '@/modules/suppliers/types'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -26,10 +26,11 @@ const loading = ref(false)
|
|||||||
const saving = ref(false)
|
const saving = ref(false)
|
||||||
const loadError = ref<ApiErrorDetails | null>(null)
|
const loadError = ref<ApiErrorDetails | null>(null)
|
||||||
const submitError = ref<ApiErrorDetails | null>(null)
|
const submitError = ref<ApiErrorDetails | null>(null)
|
||||||
const initial = (): SaveSupplierRequest => ({ name: '', category: 'BOOKING', region: '', legalRepresentative: '', contactName: '', phone: '', email: null, address: null, businessLicenseNo: null, licenseFileId: null, status: 'ACTIVE', settlementPeriod: 'MONTHLY_30', remark: null })
|
const initial = (): SaveSupplierRequest => ({ name: '', category: 'BOOKING', carrierCode: null, region: '', legalRepresentative: '', contactName: '', phone: '', email: null, address: null, businessLicenseNo: null, licenseFileId: null, status: 'ACTIVE', settlementPeriod: 'MONTHLY_30', remark: null })
|
||||||
const form = reactive(initial())
|
const form = reactive(initial())
|
||||||
const rules: FormRules<SaveSupplierRequest> = {
|
const rules: FormRules<SaveSupplierRequest> = {
|
||||||
name: [{ required: true, message: '请输入供应商名称', trigger: 'blur' }], category: [{ required: true, message: '请选择供应商类别', trigger: 'change' }],
|
name: [{ required: true, message: '请输入供应商名称', trigger: 'blur' }], category: [{ required: true, message: '请选择供应商类别', trigger: 'change' }],
|
||||||
|
carrierCode: [{ validator: (_rule, value, callback) => form.category === 'BOOKING' && !value ? callback(new Error('请选择船司标准编码')) : callback(), trigger: 'change' }],
|
||||||
region: [{ required: true, message: '请输入地区', trigger: 'blur' }], legalRepresentative: [{ required: true, message: '请输入法人代表', trigger: 'blur' }],
|
region: [{ required: true, message: '请输入地区', trigger: 'blur' }], legalRepresentative: [{ required: true, message: '请输入法人代表', trigger: 'blur' }],
|
||||||
contactName: [{ required: true, message: '请输入联系人', trigger: 'blur' }], phone: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
|
contactName: [{ required: true, message: '请输入联系人', trigger: 'blur' }], phone: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
|
||||||
email: [{ type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }], status: [{ required: true, message: '请选择合作状态', trigger: 'change' }],
|
email: [{ type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }], status: [{ required: true, message: '请选择合作状态', trigger: 'change' }],
|
||||||
@@ -39,7 +40,9 @@ const { captureBaseline } = useUnsavedWorkRegistration({ key: 'supplier-editor',
|
|||||||
|
|
||||||
function optional(value: string | null) { return value?.trim() || null }
|
function optional(value: string | null) { return value?.trim() || null }
|
||||||
function payload(): SaveSupplierRequest {
|
function payload(): SaveSupplierRequest {
|
||||||
return { ...form, name: form.name.trim(), region: form.region.trim(), legalRepresentative: form.legalRepresentative.trim(), contactName: form.contactName.trim(), phone: form.phone.trim(), email: optional(form.email), address: optional(form.address), businessLicenseNo: optional(form.businessLicenseNo), licenseFileId: form.licenseFileId, remark: optional(form.remark) }
|
const { carrierCode, ...fields } = form
|
||||||
|
const normalized = { ...fields, name: form.name.trim(), region: form.region.trim(), legalRepresentative: form.legalRepresentative.trim(), contactName: form.contactName.trim(), phone: form.phone.trim(), email: optional(form.email), address: optional(form.address), businessLicenseNo: optional(form.businessLicenseNo), licenseFileId: form.licenseFileId, remark: optional(form.remark) }
|
||||||
|
return form.category === 'BOOKING' ? { ...normalized, carrierCode } : normalized
|
||||||
}
|
}
|
||||||
let loadSequence = 0
|
let loadSequence = 0
|
||||||
function resetForm() { Object.assign(form, initial()) }
|
function resetForm() { Object.assign(form, initial()) }
|
||||||
@@ -55,7 +58,7 @@ async function load() {
|
|||||||
try {
|
try {
|
||||||
const data = await getSupplier(requestedId)
|
const data = await getSupplier(requestedId)
|
||||||
if (sequence !== loadSequence || requestedId !== supplierId.value) return
|
if (sequence !== loadSequence || requestedId !== supplierId.value) return
|
||||||
Object.assign(form, { name: data.name, category: data.category, region: data.region, legalRepresentative: data.legalRepresentative, contactName: data.contactName, phone: data.phone, email: data.email, address: data.address, businessLicenseNo: data.businessLicenseNo, licenseFileId: data.licenseFileId, status: data.status, settlementPeriod: data.settlementPeriod, remark: data.remark })
|
Object.assign(form, { name: data.name, category: data.category, carrierCode: data.category === 'BOOKING' ? data.carrierCode : null, region: data.region, legalRepresentative: data.legalRepresentative, contactName: data.contactName, phone: data.phone, email: data.email, address: data.address, businessLicenseNo: data.businessLicenseNo, licenseFileId: data.licenseFileId, status: data.status, settlementPeriod: data.settlementPeriod, remark: data.remark })
|
||||||
captureBaseline()
|
captureBaseline()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (sequence === loadSequence && requestedId === supplierId.value) loadError.value = getApiErrorDetails(error, '供应商详情加载失败')
|
if (sequence === loadSequence && requestedId === supplierId.value) loadError.value = getApiErrorDetails(error, '供应商详情加载失败')
|
||||||
@@ -74,6 +77,7 @@ async function save() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
watch(supplierId, () => { void load() }, { immediate: true })
|
watch(supplierId, () => { void load() }, { immediate: true })
|
||||||
|
watch(() => form.category, (category) => { if (category !== 'BOOKING') form.carrierCode = null })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -89,6 +93,7 @@ watch(supplierId, () => { void load() }, { immediate: true })
|
|||||||
<div class="form-grid">
|
<div class="form-grid">
|
||||||
<el-form-item label="供应商名称" prop="name"><el-input v-model="form.name" maxlength="160" placeholder="请输入供应商名称" /></el-form-item>
|
<el-form-item label="供应商名称" prop="name"><el-input v-model="form.name" maxlength="160" placeholder="请输入供应商名称" /></el-form-item>
|
||||||
<el-form-item label="供应商类别" prop="category"><el-select v-model="form.category"><el-option v-for="(label, value) in categoryLabels" :key="value" :label="label" :value="value" /></el-select></el-form-item>
|
<el-form-item label="供应商类别" prop="category"><el-select v-model="form.category"><el-option v-for="(label, value) in categoryLabels" :key="value" :label="label" :value="value" /></el-select></el-form-item>
|
||||||
|
<el-form-item v-if="form.category === 'BOOKING'" label="船司标准编码" prop="carrierCode"><el-select v-model="form.carrierCode" placeholder="请选择船司标准编码"><el-option v-for="option in carrierCodeOptions" :key="option.value" :label="option.label" :value="option.value" /></el-select></el-form-item>
|
||||||
<el-form-item label="地区" prop="region"><el-input v-model="form.region" maxlength="80" placeholder="请输入地区" /></el-form-item>
|
<el-form-item label="地区" prop="region"><el-input v-model="form.region" maxlength="80" placeholder="请输入地区" /></el-form-item>
|
||||||
<el-form-item label="法人代表" prop="legalRepresentative"><el-input v-model="form.legalRepresentative" maxlength="80" placeholder="请输入法人代表" /></el-form-item>
|
<el-form-item label="法人代表" prop="legalRepresentative"><el-input v-model="form.legalRepresentative" maxlength="80" placeholder="请输入法人代表" /></el-form-item>
|
||||||
<el-form-item label="联系人" prop="contactName"><el-input v-model="form.contactName" maxlength="80" placeholder="请输入联系人" /></el-form-item>
|
<el-form-item label="联系人" prop="contactName"><el-input v-model="form.contactName" maxlength="80" placeholder="请输入联系人" /></el-form-item>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ vi.mock('@/core/unsaved-work/useUnsavedWorkRegistration', () => ({ useUnsavedWor
|
|||||||
vi.mock('@/modules/suppliers/api/platformSuppliers', () => ({ getSupplier: mocks.getSupplier, updateSupplier: mocks.updateSupplier, createSupplier: vi.fn() }))
|
vi.mock('@/modules/suppliers/api/platformSuppliers', () => ({ getSupplier: mocks.getSupplier, updateSupplier: mocks.updateSupplier, createSupplier: vi.fn() }))
|
||||||
|
|
||||||
function supplier(id: string, name: string): Supplier {
|
function supplier(id: string, name: string): Supplier {
|
||||||
return { id, tenantId: '0', name, category: 'BOOKING', region: '宁波', legalRepresentative: '法人', contactName: '联系人', phone: '13800000000', email: null, address: null, businessLicenseNo: null, licenseFileId: null, status: 'ACTIVE', settlementPeriod: 'MONTHLY_30', remark: null, createdBy: null, createdAt: '', updatedBy: null, updatedAt: '', deleted: false, version: 1 }
|
return { id, tenantId: '0', name, category: 'BOOKING', carrierCode: 'MATSON', region: '宁波', legalRepresentative: '法人', contactName: '联系人', phone: '13800000000', email: null, address: null, businessLicenseNo: null, licenseFileId: null, status: 'ACTIVE', settlementPeriod: 'MONTHLY_30', remark: null, createdBy: null, createdAt: '', updatedBy: null, updatedAt: '', deleted: false, version: 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
function deferred<T>() {
|
function deferred<T>() {
|
||||||
|
|||||||
@@ -48,6 +48,16 @@ describe('supplier formal pages', () => {
|
|||||||
expect(detailSource).toContain('<ApiErrorMeta')
|
expect(detailSource).toContain('<ApiErrorMeta')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('uses a fixed carrier-code selector for booking suppliers and shows the code in list and detail', () => {
|
||||||
|
expect(formSource).toContain('v-if="form.category === \'BOOKING\'"')
|
||||||
|
expect(formSource).toContain('v-for="option in carrierCodeOptions"')
|
||||||
|
expect(formSource).not.toContain('v-model="form.carrierCode" maxlength')
|
||||||
|
expect(formSource).toContain("if (category !== 'BOOKING') form.carrierCode = null")
|
||||||
|
expect(formSource).toContain("return form.category === 'BOOKING' ? { ...normalized, carrierCode } : normalized")
|
||||||
|
expect(source).toContain("label: '船司标准编码'")
|
||||||
|
expect(detailSource).toContain("['船司标准编码', formatCarrierCode(supplier.value.carrierCode)]")
|
||||||
|
})
|
||||||
|
|
||||||
it('reloads detail data when the reused route id changes and protects the newer request', () => {
|
it('reloads detail data when the reused route id changes and protects the newer request', () => {
|
||||||
expect(detailSource).toContain("watch(supplierId, () => { void load() }, { immediate: true })")
|
expect(detailSource).toContain("watch(supplierId, () => { void load() }, { immediate: true })")
|
||||||
expect(detailSource).toContain('const requestedId = supplierId.value')
|
expect(detailSource).toContain('const requestedId = supplierId.value')
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
|||||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||||
import SupplierLicenseDialog from '@/modules/suppliers/components/SupplierLicenseDialog.vue'
|
import SupplierLicenseDialog from '@/modules/suppliers/components/SupplierLicenseDialog.vue'
|
||||||
import { changeSupplierStatus, getSupplierStats, listSuppliers } from '@/modules/suppliers/api/platformSuppliers'
|
import { changeSupplierStatus, getSupplierStats, listSuppliers } from '@/modules/suppliers/api/platformSuppliers'
|
||||||
import { categoryLabels, settlementLabels, statusLabels, type Supplier, type SupplierCategory, type SupplierStats, type SupplierStatus } from '@/modules/suppliers/types'
|
import { categoryLabels, formatCarrierCode, settlementLabels, statusLabels, type Supplier, type SupplierCategory, type SupplierStats, type SupplierStatus } from '@/modules/suppliers/types'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const access = useAccessPreviewStore()
|
const access = useAccessPreviewStore()
|
||||||
@@ -45,6 +45,7 @@ const columns = computed<DataTableColumn[]>(() => [
|
|||||||
{ key: 'actions', label: '操作', width: 260, fixed: 'left', slotName: 'actions' },
|
{ key: 'actions', label: '操作', width: 260, fixed: 'left', slotName: 'actions' },
|
||||||
{ key: 'name', label: '供应商名称', minWidth: 230, slotName: 'name' },
|
{ key: 'name', label: '供应商名称', minWidth: 230, slotName: 'name' },
|
||||||
{ key: 'category', label: '类别', width: 90, slotName: 'category' },
|
{ key: 'category', label: '类别', width: 90, slotName: 'category' },
|
||||||
|
{ key: 'carrierCode', label: '船司标准编码', minWidth: 160, slotName: 'carrierCode' },
|
||||||
{ key: 'region', label: '地区', minWidth: 110 },
|
{ key: 'region', label: '地区', minWidth: 110 },
|
||||||
{ key: 'legalRepresentative', label: '法人', minWidth: 120 },
|
{ key: 'legalRepresentative', label: '法人', minWidth: 120 },
|
||||||
{ key: 'contactName', label: '联系人', minWidth: 110 },
|
{ key: 'contactName', label: '联系人', minWidth: 110 },
|
||||||
@@ -148,6 +149,7 @@ onMounted(load)
|
|||||||
</template>
|
</template>
|
||||||
<template #name="{ row }"><strong class="supplier-name">{{ row.name }}</strong></template>
|
<template #name="{ row }"><strong class="supplier-name">{{ row.name }}</strong></template>
|
||||||
<template #category="{ row }">{{ categoryLabels[row.category as SupplierCategory] }}</template>
|
<template #category="{ row }">{{ categoryLabels[row.category as SupplierCategory] }}</template>
|
||||||
|
<template #carrierCode="{ row }">{{ formatCarrierCode(supplierRow(row).carrierCode) }}</template>
|
||||||
<template #license="{ row }"><el-button size="small" plain type="primary" @click="showLicense(supplierRow(row))"><FileText :size="15" />查看</el-button></template>
|
<template #license="{ row }"><el-button size="small" plain type="primary" @click="showLicense(supplierRow(row))"><FileText :size="15" />查看</el-button></template>
|
||||||
<template #status="{ row }"><StatusBadge :status="statusLabels[row.status as SupplierStatus]" /></template>
|
<template #status="{ row }"><StatusBadge :status="statusLabels[row.status as SupplierStatus]" /></template>
|
||||||
<template #settlement="{ row }">{{ settlementLabels[supplierRow(row).settlementPeriod] }}</template>
|
<template #settlement="{ row }">{{ settlementLabels[supplierRow(row).settlementPeriod] }}</template>
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
export type SupplierCategory = 'BOOKING' | 'CUSTOMS' | 'TRUCKING' | 'CERTIFICATE'
|
export type SupplierCategory = 'BOOKING' | 'CUSTOMS' | 'TRUCKING' | 'CERTIFICATE'
|
||||||
export type SupplierStatus = 'ACTIVE' | 'INACTIVE'
|
export type SupplierStatus = 'ACTIVE' | 'INACTIVE'
|
||||||
export type SettlementPeriod = 'MONTHLY_30' | 'MONTHLY_45' | 'MONTHLY_60' | 'MONTHLY_90' | 'PER_TRANSACTION' | 'IMMEDIATE'
|
export type SettlementPeriod = 'MONTHLY_30' | 'MONTHLY_45' | 'MONTHLY_60' | 'MONTHLY_90' | 'PER_TRANSACTION' | 'IMMEDIATE'
|
||||||
|
export type CarrierCode = 'MATSON' | 'SML' | 'ZIM' | 'COSCO' | 'EMC' | 'HEDE' | 'OTHER'
|
||||||
|
|
||||||
export interface Supplier {
|
export interface Supplier {
|
||||||
id: string
|
id: string
|
||||||
tenantId: string
|
tenantId: string
|
||||||
name: string
|
name: string
|
||||||
category: SupplierCategory
|
category: SupplierCategory
|
||||||
|
carrierCode?: CarrierCode | null
|
||||||
region: string
|
region: string
|
||||||
legalRepresentative: string
|
legalRepresentative: string
|
||||||
contactName: string
|
contactName: string
|
||||||
@@ -48,6 +50,7 @@ export interface SupplierQuery {
|
|||||||
export interface SaveSupplierRequest {
|
export interface SaveSupplierRequest {
|
||||||
name: string
|
name: string
|
||||||
category: SupplierCategory
|
category: SupplierCategory
|
||||||
|
carrierCode?: CarrierCode | null
|
||||||
region: string
|
region: string
|
||||||
legalRepresentative: string
|
legalRepresentative: string
|
||||||
contactName: string
|
contactName: string
|
||||||
@@ -62,6 +65,11 @@ export interface SaveSupplierRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const categoryLabels: Record<SupplierCategory, string> = { BOOKING: '订舱', CUSTOMS: '报关', TRUCKING: '拖车', CERTIFICATE: '证书' }
|
export const categoryLabels: Record<SupplierCategory, string> = { BOOKING: '订舱', CUSTOMS: '报关', TRUCKING: '拖车', CERTIFICATE: '证书' }
|
||||||
|
export const carrierCodeLabels: Record<CarrierCode, string> = {
|
||||||
|
MATSON: '美森', SML: 'SML', ZIM: '以星', COSCO: '中远', EMC: '长荣', HEDE: '合德', OTHER: '其他',
|
||||||
|
}
|
||||||
|
export const carrierCodeOptions = (Object.entries(carrierCodeLabels) as [CarrierCode, string][]).map(([value, name]) => ({ value, label: `${name} (${value})` }))
|
||||||
|
export function formatCarrierCode(code: CarrierCode | null | undefined) { return code ? `${carrierCodeLabels[code]} (${code})` : '—' }
|
||||||
export const statusLabels: Record<SupplierStatus, string> = { ACTIVE: '合作中', INACTIVE: '停用' }
|
export const statusLabels: Record<SupplierStatus, string> = { ACTIVE: '合作中', INACTIVE: '停用' }
|
||||||
export const settlementLabels: Record<SettlementPeriod, string> = {
|
export const settlementLabels: Record<SettlementPeriod, string> = {
|
||||||
MONTHLY_30: '月结30天', MONTHLY_45: '月结45天', MONTHLY_60: '月结60天', MONTHLY_90: '月结90天', PER_TRANSACTION: '票结', IMMEDIATE: '现结',
|
MONTHLY_30: '月结30天', MONTHLY_45: '月结45天', MONTHLY_60: '月结60天', MONTHLY_90: '月结90天', PER_TRANSACTION: '票结', IMMEDIATE: '现结',
|
||||||
|
|||||||
Reference in New Issue
Block a user