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

<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>