You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2179 lines
60 KiB
2179 lines
60 KiB
<template>
|
|
<div class="mod-config">
|
|
<!-- 条件查询 -->
|
|
<el-card :class="['search-card', { 'collapsed': !searchExpanded }]" shadow="hover">
|
|
<div slot="header" class="search-header">
|
|
<div class="header-left">
|
|
<i class="el-icon-search"></i>
|
|
<span class="header-title">Search</span>
|
|
</div>
|
|
<div class="header-right">
|
|
<el-button
|
|
type="text"
|
|
size="small"
|
|
@click="toggleSearchExpand"
|
|
class="collapse-btn">
|
|
<span>{{ searchExpanded ? '收起' : '展开' }}</span>
|
|
<i :class="searchExpanded ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
|
|
<el-form
|
|
:inline="true"
|
|
label-position="top"
|
|
:model="searchData"
|
|
class="search-form"
|
|
@keyup.enter.native="getMainData">
|
|
|
|
<!-- 所有查询条件 - 可展开/收起 -->
|
|
<template v-if="searchExpanded">
|
|
<!-- 第一行 -->
|
|
<el-row :gutter="16">
|
|
<el-col :span="4">
|
|
<el-form-item label="标签条码">
|
|
<el-input v-model="searchData.rollNo" placeholder="请输入" clearable></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<el-form-item label="物料编码">
|
|
<el-input v-model="searchData.partNo" placeholder="请输入" clearable></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<el-form-item label="物料名称">
|
|
<el-input v-model="searchData.partDescription" placeholder="请输入" clearable></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<el-form-item label="规格型号">
|
|
<el-input v-model="searchData.spec" placeholder="请输入" clearable></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<el-form-item label="仓库">
|
|
<el-select v-model="searchData.warehouseIdList" multiple collapse-tags clearable placeholder="请选择">
|
|
<el-option
|
|
v-for="item in warehouseList"
|
|
:key="item.warehouseId"
|
|
:label="item.warehouseName"
|
|
:value="item.warehouseId">
|
|
</el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<el-form-item label="库位号">
|
|
<el-input v-model="searchData.locationId" placeholder="请输入" clearable></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<!-- 第二行 -->
|
|
<el-row :gutter="16">
|
|
<el-col :span="4">
|
|
<el-form-item label="批次号">
|
|
<el-input v-model="searchData.batchNo" placeholder="请输入" clearable></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<el-form-item label="状态">
|
|
<el-select v-model="searchData.statusList" multiple collapse-tags clearable placeholder="请选择">
|
|
<el-option label="待检" value="待检"></el-option>
|
|
<el-option label="待入" value="待入"></el-option>
|
|
<el-option label="在库" value="在库"></el-option>
|
|
<el-option label="在途" value="在途"></el-option>
|
|
<el-option label="冻结" value="冻结"></el-option>
|
|
<el-option label="出库" value="出库"></el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<el-form-item label="来源单据类型">
|
|
<el-input v-model="searchData.orderref0" placeholder="请输入" clearable></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<el-form-item label="来源单据号">
|
|
<el-input v-model="searchData.orderref1" placeholder="请输入" clearable></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<el-form-item label="备注说明">
|
|
<el-input v-model="searchData.remark" placeholder="请输入" clearable></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<el-form-item label="库存总数">
|
|
<el-input v-model="totalQty" disabled></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</template>
|
|
|
|
<!-- 操作按钮区域 -->
|
|
<el-row :gutter="16">
|
|
<el-col :span="24">
|
|
<div class="search-actions">
|
|
<div class="action-left">
|
|
<el-button
|
|
type="primary"
|
|
icon="el-icon-search"
|
|
@click="getMainData">
|
|
查询
|
|
</el-button>
|
|
<el-button
|
|
icon="el-icon-refresh-left"
|
|
@click="resetSearch">
|
|
重置
|
|
</el-button>
|
|
</div>
|
|
<div class="action-right">
|
|
<el-button
|
|
type="primary"
|
|
icon="el-icon-printer"
|
|
@click="printLabelModel">
|
|
打印
|
|
</el-button>
|
|
<!-- <el-button-->
|
|
<!-- type="warning"-->
|
|
<!-- icon="el-icon-edit"-->
|
|
<!-- @click="openAttributeChangeDialog">-->
|
|
<!-- 属性变动-->
|
|
<!-- </el-button>-->
|
|
<el-button
|
|
type="primary"
|
|
icon="el-icon-lock"
|
|
@click="freezeStatus">
|
|
冻结
|
|
</el-button>
|
|
<download-excel
|
|
:fields="exportFields()"
|
|
:data="exportData"
|
|
type="xls"
|
|
:name="exportName"
|
|
:header="exportHeader"
|
|
:footer="exportFooter"
|
|
:fetch="createExportData"
|
|
:before-generate="startDownload"
|
|
:before-finish="finishDownload"
|
|
worksheet="实时库存数据"
|
|
class="export-btn">
|
|
<el-button
|
|
type="success"
|
|
icon="el-icon-download">
|
|
导出
|
|
</el-button>
|
|
</download-excel>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
</el-row>
|
|
</el-form>
|
|
</el-card>
|
|
|
|
<el-table
|
|
:height="height"
|
|
:data="dataList"
|
|
border
|
|
v-loading="dataListLoading"
|
|
@selection-change="handleSelectionChange"
|
|
highlight-current-row
|
|
style="width: 100%;">
|
|
<el-table-column
|
|
type="selection"
|
|
width="50"
|
|
align="center">
|
|
</el-table-column>
|
|
<el-table-column
|
|
v-for="(item,index) in columnList" :key="index"
|
|
:sortable="item.columnSortable"
|
|
:prop="item.columnProp"
|
|
:header-align="item.headerAlign"
|
|
:show-overflow-tooltip="item.showOverflowTooltip"
|
|
:align="item.align"
|
|
:fixed="item.fixed==''?false:item.fixed"
|
|
:min-width="item.columnWidth"
|
|
:label="item.columnLabel">
|
|
<template slot-scope="scope">
|
|
<span v-if="!item.columnHidden"> {{ scope.row[item.columnProp] }}</span>
|
|
<span v-if="item.columnImage"><img :src="scope.row[item.columnProp]" style="width: 100px; height: 80px"/></span>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<!-- <el-table-column-->
|
|
<!-- fixed="right"-->
|
|
<!-- header-align="center"-->
|
|
<!-- align="center"-->
|
|
<!-- width="150"-->
|
|
<!-- label="操作">-->
|
|
<!-- <template slot-scope="scope">-->
|
|
<!-- <a type="text" size="small" @click="printRoll(scope.row)" herf="#">卷补打</a>-->
|
|
<!-- </template>-->
|
|
<!-- </el-table-column>-->
|
|
|
|
</el-table>
|
|
<el-pagination
|
|
style="margin-top: 0px"
|
|
@size-change="sizeChangeHandle"
|
|
@current-change="currentChangeHandle"
|
|
:current-page="pageIndex"
|
|
:page-sizes="[20, 50, 100, 200, 500]"
|
|
:page-size="pageSize"
|
|
:total="totalPage"
|
|
layout="total, sizes, prev, pager, next, jumper">
|
|
</el-pagination>
|
|
<!-- 标签打印对话框 -->
|
|
<el-dialog
|
|
:close-on-click-modal="false"
|
|
v-drag
|
|
:visible.sync="printDialogVisible"
|
|
width="650px"
|
|
class="print-dialog">
|
|
<div slot="title" class="dialog-title-wrapper">
|
|
<i class="el-icon-printer" style="margin-right: 8px; font-size: 20px;"></i>
|
|
<span style="font-size: 18px; font-weight: 600;">标签打印设置</span>
|
|
</div>
|
|
|
|
<div class="print-dialog-content">
|
|
<!-- 打印信息提示 -->
|
|
<div class="print-info-banner">
|
|
<i class="el-icon-info" style="margin-right: 8px; font-size: 16px;"></i>
|
|
<span>已选择 <strong style="color: #3a7ba8;">{{ selectionDataList.length }}</strong> 个标签,请配置打印参数</span>
|
|
</div>
|
|
|
|
<el-form :model="printDialogData" label-position="top" style="margin-top: 20px;">
|
|
<el-row :gutter="20">
|
|
<el-col :span="12">
|
|
<el-form-item required>
|
|
<span slot="label" class="form-label">
|
|
<i class="el-icon-document-copy" style="margin-right: 5px;"></i>
|
|
打印次数
|
|
</span>
|
|
<el-input-number
|
|
v-model="printDialogData.printTimes"
|
|
:min="1"
|
|
:max="100"
|
|
controls-position="right"
|
|
placeholder="每个标签打印份数"
|
|
style="width: 100%">
|
|
</el-input-number>
|
|
<div class="form-tip">设置每个标签的打印份数</div>
|
|
</el-form-item>
|
|
</el-col>
|
|
|
|
<el-col :span="12">
|
|
<el-form-item required>
|
|
<span slot="label" class="form-label">
|
|
<i class="el-icon-tickets" style="margin-right: 5px;"></i>
|
|
标签模板
|
|
</span>
|
|
<el-select
|
|
v-model="printDialogData.labelNo"
|
|
placeholder="请选择标签模板"
|
|
style="width: 100%"
|
|
:disabled="labelTemplateList.length === 0">
|
|
<el-option
|
|
v-for="item in labelTemplateList"
|
|
:key="item.labelNo"
|
|
:label="item.labelName"
|
|
:value="item.labelNo">
|
|
<span style="float: left">{{ item.labelName }}</span>
|
|
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.labelNo }}</span>
|
|
</el-option>
|
|
</el-select>
|
|
<div class="form-tip" v-if="labelTemplateList.length === 0" style="color: #F56C6C;">
|
|
{{ multiPartNoTip }}
|
|
</div>
|
|
<div class="form-tip" v-else>
|
|
根据物料自动匹配模板
|
|
</div>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<el-row>
|
|
<el-col :span="24">
|
|
<el-form-item required>
|
|
<span slot="label" class="form-label">
|
|
<i class="el-icon-printer" style="margin-right: 5px;"></i>
|
|
目标打印机
|
|
</span>
|
|
<el-select
|
|
v-model="printDialogData.printerName"
|
|
placeholder="请选择打印机"
|
|
style="width: 100%"
|
|
:disabled="printerList.length === 0">
|
|
<el-option
|
|
v-for="item in printerList"
|
|
:key="item"
|
|
:label="item"
|
|
:value="item">
|
|
<i class="el-icon-printer" style="margin-right: 8px; color: #67C23A;"></i>
|
|
{{ item }}
|
|
</el-option>
|
|
</el-select>
|
|
<div class="form-tip" v-if="printerList.length === 0" style="color: #F56C6C;">
|
|
未检测到打印机,请确保已安装并启动 CLodop
|
|
</div>
|
|
<div class="form-tip" v-else>
|
|
已检测到 {{ printerList.length }} 台打印机
|
|
</div>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<!-- 打印预览说明 -->
|
|
<div class="print-summary">
|
|
<div class="summary-item">
|
|
<span class="summary-label">打印总数:</span>
|
|
<span class="summary-value">{{ selectionDataList.length * printDialogData.printTimes }} 张</span>
|
|
</div>
|
|
<div class="summary-item">
|
|
<span class="summary-label">标签数量:</span>
|
|
<span class="summary-value">{{ selectionDataList.length }} 个</span>
|
|
</div>
|
|
<div class="summary-item">
|
|
<span class="summary-label">每标签份数:</span>
|
|
<span class="summary-value">{{ printDialogData.printTimes }} 份</span>
|
|
</div>
|
|
</div>
|
|
</el-form>
|
|
</div>
|
|
|
|
<div slot="footer" class="dialog-footer">
|
|
<el-button
|
|
type="success"
|
|
icon="el-icon-printer"
|
|
@click="confirmPrint()"
|
|
:loading="printLoading"
|
|
:disabled="!printDialogData.printerName"
|
|
size="medium">
|
|
{{ printLoading ? '打印中...' : '开始打印' }}
|
|
</el-button>
|
|
<el-button
|
|
@click="printDialogVisible=false"
|
|
size="medium">
|
|
取消
|
|
</el-button>
|
|
</div>
|
|
</el-dialog>
|
|
|
|
<!-- 扫描标签对话框(新增) -->
|
|
<el-dialog
|
|
:close-on-click-modal="false"
|
|
v-drag
|
|
top="10vh"
|
|
:visible.sync="scanLabelDialogVisible"
|
|
width="1100px"
|
|
class="scan-label-dialog">
|
|
<div slot="title" class="dialog-title-custom">
|
|
<i class="el-icon-edit-outline"></i>
|
|
<span>属性变动</span>
|
|
</div>
|
|
|
|
<div class="scan-label-content">
|
|
<!-- 扫描输入区域 -->
|
|
<div class="scan-input-section">
|
|
<div class="input-wrapper">
|
|
<label class="input-label">标签条码</label>
|
|
<el-input
|
|
ref="scanInput"
|
|
v-model="scanLabelNo"
|
|
@keyup.enter.native="handleScanLabel"
|
|
clearable
|
|
placeholder="请扫描标签条码"
|
|
prefix-icon="el-icon-barcode"
|
|
class="scan-input">
|
|
</el-input>
|
|
</div>
|
|
|
|
<div class="mode-switch-wrapper">
|
|
<el-switch
|
|
v-model="isRemoveMode"
|
|
active-color="#ff4949"
|
|
inactive-color="#67C23A"
|
|
class="mode-switch">
|
|
</el-switch>
|
|
<span class="mode-text" :class="{ 'remove-mode': isRemoveMode }">
|
|
{{ isRemoveMode ? '移除' : '添加' }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="info-badges">
|
|
<div class="badge-item">
|
|
<i class="el-icon-document"></i>
|
|
<span class="badge-label">标签张数</span>
|
|
<span class="badge-value">{{ scannedLabelList.length }}</span>
|
|
</div>
|
|
<div class="badge-item">
|
|
<i class="el-icon-box"></i>
|
|
<span class="badge-label">物料总数</span>
|
|
<span class="badge-value">{{ totalScannedQty }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 扫描的标签列表 -->
|
|
<div class="table-wrapper">
|
|
<el-table
|
|
:data="scannedLabelList"
|
|
height="420"
|
|
stripe
|
|
class="scan-table">
|
|
<el-table-column
|
|
type="index"
|
|
label="NO."
|
|
width="60"
|
|
align="center">
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="rollNo"
|
|
label="标签条码"
|
|
header-align="center"
|
|
align="left"
|
|
min-width="120"
|
|
show-overflow-tooltip>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="qtyOnHand"
|
|
label="标签数量"
|
|
header-align="center"
|
|
align="right"
|
|
width="100">
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="partNo"
|
|
label="物料编码"
|
|
header-align="center"
|
|
align="left"
|
|
min-width="130"
|
|
show-overflow-tooltip>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="partDescription"
|
|
label="物料名称"
|
|
header-align="center"
|
|
align="left"
|
|
min-width="200"
|
|
show-overflow-tooltip>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="parentRollNo"
|
|
label="上机标签号"
|
|
header-align="center"
|
|
align="left"
|
|
min-width="120"
|
|
show-overflow-tooltip>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
</div>
|
|
|
|
<div slot="footer" class="dialog-footer-custom">
|
|
<el-button
|
|
type="success"
|
|
@click="confirmScanLabels()"
|
|
:disabled="scannedLabelList.length === 0"
|
|
icon="el-icon-check">
|
|
保存
|
|
</el-button>
|
|
<el-button @click="closeScanLabelDialog()" icon="el-icon-close">
|
|
取消
|
|
</el-button>
|
|
</div>
|
|
</el-dialog>
|
|
|
|
<!-- 属性变动对话框(原有的) -->
|
|
<el-dialog title="属性变动" :close-on-click-modal="false" v-drag :visible.sync="attributeChangeDialogVisible" width="450px">
|
|
<el-form :model="attributeChangeForm" label-position="top" style="margin-top: -5px;">
|
|
<el-row :gutter="20">
|
|
<el-col :span="24">
|
|
<el-form-item label="合约号码">
|
|
<el-input v-model="attributeChangeForm.batchNo" placeholder="请输入合约号码"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="24">
|
|
<el-form-item label="备注说明">
|
|
<el-input type="textarea" :rows="3" v-model="attributeChangeForm.remark" placeholder="请输入备注说明"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</el-form>
|
|
<el-footer style="height:35px;margin-top: 55px;text-align:center">
|
|
<el-button type="success" @click="saveAttributeChange()">保存</el-button>
|
|
<el-button type="primary" @click="attributeChangeDialogVisible=false">关闭</el-button>
|
|
</el-footer>
|
|
</el-dialog>
|
|
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
|
|
import {getCRollInfoList} from '@/api/crollinfo/crollinfo.js'
|
|
import {rollPrint} from '@/api/finishedProductWarehouse/rollPrint.js'
|
|
import {
|
|
getInboundQcResultData,
|
|
getKuCunLabelData,
|
|
updateInventoryStockAttribute,
|
|
getWarehouseList,
|
|
freezeStatusInventoryStock,
|
|
getPartLabelTemplateList,
|
|
callUspPartLabelTemplate
|
|
} from '../../../api/wms/wms'
|
|
import {kuCunLabelPrint} from '../clodopLabel/kuCunLabel'
|
|
import getLodop from '@/utils/LodopFuncs.js'
|
|
import labelPrintTemplates from '@/mixins/labelPrintTemplates.js'
|
|
|
|
export default {
|
|
mixins: [labelPrintTemplates],
|
|
data() {
|
|
return {
|
|
height: 450,
|
|
searchExpanded: true,
|
|
searchData: {
|
|
userName: this.$store.state.user.name,
|
|
partNo:'',
|
|
partDescription:'',
|
|
spec:'',
|
|
warehouseIdList:[],
|
|
locationId:'',
|
|
rollNo:'',
|
|
statusList:['在库'],
|
|
orderref0:'',
|
|
orderref1:'',
|
|
batchNo:'',
|
|
remark:'',
|
|
page: 1,
|
|
limit: 10,
|
|
},
|
|
totalQty: 0,
|
|
warehouseList: [],
|
|
pageIndex: 1,
|
|
pageSize: 50,
|
|
totalPage: 0,
|
|
columnList: [
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1BuNo',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "buNo",
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: "BU",
|
|
columnWidth: '60',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1RollNo',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "rollNo",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "标签条码",
|
|
columnWidth: '110',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1QtyOnHand',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "qtyOnHand",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "标签数量",
|
|
columnWidth: '100',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1Status',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "status",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "标签状态",
|
|
columnWidth: '100',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1PartNo',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "partNo",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "物料编码",
|
|
columnWidth: '120',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1PartDescription',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "partDescription",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "物料名称",
|
|
columnWidth: '250',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1Spec',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "spec",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "规格型号",
|
|
columnWidth: '100',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1UmName',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "umName",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "单位",
|
|
columnWidth: '100',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1LabelType',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "labelType",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "标签类型",
|
|
columnWidth: '100',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1ParentRollNo',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "parentRollNo",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "上级标签号",
|
|
columnWidth: '100',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1ParentRollType',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "parentRollType",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "上级标签类型",
|
|
columnWidth: '100',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1WarehouseName',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "warehouseName",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "仓库",
|
|
columnWidth: '120',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1LocationName',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "locationName",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "库位",
|
|
columnWidth: '120',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1FirstInDate',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "firstInDate",
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: "入库日期",
|
|
columnWidth: '130',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1ManufactureDate',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "manufactureDate",
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: "生产日期",
|
|
columnWidth: '130',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1ExpiredDate',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "expiredDate",
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: "有效期",
|
|
columnWidth: '130',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1Orderref0',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "orderref0",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "来源单据类型",
|
|
columnWidth: '100',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1OrderRef1',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "orderref1",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "来源单据号",
|
|
columnWidth: '100',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1OrderRef2',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "orderref2",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "来源单据行号",
|
|
columnWidth: '100',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1BatchNo',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "batchNo",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "合约号码",
|
|
columnWidth: '120',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1Wdr',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "wdr",
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: "批次号",
|
|
columnWidth: '100',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.functionId,
|
|
serialNumber: '680Table1Remark',
|
|
tableId: "680Table1",
|
|
tableName: "库存标签表",
|
|
columnProp: "remark",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "备注说明",
|
|
columnWidth: '200',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: false
|
|
},
|
|
],
|
|
addModelData:{
|
|
type:'A',
|
|
},
|
|
dataList: [],
|
|
addModelFlag: false,
|
|
dataListLoading: false,
|
|
// 扫描标签对话框相关(新增)
|
|
scanLabelDialogVisible: false,
|
|
scanLabelNo: '',
|
|
scannedLabelList: [],
|
|
isRemoveMode: false, // 默认为添加模式
|
|
// 属性变动相关
|
|
attributeChangeDialogVisible: false,
|
|
attributeChangeForm: {
|
|
batchNo: '',
|
|
remark: ''
|
|
},
|
|
selectionDataList:[],
|
|
// 标签打印相关
|
|
printDialogVisible: false,
|
|
printDialogData: {
|
|
printTimes: 1,
|
|
labelNo: '',
|
|
printerName: ''
|
|
},
|
|
labelTemplateList: [],
|
|
printerList: [],
|
|
printLoading: false,
|
|
multiPartNoTip: '',
|
|
// 导出相关
|
|
exportData: [],
|
|
exportName: "实时库存数据",
|
|
exportHeader: ["实时库存数据"],
|
|
exportFooter: [],
|
|
exportLoading: false
|
|
}
|
|
},
|
|
components: {
|
|
|
|
},
|
|
computed: {
|
|
// 计算物料总数(标签数量总和)
|
|
totalScannedQty() {
|
|
return this.scannedLabelList.reduce((sum, item) => {
|
|
return sum + (parseFloat(item.qtyOnHand) || 0);
|
|
}, 0);
|
|
}
|
|
},
|
|
mounted() {
|
|
this.calculateTableHeight();
|
|
window.addEventListener('resize', this.calculateTableHeight);
|
|
// 加载仓库列表
|
|
this.getWarehouseList();
|
|
},
|
|
beforeDestroy() {
|
|
window.removeEventListener('resize', this.calculateTableHeight);
|
|
},
|
|
activated() {
|
|
// this.getDataList()
|
|
},
|
|
methods: {
|
|
// 计算表格高度
|
|
calculateTableHeight() {
|
|
this.$nextTick(() => {
|
|
const windowHeight = window.innerHeight;
|
|
const headerHeight = this.searchExpanded ? 280 : 158;
|
|
this.height = windowHeight - headerHeight - 85;
|
|
});
|
|
},
|
|
// 切换搜索条件展开/收起
|
|
toggleSearchExpand() {
|
|
this.searchExpanded = !this.searchExpanded;
|
|
this.calculateTableHeight();
|
|
},
|
|
|
|
// 重置搜索条件
|
|
resetSearch() {
|
|
this.searchData = {
|
|
userName: this.$store.state.user.name,
|
|
partNo: '',
|
|
partDescription: '',
|
|
spec: '',
|
|
warehouseIdList: [],
|
|
locationId: '',
|
|
rollNo: '',
|
|
statusList: ['在库'],
|
|
orderref0: '',
|
|
orderref1: '',
|
|
batchNo: '',
|
|
remark: '',
|
|
page: 1,
|
|
limit: 10,
|
|
};
|
|
this.pageIndex = 1;
|
|
this.getMainData();
|
|
},
|
|
|
|
// 卷标签补打
|
|
printRoll(val) {
|
|
let rollList = []
|
|
rollList.push(val)
|
|
rollPrint(rollList).then(({data}) => {
|
|
if (data.code == 0) {
|
|
this.$message.success(data.msg)
|
|
} else {
|
|
this.$message.warning(data.msg)
|
|
}
|
|
})
|
|
},
|
|
handleSelectionChange(val){
|
|
this.selectionDataList = val
|
|
console.log(this.selectionDataList)
|
|
},
|
|
|
|
// 获取仓库列表
|
|
getWarehouseList(){
|
|
let params = {
|
|
userName: this.$store.state.user.name
|
|
};
|
|
getWarehouseList(params).then(({data}) => {
|
|
if (data.code === 0) {
|
|
this.warehouseList = data.rows || [];
|
|
}
|
|
});
|
|
},
|
|
getMainData(){
|
|
this.searchData.limit = this.pageSize
|
|
this.searchData.page = this.pageIndex
|
|
getKuCunLabelData(this.searchData).then(({data}) => {
|
|
if (data.code === 0) {
|
|
this.dataList = data.page.list
|
|
this.pageIndex = data.page.currPage
|
|
this.pageSize = data.page.pageSize
|
|
this.totalPage = data.page.totalCount
|
|
this.totalQty = data.page.list[0].totalQty
|
|
}
|
|
this.dataListLoading = false
|
|
})
|
|
},
|
|
// 分页处理
|
|
sizeChangeHandle(val) {
|
|
this.pageSize = val
|
|
this.pageIndex = 1
|
|
this.getMainData()
|
|
},
|
|
currentChangeHandle(val) {
|
|
this.pageIndex = val
|
|
this.getMainData()
|
|
},
|
|
async printLabelModel(){
|
|
if(this.selectionDataList.length===0){
|
|
this.$message.error('未选择标签!');
|
|
return false;
|
|
}
|
|
|
|
// 检查是否选择了不同物料的标签
|
|
const uniquePartNos = [...new Set(this.selectionDataList.map(item => item.partNo))];
|
|
const isSinglePartNo = uniquePartNos.length === 1;
|
|
|
|
if(isSinglePartNo){
|
|
// 同一物料,查询标签模板列表
|
|
await this.getLabelTemplates(uniquePartNos[0]);
|
|
// 如果没有查到模板,设置提示信息
|
|
if(this.labelTemplateList.length === 0) {
|
|
this.multiPartNoTip = '暂无可用模板';
|
|
} else {
|
|
this.multiPartNoTip = '';
|
|
}
|
|
} else {
|
|
// 不同物料,不查询模板列表,后端会自动返回
|
|
this.labelTemplateList = [];
|
|
this.multiPartNoTip = `已选择 ${uniquePartNos.length} 种物料,将由系统自动匹配模板`;
|
|
}
|
|
|
|
// 获取打印机列表
|
|
this.getPrinterList();
|
|
|
|
// 打开标签打印对话框
|
|
this.printDialogData = {
|
|
printTimes: 1,
|
|
labelNo: '',
|
|
printerName: ''
|
|
};
|
|
this.printDialogVisible = true;
|
|
},
|
|
|
|
// 获取标签模板列表(仅当选中同一物料时)
|
|
async getLabelTemplates(partNo){
|
|
const params = {
|
|
site: this.$store.state.user.site,
|
|
buNo: this.selectionDataList[0].buNo,
|
|
partNo: partNo
|
|
};
|
|
|
|
try {
|
|
const {data} = await getPartLabelTemplateList(params);
|
|
if (data && data.code === 0) {
|
|
this.labelTemplateList = data.list || [];
|
|
if(this.labelTemplateList.length > 0){
|
|
// 默认选中第一个
|
|
this.printDialogData.labelNo = this.labelTemplateList[0].labelNo;
|
|
}
|
|
} else {
|
|
this.$message.error(data.msg || '获取标签模板失败!');
|
|
}
|
|
} catch (error) {
|
|
console.error('获取标签模板失败:', error);
|
|
this.$message.error('获取标签模板失败!');
|
|
}
|
|
},
|
|
|
|
// 获取打印机列表
|
|
getPrinterList(){
|
|
try {
|
|
const LODOP = getLodop();
|
|
if (!LODOP) {
|
|
this.$message.warning('未检测到打印控件,请确保已安装并启动CLodop!');
|
|
return;
|
|
}
|
|
|
|
const printerCount = LODOP.GET_PRINTER_COUNT();
|
|
this.printerList = [];
|
|
for (let i = 0; i < printerCount; i++) {
|
|
this.printerList.push(LODOP.GET_PRINTER_NAME(i));
|
|
}
|
|
|
|
if(this.printerList.length > 0){
|
|
// 默认选中第一个打印机
|
|
this.printDialogData.printerName = this.printerList[0];
|
|
}
|
|
} catch (error) {
|
|
console.error('获取打印机列表失败:', error);
|
|
this.$message.error('获取打印机列表失败!');
|
|
}
|
|
},
|
|
|
|
// 确认打印
|
|
async confirmPrint(){
|
|
// 验证必填项
|
|
if(!this.printDialogData.printerName){
|
|
this.$message.error('请选择打印机!');
|
|
return;
|
|
}
|
|
|
|
this.printLoading = true;
|
|
|
|
try {
|
|
// 调用存储过程获取打印参数
|
|
const printDataList = [];
|
|
|
|
for(let i = 0; i < this.selectionDataList.length; i++){
|
|
const item = this.selectionDataList[i];
|
|
const params = {
|
|
site: item.site,
|
|
buNo: item.buNo,
|
|
menuID: this.$route.meta.menuId || '',
|
|
relatedOrderNo: item.orderref1 || '',
|
|
relatedOrderLineNo: item.orderref2 || '',
|
|
documentNo: item.orderref1 || '',
|
|
partNo: item.partNo,
|
|
// 如果选择了不同物料,labelNo传空字符串,让存储过程自动返回
|
|
labelNo: this.printDialogData.labelNo || '',
|
|
rollNo: item.rollNo
|
|
};
|
|
|
|
const {data} = await callUspPartLabelTemplate(params);
|
|
if (data && data.code === 0) {
|
|
// 确保 labelNo 字段存在
|
|
const printData = {
|
|
...data.row,
|
|
labelNo: data.row.labelNo || data.row.LabelNo || data.row.label_no || this.printDialogData.labelNo
|
|
};
|
|
printDataList.push(printData);
|
|
} else {
|
|
this.$message.error(`获取标签 ${item.rollNo} 的打印参数失败:${data.msg}`);
|
|
this.printLoading = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 根据 labelNo 调用相应的打印方法
|
|
await this.executePrint(printDataList);
|
|
|
|
this.printDialogVisible = false;
|
|
this.$message.success('打印任务已发送!');
|
|
this.getMainData();
|
|
|
|
} catch (error) {
|
|
console.error('打印失败:', error);
|
|
this.$message.error('打印失败:' + error.message);
|
|
} finally {
|
|
this.printLoading = false;
|
|
}
|
|
},
|
|
|
|
// 执行打印
|
|
async executePrint(printDataList){
|
|
const LODOP = getLodop();
|
|
if (!LODOP) {
|
|
this.$message.error('无法连接到打印控件!');
|
|
return;
|
|
}
|
|
|
|
// 初始化打印任务
|
|
LODOP.PRINT_INIT('库存标签补打');
|
|
|
|
// 设置打印模式
|
|
LODOP.SET_PRINT_MODE("PRINT_NOCOLLATE", true);
|
|
|
|
// 设置打印机
|
|
LODOP.SET_PRINTER_INDEX(this.printDialogData.printerName);
|
|
|
|
for(let times = 0; times < this.printDialogData.printTimes; times++){
|
|
for(let i = 0; i < printDataList.length; i++){
|
|
const printData = printDataList[i];
|
|
|
|
// 根据 labelNo 调用不同的打印方法
|
|
if(printData.labelNo === 'A001'){
|
|
await this.printLabelA001(LODOP, printData, i > 0 || times > 0);
|
|
} else if(printData.labelNo === 'A002'){
|
|
await this.printLabelA002(LODOP, printData, i > 0 || times > 0);
|
|
} else if(printData.labelNo === 'A003'){
|
|
await this.printLabelA003(LODOP, printData, i > 0 || times > 0);
|
|
} else if(printData.labelNo === 'A004'){
|
|
this.printLabelA004(LODOP, printData, i > 0 || times > 0);
|
|
} else {
|
|
this.$message.warning(`未知的标签模板:${printData.labelNo}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 预览打印(避免水印)
|
|
//LODOP.PREVIEW();
|
|
LODOP.PRINT();
|
|
},
|
|
|
|
printLabel(){
|
|
kuCunLabelPrint(this.selectionDataList,"A")
|
|
},
|
|
|
|
// 打开属性变动对话框(修改:不需要选择标签也可以打开)
|
|
openAttributeChangeDialog() {
|
|
// 初始化扫描标签列表为已勾选的标签
|
|
this.scannedLabelList = JSON.parse(JSON.stringify(this.selectionDataList));
|
|
this.scanLabelNo = '';
|
|
this.isRemoveMode = false; // 重置为添加模式
|
|
|
|
// 打开扫描标签对话框
|
|
this.scanLabelDialogVisible = true;
|
|
|
|
// 自动聚焦到输入框
|
|
this.$nextTick(() => {
|
|
if (this.$refs.scanInput) {
|
|
this.$refs.scanInput.focus();
|
|
}
|
|
});
|
|
},
|
|
|
|
// 处理扫描标签(根据模式添加或移除)
|
|
async handleScanLabel() {
|
|
if (!this.scanLabelNo || this.scanLabelNo.trim() === '') {
|
|
this.$message.warning('请输入或扫描标签条码!');
|
|
return;
|
|
}
|
|
|
|
const rollNo = this.scanLabelNo.trim();
|
|
|
|
if (this.isRemoveMode) {
|
|
// 移除模式
|
|
this.removeLabelByCode(rollNo);
|
|
} else {
|
|
// 添加模式
|
|
this.addLabelByCode(rollNo);
|
|
}
|
|
},
|
|
|
|
// 添加标签
|
|
async addLabelByCode(rollNo) {
|
|
// 检查是否已经存在
|
|
const existingIndex = this.scannedLabelList.findIndex(item => item.rollNo === rollNo);
|
|
if (existingIndex !== -1) {
|
|
this.$message.warning(`标签 ${rollNo} 已存在列表中`);
|
|
this.scanLabelNo = '';
|
|
this.$nextTick(() => {
|
|
if (this.$refs.scanInput) {
|
|
this.$refs.scanInput.focus();
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// 调用查询接口获取标签信息(使用主信息的查询SQL)
|
|
const params = {
|
|
userName: this.$store.state.user.name,
|
|
rollNo: rollNo,
|
|
page: 1,
|
|
limit: 1
|
|
};
|
|
|
|
const {data} = await getKuCunLabelData(params);
|
|
|
|
if (data && data.code === 0 && data.page && data.page.list && data.page.list.length > 0) {
|
|
const labelData = data.page.list[0];
|
|
|
|
// 添加到列表最前面(倒排)
|
|
this.scannedLabelList.unshift(labelData);
|
|
this.$message.success(`标签 ${rollNo} 添加成功`);
|
|
} else {
|
|
this.$message.error(`未找到标签 ${rollNo}`);
|
|
}
|
|
} catch (error) {
|
|
this.$message.error(`查询标签失败: ${error.message || error}`);
|
|
}
|
|
|
|
// 清空输入框并聚焦
|
|
this.scanLabelNo = '';
|
|
this.$nextTick(() => {
|
|
if (this.$refs.scanInput) {
|
|
this.$refs.scanInput.focus();
|
|
}
|
|
});
|
|
},
|
|
|
|
// 移除标签
|
|
removeLabelByCode(rollNo) {
|
|
const existingIndex = this.scannedLabelList.findIndex(item => item.rollNo === rollNo);
|
|
|
|
if (existingIndex === -1) {
|
|
this.$message.warning(`未找到标签 ${rollNo}`);
|
|
} else {
|
|
this.scannedLabelList.splice(existingIndex, 1);
|
|
this.$message.success(`标签 ${rollNo} 已移除`);
|
|
}
|
|
|
|
// 清空输入框并聚焦
|
|
this.scanLabelNo = '';
|
|
this.$nextTick(() => {
|
|
if (this.$refs.scanInput) {
|
|
this.$refs.scanInput.focus();
|
|
}
|
|
});
|
|
},
|
|
|
|
// 确认扫描标签(保存按钮)
|
|
confirmScanLabels() {
|
|
if (this.scannedLabelList.length === 0) {
|
|
this.$message.warning('请至少扫描一个标签!');
|
|
return;
|
|
}
|
|
|
|
// 关闭扫描对话框
|
|
this.scanLabelDialogVisible = false;
|
|
|
|
// 将扫描的标签列表赋值给 selectionDataList
|
|
this.selectionDataList = JSON.parse(JSON.stringify(this.scannedLabelList));
|
|
|
|
// 重置属性变动表单
|
|
this.attributeChangeForm = {
|
|
batchNo: '',
|
|
remark: ''
|
|
};
|
|
|
|
// 打开属性变动对话框
|
|
this.attributeChangeDialogVisible = true;
|
|
},
|
|
|
|
// 关闭扫描标签对话框
|
|
closeScanLabelDialog() {
|
|
this.scanLabelDialogVisible = false;
|
|
this.scanLabelNo = '';
|
|
},
|
|
|
|
// 保存属性变动
|
|
async saveAttributeChange() {
|
|
// 构建更新数据列表
|
|
const updateList = this.selectionDataList.map(item => {
|
|
return {
|
|
site: item.site,
|
|
buNo: item.buNo,
|
|
rollNo: item.rollNo,
|
|
batchNo: this.attributeChangeForm.batchNo,
|
|
remark: this.attributeChangeForm.remark
|
|
};
|
|
});
|
|
|
|
try {
|
|
const {data} = await updateInventoryStockAttribute(updateList);
|
|
if(data && data.code === 0){
|
|
this.$message.success('属性变动成功');
|
|
this.attributeChangeDialogVisible = false;
|
|
// 刷新数据
|
|
this.getMainData();
|
|
} else {
|
|
this.$message.error(data.msg || '属性变动失败');
|
|
}
|
|
} catch (error) {
|
|
this.$message.error(error.msg || '属性变动失败,请重试');
|
|
}
|
|
},
|
|
freezeStatus() {
|
|
if (this.selectionDataList.length === 0) {
|
|
this.$message.warning('请先勾选要冻结的标签!')
|
|
return false
|
|
}
|
|
let flag = true
|
|
this.selectionDataList.forEach((item)=>{
|
|
if (item.status != '在库'){
|
|
flag = false
|
|
}
|
|
})
|
|
if (!flag) {
|
|
this.$message.warning("勾选的内容存在不是'在库'状态的数据")
|
|
return false
|
|
}
|
|
this.$confirm('确认冻结所选的' + this.selectionDataList.length + '条数据?', '提示', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}).then(() => {
|
|
freezeStatusInventoryStock(this.selectionDataList).then(({data}) => {
|
|
if (data.code == 0) {
|
|
this.$message.success('操作成功')
|
|
this.getMainData()
|
|
}
|
|
}).catch()
|
|
})
|
|
},
|
|
// 导出相关方法
|
|
exportFields() {
|
|
let json = {}
|
|
this.columnList.forEach((item) => {
|
|
json[item.columnLabel] = item.columnProp
|
|
})
|
|
return json
|
|
},
|
|
async createExportData() {
|
|
// 构建查询参数,获取所有数据(不分页)
|
|
const params = {
|
|
...this.searchData,
|
|
page: 1,
|
|
limit: 999999 // 获取所有数据
|
|
}
|
|
try {
|
|
const {data} = await getKuCunLabelData(params)
|
|
if (data.code === 0) {
|
|
return data.page.list || []
|
|
} else {
|
|
this.$message.error('获取导出数据失败')
|
|
return []
|
|
}
|
|
} catch (error) {
|
|
this.$message.error('获取导出数据失败:' + error.message)
|
|
return []
|
|
}
|
|
},
|
|
startDownload() {
|
|
this.exportLoading = true
|
|
this.exportName = "实时库存数据_" + this.dayjs().format('YYYYMMDDHHmmss')
|
|
},
|
|
finishDownload() {
|
|
this.exportLoading = false
|
|
this.$message.success('导出成功')
|
|
}
|
|
},
|
|
created() {
|
|
|
|
}
|
|
}
|
|
</script>
|
|
<style scoped lang="scss">
|
|
.sl-svg {
|
|
overflow: hidden;
|
|
float: right;
|
|
}
|
|
|
|
/* 搜索卡片样式 - 参考IPQC检验页面 */
|
|
.search-card {
|
|
margin-bottom: 16px;
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.search-card:hover {
|
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
|
}
|
|
|
|
.search-card /deep/ .el-card__header {
|
|
padding: 5px 20px;
|
|
background: linear-gradient(135deg, #9ac3d0 20%, #b6c7dd 80%);
|
|
border-bottom: none;
|
|
}
|
|
|
|
.search-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.header-left {
|
|
display: flex;
|
|
align-items: center;
|
|
color: #fff;
|
|
}
|
|
|
|
.header-left i {
|
|
font-size: 16px;
|
|
margin-right: 8px;
|
|
}
|
|
|
|
.header-title {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.header-right {
|
|
color: #fff;
|
|
}
|
|
|
|
.collapse-btn {
|
|
color: #fff;
|
|
font-weight: 500;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.collapse-btn:hover {
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.collapse-btn i {
|
|
margin-left: 4px;
|
|
}
|
|
|
|
.search-form {
|
|
padding: 6px 0;
|
|
min-height: 0;
|
|
}
|
|
|
|
/* 卡片主体样式 */
|
|
.search-card /deep/ .el-card__body {
|
|
padding: 10px;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
/* 收起时的样式 */
|
|
.search-card.collapsed /deep/ .el-card__body {
|
|
padding: 10px 20px;
|
|
}
|
|
|
|
.search-form /deep/ .el-form-item {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.search-form /deep/ .el-form-item__label {
|
|
font-weight: 500;
|
|
color: #606266;
|
|
padding-bottom: 4px;
|
|
}
|
|
|
|
.search-form /deep/ .el-input__inner,
|
|
.search-form /deep/ .el-textarea__inner {
|
|
border-radius: 6px;
|
|
border: 1px solid #DCDFE6;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.search-form /deep/ .el-input__inner:focus,
|
|
.search-form /deep/ .el-textarea__inner:focus {
|
|
border-color: #9ac3d0;
|
|
box-shadow: 0 0 0 2px rgba(154, 195, 208, 0.1);
|
|
}
|
|
|
|
.search-form /deep/ .el-select {
|
|
width: 100%;
|
|
}
|
|
|
|
.search-form /deep/ .el-date-editor.el-input {
|
|
width: 100%;
|
|
}
|
|
|
|
/* 操作按钮区域 */
|
|
.search-actions {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 8px 0 2px 0;
|
|
}
|
|
|
|
/* 展开时显示上边框 */
|
|
.search-card:not(.collapsed) .search-actions {
|
|
border-top: 1px solid #f0f0f0;
|
|
margin-top: 6px;
|
|
}
|
|
|
|
/* 收起时不显示上边框和上边距 */
|
|
.search-card.collapsed .search-actions {
|
|
border-top: none;
|
|
margin-top: 0;
|
|
padding-top: 0;
|
|
}
|
|
|
|
.action-left,
|
|
.action-right {
|
|
display: flex;
|
|
gap: 8px;
|
|
}
|
|
|
|
.search-actions .el-button {
|
|
border-radius: 4px;
|
|
padding: 5px 10px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.search-actions .el-button:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
}
|
|
|
|
.search-actions .el-button--primary {
|
|
background: #60aeff;
|
|
border-color: #60aeff;
|
|
}
|
|
|
|
.search-actions .el-button--primary:hover {
|
|
background: #7dbdff;
|
|
border-color: #7dbdff;
|
|
}
|
|
|
|
.search-actions .el-button--success {
|
|
background: #67C23A;
|
|
border-color: #67C23A;
|
|
}
|
|
|
|
.search-actions .el-button--success:hover {
|
|
background: #85ce61;
|
|
border-color: #85ce61;
|
|
}
|
|
|
|
.search-actions .el-button--danger {
|
|
background: #F56C6C;
|
|
border-color: #F56C6C;
|
|
}
|
|
|
|
.search-actions .el-button--danger:hover {
|
|
background: #f78989;
|
|
border-color: #f78989;
|
|
}
|
|
|
|
.search-actions .el-button--warning {
|
|
background: #E6A23C;
|
|
border-color: #E6A23C;
|
|
}
|
|
|
|
.search-actions .el-button--warning:hover {
|
|
background: #ebb563;
|
|
border-color: #ebb563;
|
|
}
|
|
|
|
/* 导出按钮样式 */
|
|
.export-btn {
|
|
display: inline-block;
|
|
}
|
|
|
|
.export-btn .el-button {
|
|
border-radius: 4px;
|
|
padding: 5px 10px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.export-btn .el-button:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
}
|
|
|
|
/* 响应式设计 */
|
|
@media (max-width: 1200px) {
|
|
.search-actions {
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.action-left,
|
|
.action-right {
|
|
width: 100%;
|
|
justify-content: center;
|
|
}
|
|
}
|
|
|
|
/* 标签打印对话框样式 */
|
|
.print-dialog {
|
|
/deep/ .el-dialog__header {
|
|
background: linear-gradient(135deg, #9ac3d0 20%, #b6c7dd 80%);
|
|
padding: 20px 20px 20px 20px;
|
|
border-radius: 4px 4px 0 0;
|
|
}
|
|
|
|
/deep/ .el-dialog__title {
|
|
color: #ffffff;
|
|
}
|
|
|
|
/deep/ .el-dialog__headerbtn .el-dialog__close {
|
|
color: #ffffff;
|
|
font-size: 20px;
|
|
font-weight: bold;
|
|
|
|
&:hover {
|
|
color: #f0f0f0;
|
|
}
|
|
}
|
|
|
|
/deep/ .el-dialog__body {
|
|
padding: 0;
|
|
}
|
|
|
|
.dialog-title-wrapper {
|
|
color: #ffffff;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.print-dialog-content {
|
|
padding: 25px 30px;
|
|
}
|
|
|
|
.print-info-banner {
|
|
background: linear-gradient(135deg, #e8f4f8 0%, #f0f5fb 100%);
|
|
border-left: 4px solid #60aeff;
|
|
padding: 12px 16px;
|
|
border-radius: 4px;
|
|
color: #606266;
|
|
font-size: 14px;
|
|
display: flex;
|
|
align-items: center;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
|
}
|
|
|
|
.form-label {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
color: #303133;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.form-tip {
|
|
font-size: 12px;
|
|
color: #909399;
|
|
margin-top: 5px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.print-summary {
|
|
background: linear-gradient(135deg, #e1f0f5 0%, #dae8f3 100%);
|
|
border-radius: 8px;
|
|
padding: 16px 20px;
|
|
margin-top: 20px;
|
|
display: flex;
|
|
justify-content: space-around;
|
|
box-shadow: 0 2px 8px rgba(96, 174, 255, 0.15);
|
|
border: 1px solid #c8dff0;
|
|
|
|
.summary-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
|
|
.summary-label {
|
|
font-size: 12px;
|
|
color: #5a7a8f;
|
|
margin-bottom: 5px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.summary-value {
|
|
font-size: 20px;
|
|
font-weight: bold;
|
|
color: #3a7ba8;
|
|
}
|
|
}
|
|
}
|
|
|
|
/deep/ .el-form-item {
|
|
margin-bottom: 18px;
|
|
}
|
|
|
|
/deep/ .el-input-number {
|
|
width: 100%;
|
|
|
|
.el-input__inner {
|
|
text-align: left;
|
|
}
|
|
}
|
|
|
|
/deep/ .el-select {
|
|
.el-input__inner {
|
|
border: 1px solid #DCDFE6;
|
|
transition: all 0.3s;
|
|
|
|
&:hover {
|
|
border-color: #409EFF;
|
|
}
|
|
|
|
&:focus {
|
|
border-color: #409EFF;
|
|
}
|
|
}
|
|
}
|
|
|
|
/deep/ .dialog-footer {
|
|
padding: 15px 30px 25px 30px;
|
|
text-align: center;
|
|
background-color: #fafafa;
|
|
border-top: 1px solid #e8e8e8;
|
|
|
|
.el-button {
|
|
min-width: 120px;
|
|
height: 40px;
|
|
font-weight: 500;
|
|
transition: all 0.3s;
|
|
font-size: 15px;
|
|
}
|
|
|
|
.el-button--success {
|
|
background: linear-gradient(135deg, #67C23A 0%, #85ce61 100%);
|
|
border: none;
|
|
box-shadow: 0 2px 4px rgba(103, 194, 58, 0.3);
|
|
|
|
&:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 8px rgba(103, 194, 58, 0.4);
|
|
}
|
|
|
|
&:active {
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 选项样式优化 */
|
|
/deep/ .el-select-dropdown__item {
|
|
padding: 10px 20px;
|
|
transition: all 0.2s;
|
|
|
|
&:hover {
|
|
background-color: #f5f7fa;
|
|
}
|
|
}
|
|
|
|
/* 输入框聚焦效果 */
|
|
/deep/ .el-input__inner:focus,
|
|
/deep/ .el-textarea__inner:focus {
|
|
border-color: #409EFF;
|
|
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.1);
|
|
}
|
|
|
|
/* 扫描标签对话框样式 - 简约高端 */
|
|
.scan-label-dialog {
|
|
/deep/ .el-dialog {
|
|
border-radius: 8px;
|
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
|
|
}
|
|
|
|
/deep/ .el-dialog__header {
|
|
padding: 0;
|
|
border-bottom: 1px solid #e8e8e8;
|
|
}
|
|
|
|
/deep/ .el-dialog__body {
|
|
padding: 0;
|
|
}
|
|
|
|
/deep/ .el-dialog__footer {
|
|
padding: 16px 24px;
|
|
border-top: 1px solid #e8e8e8;
|
|
background-color: #fafafa;
|
|
}
|
|
|
|
.dialog-title-custom {
|
|
padding: 20px 24px;
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
color: #303133;
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
i {
|
|
font-size: 20px;
|
|
margin-right: 10px;
|
|
color: #409EFF;
|
|
}
|
|
}
|
|
|
|
.scan-label-content {
|
|
padding: 24px;
|
|
|
|
.scan-input-section {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
gap: 20px;
|
|
margin-bottom: 20px;
|
|
padding-bottom: 20px;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
.input-wrapper {
|
|
flex: 1;
|
|
|
|
.input-label {
|
|
display: block;
|
|
font-size: 14px;
|
|
color: #606266;
|
|
margin-bottom: 2px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.scan-input {
|
|
/deep/ .el-input__inner {
|
|
height: 42px;
|
|
line-height: 42px;
|
|
font-size: 14px;
|
|
border-radius: 4px;
|
|
border: 1px solid #dcdfe6;
|
|
transition: all 0.3s;
|
|
|
|
&:focus {
|
|
border-color: #409EFF;
|
|
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.1);
|
|
}
|
|
}
|
|
|
|
/deep/ .el-input__prefix {
|
|
left: 10px;
|
|
font-size: 16px;
|
|
color: #909399;
|
|
}
|
|
}
|
|
}
|
|
|
|
.mode-switch-wrapper {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
padding: 0 16px;
|
|
height: 42px;
|
|
//background: #f5f7fa;
|
|
border-radius: 4px;
|
|
|
|
//.mode-switch {
|
|
// /deep/ .el-switch__core {
|
|
// width: 44px !important;
|
|
// height: 22px;
|
|
// border-radius: 11px;
|
|
//
|
|
// &::after {
|
|
// width: 18px;
|
|
// height: 18px;
|
|
// top: 1px;
|
|
// left: 1px;
|
|
// }
|
|
// }
|
|
//
|
|
// /deep/ .el-switch.is-checked .el-switch__core::after {
|
|
// left: calc(100% - 2px);
|
|
// margin-left: -18px;
|
|
// }
|
|
//}
|
|
|
|
.mode-text {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
color: #67C23A;
|
|
transition: color 0.3s;
|
|
min-width: 40px;
|
|
|
|
&.remove-mode {
|
|
color: #ff4949;
|
|
}
|
|
}
|
|
}
|
|
|
|
.info-badges {
|
|
display: flex;
|
|
gap: 16px;
|
|
|
|
.badge-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 10px 16px;
|
|
background: linear-gradient(135deg, #f5f7fa 0%, #e8eaf0 100%);
|
|
border-radius: 4px;
|
|
border: 1px solid #e4e7ed;
|
|
|
|
i {
|
|
font-size: 18px;
|
|
color: #409EFF;
|
|
}
|
|
|
|
.badge-label {
|
|
font-size: 13px;
|
|
color: #909399;
|
|
}
|
|
|
|
.badge-value {
|
|
font-size: 18px;
|
|
font-weight: 700;
|
|
color: #303133;
|
|
min-width: 32px;
|
|
text-align: right;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.table-wrapper {
|
|
position: relative;
|
|
|
|
.scan-table {
|
|
/deep/ .el-table__header-wrapper {
|
|
th {
|
|
background-color: #f5f7fa;
|
|
color: #606266;
|
|
font-weight: 600;
|
|
font-size: 13px;
|
|
padding: 12px 0;
|
|
}
|
|
}
|
|
|
|
/deep/ .el-table__body-wrapper {
|
|
.el-table__row {
|
|
transition: background-color 0.2s;
|
|
|
|
&:hover {
|
|
background-color: #f5f7fa;
|
|
}
|
|
|
|
td {
|
|
padding: 10px 0;
|
|
font-size: 13px;
|
|
}
|
|
}
|
|
}
|
|
|
|
/deep/ .el-table--striped .el-table__body tr.el-table__row--striped td {
|
|
background-color: #fafafa;
|
|
}
|
|
}
|
|
|
|
.empty-state {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
text-align: center;
|
|
color: #909399;
|
|
|
|
i {
|
|
font-size: 64px;
|
|
color: #dcdfe6;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
p {
|
|
font-size: 14px;
|
|
margin: 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.dialog-footer-custom {
|
|
display: flex;
|
|
justify-content: center;
|
|
gap: 12px;
|
|
|
|
.el-button {
|
|
min-width: 100px;
|
|
height: 38px;
|
|
font-size: 14px;
|
|
border-radius: 4px;
|
|
transition: all 0.3s;
|
|
|
|
&.el-button--success {
|
|
background: #67C23A;
|
|
border-color: #67C23A;
|
|
|
|
&:hover {
|
|
background: #85ce61;
|
|
border-color: #85ce61;
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(103, 194, 58, 0.3);
|
|
}
|
|
|
|
&:active {
|
|
transform: translateY(0);
|
|
}
|
|
|
|
&.is-disabled {
|
|
background: #b3d8a1;
|
|
border-color: #b3d8a1;
|
|
transform: none;
|
|
box-shadow: none;
|
|
}
|
|
}
|
|
|
|
&:not(.el-button--success) {
|
|
&:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
&:active {
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|