diff --git a/pages/upload/upload.vue b/pages/upload/upload.vue index f6a03c6..326c470 100644 --- a/pages/upload/upload.vue +++ b/pages/upload/upload.vue @@ -731,9 +731,12 @@ - + 确认上传 + + 提交入库({{ pendingCount }}) + @@ -1017,7 +1020,11 @@ export default { scanPopupWhCode: '', scanPopupLocCode: '', scanPopupRaw: '', - + + // 待入库商品列表(提交入库按钮使用) + pendingProductList: [], + pendingCount: 0, + // 登录 isLoggedIn: false, shopName: '', @@ -2037,6 +2044,12 @@ export default { async submitUpload() { if (this.isSubmitting) return + // 待入库商品已达200上限,不能继续录入 + if (this.pendingCount >= 200) { + uni.showToast({ title: '本波次已满200件,请先提交入库', icon: 'none' }) + return + } + const warehouseData = this.currentTab === 'isbn' ? this.isbnWarehouseData : this.noIsbnWarehouseData if (!warehouseData) { uni.showToast({ title: '请选择货区', icon: 'none' }) @@ -2201,7 +2214,18 @@ export default { var costPrice = String(Math.round(parseFloat(this.referenceShippingFee || '0') * 100)) await this.callUpdatePriceApi(productId, salePrice, costPrice) if (warehouseData && productId) { - await this.callWaveApi(warehouseData, productId) + // 添加到待入库列表 + var entry = { + productId: productId, + price: price, + stock: stock, + warehouseData: warehouseData + } + this.pendingProductList.push(entry) + this.pendingCount = this.pendingProductList.length + if (this.pendingCount >= 200) { + uni.showToast({ title: '本波次已满200件,请先提交入库', icon: 'none', duration: 2000 }) + } } else { console.warn('【syncBook】缺少warehouseData或productId,跳过波次') } @@ -2353,7 +2377,18 @@ export default { var costPrice = String(Math.round(parseFloat(this.noIsbnReferenceShippingFee || '0') * 100)) await this.callUpdatePriceApi(productId, salePrice, costPrice) if (this.noIsbnWarehouseData && productId) { - await this.callWaveApi(this.noIsbnWarehouseData, productId) + // 添加到待入库列表 + var entry = { + productId: productId, + price: salePrice, + stock: this.noIsbnStock ?? '1', + warehouseData: this.noIsbnWarehouseData + } + this.pendingProductList.push(entry) + this.pendingCount = this.pendingProductList.length + if (this.pendingCount >= 200) { + uni.showToast({ title: '本波次已满200件,请先提交入库', icon: 'none', duration: 2000 }) + } } else { console.warn('【syncBook】缺少warehouseData或productId,跳过波次') } @@ -2507,6 +2542,121 @@ export default { } }, + // 提交入库:批量创建波次 → 释放 → 绑定 → 入库 + async submitReceive() { + var list = this.pendingProductList + if (list.length === 0) { + uni.showToast({ title: '没有待入库的商品', icon: 'none' }) + return + } + + // 用第一个商品的仓库数据(假设同批次仓库一致) + var warehouseData = list[0].warehouseData + var timestamp = String(Math.floor(Date.now() / 1000)) + const token = uni.getStorageSync('token') || '' + + // 查询小车列表 + var carInfo = await this.callCarListApi(timestamp) + if (!carInfo) return + + uni.showLoading({ title: '波次处理中...', mask: true }) + + // 构建多个商品参数 + var items = [] + for (var i = 0; i < list.length; i++) { + var item = list[i] + items.push({ + product_id: String(item.productId), + quantity: String(item.stock), + unit_price: String(item.price) + }) + } + var params = { + app_key: 'psi', + client_id: 'psi', + warehouse_id: String(warehouseData.warehouseId || ''), + direction: '1', + car_id: String(carInfo.car_id), + car_code: String(carInfo.car_code), + timestamp: timestamp, + sign_method: 'md5' + } + // 动态添加 items + for (var j = 0; j < items.length; j++) { + params['items[' + j + '][product_id]'] = items[j].product_id + params['items[' + j + '][quantity]'] = items[j].quantity + params['items[' + j + '][unit_price]'] = items[j].unit_price + } + + var sign = calculateSign(params) + params.sign = sign + + try { + const waveRes = await new Promise(function (resolve, reject) { + uni.request({ + url: 'https://psi.api.buzhiyushu.cn/api/purchase-order/create-with-wave', + method: 'POST', + header: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Authorization': 'Bearer ' + token + }, + data: params, + success: function (r) { resolve(r) }, + fail: function (e) { reject(e) } + }) + }) + + if (waveRes.statusCode !== 200 || !waveRes.data) { + uni.hideLoading() + uni.showToast({ title: '创建波次失败 HTTP ' + waveRes.statusCode, icon: 'none', duration: 3000 }) + return + } + var waveResp = waveRes.data + if (typeof waveResp === 'string') { + try { waveResp = JSON.parse(waveResp) } catch (e) { waveResp = {} } + } + if (!(waveResp.code === 200 && waveResp.data && waveResp.data.wave_id && waveResp.data.order_id)) { + uni.hideLoading() + uni.showToast({ title: '创建波次: ' + (waveResp.msg || '返回数据异常'), icon: 'none', duration: 3000 }) + return + } + + var waveId = waveResp.data.wave_id + var orderId = waveResp.data.order_id + + // 释放波次(传第一个商品信息获取 wave_no) + var releaseWaveNo = await this.callWaveReleaseApi(timestamp, waveId, orderId, carInfo, list[0].productId, list[0].stock, list[0].price) + if (!releaseWaveNo) { + uni.hideLoading() + return + } + + // 绑定波次 + var bindResult = await this.callBindWaveApi(timestamp, releaseWaveNo) + if (!bindResult) { + uni.hideLoading() + return + } + + // 提交入库(批量逐条提交) + uni.showLoading({ title: '提交入库中...', mask: true }) + for (var k = 0; k < list.length; k++) { + var p = list[k] + await this.callReceiveSubmitApi(timestamp, bindResult, p.productId, p.stock, p.warehouseData) + } + + uni.hideLoading() + uni.showToast({ title: '入库完成,共 ' + list.length + ' 件', icon: 'success' }) + + // 清空待入库列表 + this.pendingProductList = [] + this.pendingCount = 0 + } catch (e) { + uni.hideLoading() + uni.showToast({ title: '提交入库失败: ' + (e.message || ''), icon: 'none', duration: 3000 }) + } + }, + // 调用波次接口(syncBook 成功后调用) async callWaveApi(warehouseData, productId) { var timestamp = String(Math.floor(Date.now() / 1000)) @@ -4197,9 +4347,13 @@ picker { bottom: 0; left: 0; right: 0; + flex-direction: row; + align-items: center; + justify-content: space-between; } .submit-btn { + flex: 1; background-color: #409eff; border-radius: 10rpx; box-shadow: 0 4rpx 12rpx rgba(64,158,255,0.2); @@ -4207,6 +4361,24 @@ picker { display: flex; align-items: center; justify-content: center; + margin-right: 16rpx; +} + +.receive-btn { + flex: 1; + background-color: #67c23a; + border-radius: 10rpx; + box-shadow: 0 4rpx 12rpx rgba(103,194,58,0.2); + height: 88rpx; + display: flex; + align-items: center; + justify-content: center; +} + +.receive-text { + color: #ffffff; + font-size: 30rpx; + font-weight: 600; } /* ========== 折叠详情 ========== */