浏览代码

添加录像完整性

凉纪 1 年之前
父节点
当前提交
b9e64bea1f

+ 4 - 4
src/components/waterCom.vue

@@ -31,8 +31,8 @@ export default {
       let orgName=JSON.parse(sessionStorage.getItem('SET_USER_ORGNAME'))
       let userName=JSON.parse(sessionStorage.getItem('SET_USER_NAME'))
       const canvas = document.getElementById('canvas') //获取canvas
-      // canvas.width = 800 //设置画布宽度
-      canvas.height = 200 //设置画布高度
+      canvas.width = 210 //设置画布宽度
+      canvas.height = 150 //设置画布高度
       canvas.style.display = 'none' //隐藏画布本身
        //加层级权重
 
@@ -40,10 +40,10 @@ export default {
       ctx.font = '18px -apple-system'
     //   设置文字大小
       ctx.fillStyle = 'rgba(0,0,0,.1)' //设置文字颜色及透明度
-      ctx.rotate(-0.3) //设置文字旋转角度
+      ctx.rotate(-0.4) //设置文字旋转角度
       ctx.fillText(`${userName||''}${orgName||''}${this.date}`, -10, 120) //设置显示文字内容
       const img = canvas.toDataURL('image/png') //参数默认为 image/png,可以是其他image/jpeg等,该方法返回值是一个url,是base64组成的图片的源数据、可以直接赋值给图片的src属性
-      const style = `background-image:url(${img});width:300px;z-index:111;display:${type==1? 'block':'none'};` //定义样式
+      const style = `background-image:url(${img});width:1200px;z-index:111;display:${type==1? 'block':'none'};` //定义样式
       water.setAttribute('style', style) //给要添加水印的元素设置样式
     }
   }

+ 30 - 1
src/router/router.config.js

@@ -315,7 +315,36 @@ export let routers = [
         component: () => import('@/views/menu/operate/index.vue'),
         meta: { title: '操作手册', keepAlive: false ,hideTabBar:true,deep: 2}
       },
-
+      {
+        path: '/videoIntegrity',
+        name: 'videoIntegrity',
+        component: () => import('@/views/menu/iot/videoIntegrity/index.vue'),
+        meta: { title: '录像完整性',  keepAlive: true ,hideTabBar:false,deep: 1}
+      },
+      {
+        path: '/videoIntegrityDetail',
+        name: 'videoIntegrityDetail',
+        component: () => import('@/views/menu/iot/videoIntegrity/detail.vue'),
+        meta: { title: '录像完整性详情',  keepAlive: false ,hideTabBar:true,deep: 2}
+      },
+      {
+        path: '/addOrder',
+        name: 'addOrder',
+        component: () => import('@/views/menu/iot/add.vue'),
+        meta: { title: '生成运维单',  keepAlive: false ,hideTabBar:true,deep: 2}
+      },
+      // {
+      //   path: '/videoQuality',
+      //   name: 'videoQuality',
+      //   component: () => import('@/views/menu/iot/videoQuality/index.vue'),
+      //   meta: { title: '录像完整性',  keepAlive: true ,hideTabBar:false,deep: 1}
+      // },
+      // {
+      //   path: '/videoDay',
+      //   name: 'videoDay',
+      //   component: () => import('@/views/menu/iot/videoDay/index.vue'),
+      //   meta: { title: '录像完整性',  keepAlive: true ,hideTabBar:false,deep: 1}
+      // },
     ],
   },
 ]

+ 440 - 0
src/views/menu/iot/add.vue

@@ -0,0 +1,440 @@
+<template>
+  <div class="intro-add">
+    <nav-bar></nav-bar>
+    <div class="page-container">
+      <!--   基本信息   -->
+      <div class="card">
+        <van-panel title="来访信息" >
+          <template #header>
+            <span></span>
+          </template>
+          <div class="panel-box">
+            <van-cell title="机构名称" :value="selectedUser.idCard"></van-cell>
+            <van-cell title="保修设备" :value="getDictLabel(selectedUser.idType,'letter_id_type')"></van-cell>
+            <van-cell title="工程商" :value="selectedUser.userName" required is-link  @click="onClick"/>
+            <date-cell title="建议完成时间" v-model="formData.departureTime" required date-type="datetime" />
+            <van-cell title="紧急程度" :value="selectedUser.userName" required is-link  @click="onClick"/>
+            <van-field
+              v-model="formData.accompanyingPerson"
+              rows="1"
+              autosize
+              required
+              :maxlength="200"
+              placeholder="请输入"
+              label="报修原因"></van-field>
+          </div>
+            <div class="upload-box">
+              <span>上传图片</span>
+              <van-cell>
+                <uploader :maxCount="1" v-model="formData.letterFile"/>
+              </van-cell>
+            </div>
+          <div class="big-btn-box" >
+            <van-button  type="info" size="large" @click="onSubmit">提交</van-button>
+          </div>
+        </van-panel>
+      </div>
+    </div>
+
+    <!--  人员选择弹窗  -->
+    <van-popup
+      class="search-data-popup"
+      round
+      lazy-render
+      v-model="showPicker"
+      position="bottom"
+      @click-overlay="clickOverlay"
+      :close-on-click-overlay="true">
+      <div class="header-line">
+        <div class="cancel" @click="onSearchCancel">取消</div>
+        <div class="title">选择人员</div>
+        <div class="sure" @click="onSearchConfirm">确定</div>
+      </div>
+
+      <form action="/static">
+        <van-search  placeholder="输入搜索内容" v-model="searchValue" @input="inputSearchValue" />
+      </form>
+
+      <div  v-if="userList.length >0"  class="lists">
+        <div class="list-item">
+          <van-cell
+            :class="{active:item.checked}"
+            v-for="(item, index) in userList"
+            clickable
+            :key="item.id"
+            :title="item.userName"
+            :value="item.companyName"
+            @click="handleClick(item,index)">
+          </van-cell>
+        </div>
+      </div>
+      <div v-else class="lists">
+        <empty description="" />
+      </div>
+    </van-popup>
+  </div>
+</template>
+
+<script>
+import SearchSelectCell from "@/components/SearchSelectCell/index.vue";
+import DateCell from "@/components/dateCell/index.vue";
+import Uploader from "@/components/upload/gxuploader.vue";
+import {formatDate} from "@/filters/filter";
+import {mapGetters} from "vuex";
+import {imgUrl} from "@/utils";
+import {ImagePreview } from 'vant'
+import {userList, userRegister} from './videoIntegrity/api'
+import dayjs from "dayjs";
+export default {
+  components: {SearchSelectCell,Uploader, DateCell},
+  data(){
+    return {
+      minDate:null,
+      maxDate:new Date(),
+      visitId:null,
+      userList:[],
+      selectedUser:{},
+      prop:{
+        label:'userName',
+        value:'id',
+      },
+      formData:{
+        letterUserId:null,
+        arrivalTime:null,
+        departureTime:null,
+        accompanyingPerson:null,
+        checkImage:null,
+      },
+      dicts:['out_in_approve_status','letter_id_type','out_in_type'],
+      /*以下为弹窗中的变量*/
+      searchValue:'',
+      showPicker:false,
+      onSelected:null,
+      pList:[],
+    }
+  },
+  computed:{
+    ...mapGetters(['orgId','id','dictionary'])
+  },
+  mounted(){
+    this.getUserList();
+  },
+  methods:{
+    dayjs, imgUrl,formatDate,
+    onClick(){
+      this.showPicker = true;
+    },
+    clickOverlay(){
+      this.selected = this.value;
+      this.showPicker = false;
+    },
+    handleClick(v,i){
+      this.userList.forEach(v=>v.checked = false);
+      // this.$nextTick(()=>{
+      //   this.$set(this.userList[i],'checked',!this.userList[i].checked);
+      // })
+      v.checked = !v.checked;
+      this.userList.splice(i,1,v)
+      this.onSelected = v;
+    },
+    onSearchCancel() {
+      this.selected = this.value;
+      this.$emit("cancel");
+      this.showPicker = false;
+    },
+    onSearchConfirm() {
+      this.onSelected.minDate = dayjs(this.onSelected.startTime).toDate() || new Date();
+      this.selectedUser = this.onSelected;
+      this.formData.arrivalTime = null;
+      this.showPicker = false;
+    },
+    inputSearchValue(query) {
+      //搜索框值发生改变
+      setTimeout(() => {
+        this.userList= this.pList.filter(item => {
+          return item.userName.indexOf(query) > -1;
+        });
+      }, 200);
+    },
+
+
+    onSubmit(){
+      if(!this.selectedUser.id){
+        this.$toast('请选择来访人员');
+        return
+      }
+      if(!this.formData.accompanyingPerson){
+        this.$toast('请输入陪同人员');
+        return
+      }
+      if(!this.formData.checkImage){
+        this.$toast('请上传审核结果');
+        return
+      }
+      if(!this.formData.arrivalTime){
+        this.$toast('请选择到达时间');
+        return
+      }
+      let data = {
+        ...this.formData,
+        letterId:this.selectedUser.letterId,
+        checkImage:this.formData.checkImage.map(v=>{return v.imgPath}).toString(','),
+        letterUserId:this.selectedUser.id,
+        orgId:this.orgId,
+      }
+      //alert(JSON.stringify(data))
+      userRegister(data).then(res=>{
+        this.$toast.success('提交成功');
+        this.$router.replace({
+          name:'videoIntegrity',
+          path:'/videoIntegrity',
+          params:{event:'refresh'},
+        });
+      })
+    },
+    /* 失效*/
+    getItemInfo(item){
+      console.log(dayjs(item.startTime).toDate(),'77777777')
+      item.maxDate = dayjs(item.startTime).toDate() || new Date();
+      console.log(item.maxDate,'77777777')
+      this.selectedUser = item;
+      this.formData.arrivalTime = null;
+    },
+    previewFile(file){
+      this.openFilePreview(file);
+    },
+    getUserList(){
+      let data = {
+        orgId:this.orgId,
+        arrivalTime:formatDate(new Date(),'YYYY-MM-DD')
+      }
+      userList(data).then(res=>{
+        this.userList = res.data.map(v=>{
+          v.imgFile = v.imgFile.split(',');
+          if(v.letterFile && v.letterFile.length >0){
+            v.letterFile = v.letterFile.map(str=>{
+              return JSON.parse(str)
+            })
+          }
+          return v
+        })
+        this.pList = res.data;
+      })
+    },
+    preView(val) {
+      if(Array.isArray(val)){
+        let arr = val.map(v=>{
+          return imgUrl(v);
+        })
+        ImagePreview(arr);
+      }else {
+        ImagePreview([imgUrl(val)]);
+      }
+    },
+  }
+}
+</script>
+<style lang="scss">
+.intro-add{
+  .van-card{
+    padding: 20px;
+  }
+  .card-cell-box{
+    width: 70%;
+    .van-cell{
+      padding: 10px;
+      &::after{
+        left:10px;
+        right:10px;
+      }
+    }
+    .van-cell__title{
+      flex:.25;
+    }
+    .van-cell__value{
+      flex:.75;
+    }
+  }
+}
+</style>
+<style scoped lang="scss">
+.intro-add{
+  height: 100%;
+  overflow: hidden;
+}
+.page-container{
+  height: calc(100vh - 94px);
+  overflow: auto;
+  padding: 20px;
+
+}
+.flex-box{
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  >span{
+    margin: 0 20px;
+  }
+}
+.card{
+  margin-bottom: 20px;
+  box-shadow: 0 10px 10px #eaeaea;
+}
+.card:last-child{
+  margin-bottom: 0;
+}
+.panel-box{
+  -padding:0 20px;
+}
+.panel-box-item{
+  height: 36px;
+  line-height: 36px;
+}
+.item-label{
+  width: 100%;
+  display: flex;
+  justify-content: right;
+  align-items: center;
+}
+.item-value{
+  width: 100%;
+  display: flex;
+  justify-content: left;
+  align-items: center;
+}
+.upload-box{
+  padding: 0 30px;
+  display: flex;
+  >span{
+    display: inline-block;
+    height: 160px;
+    width: 200px;
+    line-height: 160px;
+    font-size: 28px;
+    color:#999;
+    >i{
+      font-style: normal;
+      color: #ee0a24;
+    }
+  }
+  .required::before{
+    content: '*';
+    color: #ee0a24;
+    position: absolute;
+    left: 14px;
+  }
+}
+.goods-card{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  padding: 10px;
+  background-color: #fff;
+  .card-img-box{
+    width: 200px;
+    height: 200px;
+    margin-right: 10px;
+    >img{
+      width: 100%;
+      height: 100%;
+      object-fit: cover;
+      border-radius: 10px;
+    }
+  }
+}
+.file-box{
+  width: 70%;
+  display: flex;
+  justify-content: flex-end;
+  color:#008cd6;
+}
+.big-btn-box{
+  padding: 20px;
+}
+.nfc-img {
+  display: inline-block;
+  width: 140px;
+  height: 140px;
+  margin: 0 10px;
+  position: relative;
+  > img {
+    width: 100%;
+    height: 100%;
+    border: none;
+  }
+  > span {
+    position: absolute;
+    padding: 0 10px;
+    bottom: 0;
+    left: 0;
+    display: block;
+    width: 100%;
+    background-color: rgba(0, 0, 0, 0.2);
+    color: #eaeaea;
+    font-size: 20px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    line-height: 30px;
+    height: 30px;
+  }
+}
+.search-data-popup{
+  .header-line {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    height: 90px;
+  }
+  .header-line .cancel {
+    padding: 0 30px;
+    font-size: 28px;
+    color: #969799;
+  }
+  .header-line .title {
+    font-weight: 500;
+    font-size: 30px;
+    color: #343434;
+  }
+  .header-line .sure {
+    padding: 0 30px;
+    font-size: 28px;
+    color: #1989fa;
+  }
+  .lists {
+    display: flex;
+    flex-direction: column;
+    -padding: 10px 12px 20px 12px;
+    min-height: 300px;
+    max-height: 700px;
+    overflow: auto;
+  }
+  .lists .line {
+    line-height: 40px;
+    font-size: 16px;
+    color: #000;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+  .lists .line img {
+    width: 20px;
+    height: 20px;
+  }
+  .tip {
+    color: #666;
+    padding-bottom: 5px;
+  }
+  .van-empty{
+    padding: 0;
+  }
+  .list-item{
+    padding:20px;
+  }
+  .active{
+    color:#1989fa;
+    border-left: 5px solid #1989fa;
+
+  }
+}
+</style>

+ 315 - 0
src/views/menu/iot/videoDay/index.vue

@@ -0,0 +1,315 @@
+<template>
+  <div class="visitRecord">
+    <NavBar/>
+    <div class="page-container">
+      <van-search v-model="query.userName" class="van-hairline--bottom" placeholder="请输入人员姓名" @clear="refreshData"  @change="refreshData"/>
+      <div class="search-flex">
+        <select-cell
+          style="border-right: 1px solid #f5f5f5;"
+          title="介绍信类型"
+          is-all
+          :border="false"
+          v-model="query.type"
+          :data-list="getDictItem('out_in_type')"
+          @change="refreshData"/>
+        <date-cell title="日期" is-all v-model="query.arrivalTime" date-type="date" @change="refreshData"/>
+      </div>
+      <div class="card-list">
+        <Scroll
+          ref="Scroll"
+          @refresh="refreshData"
+          @loadMore="getDataList"
+          :pullup="pullup">
+          <empty  v-if="!dataList || dataList.length === 0"/>
+          <card v-else v-for="(v,i) in dataList" :key="v.id">
+            <van-cell
+              :border="false"
+              class="item-title"
+              :title-style="{color:'#008cd6'}"
+              :title="`介绍信类型: ${getDictLabel(v.type,'out_in_type')}`"
+              @click="clickItem(v.id)">
+              <template #right-icon>
+                <van-button v-if="!v.departureTime" type="info" size="mini">登记离开时间</van-button>
+              </template>
+            </van-cell>
+            <van-cell
+              :border="false"
+              class="item-value"
+              @click="clickItem(v.id)">
+              <template #default>
+                <div class="info-box">
+                  <div class="info-item">
+                    <div class="item-label">人员姓名</div>
+                    <div class="item-value"> {{v.userName}}</div>
+                  </div>
+                  <div class="info-item">
+                    <div class="item-label">到达时间</div>
+                    <div class="item-value">
+                      {{ dayjs(v.arrivalTime).format('YYYY-MM-DD HH:mm')}}
+                    </div>
+                  </div>
+                  <div class="info-item">
+                    <div class="item-label">离开时间</div>
+                    <div class="item-value">
+                      {{v.departureTime? dayjs(v.departureTime).format('YYYY-MM-DD HH:mm') : '暂无'}}
+                    </div>
+                  </div>
+                </div>
+              </template>
+            </van-cell>
+          </card>
+
+
+<!--          <card v-else v-for="(v,i) in dataList" :key="v.id">-->
+<!--            <van-cell-->
+<!--              :title-style="{color:'#008cd6'}"-->
+<!--              :title="`介绍信类型: ${getDictLabel(v.type,'out_in_type')}`"-->
+<!--            @click="clickItem(v.id)">-->
+<!--              <template #right-icon>-->
+<!--                <van-button v-if="!v.departureTime" type="info" size="mini">登记离开时间</van-button>-->
+<!--                <van-button v-else type="info" size="mini">查看登记详情</van-button>-->
+<!--              </template>-->
+<!--              <template #label>-->
+<!--              <div class="info-box">-->
+<!--                <div class="info-item">-->
+<!--                  <div class="item-label">人员姓名:</div>-->
+<!--                  <div class="item-value"> {{v.userName}}</div>-->
+<!--                </div>-->
+<!--&lt;!&ndash;                <div class="info-item">&ndash;&gt;-->
+<!--&lt;!&ndash;                  <div class="item-label">证件号码:</div>&ndash;&gt;-->
+<!--&lt;!&ndash;                  <div class="item-value">{{v.idCard}}</div>&ndash;&gt;-->
+<!--&lt;!&ndash;                </div>&ndash;&gt;-->
+<!--                <div class="info-item">-->
+<!--                  <div class="item-label">到达时间:</div>-->
+<!--                  <div class="item-value">-->
+<!--                    {{ dayjs(v.arrivalTime).format('YYYY-MM-DD HH:mm')}}-->
+<!--                  </div>-->
+<!--                </div>-->
+<!--                <div class="info-item">-->
+<!--                  <div class="item-label">离开时间:</div>-->
+<!--                  <div class="item-value">-->
+<!--                    {{v.departureTime? dayjs(v.departureTime).format('YYYY-MM-DD HH:mm') : '暂无'}}-->
+<!--                  </div>-->
+<!--                </div>-->
+<!--&lt;!&ndash;                <div class="info-item">&ndash;&gt;-->
+<!--&lt;!&ndash;                  <div class="item-label">出入事由:</div>&ndash;&gt;-->
+<!--&lt;!&ndash;                  <div class="item-value">&ndash;&gt;-->
+<!--&lt;!&ndash;                    {{v.reasons}}&ndash;&gt;-->
+<!--&lt;!&ndash;                  </div>&ndash;&gt;-->
+<!--&lt;!&ndash;                </div>&ndash;&gt;-->
+<!--              </div>-->
+<!--            </template>-->
+<!--            </van-cell>-->
+<!--          </card>-->
+        </Scroll>
+      </div>
+    </div>
+    <drag-button @btnClick="clickAdd"></drag-button>
+  </div>
+</template>
+<script>
+import NavBar from '@/components/NavBar/index.vue'
+import OrgTree from '@/components/orgTree/index.vue'
+import Scroll from '@/components/scroll/scroll.vue'
+import Card from '@/components/card/index.vue'
+import dateCell from '@/components/dateCell/index.vue'
+import selectCell from '@/components/selectCell/index.vue'
+import {dataList} from './api'
+import {mapGetters} from "vuex";
+import {formatDate} from "@/filters/filter";
+import DragButton from "@/components/DragButton/index.vue";
+import dayjs from "dayjs";
+import Item from "@/views/menu/protection/components/item.vue";
+export default {
+  name: 'visitRecord',
+  components: {
+    Item,
+    DragButton,
+    NavBar,
+    OrgTree,
+    Scroll,
+    Card,
+    dateCell,
+    selectCell,
+  },
+  data() {
+    return {
+      query:{
+        arrivalTime:null,
+        userName:null,
+        pageSize:10,
+        pageNum:1,
+      },
+      dataList:[],
+      pullup:false,
+      dicts:['out_in_type']
+    }
+  },
+  beforeRouteEnter(to,from,next){
+    next(vm=>{
+      if(to.params.event === 'refresh'){
+        vm.refreshData();
+      }
+    })
+  },
+  mounted() {
+    this.initData();
+  },
+  computed:{
+    ...mapGetters(['orgId','id','dictionary']),
+  },
+  methods: {
+    dayjs,
+    clickAdd(){
+      this.$router.push({
+        path:'/visitUserRecord',
+      });
+    },
+    refreshData(){
+      this.pullup = true;
+      this.query.pageNum = 1;
+      this.total = 0;
+      this.dataList = [];
+      this.getDataList();
+    },
+    //初始化数据
+    initData(){
+      this.getDataList();
+    },
+    //获取数据列表
+    getDataList(){
+      if( this.dataList.length !== 0 && this.dataList.length >= this.total) {
+        this.pullup = false;
+        this.$toast('已加载完毕');
+        return;
+      }
+      let data = {
+        ...this.query,
+        orgId:this.orgId
+      }
+      dataList(data).then(res=>{
+        if(res.total === '0'){
+          this.pullup = false;
+          this.$toast('已加载完毕');
+          return
+        }
+        this.total = res.total;
+        if(this.dataList.length < res.total) {
+          this.dataList = [...this.dataList,...res.rows] ;
+          this.pullup = true;
+          this.query.pageNum++;
+          this.$refs.Scroll.refresh();
+        }
+      })
+    },
+    clickItem(id){
+      this.$router.push({
+        path:'/visitRecordDetail',
+        query:{id}
+      });
+    }
+  }
+}
+</script>
+<style lang="scss">
+.visitRecord{
+  .card {
+    >.van-cell{
+      padding: 0;
+    }
+  }
+  .van-cell-group{
+    margin-bottom: 20px;
+  }
+  .van-cell-group:last-child{
+    margin-bottom: 0;
+  }
+  .vue-table-root{
+    tr,td,th{
+      font-size: 25px!important;
+      color:#666!important;
+    }
+  }
+}
+</style>
+<style lang="scss" scoped>
+.problem-item{
+
+}
+.app-container{
+
+}
+.card-list{
+  padding:0 20px 20px 20px;
+  height: calc(100vh - 426px);
+  overflow:  auto;
+}
+.item-title{
+  border-bottom: 1px solid #f5f5f5;
+  padding-bottom: 20px !important;
+}
+.card-num{
+  display: flex;
+  align-items: center;
+  font-size: 28px;
+  color: #009dff;
+}
+.search-flex{
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  border-bottom: 1px solid #f5f5f5;
+  >div{
+    width: 50%;
+  }
+}
+.btn-box{
+  width: 100%;
+  height: 100%;
+  padding: 30px;
+  background-color: #fff;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.info-box{
+  color:#555;
+  padding-top: 20px;
+}
+.info-desc{
+  padding-top: 10px;
+  min-height: 50px;
+  line-height: 36px;
+  max-height: 250px;
+  display: -webkit-box;
+  -webkit-line-clamp: 3; /* 限制显示为3行 */
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  >span{
+    color:#999;
+  }
+}
+.info-item{
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  font-size: 26px;
+  .item-label{
+    flex:.25;
+    text-align: left;
+    color:#333;
+  }
+  .item-value{
+    flex:.75;
+    color:#666;
+    min-height: 50px;
+    max-height: 250px;
+    display: -webkit-box;
+    -webkit-line-clamp: 3; /* 限制显示为3行 */
+    -webkit-box-orient: vertical;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+}
+</style>

+ 44 - 0
src/views/menu/iot/videoIntegrity/api.js

@@ -0,0 +1,44 @@
+import request from "@/utils/request";
+//获取列表
+export function dataList(data) {
+  return request({
+    url: "/core/outinrecord/list",
+    method: "get",
+    params: data,
+  });
+}
+
+//用户列表
+export function userList(params) {
+  return request({
+    url: "/core/letter/approved/person",
+    method: "get",
+    params
+  });
+}
+
+//获取详情
+export function userDetails(id){
+  return request({
+    url: "/core/outinrecord/"+id,
+    method: "get",
+  });
+}
+
+//人员登记
+export function userRegister(data){
+  return request({
+    url: "/core/outinrecord",
+    method: "post",
+    data
+  });
+}
+
+//登记离开
+export function userDepart(data){
+  return request({
+    url: "/core/outinrecord",
+    method: "put",
+    data
+  });
+}

+ 386 - 0
src/views/menu/iot/videoIntegrity/detail.vue

@@ -0,0 +1,386 @@
+<template>
+  <div class="record-detail">
+    <nav-bar></nav-bar>
+    <div class="page-container">
+      <div class="card">
+        <van-panel>
+          <template #header>
+            <span></span>
+          </template>
+          <div class="tag-box">
+            <div v-for="(v,i) in tagList"
+             class="tag-item"
+             :style="{backgroundColor:getColor(v.state),borderColor:getColor(v.state)}"
+             @click="clickTag" :key="i">
+              {{v.name+i}}
+            </div>
+          </div>
+        </van-panel>
+      </div>
+      <!--   基本信息   -->
+      <div class="card">
+        <van-panel >
+            <template #header>
+              <span></span>
+            </template>
+          <div class="panel-box">
+            <van-cell title="组织机构" :value="selectedUser.userName"></van-cell>
+            <van-cell title="监控主机" :value="getDictLabel(selectedUser.type,'out_in_type')"></van-cell>
+            <van-cell title="通道号" :value="selectedUser.reasons"></van-cell>
+            <van-cell title="计划存储天数" :value="selectedUser.companyName"></van-cell>
+            <van-cell title="上报日期" :value="getDictLabel(selectedUser.idType,'letter_id_type')"></van-cell>
+            <van-cell title="检查日期" :value="selectedUser.idCard"></van-cell>
+
+            <van-cell title="计划时间" >
+              <template #label>
+                <van-cell title="1" :value="dayjs(selectedUser.arrivalTime).format('YYYY-DD-MM HH:mm')"></van-cell>
+                <van-cell title="2" :value="dayjs(selectedUser.arrivalTime).format('YYYY-DD-MM HH:mm')"></van-cell>
+                <van-cell title="3" :value="dayjs(selectedUser.arrivalTime).format('YYYY-DD-MM HH:mm')"></van-cell>
+              </template>
+            </van-cell>
+
+            <van-cell title="丢失时间" >
+              <template #label>
+                <van-cell title="1" :value="dayjs(selectedUser.arrivalTime).format('YYYY-DD-MM HH:mm')"></van-cell>
+                <van-cell title="2" :value="dayjs(selectedUser.arrivalTime).format('YYYY-DD-MM HH:mm')"></van-cell>
+                <van-cell title="3" :value="dayjs(selectedUser.arrivalTime).format('YYYY-DD-MM HH:mm')"></van-cell>
+              </template>
+            </van-cell>
+
+
+          </div>
+          <div class="big-btn-box" >
+            <van-button  type="info" size="large" @click="onSubmit">生成运维单</van-button>
+          </div>
+        </van-panel>
+      </div>
+
+    </div>
+  </div>
+</template>
+
+<script>
+
+import DateCell from "@/components/dateCell/index.vue";
+import Uploader from "@/components/upload/gxuploader.vue";
+import {formatDate} from "@/filters/filter";
+import {mapGetters} from "vuex";
+import {imgUrl} from "@/utils";
+import { ImagePreview } from 'vant'
+import {userDetails, userDepart} from './api'
+import dayjs from 'dayjs'
+export default {
+  components: {Uploader, DateCell},
+  data(){
+    return {
+      tagList:[
+        {
+          name:'通道',
+          state:1,
+        },
+        {
+          name:'通道',
+          state:3,
+        },
+        {
+          name:'通道',
+          state:2,
+        },
+        {
+          name:'通道',
+          state:1,
+        },
+        {
+          name:'通道',
+          state:3,
+        },
+        {
+          name:'通道',
+          state:2,
+        },
+        {
+          name:'通道',
+          state:1,
+        },
+        {
+          name:'通道',
+          state:3,
+        },
+        {
+          name:'通道',
+          state:2,
+        },
+        {
+          name:'通道',
+          state:1,
+        },
+        {
+          name:'通道',
+          state:3,
+        },
+        {
+          name:'通道',
+          state:2,
+        },
+        {
+          name:'通道',
+          state:1,
+        },
+        {
+          name:'通道',
+          state:3,
+        },
+        {
+          name:'通道',
+          state:2,
+        },
+      ],
+      maxData:new Date(),
+      minDate:null,
+      visitId:null,
+      userList:[],
+      selectedUser:{},
+      prop:{
+        label:'userName',
+        value:'id'
+      },
+      formData:{
+        arrivalTime:null,
+        departureTime:null,
+      },
+      dicts:['out_in_approve_status','out_in_type','letter_id_type']
+    }
+  },
+  computed:{
+    ...mapGetters(['orgId','id','dictionary']),
+  },
+  created(){
+    this.visitId = this.$route.query.id;
+    this.getUserInfo();
+  },
+  methods:{
+    imgUrl,formatDate,
+    getColor(s){
+      if(s ===1){
+        return '#009240';
+      }
+      if(s ===2){
+        return '#D7000F';
+      }
+      if(s===3){
+        return '#FFA500';
+      }
+    },
+    clickTag(){
+
+    },
+    onSubmit(){
+      this.$router.replace({
+        name:'addOrder',
+        path:'/addOrder',
+      });
+    },
+    getUserInfo(){
+      userDetails(this.visitId).then(res=>{
+        let checkImage = res.data.checkImage.split(',');
+        let imgFile = res.data.imgFile.split(',');
+        let letterFile = [];
+        if(res.data.letterFile && res.data.letterFile.length > 0){
+            letterFile = res.data.letterFile.map(v=>{
+            return JSON.parse(v)
+          })
+        }
+        this.selectedUser = res.data;
+        this.selectedUser.checkImage = checkImage;
+        this.selectedUser.imgFile = imgFile;
+        this.selectedUser.letterFile = letterFile;
+        //设置最小时间
+        let minDate = this.selectedUser.arrivalTime;
+        this.minDate = new Date(minDate);
+      })
+    },
+    previewFile(file){
+      this.openFilePreview(file);
+    },
+    preView(val) {
+      if(Array.isArray(val)){
+        let arr = val.map(v=>{
+          return imgUrl(v);
+        })
+        ImagePreview(arr);
+      }else {
+        ImagePreview([imgUrl(val)]);
+      }
+    },
+  }
+}
+</script>
+<style lang="scss">
+.record-detail{
+  .van-card{
+    padding: 20px;
+  }
+  .card-cell-box{
+    width: 70%;
+    .van-cell{
+      padding: 10px;
+      &::after{
+        left:10px;
+        right:10px;
+      }
+    }
+    .van-cell__title{
+      flex:.25;
+    }
+    .van-cell__value{
+      flex:.75;
+    }
+  }
+}
+</style>
+<style scoped lang="scss">
+.record-detail{
+  height: 100%;
+  overflow: hidden;
+}
+.page-container{
+  height: calc(100vh - 94px);
+  overflow: auto;
+  padding: 20px;
+
+}
+.tag-box{
+   padding: 20px;
+   display:  grid;
+   grid-template-columns: repeat(4, 1fr);
+  .tag-item{
+    width: 130px;
+    height: 70px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    margin: 10px 18px;
+    background-color: #009dff;
+    border:1px solid #009dff;
+    color:#fff;
+    padding:10px;
+    border-radius: 10px;
+    //&:hover{
+    //  color: #009dff;
+    //  background-color:#fff;
+    //  border:1px solid #009dff;
+    //}
+  }
+}
+.flex-box{
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  >span{
+    margin: 0 20px;
+  }
+}
+.card{
+  margin-bottom: 20px;
+  box-shadow: 0 10px 10px #eaeaea;
+}
+.card:last-child{
+  margin-bottom: 0;
+}
+.panel-box{
+  -padding:0 20px;
+}
+.panel-box-item{
+  height: 36px;
+  line-height: 36px;
+}
+.item-label{
+  width: 100%;
+  display: flex;
+  justify-content: right;
+  align-items: center;
+}
+.item-value{
+  width: 100%;
+  display: flex;
+  justify-content: left;
+  align-items: center;
+}
+.upload-box{
+  padding: 20px 30px;
+  display: flex;
+  >span{
+    display: inline-block;
+    height: 160px;
+    width: 200px;
+    line-height: 160px;
+    font-size: 28px;
+    color:#999;
+    >i{
+      font-style: normal;
+      color: #ee0a24;
+    }
+  }
+  .required::before{
+    content: '*';
+    color: #ee0a24;
+    position: absolute;
+    left: 14px;
+  }
+}
+.goods-card{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  padding: 10px;
+  background-color: #fff;
+  .card-img-box{
+    width: 200px;
+    height: 200px;
+    margin-right: 10px;
+    >img{
+      width: 100%;
+      height: 100%;
+      object-fit: cover;
+      border-radius: 10px;
+    }
+  }
+}
+.big-btn-box{
+  padding: 20px;
+}
+.file-box{
+  width: 70%;
+  display: flex;
+  justify-content: flex-end;
+  color:#008cd6;
+}
+.nfc-img {
+  display: inline-block;
+  width: 140px;
+  height: 140px;
+  margin: 0 10px;
+  position: relative;
+  > img {
+    width: 100%;
+    height: 100%;
+    border: none;
+  }
+  > span {
+    position: absolute;
+    padding: 0 10px;
+    bottom: 0;
+    left: 0;
+    display: block;
+    width: 100%;
+    background-color: rgba(0, 0, 0, 0.2);
+    color: #eaeaea;
+    font-size: 20px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    line-height: 30px;
+    height: 30px;
+  }
+}
+</style>

+ 318 - 0
src/views/menu/iot/videoIntegrity/index.vue

@@ -0,0 +1,318 @@
+<template>
+  <div class="visitRecord">
+    <NavBar/>
+    <div class="page-container">
+      <div class="org-line van-hairline--bottom">
+        <org-tree clearable v-model="query.beCheckedOrgId" placeholder="选择机构" @change="refreshData"></org-tree>
+      </div>
+      <div class="search-flex">
+        <select-cell
+          style="border-right: 1px solid #f5f5f5;"
+          title="状态"
+          is-all
+          :border="false"
+          v-model="query.type"
+          :data-list="getDictItem('out_in_type')"
+          @change="refreshData"/>
+        <date-cell title="检查日期" is-all v-model="query.arrivalTime" date-type="date" @change="refreshData"/>
+      </div>
+      <div class="card-list">
+        <Scroll
+          ref="Scroll"
+          @refresh="refreshData"
+          @loadMore="getDataList"
+          :pullup="pullup">
+          <empty  v-if="!dataList || dataList.length === 0"/>
+          <card v-else v-for="(v,i) in dataList" :key="v.id">
+            <van-cell
+              :border="false"
+              class="item-value"
+              @click="clickItem(v.id)">
+              <template #default>
+                <div class="info-item">
+                  <div class="item-label item-device">XXX设备</div>
+                  <i  class="point-icon" :class="{'active':!v.isRead}" />
+                </div>
+                <div class="info-box">
+                  <div class="info-item">
+                    <div class="item-label">品牌</div>
+                    <div class="item-value"> {{v.userName}}</div>
+                  </div>
+                  <div class="info-item">
+                    <div class="item-label">机构</div>
+                    <div class="item-value">
+                      {{ dayjs(v.arrivalTime).format('YYYY-MM-DD HH:mm')}}
+                    </div>
+                  </div>
+                </div>
+              </template>
+            </van-cell>
+          </card>
+
+
+<!--          <card v-else v-for="(v,i) in dataList" :key="v.id">-->
+<!--            <van-cell-->
+<!--              :title-style="{color:'#008cd6'}"-->
+<!--              :title="`介绍信类型: ${getDictLabel(v.type,'out_in_type')}`"-->
+<!--            @click="clickItem(v.id)">-->
+<!--              <template #right-icon>-->
+<!--                <van-button v-if="!v.departureTime" type="info" size="mini">登记离开时间</van-button>-->
+<!--                <van-button v-else type="info" size="mini">查看登记详情</van-button>-->
+<!--              </template>-->
+<!--              <template #label>-->
+<!--              <div class="info-box">-->
+<!--                <div class="info-item">-->
+<!--                  <div class="item-label">人员姓名:</div>-->
+<!--                  <div class="item-value"> {{v.userName}}</div>-->
+<!--                </div>-->
+<!--&lt;!&ndash;                <div class="info-item">&ndash;&gt;-->
+<!--&lt;!&ndash;                  <div class="item-label">证件号码:</div>&ndash;&gt;-->
+<!--&lt;!&ndash;                  <div class="item-value">{{v.idCard}}</div>&ndash;&gt;-->
+<!--&lt;!&ndash;                </div>&ndash;&gt;-->
+<!--                <div class="info-item">-->
+<!--                  <div class="item-label">到达时间:</div>-->
+<!--                  <div class="item-value">-->
+<!--                    {{ dayjs(v.arrivalTime).format('YYYY-MM-DD HH:mm')}}-->
+<!--                  </div>-->
+<!--                </div>-->
+<!--                <div class="info-item">-->
+<!--                  <div class="item-label">离开时间:</div>-->
+<!--                  <div class="item-value">-->
+<!--                    {{v.departureTime? dayjs(v.departureTime).format('YYYY-MM-DD HH:mm') : '暂无'}}-->
+<!--                  </div>-->
+<!--                </div>-->
+<!--&lt;!&ndash;                <div class="info-item">&ndash;&gt;-->
+<!--&lt;!&ndash;                  <div class="item-label">出入事由:</div>&ndash;&gt;-->
+<!--&lt;!&ndash;                  <div class="item-value">&ndash;&gt;-->
+<!--&lt;!&ndash;                    {{v.reasons}}&ndash;&gt;-->
+<!--&lt;!&ndash;                  </div>&ndash;&gt;-->
+<!--&lt;!&ndash;                </div>&ndash;&gt;-->
+<!--              </div>-->
+<!--            </template>-->
+<!--            </van-cell>-->
+<!--          </card>-->
+        </Scroll>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import NavBar from '@/components/NavBar/index.vue'
+import OrgTree from '@/components/orgTree/index.vue'
+import Scroll from '@/components/scroll/scroll.vue'
+import Card from '@/components/card/index.vue'
+import dateCell from '@/components/dateCell/index.vue'
+import selectCell from '@/components/selectCell/index.vue'
+import {dataList} from './api'
+import {mapGetters} from "vuex";
+import dayjs from "dayjs";
+import Item from "@/views/menu/protection/components/item.vue";
+export default {
+  name: 'visitRecord',
+  components: {
+    Item,
+    NavBar,
+    OrgTree,
+    Scroll,
+    Card,
+    dateCell,
+    selectCell,
+  },
+  data() {
+    return {
+      query:{
+        arrivalTime:null,
+        userName:null,
+        pageSize:10,
+        pageNum:1,
+      },
+      dataList:[],
+      pullup:false,
+      dicts:['out_in_type']
+    }
+  },
+  beforeRouteEnter(to,from,next){
+    next(vm=>{
+      if(to.params.event === 'refresh'){
+        vm.refreshData();
+      }
+    })
+  },
+  mounted() {
+    this.initData();
+  },
+  computed:{
+    ...mapGetters(['orgId','id','dictionary']),
+  },
+  methods: {
+    dayjs,
+    clickAdd(){
+      this.$router.push({
+        path:'/visitUserRecord',
+      });
+    },
+    refreshData(){
+      this.pullup = true;
+      this.query.pageNum = 1;
+      this.total = 0;
+      this.dataList = [];
+      this.getDataList();
+    },
+    //初始化数据
+    initData(){
+      this.getDataList();
+    },
+    //获取数据列表
+    getDataList(){
+      if( this.dataList.length !== 0 && this.dataList.length >= this.total) {
+        this.pullup = false;
+        this.$toast('已加载完毕');
+        return;
+      }
+      let data = {
+        ...this.query,
+        orgId:this.orgId
+      }
+      dataList(data).then(res=>{
+        if(res.total === '0'){
+          this.pullup = false;
+          this.$toast('已加载完毕');
+          return
+        }
+        this.total = res.total;
+        if(this.dataList.length < res.total) {
+          this.dataList = [...this.dataList,...res.rows] ;
+          this.pullup = true;
+          this.query.pageNum++;
+          this.$refs.Scroll.refresh();
+        }
+      })
+    },
+    clickItem(id){
+      this.$router.push({
+        path:'/videoIntegrityDetail',
+        query:{id}
+      });
+    }
+  }
+}
+</script>
+<style lang="scss">
+.visitRecord{
+  .card {
+    >.van-cell{
+      padding: 0;
+    }
+  }
+  .van-cell-group{
+    margin-bottom: 20px;
+  }
+  .van-cell-group:last-child{
+    margin-bottom: 0;
+  }
+  .vue-table-root{
+    tr,td,th{
+      font-size: 25px!important;
+      color:#666!important;
+    }
+  }
+}
+</style>
+<style lang="scss" scoped>
+.problem-item{
+
+}
+.app-container{
+
+}
+.card-list{
+  padding:0 20px 20px 20px;
+  height: calc(100vh - 408px);
+  overflow:  auto;
+  -border: 1px solid red;
+}
+.item-title{
+  border-bottom: 1px solid #f5f5f5;
+  padding-bottom: 20px !important;
+}
+.card-num{
+  display: flex;
+  align-items: center;
+  font-size: 28px;
+  color: #009dff;
+}
+.search-flex{
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  border-bottom: 1px solid #f5f5f5;
+  >div{
+    width: 50%;
+  }
+}
+.btn-box{
+  width: 100%;
+  height: 100%;
+  padding: 30px;
+  background-color: #fff;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.info-box{
+  color:#555;
+  padding-top: 20px;
+}
+.info-desc{
+  padding-top: 10px;
+  min-height: 50px;
+  line-height: 36px;
+  max-height: 250px;
+  display: -webkit-box;
+  -webkit-line-clamp: 3; /* 限制显示为3行 */
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  >span{
+    color:#999;
+  }
+}
+.info-item{
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  font-size: 26px;
+  .item-label{
+    flex:.25;
+    text-align: left;
+    color:#333;
+  }
+  .item-value{
+    flex:.75;
+    color:#666;
+    min-height: 50px;
+    max-height: 250px;
+    display: -webkit-box;
+    -webkit-line-clamp: 3; /* 限制显示为3行 */
+    -webkit-box-orient: vertical;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+  .item-device{
+    font-size: 32px;
+    color:#008cd6;
+  }
+  .point-icon{
+    width: 20px;
+    height: 20px;
+    background-color:#ccc;
+    border-radius: 50%;
+    margin-top: 10px;
+    display: none;
+    &.active{
+      display: block;
+      background-color: #ee0a24;
+    }
+  }
+}
+</style>

+ 315 - 0
src/views/menu/iot/videoQuality/index.vue

@@ -0,0 +1,315 @@
+<template>
+  <div class="visitRecord">
+    <NavBar/>
+    <div class="page-container">
+      <van-search v-model="query.userName" class="van-hairline--bottom" placeholder="请输入人员姓名" @clear="refreshData"  @change="refreshData"/>
+      <div class="search-flex">
+        <select-cell
+          style="border-right: 1px solid #f5f5f5;"
+          title="介绍信类型"
+          is-all
+          :border="false"
+          v-model="query.type"
+          :data-list="getDictItem('out_in_type')"
+          @change="refreshData"/>
+        <date-cell title="日期" is-all v-model="query.arrivalTime" date-type="date" @change="refreshData"/>
+      </div>
+      <div class="card-list">
+        <Scroll
+          ref="Scroll"
+          @refresh="refreshData"
+          @loadMore="getDataList"
+          :pullup="pullup">
+          <empty  v-if="!dataList || dataList.length === 0"/>
+          <card v-else v-for="(v,i) in dataList" :key="v.id">
+            <van-cell
+              :border="false"
+              class="item-title"
+              :title-style="{color:'#008cd6'}"
+              :title="`介绍信类型: ${getDictLabel(v.type,'out_in_type')}`"
+              @click="clickItem(v.id)">
+              <template #right-icon>
+                <van-button v-if="!v.departureTime" type="info" size="mini">登记离开时间</van-button>
+              </template>
+            </van-cell>
+            <van-cell
+              :border="false"
+              class="item-value"
+              @click="clickItem(v.id)">
+              <template #default>
+                <div class="info-box">
+                  <div class="info-item">
+                    <div class="item-label">人员姓名</div>
+                    <div class="item-value"> {{v.userName}}</div>
+                  </div>
+                  <div class="info-item">
+                    <div class="item-label">到达时间</div>
+                    <div class="item-value">
+                      {{ dayjs(v.arrivalTime).format('YYYY-MM-DD HH:mm')}}
+                    </div>
+                  </div>
+                  <div class="info-item">
+                    <div class="item-label">离开时间</div>
+                    <div class="item-value">
+                      {{v.departureTime? dayjs(v.departureTime).format('YYYY-MM-DD HH:mm') : '暂无'}}
+                    </div>
+                  </div>
+                </div>
+              </template>
+            </van-cell>
+          </card>
+
+
+<!--          <card v-else v-for="(v,i) in dataList" :key="v.id">-->
+<!--            <van-cell-->
+<!--              :title-style="{color:'#008cd6'}"-->
+<!--              :title="`介绍信类型: ${getDictLabel(v.type,'out_in_type')}`"-->
+<!--            @click="clickItem(v.id)">-->
+<!--              <template #right-icon>-->
+<!--                <van-button v-if="!v.departureTime" type="info" size="mini">登记离开时间</van-button>-->
+<!--                <van-button v-else type="info" size="mini">查看登记详情</van-button>-->
+<!--              </template>-->
+<!--              <template #label>-->
+<!--              <div class="info-box">-->
+<!--                <div class="info-item">-->
+<!--                  <div class="item-label">人员姓名:</div>-->
+<!--                  <div class="item-value"> {{v.userName}}</div>-->
+<!--                </div>-->
+<!--&lt;!&ndash;                <div class="info-item">&ndash;&gt;-->
+<!--&lt;!&ndash;                  <div class="item-label">证件号码:</div>&ndash;&gt;-->
+<!--&lt;!&ndash;                  <div class="item-value">{{v.idCard}}</div>&ndash;&gt;-->
+<!--&lt;!&ndash;                </div>&ndash;&gt;-->
+<!--                <div class="info-item">-->
+<!--                  <div class="item-label">到达时间:</div>-->
+<!--                  <div class="item-value">-->
+<!--                    {{ dayjs(v.arrivalTime).format('YYYY-MM-DD HH:mm')}}-->
+<!--                  </div>-->
+<!--                </div>-->
+<!--                <div class="info-item">-->
+<!--                  <div class="item-label">离开时间:</div>-->
+<!--                  <div class="item-value">-->
+<!--                    {{v.departureTime? dayjs(v.departureTime).format('YYYY-MM-DD HH:mm') : '暂无'}}-->
+<!--                  </div>-->
+<!--                </div>-->
+<!--&lt;!&ndash;                <div class="info-item">&ndash;&gt;-->
+<!--&lt;!&ndash;                  <div class="item-label">出入事由:</div>&ndash;&gt;-->
+<!--&lt;!&ndash;                  <div class="item-value">&ndash;&gt;-->
+<!--&lt;!&ndash;                    {{v.reasons}}&ndash;&gt;-->
+<!--&lt;!&ndash;                  </div>&ndash;&gt;-->
+<!--&lt;!&ndash;                </div>&ndash;&gt;-->
+<!--              </div>-->
+<!--            </template>-->
+<!--            </van-cell>-->
+<!--          </card>-->
+        </Scroll>
+      </div>
+    </div>
+    <drag-button @btnClick="clickAdd"></drag-button>
+  </div>
+</template>
+<script>
+import NavBar from '@/components/NavBar/index.vue'
+import OrgTree from '@/components/orgTree/index.vue'
+import Scroll from '@/components/scroll/scroll.vue'
+import Card from '@/components/card/index.vue'
+import dateCell from '@/components/dateCell/index.vue'
+import selectCell from '@/components/selectCell/index.vue'
+import {dataList} from './api'
+import {mapGetters} from "vuex";
+import {formatDate} from "@/filters/filter";
+import DragButton from "@/components/DragButton/index.vue";
+import dayjs from "dayjs";
+import Item from "@/views/menu/protection/components/item.vue";
+export default {
+  name: 'visitRecord',
+  components: {
+    Item,
+    DragButton,
+    NavBar,
+    OrgTree,
+    Scroll,
+    Card,
+    dateCell,
+    selectCell,
+  },
+  data() {
+    return {
+      query:{
+        arrivalTime:null,
+        userName:null,
+        pageSize:10,
+        pageNum:1,
+      },
+      dataList:[],
+      pullup:false,
+      dicts:['out_in_type']
+    }
+  },
+  beforeRouteEnter(to,from,next){
+    next(vm=>{
+      if(to.params.event === 'refresh'){
+        vm.refreshData();
+      }
+    })
+  },
+  mounted() {
+    this.initData();
+  },
+  computed:{
+    ...mapGetters(['orgId','id','dictionary']),
+  },
+  methods: {
+    dayjs,
+    clickAdd(){
+      this.$router.push({
+        path:'/visitUserRecord',
+      });
+    },
+    refreshData(){
+      this.pullup = true;
+      this.query.pageNum = 1;
+      this.total = 0;
+      this.dataList = [];
+      this.getDataList();
+    },
+    //初始化数据
+    initData(){
+      this.getDataList();
+    },
+    //获取数据列表
+    getDataList(){
+      if( this.dataList.length !== 0 && this.dataList.length >= this.total) {
+        this.pullup = false;
+        this.$toast('已加载完毕');
+        return;
+      }
+      let data = {
+        ...this.query,
+        orgId:this.orgId
+      }
+      dataList(data).then(res=>{
+        if(res.total === '0'){
+          this.pullup = false;
+          this.$toast('已加载完毕');
+          return
+        }
+        this.total = res.total;
+        if(this.dataList.length < res.total) {
+          this.dataList = [...this.dataList,...res.rows] ;
+          this.pullup = true;
+          this.query.pageNum++;
+          this.$refs.Scroll.refresh();
+        }
+      })
+    },
+    clickItem(id){
+      this.$router.push({
+        path:'/visitRecordDetail',
+        query:{id}
+      });
+    }
+  }
+}
+</script>
+<style lang="scss">
+.visitRecord{
+  .card {
+    >.van-cell{
+      padding: 0;
+    }
+  }
+  .van-cell-group{
+    margin-bottom: 20px;
+  }
+  .van-cell-group:last-child{
+    margin-bottom: 0;
+  }
+  .vue-table-root{
+    tr,td,th{
+      font-size: 25px!important;
+      color:#666!important;
+    }
+  }
+}
+</style>
+<style lang="scss" scoped>
+.problem-item{
+
+}
+.app-container{
+
+}
+.card-list{
+  padding:0 20px 20px 20px;
+  height: calc(100vh - 426px);
+  overflow:  auto;
+}
+.item-title{
+  border-bottom: 1px solid #f5f5f5;
+  padding-bottom: 20px !important;
+}
+.card-num{
+  display: flex;
+  align-items: center;
+  font-size: 28px;
+  color: #009dff;
+}
+.search-flex{
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  border-bottom: 1px solid #f5f5f5;
+  >div{
+    width: 50%;
+  }
+}
+.btn-box{
+  width: 100%;
+  height: 100%;
+  padding: 30px;
+  background-color: #fff;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.info-box{
+  color:#555;
+  padding-top: 20px;
+}
+.info-desc{
+  padding-top: 10px;
+  min-height: 50px;
+  line-height: 36px;
+  max-height: 250px;
+  display: -webkit-box;
+  -webkit-line-clamp: 3; /* 限制显示为3行 */
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  >span{
+    color:#999;
+  }
+}
+.info-item{
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  font-size: 26px;
+  .item-label{
+    flex:.25;
+    text-align: left;
+    color:#333;
+  }
+  .item-value{
+    flex:.75;
+    color:#666;
+    min-height: 50px;
+    max-height: 250px;
+    display: -webkit-box;
+    -webkit-line-clamp: 3; /* 限制显示为3行 */
+    -webkit-box-orient: vertical;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+}
+</style>