| | |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title ml10">产品大类:</span> |
| | | <span class="search_title ml10">产品名称:</span> |
| | | <el-input v-model="searchForm.productName" |
| | | style="width: 240px" |
| | | placeholder="请输入" |
| | | clearable/> |
| | | <span class="search_title ml10">产品大类:</span> |
| | | <el-select v-model="searchForm.parentId" |
| | | style="width: 240px" |
| | | placeholder="请输入" |
| | | clearable> |
| | | <el-option v-for="item of selectList" :key="item.id" :label="item.name" :value="item.id"></el-option> |
| | | </el-select> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> |
| | | </div> |
| | | <div> |
| | |
| | | :row-class-name="tableRowClassName" height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="序号" type="index" width="60" /> |
| | | <el-table-column label="产品大类" prop="productName" show-overflow-tooltip /> |
| | | <el-table-column label="产品名称" prop="productName" show-overflow-tooltip /> |
| | | <el-table-column label="规格型号" prop="model" show-overflow-tooltip /> |
| | | <el-table-column label="单位" prop="unit" show-overflow-tooltip /> |
| | | <el-table-column label="产品图片" prop="url" show-overflow-tooltip> |
| | | <template #default="scope"> |
| | | <img :src="scope.row.url" alt="产品图片" style="width: 50px; height: 50px;"> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="高度" prop="height" show-overflow-tooltip /> |
| | | <el-table-column label="每件数量(支)" prop="boxNum" show-overflow-tooltip /> |
| | | <el-table-column label="单价(美元/件)" prop="dollarPrice" show-overflow-tooltip /> |
| | | <el-table-column label="单价(元/件)" prop="taxInclusiveUnitPrice" show-overflow-tooltip /> |
| | | <el-table-column label="库存数量" prop="qualitity" show-overflow-tooltip /> |
| | | <el-table-column label="冻结数量" prop="lockedQuantity" show-overflow-tooltip /> |
| | | <el-table-column label="库存预警数量" prop="warnNum" show-overflow-tooltip /> |
| | | <el-table-column label="备注" prop="remark" show-overflow-tooltip /> |
| | | <el-table-column label="最近更新时间" prop="updateTime" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="操作" min-width="60" align="center"> |
| | | <el-table-column fixed="right" label="操作" width="160" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="showSubtractModal(scope.row)" :disabled="scope.row.unLockedQuantity === 0">领用</el-button> |
| | | <el-button link type="primary" size="small" v-if="scope.row.unLockedQuantity > 0" @click="showFrozenModal(scope.row)">冻结</el-button> |
| | | <el-button link type="primary" size="small" v-if="scope.row.lockedQuantity > 0" @click="showThawModal(scope.row)">解冻</el-button> |
| | | <el-button link type="success" size="small" @click="showQRCode(scope.row,2)">生成条形码</el-button> |
| | | <el-button link type="success" size="small" @click="showERCode(scope.row,2)">生成二维码</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | :operation-type="operationType" |
| | | type="qualified" |
| | | @completed="handleQuery" /> |
| | | |
| | | <el-dialog |
| | | v-model="qrCodeDialogVisible" |
| | | title="商品条形码" |
| | | width="400px" |
| | | center |
| | | > |
| | | <div style="text-align: center;"> |
| | | <img id="barcode" style="width:200px;height: 50px;"/> |
| | | <!-- <img :src="qrCodeUrl" alt="二维码" style="width:200px;height:200px;" /> --> |
| | | <div style="margin: 20px;"> |
| | | <el-button type="primary" @click="downloadQRCode">下载条形码</el-button> |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | | <!-- 二维码显示对话框 --> |
| | | <el-dialog |
| | | v-model="erCodeDialogVisible" |
| | | title="商品二维码" |
| | | width="400px" |
| | | center |
| | | > |
| | | <div style="text-align: center;"> |
| | | <img :src="erCodeUrl" alt="二维码" style="width:200px;height:200px;" /> |
| | | <div style="margin: 20px;"> |
| | | <el-button type="primary" @click="downloadERCode">下载二维码图片</el-button> |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | | <el-dialog v-model="barcodeDia" title="产品信息" width="40%" @close="closeBarcodeDia"> |
| | | <div> |
| | | <el-row v-if="barcodeDetail.url" :gutter="30"> |
| | | <el-col :span="12"> |
| | | <div class="barcode-item"> |
| | | <div class="barcode-label">图片</div> |
| | | <img class="barcode-img" :src="javaApiUrl+barcodeDetail.url"></img> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <div class="barcode-item"> |
| | | <div class="barcode-label">名称</div> |
| | | <div class="barcode-value">{{barcodeDetail.productCategory}}</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="barcode-item"> |
| | | <div class="barcode-label">产品高度</div> |
| | | <div class="barcode-value">{{barcodeDetail.height}}</div> |
| | | </div> |
| | | </el-col> |
| | | |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <div class="barcode-item"> |
| | | <div class="barcode-label">单价(美元)/件</div> |
| | | <div class="barcode-value">{{barcodeDetail.dollarPrice}}</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="barcode-item"> |
| | | <div class="barcode-label">单价(元)/件</div> |
| | | <div class="barcode-value">{{barcodeDetail.taxInclusiveUnitPrice}}</div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <div class="barcode-item"> |
| | | <div class="barcode-label">数量/件</div> |
| | | <div class="barcode-value">{{barcodeDetail.qualitity}}</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="barcode-item"> |
| | | <div class="barcode-label">每件数量/支</div> |
| | | <div class="barcode-value">{{barcodeDetail.boxNum}}</div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <div class="barcode-item"> |
| | | <div class="barcode-label">规格</div> |
| | | <div class="barcode-value">{{barcodeDetail.model}}</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="barcode-item"> |
| | | <div class="barcode-label">单位</div> |
| | | <div class="barcode-value">{{barcodeDetail.unit}}</div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="closeBarcodeDia">关闭</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import pagination from '@/components/PIMTable/Pagination.vue' |
| | | import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue' |
| | | import {ElMessage, ElMessageBox} from "element-plus"; |
| | | import { getStockInventoryListPage } from "@/api/inventoryManagement/stockInventory.js"; |
| | | import { |
| | | getStockInventoryListPage, |
| | | getProductList, |
| | | getStockInventoryById |
| | | } from "@/api/inventoryManagement/stockInventory.js"; |
| | | import QRCode from "qrcode"; |
| | | import JsBarcode from "jsbarcode"; |
| | | |
| | | const NewStockInventory = defineAsyncComponent(() => import("@/views/inventoryManagement/stockManagement/New.vue")); |
| | | const SubtractStockInventory = defineAsyncComponent(() => import("@/views/inventoryManagement/stockManagement/Subtract.vue")); |
| | | const ImportStockInventory = defineAsyncComponent(() => import("@/views/inventoryManagement/stockManagement/Import.vue")); |
| | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | productName: '', |
| | | } |
| | | }, |
| | | selectList:[ |
| | | { |
| | | id:1, |
| | | label:1 |
| | | },{ |
| | | id:2, |
| | | label:2 |
| | | },{ |
| | | id:3, |
| | | label:3 |
| | | } |
| | | ] |
| | | }) |
| | | const { searchForm } = toRefs(data) |
| | | const { searchForm, selectList } = toRefs(data) |
| | | |
| | | // 查询列表 |
| | | /** 搜索按钮操作 */ |
| | |
| | | proxy.$modal.msg("已取消") |
| | | }) |
| | | } |
| | | // 获取产品大类下拉 |
| | | const productCategorySelectList =async ()=>{ |
| | | let res =await getProductList() |
| | | console.log(res) |
| | | if(res?.code === 200 && res?.data) { |
| | | selectList.value = res.data |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList() |
| | | |
| | | // 二维码相关变量 |
| | | const qrCodeDialogVisible = ref(false); |
| | | const qrCodeUrl = ref(""); |
| | | const showQRCode = async (row,type) => { |
| | | if(barcodeDia.value)return |
| | | try { |
| | | // 构建二维码内容,只包含采购合同号(纯文本) |
| | | let qrContent = row.id || ''; |
| | | // 检查内容是否为空 |
| | | if (!qrContent) { |
| | | proxy.$modal.msgWarning("该行商品id,无法生成条形码"); |
| | | return; |
| | | } |
| | | qrContent+=`,${type}` |
| | | qrCodeDialogVisible.value = true; |
| | | await nextTick(); |
| | | JsBarcode("#barcode", qrContent+'', { |
| | | width:10, |
| | | height:100, |
| | | displayValue: false |
| | | }); |
| | | } catch (error) { |
| | | console.error('生成条形码失败:', error); |
| | | proxy.$modal.msgError("生成条形码失败:" + error.message); |
| | | } |
| | | }; |
| | | |
| | | const erCodeDialogVisible = ref(false); |
| | | const erCodeUrl = ref(""); |
| | | const showERCode = async (row,type) => { |
| | | if(barcodeDia.value)return |
| | | let qrContent = row.id || ''; |
| | | // 检查内容是否为空 |
| | | if (!qrContent) { |
| | | proxy.$modal.msgWarning("该行商品id,无法生成二维码"); |
| | | return; |
| | | } |
| | | qrContent+=`,${type}` |
| | | try { |
| | | erCodeUrl.value = await QRCode.toDataURL(qrContent+'', { |
| | | width: 200, |
| | | margin: 2, |
| | | color: { |
| | | dark: '#000000', |
| | | light: '#FFFFFF' |
| | | } |
| | | }); |
| | | erCodeDialogVisible.value = true; |
| | | } catch (error) { |
| | | console.error('生成二维码失败:', error); |
| | | proxy.$modal.msgError("生成二维码失败:" + error.message); |
| | | } |
| | | }; |
| | | const downloadQRCode = () => { |
| | | const imgSrc = document.getElementById('barcode').src |
| | | const a = document.createElement('a'); |
| | | if(!imgSrc){ |
| | | proxy.$modal.msgWarning('暂无条形码') |
| | | return |
| | | } |
| | | a.href = imgSrc; |
| | | a.download = `商品条形码_${new Date().getTime()}.png`; |
| | | document.body.appendChild(a); |
| | | a.click(); |
| | | document.body.removeChild(a); |
| | | proxy.$modal.msgSuccess("下载成功"); |
| | | }; |
| | | |
| | | // 下载二维码 |
| | | const downloadERCode = () => { |
| | | if (!erCodeUrl.value) { |
| | | proxy.$modal.msgWarning("二维码未生成"); |
| | | return; |
| | | } |
| | | |
| | | const a = document.createElement('a'); |
| | | a.href = erCodeUrl.value; |
| | | a.download = `商品二维码_${new Date().getTime()}.png`; |
| | | document.body.appendChild(a); |
| | | a.click(); |
| | | document.body.removeChild(a); |
| | | proxy.$modal.msgSuccess("下载成功"); |
| | | }; |
| | | |
| | | //扫码相关参数 |
| | | const barcodeDia = ref(false); |
| | | const scanBarcodeInput = ref(''); |
| | | const barcodeDetail = ref({}) |
| | | // 扫码函数 |
| | | function scanBarcode (e){ |
| | | if(!e||!e.target||!e.target.tagName){ |
| | | return; |
| | | } |
| | | if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') { |
| | | return |
| | | } |
| | | if (e.key === 'Enter') { |
| | | let _value = scanBarcodeInput.value |
| | | getDetail(_value) |
| | | scanBarcodeInput.value = "" |
| | | } else { |
| | | scanBarcodeInput.value += e.key |
| | | } |
| | | } |
| | | const getDetail = (barcode)=>{ |
| | | if(barcode.indexOf(",")==-1){ |
| | | proxy.$modal.msgWarning("请扫描正确的条形码") |
| | | return |
| | | } |
| | | let barcodeList = barcode.split(",") |
| | | let barcodeId = barcodeList[0] |
| | | let detailApi = getStockInventoryById |
| | | |
| | | if(!detailApi){ |
| | | proxy.$modal.msgWarning("请扫描正确的条形码") |
| | | return |
| | | } |
| | | detailApi({id:barcodeId}).then((resp) => { |
| | | if(!resp.data){ |
| | | proxy.$modal.msgError("商品不存在") |
| | | return |
| | | } |
| | | if(resp.code!=200){ |
| | | proxy.$modal.msgError(res.msg) |
| | | return |
| | | } |
| | | barcodeDetail.value = resp.data |
| | | barcodeDia.value = true |
| | | }).catch(() => { |
| | | proxy.$modal.msgError("查看详情失败") |
| | | }) |
| | | |
| | | } |
| | | |
| | | |
| | | const closeBarcodeDia = () => { |
| | | barcodeDia.value = false |
| | | } |
| | | |
| | | onMounted(async() => { |
| | | // 添加扫码枪监听事件 |
| | | document.removeEventListener('keypress',scanBarcode) |
| | | document.addEventListener('keypress', scanBarcode) |
| | | await productCategorySelectList() |
| | | await getList() |
| | | }) |
| | | </script> |
| | | |
| | |
| | | :deep(.row-low-stock:hover > td) { |
| | | background-color: #fcd4d4; |
| | | } |
| | | |
| | | .barcode-item{ |
| | | display: flex; |
| | | justify-content: space-between; |
| | | padding: 5px 0; |
| | | |
| | | } |
| | | |
| | | .barcode-img{ |
| | | width: 80px; |
| | | height: 80px; |
| | | border-radius: 5px; |
| | | background-color: #F5F5F5; |
| | | } |
| | | </style> |