This commit is contained in:
zlwu committed 2026-06-21 09:19:07 +08:00
1 parent c3be9d1dce
commit 299609706c
328 files changed
+144899 -13873

No files matched your search

+5 -2
View File
@@ -115,8 +115,11 @@ export const advanceApi = {
}
export const reimburseApi = {
generateTitle() {
return bxRequest.get('/reimburses/generate-title')
generateTitle(reimburseDate?: string, excludeApplyId?: BxId) {
const params: Record<string, string> = {}
if (reimburseDate) params.reimburseDate = reimburseDate
if (excludeApplyId) params.excludeApplyId = String(excludeApplyId)
return bxRequest.get('/reimburses/generate-title', { params })
},
list(params: {
page: number
+2
View File
@@ -60,6 +60,8 @@ export interface ContractProductForm {
description?: string
sort?: number
remark?: string
isToxic?: number
isExplosive?: number
priceTiers?: ContractProductPriceTierForm[]
}
+649
View File
@@ -0,0 +1,649 @@
/**
* 运输计划管理 API
*/
import request from '@/utils/http/bx'
// =============================================================================
// 基础数据 API
// =============================================================================
// 承运商
export interface Carrier {
id: string
carrierName: string
contactName?: string
contactPhone?: string
status: string
remark?: string
createTime: string
}
export interface CarrierQuery {
q?: string
status?: string
}
export const carrierApi = {
list: (params?: CarrierQuery) => request.get<Carrier[]>('/transport/carrier', { params }),
get: (id: string) => request.get<Carrier>(`/transport/carrier/${id}`),
create: (data: Partial<Carrier>) => request.post<Carrier>('/transport/carrier', data),
update: (id: string, data: Partial<Carrier>) => request.put<Carrier>(`/transport/carrier/${id}`, data),
delete: (id: string) => request.delete(`/transport/carrier/${id}`)
}
// 证书行(嵌套保存)
export interface CertRow {
certId?: string
certName: string
certNo?: string
expireDate?: string
remindDays?: number
attachmentUrls?: string
}
export interface CertRead extends CertRow {
id: string
ownerType: string
ownerId: string
status: string
createTime?: string
}
// 车辆-人员关联行
export interface VehiclePersonnelRow {
personnelId?: string
personnelName: string
phoneNo?: string
age?: number | null
role: string
isDefault?: number
remark?: string
}
// 车辆
export interface Vehicle {
id: string
vehicleType: string
carrierId?: string
carrierName?: string
licensePlate: string
defaultDriverId?: string
defaultDriverName?: string
personnelSummary?: string
loadCapacity?: number
vehicleStatus: string
remark?: string
createTime: string
}
export interface VehicleDetail extends Vehicle {
personnelList: VehiclePersonnelRow[]
certList: CertRead[]
}
export interface VehiclePayload {
vehicleType: string
carrierId?: string
carrierName?: string
licensePlate: string
loadCapacity?: number | null
vehicleStatus: string
remark?: string
personnelList?: VehiclePersonnelRow[]
certList?: CertRow[]
}
export interface VehicleQuery {
q?: string
vehicleType?: string
carrierId?: string
vehicleStatus?: string
}
export const vehicleApi = {
list: (params?: VehicleQuery) => request.get<Vehicle[]>('/transport/vehicle', { params }),
get: (id: string) => request.get<VehicleDetail>(`/transport/vehicle/${id}`),
create: (data: VehiclePayload) => request.post<VehicleDetail>('/transport/vehicle', data),
update: (id: string, data: Partial<VehiclePayload>) =>
request.put<VehicleDetail>(`/transport/vehicle/${id}`, data),
delete: (id: string) => request.delete(`/transport/vehicle/${id}`)
}
// 人员
export interface Personnel {
id: string
personnelName: string
phoneNo?: string
age?: number
idCardNo?: string
status: string
remark?: string
nearestExpireDate?: string
createTime: string
}
export interface PersonnelDetail extends Personnel {
certList: CertRead[]
}
export interface PersonnelPayload {
personnelName: string
phoneNo?: string
age?: number | null
idCardNo?: string
status: string
remark?: string
certList?: CertRow[]
}
export interface PersonnelQuery {
q?: string
status?: string
}
export const personnelApi = {
list: (params?: PersonnelQuery) => request.get<Personnel[]>('/transport/personnel', { params }),
get: (id: string) => request.get<PersonnelDetail>(`/transport/personnel/${id}`),
create: (data: PersonnelPayload) => request.post<PersonnelDetail>('/transport/personnel', data),
update: (id: string, data: Partial<PersonnelPayload>) =>
request.put<PersonnelDetail>(`/transport/personnel/${id}`, data),
delete: (id: string) => request.delete(`/transport/personnel/${id}`)
}
// 司机(兼容旧 API,映射至 personnel)
export interface Driver {
id: string
driverName: string
phoneNo?: string
idCardNo?: string
drivingLicenseNo?: string
drivingLicenseExpire?: string
vehicleLicenseNo?: string
vehicleLicenseExpire?: string
hazmatCertNo?: string
hazmatCertExpire?: string
remark?: string
createTime: string
}
export interface DriverQuery {
q?: string
}
function personnelToDriver(p: Personnel): Driver {
return {
id: p.id,
driverName: p.personnelName,
phoneNo: p.phoneNo,
idCardNo: p.idCardNo,
remark: p.remark,
createTime: p.createTime
}
}
function driverToPersonnelPayload(data: Partial<Driver>): PersonnelPayload {
return {
personnelName: data.driverName || '',
phoneNo: data.phoneNo,
idCardNo: data.idCardNo,
status: '1',
remark: data.remark
}
}
export const driverApi = {
list: async (params?: DriverQuery) => {
const res = await personnelApi.list({ q: params?.q })
const rows = (res.data ?? res) as Personnel[]
return { ...res, data: rows.map(personnelToDriver) }
},
get: async (id: string) => {
const res = await personnelApi.get(id)
const detail = (res.data ?? res) as PersonnelDetail
return { ...res, data: personnelToDriver(detail) }
},
create: async (data: Partial<Driver>) => {
const res = await personnelApi.create(driverToPersonnelPayload(data))
const detail = (res.data ?? res) as PersonnelDetail
return { ...res, data: personnelToDriver(detail) }
},
update: async (id: string, data: Partial<Driver>) => {
const res = await personnelApi.update(id, driverToPersonnelPayload(data))
const detail = (res.data ?? res) as PersonnelDetail
return { ...res, data: personnelToDriver(detail) }
},
delete: (id: string) => personnelApi.delete(id)
}
// =============================================================================
// 计划管理 API
// =============================================================================
export interface PlanProduct {
id: string
planId: string
productId: string
productNo: string
productName: string
model?: string
unit: string
categoryName?: string
packageSpec?: string
deliveryMethod?: string
quantity?: number
actualQty?: number
taxPrice?: number
taxAmount?: number
taxSubtotal?: number
isExplosive: number
isToxic: number
purchaseCertUrl?: string
transportCertUrl?: string
inboundEstimateQty?: number
inboundQty?: number
inboundPrice?: number
inboundAmount?: number
outboundEstimateQty?: number
outboundQty?: number
outboundPrice?: number
outboundAmount?: number
remark?: string
}
export interface Plan {
id: string
planNo: string
planDate: string
belongsCompany: string
planType: string
followStatus: string
transportStatus: string
archiveStatus: string
completeStatus: string
contractId?: string
contractNo?: string
supplierId?: string
supplierName?: string
destinationId?: string
destinationName?: string
customerId?: string
customerName?: string
contactName?: string
contactPhone?: string
partyA?: string
partyB?: string
contractStartDate?: string
contractEndDate?: string
deliveryMethod?: string
settlementMethod?: string
hasFreight: number
pickupAddress?: string
pickupTime?: string
pickupNotes?: string
destinationAddress?: string
deliveryTime?: string
destinationNotes?: string
vehicleId?: string
licensePlate?: string
driverId?: string
driverName?: string
transportId?: string
transportNo?: string
totalAmount: number
freightAmount: number
notifyMessage?: string
followUserId?: string
followUserName?: string
remark?: string
createTime: string
products?: PlanProduct[]
}
export interface PlanQuery {
q?: string
planNo?: string
planType?: string
followStatus?: string
transportStatus?: string
archiveStatus?: string
customerName?: string
planDateFrom?: string
planDateTo?: string
page?: number
pageSize?: number
}
export interface PlanListResponse {
total: number
list: Plan[]
}
export interface PlanTransportCreateBlock {
vehicleId: string
driverId?: string
carrierId?: string
distanceKm?: number
freightType: string
transportQty?: number
freightPrice?: number
freightAmount?: number
hasInvoice?: number
remark?: string
}
export interface PlanCreateFullPayload {
contractId: string
planDate: string
belongsCompany: string
planType: string
contractNo?: string
supplierId?: string
supplierName?: string
destinationId?: string
destinationName?: string
customerId?: string
customerName?: string
contactName?: string
contactPhone?: string
partyA?: string
partyB?: string
contractStartDate?: string
contractEndDate?: string
deliveryMethod?: string
settlementMethod?: string
hasFreight: number
pickupAddress?: string
pickupTime?: string
pickupNotes?: string
destinationAddress?: string
deliveryTime?: string
destinationNotes?: string
followUserId?: string
followUserName?: string
remark?: string
products: Array<{
productId: string
productNo: string
productName: string
model?: string
unit: string
categoryName?: string
packageSpec?: string
deliveryMethod?: string
quantity?: number
actualQty?: number
taxPrice?: number
taxAmount?: number
taxSubtotal?: number
remark?: string
isExplosive?: number
isToxic?: number
}>
transport?: PlanTransportCreateBlock
}
export type PlanUpdatePayload = Partial<Omit<PlanCreateFullPayload, 'contractId'>>
export const planApi = {
list: (params?: PlanQuery) => request.get<PlanListResponse>('/transport/plan/', { params }),
get: (id: string) => request.get<Plan>(`/transport/plan/${id}`),
countByContract: (contractIds: string[]) =>
request.get<{ counts: Record<string, number> }>('/transport/plan/count-by-contract', {
params: { contractIds: contractIds.join(',') }
}),
create: (data: Partial<Plan>) => request.post<Plan>('/transport/plan/', data),
createFull: (data: PlanCreateFullPayload) => request.post<Plan>('/transport/plan/create-full', data),
update: (id: string, data: PlanUpdatePayload) => request.put<Plan>(`/transport/plan/${id}`, data),
updateProductCerts: (
id: string,
products: Array<{ id: string; purchaseCertUrl?: string; transportCertUrl?: string }>
) => request.patch<Plan>(`/transport/plan/${id}/product-certs`, { products }),
cancel: (id: string) => request.post<Plan>(`/transport/plan/${id}/cancel`),
getArrangeInfo: (id: string) => request.get<PlanArrangeInfo>(`/transport/plan/${id}/arrange-info`),
archive: (id: string) => request.post<Plan>(`/transport/plan/${id}/archive`),
delete: (id: string) => request.delete(`/transport/plan/${id}`),
createFromContract: (data: { contractId: string; planDate: string; followUserId?: string; followUserName?: string }) =>
request.post<Plan>('/transport/plan/create-from-contract', data)
}
// =============================================================================
// 运输管理 API
// =============================================================================
export interface Transport {
id: string
transportNo: string
vehicleId?: string
licensePlate?: string
driverId?: string
driverName?: string
driverPhone?: string
carrierId?: string
carrierName?: string
transportMedium?: string
startPoint?: string
endPoint?: string
distanceKm?: number
unit?: string
transportQty?: number
freightPrice?: number
freightAmount: number
freightType: string
hasInvoice: number
qrCode?: string
qrExpireDate?: string
transportStatus: string
approvalStatus: string
feedbackTime?: string
feedbackQty?: number
feedbackImages?: string
feedbackRemark?: string
remark?: string
createTime: string
}
export interface TransportArrange {
vehicleId: string
driverId: string
carrierId?: string
transportMedium?: string
startPoint?: string
endPoint?: string
distanceKm?: number
unit?: string
freightType: string
freightPrice?: number
freightAmount?: number
hasInvoice?: number
remark?: string
generateDibangPlan?: boolean
}
export interface TransportInventoryLink {
planProductId: string
productName: string
dbPurchasePlanId: string
dbInventoryId: string
batchNo: string
planNo: string
}
export interface PlanArrangeInfo {
driverUrl?: string
licensePlate?: string
inventoryRecords?: TransportInventoryLink[]
}
export interface TransportArrangeResult extends Transport {
driverAccessToken?: string
driverUrl?: string
inventoryRecords?: TransportInventoryLink[]
}
export interface TransportQuery {
q?: string
transportNo?: string
transportStatus?: string
approvalStatus?: string
vehicleId?: string
driverId?: string
page?: number
pageSize?: number
}
export interface TransportListResponse {
total: number
list: Transport[]
}
export const transportApi = {
list: (params?: TransportQuery) => request.get<TransportListResponse>('/transport/order/', { params }),
get: (id: string) => request.get<Transport>(`/transport/order/${id}`),
create: (data: Partial<Transport> & { planIds?: string[] }) =>
request.post<Transport>('/transport/order/', data),
arrange: (planId: string, data: TransportArrange) =>
request.post<TransportArrangeResult>(`/transport/order/arrange/${planId}`, data),
generateQrcode: (id: string, expireDays?: number) =>
request.get<{ transportId: string; transportNo: string; qrCode: string; expireDate?: string }>(
`/transport/order/${id}/qrcode`,
{ params: { expireDays } }
),
submitApproval: (id: string, approverIds: string[]) =>
request.post<Transport>(`/transport/order/${id}/submit-approval`, { approverIds }),
scanFeedback: (data: { transportNo: string; verifyCode?: string; feedbackQty?: number; feedbackImages?: string[]; feedbackRemark?: string }) =>
request.post('/transport/order/scan/feedback', data),
getApprovals: (id: string) => request.get<any[]>(`/transport/order/${id}/approvals`)
}
// =============================================================================
// 运费结算 API
// =============================================================================
export interface FreightSettlement {
id: string
settlementNo: string
totalFreight: number
invoiceAmount?: number
invoiceNo?: string
invoiceDate?: string
settlementStatus: string
remark?: string
createTime: string
transports?: Transport[]
}
export interface FreightSettlementQuery {
q?: string
settlementStatus?: string
page?: number
pageSize?: number
}
export interface FreightSettlementListResponse {
total: number
list: FreightSettlement[]
}
export const freightApi = {
list: (params?: FreightSettlementQuery) =>
request.get<FreightSettlementListResponse>('/transport/freight/', { params }),
get: (id: string) => request.get<FreightSettlement>(`/transport/freight/${id}`),
create: (transportIds: string[]) =>
request.post<FreightSettlement>('/transport/freight/', { transportIds }),
update: (id: string, data: Partial<FreightSettlement>) =>
request.put<FreightSettlement>(`/transport/freight/${id}`, data),
submit: (id: string) => request.post<FreightSettlement>(`/transport/freight/${id}/submit`),
approve: (id: string) => request.post<FreightSettlement>(`/transport/freight/${id}/approve`)
}
// =============================================================================
// 盘存统计 API
// =============================================================================
export interface InventoryRecord {
id: string
productId: string
productNo: string
productName: string
model?: string
unit: string
stockQty: number
stockAmount: number
lowStockWarning?: number
highStockWarning?: number
createTime: string
}
export interface InventoryTransaction {
id: string
productId: string
productName: string
transactionType: string
planId?: string
planNo?: string
qty: number
unitPrice: number
amount: number
stockAfter: number
createTime: string
}
export interface InventoryWarning {
id: string
productId: string
productName: string
warningType: string
currentQty: number
thresholdValue: number
status: string
resolveTime?: string
resolveRemark?: string
createTime: string
}
export interface DocumentReminder {
id: string
certId?: string
ownerType?: string
ownerId?: string
ownerLabel?: string
driverId?: string
driverName?: string
documentType: string
documentNo?: string
expireDate: string
daysRemaining: number
status: string
remark?: string
createTime: string
}
export interface InventoryLedgerQuery {
productName?: string
page?: number
pageSize?: number
}
export interface InventoryLedgerResponse {
total: number
list: InventoryRecord[]
}
export const inventoryApi = {
ledger: (params?: InventoryLedgerQuery) =>
request.get<InventoryLedgerResponse>('/transport/inventory/ledger', { params }),
transactions: (params?: any) =>
request.get<{ total: number; list: InventoryTransaction[] }>('/transport/inventory/transactions', { params }),
summary: (params: { groupBy: string; dateFrom: string; dateTo: string; productId?: string }) =>
request.get<{ list: any[] }>('/transport/inventory/summary', { params }),
warnings: (status?: string) =>
request.get<InventoryWarning[]>('/transport/inventory/warnings', { params: { status } }),
updateWarning: (id: string, data: { status: string; resolveRemark?: string }) =>
request.put<InventoryWarning>(`/transport/inventory/warnings/${id}`, data),
setWarningThreshold: (data: { productId: string; lowStockWarning?: number; highStockWarning?: number }) =>
request.post('/transport/inventory/warning-threshold', data),
documentReminders: (status?: string) =>
request.get<DocumentReminder[]>('/transport/inventory/document-reminders', { params: { status } }),
updateDocumentReminder: (id: string, data: { status: string; remark?: string }) =>
request.put<DocumentReminder>(`/transport/inventory/document-reminders/${id}`, data)
}
+38
View File
@@ -0,0 +1,38 @@
import { publicPlGet, publicPlPost, publicPlUpload } from '@/utils/http/public-pl'
export interface PublicTransportProduct {
productName: string
model?: string
packageSpec?: string
unit?: string
quantity?: number
}
export interface PublicTransportPage {
planNo: string
planDate?: string
planType: string
pickupAddress?: string
destinationAddress?: string
licensePlate?: string
driverName?: string
driverPhone?: string
products: PublicTransportProduct[]
feedbackRemark?: string
feedbackImages: string[]
feedbackTime?: string
planVoided?: boolean
}
export interface PublicUploadResult {
fileUrl: string
fileName?: string
}
export const publicTransportApi = {
getPage: (token: string) => publicPlGet<PublicTransportPage>(`/public/pl/transport/${token}`),
saveFeedback: (token: string, data: { feedbackImages?: string[]; feedbackRemark?: string }) =>
publicPlPost<{ success: boolean }>(`/public/pl/transport/${token}/feedback`, data),
uploadAttachment: (token: string, file: File) =>
publicPlUpload<PublicUploadResult>(`/public/pl/transport/${token}/attachments`, file)
}