import request from '@/utils/request' // 1. 扫码查询库存 // // ★ requestId 必须传:在管不良品的 SKU 复制自原库存行,同一码可能同时 // 命中 stock_buy#M 与 trans_defective_goods#N —— 这是两个不同实物, // 条码本身无法区分。带上当前申请单 id 后,后端会优先返回该单批准明细 // 指定的那一条,避免「清单里明明有、扫码却说不在批准明细中」。 export function scanBarcode(barcode: string, requestId?: number) { return request({ url: '/v1/scrap/scan', method: 'get', params: { barcode, request_id: requestId } }) } // [已移除] 直接报废 createScrap —— 对应后端 POST /api/v1/scrap,该接口绕过 // 审批流直接写 trans_scrap 并扣库存,与系统自陈的「报废一律需审批」规则冲突, // 构成职责分离漏洞(同一库管可自行宣告实物销毁而无人复核),已整体删除。 // 所有报废改走:submitScrapRequest → approveScrapRequest → executeScrapByRequest。 // 该函数此前已是死代码(全仓无调用方),删除无行为影响。 // 3. 报废记录列表查询 export function getScrapRecords(params: any) { return request({ url: '/v1/scrap/records', method: 'get', params }) } // 4. 报废记录导出 Excel // // ★ 与列表页**同一套筛选参数**,但后端导出的是**全部匹配结果**而不是当前页 —— // 用户点「导出」要的就是全量,只导当前页会让他以为数据被截断了。 // ★ responseType: 'blob' 不能省,否则 axios 会把二进制当文本解析,文件打不开。 // ★ 损失金额由后端按 scrap_list:loss_amount 权限决定可不可见(与列表页同口径), // 前端不做二次处理 —— 否则导出会变成绕过字段级权限的后门。 export function exportScrapRecords(params: any) { return request({ url: '/v1/scrap/records/export', method: 'get', params, responseType: 'blob' as any, headers: { 'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' } }) } // 3.1 报废申请专用库存列表(独立于出库选单权限,Fail-Closed 剥离价格) export function getScrapStockList(params: { page?: number; pageSize?: number; keyword?: string }) { return request({ url: '/v1/scrap/stock-list', method: 'get', params }) } // ========================================== // 报废申请/审批/执行(新流程,镜像出/借库) // ========================================== // 4. 提交报废申请 export function submitScrapRequest(data: { items: Array<{ source_table: string stock_id: number scrap_qty: number name?: string spec_model?: string sku?: string location?: string batch_number?: string }> remark?: string approver_id?: number | null allowed_approvers?: Array<{ type: string; value: any }> }) { return request({ url: '/v1/scrap/request', method: 'post', data }) } // 5. 提交前预检:所选物料是否需要审批 export function checkScrapApproval(data: { items: Array<{ name?: string; spec_model?: string; base_id?: number }> }) { return request({ url: '/v1/scrap/request/check-approval', method: 'post', data }) } // 6. 报废申请列表(scope: mine | pending | executable | all) export function getScrapApprovals(params: { scope?: 'mine' | 'pending' | 'executable' | 'all' status?: number | '' page?: number limit?: number }) { return request({ url: '/v1/scrap/request', method: 'get', params }) } // 7. 报废申请详情 export function getScrapApprovalDetail(id: number) { return request({ url: `/v1/scrap/request/${id}`, method: 'get' }) } // 8. 审批(通过/驳回) export function approveScrapRequest(id: number, data: { action: 'approve' | 'reject'; reject_reason?: string }) { return request({ url: `/v1/scrap/request/${id}/approve`, method: 'patch', data }) } // 9. 按单报废执行(提交实扫明细,扣减库存) // items 必须是该申请单批准明细的子集,且累计数量不得超过批准数量 export function executeScrapByRequest(id: number, items: Array<{ source_table: string stock_id: number quantity: number sku?: string name?: string }>) { return request({ url: `/v1/scrap/request/${id}/execute`, method: 'post', data: { items } }) } // 10. 撤回已通过但尚未执行的报废申请(作废该单;若已接入预占则一并释放库存) export function withdrawScrapRequest(id: number) { return request({ url: `/v1/scrap/request/${id}/withdraw`, method: 'post' }) }