Browse Source

feat(npcIqc): 添加NPC IQC模块功能

- 新增NPC IQC数据管理页面,包含查询、分页、详情展示功能
- 实现Excel导入功能,支持模板下载、数据预览和批量保存
- 添加数据导出功能,支持按条件导出为Excel文件
- 集成API接口,实现搜索、模板下载、上传预览和批量保存操作
- 设计响应式表格布局,适配不同屏幕尺寸显示需求
- 实现多条件查询功能,支持供应商、日期、状态等筛选条件组合查询
master
qiankanghui 2 weeks ago
parent
commit
b0ff1acff2
  1. 26
      src/api/npcIqc/npcIqc.js
  2. 208
      src/views/modules/npcIqc/npcIqcList.vue

26
src/api/npcIqc/npcIqc.js

@ -2,3 +2,29 @@ import { createAPI } from '@/utils/httpRequest.js'
export const searchNpcIqc = (data) => createAPI(`/npcIqc/search`, 'post', data) export const searchNpcIqc = (data) => createAPI(`/npcIqc/search`, 'post', data)
// 下载导入模板
export const downloadTemplate = () => {
return createAPI('/npcIqc/downloadTemplate', 'post', {}, { responseType: 'blob' })
}
// 预览上传数据
export const previewUpload = (file) => {
const formData = new FormData()
formData.append('file', file)
return createAPI('/npcIqc/previewUpload', 'post', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
// 批量保存
export const batchSave = (file) => {
const formData = new FormData()
formData.append('file', file)
return createAPI('/npcIqc/batchSave', 'post', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
}

208
src/views/modules/npcIqc/npcIqcList.vue

@ -107,18 +107,76 @@
</el-pagination> </el-pagination>
<!-- 详情页签 --> <!-- 详情页签 -->
<el-tabs v-model="activeTab" :style="{marginTop: '10px', width: '100%', height: detailHeight + 'px'}" @tab-click="handleTabClick" class="customer-tab" type="border-card">
<el-tab-pane label="详情" name="detail">
<div style="height: 100%; overflow: auto;">
<el-tabs v-model="activeTab" :style="{marginTop: '10px', width: '100%'}" @tab-click="handleTabClick" class="customer-tab" type="border-card">
<el-tab-pane label="详情" name="detail" class="detail-tab-pane">
<div class="detail-content-wrapper">
<npc-iqc-detail :detail-data="currentRow" /> <npc-iqc-detail :detail-data="currentRow" />
</div> </div>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<!-- 导入弹窗 -->
<el-dialog title="NPC IQC数据导入" :visible.sync="uploadDialogVisible" width="90%">
<!-- 选择文件 -->
<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/npcIqc/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="previewUploadData">上传</el-button>
<el-button type="primary" @click="downloadTemplateFile" style="margin-left:10px">
<i class="el-icon-download"></i> 下载模板
</el-button>
</div>
<!-- 预览表格 -->
<el-table
:data="uploadPreviewList"
border
height="350"
style="width:100%;margin-top:10px"
size="mini"
>
<el-table-column prop="inspectionType" label="Inspection Type" align="center" width="120"></el-table-column>
<el-table-column prop="purOrder" label="PUR ORDER" align="center" width="120"></el-table-column>
<el-table-column prop="supplier" label="Supplier" align="left" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column prop="dateReceived" label="Date Received" align="center" width="110"></el-table-column>
<el-table-column prop="item" label="Item" align="left" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column prop="quantity" label="Quantity" align="right" width="80"></el-table-column>
<el-table-column prop="sampleSize" label="Sample Size" align="right" width="90"></el-table-column>
<el-table-column prop="dimA" label="Dim A" align="right" width="70"></el-table-column>
<el-table-column prop="dimB" label="Dim B" align="right" width="70"></el-table-column>
<el-table-column prop="dimC" label="Dim C" align="right" width="70"></el-table-column>
<el-table-column prop="dimD" label="Dim D" align="right" width="70"></el-table-column>
<el-table-column prop="dimE" label="Dim E" align="right" width="70"></el-table-column>
<el-table-column prop="total" label="Total" align="center" width="80"></el-table-column>
<el-table-column prop="status" label="Status" align="center" width="80"></el-table-column>
<el-table-column prop="problem" label="PROBLEM" align="left" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column prop="comments" label="Comments" align="left" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column prop="inspectorName" label="INSPECTOR NAME" align="left" width="120"></el-table-column>
<el-table-column prop="supplierEmail" label="SUPPLIER EMAIL" align="left" width="150" show-overflow-tooltip></el-table-column>
<el-table-column prop="caRequest" label="CA Request" align="center" width="90"></el-table-column>
<el-table-column prop="reworkHours" label="Rework Hours" align="right" width="100"></el-table-column>
<el-table-column prop="reworkRate" label="Rework Rate" align="right" width="90"></el-table-column>
<el-table-column prop="reworkTotal" label="Rework Total" align="right" width="100"></el-table-column>
<el-table-column prop="materialCost" label="Material Cost" align="right" width="100"></el-table-column>
<el-table-column prop="createdBy" label="Created By" align="left" width="100"></el-table-column>
<el-table-column prop="collection" label="Collection" align="left" width="100"></el-table-column>
<el-table-column prop="entryDate" label="Entry Date" align="center" width="110"></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-left:10px">关闭</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { searchNpcIqc } from '@/api/npcIqc/npcIqc.js'
import { searchNpcIqc, downloadTemplate, previewUpload, batchSave } from '@/api/npcIqc/npcIqc.js'
import ComNpcIqcDetail from './com_npcIqcDetail.vue' import ComNpcIqcDetail from './com_npcIqcDetail.vue'
import excel from '@/utils/excel-util.js' import excel from '@/utils/excel-util.js'
@ -150,15 +208,20 @@ export default {
pageSize: 50, pageSize: 50,
totalPage: 0, totalPage: 0,
mainDataList: [], mainDataList: [],
dataListLoading: false
dataListLoading: false,
//
uploadDialogVisible: false,
uploadFileName: '',
uploadFile: null,
uploadPreviewList: []
} }
}, },
mounted () { mounted () {
this.$nextTick(() => { this.$nextTick(() => {
//
const availableHeight = window.innerHeight - 320
this.tableHeight = availableHeight / 2
this.detailHeight = availableHeight / 2
//
const availableHeight = window.innerHeight - 280
this.tableHeight = availableHeight * 0.4
this.detailHeight = availableHeight * 0.6
this.getMainData() this.getMainData()
}) })
}, },
@ -216,7 +279,110 @@ export default {
}, },
excelImport () { excelImport () {
this.$message.info('Excel导入功能待开发')
this.uploadDialogVisible = true
this.uploadFileName = ''
this.uploadFile = null
this.uploadPreviewList = []
},
//
handleFileChange (file) {
this.uploadFile = file.raw
this.uploadFileName = file.name
},
//
previewUploadData () {
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(() => {})
},
//
downloadTemplateFile () {
const loading = this.$loading({
lock: true,
text: '正在下载模板...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
this.$http({
url: this.$http.adornUrl('/npcIqc/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 = 'NPC_IQC导入模板.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 () { exportExcel () {
@ -348,13 +514,31 @@ export default {
/deep/ .customer-tab { /deep/ .customer-tab {
overflow: hidden; overflow: hidden;
margin-top: 5px !important;
margin-top: 10px !important;
height: calc(60vh - 100px);
display: flex;
flex-direction: column;
} }
/deep/ .customer-tab .el-tabs__content { /deep/ .customer-tab .el-tabs__content {
padding: 0 !important; padding: 0 !important;
height: 100%;
flex: 1;
overflow: hidden; overflow: hidden;
display: flex;
flex-direction: column;
}
.detail-tab-pane {
height: 100%;
display: flex;
flex-direction: column;
}
.detail-content-wrapper {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
padding: 10px;
} }
/* 分页插件紧凑化 */ /* 分页插件紧凑化 */

Loading…
Cancel
Save