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.
 
 
 
 
 

1460 lines
47 KiB

<template>
<div class="customer-css">
<!-- 查询条件 -->
<el-form :inline="true" label-position="top" class="search-form-inline">
<div class="search-row">
<el-form-item label="供应商编码" class="search-item">
<el-input v-model="searchData.supplierNo" style="width: 120px" @keyup.enter.native="getMainData"/>
</el-form-item>
<el-form-item label="供应商名称" class="search-item">
<el-input v-model="searchData.supplierName" style="width: 200px" @keyup.enter.native="getMainData"/>
</el-form-item>
<el-form-item label="申请日期" class="search-item">
<div class="date-range">
<el-date-picker v-model="searchData.requestDateStart" type="date" value-format="yyyy-MM-dd" placeholder="开始" style="width: 100px"/>
<span class="split">-</span>
<el-date-picker v-model="searchData.requestDateEnd" type="date" value-format="yyyy-MM-dd" placeholder="结束" style="width: 100px"/>
</div>
</el-form-item>
<el-form-item label="状态" class="search-item">
<el-select v-model="searchData.status" clearable placeholder="全部" style="width: 100%">
<el-option label="全部" value="" />
<el-option label="草稿" value="Draft" />
<el-option label="已确认" value="Confirmed" />
<el-option label="已审核" value="Audited" />
<el-option label="已排程" value="Scheduled" />
<el-option label="已验货" value="Inspected" />
<el-option label="已取消" value="Cancelled" />
</el-select>
</el-form-item>
</div>
<div class="search-row">
<el-form-item label="申请人员" class="search-item">
<el-input v-model="searchData.createBy" style="width: 120px" @keyup.enter.native="getMainData"/>
</el-form-item>
<el-form-item label="QC人员" class="search-item">
<el-input v-model="searchData.qcOperator" style="width: 200px" @keyup.enter.native="getMainData"/>
</el-form-item>
<el-form-item label="建议验货日期" class="search-item">
<div class="date-range">
<el-date-picker v-model="searchData.needInspectDateStart" type="date" value-format="yyyy-MM-dd" placeholder="开始" style="width: 100px"/>
<span class="split">-</span>
<el-date-picker v-model="searchData.needInspectDateEnd" type="date" value-format="yyyy-MM-dd" placeholder="结束" style="width: 100px"/>
</div>
</el-form-item>
<el-form-item label="申请单号" class="search-item">
<el-input v-model="searchData.requestNo" style="width: 120px" @keyup.enter.native="getMainData"/>
</el-form-item>
<el-form-item label="计划验货日期" class="search-item">
<div class="date-range">
<el-date-picker v-model="searchData.planStartDate" type="date" value-format="yyyy-MM-dd" placeholder="开始" style="width: 100px"/>
<span class="split">-</span>
<el-date-picker v-model="searchData.planEndDate" type="date" value-format="yyyy-MM-dd" placeholder="结束" style="width: 100px"/>
</div>
</el-form-item>
</div>
<div class="search-row">
<el-form-item label=" " class="search-item search-btn-item">
<el-button type="primary" @click="getMainData" style="">查询</el-button>
<el-button type="primary" @click="addInspectionRequest" style="margin-left: 2px">新增</el-button>
<el-button type="primary" @click="importExcel" style="margin-left: 2px">Excel导入</el-button>
<el-button type="primary" @click="exportExcel" style="margin-left: 2px">导出</el-button>
</el-form-item>
</div>
</el-form>
<Chooselist ref="baseList" @getBaseData="getBaseData"></Chooselist>
<el-table
:height="height"
:data="mainDataList"
border
ref="mainTable"
highlight-current-row
@row-click="changeData"
v-loading="dataListLoading"
style="margin-top: 0px; width: 100%;">
<el-table-column
v-for="(item,index) in columnArray1" :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: 100px"/></span>
</template>
</el-table-column>
<el-table-column fixed="right" header-align="center" align="center" width="150" label="操作">
<template slot-scope="scope">
<a v-if="scope.row.status === '草稿' || scope.row.statusDb === 'Draft'"
class="customer-a" @click="confirmInspection(scope.row)">确认 |</a>
<a v-if="(scope.row.status === '草稿' || scope.row.statusDb === 'Draft') ||
(scope.row.status === '已确认' || scope.row.statusDb === 'Confirmed')"
class="customer-a" @click="deleteInspectionRequest(scope.row)">删除</a>
<span v-else class="customer-a" style="color: #909399; cursor: default;">{{ scope.row.status }}</span>
</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-tabs v-model="activeTab" style="margin-top: 0px; width: 99%;" @tab-click="handleTabClick" class="customer-tab" type="border-card">
<!-- 基本信息 -->
<el-tab-pane label="基本信息" name="base">
<inspection-request-detail :detail-data="currentRow" @update-success="getMainData"/>
</el-tab-pane>
<!-- 验货明细 -->
<el-tab-pane label="验货明细" name="detail">
<inspection-request-detail-tab ref="inspectionDetailTab" :detail-data="currentRow" :table-height="detailHeight" />
</el-tab-pane>
<!-- 验货关联PO明细 -->
<el-tab-pane label="验货关联PO明细" name="poDetail">
<inspection-request-po-detail-tab ref="poDetailTab" :detail-data="currentRow" :table-height="detailHeight" />
</el-tab-pane>
<!-- 验货结果 -->
<el-tab-pane label="验货结果" name="result">
<inspection-result-tab ref="resultTab" :detail-data="currentRow" :table-height="detailHeight" />
</el-tab-pane>
<!-- 费用明细 -->
<el-tab-pane label="费用明细" name="fee">
<inspection-request-fee-tab ref="feeTab" :detail-data="currentRow" :table-height="detailHeight" />
</el-tab-pane>
<!-- 附件管理 -->
<el-tab-pane label="附件管理" name="attachment">
<inspection-request-attachment-tab ref="attachmentTab" :detail-data="currentRow" :table-height="detailHeight" />
</el-tab-pane>
</el-tabs>
<!-- 新增弹窗 -->
<el-dialog
title="新增验货申请"
:visible.sync="addDialogVisible"
width="65%"
top="5vh"
:close-on-click-modal="false"
@close="handleCloseAddDialog">
<el-form :model="addFormData" :rules="addRules" ref="addFormData" label-width="90px" size="mini" class="add-dialog-form">
<div class="form-section">
<el-row :gutter="10">
<el-col :span="6">
<el-form-item label="申请单号" prop="requestNo">
<el-input v-model="addFormData.requestNo" placeholder="自动生成" disabled size="mini"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="申请日期" prop="requestDate">
<el-date-picker
v-model="addFormData.requestDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择日期"
size="mini"
style="width: 100%">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label=" " >
<div style="height: 28px;"></div>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="6">
<el-form-item label="供应商编码" prop="supplierNo">
<el-input v-model="addFormData.supplierNo" placeholder="请选择" readonly @click.native="selectSupplier" size="mini">
<i slot="suffix" class="el-icon-search" style="cursor: pointer;"></i>
</el-input>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="供应商名称" prop="supplierName">
<el-input v-model="addFormData.supplierName" disabled size="mini"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label=" " >
<div style="height: 28px;"></div>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="6">
<el-form-item label="建议验货日期" prop="needInspectDate">
<el-date-picker
v-model="addFormData.needInspectDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择日期"
size="mini"
style="width: 100%">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="验货地址" prop="inspectAddress">
<el-input v-model="addFormData.inspectAddress" placeholder="请输入验货地址" size="mini"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="联系人" prop="contact">
<el-input v-model="addFormData.contact" placeholder="请输入联系人及电话" size="mini"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label=" " >
<div style="height: 28px;"></div>
</el-form-item>
</el-col>
</el-row>
</div>
<!-- 步骤2批量选择PO -->
<div class="po-section">
<div class="section-title">批量选择PO</div>
<el-table
:data="poList"
border
size="small"
table-layout="fixed"
height="400px"
style="width: 100%; margin-top: 10px;"
@selection-change="handleSelectionChange"
:row-class-name="tableRowClassName">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column prop="orderRef1" label="PO号" header-align="center" align="center" width="120"/>
<el-table-column prop="orderRef2" label="PO行号" header-align="center" align="center" width="60"/>
<el-table-column prop="partNo" label="产品编码" header-align="center" align="left" min-width="100" show-overflow-tooltip/>
<el-table-column prop="partDesc" label="产品名称" header-align="center" align="left" min-width="150" show-overflow-tooltip/>
<el-table-column prop="qty" label="订单数量" header-align="center" align="right" width="80"/>
<el-table-column prop="waitInspectQty" label="未验货数量" header-align="center" align="right" width="80"/>
<el-table-column prop="shipMethod" label="运输方式" header-align="center" align="center" width="100">
<template slot-scope="scope">
<el-select v-model="scope.row.shipMethod" placeholder="请选择" size="mini" style="width: 100%; box-sizing: border-box;">
<el-option label="空运" value="空运"></el-option>
<el-option label="海运" value="海运"></el-option>
<el-option label="陆运" value="陆运"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column
prop="crd"
label="CRD日期"
header-align="center"
align="center"
width="160"
>
<template slot-scope="scope">
<el-date-picker
v-model="scope.row.crd"
type="date"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
placeholder="选择日期"
size="mini"
style="width: 100%;"
/>
</template>
</el-table-column>
<el-table-column label="此次验货数量" header-align="center" align="center" width="150">
<template slot-scope="scope">
<el-input-number
v-model="scope.row.inspectQty"
:min="0"
:max="scope.row.waitInspectQty || 999999"
size="mini"
:controls="false"
style="width: 100%; box-sizing: border-box;">
</el-input-number>
</template>
</el-table-column>
</el-table>
</div>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="handleSaveAdd">保存</el-button>
<el-button @click="handleCloseAddDialog">关闭</el-button>
</div>
</el-dialog>
<!-- 导入弹窗 -->
<el-dialog title="验货申请数据导入" :visible.sync="uploadDialogVisible" width="800px">
<!-- 选择文件 -->
<div style="margin-bottom:15px;display:flex;align-items:center">
<span style="margin-right:10px">请选择文件</span>
<el-input v-model="uploadFileName" style="width:400px;margin-right:10px" readonly></el-input>
<el-upload ref="upload" action="/api/inspection/upload"
:show-file-list="false" :on-change="handleFileChange"
:auto-upload="false">
<el-button type="primary">选择文件</el-button>
</el-upload>
<el-button type="success" style="margin-left:10px" @click="previewUpload">上传</el-button>
<el-button type="primary" @click="downloadTemplate" style="margin-left:10px">
<i class="el-icon-download"></i> 下载模板
</el-button>
</div>
<!-- 预览表格 -->
<!-- 预览表格 -->
<el-table
:data="uploadPreviewList"
border
height="250"
style="width:100%;margin-top:10px"
>
<el-table-column prop="poNo" label="PO号" align="center" width="auto"></el-table-column>
<el-table-column prop="poItemNo" label="PO行号" align="center" width="auto"></el-table-column>
<el-table-column prop="partNo" label="产品编码" align="center" width="auto"></el-table-column>
<el-table-column prop="qty" label="验货数量" align="center" width="auto"></el-table-column>
<el-table-column prop="shipMethod" label="运输方式" align="center" width="auto"></el-table-column>
<el-table-column prop="crd" label="CRD" align="center" width="auto"></el-table-column>
<el-table-column prop="suggestInspectDate" label="建议验货日期" align="center" width="auto"></el-table-column>
</el-table>
<!-- 按钮 -->
<div style="margin-top:20px;text-align:center">
<el-button type="primary" @click="confirmUpload">保存</el-button>
<el-button @click="uploadDialogVisible=false" style="margin-right:30px">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { searchInspectionRequestHeaderList, queryPoPage, saveInspectionRequest, deleteInspectionRequest, confirmInspectionRequest, downloadTemplate, previewUpload, batchSave } from '@/api/inspection/inspectionRequestHeader.js'
import { searchSrmSupplierList } from '@/api/srm/srmSupplier.js'
import Chooselist from '@/views/modules/common/Chooselist_eam'
import ComInspectionRequestDetail from './com_inspectionRequestDetail.vue'
import ComInspectionRequestDetailTab from './com_inspectionRequestDetailTab.vue'
import ComInspectionRequestPoDetailTab from './com_inspectionRequestPoDetailTab.vue'
import ComInspectionResultTab from './com_inspectionResultTab.vue'
import ComInspectionRequestAttachmentTab from './com_inspectionRequestAttachmentTab.vue'
import ComInspectionRequestFeeTab from './com_inspectionRequestFeeTab.vue'
import excel from '@/utils/excel-util.js'
export default {
components: {
Chooselist,
InspectionRequestDetail: ComInspectionRequestDetail,
InspectionRequestDetailTab: ComInspectionRequestDetailTab,
InspectionRequestPoDetailTab: ComInspectionRequestPoDetailTab,
InspectionResultTab: ComInspectionResultTab,
InspectionRequestAttachmentTab: ComInspectionRequestAttachmentTab,
InspectionRequestFeeTab: ComInspectionRequestFeeTab
},
data () {
return {
functionId: this.$route.meta.menuId,
height: 400,
detailHeight: 400,
currentRow: {},
tagNo: '',
searchType: '',
activeTab: 'base',
// 新增弹窗相关数据
addDialogVisible: false,
addFormData: {
requestNo: '',
requestDate: '',
supplierNo: '',
supplierName: '',
inspectAddress: '',
contact: '',
needInspectDate: ''
},
addRules: {
requestDate: [
{ required: true, message: '请选择申请日期', trigger: 'change' }
],
supplierNo: [
{ required: true, message: '请选择供应商', trigger: 'change' }
]
},
poList: [],
selectedPoList: [],
// 上传相关
uploadDialogVisible: false,
uploadFileName: '',
uploadFile: null,
uploadPreviewList: [],
searchData: {
requestNo: '',
supplierNo: '',
supplierName: '',
status: '',
qcOperator: '',
createBy: '',
requestDateStart: '',
requestDateEnd: '',
needInspectDateStart: '',
needInspectDateEnd: '',
planStartDate: '',
planEndDate: '',
page: 1,
limit: 50
},
pageIndex: 1,
pageSize: 50,
totalPage: 0,
mainDataList: [],
dataListLoading: false,
columnArray1: [
{
userId: this.$store.state.user.name,
functionId: this.functionId,
serialNumber: 'InspectionTable1RequestNo',
tableId: 'InspectionTable1',
tableName: '检验申请单',
columnProp: 'requestNo',
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: 'InspectionTable1RequestDate',
tableId: 'InspectionTable1',
tableName: '检验申请单',
columnProp: 'requestDate',
headerAlign: 'center',
align: 'center',
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: 'InspectionTable1SupplierNo',
tableId: 'InspectionTable1',
tableName: '检验申请单',
columnProp: 'supplierNo',
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: 'InspectionTable1SupplierName',
tableId: 'InspectionTable1',
tableName: '检验申请单',
columnProp: 'supplierName',
headerAlign: 'center',
align: 'left',
columnLabel: '供应商名称',
columnWidth: '150',
columnHidden: false,
columnImage: false,
columnSortable: false,
sortLv: 0,
status: true,
fixed: false
},
{
userId: this.$store.state.user.name,
functionId: this.functionId,
serialNumber: 'InspectionTable1CreateBy',
tableId: 'InspectionTable1',
tableName: '检验申请单',
columnProp: 'createBy',
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: 'InspectionTable1NeedInspectDate',
tableId: 'InspectionTable1',
tableName: '检验申请单',
columnProp: 'needInspectDate',
headerAlign: 'center',
align: 'center',
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: 'InspectionTable1InspectAddress',
tableId: 'InspectionTable1',
tableName: '检验申请单',
columnProp: 'inspectAddress',
headerAlign: 'center',
align: 'left',
columnLabel: '验货地址',
columnWidth: '200',
columnHidden: false,
columnImage: false,
columnSortable: false,
sortLv: 0,
status: true,
fixed: false
},
{
userId: this.$store.state.user.name,
functionId: this.functionId,
serialNumber: 'InspectionTable1Contact',
tableId: 'InspectionTable1',
tableName: '检验申请单',
columnProp: 'inspectContract',
headerAlign: 'center',
align: 'left',
columnLabel: '联系人',
columnWidth: '150',
columnHidden: false,
columnImage: false,
columnSortable: false,
sortLv: 0,
status: true,
fixed: false
},
{
userId: this.$store.state.user.name,
functionId: this.functionId,
serialNumber: 'InspectionTable1Remark',
tableId: 'InspectionTable1',
tableName: '检验申请单',
columnProp: 'remark',
headerAlign: 'center',
align: 'left',
columnLabel: '备注',
columnWidth: '150',
columnHidden: false,
columnImage: false,
columnSortable: false,
sortLv: 0,
status: true,
fixed: false
},
{
userId: this.$store.state.user.name,
functionId: this.functionId,
serialNumber: 'InspectionTable1Status',
tableId: 'InspectionTable1',
tableName: '检验申请单',
columnProp: 'status',
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: 'InspectionTable1PlanStartDate',
tableId: 'InspectionTable1',
tableName: '检验申请单',
columnProp: 'planStartDate',
headerAlign: 'center',
align: 'center',
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: 'InspectionTable1QcOperator',
tableId: 'InspectionTable1',
tableName: '检验申请单',
columnProp: 'qcOperator',
headerAlign: 'center',
align: 'left',
columnLabel: 'QC人员',
columnWidth: '100',
columnHidden: false,
columnImage: false,
columnSortable: false,
sortLv: 0,
status: true,
fixed: false
}
]
}
},
mounted () {
this.$nextTick(() => {
this.height = (window.innerHeight - 220) / 2
this.detailHeight = (window.innerHeight - 220) / 2
this.getMainData()
})
},
methods: {
// 获取基础数据列表
getBaseList (val, type) {
this.tagNo = val
this.searchType = type || ''
this.$nextTick(() => {
let strVal = ''
let conSql = ''
if (val === 1100) {
strVal = this.searchData.supplierNo || ''
conSql = " and site = '" + this.$store.state.user.site + "'"
}
if (val === 2016) {
strVal = type === 'createBy' ? (this.searchData.createBy || '') : (this.searchData.qcOperator || '')
}
this.$refs.baseList.init(val, strVal, conSql)
})
},
/* 列表方法的回调 */
getBaseData (val) {
if (this.tagNo === 1100) {
// 判断是搜索条件还是新增弹窗
if (this.addDialogVisible) {
// 新增弹窗:使用下划线命名的字段,使用$set确保响应式
this.$set(this.addFormData, 'supplierNo', val.supplier_no || '')
this.$set(this.addFormData, 'supplierName', val.supplier_name || '')
this.loadPoList()
// 查询供应商详情获取联系人和地址
if (val.supplier_no) {
// 使用 searchSrmSupplierList 接口查询供应商(精确匹配)
searchSrmSupplierList({
page: 1,
limit: 1,
supplierNo: val.supplier_no // 根据实际后端字段名调整
}).then(({ data }) => {
if (data.code === 0 && data.page && data.page.list && data.page.list.length > 0) {
const supplier = data.page.list[0];
this.$set(this.addFormData, 'inspectAddress', supplier.Address || supplier.address || '');
this.$set(this.addFormData, 'contact', supplier.Contact || supplier.contact || '');
}
}).catch(() => {});
}
} else {
// 搜索条件:使用下划线命名的字段
this.searchData.supplierNo = val.supplier_no || ''
this.searchData.supplierName = val.supplier_name || ''
}
}
if (this.tagNo === 2016) {
if (this.searchType === 'createBy') {
this.searchData.createBy = val.username || val.user_display || val.name
} else if (this.searchType === 'qcOperator') {
this.searchData.qcOperator = val.username || val.user_display || val.name
}
}
},
// 查询数据
getMainData () {
this.searchData.limit = this.pageSize
this.searchData.page = this.pageIndex
this.dataListLoading = true
searchInspectionRequestHeaderList(this.searchData).then(({ data }) => {
if (data.code === 0) {
this.mainDataList = data.page.list
// 调试信息:打印第一条数据的 hasModifiedQty 字段
if (this.mainDataList.length > 0) {
console.log('=== 主表格数据调试 ===')
console.log('第一条数据:', this.mainDataList[0])
console.log('hasModifiedQty 值:', this.mainDataList[0].hasModifiedQty)
console.log('=====================')
}
this.pageIndex = data.page.currPage
this.pageSize = data.page.pageSize
this.totalPage = data.page.totalCount
this.$nextTick(() => {
if (this.$refs.mainTable) {
this.$refs.mainTable.clearSelection()
}
})
// 判断是否有数据
if (this.mainDataList.length > 0) {
this.$refs.mainTable.setCurrentRow(this.mainDataList[0])
this.changeData(this.mainDataList[0])
} else {
this.changeData(null)
}
}
this.dataListLoading = false
}).catch(() => {
this.dataListLoading = false
})
},
// 每页数
sizeChangeHandle (val) {
this.pageSize = val
this.pageIndex = 1
this.getMainData()
},
// 当前页
currentChangeHandle (val) {
this.pageIndex = val
this.getMainData()
},
// 页签点击事件
handleTabClick (tab) {
// 每次点击页签都触发对应页签的查询
if (tab.name === 'detail') {
// 验货明细页签 - 组件内部 watch 会自动触发
this.$nextTick(() => {
if (this.$refs.inspectionDetailTab) {
this.$refs.inspectionDetailTab.loadDetailList()
}
})
} else if (tab.name === 'poDetail') {
// 验货关联PO明细页签
this.$nextTick(() => {
if (this.$refs.poDetailTab) {
this.$refs.poDetailTab.loadDetailList()
}
})
} else if (tab.name === 'result') {
// 验货结果页签
this.$nextTick(() => {
if (this.$refs.resultTab) {
this.$refs.resultTab.loadDetailList()
}
})
} else if (tab.name === 'attachment') {
// 附件管理页签 - 组件内部 watch 会自动触发
this.$nextTick(() => {
if (this.$refs.attachmentTab) {
this.$refs.attachmentTab.loadAttachmentTypeList()
}
})
} else if (tab.name === 'fee') {
// 费用明细页签 - 组件内部 watch 会自动触发
this.$nextTick(() => {
if (this.$refs.feeTab) {
this.$refs.feeTab.loadFeeDetailList()
}
})
}
},
// 行点击事件
changeData (row) {
this.currentRow = row ? JSON.parse(JSON.stringify(row)) : {}
},
// 新增验货申请
addInspectionRequest () {
this.addDialogVisible = true
this.resetAddForm()
},
// 关闭新增弹窗
handleCloseAddDialog () {
this.addDialogVisible = false
this.resetAddForm()
},
// 重置表单
resetAddForm () {
const today = new Date()
const year = today.getFullYear()
const month = String(today.getMonth() + 1).padStart(2, '0')
const day = String(today.getDate()).padStart(2, '0')
const todayStr = `${year}-${month}-${day}`
this.addFormData = {
requestNo: '',
requestDate: todayStr,
supplierNo: '',
supplierName: '',
inspectAddress: '',
contact: '',
needInspectDate: ''
}
this.poList = []
this.selectedPoList = []
if (this.$refs.addFormData) {
this.$refs.addFormData.clearValidate()
}
},
// 选择供应商
selectSupplier () {
this.tagNo = 1100 // 设置tagNo,确保回调时能正确识别
this.$nextTick(() => {
const conSql = " and site = '" + this.$store.state.user.site + "'"
this.$refs.baseList.init(1100, this.addFormData.supplierNo || '', conSql)
})
},
// 加载PO列表(选择供应商后调用)
loadPoList () {
if (!this.addFormData.supplierNo) {
this.$message.warning('请先选择供应商')
return
}
const params = {
supplierNo: this.addFormData.supplierNo,
site: this.$store.state.user.site,
page: 1,
limit: 1000
}
queryPoPage(params).then(({ data }) => {
if (data.code === 0 && data.page) {
this.poList = data.page.list.map(item => ({
...item,
inspectQty: item.waitInspectQty || 0, // 默认值为未验货数量
shipMethod: item.shipMethod || '',// 运输方式
crd: item.crd ? item.crd.split(' ')[0] : ''
}))
} else {
this.poList = []
this.$message.info('该供应商暂无可申请验货的PO')
}
}).catch(() => {
this.poList = []
this.$message.error('加载PO列表失败')
})
},
// 表格选择变化
handleSelectionChange (selection) {
this.selectedPoList = selection
},
// 验货数量变化
handleInspectQtyChange (row, value) {
console.log('验货数量变化:', row.orderRef1, value)
// 确保数据被正确更新
this.$set(row, 'inspectQty', value)
},
// 表格行样式(验货数量与原始值不同时标红)
tableRowClassName ({ row }) {
const inspectQty = Number(row.inspectQty || 0)
const waitInspectQty = Number(row.waitInspectQty || 0)
return inspectQty !== waitInspectQty
? 'modified-row'
: ''
},
// 保存
handleSaveAdd () {
console.log('开始保存,当前选择的PO列表:', this.selectedPoList)
console.log('表单数据:', this.addFormData)
this.$refs.addFormData.validate((valid) => {
console.log('表单验证结果:', valid)
if (valid) {
if (this.selectedPoList.length === 0) {
this.$message.warning('请至少选择一条PO明细')
return
}
// 检查验货数量
const hasInvalidQty = this.selectedPoList.some(item => !item.inspectQty || item.inspectQty <= 0)
if (hasInvalidQty) {
this.$message.warning('请填写有效的验货数量')
return
}
// 构建提交数据
const submitData = {
requestDate: this.addFormData.requestDate,
needInspectDate: this.addFormData.needInspectDate,
supplierNo: this.addFormData.supplierNo,
inspectAddress: this.addFormData.inspectAddress,
inspectContract: this.addFormData.contact,
remark: '',
items: this.selectedPoList.map(item => ({
orderNo: item.orderNo || item.order_ref1 || item.orderRef1,
itemNo: item.itemNo || item.item_no || item.order_ref2 || item.orderRef2,
partNo: item.partNo,
orderRef1: item.orderRef1,
orderRef2: item.orderRef2,
qty: item.inspectQty,
shipMethod: item.shipMethod,
crd: item.crd
}))
}
console.log('提交的数据:', submitData)
saveInspectionRequest(submitData).then(({ data }) => {
console.log('保存接口返回:', data)
if (data.code === 0) {
this.$message.success('保存成功')
this.handleCloseAddDialog()
this.getMainData()
} else {
this.$message.error(data.msg || '保存失败')
}
}).catch((error) => {
console.error('保存接口错误:', error)
this.$message.error('保存失败,请稍后重试')
})
} else {
console.log('表单验证失败')
this.$message.warning('请填写完整的表单信息')
}
})
},
// Excel导入
importExcel () {
this.uploadDialogVisible = true
this.uploadFileName = ''
this.uploadFile = null
this.uploadPreviewList = []
},
// 文件选择变化
handleFileChange (file) {
this.uploadFile = file.raw
this.uploadFileName = file.name
},
// 预览上传数据
previewUpload () {
if (!this.uploadFile) {
this.$message.warning('请先选择文件')
return
}
const formData = new FormData()
formData.append('file', this.uploadFile)
// 调用后端预览接口
previewUpload(this.uploadFile).then(({ data }) => {
if (data && data.code === 0) {
this.uploadPreviewList = data.data || []
this.$message.success('文件解析成功,请确认数据后点击保存')
} else {
this.$message.error(data.msg || '文件解析失败')
}
}).catch((error) => {
console.error('文件解析失败:', error)
const errorMsg = (error.response && error.response.data && error.response.data.msg) || error.message || '未知错误'
this.$message.error('文件解析失败: ' + errorMsg)
})
},
// 确认上传
confirmUpload () {
if (this.uploadPreviewList.length === 0) {
this.$message.warning('没有可保存的数据')
return
}
this.$confirm(`确认保存 ${this.uploadPreviewList.length} 条数据吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 调用后端保存接口
batchSave(this.uploadFile).then(({ data }) => {
if (data && data.code === 0) {
this.$message.success('数据保存成功')
this.uploadDialogVisible = false
this.getMainData()
} else {
this.$message.error(data.msg || '数据保存失败')
}
}).catch((error) => {
console.error('数据保存失败:', error)
const errorMsg = (error.response && error.response.data && error.response.data.msg) || error.message || '未知错误'
this.$message.error('数据保存失败: ' + errorMsg)
})
}).catch(() => {})
},
// 下载模板
downloadTemplate () {
const loading = this.$loading({
lock: true,
text: '正在下载模板...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
this.$http({
url: this.$http.adornUrl('/inspection/downloadTemplate'),
method: 'post',
responseType: 'blob'
}).then(response => {
loading.close()
// 创建下载文件
const blob = new Blob([response.data], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
})
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = '验货申请导入模板.xlsx'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
this.$message.success('模板下载成功')
}).catch(error => {
loading.close()
console.error('模板下载失败:', error)
this.$message.error('模板下载失败,请联系管理员')
})
},
// 导出
exportExcel () {
console.log('开始导出...')
// 生成文件名(使用原生 Date)
const now = new Date()
const year = now.getFullYear()
const month = String(now.getMonth() + 1).padStart(2, '0')
const day = String(now.getDate()).padStart(2, '0')
const hour = String(now.getHours()).padStart(2, '0')
const minute = String(now.getMinutes()).padStart(2, '0')
const second = String(now.getSeconds()).padStart(2, '0')
const exportName = `检验申请单${year}${month}${day}${hour}${minute}${second}`
console.log('导出参数:', this.searchData)
// 获取当前查询条件
const exportParams = {
...this.searchData,
limit: -1, // 导出全部数据
page: 1
}
try {
excel.exportTable({
url: '/inspection/searchInspectionRequestHeaderList',
columnMapping: this.columnArray1, // 使用表格列配置
mergeSetting: [], // 不需要合并
params: exportParams,
fileName: exportName + '.xlsx',
rowFetcher: res => {
console.log('导出数据响应:', res)
return res.data.page.list
}, // 从响应中提取数据列表
columnFormatter: [], // 不需要格式化
dropColumns: [] // 不需要剔除的列
})
console.log('导出请求已发送')
} catch (error) {
console.error('导出失败:', error)
this.$message.error('导出失败: ' + error.message)
}
},
// 确认验货申请
confirmInspection (row) {
this.$confirm('确定要确认该验货申请吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
confirmInspectionRequest(row.requestNo).then(({ data }) => {
if (data.code === 0) {
this.$message.success('确认成功')
this.getMainData()
} else {
this.$message.error(data.msg || '确认失败')
}
}).catch((error) => {
console.error('确认接口错误:', error)
this.$message.error('确认失败,请稍后重试')
})
}).catch(() => {
this.$message.info('已取消确认')
})
},
// 删除验货申请
deleteInspectionRequest (row) {
this.$confirm('确定要删除该验货申请吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteInspectionRequest(row.requestNo).then(({ data }) => {
if (data.code === 0) {
this.$message.success('删除成功')
this.getMainData()
} else {
this.$message.error(data.msg || '删除失败')
}
}).catch((error) => {
console.error('删除接口错误:', error)
this.$message.error('删除失败,请稍后重试')
})
}).catch(() => {
this.$message.info('已取消删除')
})
}
},
created () {
this.getMainData()
}
}
</script>
<style scoped lang="scss">
.search-form-inline {
background: #fff;
padding: 0;
margin-bottom: 0;
}
.search-row {
display: flex;
align-items: flex-end;
flex-wrap: wrap;
gap: 0;
margin-bottom: 0;
}
.search-item {
flex: none;
margin-bottom: 0;
margin-right: 12px;
}
.search-item /deep/ .el-form-item__label {
font-size: 14px;
padding-bottom: 0;
line-height: 1.2;
}
.search-btn-item {
flex: none;
margin-bottom: 0;
margin-right: 0;
}
.search-item /deep/ .el-form-item__label {
font-size: 13px;
color: #606266;
padding-bottom: 5px;
line-height: 1;
height: auto;
}
.search-item /deep/ .el-form-item__content {
line-height: normal;
}
.date-range {
display: flex;
align-items: center;
}
.split {
padding: 0 6px;
color: #606266;
font-size: 13px;
}
/deep/ .customer-tab .el-tabs__content {
padding: 5px !important;
}
.form-section {
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px solid #ebeef5;
padding: 5px 10px;
}
.add-dialog-form /deep/ .el-form-item {
margin-bottom: 10px;
}
.add-dialog-form /deep/ .el-form-item__label {
text-align: left;
float: none;
display: block;
padding: 0 0 5px 0;
line-height: 1;
font-size: 13px;
}
.add-dialog-form /deep/ .el-form-item__content {
margin-left: 0 !important;
}
.po-section {
.section-title {
font-size: 14px;
font-weight: bold;
color: #303133;
margin-bottom: 8px;
}
.section-desc {
font-size: 12px;
color: #909399;
margin-bottom: 10px;
}
}
.dialog-footer {
text-align: center;
}
/deep/ .el-input-number .el-input__inner {
text-align: right !important;
padding-right: 32px !important;
padding-left: 8px !important;
box-sizing: border-box;
}
/deep/ .el-input .el-input--mini {
line-height: 20px;
}
/deep/ .el-input-number .el-input--mini {
line-height: 20px;
}
/* PO表格输入控件防遮挡 */
.po-section {
/deep/ .el-table .cell {
overflow: visible !important;
padding-left: 4px;
padding-right: 4px;
}
/deep/ .el-input,
/deep/ .el-select {
width: 100% !important;
}
/deep/ .el-input-number .el-input__inner {
padding-left: 8px !important;
padding-right: 35px !important;
text-align: right;
}
/deep/ .el-input-number {
width: 120px !important;
min-width: 120px !important;
}
/deep/ .el-select .el-input__inner {
padding-right: 25px !important;
}
}
// 数字输入框按钮样式修复
/deep/ .el-input-number {
position: relative;
.el-input-number__increase,
.el-input-number__decrease {
width: 28px;
height: 50%;
position: absolute;
right: 0;
display: flex;
align-items: center;
justify-content: center;
background-color: #f5f7fa;
border: none;
cursor: pointer;
transition: all 0.2s;
font-size: 12px;
&:hover {
background-color: #ecf5ff;
color: #409eff;
}
&:active {
background-color: #d9e1f0;
}
}
.el-input-number__increase {
top: 0;
bottom: auto;
border-bottom: 1px solid #dcdfe6;
border-top-right-radius: 4px;
}
.el-input-number__decrease {
top: auto;
bottom: 0;
border-bottom-right-radius: 4px;
}
// 确保输入框右边留出按钮空间
.el-input__inner {
padding-right: 32px !important;
}
}
// 数字输入框按钮样式修复
/deep/ .el-input-number {
position: relative;
.el-input-number__increase,
.el-input-number__decrease {
width: 28px;
height: 50%;
position: absolute;
right: 0;
display: flex;
align-items: center;
justify-content: center;
background-color: #f5f7fa;
border: none;
cursor: pointer;
transition: all 0.2s;
font-size: 12px;
&:hover {
background-color: #ecf5ff;
color: #409eff;
}
&:active {
background-color: #d9e1f0;
}
}
.el-input-number__increase {
top: 0;
bottom: auto;
border-bottom: 1px solid #dcdfe6;
border-top-right-radius: 4px;
}
.el-input-number__decrease {
top: auto;
bottom: 0;
border-bottom-right-radius: 4px;
}
.el-input__inner {
padding-right: 32px !important;
}
}
/deep/ .el-input-number--mini {
.el-input-number__increase,
.el-input-number__decrease {
width: 24px;
font-size: 10px;
}
.el-input__inner {
padding-right: 28px !important;
}
}
// PO表格行样式 - 验货数量修改后标红
.po-section /deep/ .el-table__row.modified-row {
background-color: #fef0f0 !important;
&:hover > td {
background-color: #fde2e2 !important;
}
}
.po-section {
/deep/ .el-date-editor.el-input,
/deep/ .el-date-editor.el-input__inner {
width: 100%;
}
/deep/ .el-date-editor .el-input__inner {
height: 28px;
line-height: 28px;
padding-left: 10px;
padding-right: 10px;
font-size: 12px;
}
/deep/ .el-date-editor .el-input__prefix {
display: none;
}
/deep/ .el-date-editor .el-input__suffix {
right: 5px;
}
}
</style>