<template> 
 | 
  <GlobalWindow width="100%" title="工单详情" :withFooter="withFooter" :visible.sync="visible" :confirm-working="isWorking" 
 | 
    @confirm="confirm" @close="closeView"> 
 | 
    <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 && isShow" @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> 
 | 
      <!--  问题上报详情  --> 
 | 
      <ProblemReportingDetails ref="problem_Reporting_Details" @close="closeDetails" /> 
 | 
    </div> 
 | 
  </GlobalWindow> 
 | 
</template> 
 | 
  
 | 
<script> 
 | 
import GlobalWindow from '@/components/common/GlobalWindow' 
 | 
import BaseOpera from '@/components/base/BaseOpera' 
 | 
// import ProblemReportingDetails from './problemReportingDetails' 
 | 
// import ProblemReportingDetails from '@/views/workorder/components/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 { mapState } from 'vuex' 
 | 
import dayjs from 'dayjs' 
 | 
export default { 
 | 
  name: 'detail', 
 | 
  components: { 
 | 
    GlobalWindow, 
 | 
    ProblemReportingDetails: () => import('./problemReportingDetails') 
 | 
  }, 
 | 
  extends: BaseOpera, 
 | 
  data() { 
 | 
    return { 
 | 
      id: '', 
 | 
      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' 
 | 
      }, 
 | 
      isShow: true, 
 | 
      test: false 
 | 
    } 
 | 
  }, 
 | 
  computed: { 
 | 
    userInfo() { 
 | 
      return this.$store.state.userInfo 
 | 
    }, 
 | 
    withFooter() { 
 | 
      if (this.info) { 
 | 
        return this.info.dealStatus === 0 || (this.info.dealStatus === 1 && (this.userInfo.id === this.info.dealUserId)); 
 | 
      } else { 
 | 
        return false; 
 | 
      } 
 | 
    } 
 | 
  }, 
 | 
  created() { 
 | 
    this.getStaff() 
 | 
  }, 
 | 
  methods: { 
 | 
    closeDetails() { 
 | 
      console.log('1') 
 | 
      this.test = false 
 | 
    }, 
 | 
    closeView() { 
 | 
      this.$emit('close') 
 | 
      this.visible = false 
 | 
    }, 
 | 
    open (title, target, show) { 
 | 
      this.title = title 
 | 
      this.isShow = show 
 | 
      this.id = target.workorderId 
 | 
      this.getDetail() 
 | 
    }, 
 | 
    openWT() { 
 | 
      getByWorkorderId(this.id) 
 | 
        .then(res => { 
 | 
          this.test = true 
 | 
          this.$nextTick(() => { 
 | 
            this.$refs.problem_Reporting_Details.open('问题上报详情', res, false) 
 | 
          }) 
 | 
        }) 
 | 
    }, 
 | 
    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')) 
 | 
        } 
 | 
        this.visible = true 
 | 
      }) 
 | 
    }, 
 | 
    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> 
 |