Browse Source

feat(inspection): 新增验货申请审核页面并完善相关功能

- 添加 inspectionRequestAudit.vue 页面实现验货申请审核功能
- 更新 com_inspectionRequestDetailTab.vue 和
  com_inspectionRequestPoDetailTab.vue 中的数据获取逻辑以支持分页结构
- 在 api/inspection/inspectionRequestHeader.js 中新增删除、确认、审核等接口
- 在 inspectionRequestList.vue 中实现数据导入导出功能
- 添加 Excel 模板下载和数据预览上传功能
- 实现表格行样式标记,对修改过的验货数量进行标红显示
- 优化状态选项值从大写改为首字母大写格式以保持一致性
- 增加确认和删除操作的 API 调用及错误处理逻辑
master
qiankanghui 3 days ago
parent
commit
ef6f0fe57b
  1. 26
      src/api/inspection/inspectionRequestHeader.js
  2. 2
      src/views/modules/inspection/com_inspectionRequestDetailTab.vue
  3. 2
      src/views/modules/inspection/com_inspectionRequestPoDetailTab.vue
  4. 653
      src/views/modules/inspection/inspectionRequestAudit.vue
  5. 289
      src/views/modules/inspection/inspectionRequestList.vue

26
src/api/inspection/inspectionRequestHeader.js

@ -13,3 +13,29 @@ export const queryPoPage = (data) => createAPI(`/inspection/queryPoPage`, 'post'
// 保存验货申请 // 保存验货申请
export const saveInspectionRequest = (data) => createAPI(`/inspection/save`, 'post', data) export const saveInspectionRequest = (data) => createAPI(`/inspection/save`, 'post', data)
// 删除验货申请
export const deleteInspectionRequest = (requestNo) => createAPI(`/inspection/delete/${requestNo}`, 'post')
// 确认验货申请
export const confirmInspectionRequest = (requestNo) => createAPI(`/inspection/confirm/${requestNo}`, 'post')
// 下载验货申请导入模板
export const downloadTemplate = () => createAPI(`/inspection/downloadTemplate`, 'get', {}, { responseType: 'blob' })
// 预览上传的Excel数据
export const previewUpload = (file) => {
const formData = new FormData()
formData.append('file', file)
return createAPI(`/inspection/previewUpload`, 'post', formData)
}
// 批量保存上传的数据
export const batchSave = (file) => {
const formData = new FormData()
formData.append('file', file)
return createAPI(`/inspection/batchSave`, 'post', formData)
}
// 审核验货申请
export const auditInspectionRequest = (requestNo) => createAPI(`/inspection/audit/${requestNo}`, 'post')

2
src/views/modules/inspection/com_inspectionRequestDetailTab.vue

@ -71,7 +71,7 @@ export default {
site: this.detailData.site site: this.detailData.site
}).then(({ data }) => { }).then(({ data }) => {
if (data.code === 0) { if (data.code === 0) {
const list = data.list || []
const list = (data.page && data.page.list) || []
// //
this.detailList = list.map(item => { this.detailList = list.map(item => {
return { return {

2
src/views/modules/inspection/com_inspectionRequestPoDetailTab.vue

@ -71,7 +71,7 @@ export default {
site: this.detailData.site site: this.detailData.site
}).then(({ data }) => { }).then(({ data }) => {
if (data.code === 0) { if (data.code === 0) {
this.detailList = data.list || []
this.detailList = (data.page && data.page.list) || []
} }
this.loading = false this.loading = false
}).catch(() => { }).catch(() => {

653
src/views/modules/inspection/inspectionRequestAudit.vue

@ -0,0 +1,653 @@
<template>
<div class="customer-css">
<!-- 查询条件 -->
<el-form :inline="true" label-width="90px" class="search-form-inline">
<!-- 第一行 -->
<div class="search-row">
<el-form-item>
<span style="cursor: pointer" slot="label" @click="getBaseList(1100)"><a href="#">供应商编码</a></span>
<el-input v-model="searchData.supplierNo" class="input-small" @keyup.enter.native="getMainData"/>
</el-form-item>
<el-form-item label="供应商名称">
<el-input v-model="searchData.supplierName" class="input-small" @keyup.enter.native="getMainData"/>
</el-form-item>
<el-form-item label="申请日期">
<div class="date-range">
<el-date-picker v-model="searchData.requestDateStart" type="date" value-format="yyyy-MM-dd" placeholder="开始" class="date-small"/>
<span class="split">-</span>
<el-date-picker v-model="searchData.requestDateEnd" type="date" value-format="yyyy-MM-dd" placeholder="结束" class="date-small"/>
</div>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="searchData.status" clearable class="input-mini" placeholder="全部" disabled>
<el-option label="已确认" value="Confirmed" />
</el-select>
</el-form-item>
</div>
<!-- 第二行 -->
<div class="search-row">
<el-form-item label="申请单号">
<el-input v-model="searchData.requestNo" class="input-small" @keyup.enter.native="getMainData"/>
</el-form-item>
<el-form-item>
<span style="cursor: pointer" slot="label" @click="getBaseList(2016, 'createBy')"><a href="#">申请人员</a></span>
<el-input v-model="searchData.createBy" class="input-small" @keyup.enter.native="getMainData"/>
</el-form-item>
<el-form-item label="建议验货日期">
<div class="date-range">
<el-date-picker v-model="searchData.needInspectDateStart" type="date" value-format="yyyy-MM-dd" placeholder="开始" class="date-small"/>
<span class="split">-</span>
<el-date-picker v-model="searchData.needInspectDateEnd" type="date" value-format="yyyy-MM-dd" placeholder="结束" class="date-small"/>
</div>
</el-form-item>
</div>
<!-- 按钮 -->
<div class="search-btn-row">
<el-button type="primary" class="customer-bun-min" @click="getMainData">查询</el-button>
</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"
:row-class-name="mainTableRowClassName"
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">
<el-link v-if="scope.row.status === '已确认' || scope.row.statusDb === 'Confirmed'"
style="cursor: pointer; color: #409EFF; margin-right: 10px;"
@click="auditInspection(scope.row)">审核</el-link>
<span v-if="scope.row.status === '已审核' || scope.row.statusDb === 'Audited'"
style="color: #909399;">已审核</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" />
</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-tabs>
</div>
</template>
<script>
import { searchInspectionRequestHeaderList, auditInspectionRequest } from '@/api/inspection/inspectionRequestHeader.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'
export default {
components: {
Chooselist,
InspectionRequestDetail: ComInspectionRequestDetail,
InspectionRequestDetailTab: ComInspectionRequestDetailTab,
InspectionRequestPoDetailTab: ComInspectionRequestPoDetailTab,
InspectionResultTab: ComInspectionResultTab
},
data () {
return {
functionId: this.$route.meta.menuId,
height: 400,
detailHeight: 400,
currentRow: {},
tagNo: '',
searchType: '',
activeTab: 'base',
searchData: {
requestNo: '',
supplierNo: '',
supplierName: '',
status: 'Confirmed', //
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: 'InspectionAuditTable1RequestNo',
tableId: 'InspectionAuditTable1',
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: 'InspectionAuditTable1RequestDate',
tableId: 'InspectionAuditTable1',
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: 'InspectionAuditTable1SupplierNo',
tableId: 'InspectionAuditTable1',
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: 'InspectionAuditTable1SupplierName',
tableId: 'InspectionAuditTable1',
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: 'InspectionAuditTable1CreateBy',
tableId: 'InspectionAuditTable1',
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: 'InspectionAuditTable1NeedInspectDate',
tableId: 'InspectionAuditTable1',
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: 'InspectionAuditTable1InspectAddress',
tableId: 'InspectionAuditTable1',
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: 'InspectionAuditTable1Contact',
tableId: 'InspectionAuditTable1',
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: 'InspectionAuditTable1Remark',
tableId: 'InspectionAuditTable1',
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: 'InspectionAuditTable1Status',
tableId: 'InspectionAuditTable1',
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: 'InspectionAuditTable1PlanStartDate',
tableId: 'InspectionAuditTable1',
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: 'InspectionAuditTable1QcOperator',
tableId: 'InspectionAuditTable1',
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.$refs.baseList.init(val, strVal, conSql)
})
},
/* 列表方法的回调 */
getBaseData (val) {
if (this.tagNo === 1100) {
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
}
}
},
//
getMainData () {
this.searchData.limit = this.pageSize
this.searchData.page = this.pageIndex
this.searchData.status = 'Confirmed' //
this.dataListLoading = true
searchInspectionRequestHeaderList(this.searchData).then(({ data }) => {
if (data.code === 0) {
this.mainDataList = data.page.list
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') {
this.$nextTick(() => {
if (this.$refs.inspectionDetailTab) {
this.$refs.inspectionDetailTab.loadDetailList()
}
})
} else if (tab.name === 'poDetail') {
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()
}
})
}
},
//
changeData (row) {
this.currentRow = row ? JSON.parse(JSON.stringify(row)) : {}
},
//
mainTableRowClassName ({ row }) {
if (row.hasModifiedQty === true ||
row.hasModifiedQty === 'true' ||
row.hasModifiedQty === 'Y' ||
row.hasModifiedQty === 'y' ||
row.hasModifiedQty === 1 ||
row.hasModifiedQty === '1') {
return 'modified-request-row'
}
return ''
},
//
auditInspection (row) {
this.$confirm('确定要审核该验货申请吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
auditInspectionRequest(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 {
padding: 10px 15px 0 0;
background: #fff;
}
.search-row {
display: flex;
align-items: center;
flex-wrap: nowrap;
margin-bottom: 6px;
}
.search-btn-row {
margin-top: 10px;
padding-left: 8px;
}
.input-small {
width: 110px;
}
.input-mini {
width: 90px;
}
.date-small {
width: 130px;
}
.date-range {
display: flex;
align-items: center;
}
.split {
padding: 0 6px;
color: #606266;
font-size: 13px;
}
/deep/ .el-form-item {
margin-right: 18px;
margin-bottom: 6px;
}
/deep/ .el-form-item__label {
font-size: 13px;
color: #606266;
padding-right: 8px;
line-height: 32px;
font-weight: 500;
}
/deep/ .el-form-item__content {
line-height: normal;
}
/deep/ .el-input__inner {
height: 32px;
line-height: 32px;
}
/deep/ .el-date-editor .el-input__inner {
padding-right: 10px;
padding-left: 10px;
}
/deep/ .el-date-editor .el-input__prefix {
display: none;
}
/deep/ .el-date-editor .el-input__suffix {
display: none;
}
/deep/ .customer-tab .el-tabs__content {
padding: 5px !important;
}
// -
/deep/ .el-table__body tr.modified-request-row {
background-color: #fef0f0 !important;
}
/deep/ .el-table__body tr.modified-request-row > td {
background-color: #fef0f0 !important;
color: #f56c6c !important;
}
/deep/ .el-table__body tr.modified-request-row:hover > td {
background-color: #fde2e2 !important;
}
/deep/ .el-table__row.current-row.modified-request-row {
background-color: #fef0f0 !important;
}
/deep/ .el-table__row.current-row.modified-request-row > td {
background-color: #fef0f0 !important;
color: #f56c6c !important;
}
</style>

289
src/views/modules/inspection/inspectionRequestList.vue

@ -23,11 +23,12 @@
<el-form-item label="状态"> <el-form-item label="状态">
<el-select v-model="searchData.status" clearable class="input-mini" placeholder="全部"> <el-select v-model="searchData.status" clearable class="input-mini" placeholder="全部">
<el-option label="全部" value="" /> <el-option label="全部" value="" />
<el-option label="草稿" value="DRAFT" />
<el-option label="已确认" value="CONFIRMED" />
<el-option label="已排程" value="SCHEDULED" />
<el-option label="已验货" value="INSPECTED" />
<el-option label="已取消" value="CANCELLED" />
<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-select>
</el-form-item> </el-form-item>
@ -90,6 +91,7 @@
highlight-current-row highlight-current-row
@row-click="changeData" @row-click="changeData"
v-loading="dataListLoading" v-loading="dataListLoading"
:row-class-name="mainTableRowClassName"
style="margin-top: 0px; width: 100%;"> style="margin-top: 0px; width: 100%;">
<el-table-column <el-table-column
v-for="(item,index) in columnArray1" :key="index" v-for="(item,index) in columnArray1" :key="index"
@ -107,9 +109,15 @@
style="width: 100px; height: 100px"/></span> style="width: 100px; height: 100px"/></span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column fixed="right" header-align="center" align="center" width="100" label="操作">
<el-table-column fixed="right" header-align="center" align="center" width="150" label="操作">
<template slot-scope="scope"> <template slot-scope="scope">
<el-link style="cursor: pointer; color: #F56C6C;" @click="deleteInspectionRequest(scope.row)">删除</el-link>
<el-link v-if="scope.row.status === '草稿' || scope.row.statusDb === 'Draft'"
style="cursor: pointer; color: #409EFF; margin-right: 10px;"
@click="confirmInspection(scope.row)">确认</el-link>
<el-link v-if="scope.row.status !== '已审核' && scope.row.statusDb !== 'Audited'"
style="cursor: pointer; color: #F56C6C;"
@click="deleteInspectionRequest(scope.row)">删除</el-link>
<span v-else style="color: #909399;">已审核</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -241,7 +249,8 @@
size="small" size="small"
table-layout="fixed" table-layout="fixed"
style="width: 100%; margin-top: 10px;" style="width: 100%; margin-top: 10px;"
@selection-change="handleSelectionChange">
@selection-change="handleSelectionChange"
:row-class-name="tableRowClassName">
<el-table-column type="selection" width="55" align="center"/> <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="orderRef1" label="PO号" header-align="center" align="center" width="120"/>
<el-table-column prop="orderRef2" label="PO行号" header-align="center" align="center" width="100"/> <el-table-column prop="orderRef2" label="PO行号" header-align="center" align="center" width="100"/>
@ -299,11 +308,49 @@
<el-button @click="handleCloseAddDialog">关闭</el-button> <el-button @click="handleCloseAddDialog">关闭</el-button>
</div> </div>
</el-dialog> </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" min-width="120"></el-table-column>
<el-table-column prop="poItemNo" label="PO行号" align="center" min-width="100"></el-table-column>
<el-table-column prop="partNo" label="产品编码" align="center" min-width="120"></el-table-column>
<el-table-column prop="qty" label="验货数量" align="center" min-width="100"></el-table-column>
<el-table-column prop="shipMethod" label="运输方式" align="center" min-width="100"></el-table-column>
<el-table-column prop="crd" label="CRD" align="center" min-width="120"></el-table-column>
<el-table-column prop="suggestInspectDate" label="建议验货日期" align="center" min-width="120"></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> </div>
</template> </template>
<script> <script>
import { searchInspectionRequestHeaderList, queryPoPage, saveInspectionRequest } from '@/api/inspection/inspectionRequestHeader.js'
import { searchInspectionRequestHeaderList, queryPoPage, saveInspectionRequest, deleteInspectionRequest, confirmInspectionRequest, downloadTemplate, previewUpload, batchSave } from '@/api/inspection/inspectionRequestHeader.js'
import Chooselist from '@/views/modules/common/Chooselist_eam' import Chooselist from '@/views/modules/common/Chooselist_eam'
import ComInspectionRequestDetail from './com_inspectionRequestDetail.vue' import ComInspectionRequestDetail from './com_inspectionRequestDetail.vue'
import ComInspectionRequestDetailTab from './com_inspectionRequestDetailTab.vue' import ComInspectionRequestDetailTab from './com_inspectionRequestDetailTab.vue'
@ -348,6 +395,11 @@ export default {
}, },
poList: [], poList: [],
selectedPoList: [], selectedPoList: [],
//
uploadDialogVisible: false,
uploadFileName: '',
uploadFile: null,
uploadPreviewList: [],
searchData: { searchData: {
requestNo: '', requestNo: '',
supplierNo: '', supplierNo: '',
@ -648,6 +700,15 @@ export default {
searchInspectionRequestHeaderList(this.searchData).then(({ data }) => { searchInspectionRequestHeaderList(this.searchData).then(({ data }) => {
if (data.code === 0) { if (data.code === 0) {
this.mainDataList = data.page.list 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.pageIndex = data.page.currPage
this.pageSize = data.page.pageSize this.pageSize = data.page.pageSize
this.totalPage = data.page.totalCount this.totalPage = data.page.totalCount
@ -781,6 +842,7 @@ export default {
this.poList = data.page.list.map(item => ({ this.poList = data.page.list.map(item => ({
...item, ...item,
inspectQty: item.waitInspectQty || 0, // inspectQty: item.waitInspectQty || 0, //
originalWaitInspectQty: item.waitInspectQty || 0, //
shipMethod: item.shipMethod || '',// shipMethod: item.shipMethod || '',//
crd: item.crd ? item.crd.split(' ')[0] : '' crd: item.crd ? item.crd.split(' ')[0] : ''
})) }))
@ -806,6 +868,39 @@ export default {
this.$set(row, 'inspectQty', value) this.$set(row, 'inspectQty', value)
}, },
//
tableRowClassName ({ row }) {
if (row.inspectQty !== row.originalWaitInspectQty) {
return 'modified-row'
}
return ''
},
//
mainTableRowClassName ({ row }) {
// hasModifiedQty
console.log('Row:', row.requestNo, 'hasModifiedQty:', row.hasModifiedQty, 'type:', typeof row.hasModifiedQty)
// hasModifiedQty 使
//
if (row.hasModifiedQty === true ||
row.hasModifiedQty === 'true' ||
row.hasModifiedQty === 'Y' ||
row.hasModifiedQty === 'y' ||
row.hasModifiedQty === 1 ||
row.hasModifiedQty === '1') {
console.log('✅ 应用红色背景到:', row.requestNo)
return 'modified-request-row'
}
//
if (row.hasModifiedQty === undefined || row.hasModifiedQty === null) {
console.warn('⚠️ 警告: 行', row.requestNo, '缺少 hasModifiedQty 字段,后端可能未返回该字段')
}
return ''
},
// //
handleSaveAdd () { handleSaveAdd () {
console.log('开始保存,当前选择的PO列表:', this.selectedPoList) console.log('开始保存,当前选择的PO列表:', this.selectedPoList)
@ -829,6 +924,7 @@ export default {
// //
const submitData = { const submitData = {
requestDate: this.addFormData.requestDate, requestDate: this.addFormData.requestDate,
needInspectDate: this.addFormData.needInspectDate,
supplierNo: this.addFormData.supplierNo, supplierNo: this.addFormData.supplierNo,
inspectAddress: this.addFormData.inspectAddress, inspectAddress: this.addFormData.inspectAddress,
inspectContract: this.addFormData.contact, inspectContract: this.addFormData.contact,
@ -869,7 +965,110 @@ export default {
// Excel // Excel
importExcel () { importExcel () {
this.$message.info('Excel导入功能开发中...')
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('模板下载失败,请联系管理员')
})
}, },
// //
@ -877,6 +1076,29 @@ export default {
this.$message.info('导出功能开发中...') this.$message.info('导出功能开发中...')
}, },
//
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) { deleteInspectionRequest (row) {
this.$confirm('确定要删除该验货申请吗?', '提示', { this.$confirm('确定要删除该验货申请吗?', '提示', {
@ -884,8 +1106,17 @@ export default {
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.$message.success('删除成功')
this.getMainData()
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(() => { }).catch(() => {
this.$message.info('已取消删除') this.$message.info('已取消删除')
}) })
@ -1176,6 +1407,40 @@ padding: 10px 15px 0 0;
padding-right: 28px !important; padding-right: 28px !important;
} }
} }
// PO -
.po-section /deep/ .el-table__row.modified-row {
background-color: #fef0f0 !important;
&:hover > td {
background-color: #fde2e2 !important;
}
td {
color: #f56c6c;
}
}
// -
/deep/ .el-table__row.modified-request-row {
background-color: #fef0f0 !important;
td {
background-color: #fef0f0 !important;
color: #f56c6c !important;
}
&:hover > td {
background-color: #fde2e2 !important;
}
}
//
/deep/ .el-table__body tr.modified-request-row > td {
background-color: #fef0f0 !important;
color: #f56c6c !important;
}
.po-section { .po-section {
/deep/ .el-date-editor.el-input, /deep/ .el-date-editor.el-input,

Loading…
Cancel
Save