/** * 运输计划管理 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('/transport/carrier', { params }), get: (id: string) => request.get(`/transport/carrier/${id}`), create: (data: Partial) => request.post('/transport/carrier', data), update: (id: string, data: Partial) => request.put(`/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('/transport/vehicle', { params }), get: (id: string) => request.get(`/transport/vehicle/${id}`), create: (data: VehiclePayload) => request.post('/transport/vehicle', data), update: (id: string, data: Partial) => request.put(`/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('/transport/personnel', { params }), get: (id: string) => request.get(`/transport/personnel/${id}`), create: (data: PersonnelPayload) => request.post('/transport/personnel', data), update: (id: string, data: Partial) => request.put(`/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): 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) => { 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) => { 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 taxRate?: 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> export const planApi = { list: (params?: PlanQuery) => request.get('/transport/plan/', { params }), get: (id: string) => request.get(`/transport/plan/${id}`), countByContract: (contractIds: string[]) => request.get<{ counts: Record }>('/transport/plan/count-by-contract', { params: { contractIds: contractIds.join(',') } }), create: (data: Partial) => request.post('/transport/plan/', data), createFull: (data: PlanCreateFullPayload) => request.post('/transport/plan/create-full', data), update: (id: string, data: PlanUpdatePayload) => request.put(`/transport/plan/${id}`, data), updateProductCerts: ( id: string, products: Array<{ id: string; purchaseCertUrl?: string; transportCertUrl?: string }> ) => request.patch(`/transport/plan/${id}/product-certs`, { products }), cancel: (id: string) => request.post(`/transport/plan/${id}/cancel`), getArrangeInfo: (id: string) => request.get(`/transport/plan/${id}/arrange-info`), archive: (id: string) => request.post(`/transport/plan/${id}/archive`), delete: (id: string) => request.delete(`/transport/plan/${id}`), createFromContract: (data: { contractId: string; planDate: string; followUserId?: string; followUserName?: string }) => request.post('/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 pickupAddress?: string pickupTime?: string pickupNotes?: string destinationAddress?: string deliveryTime?: string destinationNotes?: 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 TransportSiteLink { planProductId: string productName: string siteLinkId: string planNo: string businessType: string siteAccessToken?: string siteUrl?: string siteFeedbackRemark?: string siteFeedbackImages?: string[] siteFeedbackTime?: string } export interface PlanArrangeInfo { driverUrl?: string licensePlate?: string siteRecords?: TransportSiteLink[] inventoryRecords?: TransportInventoryLink[] } export interface TransportArrangeResult extends Transport { driverAccessToken?: string driverUrl?: string siteRecords?: TransportSiteLink[] 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('/transport/order/', { params }), get: (id: string) => request.get(`/transport/order/${id}`), create: (data: Partial & { planIds?: string[] }) => request.post('/transport/order/', data), arrange: (planId: string, data: TransportArrange) => request.post(`/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/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(`/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('/transport/freight/', { params }), get: (id: string) => request.get(`/transport/freight/${id}`), create: (transportIds: string[]) => request.post('/transport/freight/', { transportIds }), update: (id: string, data: Partial) => request.put(`/transport/freight/${id}`, data), submit: (id: string) => request.post(`/transport/freight/${id}/submit`), approve: (id: string) => request.post(`/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('/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('/transport/inventory/warnings', { params: { status } }), updateWarning: (id: string, data: { status: string; resolveRemark?: string }) => request.put(`/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('/transport/inventory/document-reminders', { params: { status } }), updateDocumentReminder: (id: string, data: { status: string; remark?: string }) => request.put(`/transport/inventory/document-reminders/${id}`, data) }