import request from '@/utils/request' // 购物车商品项接口 export interface CartItem { id: number sku: string name: string spec_model: string source_table: string stock_quantity: number available_quantity: number barcode: string price: number // 单价 out_quantity: number // 本次出库数量 } // 提交出库单的数据结构 export interface OutboundSubmitData { items: Array<{ sku: string source_table: string stock_id: number barcode: string quantity: number price: number }> outbound_type: string consumer_name: string operator_name: string signature_path: string // 上传后返回的图片路径 remark?: string } export interface ScanResult { id: number sku: string name: string spec_model: string source_table: string // 'stock_buy' | 'stock_product' ... stock_quantity: number available_quantity: number batch_number?: string warehouse_location?: string barcode?: string price?: number // 扫描返回的价格 } /** * 根据条码获取库存物品详情 * * ⚠ 本文件是与 `@/api/outbound` 同名的**历史副本**(同 URL、同返回形状), * 当前无任何调用方 —— 借库扫码页 `views/transaction/borrow.vue` 是从 * `@/api/outbound` 导入的。改动请落到那边,这里同步仅为避免下次改漏。 * * @param barcode 扫描到的条码 * @param requestId 本单 ID(出库审批单 / 借库审批单) * @param bizType 单据类型,决定 requestId 查哪张表(默认 outbound) */ export function getStockByBarcode( barcode: string, requestId?: number | null, bizType: 'outbound' | 'borrow' = 'outbound' ) { return request({ url: '/v1/outbound/scan', method: 'get', params: { barcode, request_id: requestId, biz_type: bizType } }) } /** * 提交出库单 (批量) */ export function submitOutbound(data: OutboundSubmitData) { return request({ url: '/v1/outbound', method: 'post', data }) } /** * 获取出库记录列表 */ export function getOutboundList(params: any) { return request({ url: '/v1/outbound', method: 'get', params }) } /** * 提交出库申请单(申请人 → 审批流) */ export function submitOutboundRequest(data: { items: Array<{ material_type?: string name: string spec_model: string warehouse_location?: string quantity: number }> remark: string }) { return request({ url: '/v1/outbound/request', method: 'post', data }) } /** * 获取出库审批申请单列表 * @param params 支持 status, page, limit */ export function getApprovalRequestList(params: { status?: number | ''; page?: number; limit?: number }) { return request({ url: '/v1/outbound/request', method: 'get', params }) } /** * 审批(通过 / 驳回)出库申请单 * @param id 审批单ID * @param data action: 'approve' | 'reject',reject 时需传 reject_reason */ export function approveRequest(id: number, data: { action: 'approve' | 'reject'; reject_reason?: string }) { return request({ url: `/v1/outbound/request/${id}/approve`, method: 'patch', data }) } // ============================================================================== // 借库审批流 API // ============================================================================== /** * 提交借库申请单(申请人 → 审批流) */ export function submitBorrowRequest(data: { items: Array<{ name: string spec_model: string warehouse_location?: string quantity: number }> remark?: string allowed_approvers?: Array<{ type: string; value: string }> approver_id?: number }) { return request({ url: '/v1/transactions/borrow/request', method: 'post', data }) } // 借库申请预检:判断所选物料是否需审批 export function checkBorrowApproval(data: { items: Array<{ name?: string; spec_model?: string }> }) { return request({ url: '/v1/transactions/borrow/request/check-approval', method: 'post', data }) } /** * 获取借库审批申请单列表 * @param params 支持 status, page, limit */ export function getBorrowApprovalList(params: { status?: number | ''; page?: number; limit?: number }) { return request({ url: '/v1/transactions/borrow/request', method: 'get', params }) } /** * 审批(通过 / 驳回)借库申请单 * @param id 审批单ID * @param data action: 'approve' | 'reject',reject 时需传 reject_reason */ export function approveBorrowRequest(id: number, data: { action: 'approve' | 'reject'; reject_reason?: string }) { return request({ url: `/v1/transactions/borrow/request/${id}/approve`, method: 'patch', data }) } // 手动完结已通过的借库审批单(status 1 → 3) export function closeBorrowRequest(id: number) { return request({ url: `/v1/transactions/borrow/request/${id}/close`, method: 'post' }) } /** * 借库选单专用库存列表(独立权限 op_borrow_apply) */ export function getBorrowStockList(params: { page?: number; pageSize?: number; keyword?: string }) { return request({ url: '/v1/transactions/borrow/stock-list', method: 'get', params }) } /** * 执行借库扣减(审批通过后调用) * * ★ borrower_id 为**必填**:借用人身份从「姓名」升级为「ID 锚点」后, * 后端以 borrower_id 反查 sys_user 生成姓名快照;缺失会被直接拒绝。 * borrower_name 仅作兼容保留,后端不采信。 * * @param data approval_id + 扫码选中的物品 + 借用人ID + 签名 */ export function dispatchBorrow(data: { approval_id: number items: Array borrower_id: number borrower_name?: string signature_path: string remark?: string expected_return_time?: string | null }) { return request({ url: '/v1/transactions/borrow/dispatch', method: 'post', data }) } /** * 借库责任链人员名单(借用人 / 转交接收人 / 实际归还人共用) * @returns [{ id, name }] */ export function getBorrowUsers() { return request({ url: '/v1/transactions/borrow/users', method: 'get' }) } /** * 借库转交(一期:仅支持整单全量转交) * * ★ transfer_qty 必须严格等于待还量,部分转交会被后端拒绝 —— * 单行模型无法同时追踪两个持有人。 * ★ 转交是纯持有权变更,不触碰任何库存字段。 * * @param borrowId trans_borrow.id * @param data transfer_qty + to_user_id + remark */ export function transferBorrow(borrowId: number, data: { transfer_qty: number to_user_id: number to_user_name?: string remark?: string }) { return request({ url: `/v1/transactions/borrow/${borrowId}/transfer`, method: 'post', data }) } /** * 借出单的流转历史(**单品**维度):转交链 + 逐次归还明细 * @returns { record, transfers[], returns[] } */ export function getBorrowHistory(borrowId: number) { return request({ url: `/v1/transactions/borrow/${borrowId}/history`, method: 'get' }) } /** * 确认接收转交(双向握手第二步)—— 责任正式转移到接收人名下。 * * ★ 仅该转交的 to_user_id 本人可调用(后端强校验,非库管权限)。 * ★ 副作用:该单**全部未归还明细**的当前持有人一并变更。 */ export function acceptBorrowTransfer(transferId: number) { return request({ url: `/v1/transactions/borrow/transfer/${transferId}/accept`, method: 'post' }) } /** * 拒绝转交 —— 主表不动,责任仍在原持有人。权限同上。 * @param reason 可选拒绝原因,写入转交流水备注 */ export function rejectBorrowTransfer(transferId: number, reason?: string) { return request({ url: `/v1/transactions/borrow/transfer/${transferId}/reject`, method: 'post', data: { reason } }) } /** * 全局待办强提醒的轮询数据源(初始化 + 轮询)。 * * ★ 一次请求返回两类信息,避免前端多打一个请求: * count —— 待**我接收**的转交数量 * rejects —— **我发起、被对方拒绝、尚未告知我**的转交 * (被拒时物品责任仍在我手上,不告知就会误以为已交接出去) * * @returns { count, rejects: [{ id, borrow_no, sku, material_name, to_user_name, remark, ... }] } */ export function getPendingTransferCount() { return request({ url: '/v1/transactions/borrow/transfer/pending-count', method: 'get' }) } /** * 确认已知悉「转交被拒绝」—— 写 reject_seen_at,之后不再提醒。 * @param ids 留空表示该用户全部待告知的拒绝 */ export function ackTransferRejects(ids?: number[]) { return request({ url: '/v1/transactions/borrow/transfer/reject-ack', method: 'post', data: { ids } }) } /** * 整单流转时间线(**borrow_no** 维度):借出 → 转交(可多次) → 归还 → 报废 * * ★ 与 getBorrowHistory 的分工:列表页是 borrow_no 主子表结构(单张单最多 * 21 条明细),逐条明细调用单品接口会产生 21 个请求,且各条时间线无法全局 * 排序。本接口一次返回合并后的事件流,按时间**倒序**。 * * @returns { borrow_no, events[], records[] } */ export function getBorrowSlipHistory(borrowNo: string) { return request({ url: `/v1/transactions/borrow/slip/${encodeURIComponent(borrowNo)}/history`, method: 'get' }) } /** * 提交「借出未归还」的**报废申请**(需审批人审批,通过后由库管执行报废)。 * * ★ 已由「直接报废」改为「申请」: * 原 POST /v1/transactions/borrow/scrap 直接写 trans_scrap 并扣总库存, * 绕过审批、构成职责分离漏洞,已删除。现统一走 申请 → 审批 → 执行。 * * ★ 副作用提醒:申请**不立即改变**借用记录状态,提交后该笔仍显示为未归还。 * 前端必须提示用户「待审批并执行后才会标记为已报废」。 * * @param data record_ids: trans_borrow.id 列表(按整条待还量报废) * reason?: 写入申请单备注 * approver_id: 必填,指定审批人 */ export function submitBorrowScrapRequest(data: { record_ids: number[] reason?: string approver_id: number }) { return request({ url: '/v1/transactions/borrow/scrap-request', method: 'post', data }) }