Files
klp-oa/klp-ui/src/views/wms/print/index.vue
砂糖 3c694130c2 feat:
修改二维码生成逻辑,改为一次性二维码,存储更多信息
2025-08-22 11:30:23 +08:00

246 lines
8.6 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>
<div>
<el-row>
<el-col :span="8">
<div class="left-container">
<el-button type="primary" @click="handleAdd">添加二维码</el-button>
<el-form label-width="80px" size="small" label-position="top">
<div v-for="(cfg, idx) in drawerBarcodeData" :key="idx"
style="margin-bottom: 16px; border: 1px solid #eee; border-radius: 4px; padding: 12px 16px; background: #fafbfc;">
<div style="margin-bottom: 8px; display: flex; justify-content: space-between; align-items: center;">
<span style="font-weight: bold; color: #666;">二维码 {{ idx + 1 }}</span>
<el-button type="text" size="mini" @click="saveAsImage(idx)"
icon="el-icon-download">
另存为图片
</el-button>
<el-button type="text" size="mini" @click="handleDelete(cfg, idx)" icon="el-icon-delete">
删除
</el-button>
</div>
<el-row>
<el-col :span="12">
<el-form-item label="操作类型" style="margin-bottom: 8px;">
<el-select v-model="cfg.ioType" placeholder="请选择操作类型">
<el-option label="入库" value="in" />
<el-option label="出库" value="out" />
<el-option label="移库" value="transfer" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="单据" style="margin-bottom: 8px;">
<el-select clearable filterable size="mini" v-model="cfg.stockIoId" placeholder="请选择挂载单据"
class="form-input">
<el-option v-for="item in masterList.filter(i => i.ioType === cfg.ioType)" :key="item.stockIoId"
:label="item.stockIoCode"
:value="item.stockIoId" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="目标仓库" style="margin-bottom: 8px;">
<WarehouseSelect v-model="cfg.warehouseId" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="源仓库" v-if="cfg.ioType === 'transfer'" style="margin-bottom: 8px;">
<WarehouseSelect v-model="cfg.fromWarehouseId" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="物料类型" style="margin-bottom: 8px;">
<el-select v-model="cfg.itemType" placeholder="请选择物料类型">
<el-option v-for="dict in dict.type.stock_item_type" :key="dict.value" :label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料信息" style="margin-bottom: 8px;">
<ProductSelect v-if="cfg.itemType === 'product'" v-model="cfg.itemId" placeholder="请选择产品" />
<SemiSelect v-else-if="cfg.itemType === 'semi'" v-model="cfg.itemId" placeholder="请选择半成品" />
<RawMaterialSelect v-else-if="cfg.itemType === 'raw_material'" v-model="cfg.itemId"
placeholder="请选择原材料" />
<el-input v-else disabled v-model="cfg.itemId" placeholder="请先选择物料类型" :disabled="true"
style="width: 100%;" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="数量" style="margin-bottom: 8px;">
<el-input-number v-model="cfg.count" :min="1" :max="100" size="mini" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下方文字" style="margin-bottom: 8px;">
<el-input v-model="cfg.text" size="mini" />
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
</div>
</el-col>
<el-col :span="16">
<div class="right-container">
<div v-loading="loading">
<BarCode :barcodes="barCodeConfigs" />
</div>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import BarCode from './components/CodeRenderer.vue';
import ProductSelect from '@/components/KLPService/ProductSelect/index.vue';
import SemiSelect from '@/components/KLPService/SemiSelect/index.vue';
import RawMaterialSelect from '@/components/KLPService/RawMaterialSelect/index.vue';
import WarehouseSelect from '@/components/WarehouseSelect/index.vue';
import { saveAsImage } from '@/utils/klp';
import { listStockIo } from '@/api/wms/stockIo';
export default {
name: 'Print',
components: { BarCode, ProductSelect, SemiSelect, RawMaterialSelect, WarehouseSelect },
dicts: ['stock_item_type', 'stock_io_type'],
data() {
return {
drawerBarcodeData: [], // 条码数据
loading: false, // 加载状态
itemId: undefined, // 物料ID
itemType: undefined, // 物料类型
masterList: [],
};
},
mounted() {
this.fetchMaster();
},
computed: {
barCodeConfigs() {
return this.drawerBarcodeData.map(b => ({
code: JSON.stringify({
ioType: b.ioType,
stockIoId: b.stockIoId,
fromWarehouseId: b.fromWarehouseId,
warehouseId: b.warehouseId,
itemType: b.itemType,
itemId: b.itemId,
batchNo: b.batchNo
}),
count: b.count || 1,
textTpl: b.text || ''
}));
}
},
methods: {
onItemChange(item) {
// 选中后构造条码数据并插入
console.log(item);
const itemType = this.itemType;
const name = (itemType == 'semi' || itemType == 'product') ? item.productName : item.rawMaterialName;
const code = (itemType == 'semi' || itemType == 'product') ? item.productCode : item.rawMaterialCode;
const itemId = (itemType == 'semi' || itemType == 'product') ? item.productId : item.rawMaterialId;
const o = {
code: encodeURIComponent(`${itemType}__${itemId || ''}`),
count: 1,
textTpl: `${name}[${code}]`
}
this.drawerBarcodeData.push(o);
},
fetchMaster() {
listStockIo({ pageSize: 9999, pageNum: 1 }).then(res => {
console.log("获取挂载单据", res);
this.masterList = res.rows || [];
}).catch(error => {
console.error("获取挂载单据失败", error);
this.$message.error("获取挂载单据失败");
});
},
handleDelete(cfg, idx) {
console.log(cfg, idx);
this.drawerBarcodeData.splice(idx, 1);
},
handleAdd() {
const o = {
ioType: undefined,
stockIoId: undefined,
fromWarehouseId: undefined,
warehouseId: undefined,
itemType: undefined,
itemId: undefined,
batchNo: 'auto',
count: 0,
text: '默认文字',
}
this.drawerBarcodeData.push(o);
},
// 补充saveAsImage方法的空实现避免控制台报错
saveAsImage(index) {
saveAsImage(this.barCodeConfigs[index].code, this.barCodeConfigs[index].textTpl, index, this);
}
}
};
</script>
<style scoped lang="scss">
// 左侧容器样式
.left-container {
height: calc(100vh - 84px); // 高度为视口高度减去顶部间距
overflow-y: auto; // 纵向滚动
padding-right: 10px; // 避免内容与滚动条重叠
box-sizing: border-box;
}
// 右侧容器样式
.right-container {
height: calc(100vh - 84px); // 与左侧保持一致的高度
overflow-y: auto;
padding-left: 10px; // 与左侧间距区分
box-sizing: border-box;
}
// 美化滚动条
::-webkit-scrollbar {
width: 6px; // 滚动条宽度
height: 6px;
}
::-webkit-scrollbar-thumb {
background: #ddd;
border-radius: 3px;
}
::-webkit-scrollbar-track {
background: #f5f5f5;
}
// 解决scoped样式无法穿透到滚动条的问题
::v-deep ::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::v-deep ::-webkit-scrollbar-thumb {
background: #ddd;
border-radius: 3px;
}
::v-deep ::-webkit-scrollbar-track {
background: #f5f5f5;
}
</style>