Browse Source

2026-03-31

物料档案管理-》SOP清单页签优化上传文件功能
master
fengyuan_yang 2 weeks ago
parent
commit
5ee851926f
  1. 210
      src/views/modules/qc/sopFileManagementUpload.vue
  2. 45
      src/views/modules/qc/sopFileUpload.vue
  3. 17
      src/views/modules/qc/sopListComponent.vue

210
src/views/modules/qc/sopFileManagementUpload.vue

@ -4,35 +4,102 @@
title="文件上传" title="文件上传"
:close-on-click-modal="false" :close-on-click-modal="false"
:visible.sync="visible" :visible.sync="visible"
width="390px"
width="1200px"
append-to-body
class="customer-dialog"> class="customer-dialog">
<el-form :inline="true" label-position="top" label-width="80px"> <el-form :inline="true" label-position="top" label-width="80px">
<el-row>
<el-col :span="24">
<el-form-item class="customer-item" label="物料编码">
<el-input v-model="pageData.partNo" style="width: 340px;" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<el-upload <el-upload
class="customer-upload" class="customer-upload"
drag
multiple
:file-list="fileList"
action="javascript:void(0);" action="javascript:void(0);"
ref="uploadFile" ref="uploadFile"
multiple
:show-file-list="false"
:before-upload="beforeUploadHandle" :before-upload="beforeUploadHandle"
:on-change="onChange" :on-change="onChange"
accept="*" accept="*"
:auto-upload="false" :auto-upload="false"
style="text-align: left;">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em>支持多选</div>
style="text-align: left; margin-bottom: 10px;">
<el-button type="primary">上传</el-button>
</el-upload> </el-upload>
</el-col> </el-col>
</el-row> </el-row>
<el-row>
<el-col :span="24">
<div class="rq">
<el-table
:data="fileList"
border
style="width: 100%;"
height="400">
<el-table-column label="文件编码" min-width="150">
<template slot-scope="scope">
<el-input v-model="scope.row.fileNo" placeholder="请输入文件编码" size="small"></el-input>
</template>
</el-table-column>
<el-table-column prop="fileName" label="文件名称" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="文件类型" min-width="100">
<template slot-scope="scope">
<el-select v-model="scope.row.sopType" placeholder="请选择" size="small">
<el-option label="PD" value="PD"></el-option>
<el-option label="SOP" value="SOP"></el-option>
<el-option label="SIP" value="SIP"></el-option>
<el-option label="TPI" value="TPI"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="fileSuffix" label="文件后缀" min-width="80"></el-table-column>
<el-table-column label="版本号" min-width="100">
<template slot-scope="scope">
<el-input v-model="scope.row.version" placeholder="请输入版本号" size="small"></el-input>
</template>
</el-table-column>
<el-table-column label="工序" min-width="150">
<template slot-scope="scope">
<el-select v-model="scope.row.itemNo" clearable placeholder="请选择工序" size="small">
<el-option
v-for="i in operationList"
:key="i.id"
:label="i.operationDesc"
:value="i.operationDesc">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="生效日期" min-width="160">
<template slot-scope="scope">
<el-date-picker
v-model="scope.row.phaseInDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择日期"
style="width: 100%"
:picker-options="getPhaseInPickerOptions(scope.row)">
</el-date-picker>
</template>
</el-table-column>
<el-table-column label="失效日期" min-width="160">
<template slot-scope="scope">
<el-date-picker
v-model="scope.row.phaseOutDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择日期"
style="width: 100%"
:picker-options="getPhaseOutPickerOptions(scope.row)">
</el-date-picker>
</template>
</el-table-column>
<el-table-column label="操作" width="80" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="text" size="small" @click="removeFile(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-col>
</el-row>
</el-form> </el-form>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button type="primary" :loading="saveLoading" @click="saveUploadFile">保存</el-button> <el-button type="primary" :loading="saveLoading" @click="saveUploadFile">保存</el-button>
@ -43,7 +110,7 @@
</template> </template>
<script> <script>
import { sopFileBatchUpload } from '@/api/qc/qc.js'
import { sopFileBatchUpload, getStandardOperation } from '@/api/qc/qc.js'
export default { export default {
data () { data () {
@ -51,29 +118,81 @@ export default {
visible: false, visible: false,
saveLoading: false, saveLoading: false,
fileList: [], fileList: [],
operationList: [],
pageData: { pageData: {
partNo: '',
site: '', site: '',
buNo: '' buNo: ''
} }
} }
}, },
methods: { methods: {
init (partNo, site, buNo) {
init (site, buNo) {
this.pageData = { this.pageData = {
partNo: partNo || '',
site: site || this.$store.state.user.site || '', site: site || this.$store.state.user.site || '',
buNo: (buNo != null && buNo !== '') ? String(buNo) : (this.$store.state.user.buNo || '') buNo: (buNo != null && buNo !== '') ? String(buNo) : (this.$store.state.user.buNo || '')
} }
this.fileList = [] this.fileList = []
this.visible = true this.visible = true
this.getStandardOperation(this.pageData.site)
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.uploadFile && this.$refs.uploadFile.clearFiles() this.$refs.uploadFile && this.$refs.uploadFile.clearFiles()
}) })
}, },
getStandardOperation (site) {
let tempData = {
site: site
}
getStandardOperation(tempData).then(({data}) => {
if (data.code === 0) {
this.operationList = data.rows
}
})
},
beforeUploadHandle () {}, beforeUploadHandle () {},
onChange (file, fileList) { onChange (file, fileList) {
this.fileList = fileList
// Check if file is already in the list
const exists = this.fileList.some(f => f.raw.uid === file.raw.uid)
if (!exists) {
const fileName = file.name
const lastDotIndex = fileName.lastIndexOf('.')
const nameWithoutSuffix = lastDotIndex > -1 ? fileName.substring(0, lastDotIndex) : fileName
const suffix = lastDotIndex > -1 ? fileName.substring(lastDotIndex + 1) : ''
this.fileList.push({
raw: file.raw,
fileNo: nameWithoutSuffix,
fileName: fileName,
sopType: '',
fileSuffix: suffix,
version: 'A0',
itemNo: '',
phaseInDate: '',
phaseOutDate: ''
})
}
},
removeFile (index) {
this.fileList.splice(index, 1)
},
getPhaseInPickerOptions (row) {
return {
disabledDate (time) {
if (row.phaseOutDate) {
return time.getTime() > new Date(row.phaseOutDate).getTime()
}
return false
}
}
},
getPhaseOutPickerOptions (row) {
return {
disabledDate (time) {
if (row.phaseInDate) {
return time.getTime() < new Date(row.phaseInDate).getTime()
}
return false
}
}
}, },
closeDialog () { closeDialog () {
this.fileList = [] this.fileList = []
@ -82,29 +201,51 @@ export default {
this.$emit('uploaded') this.$emit('uploaded')
}, },
saveUploadFile () { saveUploadFile () {
if (!this.pageData.partNo) {
this.$message.warning('请先选择物料')
if (!this.fileList || this.fileList.length === 0) {
this.$message.error('请先选择要上传的文件')
return return
} }
if (!this.pageData.buNo) {
this.$message.warning('当前物料未带出部门(buNo),请确认已选中物料行')
// Validate required fields
for (let i = 0; i < this.fileList.length; i++) {
const file = this.fileList[i]
if (!file.fileNo) {
this.$message.error(`${i + 1} 行文件编码不能为空`)
return return
} }
if (!this.fileList || this.fileList.length === 0) {
this.$message.error('请先选择要上传的文件')
if (!file.sopType) {
this.$message.error(`${i + 1} 行文件类型不能为空`)
return return
} }
}
const formData = new FormData() const formData = new FormData()
const currentDate = new Date()
const formatDate = currentDate.getFullYear() + '-' +
String(currentDate.getMonth() + 1).padStart(2, '0') + '-' +
String(currentDate.getDate()).padStart(2, '0')
for (let i = 0; i < this.fileList.length; i++) { for (let i = 0; i < this.fileList.length; i++) {
const raw = this.fileList[i].raw
if (raw) {
formData.append('file', raw)
}
const file = this.fileList[i]
formData.append('file', file.raw)
} }
const fileMetaData = this.fileList.map(file => ({
fileNo: file.fileNo || '',
fileName: file.fileName || '',
sopType: file.sopType || '',
fileSuffix: file.fileSuffix || '',
version: file.version || 'A0',
itemNo: file.itemNo || '',
phaseInDate: file.phaseInDate || formatDate,
phaseOutDate: file.phaseOutDate || ''
}))
formData.append('fileMetaData', JSON.stringify(fileMetaData))
formData.append('site', String(this.pageData.site)) formData.append('site', String(this.pageData.site))
formData.append('buNo', String(this.pageData.buNo)) formData.append('buNo', String(this.pageData.buNo))
formData.append('partNo', String(this.pageData.partNo))
formData.append('createBy', this.$store.state.user.name || '') formData.append('createBy', this.$store.state.user.name || '')
this.saveLoading = true this.saveLoading = true
sopFileBatchUpload(formData).then(({ data }) => { sopFileBatchUpload(formData).then(({ data }) => {
if (data && data.code === 0) { if (data && data.code === 0) {
@ -127,4 +268,13 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
::v-deep .el-table .cell {
padding: 5px;
}
::v-deep .el-input__inner {
padding: 0 5px;
}
::v-deep .el-dialog__body {
padding: 10px 20px;
}
</style> </style>

45
src/views/modules/qc/sopFileUpload.vue

@ -2,26 +2,31 @@
<div> <div>
<el-dialog title="文件上传" :close-on-click-modal="false" :visible.sync="visible" width="70%" top="5vh"> <el-dialog title="文件上传" :close-on-click-modal="false" :visible.sync="visible" width="70%" top="5vh">
<div class="upload-content"> <div class="upload-content">
<!-- 查询表单 -->
<el-form :inline="true" :model="searchForm" @keyup.enter.native="getFileList()" style="background: #f5f5f5; padding: 10px; margin-bottom: 10px;"> <el-form :inline="true" :model="searchForm" @keyup.enter.native="getFileList()" style="background: #f5f5f5; padding: 10px; margin-bottom: 10px;">
<el-form-item> <el-form-item>
<span style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">文件编码</span> <span style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">文件编码</span>
<el-input v-model="searchForm.fileNo" placeholder="请输入文件编码" clearable style="width: 150px;"></el-input>
<el-input v-model="searchForm.fileNo" placeholder="请输入文件编码" clearable style="width: 120px;"></el-input>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<span style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">文件名称</span> <span style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">文件名称</span>
<el-input v-model="searchForm.fileName" placeholder="请输入文件名称" clearable style="width: 150px;"></el-input>
<el-input v-model="searchForm.fileName" placeholder="请输入文件名称" clearable style="width: 120px;"></el-input>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<span style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">文件类型</span> <span style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">文件类型</span>
<el-input v-model="searchForm.fileType" placeholder="请输入文件类型" clearable style="width: 150px;"></el-input>
<el-select v-model="searchForm.fileType" placeholder="请选择文件类型" clearable style="width: 100px;">
<el-option label="PD" value="PD"></el-option>
<el-option label="SOP" value="SOP"></el-option>
<el-option label="SIP" value="SIP"></el-option>
<el-option label="TPI" value="TPI"></el-option>
</el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<span style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">版本号</span> <span style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">版本号</span>
<el-input v-model="searchForm.sopRevNo" placeholder="请输入版本号" clearable style="width: 150px;"></el-input>
<el-input v-model="searchForm.sopRevNo" placeholder="请输入版本号" clearable style="width: 100px;"></el-input>
</el-form-item> </el-form-item>
<el-form-item>
<el-form-item style="margin-left: 40px">
<el-button type="primary" icon="el-icon-search" @click="getFileList()">查询</el-button> <el-button type="primary" icon="el-icon-search" @click="getFileList()">查询</el-button>
<el-button type="primary" @click="openUploadDialog()">上传文件</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -76,12 +81,14 @@
min-width="80"> min-width="80">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="phaseInDate"
header-align="center" header-align="center"
align="center" align="center"
label="生效日期" label="生效日期"
min-width="120"> min-width="120">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="phaseOutDate"
header-align="center" header-align="center"
align="center" align="center"
label="失效日期" label="失效日期"
@ -160,12 +167,14 @@
min-width="80"> min-width="80">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="phaseInDate"
header-align="center" header-align="center"
align="center" align="center"
label="生效日期" label="生效日期"
min-width="120"> min-width="120">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="phaseOutDate"
header-align="center" header-align="center"
align="center" align="center"
label="失效日期" label="失效日期"
@ -197,10 +206,16 @@
<el-button @click="closeDialog">关闭</el-button> <el-button @click="closeDialog">关闭</el-button>
</span> </span>
</el-dialog> </el-dialog>
<sop-file-management-upload
ref="sopFileManagementUpload"
@uploaded="getFileList">
</sop-file-management-upload>
</div> </div>
</template> </template>
<script> <script>
import SopFileManagementUpload from './sopFileManagementUpload'
import { import {
sopAvailableFiles, sopAvailableFiles,
sopFileUploadSave, sopFileUploadSave,
@ -208,6 +223,9 @@ import {
} from '@/api/qc/qc.js' } from '@/api/qc/qc.js'
export default { export default {
components: {
SopFileManagementUpload
},
data () { data () {
return { return {
visible: false, visible: false,
@ -268,6 +286,11 @@ export default {
this.originalFileList = [] this.originalFileList = []
this.filePageIndex = 1 this.filePageIndex = 1
}, },
openUploadDialog () {
this.$nextTick(() => {
this.$refs.sopFileManagementUpload.init(this.currentSite, this.currentBuNo)
})
},
// //
getFileList () { getFileList () {
this.fileListLoading = true this.fileListLoading = true
@ -349,7 +372,9 @@ export default {
sopUrl: file.sopUrl || file.sop_url || '', sopUrl: file.sopUrl || file.sop_url || '',
sopType: file.sopType, sopType: file.sopType,
sourceSystem: file.sourceSystem || '', sourceSystem: file.sourceSystem || '',
standardFields: file.standardFields || ''
standardFields: file.standardFields || '',
phaseInDate: file.phaseInDate || '',
phaseOutDate: file.phaseOutDate || ''
}) })
} }
}) })
@ -424,10 +449,10 @@ export default {
sopName: file.fileName, sopName: file.fileName,
sopUrl: file.sopUrl || '', sopUrl: file.sopUrl || '',
sopType: file.sopType || '', sopType: file.sopType || '',
version: file.sopRevNo || '',
version: file.sopRevNo || 'A0',
sopStatus: 'A', // sopStatus: 'A', //
phaseInDate: formatDate,
phaseOutDate: null,
phaseInDate: file.phaseInDate || formatDate,
phaseOutDate: file.phaseOutDate || null,
createdBy: this.$store.state.user.name, createdBy: this.$store.state.user.name,
creationDate: formatDate, creationDate: formatDate,
fileType: file.fileType || '', fileType: file.fileType || '',

17
src/views/modules/qc/sopListComponent.vue

@ -2,7 +2,6 @@
<div class="sop-list-component" style="padding: 2px !important"> <div class="sop-list-component" style="padding: 2px !important">
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()"> <el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
<el-form-item> <el-form-item>
<el-button type="primary" @click="localFileUploadHandle()">上传文件</el-button>
<el-button @click="fileLibraryHandle()">从文件库添加</el-button> <el-button @click="fileLibraryHandle()">从文件库添加</el-button>
<el-button type="danger" @click="batchDeleteHandle()" :disabled="dataListSelections.length === 0" :loading="deleteLoading">删除</el-button> <el-button type="danger" @click="batchDeleteHandle()" :disabled="dataListSelections.length === 0" :loading="deleteLoading">删除</el-button>
</el-form-item> </el-form-item>
@ -115,10 +114,6 @@
</el-pagination> </el-pagination>
<!-- 文件上传弹窗 --> <!-- 文件上传弹窗 -->
<sop-file-management-upload
ref="sopFileManagementUpload"
@uploaded="getDataList">
</sop-file-management-upload>
<sop-file-upload <sop-file-upload
v-if="sopFileUploadVisible" v-if="sopFileUploadVisible"
ref="sopFileUpload" ref="sopFileUpload"
@ -128,14 +123,12 @@
</template> </template>
<script> <script>
import SopFileManagementUpload from './sopFileManagementUpload'
import SopFileUpload from './sopFileUpload' import SopFileUpload from './sopFileUpload'
import { sopListSearch, sopRecordDelete, downloadSopFile } from '@/api/qc/qc.js' import { sopListSearch, sopRecordDelete, downloadSopFile } from '@/api/qc/qc.js'
export default { export default {
name: 'SopListComponent', name: 'SopListComponent',
components: { components: {
SopFileManagementUpload,
SopFileUpload SopFileUpload
}, },
props: { props: {
@ -224,16 +217,6 @@ export default {
selectionChangeHandle (val) { selectionChangeHandle (val) {
this.dataListSelections = val this.dataListSelections = val
}, },
// file_management IPQC
localFileUploadHandle () {
if (!this.partNo) {
this.$message.warning('请先选择物料')
return
}
this.$nextTick(() => {
this.$refs.sopFileManagementUpload.init(this.partNo, this.site, this.buNo)
})
},
// //
fileLibraryHandle () { fileLibraryHandle () {
if (!this.partNo) { if (!this.partNo) {

Loading…
Cancel
Save