<template>
|
<GlobalWindow width="100%" title="工单详情" :visible.sync="visible" :confirm-working="isWorking" @close="close"
|
@confirm="confirm">
|
<div class="main">
|
<div class="title">
|
<div class="title_left">
|
<span>工单详情</span>
|
<div>
|
<div class="status primaryColor" v-if="info.dealStatus == 0 || info.dealStatus == null">待指派</div>
|
<div class="status green" v-if="info.dealStatus == 1">已指派</div>
|
<div class="status gray" v-if="info.dealStatus == 2">已处理</div>
|
</div>
|
</div>
|
<el-button v-if="info.origin === 1" @click="openWT">查看问题上报</el-button>
|
</div>
|
<div class="main_content">
|
<div class="list">
|
<div class="item">
|
<div class="la">位置类型</div>
|
<div class="val">{{ info.areaType == 0 ? '室内维修' : '公共维修' }}</div>
|
</div>
|
<div class="item">
|
<div class="la">对应位置</div>
|
<div class="val">{{ info.projectName }}/{{ info.buildingName }} / {{ info.roomNum || info.floorName }}</div>
|
</div>
|
<div class="item">
|
<div class="la">工单分类</div>
|
<div class="val">{{ info.categoryName }}</div>
|
</div>
|
<div class="item">
|
<div class="la">来源</div>
|
<div class="val" v-if="info.origin === 0">自建</div>
|
<div class="val" v-if="info.origin === 1">问题转工单</div>
|
</div>
|
<div class="item">
|
<div class="la">上报人</div>
|
<div class="val">{{ info.creatorName }}{{ info.creatorCompany ? "-" + info.creatorCompany : '' }}</div>
|
</div>
|
<div class="item">
|
<div class="la">上报人电话</div>
|
<div class="val">{{ info.creatorPhone || info.creatorMobile }}</div>
|
</div>
|
<div class="item">
|
<div class="la">上报时间</div>
|
<div class="val">{{ info.createDate }}</div>
|
</div>
|
<div class="item max" v-if="info.areaType == 0">
|
<div class="la">上门时间</div>
|
<div class="val">{{ info.getDate }}</div>
|
</div>
|
<div class="item max">
|
<div class="la">问题描述</div>
|
<div class="val">{{ info.content }}</div>
|
</div>
|
<div class="item max">
|
<div class="la">问题图片</div>
|
<div class="value" v-if="info.fileList == null || !info.fileList.length">无</div>
|
<div class="value" v-if="info.fileList != null && info.fileList.length">
|
<div v-for="item in info.fileList" :key="item.id" style="display: inline;margin-right: 20px">
|
<!-- <video v-if="item.fileurlFull && item.fileurlFull.endsWith('.mp4')" ref="videoRef" controls
|
preload="auto" style="width: 80px;height: 80px;object-fit: contain;" :src="item.fileurlFull" /> -->
|
<el-image v-if="item.type == 0" style="width:80px; height: 80px" :src="item.fileurlFull"
|
:preview-src-list="[item.fileurlFull]">
|
</el-image>
|
</div>
|
</div>
|
</div>
|
<div v-if="info.fileList && info.fileList.length > 0 && info.fileList.filter(i => i.type == 1).length > 0"
|
class="item max">
|
<div class="la">问题视频</div>
|
<div class="value">
|
<div v-for="item in info.fileList" :key="item.id" style="display: inline;margin-right: 20px">
|
<video v-if="item.type == 1" ref="videoRef" controls preload="auto"
|
style="width: 240px;height: 160px;object-fit: contain;" :src="item.fileurlFull" />
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="side">
|
<div class="title">工单流转记录</div>
|
<div class="flow_list">
|
<div class="item" v-for="item, i in info.logList">
|
<div class="icon">
|
<div class="dian"></div>
|
<div v-if="i < info.logList.length - 1" class="line"></div>
|
</div>
|
<div class="content">
|
<div class="name">{{ item.title }}</div>
|
<div class="time">操作时间:{{ item.createDate }}</div>
|
<div class="creator">操作人:{{ item.param1 }}</div>
|
<div class="creator" v-if="item.param2">指派给:{{ item.param2 }}</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="title"
|
v-if="info.dealStatus == 2 || info.dealStatus == 0 || (info.dealStatus == 1 && info.dealUserId === userInfo.id)">
|
{{ info.dealStatus == 0 || info.dealStatus == 1 ? '工单处理' : '处理结果' }}</div>
|
<el-form :model="param" ref="form" :rules="rules">
|
<template v-if="info.dealStatus == 0 || info.dealStatus == null">
|
<el-form-item label="处理方式" prop="dealType">
|
<div>
|
<el-radio v-model="param.dealType" :label="0">指派</el-radio>
|
<el-radio v-model="param.dealType" :label="1">直接回复</el-radio>
|
</div>
|
</el-form-item>
|
<el-form-item v-if="param.dealType == 0" label="指派给" prop="dealUserId">
|
<el-select v-model="param.dealUserId" clearable filterable class="w400">
|
<el-option v-for="item in staffList" :label="item.realname" :value="item.id"></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item v-if="param.dealType == 1" label="回复内容" prop="dealInfo">
|
<el-input type="textarea" class="w400" :rows="4" v-model="param.dealInfo" placeholder="请填写说明"></el-input>
|
</el-form-item>
|
</template>
|
<template v-if="info.dealStatus == 1 && info.dealUserId === userInfo.id">
|
<el-form-item label="处理时间" prop="getDate">
|
<el-date-picker type="datetime" class="w400" v-model="param.getDate" format="yyyy-MM-dd HH:mm"
|
value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择"></el-date-picker>
|
</el-form-item>
|
<el-form-item label="处理说明" prop="dealInfo">
|
<el-input type="textarea" class="w400" :rows="4" v-model="param.dealInfo" placeholder="请填写说明"></el-input>
|
</el-form-item>
|
<el-form-item label="现场图片">
|
<div class="file_list">
|
<el-upload class="avatar-uploader" :data="uploadData" :auto-upload="true" :action="uploadImgUrl"
|
:show-file-list="false" :on-success="uploadAvatarSuccess" :on-error="uploadError"
|
:before-upload="beforeUpload">
|
<div class="upload_wrap">
|
<i class="el-icon-plus avatar-uploader-icon"></i>
|
<div>图片/视频</div>
|
</div>
|
</el-upload>
|
<div v-for="(item, i) in dealFileList" :key="i" class="item">
|
<i @click="handleDelImg(i)" class="el-icon-error close"></i>
|
<el-image :src="item.fileurlFull" :preview-src-list="[item.fileurlFull]" v-if="item.type == 0"
|
class="img"></el-image>
|
<video :src="item.fileurlFull" controls v-if="item.type == 1" class="img"></video>
|
</div>
|
</div>
|
</el-form-item>
|
</template>
|
<template v-if="info.dealStatus == 2">
|
<div class="list">
|
<div class="item item2">
|
<div class="la">{{ info.dispatchUserId ? '处理人' : '回复人' }}:</div>
|
<div class="val">{{ info.dealUserName }}{{ info.dealUserCompany ? '-' + info.dealUserCompany : '' }}</div>
|
</div>
|
<div class="item item2">
|
<div class="la">{{ info.dispatchUserId ? '处理时间' : '回复时间' }}:</div>
|
<div class="val">{{ info.dealDate || info.getDate }}</div>
|
</div>
|
<div class="item item2">
|
<div class="la">{{ info.dispatchUserId ? '处理说明' : '回复内容' }}:</div>
|
<div class="val">{{ info.dealInfo }}</div>
|
</div>
|
<div v-if="info.dealFileList != null && info.dealFileList.length" class="item item2">
|
<div class="la">现场照片:</div>
|
<div class="value" v-if="info.dealFileList == null || !info.dealFileList.length">无</div>
|
<div class="value" v-if="info.dealFileList != null && info.dealFileList.length">
|
<div v-for="item in info.dealFileList" :key="item.id" style="display: inline;margin-right: 20px">
|
<video v-if="item.fileurlFull && item.fileurlFull.endsWith('.mp4')" ref="videoRef" controls
|
preload="auto" style="width: 80px;height: 80px;object-fit: contain;" :src="item.fileurlFull" />
|
<el-image v-else-if="item.fileurlFull" style="width:80px; height: 80px" :src="item.fileurlFull"
|
:preview-src-list="[item.fileurlFull]">
|
</el-image>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
</el-form>
|
</div>
|
<!-- 问题上报详情 -->
|
<problemReportingDetails ref="problemReportingDetails" />
|
</GlobalWindow>
|
</template>
|
|
<script>
|
import GlobalWindow from '@/components/common/GlobalWindow'
|
import BaseOpera from '@/components/base/BaseOpera'
|
import problemReportingDetails from './problemReportingDetails'
|
import { detailById, dispatchOrder, dealOrder } from '@/api/workorder/ywWorkorder'
|
import { getByWorkorderId } from '@/api/ywProblem'
|
import { getUserList } from '@/api/system/user'
|
import { Message, Loading } from 'element-ui'
|
import dayjs from 'dayjs'
|
export default {
|
components: {
|
GlobalWindow,
|
problemReportingDetails
|
},
|
extends: BaseOpera,
|
data() {
|
return {
|
id: '',
|
visible: false,
|
param: {
|
dealType: 0
|
},
|
info: {},
|
rules: {
|
dealType: [{ required: true, message: '请选择' }],
|
dealUserId: [{ required: true, message: '请选择' }],
|
},
|
staffList: [],
|
|
uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/visitsAdmin/cloudService/public/uploadBatch',
|
dealFileList: [],
|
uploadData: {
|
folder: 'YW_WORKORDER_FILE'
|
},
|
}
|
},
|
computed: {
|
userInfo() {
|
return this.$store.state.userInfo
|
}
|
},
|
created() {
|
this.getStaff()
|
},
|
methods: {
|
openWT() {
|
getByWorkorderId(this.id)
|
.then(res => {
|
console.log(res)
|
this.$refs.problemReportingDetails.open('问题上报详情', res)
|
})
|
},
|
confirm() {
|
this.$refs['form'].validate((valid) => {
|
if (valid) {
|
const { param, id, dealFileList, info } = this
|
let fn = null
|
if (info.dealStatus == 0 || info.dealStatus == null) {
|
fn = param.dealType == 0 ? dispatchOrder : dealOrder
|
} else {
|
fn = dealOrder
|
}
|
fn({
|
id,
|
...param,
|
dealFileList
|
}).then(res => {
|
Message.success('提交成功')
|
this.visible = false
|
this.$emit('success')
|
})
|
}
|
})
|
},
|
getDetail() {
|
const { id } = this
|
detailById(id).then(res => {
|
this.info = res
|
if (this.info.dealStatus == 1) {
|
this.$set(this.param, 'getDate', dayjs().format('YYYY-MM-DD HH:mm:ss'))
|
}
|
})
|
},
|
getStaff() {
|
getUserList({}).then(res => {
|
this.staffList = res
|
})
|
},
|
beforeUpload(file) {
|
if (['video/mp4', 'video/ogg', 'video/flv', 'video/avi', 'video/wmv', 'video/rmvb', 'image/jpeg', 'image/jpg', 'image/png', 'image/gif'].indexOf(file.type) == -1) {
|
this.$message.error('请上传正确的视频/图片格式')
|
return false
|
}
|
if (this.dealFileList.length > 8) return Message.warning('现场图片不能超过9张')
|
this.loadingInstance = Loading.service({
|
lock: true,
|
text: 'Loading',
|
spinner: 'el-icon-loading',
|
background: 'rgba(0, 0, 0, 0.7)'
|
})
|
},
|
uploadError() {
|
this.$nextTick(() => { // 以服务的方式调用的 Loading 需要异步关闭
|
if (this.loadingInstance) {
|
this.loadingInstance.close()
|
}
|
})
|
},
|
uploadAvatarSuccess(file) {
|
this.$nextTick(() => { // 以服务的方式调用的 Loading 需要异步关闭
|
if (this.loadingInstance) {
|
this.loadingInstance.close()
|
}
|
})
|
console.log('file', file)
|
const item = file.data[0]
|
if (['.mp4', '.avi', '.flv', '.wmv'].some(char => item.imgaddr.includes(char))) {
|
this.dealFileList.push({
|
type: 1,
|
fileurl: item.imgaddr,
|
fileurlFull: item.url
|
})
|
} else {
|
this.dealFileList.push({
|
type: 0,
|
fileurl: item.imgaddr,
|
fileurlFull: item.url
|
})
|
}
|
console.log('file', this.dealFileList)
|
// this.$set(this.param, 'faceImg', file.imgurl)
|
// this.$set(this.param, 'faceImgUrl', file.imgurlfull)
|
},
|
handleDelImg(i) {
|
this.dealFileList.splice(i, 1)
|
},
|
close() {
|
this.visible = false
|
this.$emit('close')
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
@import '@/assets/style/variables.scss';
|
|
.main {
|
padding-top: 20px;
|
|
.title {
|
|
margin-bottom: 10px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
.title_left {
|
display: flex;
|
align-items: center;
|
font-weight: 500;
|
font-size: 18px;
|
color: $primary-color;
|
.status {
|
padding: 0 12px;
|
height: 24px;
|
line-height: 24px;
|
border-radius: 2px;
|
border: 1px solid #00BA92;
|
color: #00BA92;
|
font-weight: 400;
|
font-size: 12px;
|
margin-left: 10px;
|
}
|
.primaryColor {
|
border: 1px solid rgba(63, 126, 239, .2);
|
background-color: rgba(63, 126, 239, .2);
|
}
|
.green {
|
background-color: rgba(83, 183, 148, .2);
|
border: 1px solid rgba(83, 183, 148, .2);
|
}
|
.gray {
|
color: #333333;
|
background-color: rgba(128, 128, 128, .2);
|
border: 1px solid rgba(128, 128, 128, .2);
|
}
|
}
|
}
|
|
.list {
|
display: flex;
|
flex-wrap: wrap;
|
/* background: #F7F7F7; */
|
border-radius: 2px;
|
padding: 15px 20px;
|
margin-bottom: 16px;
|
|
.item {
|
width: 33.3%;
|
margin-bottom: 14px;
|
|
.la {
|
color: #7f7f7f;
|
margin-bottom: 6px;
|
}
|
}
|
|
.item2 {
|
width: 100%;
|
display: flex;
|
align-items: center;
|
|
.la {
|
margin-bottom: 0;
|
width: 72px;
|
}
|
}
|
|
.max {
|
width: 100%;
|
}
|
}
|
|
.main_content {
|
display: flex;
|
|
.side {
|
width: 370px;
|
|
.title {
|
font-size: 14px;
|
}
|
|
.flow_list {
|
.item {
|
display: flex;
|
|
.icon {
|
width: 28px;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
|
.dian {
|
width: 12px;
|
height: 12px;
|
border-radius: 50%;
|
background-color: #e89e42;
|
}
|
|
.line {
|
width: 1px;
|
height: 100%;
|
background-color: #e89e42;
|
}
|
}
|
|
.content {
|
font-size: 12px;
|
color: #999999;
|
padding-bottom: 12px;
|
|
.name {
|
font-size: 13px;
|
color: #333333;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
.file_list {
|
display: flex;
|
flex-wrap: wrap;
|
|
.avatar-uploader {
|
width: 92px;
|
height: 92px;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
border: 1px dashed #d9d9d9;
|
}
|
|
.item {
|
width: 92px;
|
max-height: 92px;
|
margin-left: 10px;
|
position: relative;
|
border: 1px dashed #d9d9d9;
|
border-radius: 4px;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
|
.close {
|
font-size: 20px;
|
position: absolute;
|
right: -10px;
|
top: -10px;
|
z-index: 111;
|
color: red;
|
cursor: pointer;
|
}
|
|
.img {
|
width: 92px;
|
max-height: 92px;
|
}
|
}
|
}
|
</style>
|