<template>
<div>
<el-dialog
:visible.sync="dialogVisible"
width="70%"
:show-close="false"
:close-on-click-modal="false"
append-to-body
@open="handleOpen"
@close="handleClose"
>
<template slot="title">
<div style="text-align: center; font-size: 22px;">
{{ title }}
</div>
</template>
<el-form :model="detailForm" label-width="130px" v-loading="loading">
<el-row>
<el-col :span="8">
<el-form-item label="日期:">
<el-input readonly v-model="detailForm.recordDate"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="班别:">
<el-input readonly v-model="detailForm.workClass"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="异常机况:">
<el-table :data="eqpList" style="width: 100%" id="eqpTable">
<el-table-column prop="area" label="Area"></el-table-column>
<el-table-column prop="eqpId" label="Eqp Id"></el-table-column>
<el-table-column prop="eqpName" label="Eqp Name"></el-table-column>
<el-table-column prop="eqpStatus" label="Eqp Status"></el-table-column>
<el-table-column prop="eqpHour" label="Hour"></el-table-column>
<el-table-column prop="eqpUser" label="User"></el-table-column>
<el-table-column prop="comments" label="Comment"></el-table-column>
</el-table>
<el-input
type="textarea"
v-model="detailForm.abnormal"
:autosize="{ minRows: 2 }"
placeholder="请输入异常机况 或 选中粘贴图片"
@paste="handlePaste($event, abnormalImageRef)"
:readonly="!detailForm.editAuth"
></el-input>
<el-upload
ref="abnormalImageRef"
v-model="detailForm.abnormalImageList"
action="#"
:http-request="handleHttpUpload"
list-type="picture-card"
:before-upload="beforeUpload"
:on-success="() => uploadSuccess('abnormalImageList')"
:on-error="uploadError"
:accept="fileType.join(',')"
:on-preview="handlePreview"
:disabled="!detailForm.editAuth"
>
<i class="el-icon-plus"></i>
</el-upload>
</el-form-item>
<el-form-item label="产片:">
<el-table :data="lotList" style="width: 100%" id="lotTable">
<el-table-column prop="eqp" label="机台"></el-table-column>
<el-table-column prop="priority" label="Priority"></el-table-column>
<el-table-column prop="lotId" label="Lot ID"></el-table-column>
<el-table-column prop="maskTitle" label="Mask Title"></el-table-column>
<el-table-column prop="dueDay" label="Due Day"></el-table-column>
</el-table>
<el-input
type="textarea"
v-model="detailForm.product"
:autosize="{ minRows: 2 }"
placeholder="请输入产片 或 选中粘贴图片"
@paste="handlePaste($event, productImageRef)"
:readonly="!detailForm.editAuth"
></el-input>
<el-upload
ref="productImageRef"
v-model="detailForm.productImageList"
action="#"
:http-request="handleHttpUpload"
list-type="picture-card"
:before-upload="beforeUpload"
:on-success="() => uploadSuccess('productImageList')"
:on-error="uploadError"
:accept="fileType.join(',')"
:on-preview="handlePreview"
:disabled="!detailForm.editAuth"
>
<i class="el-icon-plus"></i>
</el-upload>
</el-form-item>
<el-form-item label="工程师交接事项:">
<el-input
type="textarea"
v-model="detailForm.engHandover"
:autosize="{ minRows: 2 }"
placeholder="请输入工程师交接事项 或 选中粘贴图片"
@paste="handlePaste($event, engHandoverImageRef)"
:readonly="!detailForm.editAuth"
></el-input>
<el-upload
ref="engHandoverImageRef"
v-model="detailForm.engHandoverImageList"
action="#"
:http-request="handleHttpUpload"
list-type="picture-card"
:before-upload="beforeUpload"
:on-success="() => uploadSuccess('engHandoverImageList')"
:on-error="uploadError"
:accept="fileType.join(',')"
:on-preview="handlePreview"
:disabled="!detailForm.editAuth"
>
<i class="el-icon-plus"></i>
</el-upload>
</el-form-item>
<el-form-item label="课长:" v-if="detailForm.managerName !== null">
<el-input v-model="detailForm.managerName" readonly></el-input>
</el-form-item>
<el-form-item label="接班人:" v-if="detailForm.assigneeName !== null">
<el-input type="textarea" v-model="detailForm.assigneeName" readonly autosize></el-input>
</el-form-item>
</el-form>
<template slot="footer">
<el-button type="primary" @click="save" v-if="detailForm.editAuth">保存</el-button>
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="submit" v-if="detailForm.submitAuth">提交</el-button>
<el-button type="primary" @click="audit" v-if="detailForm.auditAuth">审核</el-button>
<el-button type="primary" @click="assign" v-if="detailForm.assignAuth">签核</el-button>
</template>
</el-dialog>
<el-dialog :visible.sync="previewVisible" :show-close="false">
<img width="100%" :src="previewImageUrl" alt="Preview Image"/>
</el-dialog>
</div>
</template>
<script>
import { getJournalForEdit, saveJournal, submitJournal, auditJournal, assignJournal, clearEditUser } from '@/api/mfgLog/area';
import request from '@/utils/request';
import {Message, MessageBox } from "element-ui";
import dayjs from 'dayjs';
import { getToken } from '@/utils/auth'
export default {
data() {
return {
loading: false,
dialogVisible: false,
title: '光罩厂制造部站点交接记录簿',
fileType: ['image/jpeg', 'image/png', 'image/gif'],
abnormalImageRef: null,
engHandoverImageRef: null,
productImageRef: null,
previewVisible: false,
previewImageUrl: '',
detailForm: {
recordDate: '',
workClass: '',
workArea: '',
abnormal: '',
lotList: [],
eqpList: [],
abnormalImage: '',
abnormalImageList: [],
product: '',
productImage: '',
productImageList: [],
engHandover: '',
engHandoverImage: '',
engHandoverImageList: [],
managerName: '',
assigneeName: '',
editAuth: false,
submitAuth: false,
auditAuth: false,
assignAuth: false,
id: ''
},
timer: null
};
},
mounted() {
// 监听事件以重置计时器
window.addEventListener('keydown', this.resetTimer);
window.addEventListener('mousemove', this.resetTimer);
window.addEventListener('mouseenter', this.resetTimer);
// 浏览器关闭事件
window.addEventListener('beforeunload', (e) => {
this.userInactive();
});
},
beforeDestroy() {
// 清除事件监听和计时器
window.removeEventListener('keydown', this.resetTimer);
window.removeEventListener('mousemove', this.resetTimer);
window.removeEventListener('mouseenter', this.resetTimer);
clearTimeout(this.timer);
},
methods: {
handleOpen() {
this.resetTimer();
},
handleClose() {
clearTimeout(this.timer);
},
resetTimer() {
// 用户进行了操作,重置计时器
if (this.timer) {
clearTimeout(this.timer);
}
this.startTimer();
},
startTimer() {
// 设置5分钟后的无操作处理
this.timer = setTimeout(() => {
// 用户5分钟内无操作,执行相关逻辑
if (this.dialogVisible) {
this.userInactive();
}
}, 5 * 60 * 1000);
},
userInactive() {
// 用户处于非活跃状态的逻辑处理
if (this.detailForm.editAuth) {
this.save();
}
this.closeDialog();
},
showDialog(row) {
this.loading = true;
getJournalForEdit(row).then(res => {
Object.assign(this.detailForm, res.data);
// 显示提示信息
if (!this.detailForm.editAuth && !this.detailForm.assignAuth && this.detailForm.editUser) {
Message.warning({
message: "当前日志正在被 " + this.detailForm.editUserName + " 编辑",
position: 'top', // 确保消息显示在页面顶部
duration: 5000 // 消息显示时间为 5 秒
});
return 0;
}
this.detailForm.abnormalImageList = [];
if (this.detailForm.abnormalImage?.length > 0) {
let abnormalList = this.detailForm.abnormalImage.split(",");
for (let index in abnormalList) {
this.detailForm.abnormalImageList.push({ url: abnormalList[index] });
}
}
this.detailForm.productImageList = [];
if (this.detailForm.productImage?.length > 0) {
let productList = this.detailForm.productImage.split(",");
for (let index in productList) {
this.detailForm.productImageList.push({ url: productList[index] });
}
}
this.detailForm.engHandoverImageList = [];
if (this.detailForm.engHandoverImage?.length > 0) {
let engHandoverList = this.detailForm.engHandoverImage?.split(",");
for (let index in engHandoverList) {
this.detailForm.engHandoverImageList.push({ url: engHandoverList[index] });
}
}
if (this.detailForm.lotList && Array.isArray(this.detailForm.lotList)) {
this.lotList = this.detailForm.lotList;
} else {
this.lotList = []; // 否则初始化为空数组
}
if (this.detailForm.eqpList && Array.isArray(this.detailForm.eqpList)) {
this.eqpList = this.detailForm.eqpList;
} else {
this.eqpList = []; // 否则初始化为空数组
}
this.title = "光罩厂制造部 " + this.detailForm.workArea + " 站点交接记录簿";
// 判断当前时间是否允许提交/审核日志
if (this.detailForm.submitAuth || this.detailForm.auditAuth) {
// 白班18点30分之前不允许提交和审核
let authTime = this.detailForm.recordDate + " 18:30:00";
if ('N' == this.detailForm.workClass.substring(0, 1)) {
// 晚班06点30分之前不允许提交和审核
authTime = dayjs(this.detailForm.recordDate).add(1, 'day').format("YYYY-MM-DD") + " 06:30:00";
}
if (dayjs().isBefore(dayjs(authTime))) {
this.detailForm.submitAuth = false;
this.detailForm.auditAuth = false;
}
}
// 父系统页面打开遮罩
window.parent.postMessage("open", '*');
this.dialogVisible = true;
// 设置初始计时器
this.loading = false;
}).catch(error => {
console.log(error);
this.loading = false;
});
},
closeDialog() {
clearEditUser({ id: this.detailForm.id }).catch(error => {
Message.error(error.msg ? error.msg : error);
});
this.$emit('close');
// 父系统页面关闭遮罩
window.parent.postMessage("close", '*');
this.dialogVisible = false;
},
save() {
this.detailForm.abnormalImage = this.detailForm.abnormalImageList.map(item => item.url).join(",");
this.detailForm.productImage = this.detailForm.productImageList.map(item => item.url).join(",");
this.detailForm.engHandoverImage = this.detailForm.engHandoverImageList.map(item => item.url).join(",");
this.loading = true;
saveJournal(this.detailForm).then(res => {
this.loading = false;
Message.success("保存成功");
this.closeDialog();
}).catch(error => {
this.loading = false;
});
},
submit() {
MessageBox.confirm("确认要提交吗?", "提示", {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}).then(res => {
this.detailForm.abnormalImage = this.detailForm.abnormalImageList.map(item => item.url).join(",");
this.detailForm.productImage = this.detailForm.productImageList.map(item => item.url).join(",");
this.detailForm.engHandoverImage = this.detailForm.engHandoverImageList.map(item => item.url).join(",");
this.loading = true;
submitJournal(this.detailForm).then(res => {
this.loading = false;
Message.success("提交成功");
this.closeDialog();
}).catch(error => {
this.loading = false;
Message.error(error.msg ? error.msg : error);
});
}).catch(error => {
console.log(error);
});
},
audit() {
MessageBox.confirm("确认要提交审核吗?", "提示", {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}).then(res => {
this.detailForm.abnormalImage = this.detailForm.abnormalImageList.map(item => item.url).join(",");
this.detailForm.productImage = this.detailForm.productImageList.map(item => item.url).join(",");
this.detailForm.engHandoverImage = this.detailForm.engHandoverImageList.map(item => item.url).join(",");
this.detailForm.lotList = this.detailForm.lotList
this.detailForm.eqpList = this.detailForm.eqpList
this.loading = true;
auditJournal(this.detailForm).then(res => {
this.loading = false;
Message.success("审核成功");
this.closeDialog();
}).catch(error => {
this.loading = false;
Message.error(error.msg ? error.msg : error);
});
}).catch(error => {
console.log(error);
});
},
assign() {
MessageBox.confirm("确认要签核吗?", "提示", {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}).then(res => {
this.loading = true;
assignJournal({ id: this.detailForm.id }).then(res => {
this.loading = false;
Message.success("签核成功");
this.closeDialog();
}).catch(error => {
this.loading = false;
Message.error(error.msg ? error.msg : error);
});
}).catch(error => {
console.log(error);
});
},
handleHttpUpload(options) {
return process.env.VUE_APP_BASE_API + '/viewException/uploadImage'
},
headers(){
return {
"Authorization": 'Bearer ' + getToken()
}
},
beforeUpload(rawFile) {
const imgType = this.fileType.includes(rawFile.type);
if (!imgType) {
Message.warning({
title: '温馨提示',
message: '上传图片不符合所需的格式!',
});
}
return imgType;
},
uploadSuccess(imageListName) {
Message.success({
title: '温馨提示',
message: '图片上传成功!',
});
this.detailForm[imageListName].forEach(item => {
if (item.url.indexOf("/api/") < 0)
item.url = item.response.url;
});
},
uploadError() {
Message.error({
title: '温馨提示',
message: '图片上传失败,请您重新上传!',
});
},
handlePaste(event, uploadRef) {
const items = (event.clipboardData || window.clipboardData).items;
let file = null;
if (!items || items.length === 0) {
Message.error("当前浏览器不支持粘贴板");
return;
}
// 搜索剪切板items
for (let i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") !== -1) {
file = items[i].getAsFile();
break;
}
}
if (!file) {
return;
}
uploadRef.handleStart(file); // 将粘贴过来的图片加入预上传队列
uploadRef.submit(); // 提交图片上传队列
},
handlePreview(file) {
this.previewImageUrl = file.url;
this.previewVisible = true;
}
}
};
</script>
<style scoped>
.layout-padding-custom {
padding: 20px;
}
.border-vxe-table {
margin-top: 20px;
}
</style>
报错vue.runtime.esm.js:620 [Vue warn]: Error in v-on handler: "TypeError: reqs[uid].abort is not a function"
found in
---> <ElUploadList> at packages/upload/src/upload-list.vue
<ElUpload> at packages/upload/src/index.vue
<ElFormItem> at packages/form/src/form-item.vue
<ElForm> at packages/form/src/form.vue
<ElDialog> at packages/dialog/src/component.vue
<Detail> at src/views/mfgLog/area/detail.vue
<Index> at src/views/mfgLog/area/index.vue
<AppMain> at src/layout/components/AppMain.vue
<Layout> at src/layout/index.vue
<App> at src/App.vue
<Root>
warn @ vue.runtime.esm.js:620
logError @ vue.runtime.esm.js:1892
globalHandleError @ vue.runtime.esm.js:1887
handleError @ vue.runtime.esm.js:1847
invokeWithErrorHandling @ vue.runtime.esm.js:1870
invoker @ vue.runtime.esm.js:2187
invokeWithErrorHandling @ vue.runtime.esm.js:1862
Vue.$emit @ vue.runtime.esm.js:3897
click @ element-ui.common.js:28831
invokeWithErrorHandling @ vue.runtime.esm.js:1862
invoker @ vue.runtime.esm.js:2187
original._wrapper @ vue.runtime.esm.js:6951
vue.runtime.esm.js:1896 TypeError: reqs[uid].abort is not a function
at VueComponent.abort (element-ui.common.js:29351:21)
at VueComponent.abort (element-ui.common.js:29717:34)
at doRemove (element-ui.common.js:29688:16)
at VueComponent.handleRemove (element-ui.common.js:29695:9)
at invokeWithErrorHandling (vue.runtime.esm.js:1862:26)
at Proxy.invoker (vue.runtime.esm.js:2187:14)
at invokeWithErrorHandling (vue.runtime.esm.js:1862:26)
at Vue.$emit (vue.runtime.esm.js:3897:9)
at click (element-ui.common.js:28831:37)
at invokeWithErrorHandling (vue.runtime.esm.js:1862:26)
最新发布