<template>
|
<div class="main-container">
|
<el-form :model="problem" label-width="auto" style="max-width: 95%">
|
<el-form-item label="问题类型" prop="proType">
|
<el-select v-model="proType" @change="onProTypeChange" class="row" :disabled="readonly">
|
<el-option
|
v-for="item in problemTypeOptions"
|
:key="item.typeid"
|
:label="item.typename"
|
:value="item.typename"
|
/>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="问题描述" prop="description">
|
<el-select
|
v-model="deepCopyProblem.description"
|
@change="onProDesChange"
|
class="row"
|
:disabled="readonly"
|
>
|
<el-option
|
v-for="item in descriptionOptions"
|
:key="item.guid"
|
:label="item.description"
|
:value="item.guid"
|
/>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="问题位置" prop="locationid">
|
<el-select
|
v-model="deepCopyProblem.locationid"
|
@change="onProLocationChange"
|
class="row"
|
:disabled="readonly"
|
>
|
<el-option
|
v-for="item in posList"
|
:key="item.index"
|
:label="item.text"
|
:value="item.index"
|
/>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="问题建议" prop="advise">
|
<el-select v-model="deepCopyProblem.advise" class="row" :disabled="readonly">
|
<el-option
|
v-for="item in adviseOptions"
|
:key="item.adGuid"
|
:label="item.adName"
|
:value="item.adName"
|
/>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="补充说明" :disabled="readonly" prop="proRemark">
|
<el-input
|
v-model="proRemark"
|
type="textarea"
|
@change="onProRemarkChange"
|
class="row"
|
placeholder="请输入"
|
/>
|
</el-form-item>
|
<div class="t-card_item">
|
问题图片
|
<div>
|
<el-button @click="chosePicFromAnyPic" v-show="!readonly">从任意图片选取</el-button>
|
<el-button @click="chosePicFromDevicePic" v-show="!readonly">从设备图片选取</el-button>
|
<el-button @click="chosePicFromLedgerPic" v-show="!readonly">从台账选取</el-button>
|
<el-button @click="choseChangePic" v-show="!readonly">从文件夹选取</el-button>
|
</div>
|
</div>
|
<el-upload
|
class="img-upload"
|
ref="uploadRef"
|
v-model:file-list="fileList"
|
list-type="picture-card"
|
multiple
|
:auto-upload="false"
|
crossorigin="Anonymous"
|
:before-remove="beforeRemoveFile"
|
:on-preview="handlePictureCardPreview"
|
:disabled="readonly"
|
accept="image/*"
|
>
|
<el-button type="primary" id="uploadBtnId" style="display: none"></el-button>
|
<el-icon>
|
<Plus />
|
</el-icon>
|
</el-upload>
|
<el-form-item>
|
<el-button type="primary" @click="onSubmit" v-show="!readonly">保存</el-button>
|
<el-button @click="this.$emit('submited', false)" v-show="!readonly">取消</el-button>
|
</el-form-item>
|
</el-form>
|
<el-dialog
|
title="任意图片"
|
width="80%"
|
v-model="anyPhotoDialog"
|
:before-close="beforeAnyPhotoDialogclose"
|
class="dialog_style"
|
>
|
<ArbitraryPhoto
|
v-if="anyPhotoDialog"
|
@selectByAnyPhonoEvent="handleSelectedAnyPhono"
|
:subtask="subtask"
|
:defaultFile="fileList"
|
ref="arbitraryPhotoRef"
|
>
|
</ArbitraryPhoto>
|
</el-dialog>
|
<el-dialog
|
width="80%"
|
v-model="ledgerPicDialog"
|
:before-close="beforeLedgerPicDialogclose"
|
class="dialog_style"
|
>
|
<LedgerPic
|
v-if="ledgerPicDialog"
|
@selectByLedgerPicEvent="handleLedgerPicPhono"
|
:month="month"
|
:subtask="subtask"
|
:defaultFile="fileList"
|
ref="ledgerPicRef"
|
>
|
</LedgerPic>
|
</el-dialog>
|
<el-dialog
|
title="设备图片"
|
width="80%"
|
v-model="deiveceImgDialog"
|
:before-close="beforeDeiveceImgDialogclose"
|
class="dialog_style"
|
>
|
<CompDevicePhono
|
v-if="deiveceImgDialog"
|
@selectPhonoEvent="handleSelectedDevicePhono"
|
:imgPathsDataSource="deviceImgObjList"
|
:defaultFile="fileList"
|
ref="deiveceImgDialogRef"
|
>
|
</CompDevicePhono>
|
</el-dialog>
|
<el-dialog v-model="previewDialogVisible">
|
<img w-full :src="previewDialogImageUrl" alt="预览" class="preview-pic"/>
|
</el-dialog>
|
</div>
|
</template>
|
<script>
|
import ArbitraryPhoto from './ArbitraryPhoto.vue';
|
import LedgerPic from './CompLedgerPic.vue';
|
import CompDevicePhono from './CompDevicePhono.vue';
|
import problemApi from '@/api/fysp/problemApi.js';
|
|
import { $fysp } from '@/api/index.js';
|
import fileUtil from '@/utils/fileUtils.js';
|
import { useCloned } from '@vueuse/core';
|
import { ElMessage } from 'element-plus';
|
import deviceApi from '@/api/fysp/deviceApi';
|
export default {
|
components: {
|
ArbitraryPhoto,
|
LedgerPic,
|
CompDevicePhono
|
},
|
props: {
|
readonly: {
|
type: Boolean,
|
default: false
|
},
|
topTask: {
|
type: Object,
|
default: () => {
|
return {};
|
}
|
},
|
subtask: {
|
type: Object,
|
default: () => {
|
return {};
|
}
|
},
|
insGuid: {
|
type: String
|
},
|
problem: {
|
type: Object,
|
default: () => {
|
return {};
|
}
|
}
|
},
|
data() {
|
return {
|
previewDialogVisible: false,
|
previewDialogImageUrl: '',
|
// 设备图片列表
|
deviceImgObjList: [],
|
// 0代表新增 1修改
|
type: -1,
|
deepCopyProblem: {},
|
currProTypeGuid: '',
|
proType: '',
|
proRemark: null,
|
|
suggestions: [],
|
problemTypeList: [],
|
posList: [],
|
|
fileList: [],
|
oldFileList: [],
|
deleteImg: [],
|
deiveceImgDialog: false,
|
anyPhotoDialog: false,
|
// 台账
|
month: -1,
|
ledgerPicDialog: false,
|
rules: {
|
proType: { required: true, message: '问题类型不能为空', trigger: 'change' },
|
description: { required: true, message: '问题描述不能为空', trigger: 'change' },
|
locationid: { required: true, message: '问题位置不能为空', trigger: 'change' },
|
advise: { required: true, message: '问题建议不能为空', trigger: 'change' },
|
proRemark: { required: true, message: '补充说明不能为空', trigger: 'change' }
|
},
|
deviceTopTypes: [
|
{ id: 0, label: '监控设备' },
|
{ id: 1, label: '治理设备' },
|
{ id: 2, label: '生产设备' }
|
]
|
};
|
},
|
watch: {
|
fileList: {
|
handler(newFileList, oldFileList) {
|
console.log('newFileList', newFileList);
|
// 图片校验
|
this.pictureValidate();
|
},
|
deep: true
|
}
|
},
|
computed: {
|
descriptionOptions() {
|
const descriptions = [];
|
this.problemTypeList.forEach((item) => {
|
if (item.typename == this.proType) {
|
descriptions.push(item);
|
}
|
});
|
return descriptions;
|
},
|
problemTypeOptions() {
|
return this.problemTypeList.reduce((acc, current) => {
|
const x = acc.find((item) => item.typeid === current.typeid);
|
if (!x) {
|
acc.push(current);
|
}
|
return acc;
|
}, []);
|
},
|
adviseOptions() {
|
var array = this.suggestions.filter((item) => item.adProblemtypeguid == this.currProTypeGuid);
|
console.log('adName', array);
|
|
return array;
|
}
|
},
|
mounted() {
|
this.initOptions();
|
this.getDeviceImgList();
|
},
|
methods: {
|
handlePictureCardPreview(uploadFile) {
|
this.previewDialogVisible = true;
|
this.previewDialogImageUrl = uploadFile.url;
|
},
|
beforeDeiveceImgDialogclose() {
|
this.deiveceImgDialog = false;
|
},
|
// 标准化属性名
|
convertKeys(obj) {
|
// 将一个js对象中所有di,wi,pi开头的属性全部改成去掉这些前缀并且重新变为驼峰式命名
|
const newObj = {};
|
for (const key in obj) {
|
if (obj.hasOwnProperty(key)) {
|
let newKey = key;
|
if (key.startsWith('di')) {
|
newKey = key.substring(2);
|
} else if (key.startsWith('wi')) {
|
newKey = key.substring(2);
|
} else if (key.startsWith('pi')) {
|
newKey = key.substring(2);
|
}
|
newKey = newKey.charAt(0).toLowerCase() + newKey.slice(1);
|
newObj[newKey] = obj[key];
|
}
|
}
|
return newObj;
|
},
|
// 保存状态信息
|
saveStatus(device, status) {
|
var _picUrl = $fysp.imgUrl + status.dlPicUrl;
|
device._picUrl = _picUrl;
|
status._picUrl = _picUrl;
|
if ('_statusList' in device) {
|
device._statusList.push(status);
|
} else {
|
device._statusList = Array.of(status);
|
}
|
// 排序
|
device._statusList.sort(function (x, y) {
|
return new Date(x.dlCreateTime) - new Date(y.dlCreateTime); // 降序,升序则反之
|
});
|
},
|
getDeviceImgList() {
|
this.deviceImgObjList = [];
|
this.deviceTopTypes.forEach(e => {
|
|
const topTypeId = e.id;
|
deviceApi.fetchDevices(this.subtask.sceneId, topTypeId).then((result) => {
|
// 标准化属性名
|
for (let i = 0; i < result.data.length; i++) {
|
var element = this.convertKeys(result.data[i]);
|
// 获取设备状态信息
|
let data = {
|
deviceId: element.id,
|
sceneId: element.sceneGuid,
|
deviceTypeId: topTypeId
|
};
|
deviceApi
|
.fetchDeviceStatus(data)
|
.then((status) => {
|
var statusData = status.data;
|
var imgPaths = [];
|
|
if (statusData) {
|
if (statusData.length == 0) {
|
this.deviceImgObjList.push(element);
|
return;
|
}
|
element = this.convertKeys(result.data[i]);
|
for (let j = 0; j < statusData.length; j++) {
|
// 复制出一个设备对象
|
var newDevice = useCloned(element).cloned.value;
|
const statusItem = statusData[j];
|
// 设备对象添加一个属性列表属性用来保存设备状态
|
this.saveStatus(newDevice, statusItem);
|
newDevice.dlLocation = statusItem.dlLocation;
|
newDevice.topTypeId = topTypeId;
|
console.log('newDevice.topTypeId', newDevice.topTypeId);
|
console.log('newDevice', newDevice);
|
|
this.deviceImgObjList.push(newDevice);
|
}
|
}
|
})
|
.catch((err) => {});
|
}
|
});
|
});
|
},
|
initOptions() {
|
if (this.problem == undefined || this.problem == null) {
|
this.problem = {};
|
this.deepCopyProblem = {};
|
} else {
|
this.deepCopyProblem = useCloned(this.problem).cloned.value;
|
}
|
|
this.type = 'guid' in this.deepCopyProblem ? 1 : 0;
|
// 获取问题类型
|
let data = {
|
sceneTypeId: this.subtask.sceneTypeId,
|
cityCode: this.topTask.citycode,
|
districtCode: this.topTask.districtcode
|
};
|
problemApi.fetchProblemType(data).then((res) => {
|
this.problemTypeList = res.data;
|
|
if (this.type == 1) {
|
let currProName = String(this.problem.problemname);
|
|
let currDescription;
|
if (currProName.lastIndexOf('(') == -1) {
|
currDescription = currProName;
|
this.problemTypeList.forEach((item) => {
|
if (item.description == currDescription) {
|
this.proType = item.typename;
|
}
|
});
|
this.deepCopyProblem.description = currDescription;
|
this.proRemark = '';
|
} else {
|
currDescription = currProName.substring(0, currProName.lastIndexOf('('));
|
|
this.problemTypeList.forEach((item) => {
|
if (item.description === currDescription) {
|
this.proType = item.typename;
|
}
|
});
|
this.deepCopyProblem.description = currDescription;
|
this.proRemark = currProName.substring(
|
currProName.lastIndexOf('(') + 1,
|
currProName.length - 1
|
);
|
}
|
|
let beforeEditImgList = [];
|
let oldFiles = this.problem.mediafileList;
|
if (oldFiles && oldFiles.length > 0) {
|
this.problem.mediafileList.forEach((item) => {
|
if (item.ischanged == 0) {
|
item.url = $fysp.imgUrl + item.extension1 + item.guid + '.jpg';
|
item.name = '1';
|
beforeEditImgList.push(item);
|
}
|
});
|
this.fileList = useCloned(beforeEditImgList).cloned.value;
|
this.oldFileList = useCloned(beforeEditImgList).cloned.value;
|
}
|
}
|
});
|
|
// 问题建议
|
problemApi.getSuggestion().then((res) => {
|
this.suggestions = res.data;
|
// 填充当前问题建议
|
this.deepCopyProblem.advise = this.suggestions.filter(
|
(item) => item.adProblemtypeguid == this.deepCopyProblem.guid
|
)[0].adName;
|
});
|
|
// 问题位置
|
problemApi
|
.getLocation({
|
sceneTypeId: this.subtask.sceneTypeId
|
})
|
.then((res) => {
|
this.posList = res.data;
|
});
|
},
|
beforeRemoveFile(file, fileList) {
|
if (file.remark == '已上传') {
|
this.deleteImg.push(file.guid);
|
this.oldFileList.filter((item) => item.url != file.url);
|
}
|
},
|
handleLedgerPicPhono() {
|
this.beforeLedgerPicDialogclose();
|
let isExist = false;
|
for (const item of data) {
|
for (const already of this.fileList) {
|
if (item.url == already.url) {
|
isExist = true;
|
}
|
}
|
if (!isExist) {
|
this.fileList.push({
|
url: item.url,
|
name: '1'
|
});
|
}
|
isExist = false;
|
}
|
},
|
beforeLedgerPicDialogclose() {
|
this.ledgerPicDialog = false;
|
},
|
findProTypeByGuid(guid) {
|
let result;
|
this.problemTypeList.forEach((item) => {
|
if (item.guid == guid) {
|
result = item;
|
}
|
});
|
return result;
|
},
|
changeProblemname() {
|
if (this.proRemark == null || this.proRemark == '') {
|
this.deepCopyProblem.problemname = this.deepCopyProblem.description;
|
} else {
|
this.deepCopyProblem.problemname =
|
this.deepCopyProblem.description + '(' + this.proRemark + ')';
|
}
|
},
|
onProRemarkChange(value) {
|
this.changeProblemname();
|
},
|
onProTypeChange(value) {
|
this.deepCopyProblem.description = '';
|
this.deepCopyProblem.advise = '';
|
},
|
onProDesChange(value) {
|
let currPro = this.findProTypeByGuid(value);
|
this.deepCopyProblem.advise = '';
|
this.currProTypeGuid = value;
|
this.deepCopyProblem.description = currPro.description;
|
this.changeProblemname();
|
this.deepCopyProblem.advise = '';
|
|
this.deepCopyProblem.advise = this.adviseOptions[0].adName;
|
},
|
onProLocationChange(value) {
|
this.posList.forEach((item) => {
|
if (item.index == value) {
|
this.deepCopyProblem.location = item.text;
|
}
|
});
|
},
|
pictureValidate() {
|
if (this.fileList.length < 1) {
|
ElMessage({
|
message: '至少上传一张图片',
|
type: 'error'
|
});
|
return false;
|
} else if (this.fileList.length > 3) {
|
ElMessage({
|
message: '超过三张, 已删除多出的图片',
|
type: 'error'
|
});
|
this.fileList = this.fileList.slice(0, 3);
|
return false;
|
}
|
return true;
|
},
|
// TODO
|
validateForm() {},
|
onSubmit() {
|
this.validateForm();
|
// 图片校验
|
if (!this.pictureValidate()) {
|
return;
|
}
|
// 数据准备
|
let deepCopyPro = useCloned(this.deepCopyProblem).cloned.value;
|
let data = new FormData();
|
var picUrls = [];
|
this.fileList.forEach((item) => {
|
if (!('guid' in item)) {
|
// 新的
|
let exclude = false;
|
for (let index = 0; index < this.oldFileList.length; index++) {
|
const element = this.oldFileList[index];
|
if (item.url == element.url) {
|
exclude = true;
|
break;
|
}
|
}
|
if (!exclude) {
|
picUrls.push(item.url);
|
}
|
exclude = false;
|
// picUrls.push(item)
|
} else {
|
}
|
});
|
if (this.type == 1) {
|
let deleteImgCopy = this.deleteImg;
|
fileUtil.getImageFiles(picUrls, function (files) {
|
data.append('deleteImg', deleteImgCopy);
|
delete deepCopyPro['mediafileList'];
|
delete deepCopyPro['description'];
|
data.append('problem', JSON.stringify(deepCopyPro));
|
files.forEach((image) => {
|
data.append('images', image);
|
});
|
problemApi.updateProblem(data).then((res) => {});
|
});
|
} else {
|
const deepCopySubTask = useCloned(this.subtask).cloned.value;
|
const that = this;
|
fileUtil.getImageFiles(picUrls, function (files) {
|
console.log('deepCopySubTask', deepCopySubTask);
|
deepCopyPro.insGuid = deepCopySubTask.insGuid;
|
delete deepCopyPro['advise'];
|
delete deepCopyPro['description'];
|
deepCopyPro.proName = deepCopyPro.problemname;
|
delete deepCopyPro['problemname'];
|
deepCopyPro.ptGuid = that.findProTypeByGuid(that.currProTypeGuid).guid;
|
deepCopyPro.locationId = deepCopyPro.locationid;
|
delete deepCopyPro['locationid'];
|
data.append('problemVo', JSON.stringify(deepCopyPro));
|
files.forEach((image) => {
|
data.append('images', image);
|
});
|
problemApi.newProblem(data).then((res) => {});
|
});
|
}
|
this.$emit('submited', true);
|
},
|
handleSelectedAnyPhono(data) {
|
this.beforeAnyPhotoDialogclose();
|
let isExist = false;
|
for (const item of data) {
|
for (const already of this.fileList) {
|
if (item.url == already.url) {
|
isExist = true;
|
}
|
}
|
if (!isExist) {
|
this.fileList.push({
|
url: item.url,
|
name: '1'
|
});
|
}
|
isExist = false;
|
}
|
},
|
handleSelectedDevicePhono(data) {
|
this.beforeDeiveceImgDialogclose();
|
let isExist = false;
|
for (const item of data) {
|
for (const already of this.fileList) {
|
if (item._picUrl == already.url) {
|
isExist = true;
|
}
|
}
|
if (!isExist) {
|
this.fileList.push({
|
url: item._picUrl,
|
name: '1'
|
});
|
}
|
isExist = false;
|
}
|
},
|
handleLedgerPicPhono(data) {
|
let isExist = false;
|
for (const item of data) {
|
for (const already of this.fileList) {
|
if (item.url == already.url) {
|
isExist = true;
|
}
|
}
|
if (!isExist) {
|
this.fileList.push({
|
url: item.url,
|
name: '1'
|
});
|
}
|
isExist = false;
|
}
|
|
this.beforeAnyPhotoDialogclose();
|
},
|
chosePicFromAnyPic() {
|
this.anyPhotoDialog = true;
|
},
|
chosePicFromDevicePic() {
|
this.deiveceImgDialog = true;
|
},
|
chosePicFromLedgerPic() {
|
// 使用Date对象解析日期字符串
|
var date = new Date(this.subtask.subtask.planstarttime);
|
// 获取月份信息,月份是从0开始的,所以需要加1
|
this.month = date.getMonth() + 1;
|
if (String(this.month).length == 1) {
|
this.month = `0${this.month}`;
|
}
|
var year = date.getFullYear();
|
this.month = `${year}-${this.month}`;
|
this.ledgerPicDialog = true;
|
},
|
// 从文件夹中
|
choseChangePic() {
|
// 获取指定ID的元素
|
var btnElement = document.getElementById('uploadBtnId');
|
// 检查元素是否存在
|
if (btnElement) {
|
// 触发点击事件
|
btnElement.click();
|
}
|
},
|
beforeAnyPhotoDialogclose() {
|
this.anyPhotoDialog = false;
|
},
|
beforeLedgerPicDialogclose() {
|
this.ledgerPicDialog = false;
|
},
|
|
destoryMyself() {
|
this.$destroy();
|
}
|
}
|
};
|
</script>
|
<style scoped>
|
.main-container {
|
padding: 3px;
|
}
|
.t-card_item {
|
display: flex;
|
}
|
|
.w-msg-img {
|
position: absolute;
|
width: 25rem;
|
height: 27rem;
|
}
|
|
.img-upload {
|
margin-top: 30px;
|
margin-bottom: 30px;
|
margin-left: 63px;
|
}
|
.row {
|
width: 100%;
|
}
|
|
::v-deep .el-dialog__body {
|
width: 95%;
|
}
|
::v-deep .el-upload-list--picture-card .el-upload-list__item-thumbnail {
|
object-fit: cover !important;
|
}
|
.preview-pic {
|
object-fit: cover;
|
width: 100%;
|
height: 100%;
|
}
|
</style>
|