MrShi
2025-03-12 69a1b3bf45738f048361ee4ccb6bdc64fce35720
admin/src/components/business/OperaHiddenDangerWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,774 @@
<template>
  <GlobalWindow
      :title="title"
      :visible.sync="visible"
      @confirm="confirm"
      @close="reject"
  >
    <div class="modal_wrap">
      <div class="modal_content">
        <div class="header">
          <div class="left">
            <div class="h1">隐患提报</div>
            <div class="time">提报时间:{{model.createDate}}</div>
          </div>
          <div class="right" v-if="model.status==0">待处理</div>
          <div class="right"  style="background:#53b76f " v-if="model.status==1">已处理</div>
          <div class="right" style="background:#dc362e "  v-if="model.status==2">已退回</div>
        </div>
        <div class="info">
          <div class="title">隐患提报详情</div>
          <div class="list">
            <div class="item">
              <div class="label">提报人</div>
              <div class="value">{{model.memberName || ''}} {{model.memberPhone || ''}}</div>
            </div>
            <div class="item">
              <div class="label">隐患区域</div>
              <div class="value">{{model.areaName || ''}}</div>
            </div>
            <div class="item">
              <div class="label">隐患类型</div>
              <div class="value">{{model.categoryName || ''}}</div>
            </div>
            <div class="item">
              <div class="label">隐患描述</div>
              <div class="value">{{model.content || ''}}</div>
            </div>
            <div class="item" style="width: 100%">
              <div class="label">现场情况</div>
              <div class="value" v-if="model.submitFileList ==null || !model.submitFileList.length">无</div>
              <div class="value" v-if="model.submitFileList !=null && model.submitFileList.length">
                <div v-for="item in model.submitFileList" :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 class="item" v-if="model.status==1||model.status==2" style="width: 100%">
              <div class="label">处理前</div>
              <div class="value" v-if="model.dealBeforeFileList !=null && model.dealBeforeFileList.length">
                <div v-for="item in model.dealBeforeFileList" :key="item.id" style="display: inline;margin-right: 20px">
                  <video
                      v-if="item.fileurlFull && item.fileurlFull.endsWith('.mp4')"
                      ref="videoRef"
                      autoplay
                      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 class="item" v-if="model.status==1" style="width: 100%">
              <div class="label">处理后</div>
              <div class="value" v-if="model.dealAfterFileList !=null && model.dealAfterFileList.length">
                <div v-for="item in model.dealAfterFileList" :key="item.id" style="display: inline;margin-right: 20px">
                  <video
                      v-if="item.fileurlFull && item.fileurlFull.endsWith('.mp4')"
                      ref="videoRef"
                      autoplay
                      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 class="item" v-if="model.status==1 || model.status==2">
              <div class="label" v-if="model.status==1">处理说明</div>
              <div class="label" v-if="model.status==2">退回说明</div>
              <div class="value">{{model.checkInfo}}</div>
            </div>
          </div>
        </div>
      </div>
      <div class="side">
        <div class="side_title">审批流程</div>
        <div class="list">
          <div class="item" v-for="(item,index) in logList" :key="item.id">
            <div class="separate" v-if="index < logList.length-1"></div>
            <div class="info">
              <img src="@/assets/icons/ic_tongguo.png"   class="iconnew" v-if="(model.status ==1) || index < logList.length-1"/>
              <img src="@/assets/icons/ic_dangqian.png"   class="iconnew"   v-if="(model.status==0)  && index == logList.length-1"/>
              <img src="@/assets/icons/ic_jujue.png"  class="iconnew"   v-if="(model.status==2)  && index == logList.length-1"/>
              <img v-if="item.avatar!=null && item.avatar !=''" :src="item.avatar" class="avatar" alt="" />
              <img v-if="item.avatar ==null ||item.avatar ==''"  src="@/assets/avatar/man.png" class="avatar" alt="" />
              <div class="content">
                <div class="line">
                  <div class="name">{{ item.title}}</div>
                  <div class="time">{{ item.createDate }}</div>
                </div>
                <div class="line">
                  <div class="company">
                    {{ item.createUserName }}
                    <div style="display: inline" v-if="index == logList.length-1">
                      ï¼ˆ<span class="status-green" v-if="model.status==1">已处理</span>
                      <span class="status-blue" v-if="model.status==0">待处理</span>
                      <span class="status-red" v-if="model.status==2">已退回</span>)
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!--  -->
    <template   v-slot:footer>
      <el-button @click="openHandModal"  type="primary"  v-if="model.status==0&& model.checkUserId == userInfo.memberId"  class="status-red">处理</el-button>
      <el-button type="primary" plain v-if="model.status==0 && model.checkUserId == userInfo.memberId" @click="handleTransfer">转交</el-button>
      <el-button @click="openBackModal"  v-if="model.status==0&& model.checkUserId == userInfo.memberId" type="danger"  >退回</el-button>
      <el-button @click="visible=false">返回</el-button>
    </template>
    <el-dialog
        append-to-body
        title="转交"
        class="dialogCl"
        :visible.sync="isShowTransfer"
        width="480px"
    >
      <el-form :model="transForm" ref="transForm" :rules="rulesTrans">
        <el-form-item label="隐患转交人" prop="memberId">
          <el-select v-model="transForm.memberId" style="width: 300px"  filterable clearable placeholder="请选择转交安全员">
            <el-option
                v-for="item in memberList"
                :key="item.memberId"
                :label="item.companyName ? `${item.realname}-${item.companyName}` : item.realname"
                :value="item.memberId">
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShowTransfer = false">取消</el-button>
        <el-button type="primary" :loading="transfering" @click="transferSubmit">确定</el-button>
      </span>
    </el-dialog>
    <!-- é𐿂£ -->
    <el-dialog
        append-to-body
        title="隐患处理"
        class="dialogCl"
        :visible.sync="isShowProblem"
        width="600px"
    >
      <el-form :model="dealForm" :rules="rulesDeal" ref="dealForm" label-width="100px">
        <el-form-item label="整改时间" prop="checkDate">
          <el-date-picker
              class="w300"
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              placeholder="选择整改时间"
              v-model="dealForm.checkDate"
          />
        </el-form-item>
        <el-form-item label="整改前" prop="dealBeforeFileList">
          <div class="df_ac">
            <upload  width="80px" height="80px" :list="dealForm.dealBeforeFileList" :tips="'图片/视频'"  accept=".png,.jpg,.jpeg,.mp4" folder="hiddendanger" @loading="uploading = true" @dele="dele($event,0)" @success="uploadFileList($event, 0)" />
          </div>
        </el-form-item>
        <el-form-item label="整改后" prop="dealAfterFileList">
          <div class="df_ac">
            <upload   width="80px" height="80px" :list="dealForm.dealAfterFileList"  :tips="'图片/视频'"   accept=".png,.jpg,.jpeg,.mp4" folder="hiddendanger" @loading="uploading = true"  @dele="dele($event,1)" @success="uploadFileList($event, 1)" />
          </div>
        </el-form-item>
        <el-form-item label="处理说明">
          <el-input
              type="textarea"
              placeholder="请填写说明"
              :rows="4"
              v-model="dealForm.checkInfo"
          />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShowProblem = false">取消</el-button>
        <el-button type="primary" :loading="dealing" @click="dealDo"
        >确定</el-button
        >
      </span>
    </el-dialog>
    <el-dialog
        append-to-body
        title="隐患退回"
        class="dialogCl"
        :visible.sync="isBackProblem"
        width="600px"
    >
      <el-form :model="backForm" :rules="rulesBack" ref="backForm" label-width="100px">
        <el-form-item label="退回时间" prop="checkDate">
          <el-date-picker
              class="w300"
              value-format="yyyy-MM-dd HH:mm:ss"
              type="datetime"
              placeholder="选择退回时间"
              v-model="backForm.checkDate"
          />
        </el-form-item>
        <el-form-item label="图片/视频" prop="dealBeforeFileList">
          <div class="df_ac">
            <upload  width="80px" height="80px" :list="backForm.dealBeforeFileList" :tips="'图片/视频'"    accept=".png,.jpg,.jpeg,.mp4" folder="hiddendanger" @loading="uploading = true" @dele="dele($event,2)" @success="uploadFileList($event, 2)" />
          </div>
        </el-form-item>
        <el-form-item label="退回说明">
          <el-input
              type="textarea"
              placeholder="请填写说明"
              :rows="4"
              v-model="backForm.checkInfo"
          />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isBackProblem= false">取消</el-button>
        <el-button type="primary" :loading="transfering" @click="backDo"
        >确定</el-button
        >
      </span>
    </el-dialog>
  </GlobalWindow>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import upload from '@/components/common/upload'
import dayjs from 'dayjs'
import { memberList } from '@/api/business/hiddenDangerParam'
import { mapState } from 'vuex'
import {findAllList as userList} from "@/api/system/user";
export default {
  components: { GlobalWindow, upload },
  extends: BaseOpera,
  data () {
    return {
      title: '访客预约详情',
      visible: false,
      transfering: false,
      dataId: null,
      model: { },
      logList: [],
      isShowAppr: false,
      apprTitle: '同意',
      param: {},
      uploading: false,
      dealing: false,
      isShowProblem: false,
      isBackProblem: false,
      isShowTransfer: false,
      rules: {},
      rulesTrans: {
        memberId: [
          { required: true, message: '请选择' }
        ]
      },
      rulesDeal: {
        checkDate: [
          { required: true, message: '请选择整改时间' }
        ],
        dealBeforeFileList: [
          { required: true, message: '请上传整改前情况' }
        ],
        dealAfterFileList: [
          { required: true, message: '请上传整改后情况' }
        ]
      },
      rulesBack: {
        checkDate: [
          { required: true, message: '请选择退回时间' }
        ]
        /*,
        dealBeforeFileList: [
          { required: true, message: '请上传整改前情况' }
        ] */
      },
      memberList: [],
      transForm: {
        memberId: null
      },
      dealForm: {
        checkDate: null,
        checkInfo: null,
        dealBeforeFileList: [],
        dealAfterFileList: []
      },
      backForm: {
        checkDate: null,
        checkInfo: null,
        dealBeforeFileList: []
      }
    }
  },
  computed: {
    ...mapState(['userInfo'])
  },
  created () {
    this.config({
      api: '/business/hiddenDanger',
      'field.id': 'id'
    })
  },
  methods: {
    openHandModal () {
      const { model } = this
      this.isShowProblem = true
      this.$set(this.dealForm, 'checkDate', dayjs().format('YYYY-MM-DD HH:mm:ss'))
      if (model.submitFileList && model.submitFileList.length > 0) {
        this.$set(this.dealForm, 'dealBeforeFileList', model.submitFileList.map(item => {
          return {
            fileurl: item.fileurl,
            name: item.name,
            url: item.fileurlFull
          }
        }))
      }
    },
    openBackModal () {
      this.isBackProblem = true
      this.$set(this.backForm, 'checkDate', dayjs().format('YYYY-MM-DD HH:mm:ss'))
    },
    dele (index, type) {
      if (type == 0) {
        if (this.dealForm.dealBeforeFileList != null && this.dealForm.dealBeforeFileList.length > index) {
          this.dealForm.dealBeforeFileList.splice(index, 1)
        }
      } else if (type == 1) {
        if (this.dealForm.dealAfterFileList != null && this.dealForm.dealAfterFileList.length > index) {
          this.dealForm.dealAfterFileList.splice(index, 1)
        }
      } else if (type == 2) {
        if (this.backForm.dealBeforeFileList != null && this.backForm.dealBeforeFileList.length > index) {
          this.backForm.dealBeforeFileList.splice(index, 1)
        }
      }
    },
    uploadFileList (e, objType) {
      if (objType === 0) {
        if (this.dealForm.dealBeforeFileList == null) {
          this.dealForm.dealBeforeFileList = []
        }
        this.dealForm.dealBeforeFileList.push({
          fileurl: e.imgaddr,
          url: e.url,
          name: e.originname,
          fileType: e.type
        })
      } else if (objType === 1) {
        if (this.dealForm.dealAfterFileList == null) {
          this.dealForm.dealAfterFileList = []
        }
        this.dealForm.dealAfterFileList.push({
          fileurl: e.imgaddr,
          url: e.url,
          name: e.originname,
          fileType: e.type
        })
      } else if (objType === 2) {
        if (this.backForm.dealBeforeFileList == null) {
          this.backForm.dealBeforeFileList = []
        }
        this.backForm.dealBeforeFileList.push({
          fileurl: e.imgaddr,
          url: e.url,
          name: e.originname,
          fileType: e.type
        })
      }
    },
    dealDo () {
      this.$refs.dealForm.validate((valid) => {
      // debugger
        if (!valid) {
          return
        }
        this.$dialog.actionConfirm('操作确认', '您确认提交该隐患处理情况吗?')
          .then(() => {
            this.dealing = true
            this.api.dealHiddenDanger({
              id: this.dataId,
              status: 1,
              dealTime: this.dealForm.checkDate,
              checkInfo: this.dealForm.checkInfo,
              dealBeforeFileList: this.dealForm.dealBeforeFileList,
              dealAfterFileList: this.dealForm.dealAfterFileList
            })
              .then(res => {
                this.$tip.apiSuccess('处理成功')
                this.getDetail()
                this.getLogList()
                this.$emit('success')
                this.isShowProblem = false
              })
              .catch(e => {
              })
              .finally(() => {
                this.dealing = false
              })
          })
      })
    },
    backDo () {
      this.$refs.backForm.validate((valid) => {
        if (!valid) {
          return
        }
        this.$dialog.actionConfirm('操作确认', '您确认退回该隐患处理情况吗?')
          .then(() => {
            this.dealing = true
            this.api.dealHiddenDanger({
              id: this.dataId,
              status: 2,
              dealTime: this.backForm.checkDate,
              checkInfo: this.backForm.checkInfo,
              dealBeforeFileList: this.backForm.dealBeforeFileList
            })
              .then(res => {
                this.$tip.apiSuccess('退回成功')
                this.getDetail()
                this.getLogList()
                this.$emit('success')
                this.isBackProblem = false
              })
              .catch(e => {
              })
              .finally(() => {
                this.dealing = false
              })
          })
      })
    },
    open (title, target) {
      this.title = title
      this.visible = true
      this.model = {}
      this.dataId = target.id
      this.$nextTick(() => {
        this.memberList = []
        this.transForm = {
          memberId: null
        }
        this.dealForm = {
          checkDate: null,
          checkInfo: null,
          dealBeforeFileList: [],
          dealAfterFileList: []
        }
        this.backForm = {
          checkDate: null,
          checkInfo: null,
          dealBeforeFileList: []
        }
        this.getDetail()
        this.getLogList()
      })
    },
    transferSubmit () {
      this.$refs.transForm.validate((valid) => {
        // debugger
        if (!valid) {
          return
        }
        this.$dialog.actionConfirm('操作确认', '您确认转交该隐患提报吗?')
          .then(() => {
            this.transfering = true
            this.api.transferHiddenDanger({
              id: this.dataId,
              checkUserId: this.transForm.memberId
            })
              .then(res => {
                this.$tip.apiSuccess('转交成功')
                this.getDetail()
                this.getLogList()
                this.$emit('success')
                this.isShowTransfer = false
              })
              .catch(e => {
              })
              .finally(() => {
                this.transfering = false
              })
          })
      })
    },
    getLogList () {
      this.api.findLogList({ hiddenDangerId: this.dataId })
        .then(res => {
          this.logList = res
        })
    },
    getDetail () {
      this.api.detail(this.dataId)
        .then(res => {
          this.model = res
        })
    },
    confirm () {
      console.log('--')
    },
    handleTransfer () {
      this.isShowTransfer = true
      this.loadMemberList()
    },
    loadMemberList () {
      userList({ queryParam: this.filterText, querySpecial: 1, type: 2, companyType: 1, workStatus: 0 })
        .then(res => {
          this.memberList = res || []
        })
      /*memberList({}).then(res => {
        this.memberList = res
      })*/
    },
    reject () { },
    handleAvatarSuccess () { },
    beforeAvatarUpload () { }
  }
}
</script>
<style lang="scss" scoped>
@import "@/assets/style/variables.scss";
.side_title{
  font-weight: 600;
  font-size: 18px;
  color: #111111;
  margin-bottom: 20px;
  margin-left: 20px;
  margin-top: 20px;
}
.upload_box {
  width: 84px;
  height: 84px;
  border-radius: 4px;
  background-color: #f7f7f7;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: #999999;
  border: 1px solid #e4e4e4;
  .icon {
    font-size: 24px;
  }
  .text {
    font-size: 12px;
  }
}
.modal_wrap {
  display: flex;
  height: 100%;
  .modal_content {
    flex: 1;
    padding: 0px 30px;
    border-radius: 8px;
    overflow: hidden;
    height: 100%;
    .title {
      font-weight: 600;
      font-size: 18px;
      color: #333333;
      margin-bottom: 20px;
      margin-top: 30px;
    }
    .info {
      .list {
        display: flex;
        flex-wrap: wrap;
        .item {
          display: flex;
          width: 40%;
          margin-bottom: 20px;
          &:nth-of-type(2n) {
            width: 60%;
          }
          .label {
            color: #888888;
            width: 68px;
          }
          .value {
            color: #111111;
            flex: 1;
          }
        }
      }
    }
    .header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 20px 30px;
      margin: 0 -30px;
      border-radius: 8px 8px 0 0;
      background: linear-gradient(to right, #f2f6fe, #cadffa);
      .h1 {
        font-weight: 600;
        font-size: 22px;
        color: #111111;
        margin-bottom: 8px;
      }
      .time {
        font-size: 14px;
        color: #999999;
      }
      .right {
        height: 40px;
        font-size: 16px;
        color: #ffffff;
        line-height: 40px;
        padding: 0 20px;
        background: #207ff7;
        box-shadow: 4px 4px 0px 0px rgba(32, 127, 247, 0.16);
        border-radius: 16px 0px 16px 0px;
      }
    }
    .table_info {
      .name_wrap {
        display: flex;
        align-items: center;
        .avatar {
          width: 40px;
          height: 40px;
          border-radius: 50%;
          margin-right: 12px;
        }
        .content {
          .line {
            display: flex;
          }
          .tag {
            color: #b2cbf9;
            border: 1px solid #b2cbf9;
            padding: 0px 4px;
            border-radius: 4px;
            margin-left: 6px;
          }
        }
      }
    }
  }
  .side {
    height: 100%;
    width: 420px;
    background: #ffffff;
    border-left: 20px solid #f7f7f7;
    .list {
      .item {
        padding: 8px 0;
        position: relative;
        .separate {
          position: absolute;
          border-left: 2px dashed #cccccc;
          left: 31px;
          height: calc(100% - 24px);
          top: 46px;
        }
        .info {
          display: flex;
          align-items: center;
          margin-left: 20px;
          .icon {
            position: relative;
            z-index: 11;
            color: #53b76f;
            font-size: 24px;
          }
          .iconnew{
            width: 24px;
            height: 24px;
          }
          .icon1 {
            position: relative;
            z-index: 11;
            color: deepskyblue;
            font-size: 24px;
          }
          .icon2 {
            position: relative;
            z-index: 11;
            color: #dc362e;
            font-size: 24px;
          }
          .avatar {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            margin: 0 12px 0 16px;
            //border: 1px solid;
          }
          .content {
            flex: 1;
            .line {
              display: flex;
              justify-content: space-between;
              align-content: center;
              margin-bottom: 6px;
              .name {
                font-weight: 600;
                font-size: 16px;
                color: #111111;
              }
              .time {
                color: #888888;
              }
              .company {
                font-size: 13px;
                color: #888888;
                .status {
                  color: $primaryColor;
                }
              }
            }
          }
        }
        .remark {
          background: #f7f7f7;
          border-radius: 4px;
          padding: 13px 15px;
          color: #666666;
          margin-left: 120px;
        }
      }
    }
  }
}
</style>