优化
This commit is contained in:
@@ -8,7 +8,7 @@ vi.mock('@/shared/api/http', async (original) => ({
|
||||
http: { get: vi.fn(), post: vi.fn(), put: vi.fn(), patch: vi.fn() },
|
||||
}))
|
||||
|
||||
const payload: SaveSupplierRequest = { name: '测试供应商', category: 'BOOKING', carrierCodes: ['MATSON', 'SML'], region: '宁波', legalRepresentative: '张三', contactName: '李四', phone: '13800000000', email: null, address: null, businessLicenseNo: null, licenseFileId: '9007199254740995', status: 'ACTIVE', settlementPeriod: 'MONTHLY_30', remark: null }
|
||||
const payload: SaveSupplierRequest = { name: '测试供应商', category: 'BOOKING', truckingScope: null, carrierCodes: ['MATSON', 'SML'], region: '宁波', legalRepresentative: '张三', contactName: '李四', phone: '13800000000', email: null, address: null, businessLicenseNo: null, licenseFileId: '9007199254740995', status: 'ACTIVE', settlementPeriod: 'MONTHLY_30', remark: null }
|
||||
const resource = { id: 9007199254740993, tenantId: 0, ...payload, createdBy: 9007199254740994, createdAt: '2026-08-13T10:00:00', updatedBy: null, updatedAt: '2026-08-13T10:00:00', deleted: false, version: 1 }
|
||||
|
||||
describe('platform supplier API', () => {
|
||||
@@ -37,4 +37,11 @@ describe('platform supplier API', () => {
|
||||
expect(http.put).toHaveBeenCalledWith('/platform/v1/suppliers/77', payload, { params: { tenantId: 0 } })
|
||||
expect(http.patch).toHaveBeenCalledWith('/platform/v1/suppliers/77/status', { status: 'INACTIVE' }, { params: { tenantId: 0 } })
|
||||
})
|
||||
it('passes the trucking scope filter and keeps the authoritative type in resources', async () => {
|
||||
vi.mocked(http.get).mockResolvedValue({ code: '200', data: { records: [{ ...resource, category: 'TRUCKING', carrierCodes: [], truckingScope: 'OVERSEAS' }], page: 1, size: 20, total: 1, pages: 1 } })
|
||||
const page = await listSuppliers({ category: 'TRUCKING', truckingScope: 'OVERSEAS', status: 'ACTIVE' })
|
||||
expect(http.get).toHaveBeenCalledWith('/platform/v1/suppliers', { params: expect.objectContaining({ category: 'TRUCKING', truckingScope: 'OVERSEAS', status: 'ACTIVE' }) })
|
||||
expect(page.records[0]?.truckingScope).toBe('OVERSEAS')
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@@ -21,7 +21,7 @@ export async function listSuppliers(query: SupplierQuery): Promise<SupplierPage>
|
||||
page: query.page ?? 1, size: query.size ?? 20, category: query.category,
|
||||
region: query.region?.trim() || undefined,
|
||||
status: query.status || undefined, keyword: query.keyword?.trim() || undefined,
|
||||
carrierCode: query.carrierCode || undefined,
|
||||
carrierCode: query.carrierCode || undefined, truckingScope: query.truckingScope,
|
||||
},
|
||||
})
|
||||
const data = unwrapApiResponse(response)
|
||||
|
||||
@@ -12,7 +12,7 @@ import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import SupplierLicenseDialog from '@/modules/suppliers/components/SupplierLicenseDialog.vue'
|
||||
import { getSupplier } from '@/modules/suppliers/api/platformSuppliers'
|
||||
import { categoryLabels, formatCarrierCodes, settlementLabels, statusLabels, type Supplier } from '@/modules/suppliers/types'
|
||||
import { formatTruckingScope, categoryLabels, formatCarrierCodes, settlementLabels, statusLabels, type Supplier } from '@/modules/suppliers/types'
|
||||
|
||||
const route = useRoute(); const router = useRouter(); const access = useAccessPreviewStore()
|
||||
const canView = computed(() => access.can('platform:supplier:list'))
|
||||
@@ -21,6 +21,7 @@ const supplier = ref<Supplier | null>(null); const loading = ref(false); const e
|
||||
let loadSequence = 0
|
||||
const items = computed(() => supplier.value ? [
|
||||
['供应商名称', supplier.value.name], ['供应商类别', categoryLabels[supplier.value.category]], ['可代理船公司', supplier.value.category === 'BOOKING' ? formatCarrierCodes(supplier.value.carrierCodes) : '—'], ['地区', supplier.value.region],
|
||||
...(supplier.value.category === 'TRUCKING' ? [['拖车类型', formatTruckingScope(supplier.value.truckingScope)]] : []),
|
||||
['法人代表', 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 || '—'],
|
||||
] : [])
|
||||
|
||||
@@ -14,7 +14,7 @@ import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import { useUnsavedWorkRegistration } from '@/core/unsaved-work/useUnsavedWorkRegistration'
|
||||
import { createSupplier, getSupplier, updateSupplier } from '@/modules/suppliers/api/platformSuppliers'
|
||||
import { carrierCodeOptions, categoryLabels, settlementLabels, statusLabels, type SaveSupplierRequest } from '@/modules/suppliers/types'
|
||||
import { truckingScopeLabels, carrierCodeOptions, categoryLabels, settlementLabels, statusLabels, type TruckingScope, type SaveSupplierRequest } from '@/modules/suppliers/types'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@@ -27,10 +27,13 @@ const loading = ref(false)
|
||||
const saving = ref(false)
|
||||
const loadError = ref<ApiErrorDetails | null>(null)
|
||||
const submitError = ref<ApiErrorDetails | null>(null)
|
||||
const initial = (): SaveSupplierRequest => ({ name: '', category: 'BOOKING', carrierCodes: [], 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', truckingScope: null, carrierCodes: [], region: '', legalRepresentative: '', contactName: '', phone: '', email: null, address: null, businessLicenseNo: null, licenseFileId: null, status: 'ACTIVE', settlementPeriod: 'MONTHLY_30', remark: null })
|
||||
const form = reactive(initial())
|
||||
const saveAttempted = ref(false)
|
||||
const truckingScopeError = computed(() => saveAttempted.value && form.category === 'TRUCKING' && !form.truckingScope ? '请选择国内拖车或海外车队' : '')
|
||||
const rules: FormRules<SaveSupplierRequest> = {
|
||||
name: [{ required: true, message: '请输入供应商名称', trigger: 'blur' }], category: [{ required: true, message: '请选择供应商类别', trigger: 'change' }],
|
||||
truckingScope: [{ required: true, type: 'enum', enum: ['DOMESTIC', 'OVERSEAS'], message: '请选择国内拖车或海外车队', trigger: 'change' }],
|
||||
carrierCodes: [{ validator: (_rule, value, callback) => form.category === 'BOOKING' && (!Array.isArray(value) || value.length === 0) ? callback(new Error('请至少选择一家可代理船公司')) : callback(), trigger: 'change' }],
|
||||
region: [{ required: true, message: '请输入地区', trigger: 'blur' }], legalRepresentative: [{ required: true, message: '请输入法人代表', trigger: 'blur' }],
|
||||
contactName: [{ required: true, message: '请输入联系人', trigger: 'blur' }], phone: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
|
||||
@@ -42,11 +45,11 @@ const { captureBaseline } = useUnsavedWorkRegistration({ key: 'supplier-editor',
|
||||
function optional(value: string | null) { return value?.trim() || null }
|
||||
function payload(): SaveSupplierRequest {
|
||||
const { carrierCodes, ...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) }
|
||||
const normalized = { ...fields, truckingScope: form.category === 'TRUCKING' ? form.truckingScope : null, 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, carrierCodes: [...(carrierCodes || [])] } : normalized
|
||||
}
|
||||
let loadSequence = 0
|
||||
function resetForm() { Object.assign(form, initial()) }
|
||||
function resetForm() { Object.assign(form, initial()); saveAttempted.value = false }
|
||||
async function load() {
|
||||
const requestedId = supplierId.value
|
||||
const sequence = ++loadSequence
|
||||
@@ -59,7 +62,7 @@ async function load() {
|
||||
try {
|
||||
const data = await getSupplier(requestedId)
|
||||
if (sequence !== loadSequence || requestedId !== supplierId.value) return
|
||||
Object.assign(form, { name: data.name, category: data.category, carrierCodes: data.category === 'BOOKING' ? [...data.carrierCodes] : [], 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, truckingScope: data.truckingScope, carrierCodes: data.category === 'BOOKING' ? [...data.carrierCodes] : [], 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()
|
||||
} catch (error) {
|
||||
if (sequence === loadSequence && requestedId === supplierId.value) loadError.value = getApiErrorDetails(error, '供应商详情加载失败')
|
||||
@@ -67,6 +70,8 @@ async function load() {
|
||||
}
|
||||
async function save() {
|
||||
if (!access.can(requiredPermission.value)) return
|
||||
saveAttempted.value = true
|
||||
if (truckingScopeError.value) return
|
||||
if (!await formRef.value?.validate().catch(() => false)) return
|
||||
saving.value = true; submitError.value = null
|
||||
try {
|
||||
@@ -86,7 +91,7 @@ onActivated(() => {
|
||||
else activatedOnce = true
|
||||
})
|
||||
onDeactivated(() => { active = false })
|
||||
watch(() => form.category, (category) => { if (category !== 'BOOKING') form.carrierCodes = [] })
|
||||
watch(() => form.category, (category) => { if (category !== 'BOOKING') form.carrierCodes = []; if (category !== 'TRUCKING') form.truckingScope = null })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -103,6 +108,7 @@ watch(() => form.category, (category) => { if (category !== 'BOOKING') form.carr
|
||||
<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 v-if="form.category === 'BOOKING'" label="可代理船公司" prop="carrierCodes"><el-select v-model="form.carrierCodes" multiple collapse-tags collapse-tags-tooltip 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 v-if="form.category === 'TRUCKING'" label="拖车类型" prop="truckingScope" :error="truckingScopeError" required><el-radio-group :model-value="form.truckingScope ?? undefined" @update:model-value="form.truckingScope = $event as TruckingScope"><el-radio v-for="(label, value) in truckingScopeLabels" :key="value" :value="value">{{ label }}</el-radio></el-radio-group></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="contactName"><el-input v-model="form.contactName" maxlength="80" placeholder="请输入联系人" /></el-form-item>
|
||||
|
||||
@@ -26,7 +26,7 @@ vi.mock('@/modules/suppliers/api/platformSuppliers', () => ({
|
||||
}))
|
||||
|
||||
function supplier(id: string, name: string): Supplier {
|
||||
return { id, tenantId: '0', name, category: 'BOOKING', carrierCodes: ['MATSON', 'SML'], 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', truckingScope: null, carrierCodes: ['MATSON', 'SML'], 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>() {
|
||||
@@ -152,4 +152,24 @@ describe('supplier route reuse', () => {
|
||||
expect(mocks.listSuppliers).toHaveBeenCalledTimes(2)
|
||||
expect(mocks.getSupplierStats).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
it('requires one trucking type, saves overseas and clears the type after changing category', async () => {
|
||||
mocks.getSupplier.mockResolvedValue({ ...supplier('A', '车队'), category: 'TRUCKING', carrierCodes: [], truckingScope: null })
|
||||
const wrapper = mount(SupplierFormView, { global: { plugins: [ElementPlus], stubs } })
|
||||
await flushPromises()
|
||||
const save = wrapper.findAll('button').find((button) => button.text().includes('保存'))!
|
||||
await save.trigger('click'); await flushPromises()
|
||||
expect(mocks.updateSupplier).not.toHaveBeenCalled()
|
||||
expect(wrapper.findAllComponents({ name: 'ElFormItem' }).find(item => item.props('prop') === 'truckingScope')?.props('error')).toBe('请选择国内拖车或海外车队')
|
||||
const radios = wrapper.findComponent({ name: 'ElRadioGroup' })
|
||||
expect(radios.text()).toContain('国内拖车')
|
||||
expect(radios.text()).toContain('海外车队')
|
||||
radios.vm.$emit('update:modelValue', 'OVERSEAS')
|
||||
await flushPromises(); await save.trigger('click'); await flushPromises()
|
||||
expect(mocks.updateSupplier).toHaveBeenLastCalledWith('A', expect.objectContaining({ category: 'TRUCKING', truckingScope: 'OVERSEAS' }))
|
||||
wrapper.findAllComponents({ name: 'ElSelect' })[0]!.vm.$emit('update:modelValue', 'CUSTOMS')
|
||||
await flushPromises(); await save.trigger('click'); await flushPromises()
|
||||
expect(wrapper.findComponent({ name: 'ElRadioGroup' }).exists()).toBe(false)
|
||||
expect(mocks.updateSupplier).toHaveBeenLastCalledWith('A', expect.objectContaining({ category: 'CUSTOMS', truckingScope: null }))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@@ -16,7 +16,7 @@ import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import SupplierLicenseDialog from '@/modules/suppliers/components/SupplierLicenseDialog.vue'
|
||||
import { changeSupplierStatus, getSupplierStats, listSuppliers } from '@/modules/suppliers/api/platformSuppliers'
|
||||
import { carrierCodeOptions, categoryLabels, formatCarrierCodes, settlementLabels, statusLabels, type CarrierCode, type Supplier, type SupplierCategory, type SupplierStats, type SupplierStatus } from '@/modules/suppliers/types'
|
||||
import { truckingScopeOptions, formatTruckingScope, type TruckingScope, carrierCodeOptions, categoryLabels, formatCarrierCodes, settlementLabels, statusLabels, type CarrierCode, type Supplier, type SupplierCategory, type SupplierStats, type SupplierStatus } from '@/modules/suppliers/types'
|
||||
|
||||
const router = useRouter()
|
||||
const access = useAccessPreviewStore()
|
||||
@@ -32,14 +32,15 @@ const loadError = ref<ApiErrorDetails | null>(null)
|
||||
const actionId = ref('')
|
||||
const licenseOpen = ref(false)
|
||||
const licenseSupplier = ref<Supplier | null>(null)
|
||||
type Filters = QueryModel & { status: SupplierStatus | ''; region: string; keyword: string; carrierCode: CarrierCode | '' }
|
||||
const filters = ref<Filters>({ status: '', region: '', keyword: '', carrierCode: '' })
|
||||
type Filters = QueryModel & { status: SupplierStatus | ''; region: string; keyword: string; carrierCode: CarrierCode | ''; truckingScope: TruckingScope | '' }
|
||||
const filters = ref<Filters>({ status: '', region: '', keyword: '', carrierCode: '', truckingScope: '' })
|
||||
const applied = ref<Filters>({ ...filters.value })
|
||||
let sequence = 0
|
||||
|
||||
const queryFields = computed<QueryField[]>(() => [
|
||||
{ key: 'status', type: 'select', label: '状态', placeholder: '全部状态', width: 150, options: [{ label: '合作中', value: 'ACTIVE' }, { label: '停用', value: 'INACTIVE' }] },
|
||||
...(activeCategory.value === 'BOOKING' ? [{ key: 'carrierCode', type: 'select' as const, label: '可代理船公司', placeholder: '全部船公司', width: 190, options: carrierCodeOptions }] : []),
|
||||
...(activeCategory.value === 'TRUCKING' ? [{ key: 'truckingScope', type: 'select' as const, label: '拖车类型', placeholder: '全部拖车类型', width: 170, options: truckingScopeOptions }] : []),
|
||||
{ key: 'region', type: 'input', label: '地区', placeholder: '请输入地区', width: 170, props: { maxlength: 80 } },
|
||||
{ key: 'keyword', type: 'input', label: '名称或联系人', placeholder: '供应商名称/联系人', width: 220, props: { maxlength: 160 } },
|
||||
])
|
||||
@@ -48,7 +49,8 @@ const columns = computed<DataTableColumn[]>(() => [
|
||||
{ key: 'actions', label: '操作', width: 260, fixed: 'left', slotName: 'actions' },
|
||||
{ key: 'name', label: '供应商名称', minWidth: 200, slotName: 'name' },
|
||||
{ key: 'category', label: '类别', width: 70, slotName: 'category' },
|
||||
{ key: 'carrierCodes', label: '可代理船公司', minWidth: 200, slotName: 'carrierCodes' },
|
||||
...(activeCategory.value === 'BOOKING' ? [{ key: 'carrierCodes', label: '可代理船公司', minWidth: 200, slotName: 'carrierCodes' }] : []),
|
||||
...(activeCategory.value === 'TRUCKING' ? [{ key: 'truckingScope', label: '拖车类型', width: 110, slotName: 'truckingScope' }] : []),
|
||||
{ key: 'region', label: '地区', minWidth: 100 },
|
||||
{ key: 'legalRepresentative', label: '法人', minWidth: 100 },
|
||||
{ key: 'contactName', label: '联系人', minWidth: 120 },
|
||||
@@ -72,7 +74,7 @@ async function load() {
|
||||
loadError.value = null
|
||||
try {
|
||||
const [result, counts] = await Promise.all([
|
||||
listSuppliers({ page: page.value, size: pageSize.value, category: activeCategory.value, status: applied.value.status, region: applied.value.region, keyword: applied.value.keyword, carrierCode: activeCategory.value === 'BOOKING' ? applied.value.carrierCode || undefined : undefined }),
|
||||
listSuppliers({ page: page.value, size: pageSize.value, category: activeCategory.value, status: applied.value.status, region: applied.value.region, keyword: applied.value.keyword, truckingScope: activeCategory.value === 'TRUCKING' ? applied.value.truckingScope || undefined : undefined, carrierCode: activeCategory.value === 'BOOKING' ? applied.value.carrierCode || undefined : undefined }),
|
||||
getSupplierStats(),
|
||||
])
|
||||
if (current !== sequence) return
|
||||
@@ -152,6 +154,7 @@ onActivated(() => {
|
||||
</template>
|
||||
<template #name="{ row }"><LineClampText :content="row.name" /></template>
|
||||
<template #category="{ row }">{{ categoryLabels[row.category as SupplierCategory] }}</template>
|
||||
<template #truckingScope="{ row }">{{ formatTruckingScope(supplierRow(row).truckingScope) }}</template>
|
||||
<template #carrierCodes="{ row }"><LineClampText :content="supplierRow(row).category === 'BOOKING' ? formatCarrierCodes(supplierRow(row).carrierCodes) : null" /></template>
|
||||
<template #license="{ row }"><el-button data-tone="neutral" class="density-action" size="small" @click="showLicense(supplierRow(row))">查看</el-button></template>
|
||||
<template #status="{ row }"><StatusBadge :status="statusLabels[supplierRow(row).status] ?? '—'" /></template>
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
export type SupplierCategory = 'BOOKING' | 'CUSTOMS' | 'TRUCKING' | 'CERTIFICATE'
|
||||
export type TruckingScope = 'DOMESTIC' | 'OVERSEAS'
|
||||
export const truckingScopeLabels: Record<TruckingScope, string> = { DOMESTIC: '国内拖车', OVERSEAS: '海外车队' }
|
||||
export const truckingScopeOptions = Object.entries(truckingScopeLabels).map(([value, label]) => ({ value, label }))
|
||||
export function formatTruckingScope(scope: TruckingScope | null) { return scope ? truckingScopeLabels[scope] : '—' }
|
||||
export type SupplierStatus = 'ACTIVE' | 'INACTIVE'
|
||||
export type SettlementPeriod = 'MONTHLY_30' | 'MONTHLY_45' | 'MONTHLY_60' | 'MONTHLY_90' | 'PER_TRANSACTION' | 'IMMEDIATE'
|
||||
export type CarrierCode = 'MATSON' | 'SML' | 'ZIM' | 'COSCO' | 'EMC' | 'HEDE' | 'OTHER'
|
||||
@@ -8,6 +12,7 @@ export interface Supplier {
|
||||
tenantId: string
|
||||
name: string
|
||||
category: SupplierCategory
|
||||
truckingScope: TruckingScope | null
|
||||
carrierCodes: CarrierCode[]
|
||||
region: string
|
||||
legalRepresentative: string
|
||||
@@ -42,6 +47,7 @@ export interface SupplierQuery {
|
||||
page?: number
|
||||
size?: number
|
||||
category?: SupplierCategory
|
||||
truckingScope?: TruckingScope
|
||||
region?: string
|
||||
status?: SupplierStatus | ''
|
||||
keyword?: string
|
||||
@@ -51,6 +57,7 @@ export interface SupplierQuery {
|
||||
export interface SaveSupplierRequest {
|
||||
name: string
|
||||
category: SupplierCategory
|
||||
truckingScope: TruckingScope | null
|
||||
carrierCodes?: CarrierCode[]
|
||||
region: string
|
||||
legalRepresentative: string
|
||||
|
||||
Reference in New Issue
Block a user