Files
pda-cli/src/pages/saleship/salepickscandetail.vue
T
xuan 36c0f9a3a0 feat(scan): 添加手机扫码功能支持
- 在 FabricOutScanBar 组件中添加手机扫码图标和事件处理
- 更新工作台页面的扫码逻辑以支持手机扫码回退
- 在销售拣货详情页添加手机扫码按钮和处理方法
- 重构扫码设置页面以支持扫码方式选择
- 添加手机扫码配置和判断逻辑到扫码配置模块
- 扩展扫码混入模块以支持手机扫码模式和设备检测
- 在多个业务页面中集成手机扫码功能和界面元素
- 更新扫码配置存储和读取逻辑以兼容新配置结构
2026-06-23 17:08:17 +08:00

560 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="wrap">
<u-form ref="uForm">
<u-form-item>
<text class="title" style="width: 200px">单号:{{ BillNo }}</text>
<text class="title" style="width: 200px">日期:{{ BillDate }}</text>
</u-form-item>
<u-form-item>
<text class="title" style="width: 200px">客户名称:{{ CustomerName }}</text>
<text class="title" style="width: 200px">销 售 员:{{ SaleUserName }}</text>
</u-form-item>
<u-form-item>
<text class="title" style="width: 200px">仓库名称:{{ StoreName }}{{ ToStoreName }}</text>
</u-form-item>
<u-form-item>
<text class="title" style="width: 200px">备注内容:{{ BillRemark }}</text>
</u-form-item>
<u-form-item label-width="130" label="条码资料:">
<input type="text" v-model="QRBarCode" maxlength="-1" style="width: 170px" @confirm="SalePickBillDetailScan" />
<u-icon
v-if="usePhoneScanFallback"
name="scan"
size="44"
color="#2979ff"
style="margin-left: 8px;"
@click="handlePhoneScan"
/>
<checkbox-group @change="handleAllCrockNoChange">
<checkbox :checked="AllCrockNoScanStatus">整缸</checkbox>
</checkbox-group>
<checkbox-group @change="handleBarCodeDelChange">
<checkbox :checked="BarCodeDelStatus">删除</checkbox>
</checkbox-group>
</u-form-item>
</u-form>
<u-form ref="uForm">
<u-form-item>
<text class="title" style="width: 400px">成品名称:{{ FabricGoodsNo }}{{ FabricGoodsName }}</text>
</u-form-item>
<u-form-item>
<text class="title" style="width: 400px">色号颜色:{{ GoodsCodeNo }}{{ GoodsCodeName }}</text>
</u-form-item>
<u-form-item>
<text class="title" style="width: 200px">成品缸号:{{ CrockNo }}</text>
<text class="title" style="width: 200px">成品卷号:{{ GoodsBillNo }}</text>
</u-form-item>
<u-form-item>
<text class="title">{{ BillDataMessage }}</text>
</u-form-item>
<u-form-item>
<text class="title" style="width: 130px">配布条数:{{ BillSumRoll }}</text>
<text class="title" style="width: 130px">数量:{{ BillSumQty }}</text>
<text class="title" style="width: 120px">米数:{{ BillSumMQty }}</text>
</u-form-item>
<u-form-item>
<text class="title" style="width: 130px">已配条数:{{ BillScanRoll }}</text>
<text class="title" style="width: 130px">数量:{{ BillScanQty }}</text>
<text class="title" style="width: 120px">米数:{{ BillScanMQty }}</text>
</u-form-item>
<view class="submitView">
<u-button type="primary" class="submitBtn" :ripple="true" :loading="submitLoading" ripple-bg-color="#909399"
@click="submitBtnFun">
{{ pageType ? "保存" : "提交" }}
</u-button>
</view>
</u-form>
<view class="u-demo-area">
<u-toast ref="uToast"></u-toast>
<wyb-table ref="table" :headers="headersMaster" :contents="GoodsDetailList" />
</view>
</view>
</template>
<script>
import util, {
parFabricGoodsBarCode2D,
parYarnGoodsBarCode2D,
playSuccessAudio,
playErrorAudio,
} from "../../common/util";
import wybTable from "@/components/wyb-table/wyb-table.vue";
import scanMixin from "@/common/scanMixin.js";
let that = "";
export default {
mixins: [scanMixin],
data() {
return {
SaleBillNo: "", // 单号
BillMasterID: 0, // 订单ID
borderColor: "#e4e7ed",
align: "center",
index: 0,
pageType: "",
submitLoading: false,
actionSheetShow: false,
QRBarCode: "",
BillNo: "",
BillDate: "",
BillTypeID: 0,
BillRemark: "",
CustomerName: "",
StoreNameID: 0,
StoreName: "",
ToStoreName: "",
SaleUserName: "",
BillTypeName: "",
FabricGoodsNo: "",
FabricGoodsName: "",
GoodsCodeNo: "",
GoodsCodeName: "",
CrockNo: "",
GoodsBillNo: "",
BillSumRoll: 0,
BillSumQty: 0,
BillSumMQty: 0,
BillScanRoll: 0,
BillScanQty: 0,
BillScanMQty: 0,
AllCrockNoScanStatus: false,
BarCodeDelStatus: false,
GoodsDetailList: [],
BillDataMessage: "",
headersMaster: [
{
label: "成品编号",
key: "product_code",
},
{
label: "色号",
key: "product_color_code",
},
{
label: "颜色",
key: "product_color_name",
},
{
label: "缸号",
key: "dye_factory_dyelot_number",
},
{
label: "配布条数",
key: "push_roll",
},
{
label: "配布数量",
key: "push_weight",
},
{
label: "配布长度",
key: "push_length",
},
{
label: "已配条数",
key: "arrange_roll",
},
{
label: "已配数量",
key: "arrange_weight",
},
{
label: "成品等级",
key: "product_level_name",
},
{
label: "成品备注",
key: "product_remark",
},
],
scanningInput: "", // 用于累积扫码输入
lastKeyTime: 0, // 用于判断扫码速度
// scanReceiver 和 isPageActive 由 scanMixin 提供
};
},
onLoad(e) {
that = this;
if (e.billid) {
that.BillMasterID = e.billid;
}
if (e.order_no) {
that.SaleBillNo = e.order_no;
}
this.SalePickDetail();
// #ifdef APP-PLUS
this.isPageActive = true;
// this.registerScanBroadcast();
// #endif
},
onUnload() {
this.isPageActive = false;
this.unregisterScanBroadcast();
},
onHide() {
this.isPageActive = false;
this.unregisterScanBroadcast();
},
onShow() {
this.isPageActive = true;
this.registerScanBroadcast((scanResult) => {
console.log("配布单详情-扫码结果:", scanResult);
this.QRBarCode = scanResult;
this.$nextTick(() => {
this.handleScans();
});
});
},
methods: {
handlePhoneScan() {
this.openPhoneScan();
},
playSuccess() {
util.playSuccessAudio();
},
playError() {
util.playErrorAudio();
},
handleAllCrockNoChange() {
if (this.AllCrockNoScanStatus) {
this.AllCrockNoScanStatus = false;
} else {
this.AllCrockNoScanStatus = true;
this.BarCodeDelStatus = false;
}
},
handleBarCodeDelChange() {
if (this.BarCodeDelStatus) {
this.BarCodeDelStatus = false;
} else {
this.BarCodeDelStatus = true;
this.AllCrockNoScanStatus = false;
}
},
SalePickDetail: function () {
// 获取成品配布单详情
this.$u.api.getFpmArrangeOrder({
id: this.BillMasterID,
order_no: this.SaleBillNo
}).then(res => {
this.triggered = false;
var aResultData = res;
this.BillMasterID = aResultData.id; // 重写订单ID
this.BillNo = aResultData.order_no; // 重写单号
this.BillDate = this.$u.timeFormat(
aResultData.arrange_time,
"yyyy-mm-dd"
);
this.CustomerName = aResultData.biz_unit_name;
this.StoreNameID = aResultData.warehouse_id;
this.StoreName = aResultData.warehouse_name;
this.SaleUserName = aResultData.sale_user_name;
this.BillTypeName = aResultData.out_order_type_name;
this.BillRemark = aResultData.internal_remark;
this.BillSumRoll = aResultData.push_roll / 100 + "匹";
this.BillSumQty = aResultData.push_weight / 10000 + "Kg";
this.BillSumMQty = aResultData.push_length / 10000 + "米";
this.BillScanRoll = aResultData.total_roll / 100 + "匹";
this.BillScanQty = aResultData.total_weight / 10000 + "Kg";
this.BillScanMQty = aResultData.total_length / 10000 + "米";
let aResultDataList = res.item_data;
for (var i = 0; i < aResultDataList.length; i++) {
aResultDataList[i].push_roll = aResultDataList[i].push_roll / 100;
aResultDataList[i].push_weight = aResultDataList[i].push_weight / 10000;
aResultDataList[i].push_length = aResultDataList[i].push_length / 10000;
aResultDataList[i].arrange_roll = aResultDataList[i].arrange_roll / 100;
aResultDataList[i].arrange_weight = aResultDataList[i].arrange_weight / 10000;
}
this.GoodsDetailList = aResultDataList;
}).catch(error => {
this.triggered = false;
this.showError(error.msg);
});
},
// 添加通用错误提示方法
showError(message) {
this.playError();
uni.showModal({
title: '提示',
content: message,
showCancel: false
});
},
// 添加成功提示方法
showSuccess(message) {
this.playSuccess();
uni.showToast({
title: message,
icon: 'success'
});
},
handleScans() {
// 删除模式判断
let aBarCodeDelStatus = 1; // 1=正常扫码,3=删除模式
if (this.BarCodeDelStatus) {
aBarCodeDelStatus = 3;
}
// 整缸扫描判断
let aAllCrockNoScanStatus = 2; // 0=普通扫描,1=整缸扫描
if (this.AllCrockNoScanStatus) {
aAllCrockNoScanStatus = "1";
}
// 数据清理:去除空格、换行符等
let cleanCode = this.QRBarCode.replace(/\s+/g, '').replace(/[\r\n]/g, '');
console.log("this.QRBarCode ---->>" + cleanCode);
// 初始化条码和二维码变量
let aQRBarCode = "";
let aBarCode = "";
if (cleanCode.startsWith("66^") || cleanCode.startsWith("99^") || /[\u4E00-\u9FA5]/.test(cleanCode)) {
aQRBarCode = cleanCode;
} else {
aBarCode = cleanCode;
}
if (aQRBarCode == "" && aBarCode == "") {
this.QRBarCode = "";
this.showError('请扫描二维码或者条码');
return;
}
console.log('请求参数', aBarCodeDelStatus);
console.log('请求参数', aBarCode);
console.log('请求参数', aQRBarCode);
console.log('请求参数', this.BillMasterID);
console.log('请求参数 SaleBillNo', this.SaleBillNo);
console.log('请求参数 token', uni.getStorageSync("userToken").Token);
// 发送请求
util.request({
url: "/product/fpmArrangeOrder/updateFpmArrangeOrder",
method: "PUT",
header: {
Platform: 2,
Authorization: uni.getStorageSync("userToken").Token,
},
data: {
arrange_type: aBarCodeDelStatus, // 1=正常扫码,3=删除模式
bar_code: aBarCode, // 条码(如果是条形码就使用这个)
qr_code: aQRBarCode, // 二维码(如果是二维码就使用这个)
id: parseInt(this.BillMasterID), // 订单ID
// order_no: this.SaleBillNo, // 单号
},
success: (res) => {
console.log('API响应:', res);
if (res.data.code == 0 && res.data.msg == "success") {
var aResultData = res.data.data;
this.playSuccess();
this.FabricGoodsNo = aResultData.product_code;
this.FabricGoodsName = aResultData.product_name;
this.GoodsCodeNo = aResultData.product_color_code;
this.GoodsCodeName = aResultData.product_color_name;
this.CrockNo = aResultData.dyelot_number;
this.GoodsBillNo = aResultData.volume_number;
this.QRBarCode = "";
if (aBarCodeDelStatus == 1) {
this.showSuccess("扫描成功!");
} else {
this.showSuccess("删除成功!");
}
this.SalePickDetail();
} else {
this.showError("扫描出错," + res.data.msg);
this.QRBarCode = "";
}
},
fail: (error) => {
console.error('API请求失败:', error);
this.QRBarCode = "";
this.showError("连接服务器出错,请检查后台服务是否启动!");
},
});
},
SalePickBillDetailScan() {
// 聚焦输入框触发的方法
this.handleScans();
},
// 提交按钮方法
submitBtnFun: function () {
if (this.BillMasterID == 0) {
this.playError();
this.BillDataMessage = "单号为空,不能提交";
return;
}
// 获取配布总匹数和已配匹数进行比较
const totalRoll = parseFloat(this.BillSumRoll.replace('匹', '')); // 配布总匹数
const arrangedRoll = parseFloat(this.BillScanRoll.replace('匹', '')); // 已配匹数
if (arrangedRoll < totalRoll) {
// 如果已配匹数小于总匹数,显示确认弹窗
uni.showModal({
title: '提示',
content: '配布匹数不足,是否确定提交',
cancelText: '取消',
confirmText: '确定',
success: (res) => {
if (res.confirm) {
// 用户点击确定,继续提交
this.submitOrder();
}
}
});
} else {
// 匹数足够,直接提交
this.submitOrder();
}
},
// 新增提交订单的方法
submitOrder: function () {
this.submitLoading = true
this.$u.api.outFpmArrangeOrder({
id: parseInt(this.BillMasterID)
}).then(res => {
this.submitLoading = false
console.log('outFpmArrangeOrder res', res)
if (res) {
this.BillDataMessage = "成功生成出仓单!";
this.playSuccess();
} else {
this.playError();
this.BillDataMessage = "提交生成出仓单出错!" + res.msg;
return;
}
}).catch(error => {
this.submitLoading = false
this.playError();
this.BillDataMessage = "连接服务器出错,请检查后台服务是否启动!";
});
},
},
};
</script>
<style>
page {
background-color: #f8f8f8;
padding-bottom: 260rpx;
}
.u-radio {
width: 200rpx !important;
}
.submitView {
width: 100%;
padding: 16rpx 0 26rpx;
background-color: #ffffff;
position: fixed;
bottom: 0;
left: 0;
border-top: 1rpx solid #f1f1f1;
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
}
.submitBtn {
width: 666rpx;
}
.productBox {
background-color: #ffffff;
margin-top: 32rpx;
padding: 26rpx 0;
}
.tjcpName {
width: 686rpx;
height: 40rpx;
font-size: 16px;
font-weight: bold;
border-left: 6rpx solid #007aff;
padding-left: 12rpx;
margin-left: 26rpx;
margin-top: 26rpx;
}
.cpInput {
width: 150rpx !important;
margin-right: 12rpx;
}
.cpInput>input {
box-sizing: border-box;
border: 1rpx solid #dddddd;
width: 100%;
height: 60rpx;
border-radius: 10rpx;
padding: 0 10rpx;
}
.cpInput1 {
width: 200rpx !important;
margin-right: 12rpx;
}
.cpInput1>input {
box-sizing: border-box;
border: 1rpx solid #dddddd;
width: 100%;
height: 60rpx;
border-radius: 10rpx;
padding: 0 10rpx;
}
.clearIcon {
position: absolute;
right: 6rpx;
top: 6rpx;
}
.greenPrice {
font-size: 16px;
color: #19be6b !important;
font-weight: bold;
}
.disFlex {
display: flex;
align-items: center;
margin-bottom: 8rpx;
}
.inputName {
color: #adadad;
font-size: 16px;
}
.addHKQS {
display: flex;
align-items: center;
padding: 16rpx 26rpx;
font-size: 15px;
font-weight: bold;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
</style>