han\hanst 4 months ago
parent
commit
f84faa1f42
  1. 6
      src/api/qc/qc.js
  2. 12
      src/views/modules/qc/qcPartAttribute.vue
  3. 469
      src/views/modules/qc/sopFileUpload.vue
  4. 269
      src/views/modules/qc/sopListComponent.vue

6
src/api/qc/qc.js

@ -232,3 +232,9 @@ export const getOperatorList = data => createAPI(`/pms/qc/getOperatorList`,'post
export const getCustomerList = data => createAPI(`/pms/qc/getCustomerList`,'post',data) export const getCustomerList = data => createAPI(`/pms/qc/getCustomerList`,'post',data)
// ===================================== SOP清单 =====================================
export const sopListSearch = data => createAPI(`/pms/qc/sopListSearch`,'post',data)
export const sopAvailableFiles = data => createAPI(`/pms/qc/sopAvailableFiles`,'post',data)
export const sopFileUploadSave = data => createAPI(`/pms/qc/sopFileUploadSave`,'post',data)
export const sopRecordDelete = data => createAPI(`/pms/qc/sopList/delete`,'post',data)

12
src/views/modules/qc/qcPartAttribute.vue

@ -307,7 +307,13 @@
<!-- Routing页签 --> <!-- Routing页签 -->
<el-tab-pane label="Routing" name="routing"></el-tab-pane> <el-tab-pane label="Routing" name="routing"></el-tab-pane>
<!-- SOP清单 --> <!-- SOP清单 -->
<el-tab-pane label="SOP清单" name="partSop"></el-tab-pane>
<el-tab-pane label="SOP清单" name="partSop">
<sop-list-component
v-if="activeTable === 'partSop'"
:part-no="partCurrentRow.partNo"
:site="partCurrentRow.site">
</sop-list-component>
</el-tab-pane>
<!-- 质量检验模板页签 --> <!-- 质量检验模板页签 -->
<el-tab-pane label="质量检验模板" name="qcTemplate"> <el-tab-pane label="质量检验模板" name="qcTemplate">
<el-form label-position="top" style="margin-left: 2px;"> <el-form label-position="top" style="margin-left: 2px;">
@ -1190,11 +1196,13 @@
import {verifyData} from "@/api/chooselist/chooselist.js" import {verifyData} from "@/api/chooselist/chooselist.js"
import qcUpload from "./qc_upload" import qcUpload from "./qc_upload"
import qcSOPUploadFile from "./qc_SOP_upload_file" import qcSOPUploadFile from "./qc_SOP_upload_file"
import SopListComponent from "./sopListComponent"
export default { export default {
components: { components: {
qcSOPUploadFile, qcSOPUploadFile,
Chooselist, Chooselist,
qcUpload
qcUpload,
SopListComponent
}, },
data () { data () {
return { return {

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

@ -0,0 +1,469 @@
<template>
<div>
<el-dialog title="文件上传" :close-on-click-modal="false" :visible.sync="visible" width="50%" top="5vh">
<div class="upload-content">
<!-- 查询表单 -->
<el-form :inline="true" :model="searchForm" @keyup.enter.native="getFileList()" style="background: #f5f5f5; padding: 10px; margin-bottom: 10px;">
<el-form-item>
<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-form-item>
<el-form-item>
<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-form-item>
<el-form-item>
<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-form-item>
<el-form-item>
<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-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="getFileList()">查询</el-button>
</el-form-item>
</el-form>
<!-- 文件列表表格 -->
<el-table
ref="fileTable"
:data="fileList"
border
v-loading="fileListLoading"
@selection-change="fileSelectionChange"
height="280"
style="width: 100%;">
<el-table-column
type="selection"
header-align="center"
align="center"
width="50">
</el-table-column>
<el-table-column
prop="fileNo"
header-align="center"
align="center"
label="文件编码"
width="120">
</el-table-column>
<el-table-column
prop="fileName"
header-align="center"
align="left"
label="文件名称"
min-width="180">
</el-table-column>
<el-table-column
prop="sopType"
header-align="center"
align="center"
label="文件类型"
width="100">
</el-table-column>
<el-table-column
prop="fileSuffix"
header-align="center"
align="center"
label="文件后缀"
width="100">
</el-table-column>
<el-table-column
prop="sopRevNo"
header-align="center"
align="center"
label="版本号"
width="100">
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="生效日期"
width="120">
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="失效日期"
width="120">
</el-table-column>
</el-table>
<!-- 分页 -->
<div style="margin-top: 10px; display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; align-items: center;">
<span style="margin-right: 10px;"></span>
<el-input v-model="filePageIndex" style="width: 60px;" @change="fileCurrentChangeHandle(filePageIndex)"></el-input>
<span style="margin: 0 10px;"></span>
<el-select v-model="filePageSize" @change="fileSizeChangeHandle" style="width: 100px;">
<el-option label="10条/页" :value="10"></el-option>
<el-option label="20条/页" :value="20"></el-option>
<el-option label="50条/页" :value="50"></el-option>
</el-select>
</div>
<div style="display: flex; align-items: center;">
<el-button :disabled="filePageIndex <= 1" @click="fileCurrentChangeHandle(filePageIndex - 1)"></el-button>
<span style="margin: 0 10px;">{{ filePageIndex }}</span>
<el-button @click="fileCurrentChangeHandle(filePageIndex + 1)">2</el-button>
<el-button @click="fileCurrentChangeHandle(filePageIndex + 2)">3</el-button>
<el-button></el-button>
<span style="margin-left: 10px;">前至</span>
<el-input style="width: 50px; margin: 0 5px;"></el-input>
<span></span>
<el-button style="margin-left: 10px;">GO</el-button>
</div>
</div>
<!-- 操作按钮 -->
<div style="margin-top: 20px; text-align: center;">
<el-button type="primary" @click="addSelectedFiles">添加>></el-button>
<el-button type="danger" @click="removeSelectedFiles">删除<<</el-button>
</div>
<!-- 已上传的文件 -->
<div style="margin-top: 20px;">
<h4 style="margin-bottom: 10px;">已上传的文件</h4>
<el-table
ref="uploadedFileTable"
:data="uploadedFileList"
border
height="180"
style="width: 100%;"
@selection-change="uploadedFileSelectionChange"
>
<el-table-column
type="selection"
header-align="center"
align="center"
width="50">
</el-table-column>
<el-table-column
prop="fileNo"
header-align="center"
align="center"
label="文件编码"
width="120">
</el-table-column>
<el-table-column
prop="fileName"
header-align="center"
align="center"
label="文件名称"
min-width="180">
</el-table-column>
<el-table-column
prop="sopType"
header-align="center"
align="center"
label="文件类型"
width="100">
</el-table-column>
<el-table-column
prop="fileSuffix"
header-align="center"
align="center"
label="文件后缀"
width="100">
</el-table-column>
<el-table-column
prop="sopRevNo"
header-align="center"
align="center"
label="版本号"
width="100">
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="生效日期"
width="120">
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="失效日期"
width="120">
</el-table-column>
</el-table>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="saveFiles">保存</el-button>
<el-button @click="closeDialog">关闭</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import {sopAvailableFiles, sopFileUploadSave} from '@/api/qc/qc.js'
export default {
data () {
return {
visible: false,
currentPartNo: '',
currentSite: '',
searchForm: {
fileNo: '',
fileName: '',
fileType: '',
sopRevNo: ''
},
fileList: [],
originalFileList: [], //
filePageIndex: 1,
filePageSize: 10,
fileTotalPage: 0,
fileListLoading: false,
selectedFiles: [],
uploadedFileList: [],
selectedUploadedFiles: [] //
}
},
methods: {
init (partNo, site) {
this.visible = true
this.currentPartNo = partNo || ''
this.currentSite = site || this.$store.state.user.site
this.resetData()
this.getFileList()
},
resetData () {
this.searchForm = {
fileNo: '',
fileName: '',
fileType: '',
sopRevNo: ''
}
this.selectedFiles = []
this.uploadedFileList = []
this.selectedUploadedFiles = []
this.originalFileList = []
this.filePageIndex = 1
},
//
getFileList () {
this.fileListLoading = true
sopAvailableFiles({
page: this.filePageIndex,
limit: this.filePageSize,
fileNo: this.searchForm.fileNo,
fileName: this.searchForm.fileName,
fileType: this.searchForm.fileType,
sopRevNo: this.searchForm.sopRevNo,
site: this.$store.state.user.site
}).then(({data}) => {
if (data && data.code === 0) {
this.originalFileList = data.page.list || [] //
//
this.fileList = this.originalFileList.filter(file =>
!this.uploadedFileList.some(uploaded => uploaded.fileNo === file.fileNo)
)
this.fileTotalPage = data.page.totalCount || 0
} else {
this.fileList = []
this.originalFileList = []
this.fileTotalPage = 0
}
this.fileListLoading = false
})
},
//
resetSearch () {
this.searchForm = {
fileNo: '',
fileName: '',
fileType: '',
sopRevNo: ''
}
this.filePageIndex = 1
this.getFileList()
},
//
fileSizeChangeHandle (val) {
this.filePageSize = val
this.filePageIndex = 1
this.getFileList()
},
//
fileCurrentChangeHandle (val) {
this.filePageIndex = val
this.getFileList()
},
//
fileSelectionChange (val) {
//
this.selectedFiles = val.map(selectedFile => {
//
const completeFile = this.fileList.find(file => file.fileNo === selectedFile.fileNo)
return completeFile || selectedFile
})
},
//
addSelectedFiles () {
if (this.selectedFiles.length === 0) {
this.$message.warning('请先选择要添加的文件')
return
}
//
this.selectedFiles.forEach(file => {
const exists = this.uploadedFileList.some(uploaded => uploaded.fileNo === file.fileNo)
if (!exists) {
this.uploadedFileList.push({
site: file.site,
buNo: file.buNo,
fileNo: file.fileNo,
fileName: file.fileName,
fileType: file.fileType,
fileSuffix: file.fileSuffix,
sopRevNo: file.sopRevNo,
sopUrl: file.sopUrl || file.sop_url || '',
sopType: file.sopType,
sourceSystem: file.sourceSystem || '',
standardFields: file.standardFields || ''
})
}
})
//
this.fileList = this.fileList.filter(file =>
!this.selectedFiles.some(selected => selected.fileNo === file.fileNo)
)
this.$message.success(`已添加${this.selectedFiles.length}个文件`)
//
this.$refs.fileTable && this.$refs.fileTable.clearSelection()
this.selectedFiles = []
},
//
removeSelectedFiles () {
if (this.selectedUploadedFiles.length === 0) {
this.$message.warning('请先选择要删除的文件')
return
}
//
this.selectedUploadedFiles.forEach(file => {
//
const originalFile = this.originalFileList.find(original => original.fileNo === file.fileNo)
if (originalFile) {
//
const exists = this.fileList.some(existing => existing.fileNo === file.fileNo)
if (!exists) {
this.fileList.push(originalFile)
}
}
})
//
this.uploadedFileList = this.uploadedFileList.filter(file =>
!this.selectedUploadedFiles.some(selected => selected.fileNo === file.fileNo)
)
this.$message.success(`已删除${this.selectedUploadedFiles.length}个文件`)
//
this.$refs.uploadedFileTable && this.$refs.uploadedFileTable.clearSelection()
this.selectedUploadedFiles = []
},
//
uploadedFileSelectionChange (val) {
this.selectedUploadedFiles = val
},
//
removeUploadedFile (index) {
this.uploadedFileList.splice(index, 1)
this.$message.success('文件已移除')
},
//
saveFiles () {
if (this.uploadedFileList.length === 0) {
this.$message.warning('请先添加要保存的文件')
return
}
//
const currentDate = new Date()
const formatDate = currentDate.getFullYear() + '-' +
String(currentDate.getMonth() + 1).padStart(2, '0') + '-' +
String(currentDate.getDate()).padStart(2, '0')
const saveData = this.uploadedFileList.map(file => ({
site: this.currentSite,
buNo: file.buNo || this.$store.state.user.buNo,
partNo: this.currentPartNo,
sopNo: file.fileNo,
sopName: file.fileName,
sopUrl: file.sopUrl || '',
sopType: file.sopType || '',
version: file.sopRevNo || '',
sopStatus: 'A', //
phaseInDate: formatDate,
phaseOutDate: null,
createdBy: this.$store.state.user.name,
creationDate: formatDate,
fileType: file.fileType || '',
fileSuffix: file.fileSuffix || '',
sourceSystem: file.sourceSystem || '',
standardFields: file.standardFields || ''
}))
sopFileUploadSave(saveData).then(({data}) => {
if (data && data.code === 0) {
this.$message.success('保存成功')
this.closeDialog()
this.$emit('refreshDataList')
} else {
this.$message.error(data.msg || '保存失败')
}
})
},
//
closeDialog () {
this.visible = false
this.resetData()
}
}
}
</script>
<style scoped>
.upload-content {
height: 70vh;
overflow-y: auto;
}
/* 自定义表格样式 */
::v-deep .el-table th {
background: #409EFF !important;
color: white !important;
}
/* 自定义分页样式 */
::v-deep .el-pagination {
text-align: center;
}
/* 自定义按钮样式 */
::v-deep .el-button {
border-radius: 4px;
}
/* 查询表单样式 */
::v-deep .el-form--inline .el-form-item {
margin-right: 15px;
margin-bottom: 8px;
}
/* 输入框对齐 */
::v-deep .el-input {
vertical-align: middle;
}
/* 表格行高 */
::v-deep .el-table .cell {
padding: 5px;
}
</style>

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

@ -0,0 +1,269 @@
<template>
<div class="sop-list-component">
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
<el-form-item>
<el-button type="primary" @click="fileUploadHandle()">文件上传</el-button>
<el-button type="danger" @click="batchDeleteHandle()" :disabled="dataListSelections.length === 0">删除</el-button>
</el-form-item>
</el-form>
<el-table
:data="dataList"
border
v-loading="dataListLoading"
@selection-change="selectionChangeHandle"
:height="tableHeight"
style="width: 100%;">
<el-table-column
type="selection"
header-align="center"
align="center"
width="50">
</el-table-column>
<el-table-column
prop="sopNo"
header-align="center"
align="center"
label="文件编码"
width="120">
</el-table-column>
<el-table-column
prop="sopName"
header-align="center"
align="left"
label="文件名称"
min-width="200">
</el-table-column>
<el-table-column
prop="sopType"
header-align="center"
align="center"
label="文件类型"
width="100">
</el-table-column>
<el-table-column
prop="fileSuffix"
header-align="center"
align="center"
label="文件后缀"
width="100">
</el-table-column>
<el-table-column
prop="version"
header-align="center"
align="center"
label="版本号"
width="100">
</el-table-column>
<el-table-column
prop="phaseInDate"
header-align="center"
align="center"
label="生效日期"
width="120">
</el-table-column>
<el-table-column
prop="phaseOutDate"
header-align="center"
align="center"
label="失效日期"
width="120">
</el-table-column>
<el-table-column
prop="sourceSystem"
header-align="center"
align="center"
label="来源系统"
width="100">
</el-table-column>
<el-table-column
prop="standardFields"
header-align="center"
align="center"
label="4个标准字段"
width="120">
</el-table-column>
<el-table-column
fixed="right"
header-align="center"
align="center"
width="100"
label="操作">
<template slot-scope="scope">
<a type="text" size="small" @click="previewHandle(scope.row)">预览</a>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
:current-page="pageIndex"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
:total="totalPage"
layout="total, sizes, prev, pager, next, jumper"
style="margin-top: 10px;">
</el-pagination>
<!-- 文件上传弹窗 -->
<sop-file-upload
v-if="sopFileUploadVisible"
ref="sopFileUpload"
@refreshDataList="getDataList">
</sop-file-upload>
</div>
</template>
<script>
import SopFileUpload from './sopFileUpload'
import { sopListSearch, sopRecordDelete } from '@/api/qc/qc.js'
export default {
name: 'SopListComponent',
components: {
SopFileUpload
},
props: {
partNo: {
type: String,
default: ''
},
site: {
type: [String, Number],
default: ''
},
tableHeight: {
type: Number,
default: 200
}
},
data () {
return {
dataForm: {},
dataList: [],
pageIndex: 1,
pageSize: 20,
totalPage: 0,
dataListLoading: false,
dataListSelections: [],
sopFileUploadVisible: false
}
},
watch: {
partNo: {
handler (newVal) {
if (newVal) {
this.getDataList()
}
},
immediate: true
}
},
methods: {
//
getDataList () {
if (!this.partNo) {
this.dataList = []
this.totalPage = 0
return
}
this.dataListLoading = true
sopListSearch({
page: this.pageIndex,
limit: this.pageSize,
partNo: this.partNo,
site: this.site || this.$store.state.user.site
}).then(({data}) => {
if (data && data.code === 0) {
this.dataList = data.page.list || []
this.totalPage = data.page.totalCount || 0
} else {
this.dataList = []
this.totalPage = 0
}
this.dataListLoading = false
}).catch(() => {
this.dataList = []
this.totalPage = 0
this.dataListLoading = false
})
},
//
sizeChangeHandle (val) {
this.pageSize = val
this.pageIndex = 1
this.getDataList()
},
//
currentChangeHandle (val) {
this.pageIndex = val
this.getDataList()
},
//
selectionChangeHandle (val) {
this.dataListSelections = val
},
//
fileUploadHandle () {
if (!this.partNo) {
this.$message.warning('请先选择物料')
return
}
this.sopFileUploadVisible = true
this.$nextTick(() => {
this.$refs.sopFileUpload.init(this.partNo, this.site)
})
},
//
previewHandle (row) {
if (row.sopUrl) {
window.open(row.sopUrl, '_blank')
} else {
this.$message.warning('该文件暂无预览路径')
}
},
//
batchDeleteHandle () {
if (this.dataListSelections.length === 0) {
this.$message.warning('请先选择要删除的记录')
return
}
this.$confirm(`确定要删除选中的${this.dataListSelections.length}条SOP记录吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const deletePromises = this.dataListSelections.map(row => {
return sopRecordDelete({
site: row.site,
buNo: row.buNo,
partNo: row.partNo,
sopNo: row.sopNo
})
})
Promise.all(deletePromises).then((responses) => {
const successCount = responses.filter(({data}) => data && data.code === 0).length
if (successCount === this.dataListSelections.length) {
this.$message.success(`成功删除${successCount}条记录`)
} else {
this.$message.warning(`删除了${successCount}条记录,${this.dataListSelections.length - successCount}条删除失败`)
}
this.getDataList()
}).catch(() => {
this.$message.error('删除失败')
})
}).catch(() => {})
}
}
}
</script>
<style scoped>
.sop-list-component {
padding: 10px;
}
</style>
Loading…
Cancel
Save