..
liukangdong
2024-06-06 4bb5b47acbe07a47120b6454483ce411295e0716
..
已添加4个文件
已删除1个文件
已修改5个文件
2880 ■■■■ 文件已修改
admin/src/api/business/approve.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/index.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/platform/index.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaCarUseBookWindow.vue 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/reportRecord.vue 145 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/task/dangetDetail.vue 846 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/task/index.vue 177 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/task/taskDetail.vue 417 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/task/visReportDetail.vue 594 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/task/visSubDetail.vue 647 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/approve.js
@@ -16,3 +16,25 @@
export function taskCenterPage (data) {
  return request.post('/visitsAdmin/cloudService/business/staging/taskPage', data)
}
// è®¿å®¢è®°å½•详情
export function getVisitedDetail (data) {
  return request.get('/visitsAdmin/cloudService/web/visitor/detail', {
    params: { ...data }
  })
}
// è®¿å®¢æŠ¥å¤‡è¯¦æƒ…
export function getVisitedReDetail (data) {
  return request.get('visitsAdmin/cloudService/business/visits/' + data.id)
}
// é𐿂£è¯¦æƒ…
export function hiddenDangerDetail (id) {
  return request.get('/visitsAdmin/cloudService/business/hiddenDanger/' + id)
}
// ä»»åŠ¡ä¸­å¿ƒ é𐿂£è½¬äº¤
export function transferHiddenDanger (data) {
  return request.post('/visitsAdmin/cloudService/business/hiddenDanger/transferHiddenDanger', data)
}
// ä»»åŠ¡ä¸­å¿ƒ å¤„理
export function dealHiddenDanger (data) {
  return request.post('/visitsAdmin/cloudService/business/hiddenDanger/dealHiddenDanger', data)
}
admin/src/api/business/index.js
@@ -11,3 +11,4 @@
export function approveTemplByType (type) {
  return request.get(`/visitsAdmin/cloudService/business/approveTempl/${type}`)
}
export const uploadUrl = 'visitsAdmin/cloudService/public/upload'
admin/src/api/platform/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
import request from '@/utils/request'
// æœˆå°åˆ—表
export function getPlatform (data) {
  return request.post('/visitsAdmin/cloudService/business/platform/page', data, {
    trim: true
  })
}
// æœˆå°è°ƒåº¦ä¸­å¿ƒ åˆ—表
export function getPlatformJob (data) {
  return request.post('/visitsAdmin/cloudService/business/platformJob/page', data, {
    trim: true
  })
}
admin/src/components/business/OperaCarUseBookWindow.vue
@@ -298,14 +298,6 @@
</script>
<style lang="scss" scoped>
.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;
@@ -324,7 +316,14 @@
    font-size: 12px;
  }
}
.side_title{
  font-weight: 600;
  font-size: 18px;
  color: #111111;
  margin-bottom: 20px;
  margin-left: 20px;
  margin-top: 20px;
}
.modal_wrap {
  display: flex;
  height: 100%;
admin/src/views/business/reportRecord.vue
@@ -1,30 +1,106 @@
<template>
  <div class="main_app">
    <QueryForm v-model="filters" :query-form-config="queryFormConfig" @handleQuery="getList(1)" @clear="clear" />
    <el-table v-loading="loading" :data="list" stripe row-key="id" default-expand-all>
      <el-table-column prop="" label="入园车辆" min-width="100" show-overflow-tooltip></el-table-column>
      <el-table-column prop="" label="公司名称" min-width="120" show-overflow-tooltip></el-table-column>
      <el-table-column prop="" label="联系人信息" min-width="100" show-overflow-tooltip></el-table-column>
      <el-table-column prop="" label="手机号" min-width="120" show-overflow-tooltip></el-table-column>
      <el-table-column prop="" label="被访人" min-width="120" show-overflow-tooltip></el-table-column>
      <el-table-column prop="" label="拜访时间" min-width="120" show-overflow-tooltip></el-table-column>
      <el-table-column prop="" label="拜访事由" min-width="80" show-overflow-tooltip></el-table-column>
      <el-table-column prop="" fixed="right" label="状态" min-width="100"></el-table-column>
    <QueryForm
      v-model="filters"
      :query-form-config="queryFormConfig"
      @handleQuery="getList(1)"
      @clear="clear"
    />
    <el-table
      v-loading="loading"
      :data="dataList"
      stripe
      row-key="id"
      default-expand-all
    >
      <el-table-column
        prop="carNos"
        label="入园车辆"
        min-width="100px"
      ></el-table-column>
      <el-table-column
        prop="companyName"
        label="公司名称"
        min-width="100px"
      ></el-table-column>
      <el-table-column
        prop="name"
        label="联系人信息"
        min-width="100px"
      ></el-table-column>
      <el-table-column
        prop="phone"
        label="手机号"
        min-width="100px"
      ></el-table-column>
      <el-table-column
        prop="receptMemberName"
        label="被访人"
        min-width="100px"
      ></el-table-column>
      <el-table-column label="拜访时间" min-width="170px">
        <template slot-scope="{ row }">
          <span>起:{{ row.starttime }}</span
          ><br />
          <span>止:{{ row.endtime }}</span>
        </template>
      </el-table-column>
      <el-table-column
        prop="reason"
        label="拜访事由"
        min-width="100px"
      ></el-table-column>
      <el-table-column
        prop="status"
        fixed="right"
        label="状态"
        min-width="100px"
      >
        <template slot-scope="{ row }">
          <span style="color: rgba(245, 154, 35, 0.996)" v-if="row.status === 0"
            >待提交审批</span
          >
          <span v-if="row.status === 1" style="color: rgba(245, 154, 35, 0.996)"
            >审批中</span
          >
          <span v-if="row.status === 2" style="color: rgba(245, 154, 35, 0.996)"
            >审核通过</span
          >
          <span style="color: gray" v-if="row.status === 3">审核不通过</span>
          <span v-if="row.status === 4" style="color: gray">取消</span>
          <span v-if="row.status === 5" style="color: green">预约成功</span>
          <span v-if="row.status === 6" style="color: gray">预约失败</span>
          <span v-if="row.status === 7" style="color: green">拜访中</span>
          <span v-if="row.status === 8" style="color: red">已签离</span>
          <span v-if="row.status === 9" style="color: gray">已失效</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="230" fixed="right">
        <template slot-scope="{row}">
          <el-button type="text" @click="handleDetail(row)" v-permissions="['business:company:update']">查看详情</el-button>
        <template slot-scope="{ row }">
          <el-button
            type="text"
            @click="handleDetail(row)"
            v-permissions="['business:company:update']"
            >查看详情</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <pagination @size-change="handleSizeChange" @current-change="getList" :pagination="pagination" />
    <ReportDetail v-if="isShowDetail" ref="DetailRef" />
    <pagination
      @size-change="handleSizeChange"
      @current-change="getList"
      :pagination="pagination"
    />
    <ReportDetail v-if="isShowReport" ref="VisReportDetailRef" />
  </div>
</template>
<script>
import Pagination from '@/components/common/Pagination'
import QueryForm from '@/components/common/QueryForm'
import ReportDetail from './page-components/ReportDetail.vue'
// import ReportDetail from './page-components/ReportDetail.vue'
import ReportDetail from '@/views/task/visReportDetail.vue'
import { fetchList } from '@/api/business/visits'
export default {
  components: {
    ReportDetail,
@@ -33,18 +109,19 @@
  },
  data () {
    return {
      isShowDetail: false,
      isShowReport: false,
      activeTab: '0',
      filters: {},
      dataList: [],
      queryFormConfig: {
        formItems: [
          {
            filed: 'idCard',
            filed: 'carNos',
            type: 'input',
            label: '车牌号'
          },
          {
            filed: 'name',
            filed: 'companyName',
            type: 'input',
            label: '公司名称'
          }
@@ -60,19 +137,38 @@
        capacity: 10,
        page: 1
      },
      list: [{}],
      total: 0
    }
  },
  created () {
    this.getList()
  },
  methods: {
    handleDetail () {
      this.isShowDetail = true
    handleDetail (row) {
      this.isShowReport = true
      this.$nextTick(() => {
        this.$refs.DetailRef.isShowModal = true
        this.$nextTick(() => {
          this.$refs.VisReportDetailRef.id = row.id
          this.$refs.VisReportDetailRef.type = 1
          this.$refs.VisReportDetailRef.getDetail()
          this.$refs.VisReportDetailRef.isShowModal = true
        })
      })
    },
    getList (page) {},
    clear () { },
    getList (page) {
      const { pagination, filters } = this
      pagination.page = page || pagination.page
      fetchList({
        model: { ...filters, type: 2 },
        ...pagination
      }).then(res => {
        this.dataList = res.records || []
      })
    },
    clear () {
      this.filters = {}
      this.getList(0)
    },
    handleSizeChange (capacity) {
      this.pagination.capacity = capacity
    }
@@ -81,5 +177,4 @@
</script>
<style lang="scss" scoped>
</style>
admin/src/views/task/dangetDetail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,846 @@
<template>
  <GlobalWindow :title="title" :visible.sync="isShowModal" @confirm="confirm">
    <div class="modal_wrap">
      <div class="modal_content">
        <div class="header">
          <div class="left">
            <div class="h1">{{ cateList[type] }}</div>
            <div class="time">提交时间:{{ info.createDate }}</div>
          </div>
          <div class="right">{{ statusMap[info.status] }}</div>
        </div>
        <div class="info">
          <div class="title">隐患随手拍信息</div>
          <div class="list">
            <div class="item">
              <div class="label">提报人</div>
              <div class="value">
                {{ info.memberName }} {{ info.memberPhone }}
              </div>
            </div>
            <div class="item">
              <div class="label">隐患区域</div>
              <div class="value">{{ info.areaName }}</div>
            </div>
            <div class="item">
              <div class="label">隐患类型</div>
              <div class="value">{{ info.categoryName }}</div>
            </div>
            <div class="item">
              <div class="label">隐患描述</div>
              <div class="value">{{ info.content }}</div>
            </div>
            <div class="item file">
              <div class="label">现场情况</div>
              <div class="value">
                <div class="file_list">
                  <template v-for="item in info.submitFileList">
                    <img
                      v-if="item.type == 0"
                      :key="item.id"
                      :src="item.fileurlFull"
                      mode="widthFix"
                      class="img"
                    />
                    <video
                      v-if="item.type == 1"
                      :key="item.id"
                      :src="item.fileurlFull"
                      class="img"
                      controls
                    />
                  </template>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="side">
        <div class="side_title">审批流程</div>
        <div
          class="list"
          v-if="
            info.approveDateVO != null && info.approveDateVO.approveList != null
          "
        >
          <div
            class="item"
            v-for="(item, index) in info.approveDateVO.approveList"
            :key="item.id"
          >
            <div
              class="separate"
              v-if="index < info.approveDateVO.approveList.length - 1"
            ></div>
            <div class="info">
              <img
                src="@/assets/icons/ic_tongguo.png"
                class="iconnew"
                v-if="item.status == 2"
              />
              <img
                src="@/assets/icons/ic_dangqian.png"
                class="iconnew"
                v-if="item.status == 1"
              />
              <img
                src="@/assets/icons/ic_jujue.png"
                class="iconnew"
                v-if="item.status == 3"
              />
              <img
                src="@/assets/icons/ic_grey.png"
                class="iconnew"
                v-if="item.status == null || item.status == 0"
              />
              <div style="display: inline" v-if="item.approveType != 1">
                <img
                  v-if="item.faceImg != null && item.faceImg != ''"
                  :src="item.faceImg"
                  class="avatar"
                  alt=""
                />
                <img
                  v-if="item.faceImg == null || item.faceImg == ''"
                  src="@/assets/avatar/man.png"
                  class="avatar"
                  alt=""
                />
              </div>
              <div style="display: inline" v-if="item.approveType == 1">
                <img
                  v-if="item.type != 1"
                  src="@/assets/icons/ic_duoren.png"
                  class="avatar"
                  alt=""
                />
                <img
                  v-if="item.type == 1"
                  src="@/assets/icons/ic_chaosong.png"
                  class="avatar"
                  alt=""
                />
              </div>
              <div class="content">
                <div class="line">
                  <div class="name">{{ item.title }}</div>
                  <div class="time">{{ item.checkDate }}</div>
                </div>
                <div class="line">
                  <div class="company">
                    {{ item.memberName }}
                    <div
                      style="display: inline"
                      v-if="item.statusInfo != null && item.statusInfo != ''"
                    >
                      ï¼ˆ<span class="status-green">{{
                        item.statusInfo || ""
                      }}</span
                      >)
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div
              v-if="
                item.approveType != 1 &&
                item.checkInfo != null &&
                item.checkInfo != ''
              "
              class="remark"
            >
              {{ item.checkInfo || "" }}
            </div>
            <div v-if="item.approveType == 1" class="childList">
              <div
                class="m_content company"
                v-for="item1 in item.approveList"
                :key="item1.id"
              >
                <img
                  v-if="item1.faceImg != null && item1.faceImg != ''"
                  :src="item1.faceImg"
                  class="avatar"
                  alt=""
                />
                <img
                  v-if="item1.faceImg == null || item1.faceImg == ''"
                  src="@/assets/avatar/man.png"
                  class="avatar"
                  alt=""
                />
                <span> {{ item1.memberName }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!--  -->
    <template v-slot:footer>
      <el-button @click="handleAppr" type="primary" class="status-red"
        >处理</el-button
      >
      <el-button @click="isShowTransfer = true" type="primary" plain
        >转交</el-button
      >
      <el-button @click="isShowBack = true" type="danger" plain>退回</el-button>
      <el-button @click="isShowModal = false">返回</el-button>
    </template>
    <!--  åŒæ„/拒绝 -->
    <el-dialog
      append-to-body
      title="隐患转交"
      :visible.sync="isShowTransfer"
      width="600px"
    >
      <el-form
        :model="transferForm"
        :rules="handleRules"
        ref="transferForm"
        label-width="100px"
        class="demo-ruleForm"
      >
        <el-form-item label="隐患转交人" prop="checkUserId">
          <el-select
            v-model="transferForm.checkUserId"
            filterable
            placeholder="请选择 å•选"
          >
            <el-option
              v-for="item in memberList"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShowTransfer = false">取消</el-button>
        <el-button :loading="subLoading" type="primary" @click="onTransfer"
          >确定</el-button
        >
      </span>
    </el-dialog>
    <!-- é𐿂£ -->
    <el-dialog
      append-to-body
      title="隐患整改"
      :visible.sync="isShowProblem"
      width="600px"
    >
      <el-form
        :model="handleParam"
        :rules="handleRules"
        ref="handleForm"
        label-width="100px"
      >
        <el-form-item label="整改时间" prop="dealTime">
          <el-date-picker
            class="w300"
            value-format="yyyy-MM-dd hh:mm:ss"
            type="datetime"
            placeholder="选择日期"
            v-model="handleParam.dealTime"
          />
        </el-form-item>
        <el-form-item label="整改前" prop="dealBeforeFileList">
          <div class="upload_wrap">
            <el-upload
              class="avatar-uploader"
              :action="uploadUrl"
              :show-file-list="false"
              :on-success="handleAvatarSuccess"
              :before-upload="beforeAvatarUpload"
            >
              <img v-if="param.url" :src="param.url" class="avatar" />
              <div v-else class="upload_box">
                <el-icon class="el-icon-plus icon" />
                <div class="text">图片/视频</div>
              </div>
            </el-upload>
            <template v-if="handleParam.dealBeforeFileList">
              <div
                class="img_wrap"
                v-for="(img, i) in handleParam.dealBeforeFileList"
                :key="i"
              >
                <img v-if="img.type == 0" :src="img.fileurlFull" alt="" />
                <video
                  v-if="img.type == 1"
                  :src="img.fileurlFull"
                  controls
                  alt=""
                />
              </div>
            </template>
          </div>
        </el-form-item>
        <el-form-item label="整改后" prop="dealAfterFileList">
          <div class="upload_wrap">
            <el-upload
              class="avatar-uploader"
              :action="uploadUrl"
              :show-file-list="false"
              :on-success="handleAfterSuccess"
              :before-upload="beforeAvatarUpload"
            >
              <img v-if="param.url" :src="param.url" class="avatar" />
              <div v-else class="upload_box">
                <el-icon class="el-icon-plus icon" />
                <div class="text">图片/视频</div>
              </div>
            </el-upload>
            <template v-if="handleParam.dealAfterFileList">
              <div
                class="img_wrap"
                v-for="(img, i) in handleParam.dealAfterFileList"
                :key="i"
              >
                <img v-if="img.type == 0" :src="img.fileurlFull" alt="" />
                <video
                  v-if="img.type == 1"
                  :src="img.fileurlFull"
                  controls
                  alt=""
                />
              </div>
            </template>
          </div>
        </el-form-item>
        <el-form-item label="整改说明">
          <el-input
            type="textarea"
            placeholder="请填写说明"
            :rows="4"
            v-model="handleParam.checkInfo"
          />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShowProblem = false">取消</el-button>
        <el-button type="primary" :loading="subLoading" @click="onSubAppr"
          >确定</el-button
        >
      </span>
    </el-dialog>
    <el-dialog
      append-to-body
      title="隐患退回"
      :visible.sync="isShowBack"
      width="600px"
    >
      <el-form
        :model="backForm"
        :rules="handleRules"
        ref="backForm"
        label-width="100px"
      >
        <el-form-item label="整改时间" prop="dealTime">
          <el-date-picker
            class="w300"
            value-format="yyyy-MM-dd hh:mm:ss"
            type="datetime"
            placeholder="选择日期"
            v-model="backForm.dealTime"
          />
        </el-form-item>
        <el-form-item label="整改前">
          <div class="upload_wrap">
            <el-upload
              class="avatar-uploader"
              :action="uploadUrl"
              :show-file-list="false"
              :on-success="handleBackSuccess"
              :before-upload="beforeAvatarUpload"
            >
              <div class="upload_box">
                <el-icon class="el-icon-plus icon" />
                <div class="text">图片/视频</div>
              </div>
            </el-upload>
            <template v-if="backForm.dealBeforeFileList">
              <div
                class="img_wrap"
                v-for="(img, i) in backForm.dealBeforeFileList"
                :key="i"
              >
                <img v-if="img.type == 0" :src="img.fileurlFull" alt="" />
                <video
                  v-if="img.type == 1"
                  :src="img.fileurlFull"
                  controls
                  alt=""
                />
              </div>
            </template>
          </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="isShowBack = false">取消</el-button>
        <el-button type="primary" :loading="subLoading" @click="onSubBack"
          >确定</el-button
        >
      </span>
    </el-dialog>
  </GlobalWindow>
</template>
<script>
import GlobalWindow from '@/components/common/GlobalWindow'
import { memberList } from '@/api/business/hiddenDangerParam'
import {
  uploadFile,
  hiddenDangerDetail,
  dealHiddenDanger,
  transferHiddenDanger
} from '@/api/index'
export default {
  components: { GlobalWindow },
  data () {
    return {
      id: '',
      type: '',
      uploadUrl: uploadFile,
      title: '访客预约详情',
      isShowModal: false,
      info: {},
      isShowAppr: false,
      apprTitle: '同意',
      subLoading: false,
      param: {},
      handleParam: {},
      backForm: {},
      isShowBack: false,
      isShowTransfer: false,
      transferForm: {},
      memberList: [],
      isShowProblem: false,
      rules: {
        checkInfo: [{ required: true, message: '请输入', trigger: 'blur' }]
      },
      handleRules: {
        dealTime: [{ required: true, message: '请选择', trigger: 'change' }],
        dealBeforeFileList: [{ type: 'array', required: true, message: '请选择', trigger: 'change' }],
        checkUserId: [{ required: true, message: '请选择', trigger: 'change' }],
        dealAfterFileList: [{ type: 'array', required: true, message: '请选择', trigger: 'change' }]
      },
      statusMap: {
        0: '待审批',
        1: '审批中',
        2: '审批通过',
        3: '审批未通过',
        4: '已取消',
        5: '他人或签',
        6: '他人拒绝'
      },
      cateList: {
        0: '访客申请',
        1: '访客报备',
        2: '用车申请',
        3: '隐患随手拍',
        4: '物流车申请'
      }
    }
  },
  created() {
    this.getMemberList()
  },
  methods: {
    onSubAppr () {
      this.$refs.handleForm.validate((valid) => {
        if (!valid) {
          return
        }
        this.subLoading = true
        dealHiddenDanger({
          ...this.handleParam,
          status: 1,
          id: this.id
        })
          .then(res => {
            this.subLoading = false
            this.$tip.apiSuccess('处理成功')
            this.getDetail()
            this.isShowProblem = false
          })
          .finally(() => {
            this.subLoading = false
          })
      })
    },
    onSubBack () {
      this.$refs.backForm.validate((valid) => {
        if (!valid) {
          return
        }
        this.subLoading = true
        dealHiddenDanger({
          ...this.backForm,
          status: 2,
          id: this.id
        })
          .then(res => {
            this.subLoading = false
            this.$tip.apiSuccess('退回成功')
            this.getDetail()
            this.isShowProblem = false
          })
          .finally(() => {
            this.subLoading = false
          })
      })
    },
    onTransfer () {
      this.$refs.transferForm.validate((valid) => {
        if (!valid) {
          return
        }
        this.subLoading = true
        transferHiddenDanger({
          ...this.transferForm,
          id: this.id
        })
          .then(res => {
            this.subLoading = false
            if (res.code !== 200) return
            this.$tip.apiSuccess('转交成功')
            this.getDetail()
            this.isShowTransfer = false
          })
          .finally(() => {
            this.subLoading = false
          })
      })
    },
    getMemberList () {
      memberList({}).then(res => {
        this.memberList = res || []
      })
    },
    getDetail () {
      const { id } = this
      hiddenDangerDetail(id).then(res => {
        this.info = res
      })
    },
    handleAppr (val) {
      this.isShowProblem = true
    },
    confirm () {
      console.log('--')
    },
    handleTransfer () {
      this.isShowProblem = true
    },
    reject () { },
    handleAvatarSuccess (res) {
      if (res.code === 200) {
        const str = res.data.url.indexOf('png') > 0 || res.data.url.indexOf('jpg') > 0
        const arr = this.handleParam.dealBeforeFileList || []
        arr.push({
          type: str ? 0 : 1,
          fileurl: res.data.imgaddr,
          fileurlFull: res.data.url
        })
        this.$set(this.handleParam, 'dealBeforeFileList', arr)
      }
    },
    handleAfterSuccess (res) {
      if (res.code === 200) {
        const str = res.data.url.indexOf('png') > 0 || res.data.url.indexOf('jpg') > 0
        const arr = this.handleParam.dealAfterFileList || []
        arr.push({
          type: str ? 0 : 1,
          fileurl: res.data.imgaddr,
          fileurlFull: res.data.url
        })
        this.$set(this.handleParam, 'dealAfterFileList', arr)
      }
    },
    handleBackSuccess (res) {
      if (res.code === 200) {
        const str = res.data.url.indexOf('png') > 0 || res.data.url.indexOf('jpg') > 0
        const arr = this.backForm.dealBeforeFileList || []
        arr.push({
          type: str ? 0 : 1,
          fileurl: res.data.imgaddr,
          fileurlFull: res.data.url
        })
        this.$set(this.backForm, 'dealBeforeFileList', arr)
      }
    },
    beforeAvatarUpload () { }
  }
}
</script>
<style lang="scss" scoped>
.upload_wrap {
  display: flex;
  flex-wrap: wrap;
  .img_wrap {
    width: 85px;
    margin-right: 10px;
    margin-bottom: 10px;
    img,
    video {
      width: 100%;
    }
  }
}
.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;
  }
}
.side_title {
  font-weight: 600;
  font-size: 18px;
  color: #111111;
  margin-bottom: 20px;
  margin-left: 20px;
  margin-top: 20px;
}
.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: 100px;
          }
          .file_list {
            display: flex;
            .img {
              width: 200px;
              margin-right: 12px;
              margin-bottom: 12px;
            }
          }
          .value {
            color: #111111;
          }
        }
        .file {
          width: 100%;
        }
      }
    }
    .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% - 36px);
          top: 49px;
        }
        .avatar {
          width: 40px;
          height: 40px;
          border-radius: 50%;
          margin: 0 12px 0 16px;
          //border: 1px solid;
        }
        .childList {
          display: flex;
          flex-wrap: wrap;
          margin-left: 100px;
        }
        .company {
          font-size: 13px;
          color: #888888;
          .status {
            color: #00ba67;
          }
        }
        .m_content {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          margin-bottom: 4px;
        }
        .info {
          display: flex;
          align-items: center;
          margin-left: 20px;
          .icon {
            position: relative;
            z-index: 11;
            color: #53b76f;
            font-size: 24px;
          }
          .icon1 {
            position: relative;
            z-index: 11;
            color: deepskyblue;
            font-size: 24px;
          }
          .icon2 {
            position: relative;
            z-index: 11;
            color: #dc362e;
            font-size: 24px;
          }
          .iconnew {
            width: 24px;
            height: 24px;
          }
          .icon3 {
            position: relative;
            z-index: 11;
            color: gray;
            font-size: 24px;
          }
          .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;
              }
            }
          }
        }
        .remark {
          background: #f7f7f7;
          border-radius: 4px;
          padding: 13px 15px;
          color: #666666;
          margin-left: 100px;
        }
      }
    }
  }
}
</style>
admin/src/views/task/index.vue
@@ -7,12 +7,13 @@
      @clear="clear"
    />
    <!--  -->
    <el-tabs v-model="filters.queryType">
    <el-tabs v-model="filters.queryType" @tab-click="(e) => getList(1)">
      <el-tab-pane label="待处理" name="0">
        <template #label>
          <span
            >待处理
            <el-badge
              v-if="headData.noticeWaitNum"
              :value="headData.noticeWaitNum"
              class="item"
              type="danger"
@@ -21,21 +22,48 @@
          </span>
        </template>
      </el-tab-pane>
      <el-tab-pane
        :value="headData.noticeDealNum"
        label="已处理"
        name="1"
      ></el-tab-pane>
      <el-tab-pane
        :value="headData.noticeCreateNum"
        label="我发起的"
        name="2"
      ></el-tab-pane>
      <el-tab-pane
        :value="headData.noticeCopyNum"
        label="抄送我的"
        name="3"
      ></el-tab-pane>
      <el-tab-pane :value="headData.noticeDealNum" label="已处理" name="1">
        <template #label>
          <span
            >已处理
            <el-badge
              v-if="headData.noticeDealNum"
              :value="headData.noticeDealNum"
              class="item"
              type="danger"
            >
            </el-badge>
          </span>
        </template>
      </el-tab-pane>
      <el-tab-pane :value="headData.noticeCreateNum" label="我发起的" name="2">
        <template #label>
          <span
            >我发起的
            <el-badge
              v-if="headData.noticeCreateNum"
              :value="headData.noticeCreateNum"
              class="item"
              type="danger"
            >
            </el-badge>
          </span>
        </template>
      </el-tab-pane>
      <el-tab-pane :value="headData.noticeCopyNum" label="抄送我的" name="3">
        <template #label>
          <span
            >抄送我的
            <el-badge
              v-if="headData.noticeCopyNum"
              :value="headData.noticeCopyNum"
              class="item"
              type="danger"
            >
            </el-badge>
          </span>
        </template>
      </el-tab-pane>
    </el-tabs>
    <el-table
      v-loading="loading"
@@ -46,19 +74,24 @@
    >
      <el-table-column prop="name" label="任务类型" min-width="100">
        <template v-slot="scope">
          <span>{{ cateList[scope.row.objType].name }}</span>
          <span
            v-if="
              (scope.row.objType || scope.row.objType == 0) &&
              cateList[scope.row.objType].name
            "
            >{{ cateList[scope.row.objType].name }}</span
          >
        </template>
      </el-table-column>
      <el-table-column
        prop="name"
        label="提交人"
        min-width="80"
      ></el-table-column>
      <el-table-column
        prop="createDate"
        label="提交时间"
        min-width="100"
      ></el-table-column>
      <el-table-column label="提交人" min-width="80">
        <template v-slot="scope">
          <span v-if="scope.row.title">{{
            scope.row.title.split(" - ")[1]
          }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="createDate" label="提交时间" min-width="100">
      </el-table-column>
      <el-table-column label="操作" width="230" fixed="right">
        <template slot-scope="{ row }">
          <el-button
@@ -76,13 +109,26 @@
      :pagination="pagination"
    />
    <TaskDetail v-if="isShowDetail" ref="DetailRef" />
    <VisReportDetail v-if="isShowReport" ref="VisReportDetailRef" />
    <DangetDetail v-if="isShowDanger" ref="DangetDetailRef" />
    <!-- ç”¨è½¦ç”³è¯· -->
    <OperaCarUseBookWindow ref="OperaDetailsWindow" @success="getList"/>
    <!-- é𐿂£ -->
    <OperaHiddenDangerWindow ref="OperaHiddenDangerWindow" @success="getList"/>
    <!-- é¢„约详情 -->
     <OperaVisitsDesWindow ref="OperaVisitsDesWindow" />
  </div>
</template>
<script>
import Pagination from '@/components/common/Pagination'
import QueryForm from '@/components/common/QueryForm'
import TaskDetail from './taskDetail.vue'
import TaskDetail from './visSubDetail.vue'
import VisReportDetail from './visReportDetail.vue'
import DangetDetail from './dangetDetail.vue'
import OperaCarUseBookWindow from '@/components/business/OperaCarUseBookWindow'
import OperaHiddenDangerWindow from '@/components/business/OperaHiddenDangerWindow'
import OperaVisitsDesWindow from '@/components/business/OperaVisitsDesWindow'
import {
  taskCenterHead,
  taskCenterPage
@@ -90,14 +136,21 @@
export default {
  components: {
    TaskDetail,
    VisReportDetail,
    DangetDetail,
    QueryForm,
    Pagination
    Pagination,
    OperaCarUseBookWindow,
    OperaHiddenDangerWindow,
    OperaVisitsDesWindow
  },
  data () {
    return {
      isShowDetail: false,
      isShowReport: false,
      isShowDanger: false,
      filters: {
        queryType: 0
        queryType: '0'
      },
      queryFormConfig: {
        formItems: [
@@ -105,12 +158,13 @@
            filed: 'type',
            type: 'select',
            label: '任务类型',
            clearable: false,
            options: [
              { label: '访客申请', value: 0 },
              { label: '访客报备', value: 1 },
              { label: '用车申请', value: 2 },
              { label: '隐患随手拍', value: 3 },
              { label: '物流车申请', value: 4 }
              { label: '访客申请', value: '0' },
              { label: '访客报备', value: '1' },
              { label: '用车申请', value: '2' },
              { label: '隐患随手拍', value: '3' },
              { label: '物流车申请', value: '4' }
            ]
          },
          {
@@ -121,15 +175,11 @@
        ],
        online: true
      },
      loading: false,
      sorting: false,
      searchForm: {
        // type: 1
      },
      pagination: {
        capacity: 10,
        page: 1
      },
      loading: false,
      dataList: [],
      headData: {},
      total: 0,
@@ -148,23 +198,49 @@
    this.getList()
  },
  methods: {
    handleDetail () {
      this.isShowDetail = true
      this.$nextTick(() => {
        this.$refs.DetailRef.isShowModal = true
      })
    handleDetail (row) {
      if (row.objType === 2) {
        this.$refs.OperaDetailsWindow.open('公务车申请详情', row)
        return
      }
      if (row.objType === 1) {
        this.isShowReport = true
        this.$nextTick(() => {
          this.$refs.VisReportDetailRef.id = row.objId
          this.$refs.VisReportDetailRef.type = row.objType
          this.$refs.VisReportDetailRef.getDetail()
          this.$refs.VisReportDetailRef.isShowModal = true
        })
        return
      }
      if (row.objType === 3) {
        const obj = { ...row, id: row.objId }
        this.$refs.OperaHiddenDangerWindow.open('隐患随手拍详情', obj)
        return
      }
      if (row.objType === 0) {
        this.isShowDetail = true
        this.$nextTick(() => {
          this.$refs.DetailRef.id = row.objId
          this.$refs.DetailRef.type = row.objType
          this.$refs.DetailRef.getDetail()
          this.$refs.DetailRef.isShowModal = true
        })
      }
    },
    getList (page) {
      console.log(this.filters)
      const { filters, pagination } = this
      if (filters.selDate && filters.length > 0) {
      if (filters.selDate && filters.selDate.length > 0) {
        filters.startDate = filters.selDate[0]
        filters.endDate = filters.selDate[1]
      } else {
        filters.startDate = null
        filters.endDate = null
      }
      pagination.page = page || pagination.page
      taskCenterPage({
        model: { ...filters },
        model: { ...filters, queryType: Number(filters.queryType) },
        ...pagination
      }).then(res => {
        console.log('res', res)
@@ -181,7 +257,12 @@
        this.headData = res
      })
    },
    clear () { },
    clear () {
      this.filters = {
        queryType: '0'
      }
      this.getList(0)
    },
    handleSizeChange (capacity) {
      this.pagination.capacity = capacity
    }
admin/src/views/task/taskDetail.vue
ÎļþÒÑɾ³ý
admin/src/views/task/visReportDetail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,594 @@
<template>
  <GlobalWindow :title="title" :visible.sync="isShowModal" @confirm="confirm">
    <div class="modal_wrap">
      <div class="modal_content">
        <div class="header">
          <div class="left">
            <div class="h1">{{ cateList[type] }}</div>
            <div class="time">提交时间:{{ info.createDate }}</div>
          </div>
          <div class="right">{{ statusMap[info.status] }}</div>
        </div>
        <div class="info">
          <div class="title">访客报备信息</div>
          <div class="list">
            <div class="item">
              <div class="label">被访人</div>
              <div class="value">{{ info.receptMemberName }} {{ info.receptMemberDepartment }}</div>
            </div>
            <div class="item">
              <div class="label">来访时间</div>
              <div class="value">{{ info.starttime }}至{{ info.endtime }}</div>
            </div>
             <div class="item">
              <div class="label">来访单位</div>
              <div class="value">{{ info.companyName }}</div>
            </div>
            <div class="item">
              <div class="label">来访事由</div>
              <div class="value">{{ info.reason }}</div>
            </div>
            <div class="item">
              <div class="label">联系人</div>
              <div class="value">{{ info.name }} {{ info.phone }}</div>
            </div>
            <div class="item">
              <div class="label">入园车辆</div>
              <div class="value">{{ info.carNos }}</div>
            </div>
            <div class="item">
              <div class="label">随车人数</div>
              <div class="value">{{ info.memberNum || 0 }}人</div>
            </div>
          </div>
        </div>
      </div>
      <div class="side">
        <div class="side_title">审批流程</div>
        <div
          class="list"
          v-if="
            info.approveDateVO != null && info.approveDateVO.approveList != null
          "
        >
          <div
            class="item"
            v-for="(item, index) in info.approveDateVO.approveList"
            :key="item.id"
          >
            <div
              class="separate"
              v-if="index < info.approveDateVO.approveList.length - 1"
            ></div>
            <div class="info">
              <img
                src="@/assets/icons/ic_tongguo.png"
                class="iconnew"
                v-if="item.status == 2"
              />
              <img
                src="@/assets/icons/ic_dangqian.png"
                class="iconnew"
                v-if="item.status == 1"
              />
              <img
                src="@/assets/icons/ic_jujue.png"
                class="iconnew"
                v-if="item.status == 3"
              />
              <img
                src="@/assets/icons/ic_grey.png"
                class="iconnew"
                v-if="item.status == null || item.status == 0"
              />
              <div style="display: inline" v-if="item.approveType != 1">
                <img
                  v-if="item.faceImg != null && item.faceImg != ''"
                  :src="item.faceImg"
                  class="avatar"
                  alt=""
                />
                <img
                  v-if="item.faceImg == null || item.faceImg == ''"
                  src="@/assets/avatar/man.png"
                  class="avatar"
                  alt=""
                />
              </div>
              <div style="display: inline" v-if="item.approveType == 1">
                <img
                  v-if="item.type != 1"
                  src="@/assets/icons/ic_duoren.png"
                  class="avatar"
                  alt=""
                />
                <img
                  v-if="item.type == 1"
                  src="@/assets/icons/ic_chaosong.png"
                  class="avatar"
                  alt=""
                />
              </div>
              <div class="content">
                <div class="line">
                  <div class="name">{{ item.title }}</div>
                  <div class="time">{{ item.checkDate }}</div>
                </div>
                <div class="line">
                  <div class="company">
                    {{ item.memberName }}
                    <div
                      style="display: inline"
                      v-if="item.statusInfo != null && item.statusInfo != ''"
                    >
                      ï¼ˆ<span class="status-green">{{
                        item.statusInfo || ""
                      }}</span
                      >)
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div
              v-if="
                item.approveType != 1 &&
                item.checkInfo != null &&
                item.checkInfo != ''
              "
              class="remark"
            >
              {{ item.checkInfo || "" }}
            </div>
            <div v-if="item.approveType == 1" class="childList">
              <div
                class="m_content company"
                v-for="item1 in item.approveList"
                :key="item1.id"
              >
                <img
                  v-if="item1.faceImg != null && item1.faceImg != ''"
                  :src="item1.faceImg"
                  class="avatar"
                  alt=""
                />
                <img
                  v-if="item1.faceImg == null || item1.faceImg == ''"
                  src="@/assets/avatar/man.png"
                  class="avatar"
                  alt=""
                />
                <span> {{ item1.memberName }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!--  -->
    <template v-slot:footer>
      <el-button
        @click="handleAppr(2)"
        type="primary"
        class="status-red"
        v-if="
          info.approveDateVO != null &&
          info.approveDateVO.canBeApproved != null &&
          info.approveDateVO.canBeApproved == 1
        "
        >同意</el-button
      >
      <el-button
        @click="handleAppr(3)"
        type="danger"
        v-if="
          info.approveDateVO != null &&
          info.approveDateVO.canBeApproved != null &&
          info.approveDateVO.canBeApproved == 1
        "
        >拒绝</el-button
      >
      <el-button @click="isShowModal = false">返回</el-button>
    </template>
    <!--  åŒæ„/拒绝 -->
    <el-dialog
      append-to-body
      :title="apprTitle"
      :visible.sync="isShowAppr"
      width="480px"
    >
      <el-form :model="param" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
        <el-form-item :prop="param.status == 3 ? 'checkInfo' : ''" :label="param.status == 2 ? '同意说明' : '拒绝说明'">
          <el-input
            type="textarea"
            :placeholder="
              param.status == 2 ? '同意说明,非必填' : '拒绝说明必填'
            "
            :rows="4"
            v-model="param.checkInfo"
          />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShowAppr = false">取消</el-button>
        <el-button :loading="subLoading" type="primary" @click="onSubAppr">确定</el-button>
      </span>
    </el-dialog>
    <!-- é𐿂£ -->
    <el-dialog
      append-to-body
      title="隐患"
      :visible.sync="isShowProblem"
      width="480px"
    >
      <el-form :model="param" :rules="rules" ref="ruleForm" label-width="100px">
        <el-form-item label="退回时间">
          <el-date-picker
            class="w300"
            value-format="yyyy-MM-dd"
            type="date"
            placeholder="选择日期"
            v-model="param.date"
          />
        </el-form-item>
        <el-form-item label="整改前">
          <div class="df_ac">
            <img src="@/assets/avatar/man.png" />
            <el-upload
              class="avatar-uploader"
              action="https://jsonplaceholder.typicode.com/posts/"
              :show-file-list="false"
              :on-success="handleAvatarSuccess"
              :before-upload="beforeAvatarUpload"
            >
              <img v-if="param.url" :src="param.url" class="avatar" />
              <div v-else class="upload_box">
                <el-icon class="el-icon-plus icon" />
                <div class="text">图片/视频</div>
              </div>
            </el-upload>
          </div>
        </el-form-item>
        <el-form-item label="退回说明">
          <el-input
            type="textarea"
            placeholder="请填写说明"
            :rows="4"
            v-model="param.explain"
          />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShowProblem = false">取消</el-button>
        <el-button type="primary" @click="isShowProblem = false"
          >确定</el-button
        >
      </span>
    </el-dialog>
  </GlobalWindow>
</template>
<script>
import GlobalWindow from '@/components/common/GlobalWindow'
import {
  getVisitedReDetail,
  approveDo
} from '@/api'
export default {
  components: { GlobalWindow },
  data () {
    return {
      id: '',
      type: '',
      title: '访客预约详情',
      isShowModal: false,
      info: {},
      isShowAppr: false,
      apprTitle: '同意',
      subLoading: false,
      param: {},
      isShowProblem: false,
      rules: {
        checkInfo: [{ required: true, message: '请输入', trigger: 'blur' }]
      },
      statusMap: {
        0: '待审批',
        1: '审批中',
        2: '审批通过',
        3: '审批未通过',
        4: '已取消',
        5: '他人或签',
        6: '他人拒绝'
      },
      cateList: {
        0: '访客申请',
        1: '访客报备',
        2: '用车申请',
        3: '隐患随手拍',
        4: '物流车申请'
      }
    }
  },
  methods: {
    onSubAppr () {
      this.$refs.ruleForm.validate((valid) => {
        if (!valid) {
          return
        }
        this.$dialog.actionConfirm('操作确认', this.param.status === 2 ? '您确认同意该申请吗?' : '您确认拒绝该申请吗?')
          .then(() => {
            this.subLoading = true
            approveDo({
              objId: this.id,
              objType: 2,
              status: this.param.status,
              checkInfo: this.param.checkInfo
            })
              .then(res => {
                this.subLoading = false
                this.$tip.apiSuccess('处理成功')
                this.getDetail()
                this.isShowAppr = false
              })
              .finally(() => {
                this.subLoading = false
              })
          })
      })
    },
    getDetail () {
      const { id } = this
      getVisitedReDetail({ id }).then(res => {
        this.info = res
      })
    },
    handleAppr (val) {
      this.$set(this.param, 'status', val)
      this.isShowAppr = true
    },
    confirm () {
      console.log('--')
    },
    handleTransfer () {
      this.isShowProblem = true
    },
    reject () { },
    handleAvatarSuccess () { },
    beforeAvatarUpload () { }
  }
}
</script>
<style lang="scss" scoped>
.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;
  }
}
.side_title {
  font-weight: 600;
  font-size: 18px;
  color: #111111;
  margin-bottom: 20px;
  margin-left: 20px;
  margin-top: 20px;
}
.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: 100px;
          }
          .value {
            color: #111111;
          }
        }
      }
    }
    .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% - 36px);
          top: 49px;
        }
        .avatar {
          width: 40px;
          height: 40px;
          border-radius: 50%;
          margin: 0 12px 0 16px;
          //border: 1px solid;
        }
        .childList {
          display: flex;
          flex-wrap: wrap;
          margin-left: 100px;
        }
        .company {
          font-size: 13px;
          color: #888888;
          .status {
            color: #00ba67;
          }
        }
        .m_content {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          margin-bottom: 4px;
        }
        .info {
          display: flex;
          align-items: center;
          margin-left: 20px;
          .icon {
            position: relative;
            z-index: 11;
            color: #53b76f;
            font-size: 24px;
          }
          .icon1 {
            position: relative;
            z-index: 11;
            color: deepskyblue;
            font-size: 24px;
          }
          .icon2 {
            position: relative;
            z-index: 11;
            color: #dc362e;
            font-size: 24px;
          }
          .iconnew {
            width: 24px;
            height: 24px;
          }
          .icon3 {
            position: relative;
            z-index: 11;
            color: gray;
            font-size: 24px;
          }
          .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;
              }
            }
          }
        }
        .remark {
          background: #f7f7f7;
          border-radius: 4px;
          padding: 13px 15px;
          color: #666666;
          margin-left: 100px;
        }
      }
    }
  }
}
</style>
admin/src/views/task/visSubDetail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,647 @@
<template>
  <GlobalWindow :title="title" :visible.sync="isShowModal" @confirm="confirm">
    <div class="modal_wrap">
      <div class="modal_content">
        <div class="header">
          <div class="left">
            <div class="h1">{{ cateList[type] }}</div>
            <div class="time">提交时间:{{ info.createDate }}</div>
          </div>
          <div class="right">{{ statusMap[info.status] }}</div>
        </div>
        <div class="info">
          <div class="title">访客预约信息</div>
          <div class="list">
            <div class="item">
              <div class="label">被访人</div>
              <div class="value">{{ info.visitUserName }}</div>
            </div>
            <div class="item">
              <div class="label">来访时间</div>
              <div class="value">{{ info.visitTime }}</div>
            </div>
            <div class="item">
              <div class="label">来访事由</div>
              <div class="value">{{ info.visitReason }}</div>
            </div>
            <div class="item">
              <div class="label">随行车辆</div>
              <div class="value">{{ info.carNos }}</div>
            </div>
            <div class="item">
              <div class="label">施工人员</div>
              <div class="value">{{ info.type == "0" ? "否" : "是" }}</div>
            </div>
            <div class="item">
              <div class="label">施工内容</div>
              <div class="value">{{ info.constructionReason }}</div>
            </div>
          </div>
        </div>
        <div class="table_info">
          <div class="title">访客信息</div>
          <el-table :data="[info]" border fit>
            <el-table-column label="姓名" prop="" min-width="150">
              <template slot-scope="{ row }">
                <div class="name_wrap">
                  <image
                    :src="
                      row.prefix
                        ? row.prefix
                        : require('@/assets/avatar/man.png')
                    "
                    class="avatar"
                    mode=""
                  />
                  <div class="content">
                    <div class="line">
                      <div class="name">{{ row.name }}</div>
                      <div class="tag">申请人</div>
                    </div>
                    <div class="line placeholder9">{{ row.phone }}</div>
                  </div>
                </div>
              </template>
            </el-table-column>
            <!-- <el-table-column label="性别" prop="" min-width="40" /> -->
            <el-table-column
              label="证件类型"
              prop="idcardTypeName"
              min-width="80"
            />
            <el-table-column
              label="证件号码"
              prop="idCardDecode"
              min-width="120"
            />
            <el-table-column
              label="公司名称"
              prop="companyName"
              min-width="120"
            />
            <el-table-column label="人脸照片" prop="" min-width="80">
              <template slot-scope="{ row }">
                <el-image :src="row.prefix" :preview-src-list="[row.prefix]">
                </el-image>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
      <div class="side">
        <div class="side_title">审批流程</div>
        <div
          class="list"
          v-if="
            info.approveDateVO != null && info.approveDateVO.approveList != null
          "
        >
          <div
            class="item"
            v-for="(item, index) in info.approveDateVO.approveList"
            :key="item.id"
          >
            <div
              class="separate"
              v-if="index < info.approveDateVO.approveList.length - 1"
            ></div>
            <div class="info">
              <img
                src="@/assets/icons/ic_tongguo.png"
                class="iconnew"
                v-if="item.status == 2"
              />
              <img
                src="@/assets/icons/ic_dangqian.png"
                class="iconnew"
                v-if="item.status == 1"
              />
              <img
                src="@/assets/icons/ic_jujue.png"
                class="iconnew"
                v-if="item.status == 3"
              />
              <img
                src="@/assets/icons/ic_grey.png"
                class="iconnew"
                v-if="item.status == null || item.status == 0"
              />
              <div style="display: inline" v-if="item.approveType != 1">
                <img
                  v-if="item.faceImg != null && item.faceImg != ''"
                  :src="item.faceImg"
                  class="avatar"
                  alt=""
                />
                <img
                  v-if="item.faceImg == null || item.faceImg == ''"
                  src="@/assets/avatar/man.png"
                  class="avatar"
                  alt=""
                />
              </div>
              <div style="display: inline" v-if="item.approveType == 1">
                <img
                  v-if="item.type != 1"
                  src="@/assets/icons/ic_duoren.png"
                  class="avatar"
                  alt=""
                />
                <img
                  v-if="item.type == 1"
                  src="@/assets/icons/ic_chaosong.png"
                  class="avatar"
                  alt=""
                />
              </div>
              <div class="content">
                <div class="line">
                  <div class="name">{{ item.title }}</div>
                  <div class="time">{{ item.checkDate }}</div>
                </div>
                <div class="line">
                  <div class="company">
                    {{ item.memberName }}
                    <div
                      style="display: inline"
                      v-if="item.statusInfo != null && item.statusInfo != ''"
                    >
                      ï¼ˆ<span class="status-green">{{
                        item.statusInfo || ""
                      }}</span
                      >)
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div
              v-if="
                item.approveType != 1 &&
                item.checkInfo != null &&
                item.checkInfo != ''
              "
              class="remark"
            >
              {{ item.checkInfo || "" }}
            </div>
            <div v-if="item.approveType == 1" class="childList">
              <div
                class="m_content company"
                v-for="item1 in item.approveList"
                :key="item1.id"
              >
                <img
                  v-if="item1.faceImg != null && item1.faceImg != ''"
                  :src="item1.faceImg"
                  class="avatar"
                  alt=""
                />
                <img
                  v-if="item1.faceImg == null || item1.faceImg == ''"
                  src="@/assets/avatar/man.png"
                  class="avatar"
                  alt=""
                />
                <span> {{ item1.memberName }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!--  -->
    <template v-slot:footer>
      <el-button
        @click="handleAppr(2)"
        type="primary"
        class="status-red"
        v-if="
          info.approveDateVO != null &&
          info.approveDateVO.canBeApproved != null &&
          info.approveDateVO.canBeApproved == 1
        "
        >同意</el-button
      >
      <el-button
        @click="handleAppr(3)"
        type="danger"
        v-if="
          info.approveDateVO != null &&
          info.approveDateVO.canBeApproved != null &&
          info.approveDateVO.canBeApproved == 1
        "
        >拒绝</el-button
      >
      <el-button @click="isShowModal = false">返回</el-button>
    </template>
    <!--  åŒæ„/拒绝 -->
    <el-dialog
      append-to-body
      :title="apprTitle"
      :visible.sync="isShowAppr"
      width="480px"
    >
      <el-form :model="param" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
        <el-form-item :prop="param.status == 3 ? 'checkInfo' : ''" :label="param.status == 2 ? '同意说明' : '拒绝说明'">
          <el-input
            type="textarea"
            :placeholder="
              param.status == 2 ? '同意说明,非必填' : '拒绝说明必填'
            "
            :rows="4"
            v-model="param.checkInfo"
          />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShowAppr = false">取消</el-button>
        <el-button :loading="subLoading" type="primary" @click="onSubAppr">确定</el-button>
      </span>
    </el-dialog>
    <!-- é𐿂£ -->
    <el-dialog
      append-to-body
      title="隐患"
      :visible.sync="isShowProblem"
      width="480px"
    >
      <el-form :model="param" :rules="rules" ref="ruleForm" label-width="100px">
        <el-form-item label="退回时间">
          <el-date-picker
            class="w300"
            value-format="yyyy-MM-dd"
            type="date"
            placeholder="选择日期"
            v-model="param.date"
          />
        </el-form-item>
        <el-form-item label="整改前">
          <div class="df_ac">
            <img src="@/assets/avatar/man.png" />
            <el-upload
              class="avatar-uploader"
              action="https://jsonplaceholder.typicode.com/posts/"
              :show-file-list="false"
              :on-success="handleAvatarSuccess"
              :before-upload="beforeAvatarUpload"
            >
              <img v-if="param.url" :src="param.url" class="avatar" />
              <div v-else class="upload_box">
                <el-icon class="el-icon-plus icon" />
                <div class="text">图片/视频</div>
              </div>
            </el-upload>
          </div>
        </el-form-item>
        <el-form-item label="退回说明">
          <el-input
            type="textarea"
            placeholder="请填写说明"
            :rows="4"
            v-model="param.explain"
          />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShowProblem = false">取消</el-button>
        <el-button type="primary" @click="isShowProblem = false"
          >确定</el-button
        >
      </span>
    </el-dialog>
  </GlobalWindow>
</template>
<script>
import GlobalWindow from '@/components/common/GlobalWindow'
import {
  getVisitedDetail,
  approveDo
} from '@/api'
export default {
  components: { GlobalWindow },
  data () {
    return {
      id: '',
      type: '',
      title: '访客预约详情',
      isShowModal: false,
      info: {},
      isShowAppr: false,
      apprTitle: '同意',
      subLoading: false,
      param: {},
      isShowProblem: false,
      rules: {
        checkInfo: [{ required: true, message: '请输入', trigger: 'blur' }]
      },
      statusMap: {
        0: '待审批',
        1: '审批中',
        2: '审批通过',
        3: '审批未通过',
        4: '已取消',
        5: '他人或签',
        6: '他人拒绝'
      },
      cateList: {
        0: '访客申请',
        1: '访客报备',
        2: '用车申请',
        3: '隐患随手拍',
        4: '物流车申请'
      }
    }
  },
  methods: {
    onSubAppr () {
      this.$refs.ruleForm.validate((valid) => {
        if (!valid) {
          return
        }
        this.$dialog.actionConfirm('操作确认', this.param.status === 2 ? '您确认同意该申请吗?' : '您确认拒绝该申请吗?')
          .then(() => {
            this.subLoading = true
            approveDo({
              objId: this.id,
              objType: this.info.type,
              status: this.param.status,
              checkInfo: this.param.checkInfo
            })
              .then(res => {
                this.subLoading = false
                this.$tip.apiSuccess('处理成功')
                this.getDetail()
                this.isShowAppr = false
              })
              .finally(() => {
                this.subLoading = false
              })
          })
      })
    },
    getDetail () {
      const { id, type } = this
      console.log(id, type)
      switch (type) {
      case 0:
        getVisitedDetail({ id }).then(res => {
          this.info = res
        })
        break
      default:
        break
      }
    },
    handleAppr (val) {
      this.$set(this.param, 'status', val)
      this.isShowAppr = true
    },
    confirm () {
      console.log('--')
    },
    handleTransfer () {
      this.isShowProblem = true
    },
    reject () { },
    handleAvatarSuccess () { },
    beforeAvatarUpload () { }
  }
}
</script>
<style lang="scss" scoped>
.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;
  }
}
.side_title {
  font-weight: 600;
  font-size: 18px;
  color: #111111;
  margin-bottom: 20px;
  margin-left: 20px;
  margin-top: 20px;
}
.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: 100px;
          }
          .value {
            color: #111111;
          }
        }
      }
    }
    .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% - 36px);
          top: 49px;
        }
        .avatar {
          width: 40px;
          height: 40px;
          border-radius: 50%;
          margin: 0 12px 0 16px;
          //border: 1px solid;
        }
        .childList {
          display: flex;
          flex-wrap: wrap;
          margin-left: 100px;
        }
        .company {
          font-size: 13px;
          color: #888888;
          .status {
            color: #00ba67;
          }
        }
        .m_content {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          margin-bottom: 4px;
        }
        .info {
          display: flex;
          align-items: center;
          margin-left: 20px;
          .icon {
            position: relative;
            z-index: 11;
            color: #53b76f;
            font-size: 24px;
          }
          .icon1 {
            position: relative;
            z-index: 11;
            color: deepskyblue;
            font-size: 24px;
          }
          .icon2 {
            position: relative;
            z-index: 11;
            color: #dc362e;
            font-size: 24px;
          }
          .iconnew {
            width: 24px;
            height: 24px;
          }
          .icon3 {
            position: relative;
            z-index: 11;
            color: gray;
            font-size: 24px;
          }
          .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;
              }
            }
          }
        }
        .remark {
          background: #f7f7f7;
          border-radius: 4px;
          padding: 13px 15px;
          color: #666666;
          margin-left: 100px;
        }
      }
    }
  }
}
</style>