Selaa lähdekoodia

Merge branch 'V0.0.7' of http://10.87.21.221:8000/jzyd_yyds/soc_app into V0.0.7

jiawuxian 1 vuosi sitten
vanhempi
commit
55cc5e6d7b

+ 1 - 1
src/api/toConsult.js

@@ -112,7 +112,7 @@ export function getEditInfo(query) {
   })
 }
 //结束调阅
-export function getEndInfo(data) {
+export function finishRegistration(data) {
   return request({
     url: `/core/registration`,
     method: 'put',

+ 6 - 0
src/router/router.config.js

@@ -346,6 +346,12 @@ export let routers = [
         meta: { title: '新增申请', keepAlive: false, hideTabBar: true, deep: 2 }
       },
       {
+        path: '/visitAddOutInRequset',
+        name: 'visitAddOutInRequset',
+        component: () => import('@/views/menu/visitRegister/addOutInRequest.vue'),
+        meta: { title: '出入申请', keepAlive: false, hideTabBar: true, deep: 2 }
+      },
+      {
         path: '/visitDetail',
         name: 'visitDetail',
         component: () => import('@/views/menu/visitRegister/detail.vue'),

+ 10 - 1
src/views/menu/cockpit/indexEcharts.js

@@ -457,7 +457,16 @@ let resumption = (data, type = 0) => {
         type: 'none'
       },
       formatter: function (params) {
-        return getzszy[params[0].dataIndex] + '<br>完成率: ' + getzswcl2[params[0].dataIndex]
+        // console.log("params",params)
+        let tempValue= getzswcl2[params[0].dataIndex];
+        if(tempValue.includes("项") || params[0].name=="整改率")
+        {
+          return getzszy[params[0].dataIndex] + ': '+getzswcl2[params[0].dataIndex]
+        }
+        else
+        {
+          return getzszy[params[0].dataIndex] + '<br>完成率: ' + getzswcl2[params[0].dataIndex]
+        }      
       }
     },
     xAxis: {

+ 184 - 0
src/views/menu/monitoringCall/components/areaMonitoringList.vue

@@ -0,0 +1,184 @@
+<template>
+  <div>
+    <div class="topBox">
+      <div class="title" style="padding-top: 10px; margin-top: 0px">区域名称:{{ list.areaName }}</div>
+      <!-- <div class="title">摄像机:{{ list.videoChannelName }}</div> -->
+      <van-row class="List titleList">
+        <van-col class="vancol" span="10">项目</van-col>
+        <van-col class="vancol" span="14">检查情况</van-col>
+      </van-row>
+      <div v-for="item in list.coreMonitoringTaskMonitorInfoList" :key="item.id">
+        <van-row>
+          <van-col :class="item.situation == 1 ? 'vancol borderClsyc' : 'vancol borderCls'" span="10">{{
+            item.project | proJectListFilter(this_)
+          }}</van-col>
+          <van-col :class="item.situation == 1 ? 'vancol borderClsyc' : 'vancol borderCls'" span="14"
+            ><span :style="{ color: item.situation == 1 ? '#12b533' : '#12b533' }">{{
+              item.situation | dictFilter(this_)
+            }}</span></van-col
+          >
+        </van-row>
+        <van-row v-if="item.situation == 1" class="borderyc">
+          <van-col class="abnorText yctextleft" span="10" >异常情况描述:</van-col>
+          <van-col class="abnorText yctext" span="14">{{ item.abnormalIllustrate }}</van-col>
+        </van-row>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  name: 'SocAppMonitoringList',
+  props: {
+    list: {
+      type: Object,
+      default: {}
+    },
+    //调阅状态
+    taskStatus: {
+      type: String
+    }
+  },
+  data() {
+    return {
+      this_: this,
+      proJectList: [],
+      dictList: [] //字典情况数组
+    }
+  },
+  filters: {
+    dictFilter: function (value, that) {
+      let label = ''
+      if (that.dictList && that.dictList.length > 0) {
+        that.dictList.filter(item => {
+          if (value == item.dictValue) {
+            label = item.dictLabel
+          }
+        })
+      }
+      return label
+    },
+    proJectListFilter: function (value, that) {
+      let label = ''
+      if (that.proJectList && that.proJectList.length > 0) {
+        that.proJectList.filter(item => {
+          if (value == item.dictValue) {
+            label = item.dictLabel
+          }
+        })
+      }
+      return label
+    }
+  },
+  created() {
+    //获取异常情况字典
+    this.getDictHandler('core_check_type', res => {
+      this.dictList = res
+    })
+    //获取项目字典
+    this.getDictHandler('core_registration_project', res => {
+      this.proJectList = JSON.parse(JSON.stringify(res))
+      this.proJectList.forEach(item => {})
+    })
+  },
+  mounted() {},
+
+  methods: {
+    //编辑项目
+    // editHandler(isEdit) {
+    //   let path = ''
+    //   if (isEdit === 1) {
+    //     path = 'info'
+    //   } else {
+    //     path = 'update'
+    //   }
+    //   // isEdit 1查看 0编辑
+    //   console.log()
+    //   this.$router.push(`/${path}/` + this.$route.params.id.split('_')[0] + '_' + this.list.id + '_edit' + '_' + isEdit)
+    // }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.topBox {
+  position: relative;
+  background-color: #fff;
+  // width: 100%;
+  // border-radius: 10px;
+  margin-left: 20px;
+  margin-right: 20px;
+
+  font-size: 26px;
+  // box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+.title {
+  margin-top: 10px;
+  margin-bottom: 10px;
+  margin-left: 20px;
+}
+.van-row {
+  // padding-left: 10px;
+}
+
+.List {
+  background-color: #e8e8e8;
+  margin-bottom: -1px;
+  text-align: left;
+  height: 100%;
+}
+.titleList {
+  font-size: 26px;
+  text-align: left;
+  font-weight: bold;
+}
+.vancol {
+  height: 100%;
+
+  line-height: 60px;
+
+  padding-left: 20px;
+}
+.borderCls {
+  border: 1px solid #ccc;
+  border-top: none;
+}
+.borderClsyc{
+  border: 1px solid #ccc;
+  border-bottom: none;
+}
+
+.borderyc {
+  font-size: 20px;
+  border-right: 1px solid #ccc;
+  border-left: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+}
+.yctextleft{
+  border-right: 1px solid #ccc;
+}
+.yctext {
+  border-left: 2px solid #ccc;
+  
+ 
+}
+.abnorText {
+  // font-size: 20px;
+  color: #ff0202;
+  padding-left: 10px;
+  word-wrap: break-word;
+  padding-left: 10px;
+}
+.img {
+  width: 50px;
+  height: 50px;
+  position: absolute;
+  right: 20px;
+}
+.buttoncls {
+  width: 100px;
+  height: 50px;
+  position: absolute;
+  right: 20px;
+  top: 5%;
+}
+</style>

+ 124 - 0
src/views/menu/monitoringCall/components/areaPassage.vue

@@ -0,0 +1,124 @@
+<template>
+  <div>
+    <van-row v-if="list && list.length > 0">
+      <van-col
+        span="11"
+        @click="passageEdit(item.dictValue,item.dictLabel)"
+        :class="'passageIcon' + ' ' + classlist[item.type]"
+        v-for="item in list"
+        :key="item.name"
+      >
+        <span class="pors success" v-if="item.type == '1'">
+          <van-icon name="success" size="14" color="#fff" />
+        </span>
+        <span class="pors success" v-if="item.type == '2'">
+          <van-icon name="success" size="14" color="#fff" />
+        </span>
+        
+       <span :class="item.dictLabel.length<=10? 'textClass':'textClassLength10'">
+        {{ item.dictLabel }}        
+       </span> 
+       
+        
+      </van-col>
+    </van-row>
+    <!-- 添加或编辑调阅任务弹框 -->
+    <!-- @resetList="" -->
+    <areaTaskInfo ref="areaTaskInfo" @resetList="resetList"></areaTaskInfo>
+  </div>
+</template>
+<script>
+//调阅弹框组件
+// import taskInfo from './taskInfo.vue'
+import areaTaskInfo from './areaTaskInfo.vue'
+
+export default {
+  name: 'SocAppPassage',
+  components: {
+    areaTaskInfo
+  },
+  props: {
+    //区域列表
+    list: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    //任务ID
+    taskId: {
+      type: String,
+      default: ''
+    },
+  },
+  data() {
+    return {
+      classlist: ['cls0', 'cls1', 'cls2']
+    }
+  },
+
+  mounted() {},
+
+  methods: {
+    passageEdit(areaValue,areaName) {
+      console.log("passageEdit",areaValue,areaName)
+      //添加或者编辑调阅
+      this.$refs.areaTaskInfo.init(this.taskId,areaValue,areaName)
+    },
+    resetList(){
+        this.$emit('resetList',0)
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.passageIcon {
+  position: relative;
+  text-align: center;
+  margin: 10px 10px 0px 10px;
+  box-sizing: border-box;
+  border-radius: 10px;
+  min-height: 100px;
+  .textClass{
+    line-height: 100px;
+    
+  }
+  .textClassLength10{
+  text-align: left !important;
+  }
+
+  
+}
+.cls0 {
+  background-color: #e6e6e6;
+  border: 1px solid #fff;
+}
+.cls1 {
+  background-color: #fff;
+  border: 1px solid #3cbda9;
+  color: #3cbda9;
+}
+.cls2 {
+  background-color: #fff;
+  // background-color: #ff6b00;
+  border: 1px solid #3cbda9;
+  color: #3cbda9;
+}
+.pors {
+  position: absolute;
+  border-radius: 50%;
+  width: 36px;
+  text-align: center;
+  height: 36px;
+  top: -20px;
+  right: -12px;
+  // transform: translate();
+}
+.success {
+  background-color: #3cbda9;
+}
+.error {
+  background-color: #3cbda9;
+}
+// 'cls0', 'cls1', 'cls2']
+</style>

+ 361 - 0
src/views/menu/monitoringCall/components/areaTaskInfo.vue

@@ -0,0 +1,361 @@
+<template>
+  <div>
+    <van-overlay :show="show" :lock-scroll="false">
+      <div class="wrapper">
+        <div class="block">
+          <!-- 标题信息 -->
+          <van-row>
+            <van-col span="24">
+              <div class="textTitle">调阅记录</div>
+            </van-col>
+            <van-col span="24">
+              <div class="text">{{ areaName }}</div>
+            </van-col>
+          </van-row>
+          <!-- //主体内容 -->
+          <div class="mainBox">
+            <van-row class="titleList">
+              <van-col class="itemCol" span="8"> 项目</van-col>
+              <van-col class="itemCol" span="8"> 正常</van-col>
+              <van-col class="itemCol" span="8"> 异常</van-col>
+            </van-row>
+            <div class="mainItem">
+              <van-row class="rowItem" v-for="item in dataList" :key="item.id">
+                <van-col class="itemCls" span="10" style="display: flex"
+                ><van-checkbox
+                  v-model="item.isChecked"
+                  @change="checkedFc($event, item)"
+                  :disabled="disabled"
+                  icon-size="16px"
+                  shape="square"
+                >
+                </van-checkbox>
+                  <span class="info"
+                  >{{ item.dictLabel }}<van-icon class="info-o" name="info-o" @click="textTitleHandler(item.remark)"
+                  /></span>
+                </van-col>
+                <van-radio-group v-model="item.situation" @change="checkHandler($event, item)">
+                  <van-col class="itemCls radioItem" span="7" v-for="itemDict in dictList" :key="itemDict.dictValue">
+                    <van-radio icon-size="16px" :name="itemDict.dictValue">{{ itemDict.dictLabel }}</van-radio></van-col
+                  >
+                </van-radio-group>
+
+                <van-col span="24" v-if="item.situation == '1'">
+                  <van-field
+                    v-model="item.abnormalIllustrate"
+                    rows="2"
+                    required
+                    autosize
+                    label=""
+                    type="textarea"
+                    maxlength="200"
+                    placeholder="请输入异常描述"
+                    show-word-limit
+                    :rules="[{ required: true, message: '异常描述不能为空' }]"
+                  /></van-col>
+              </van-row>
+            </div>
+            <!-- 文字描述弹框 -->
+            <van-dialog v-model="showDialog" title="提示">
+              <div class="showtext" >
+                {{ showText }}
+                <!--<div v-for="item in showText" :key="item">{{ item }}</div>-->
+              </div>
+            </van-dialog>
+            <!-- 底部按钮 -->
+            <div>
+              <van-row>
+                <van-col span="12">
+                  <van-button class="btn" size="small" @click="show = false" type="default">取消</van-button></van-col
+                >
+                <van-col span="12">
+                  <van-button class="btn" size="small" type="info" v-if="!disabled" @click="submitHadnler">{{
+                    '确定'
+                    }}</van-button></van-col
+                >
+              </van-row>
+            </div>
+          </div>
+        </div>
+      </div>
+    </van-overlay>
+  </div>
+</template>
+<script>
+  import { updateInfo, getEditInfo } from '@/api/toConsult.js'
+  import { Toast, Dialog } from 'vant'
+
+  export default {
+    name: 'SocAppTaskInfo',
+
+    data() {
+      return {
+        showText:'',
+        showDialog: false,
+        taskId: '', //任务ID
+        show: false,
+        // host: '',
+        // hostId: '',
+        // videoChannelName: '',
+        // videoChannel: '',
+        areaCode:'',
+        areaName:'',
+        taskRegistrationId: '',
+        id: '',
+        falg: false,
+        checked: '',
+        message: '',
+        radio: '0',
+        dictList: [],
+        dataList: [] //列表
+      }
+    },
+    created() {
+      this.disabled = +this.$route.params.id.split('_')[3] ? true : false
+    },
+
+    mounted() {
+      // let list = document.querySelector('.mainItem')
+      // list.addEventListener('touchmove', e => e.stopPropagation(), false)
+    },
+
+    methods: {
+      //组件初始化
+      init(taskId, areaValue,areaName) {
+        // Toast(`当前为调阅项目选择界面,仅需部分登记发现调阅项目填写正常或者异常项,无需全部填写。`,{duration:5000});
+        Dialog.alert({
+            message: '当前为调阅项目选择界面,请根据实际调阅情况选择,无需全部填写。',
+          }).then(() => {
+          });
+        
+        
+        this.taskId = taskId
+        this.show = true
+        //获取调阅字典
+        this.getDictHandler('core_registration_project', res => {
+          this.dataList = JSON.parse(JSON.stringify(res))
+          this.dataList.forEach(item => {
+            this.$set(item, 'situation', '') //异常情况初始化默认值
+            this.$set(item, 'isChecked', false) //选中初始值
+            this.$set(item, 'abnormalIllustrate', '') //情况说明初始化默认值
+          })
+          //获取异常情况字典
+          this.getDictHandler('core_check_type', res => {
+            this.dictList = res
+            this.dictList.forEach(item => {
+              item.text = item.dictLabel
+              item.value = item.dictValue
+            })
+          })
+          this.getInfoHandler(taskId, areaValue,areaName) //获取详情
+        })
+      },
+      //复选框选中变化
+      checkHandler(val, item) {
+        if (val) {
+          item.isChecked = true
+        }
+        if (val && item.situation == '0') {
+          item.abnormalIllustrate = ''
+        }
+      },
+      checkedFc(val, item) {
+        if (val) {
+          if (!item.situation) {
+            item.situation = '0'
+          }
+        } else {
+          item.situation = ''
+          item.abnormalIllustrate = ''
+        }
+      },
+      getInfoHandler(id, areaValue,areaName) {
+        //获取卡片详情数据
+        getEditInfo({ taskId: id + '', areaValue: areaValue + '',areaName:areaName}).then(res => {
+          let { data, msg, code } = res
+          if (code == 200) {
+            this.dataList.forEach(item => {
+              data.coreMonitoringTaskMonitorInfoList.forEach(i => {
+                if (i.project === item.dictValue) {
+                  //查询赋值
+                  this.$set(item, 'isChecked', true)
+                  this.$set(item, 'situation', i.situation)
+                  this.$set(item, 'abnormalIllustrate', i.abnormalIllustrate)
+                }
+              })
+            })
+            console.log(this.dataList)
+            //赋值主机&通道名称
+            // this.host = data.hostName
+            // this.hostId = data.host
+            // this.videoChannelName = data.videoChannelName
+            // this.videoChannel = data.videoChannel
+            this.areaCode=data.areaCode;
+            this.areaName=data.areaName;
+            this.taskRegistrationId = data.registrationId
+            this.id = data.id
+          }
+        })
+      },
+
+      //表单提交前校验
+      beforSubmitV() {
+        this.falg = false
+
+        this.dataList.forEach(item => {
+          if (item.isChecked) {
+            console.log(item)
+            if (item.situation == '1' && item.abnormalIllustrate == '') {
+              Toast(`${item.dictLabel}的情况描述不能为空!`)
+
+              this.falg = true
+            }
+          }
+        })
+      },
+      submitHadnler() {
+        this.beforSubmitV()
+        if (this.falg) {
+          //校验不通过
+        } else {
+          let list = []
+
+          this.dataList.forEach(item => {
+            if (item.isChecked) {
+              item.project = item.dictValue
+              list.push(item)
+            }
+          })
+          if(list.length==0){
+            return Toast(`单通道调阅项至少勾选一项!`)
+          }
+          //编辑提交
+          updateInfo({
+            // host: this.hostId,
+            // videoChannel: this.videoChannel,
+            areaCode:this.areaCode,  
+            areaName:this.areaName,          
+            taskRegistrationId: this.taskRegistrationId,
+            id: this.id || '',
+            coreMonitoringTaskMonitorInfoList: list
+          }).then(res => {
+            let { data, msg, code } = res
+            if (code == 200) {
+              Toast('编辑成功!')
+              this.show = false
+              this.$emit('resetList')
+            }
+            this.falg = false
+          })
+        }
+      },
+      //文字提示
+      textTitleHandler(text) {
+        if(!text){
+          text='可参照相关部门管理办法!'
+        }
+        // text='1.挖掘第哦啊uiOS多i,2.是多久啊了多久哦'
+        this.showDialog = true
+        // this.showText = text.split(',')
+        this.showText = text;
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .mainItem {
+    height: 95%;
+    overflow: scroll;
+  }
+  .rowItem {
+    min-height: 100px;
+    line-height: 100px;
+    border: 1px solid #e8e8e8;
+    border-bottom:none;
+
+  }
+  .block {
+    width: 90vw;
+    height: 98%;
+    background-color: #fff;
+    margin: auto;
+    position: absolute;
+    top: 1%;
+    bottom: 1%;
+    left: 5%;
+    right: 5%;
+    padding: 20px;
+  }
+  .textTitle {
+    font-size: 30px;
+    font-weight: bold;
+    padding: 10px;
+    color: black;
+    text-align: center;
+
+  }
+
+  .text {
+    text-align: center;
+
+    color: black;
+  }
+  .mainBox {
+    height: 80vh;
+    .titleList {
+      background-color: #e8e8e8;
+      margin-top: 20px;
+      font-size: 22px;
+      text-align: left;
+      font-weight: bold;
+      .itemCol {
+        padding: 10px;
+        color: black;
+
+        font-size: 4vw;
+        text-align: center;
+      }
+    }
+  }
+  .itemCls {
+    padding-left: 10px;
+    border-right: 1px solid #e8e8e8;
+    height: 100%;
+    .van-radio{
+
+
+    }
+
+  }
+  .radioItem{
+    height: 100px;
+    line-height: 100px;
+    align-items: center;
+    display: flex;
+  }
+  .btn {
+    width: 90%;
+  }
+  .info {
+    color: #1989fa;
+    margin-left: 10px;
+    // text-decoration: underline;
+    .info-o{
+      margin-left: 10px;
+    }
+  }
+  .showtext{
+    text-align: left;
+    color: #0e0e0e;
+    padding-left: 20px;
+    padding-right: 15px;
+    margin-top: 50px;
+    margin-bottom: 50px;
+    max-height: 135vw;
+    overflow: auto;
+    white-space: pre-wrap;
+  }
+  .van-overlay{
+    z-index: 200;
+  }
+</style>

+ 125 - 35
src/views/menu/monitoringCall/components/consultInfo.vue

@@ -16,12 +16,12 @@
           <!-- 调阅列表 -->
           <div class="topBox" v-for="item in taskData.coreMonitoringTaskRegistrationMonitorVOList" :key="item.id">
             <!-- //主机列表组件 -->
-            <MonitoingList :list="item" :taskStatus="taskData.taskStatus"></MonitoingList>
+            <areaMonitoringList :list="item" :taskStatus="taskData.taskStatus"></areaMonitoringList>
           </div>
         </div>
 
         <div v-else>
-          <van-collapse-item :name="item.hostId" v-for="item in hostList" :key="item.hostId">
+          <!-- <van-collapse-item :name="item.hostId" v-for="item in hostList" :key="item.hostId">
             <template #title>
               <div class="textTitle">{{ item.hostName }}</div>
             </template>
@@ -32,7 +32,18 @@
               :hostId="item.hostId"
               @resetList="getHostHandlerA"
             ></passage>
-          </van-collapse-item>
+          </van-collapse-item> -->
+          <van-collapse-item>
+            <template #title>
+              <div class="textTitle">区域列表</div>
+            </template>
+          <areaPassage
+              ref="passage"
+              :list="retrievalAreaList"
+              :taskId="$route.params.id.split('_')[0]"            
+              @resetList="getHostHandlerA"
+            ></areaPassage>   
+          </van-collapse-item>       
         </div>
       </van-collapse>
 
@@ -43,13 +54,16 @@
             <van-button type="info" @click="addInfoHandler">添加调阅记录</van-button>
           </van-col>
         </van-row> -->
-        <van-row v-if="hostList && hostList.length > 0">
+        <van-row v-if="retrievalAreaList && retrievalAreaList.length > 0">
           <van-col span="24">
             <van-button type="info" @click="endMontor">结束调阅</van-button>
           </van-col>
         </van-row>
       </div>
     </div>
+    <van-action-sheet v-model="showSign" :title="shwoSignTitle" class="sheet">
+            <writingPad ref="esign" @resultImg="resultSginImg"></writingPad>
+    </van-action-sheet>
     <!-- 扫描弹框 -->
     <scandialog ref="scandialog" @input="resultImg" @changeNFC="getNFC"></scandialog>
   </div>
@@ -58,12 +72,17 @@
 import NavBar from '@/components/NavBar'
 //通道列表
 import passage from './passage.vue'
+import areaPassage from './areaPassage.vue'
 // 主机列表组件
 import MonitoingList from './monitoringList.vue'
+import areaMonitoringList from './areaMonitoringList.vue'
+
 import { upload } from '@/api/public'
 import { Col, Row, Dialog, Toast, Icon, Picker } from 'vant'
-import { registrationList, getEndInfo, login, getSysDeviceByTaskId, registration } from '@/api/toConsult.js'
+import { registrationList, finishRegistration, login, getSysDeviceByTaskId, registration } from '@/api/toConsult.js'
 import scandialog from '@/components/nfcPopup/alone.vue'
+import writingPad from '@/components/writingPad/index.vue'
+import imgCom from '@/components/imgCom/index.vue'
 import { base64ToBlob } from '@/utils/base64TurnImg.js'
 export default {
   data() {
@@ -71,20 +90,27 @@ export default {
       endNum: false, //判断是否能结束调阅
       taskData: {},
       hostList: [], //主机列表
-      activeNames: []
+      retrievalAreaList:[], // 监控调阅区域名称
+      activeNames: [],
+      showSign:false,
+      shwoSignTitle:"签署名字",
+      signImgUrl:"",
     }
   },
   components: {
     scandialog,
-
-    passage,
+    areaPassage,
+    // passage,
     NavBar,
     Dialog,
     Icon,
     Picker,
     Col,
     Row,
-    MonitoingList
+    // MonitoingList,
+    areaMonitoringList,
+    writingPad,
+    imgCom,
   },
 
   created() {
@@ -102,7 +128,7 @@ export default {
             }
           if(num === 1 && data.taskStatus !=2){
             Dialog.alert({
-            message: '当前为调阅通道选择界面,仅需选择实际调阅通道,无需全选。',
+            message: '当前为监控调阅区域选择界面,请根据实际调阅情况选择,无需全部填写。',
             }).then(() => {
 
             });
@@ -116,17 +142,56 @@ export default {
     getHostHandler(num = 0) {
       // num//判断是不是第一次初始化
       console.log(num);
-      getSysDeviceByTaskId({ taskId: this.$route.params.id.split('_')[0] }).then(res => {
-        let { code, data, msg } = res
-        if (code == 200) {
-          this.hostList = data
-          if (num == 1) {
-            this.activeNames = [this.hostList[0].hostId]
-          } else {
-            console.log(this.activeNames, '////')
-          }
-        }
-      })
+      // getSysDeviceByTaskId({ taskId: this.$route.params.id.split('_')[0] }).then(res => {
+      //   let { code, data, msg } = res
+      //   if (code == 200) {
+      //     this.hostList = data
+      //     if (num == 1) {
+      //       this.activeNames = [this.hostList[0].hostId]
+      //     } else {
+      //       console.log(this.activeNames, '////')
+      //     }
+      //   }
+      // })
+
+       //获取调阅字典
+       this.getDictHandler('video_retrieval_area', res => {
+           let areaList = JSON.parse(JSON.stringify(res));
+
+           if(this.taskData.coreMonitoringTaskRegistrationMonitorVOList){
+            areaList.forEach(area=>{
+             let tempList= this.taskData.coreMonitoringTaskRegistrationMonitorVOList.filter(item=>item.areaCode == area.dictValue);
+             if(tempList && tempList.length>0)
+             {
+                console.log("tempList",tempList);
+                console.log("tempList",tempList[0].coreMonitoringTaskMonitorInfoList.findIndex(x=>{
+                 return x.situation=="1"})>-1);
+                if(tempList[0].coreMonitoringTaskMonitorInfoList && tempList[0].coreMonitoringTaskMonitorInfoList.findIndex(x=>{
+                 return x.situation=="1";
+                })>-1)
+                {
+                  this.$set(area, 'type', 2)
+                }
+                else{
+                  this.$set(area, 'type', 1)
+                }              
+             }
+             else{
+              this.$set(area, 'type', 0)
+             }
+
+            });
+           }
+
+           console.log("areaList",areaList);
+           this.retrievalAreaList=areaList;
+          // this.dataList.forEach(item => {
+          //   this.$set(item, 'situation', '') //异常情况初始化默认值
+          //   this.$set(item, 'isChecked', false) //选中初始值
+          //   this.$set(item, 'abnormalIllustrate', '') //情况说明初始化默认值
+          // })
+        })
+
     },
     addInfoHandler() {
       this.$router.push('/addInfo/' + this.$route.params.id.split('_')[0] + '_' + this.taskData.id + '_add')
@@ -146,17 +211,20 @@ export default {
         let endDate = Date.parse(new Date())
 
         if (endDate - startDate) {
-          Dialog.confirm({
-            title: '提示',
-            message: `当前调阅时长为${this.dateTime(endDate - startDate)},是否结束调阅?`
-          })
-            .then(() => {
-              this.$refs.scandialog.visible = true
-        this.globalLoading = true
-            })
-            .catch(() => {
-              // on cancel
-            })
+          this.shwoSignTitle= `调阅时长为${this.dateTime(endDate - startDate)},是否结束调阅?`;
+          this.showSign=true;
+         
+
+          // Dialog.confirm({
+          //   title: '提示',
+          //   message: `当前调阅时长为${this.dateTime(endDate - startDate)},是否结束调阅?`
+          // }).then(() => {
+          //     this.$refs.scandialog.visible = true
+          //     this.globalLoading = true
+          //   })
+          //   .catch(() => {
+          //     // on cancel
+          //   })
         }
 
       } else {
@@ -196,6 +264,27 @@ export default {
       }
       return time
     },
+     //上传签名图到服务器
+    resultSginImg(img) {
+      let obj = base64ToBlob(img)
+      let formData = new FormData()
+
+      obj.name = '签名.jpg'
+      formData.append('file', base64ToBlob(img))
+
+      upload(formData, 'image')
+        .then(res => {
+          console.log(process.env.NODE_ENV)
+          /*上传成功*/
+          this.signImgUrl = process.env.NODE_ENV === 'development' ? res.data.url : res.data.url
+          this.showSign=false;
+          this.$refs.scandialog.visible = true
+          this.globalLoading = true
+        })
+        .catch(err => {
+          /*上传失败*/
+        })
+    },
     //文件上传
     resultImg(img) {
       this.photoHandler(img[0].url)
@@ -210,7 +299,7 @@ export default {
       //开始调阅上传
       let obj = {
         endPicture: img,
-        endNfc: nfc,
+        endNfc: nfc,        
         taskId: this.$route.params.id.split('_')[0]
       }
       registration(obj).then(res => {
@@ -222,8 +311,9 @@ export default {
       })
     },
     endHandler() {
-      getEndInfo({
-        id: this.taskData.id,
+      finishRegistration({
+        id: this.taskData.id,        
+        signImgUrl:this.signImgUrl,
         taskId: this.$route.params.id.split('_')[0]
       }).then(res => {
         this.$router.go(-1)

+ 1 - 1
src/views/menu/monitoringCall/components/taskInfo.vue

@@ -122,7 +122,7 @@
       init(taskId, videoId, hostId) {
         // Toast(`当前为调阅项目选择界面,仅需部分登记发现调阅项目填写正常或者异常项,无需全部填写。`,{duration:5000});
         Dialog.alert({
-            message: '当前为调阅项目选择界面,仅需部分登记发现调阅项目填写正常或者异常项,无需全部填写。',
+            message: '当前为调阅项目选择界面,请根据实际调阅情况选择,无需全部填写。',
           }).then(() => {
           });
         

+ 186 - 117
src/views/menu/securityCheckRegister/add.vue

@@ -16,9 +16,10 @@
               </span>
             </template>
           </van-cell>
-          <van-cell class="cell-item28" title="日期时间" :value="formatTime(taskInfo.planStartTime,taskInfo.planEndTime)" />
-          <van-cell class="cell-item28" title="受检机构" :value="taskInfo.beCheckedOrgName" />
-          <van-cell class="cell-item28" v-if="!enable" title="检查组成员" :value="taskInfo.checkTeam || '无'" />
+          <van-cell class="cell-item28" title="日期时间"
+                    :value="formatTime(taskInfo.planStartTime,taskInfo.planEndTime)"/>
+          <van-cell class="cell-item28" title="受检机构" :value="taskInfo.beCheckedOrgName"/>
+          <van-cell class="cell-item28" v-if="!enable" title="检查组成员" :value="taskInfo.checkTeam || '无'"/>
           <van-field
             v-else
             v-model="taskInfo.checkTeam"
@@ -36,17 +37,20 @@
         <div class="card">
           <p class="legend">检查项<span v-if="enable" @click="addCheck">添加检查内容</span></p>
           <!--  搜索框  -->
-          <van-search v-model="itemName" class="van-hairline--top" placeholder="请输入检查内容" />
+          <van-search v-model="itemName" class="van-hairline--top" placeholder="请输入检查内容"/>
           <van-collapse v-model="activeNames" v-for="(v,i) in resultList" :key="v.itemId">
             <van-collapse-item :title="`${i+1}.${v.itemName}`" :name="v.itemName">
-              <div v-for="(item, index) in v.pointList" :key="item.pointId" class="collapse-box" :class="{'van-hairline--bottom':item.status}">
+              <div v-for="(item, index) in v.pointList" :key="item.pointId" class="collapse-box"
+                   :class="{'van-hairline--bottom':item.status}">
                 <van-cell :border="true">
                   <template #title>
-                    <pre> <span>{{`${i+1}-${index+1}`}}.</span> {{ item.pointName }}</pre>
+                    <pre> <span>{{ `${i + 1}-${index + 1}` }}.</span> {{ item.pointName }}</pre>
                   </template>
                   <template #right-icon>
                     <span v-if="item.nfcList && item.nfcList.length" @click="clickNFCNum(item.nfcList)">
-                        <span style="color:#009240;">{{ getNfcState(item.nfcList) }}</span>/<span >{{item.nfcList.length}}</span>
+                        <span style="color:#009240;">{{
+                            getNfcState(item.nfcList)
+                          }}</span>/<span>{{ item.nfcList.length }}</span>
                     </span>
                     <img
                       v-if="enable && item.nfcList && item.nfcList.length"
@@ -79,7 +83,7 @@
                       :key="img.img"
                       @click="preViewNFC(i)"
                     >
-                      <img :src="imgUrl(img.img)" alt="" />
+                      <img :src="imgUrl(img.img)" alt=""/>
                       <span>{{ img.checkName }}</span>
                     </div>
                   </van-cell>
@@ -103,14 +107,14 @@
                     :data-list="dateList"
                   />
                   <div class="upload-box">
-                    <uploader v-if="enable" :maxCount="5" v-model="item.imgData" />
+                    <uploader v-if="enable" :maxCount="5" v-model="item.imgData"/>
                     <van-cell v-else-if="item.imgData">
                       <div
                         class="nfc-img"
                         v-for="(v, i) in item.imgData"
                         :key="v.imgPath"
                         @click="clickWarnImage(item.imgData, i)">
-                        <img :src="imgUrl(v.imgPath)" alt="" />
+                        <img :src="imgUrl(v.imgPath)" alt=""/>
                       </div>
                       <!--                      <img class="nfc-img" v-for="v in item.imgData" :src="imgUrl(v.imgPath)" alt="" :key="v.id">-->
                     </van-cell>
@@ -123,11 +127,14 @@
       </fieldset>
 
     </div>
+    <van-action-sheet v-model="showSign" title="签署名字" class="sheet">
+      <writingPad ref="esign" @resultImg="resultImg"></writingPad>
+    </van-action-sheet>
     <!--  按钮   -->
     <div v-if="enable" class="bottom-box">
       <div class="flex-box">
         <van-button type="default" plain @click="accredit" v-if="showGrantBtn">授权</van-button>
-        <van-button type="info" :disabled="Boolean(!isSubmit)"  plain hairline @click="saveData">保存</van-button>
+        <van-button type="info" :disabled="Boolean(!isSubmit)" plain hairline @click="saveData">保存</van-button>
         <van-button type="info" :disabled="Boolean(!isSubmit)" @click="submitData">提交</van-button>
       </div>
       <p v-show="Boolean(!isSubmit)">注:不在任务登记时间内,禁止操作</p>
@@ -144,18 +151,18 @@
             <div v-if="unmetList.length > 0" class="nfc-list">
               <van-cell v-for="item in unmetList" :title="item.nfcName" :key="item.nfcCode">
                 <!-- <img :src="require('../../../assets/svg/NFC.svg')" class="nfc-icon"/>-->
-<!--                <span >{{item.pointScan == 1?'必扫':'可选'}}</span>-->
+                <!--                <span >{{item.pointScan == 1?'必扫':'可选'}}</span>-->
               </van-cell>
             </div>
-            <van-empty v-else description="" />
+            <van-empty v-else description=""/>
           </van-tab>
           <van-tab title="已扫描" name="a">
             <div v-if="fullList.length > 0" class="nfc-list">
               <van-cell v-for="item in fullList" :title="item.nfcName" :key="item.nfcCode">
-                <span style="color: green"> {{item.scanMethod == 0?'NFC扫描':'拍照上传'}}</span>
+                <span style="color: green"> {{ item.scanMethod == 0 ? 'NFC扫描' : '拍照上传' }}</span>
               </van-cell>
             </div>
-            <van-empty v-else description="" />
+            <van-empty v-else description=""/>
           </van-tab>
         </van-tabs>
       </div>
@@ -174,14 +181,18 @@ import DateCell from '@/components/dateCell'
 import Uploader from '@/components/upload/gxuploader'
 import NfcPopup from '@/components/nfcPopup/more'
 import AddCheck from './addCheck'
-import { registerDetail, registerSubmit } from './api'
-import { imgUrl} from '@/utils'
+import {registerDetail, registerSubmit} from './api'
+import {imgUrl} from '@/utils'
 import {Dialog, ImagePreview} from 'vant'
-import { mapGetters } from 'vuex'
+import {mapGetters} from 'vuex'
 import dayjs from 'dayjs'
+import writingPad from '@/components/writingPad/index.vue'
+import {base64ToBlob} from "@/utils/base64TurnImg";
+import {upload} from "api/public";
+
 export default {
   name: 'securityDetail',
-  components: { NavBar, SelectCell, DateCell, Uploader, NfcPopup, AddCheck },
+  components: {NavBar, SelectCell, DateCell, Uploader, NfcPopup, AddCheck, writingPad},
   data() {
     return {
       id: null,
@@ -202,12 +213,13 @@ export default {
       checkNum: 0,
       //nfc图片
       nfcImage: [],
+      showSign: false,
       //是否能提交
-      isSubmit:false, //未到提交时间不能提交
+      isSubmit: false, //未到提交时间不能提交
       enable: false,
       stateList: [],
       dayList: [],
-      itemName:null,
+      itemName: null,
       preViewImages: {
         images: [],
         startPosition: 0
@@ -216,33 +228,33 @@ export default {
       showPreView: false,
       selected: null,
       active: true,
-      dateList:[],
+      dateList: [],
       /* 以下为NFC弹窗详情数据*/
-      total_show:false,
-      fullList:[],
-      unmetList:[],
+      total_show: false,
+      fullList: [],
+      unmetList: [],
       go: {
         type: 'replace',
         path: '/securityCheckRegister'
       },
-      event:null,
+      event: null,
     }
   },
   computed: {
-    ...mapGetters(['dictionary',"roleList",'orgId']),
-    showGrantBtn(){
+    ...mapGetters(['dictionary', "roleList", 'orgId']),
+    showGrantBtn() {
       let userRoleIds = this.roleList.map((r) => r.roleId);
       let taskRoleIds = this.taskInfo.checkRoles
         ? this.taskInfo.checkRoles.map((r) => r.id)
         : [];
       return (
         this.taskInfo.status != 3 &&
-        this.taskInfo.planType==3 &&
+        this.taskInfo.planType == 3 &&
         this.taskInfo.checkOrgId == this.orgId &&
         userRoleIds.find((ur) => taskRoleIds.includes(ur))
       );
     },
-    resultList(){
+    resultList() {
       if (!this.itemName) {
         return this.checkList;
       }
@@ -268,34 +280,34 @@ export default {
     clearInterval(this.timer);
   },
   methods: {
-    barGoBack(){
+    barGoBack() {
       this.getRouter();
-      if(this.fromPages.name === "works"){
+      if (this.fromPages.name === "works") {
         this.$router.go(-1);
-      }else {
+      } else {
         this.$router.replace({
-          name:'securityCheckRegister',
-          path:'/securityCheckRegister',
-          params:{event:this.event}
+          name: 'securityCheckRegister',
+          path: '/securityCheckRegister',
+          params: {event: this.event}
         });
       }
     },
     //点击NFC数字图标
     clickNFCNum(arr) {
-      arr.forEach(v=>{
-        if(v.status){
+      arr.forEach(v => {
+        if (v.status) {
           this.fullList.push(v);
-        }else {
+        } else {
           this.unmetList.push(v)
         }
       })
-      this.total_show =true;
+      this.total_show = true;
     },
-    closedNfcList(){
+    closedNfcList() {
       this.fullList = [];
       this.unmetList = [];
     },
-    onClose(){
+    onClose() {
       window.openCameraCallBack = null;
       window.openNFCScanCallBack = null;
       this.$toast.clear();
@@ -304,21 +316,23 @@ export default {
     //长度校验
     validator(val) {
       let len = val.length;
-      if( len > 5) {
+      if (len > 5) {
         this.$toast.fail('问题情况输入长度不能超过200');
         return true
-      }else {
+      } else {
         return false
       }
     },
     //获取NFC已扫描数据
-    getNfcState(arr){
-        arr = arr || [];
-        let nums = arr.filter(v=>{return v.status === 1});
-        return nums.length;
+    getNfcState(arr) {
+      arr = arr || [];
+      let nums = arr.filter(v => {
+        return v.status === 1
+      });
+      return nums.length;
     },
     //调用nfc
-    checkNFC(){
+    checkNFC() {
       //设置nfc调用后的回调
       window.openNFCScanCallBack = this.openNFCScanCallBack;
       //设置loading弹窗
@@ -332,7 +346,7 @@ export default {
       let second = 30;
       this.timer = setInterval(() => {
         second--;
-        if(!second){
+        if (!second) {
           this.$toast.clear();
           clearInterval(this.timer);
           this.$toast.fail({
@@ -345,14 +359,14 @@ export default {
       this.useNFC();
     },
     //调用nfc后的回调
-    openNFCScanCallBack(nfcStr){
+    openNFCScanCallBack(nfcStr) {
       //alert(JSON.stringify(nfcStr))
       clearInterval(this.timer);
       let nfcCode = '';
-      try{
+      try {
         let nfc = JSON.parse(nfcStr);
-        nfcCode =  nfc.content;
-      }catch (e) {
+        nfcCode = nfc.content;
+      } catch (e) {
         nfcCode = nfcStr.content;
       }
       // let nfc = JSON.parse(nfcStr);
@@ -361,13 +375,13 @@ export default {
       this.checkNfcFilter(nfcCode);
     },
     //验证nfc数据
-    checkNfcFilter(nfcCode){
+    checkNfcFilter(nfcCode) {
       //let areaId = null;
-      let checkOk =  false;
+      let checkOk = false;
       //alert(JSON.stringify(this.NFCList,'NFCList'));
       this.NFCList.forEach(v => {
-        if(v.nfcCode === nfcCode){
-          if(v.status === 1){
+        if (v.nfcCode === nfcCode) {
+          if (v.status === 1) {
             this.$toast.fail('NFC:' + v.nfcName + '已扫描,请勿重复扫描!');
           }
           v.status = 1;
@@ -377,17 +391,17 @@ export default {
           checkOk = true;
         }
       });
-      if(!checkOk){
-        this.$toast.fail( "扫描结果不在本次检查范围内!");
-      }else{
+      if (!checkOk) {
+        this.$toast.fail("扫描结果不在本次检查范围内!");
+      } else {
         this.saveData();
       }
     },
 
     //是否显示nfc图标
-    nfcState(item){
-      if(item.nfcList && item.nfcList.length > 0){
-        return item.nfcList.some(v=>{
+    nfcState(item) {
+      if (item.nfcList && item.nfcList.length > 0) {
+        return item.nfcList.some(v => {
           return v.status === 0
         })
       }
@@ -395,8 +409,8 @@ export default {
     },
 
     //格式化时间范围
-    formatTime(start,end,format){
-      format = format ||  'YYYY年MM月DD日'
+    formatTime(start, end, format) {
+      format = format || 'YYYY年MM月DD日'
       return `${this.dayjs(start).format(format)} ~ ${this.dayjs(end).format(format)}`;
     },
     //插入检查项
@@ -420,7 +434,7 @@ export default {
           }
         } else {
           this.checkList.push({
-            isAdd:1,
+            isAdd: 1,
             itemId: valItem.itemId,
             itemName: valItem.itemName,
             pointList: [valItem]
@@ -433,7 +447,7 @@ export default {
       this.active = true
     },
     getState(state) {
-      switch (state){
+      switch (state) {
         case '待检查':
           return '#008cd6';
         case '进行中':
@@ -473,9 +487,9 @@ export default {
         this.activeNames = this.checkList.map(v => v.itemName);
         //判断是否可提交(在任务时间内)
         this.isSubmit = res.data.inRegisterTime;
-        this.checkList.forEach(v=>{
-          v.pointList.forEach(item=>{
-            if(item.status == null ){
+        this.checkList.forEach(v => {
+          v.pointList.forEach(item => {
+            if (item.status == null) {
               item.status = 0
             }
           })
@@ -502,8 +516,8 @@ export default {
         this.$toast('保存成功');
         this.event = 'refresh';
         //this.toPagesFcn();
-      }).catch(error=>{
-        if( error === '任务已完成'){
+      }).catch(error => {
+        if (error === '任务已完成') {
           this.toPagesFcn();
         }
       })
@@ -519,14 +533,14 @@ export default {
           //验证必填项
           let pointData = this.checkList.flatMap(v => v.pointList);
           let allNfcList = [];
-          pointData.forEach(v=>{
-            if(v.nfcList && v.nfcList.length > 0){
+          pointData.forEach(v => {
+            if (v.nfcList && v.nfcList.length > 0) {
               allNfcList.push(...v.nfcList)
             }
           })
-          if(allNfcList.length > 0){
-            let result = allNfcList.some(v=>v.status != 1);
-            if(result){
+          if (allNfcList.length > 0) {
+            let result = allNfcList.some(v => v.status != 1);
+            if (result) {
               this.$toast('请先扫描NFC标签');
               return;
             }
@@ -538,15 +552,8 @@ export default {
           })
           if (arr.length) return this.$toast(`${arr[0].itemName}:该信息不完整请填写`);
           this.taskInfo.isSubmit = 1;
-          console.log(this.taskInfo,'taskInfo');
-          registerSubmit(this.taskInfo).then(res => {
-            this.$toast('提交成功');
-            this.toPagesFcn();
-          }).catch(error=>{
-            if( error === '任务已完成'){
-              this.toPagesFcn();
-            }
-          });
+          console.log(this.taskInfo, 'taskInfo');
+          this.signatureHandler()
         })
         .catch(() => {
           // on cancel
@@ -554,21 +561,21 @@ export default {
 
     },
     //页面跳转逻辑
-    toPagesFcn(){
+    toPagesFcn() {
       this.getRouter();
-      if(this.fromPages.name === "works"){
+      if (this.fromPages.name === "works") {
         this.$router.go(-1)
-      }else {
+      } else {
         this.$router.replace({
-          name:'securityCheckRegister',
-          path:'/securityCheckRegister',
-          params:{event:'refresh'}
+          name: 'securityCheckRegister',
+          path: '/securityCheckRegister',
+          params: {event: 'refresh'}
         });
       }
     },
     //授权
     accredit() {
-      let { checkOrgId, ymdDate, planId, beCheckedOrgId, id } = this.taskInfo
+      let {checkOrgId, ymdDate, planId, beCheckedOrgId, id} = this.taskInfo
       this.$router.push({
         path: '/addWorker',
         query: {
@@ -617,19 +624,52 @@ export default {
       })
       this.saveData();
     },
+    signatureHandler() {
+      this.showSign = true
+    },
+    //上传签名图到服务器
+    resultImg(img) {
+      let obj = base64ToBlob(img)
+      let formData = new FormData()
+
+      obj.name = '签名.jpg'
+      formData.append('file', base64ToBlob(img))
+
+      upload(formData, 'image')
+        .then(res => {
+          console.log(process.env.NODE_ENV)
+          /*上传成功*/
+          this.taskInfo.signImg = process.env.NODE_ENV === 'development' ? res.data.url : res.data.url
+          // this.submitSign(imgUrl)
+          registerSubmit(this.taskInfo).then(res => {
+            this.$toast('提交成功');
+            this.toPagesFcn();
+          }).catch(error => {
+            if (error === '任务已完成') {
+              this.toPagesFcn();
+            }
+          });
+          // this.$emit("imgUrl", res.data.url);
+        })
+        .catch(err => {
+          /*上传失败*/
+        })
+    },
   }
 }
 </script>
 <style lang="scss">
-.register-edit{
-  .van-collapse-item__content{
-    padding:0 20px;
+.register-edit {
+  .van-collapse-item__content {
+    padding: 0 20px;
   }
 }
-.collapse-box{
-  .van-cell{
-    padding:20px 30px;
-    &:last-child{
+
+.collapse-box {
+  .van-cell {
+    padding: 20px 30px;
+
+    &:last-child {
       border-bottom: none;
     }
   }
@@ -639,38 +679,45 @@ export default {
 .register-edit {
   height: 100%;
   overflow: hidden;
+
   .page-container {
     height: calc(100vh - 262px);
     overflow: auto;
     padding: 20px;
-    -border:1px solid red;
+    -border: 1px solid red;
   }
-  .bottom-box{
+
+  .bottom-box {
     height: 170px;
-    padding:20px 20px 20px 20px;
-    >P{
+    padding: 20px 20px 20px 20px;
+
+    > P {
       padding-left: 10px;
       font-size: 22px;
       color: red;
       line-height: 36px;
     }
+
     .flex-box {
       width: 100%;
       display: flex;
       justify-content: space-between;
 
-      >button{
+      > button {
         &:first-child {
           margin-left: 0;
         }
+
         &:last-child {
           margin-right: 0;
         }
-        flex:1;
-        margin:0 10px;
+
+        flex: 1;
+        margin: 0 10px;
       }
     }
   }
+
   .legend {
     background-color: #fff;
     padding: 0 20px;
@@ -679,20 +726,25 @@ export default {
     font-size: 30px;
     display: flex;
     justify-content: space-between;
+
     > span {
       color: orange;
     }
   }
+
   .card {
     margin-bottom: 20px;
     box-shadow: 0 10px 10px #eaeaea;
+
     &:last-child {
       margin-bottom: 0;
     }
   }
-  .collapse-box{
+
+  .collapse-box {
     -padding-bottom: 10px;
   }
+
   .check-area {
     background-color: #f1f1f1;
     margin: 10px;
@@ -704,39 +756,47 @@ export default {
     align-items: center;
     box-shadow: 0 2px 6px #ddd;
   }
+
   .nfc-icon {
     width: 50px;
     height: 50px;
     margin: 0 20px;
   }
+
   .custom-title {
     align-self: center;
     vertical-align: middle;
   }
+
   .upload-box {
     padding: 30px;
   }
+
   .warning-msg {
     color: orange;
     text-align: center;
     height: 80px;
     line-height: 80px;
   }
+
   .active {
     color: #fff;
     background-color: #1989fa;
   }
+
   .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;
@@ -754,7 +814,8 @@ export default {
       height: 30px;
     }
   }
-  .nfc-list{
+
+  .nfc-list {
     min-height: 300px;
     max-height: 600px;
     overflow: auto;
@@ -769,25 +830,33 @@ export default {
     }
 
   }
+
   .select-cell {
-    ::v-deep  .van-cell__title{
+    ::v-deep .van-cell__title {
       min-width: 32%;
     }
-    ::v-deep  .van-cell__value {
-      min-width: 68%;	//可根据自己需求设定值
+
+    ::v-deep .van-cell__value {
+      min-width: 68%; //可根据自己需求设定值
       color: #0e0e0e;
       text-align: left;
     }
   }
-  .cell-item28{
-    ::v-deep  .van-cell__title{
+
+  .cell-item28 {
+    ::v-deep .van-cell__title {
       min-width: 22%;
     }
-    ::v-deep  .van-cell__value {
-      min-width: 78%;	//可根据自己需求设定值
+
+    ::v-deep .van-cell__value {
+      min-width: 78%; //可根据自己需求设定值
       color: #0e0e0e;
       text-align: left;
     }
   }
+
+  .sheet {
+    height: 45%;
+  }
 }
 </style>

+ 3 - 1
src/views/menu/visitCheck/api.js

@@ -12,11 +12,13 @@ export function dataList(params) {
 //获取详情
 export function visitDetails(id){
   return request({
-    url: "/core/letter/"+id,
+    url: "/core/letter/outinrequest/"+id,
     method: "get",
   });
 }
 
+
+
 // 审批
 export function visitCheck(data) {
   return request({

+ 60 - 9
src/views/menu/visitCheck/detail.vue

@@ -15,8 +15,8 @@
             </van-cell>
           </template>
           <div class="panel-box">
-            <van-cell title="来访类型" :value="getDictLabel(visitInfo.type,'out_in_type')"></van-cell>
-            <van-cell title="来访事由" :value="visitInfo.reasons"></van-cell>
+            <van-cell title="来访类型" :value="getDictLabel(visitInfo.letterType,'out_in_type')"></van-cell>
+            <van-cell title="来访事由" :value="visitInfo.letterReasons"></van-cell>
             <van-cell title="介绍信编号" v-if="visitInfo.letterNo"  :value="visitInfo.letterNo"></van-cell>
             <van-cell title="开具日期" v-if="visitInfo.startTimeStr"  :value="visitInfo.startTimeStr"></van-cell>
             <van-cell title="有效天数" v-if="visitInfo.effectiveDays"  :value="`${visitInfo.effectiveDays}天`"></van-cell>
@@ -29,7 +29,18 @@
                 </div>
               </template>
             </van-cell>
-            <van-cell v-if="visitInfo.description" title="备注信息" :value="visitInfo.description"></van-cell>
+            <van-cell v-if="visitInfo.letterDescription" title="备注信息" :value="visitInfo.letterDescription"></van-cell>
+            <!-- <div class="upload-box" v-if="visitInfo.approveSignImg">
+              <span>审批签名</span>
+              <van-cell >
+                <div
+                  class="nfc-img van-hairline--surround"
+                  :key="visitInfo.approveSignImg"
+                  @click="preView(visitInfo.approveSignImg)">
+                  <img :src="imgUrl(visitInfo.approveSignImg)" alt="" />
+                </div>
+              </van-cell>
+            </div> -->
           </div>
         </van-panel>
       </div>
@@ -61,7 +72,10 @@
       <div v-if="approveRemark" class="input-box">
         <van-cell title="审批说明" :value="approveRemark"></van-cell>
       </div>
-      <div v-if="approveStatus == 0 && visitInfo.status == 1" class="flex-box">
+      <van-action-sheet v-model="showSign" title="签署名字" class="sheet">
+            <writingPad ref="esign" @resultImg="resultImg"></writingPad>
+          </van-action-sheet>
+      <div v-if="approveStatus == 0" class="flex-box">
         <van-button type="info" style="width: 48%" plain @click="refuse">不同意</van-button>
         <van-button type="info" style="width: 48%" @click="accredit">同意</van-button>
       </div>
@@ -78,8 +92,15 @@ import {mapGetters} from "vuex";
 import {imgUrl} from "@/utils";
 import { ImagePreview } from 'vant'
 import {visitDetails,visitCheck} from './api'
+import writingPad from '@/components/writingPad/index.vue'
+import imgCom from '@/components/imgCom/index.vue'
+import { base64ToBlob } from '@/utils/base64TurnImg.js'
+import { upload } from '@/api/public'
 export default {
-  components: {Uploader, DateCell},
+  components: {Uploader, DateCell,
+    imgCom,
+    writingPad
+  },
   data(){
     return {
       go:{
@@ -94,6 +115,7 @@ export default {
       userInfos:[],
       formData:{},
       showInput:false,
+      showSign:false,
       dicts:['out_in_approve_status','out_in_type','letter_id_type']
     }
   },
@@ -112,7 +134,7 @@ export default {
         let data = {
           approveStatus:2,
           approveRemark:this.formData.description,
-          id:this.visitInfo.approveLog.id
+          id:this.visitInfo.id
         }
         visitCheck(data).then(res=>{
           this.$toast('操作成功');
@@ -125,6 +147,27 @@ export default {
       }
       this.showInput = true;
     },
+    //上传签名图到服务器
+    resultImg(img) {
+      let obj = base64ToBlob(img)
+      let formData = new FormData()
+
+      obj.name = '签名.jpg'
+      formData.append('file', base64ToBlob(img))
+
+      upload(formData, 'image')
+        .then(res => {
+          console.log(process.env.NODE_ENV)
+          /*上传成功*/
+          let imgUrl = process.env.NODE_ENV === 'development' ? res.data.url : res.data.url
+          // this.submitSign(imgUrl)
+          this.submitApproveData(imgUrl);
+          // this.$emit("imgUrl", res.data.url);
+        })
+        .catch(err => {
+          /*上传失败*/
+        })
+    },
     //页面跳转逻辑
     toPagesFcn(){
       this.getRouter();
@@ -140,9 +183,14 @@ export default {
     },
     // 同意
     accredit(){
+      this.showSign=true;      
+    },
+    submitApproveData(imgUrl)
+    {
       let data = {
         approveStatus:1,
-        id:this.visitInfo.approveLog.id
+        id:this.visitInfo.id,
+        approveSignImg:imgUrl
       }
       visitCheck(data).then(res=>{
         this.$toast('操作成功');
@@ -168,8 +216,8 @@ export default {
     getInfo(){
       visitDetails(this.visitId).then(res=>{
         this.visitInfo = res.data;
-        this.approveStatus = this.visitInfo.approveLog.approveStatus;
-        this.approveRemark = this.visitInfo.approveLog.approveRemark;
+        this.approveStatus = this.visitInfo.approveStatus;
+        this.approveRemark = this.visitInfo.approveRemark;
         if(res.data.letterFile){
           let imgArr = res.data.letterFile.map(v=>{
             return JSON.parse(v)
@@ -344,6 +392,9 @@ export default {
   }
 
 }
+.sheet {
+  height: 45%;
+}
 .input-box{
   margin-bottom: 20px;
 }

+ 9 - 5
src/views/menu/visitCheck/index.vue

@@ -33,7 +33,7 @@
               :border="false"
               class="item-title"
               :title-style="{color:'#008cd6'}"
-              :title="`介绍信类型: ${getDictLabel(v.type,'out_in_type')}`"
+              :title="`介绍信类型: ${getDictLabel(v.letterType,'out_in_type')}`"
               @click="clickItem(v.id)">
               <template #right-icon>
                   <span :style="{color:getState(getDictLabel(v.approveStatus,'out_in_approve_status'))}">
@@ -52,13 +52,17 @@
                     <div class="item-value"> {{v.letterNo}}</div>
                   </div>
                   <div class="info-item">
-                    <div class="item-label">有效期限</div>
+                    <div class="item-label">介绍信有效期限</div>
                     <div class="item-value">{{v.startTime}}~{{v.endTime}}</div>
                   </div>
                   <div class="info-item">
+                    <div class="item-label">出入申请日期</div>
+                    <div class="item-value">{{v.createTime}}</div>
+                  </div>
+                  <div class="info-item">
                     <div class="item-label">来访事由</div>
                     <div class="item-value">
-                      {{v.reasons}}
+                      {{v.letterReasons}}
                     </div>
                   </div>
                 </div>
@@ -271,12 +275,12 @@ export default {
   align-items: center;
   font-size: 26px;
   .item-label{
-    flex:.25;
+    flex:.30;
     text-align: left;
     color:#333;
   }
   .item-value{
-    flex:.75;
+    flex:.70;
     color:#666;
     min-height: 50px;
     max-height: 250px;

+ 8 - 0
src/views/menu/visitRecord/api.js

@@ -34,6 +34,14 @@ export function userRegister(data){
   });
 }
 
+//人员登记
+export function deleteUserRegister(ids){
+  return request({
+    url: "/core/outinrecord/"+ids,
+    method: "delete",
+  });
+}
+
 //登记离开
 export function userDepart(data){
   return request({

+ 143 - 22
src/views/menu/visitRecord/detail.vue

@@ -10,8 +10,8 @@
             </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="getDictLabel(selectedUser.letterType,'out_in_type')"></van-cell>
+            <van-cell title="来访事由" :value="selectedUser.letterReasons"></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>
@@ -49,12 +49,44 @@
                 </div>
               </van-cell>
             </div>
-            <van-cell title="陪同人员" :value="selectedUser.accompanyingPerson"></van-cell>
+            <div class="upload-box" v-if="canRecord() && !selectedUser.departureTime && !selectedUser.checkImage">
+              <span class="required">核验结果</span>
+              <van-cell>
+                <uploader :maxCount="2" v-model="formData.checkImage"/>
+              </van-cell>
+            </div>
+            <van-cell v-if="selectedUser.accompanyingPerson" title="陪同人员" :value="selectedUser.accompanyingPerson"></van-cell>
+            <!-- <date-cell v-if="selectedUser.approveStatus==1 && !selectedUser.accompanyingPerson" required title="到达时间" :max-date="maxData" :min-date='minDate' :is-row="true"  v-model="formData.arrivalTime" date-type="datetime" /> -->
+            <van-field
+              v-if="canRecord() && !selectedUser.accompanyingPerson"
+              v-model="formData.accompanyingPerson"
+              rows="1"
+              autosize
+              required
+              :maxlength="200"
+              placeholder="请输入陪同人员姓名"
+              label="陪同人员"></van-field>
             <van-cell title="到达时间" v-if="selectedUser.arrivalTime" :value="dayjs(selectedUser.arrivalTime).format('YYYY-DD-MM HH:mm')"></van-cell>
             <van-cell title="离开时间" v-if="selectedUser.departureTime" :value="dayjs(selectedUser.departureTime).format('YYYY-DD-MM HH:mm')"></van-cell>
-            <date-cell v-else required title="离开时间" :max-date="maxData" :min-date='minDate' :is-row="true"  v-model="formData.departureTime" date-type="datetime" />
+            <div class="upload-box" v-if="selectedUser.submitSign">
+              <span>登记签名</span>
+              <van-cell >
+                <div
+                  class="nfc-img van-hairline--surround"
+                  :key="selectedUser.submitSign"
+                  @click="preView(selectedUser.submitSign)">
+                  <img :src="imgUrl(selectedUser.submitSign)" alt="" />
+                </div>
+              </van-cell>
+            </div>
+            <date-cell v-if="canRecord() && !selectedUser.arrivalTime" required title="到达时间" :max-date="maxData" :min-date='minDate' :is-row="true"  v-model="formData.arrivalTime" date-type="datetime" />
+            <date-cell v-if="canRecord() && selectedUser.arrivalTime && !selectedUser.departureTime" required title="离开时间" :max-date="maxData" :min-date='minDate' :is-row="true"  v-model="formData.departureTime" date-type="datetime" />
           </div>
-          <div v-if="!selectedUser.departureTime" class="big-btn-box" >
+          
+          <van-action-sheet v-model="showSign" title="签署名字" class="sheet">
+            <writingPad ref="esign" @resultImg="resultImg"></writingPad>
+          </van-action-sheet>
+          <div v-if="canRecord() &&!selectedUser.departureTime" class="big-btn-box" >
             <van-button  type="info" size="large" @click="onSubmit">确认登记</van-button>
           </div>
         </van-panel>
@@ -72,10 +104,14 @@ import {formatDate} from "@/filters/filter";
 import {mapGetters} from "vuex";
 import {imgUrl} from "@/utils";
 import { ImagePreview } from 'vant'
+import writingPad from '@/components/writingPad/index.vue'
+import imgCom from '@/components/imgCom/index.vue'
+import { base64ToBlob } from '@/utils/base64TurnImg.js'
+import { upload } from '@/api/public'
 import {userDetails, userDepart} from './api'
 import dayjs from 'dayjs'
 export default {
-  components: {Uploader, DateCell},
+  components: {Uploader, DateCell,writingPad,imgCom},
   data(){
     return {
       maxData:new Date(),
@@ -83,6 +119,7 @@ export default {
       visitId:null,
       userList:[],
       selectedUser:{},
+      showSign:false,
       prop:{
         label:'userName',
         value:'id'
@@ -90,6 +127,8 @@ export default {
       formData:{
         arrivalTime:null,
         departureTime:null,
+        checkImage:null,
+        accompanyingPerson:null,
       },
       dicts:['out_in_approve_status','out_in_type','letter_id_type']
     }
@@ -103,30 +142,109 @@ export default {
   },
   methods:{
     imgUrl,formatDate,
+    canRecord(){
+      return this.selectedUser.approveStatus==1 && this.selectedUser.status!=3
+    },
     onSubmit(){
-      let {departureTime} = this.formData;
-      if(!departureTime){
+      let {arrivalTime,departureTime,accompanyingPerson,checkImage} = this.formData;
+      if(!this.selectedUser.checkImage && !checkImage){
+        this.$toast('请上传审核结果');
+        return
+      }
+
+      if(!this.selectedUser.accompanyingPerson && !accompanyingPerson){
+        this.$toast('请输入陪同人员姓名');
+        return
+      }
+
+      if(!this.selectedUser.arrivalTime && !arrivalTime){
+        this.$toast('请选择到达时间');
+        return
+      }
+
+      if(this.selectedUser.arrivalTime && !this.selectedUser.departureTime && !departureTime){
         this.$toast('请选择离开时间');
         return
       }
-      let data = {
-        id:this.selectedUser.id,
-        arrivalTime:this.selectedUser.arrivalTime,
-        departureTime,
+      
+      if(departureTime){
+        this.signatureHandler();
       }
-      //alert(JSON.stringify(data))
-      userDepart(data).then(res=>{
-        this.$toast.success('提交成功');
-        this.$router.replace({
-          name:'visitRecord',
-          path:'/visitRecord',
-          params:{event:'refresh'},
-        });
-      })
+      else{
+        this.submitRecordData(arrivalTime,departureTime,accompanyingPerson,checkImage);
+      }      
+    },
+    submitRecordData(arrivalTime,departureTime,accompanyingPerson,checkImage,signImgUrl)
+    {
+        let data = {
+          id:this.selectedUser.id,
+          // accompanyingPerson:this.selectedUser.accompanyingPerson?this.selectedUser.accompanyingPerson:accompanyingPerson,
+          // arrivalTime: this.selectedUser.arrivalTime ? this.selectedUser.arrivalTime:arrivalTime,
+          // departureTime,
+        }
+        if(arrivalTime)
+        {
+          data.arrivalTime=arrivalTime;
+        }
+        if(departureTime)
+        {
+          data.departureTime=departureTime;
+        }
+        if(accompanyingPerson)
+        {
+          data.accompanyingPerson=accompanyingPerson;
+        }
+        if(checkImage)
+        {          
+          data.checkImage=checkImage.map(v=>{return v.imgPath}).toString(',');
+        }
+        if(signImgUrl)
+        {
+          data.submitSign=signImgUrl;
+        }
+        //alert(JSON.stringify(data))
+        userDepart(data).then(res=>{
+          this.$toast.success('提交成功');
+          this.$router.replace({
+            name:'visitRecord',
+            path:'/visitRecord',
+            params:{event:'refresh'},
+          });
+        })
+    },
+    signatureHandler() {
+      this.showSign = true
+    },
+    //上传签名图到服务器
+    resultImg(img) {
+      let obj = base64ToBlob(img)
+      let formData = new FormData()
+
+      obj.name = '签名.jpg'
+      formData.append('file', base64ToBlob(img))
+
+      upload(formData, 'image')
+        .then(res => {
+          console.log(process.env.NODE_ENV)
+          /*上传成功*/
+          let signImgUrl = process.env.NODE_ENV === 'development' ? res.data.url : res.data.url
+          // this.submitSign(imgUrl)
+          let {arrivalTime,departureTime,accompanyingPerson,checkImage} = this.formData;
+          this.submitRecordData(arrivalTime,departureTime,accompanyingPerson,checkImage,signImgUrl);
+          // this.$emit("imgUrl", res.data.url);
+        })
+        .catch(err => {
+          /*上传失败*/
+        })
     },
     getUserInfo(){
       userDetails(this.visitId).then(res=>{
-        let checkImage = res.data.checkImage.split(',');
+
+        let checkImage = "";
+        if(res.data.checkImage)
+        {
+          checkImage= res.data.checkImage.split(',')
+        }
         let imgFile = res.data.imgFile.split(',');
         let letterFile = [];
         if(res.data.letterFile && res.data.letterFile.length > 0){
@@ -304,4 +422,7 @@ export default {
     height: 30px;
   }
 }
+.sheet {
+  height: 45%;
+}
 </style>

+ 66 - 6
src/views/menu/visitRecord/index.vue

@@ -14,6 +14,14 @@
           @change="refreshData"/>
         <date-cell title="日期" is-all v-model="query.arrivalTime" date-type="date" @change="refreshData"/>
       </div>
+      <select-cell
+          style="border-right: 1px solid #f5f5f5;"
+          title="审批状态"
+          :isAll="true"
+          :border="false"
+          v-model="query.approveStatus"
+          :data-list="getDictItem('out_in_approve_status')"
+          @change="refreshData"/>
       <div class="card-list">
         <Scroll
           ref="Scroll"
@@ -26,10 +34,15 @@
               :border="false"
               class="item-title"
               :title-style="{color:'#008cd6'}"
-              :title="`介绍信类型: ${getDictLabel(v.type,'out_in_type')}`"
+              :title="`介绍信类型: ${getDictLabel(v.letterType,'out_in_type')}`"
               @click="clickItem(v.id)">
               <template #right-icon>
-                <van-button v-if="!v.departureTime" type="info" size="mini">登记离开时间</van-button>
+                <span v-if="v.approveStatus==1 && v.status==3" style="color:#D7000F">
+                    已失效
+                  </span>
+                <van-button v-if="v.approveStatus==0" @click.stop="cancelOutInRequest(v.id)" type="info" size="mini">取消出入申请</van-button>
+                <van-button v-if="v.approveStatus==1 && v.status!=3 &&!v.arrivalTime" type="info" size="mini">登记达到时间</van-button>
+                <van-button v-if="v.approveStatus==1 && v.status!=3 && v.arrivalTime&&!v.departureTime" type="info" size="mini">登记离开时间</van-button>
               </template>
             </van-cell>
             <van-cell
@@ -39,13 +52,32 @@
               <template #default>
                 <div class="info-box">
                   <div class="info-item">
+                    <div class="item-label">审批状态</div>
+                    <div class="item-value" :style="{color:getState(getDictLabel(v.approveStatus,'out_in_approve_status'))}">
+                      {{getDictLabel(v.approveStatus,'out_in_approve_status') }}
+                    </div>
+                  </div>
+                  <div class="info-item" v-if="v.approveRemark">
+                    <div class="item-label">审批说明</div>
+                    <div class="item-value"> {{v.approveRemark}}</div>
+                  </div>
+                  <div class="info-item">
+                    <div class="item-label">审批时间</div>
+                    <div class="item-value">
+                       <!-- {{v.approveTime}} -->
+                       {{v.approveTime? dayjs(v.approveTime).format('YYYY-MM-DD HH:mm') : '暂无'}}
+                      </div>
+                  </div>
+                
+                  <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')}}
+                      <!-- {{ dayjs(v.arrivalTime).format('YYYY-MM-DD HH:mm')}} -->
+                      {{v.arrivalTime? dayjs(v.arrivalTime).format('YYYY-MM-DD HH:mm') : '暂无'}}
                     </div>
                   </div>
                   <div class="info-item">
@@ -103,8 +135,9 @@
 <!--          </card>-->
         </Scroll>
       </div>
+     
     </div>
-    <drag-button @btnClick="clickAdd"></drag-button>
+    <!-- <drag-button @btnClick="clickAdd"></drag-button> -->
   </div>
 </template>
 <script>
@@ -114,7 +147,7 @@ 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 {dataList,deleteUserRegister} from './api'
 import {mapGetters} from "vuex";
 import {formatDate} from "@/filters/filter";
 import DragButton from "@/components/DragButton/index.vue";
@@ -142,7 +175,7 @@ export default {
       },
       dataList:[],
       pullup:false,
-      dicts:['out_in_type']
+      dicts:['out_in_type','out_in_approve_status']
     }
   },
   beforeRouteEnter(to,from,next){
@@ -160,6 +193,18 @@ export default {
   },
   methods: {
     dayjs,
+    getState(state){
+      switch (state){
+        case '待审批':
+          return '#008cd6';
+        case '不同意':
+          return '#bc9f71';
+        case '同意':
+          return '#009240';
+        case '已失效':
+          return '#D7000F';
+      }
+    },
     clickAdd(){
       this.$router.push({
         path:'/visitUserRecord',
@@ -207,6 +252,21 @@ export default {
         path:'/visitRecordDetail',
         query:{id}
       });
+    },
+    cancelOutInRequest(id)
+    {
+      // let data = {
+      //   id:this.selectedUser.id,
+      //   accompanyingPerson:this.selectedUser.accompanyingPerson?this.selectedUser.accompanyingPerson:accompanyingPerson,
+      //   arrivalTime: this.selectedUser.arrivalTime ? this.selectedUser.arrivalTime:arrivalTime,
+      //   departureTime,
+      // }
+      //alert(JSON.stringify(data))
+      let ids=[id];
+      deleteUserRegister(ids).then(res=>{
+        this.$toast.success('提交成功');
+        this.refreshData();
+      })
     }
   }
 }

+ 405 - 0
src/views/menu/visitRegister/addOutInRequest.vue

@@ -0,0 +1,405 @@
+<template>
+  <div class="intro-add">
+    <nav-bar></nav-bar>
+    <div class="page-container">
+      <!--   基本信息   -->
+      <div class="card">
+        <van-panel title="来访信息" >
+          <template #header>
+            <van-cell title="介绍信情况">
+              <template #extra>
+                  <span :style="{color:getState(visitInfo.status)}">
+                    {{getDictLabel(visitInfo.status,'letter_status') }}
+                  </span>
+              </template>
+            </van-cell>
+          </template>
+          <div class="panel-box">
+            <van-cell title="来访类型" :value="getDictLabel(visitInfo.type,'out_in_type')"></van-cell>
+            <van-cell title="来访事由" :value="visitInfo.reasons"></van-cell>
+            <van-cell title="介绍信编号" v-if="visitInfo.letterNo"  :value="visitInfo.letterNo"></van-cell>
+            <van-cell title="开具日期" v-if="visitInfo.startTimeStr"  :value="visitInfo.startTimeStr"></van-cell>
+            <van-cell title="有效天数" v-if="visitInfo.effectiveDays"  :value="`${visitInfo.effectiveDays}天`"></van-cell>
+            <van-cell title="介绍信附件"  v-if="visitInfo.letterFile && visitInfo.letterFile.length > 0">
+              <template #right-icon>
+                <div class="file-box">
+                  <p class="van-ellipsis" v-for="(v, i) in visitInfo.letterFile"
+                     :key="v.url"
+                     @click="previewFile(v)">{{v.name}}</p>
+                </div>
+              </template>
+            </van-cell>
+            <van-cell v-if="visitInfo.description" title="备注信息" :value="visitInfo.description"></van-cell>
+          </div>
+        </van-panel>
+      </div>
+
+      <!--  人员列表  -->
+      <div class="card" v-for="(v,i) in userInfos" :key="i">
+        <div class="goods-card">
+          <div class="card-cell-checkbox">
+            <van-checkbox v-model="v.checked" shape="square" @click.native="checkboxClicked(i)"/>
+          </div>
+          <div class="card-img-box" v-if="v.imgFile && v.imgFile.length > 0" @click="preView(v.imgFile)">
+            <img :src="imgUrl(v.imgFile[0])" alt="">
+          </div>
+          <div class="card-cell-box">
+            <van-cell title="来访单位" :value="v.companyName"></van-cell>
+            <van-cell title="来访人员" :value="v.userName"></van-cell>
+            <van-cell title="证件类型" :value="getDictLabel(v.idType,'letter_id_type')"></van-cell>
+            <van-cell title="证件号码" :value="v.idCard"></van-cell>
+          </div>
+        </div>
+      </div>
+      <!-- <van-checkbox v-model="checked" icon-size="24px">复选框</van-checkbox> -->
+      <!-- <div v-show="showInput" class="input-box">
+        <van-field
+          v-model="formData.description"
+          rows="1"
+          autosize
+          :maxlength="200"
+          label="审批说明"
+          type="textarea"
+          placeholder="请输入"/>
+      </div>
+      <div v-if="approveRemark" class="input-box">
+        <van-cell title="审批说明" :value="approveRemark"></van-cell>
+      </div> -->
+      <!-- <div v-if="approveStatus == 0 && visitInfo.status == 1" class="flex-box">
+        <van-button type="info" style="width: 48%" plain @click="refuse">不同意</van-button>
+        <van-button type="info" style="width: 48%" @click="accredit">同意</van-button>
+      </div> -->
+      <div class="big-btn-box">
+        <van-button  type="info" size="large" @click="onSubmit">提交申请</van-button>
+      </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 { ref } from 'vue';
+import {imgUrl} from "@/utils";
+import { ImagePreview } from 'vant'
+import {visitDetails,visitCheck,outInRequestAdd} from './api'
+export default {
+  components: {Uploader, DateCell},
+  data(){
+    return {
+      go:{
+        type:'replace', //参数:go push replace
+        path:'/visitCheck',
+      },
+      visitId:null,
+      approveStatus:null,
+      approveRemark:null,
+      activeNames:['1'],
+      visitInfo: {},
+      userInfos:[],
+      formData:{},
+      showInput:false,
+      dicts:['out_in_approve_status','out_in_type','letter_id_type','letter_status'],
+      checked:null
+    }
+  },
+  computed:{
+    ...mapGetters(['orgId','id','dictionary'])
+  },
+  mounted(){
+    this.visitId = this.$route.query.id;
+    this.getInfo();
+  },
+  methods:{
+    imgUrl,formatDate,
+    // 拒绝
+    refuse(){
+      if(this.showInput){
+        let data = {
+          approveStatus:2,
+          approveRemark:this.formData.description,
+          id:this.visitInfo.approveLog.id
+        }
+        visitCheck(data).then(res=>{
+          this.$toast('操作成功');
+          this.toPagesFcn();
+        }).catch(error=>{
+          if( error === '任务已完成'){
+            this.toPagesFcn();
+          }
+        })
+      }
+      this.showInput = true;
+    },
+    //页面跳转逻辑
+    toPagesFcn(){
+      this.getRouter();
+      if(this.fromPages.name === "works"){
+        this.$router.go(-1)
+      }else {
+        this.$router.replace({
+          name:'visitCheck',
+          path:'/visitCheck',
+          params:{event:'refresh'}
+        });
+      }
+    },
+    // 同意
+    accredit(){
+      let data = {
+        approveStatus:1,
+        id:this.visitInfo.approveLog.id
+      }
+      visitCheck(data).then(res=>{
+        this.$toast('操作成功');
+        this.toPagesFcn();
+      }).catch(error=>{
+        if( error === '任务已完成'){
+          this.toPagesFcn();
+        }
+      })
+    },
+    getState(state){
+      switch (state){
+        case 0:
+          return '#008cd6';
+        case 1:
+          return '#009240';
+        case 2:
+          return '#bc9f71';
+        case 3:
+          return '#D7000F';
+      }
+    },
+    getInfo(){
+      visitDetails(this.visitId).then(res=>{
+        this.visitInfo = res.data;
+        // this.approveStatus = this.visitInfo.approveLog.approveStatus;
+        // this.approveRemark = this.visitInfo.approveLog.approveRemark;
+        if(res.data.letterFile){
+          let imgArr = res.data.letterFile.map(v=>{
+            return JSON.parse(v)
+          })
+          this.visitInfo.letterFile = imgArr;
+        }
+        if(res.data.userInfos){
+          let users = res.data.userInfos.map(v=>{
+            if(v.imgFile){
+              v.imgFile = v.imgFile.split(',');
+            }
+            v.checked=false;
+            return v
+          });
+          console.log(users,'users')
+          this.userInfos = users;
+        }
+      })
+    },
+    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)]);
+      }
+    },
+    checkboxClicked(index)
+    {
+      this.userInfos[index].checked=!this.userInfos[index].checked;
+      this.$nextTick(()=>{
+        this.$forceUpdate();
+      })
+      // console.log('checkboxClicked', this.userInfos )     
+    },
+    onSubmit(){      
+      try{
+
+        if (this.userInfos.filter(x=>x.checked==true).length == 0) {
+          this.$toast('请勾选出入申请出入人员');
+          return;
+        }
+        
+        let requestUserInfos=JSON.parse(JSON.stringify(this.userInfos));        
+        let data = {id:this.visitInfo.id};        
+        data.userInfos = requestUserInfos.filter(x=>x.checked==true).map(user=>{
+          let urlArr = user.imgFile.map(v=>{
+            return v.imgPath
+          })
+          user.imgFile = urlArr.join(',');
+          return user
+        });
+        console.log("data",data)
+        outInRequestAdd(data).then(res=>{
+          this.$toast.success('提交成功');
+          this.$router.replace({
+            name:'visitRegister',
+            path:'/visitRegister',
+            params:{event:'refresh'},
+          });
+        })
+      }catch (e) {
+        alert(e)
+      }
+    },
+
+  }
+}
+</script>
+<style lang="scss">
+.intro-add{
+  .van-card{
+    padding: 20px;
+  }
+  .card-cell-box{
+    width: 60%;
+    .van-cell{
+      padding: 4px;
+      &::after{
+        left:10px;
+        right:10px;
+      }
+    }
+    .van-cell__title{
+      flex:.30;
+    }
+    .van-cell__value{
+      flex:.70;
+    }
+  }
+}
+</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: 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;
+    }
+  }
+}
+.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;
+    }
+  }
+  .card-cell-checkbox{
+    margin-right: 10px;
+  }
+}
+.big-btn-box{
+  padding-bottom: 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;
+  }
+
+}
+.input-box{
+  margin-bottom: 20px;
+}
+.checkboxList {
+  z-index: 999;
+}
+</style>

+ 10 - 0
src/views/menu/visitRegister/api.js

@@ -17,6 +17,16 @@ export function visitAdd(data) {
   });
 }
 
+// 添加
+export function outInRequestAdd(data) {
+  return request({
+    url: "/core/letter/outInRequest",
+    method: "post",
+    data,
+  });
+}
+
+
 //获取详情
 export function visitDetails(id){
   return request({

+ 8 - 10
src/views/menu/visitRegister/detail.vue

@@ -9,8 +9,8 @@
           <div class="panel-box">
             <van-cell title="状态">
               <template #extra>
-                  <span :style="{color:getState(approveStatus)}">
-                    {{getDictLabel(approveStatus,'out_in_approve_status') }}
+                  <span :style="{color:getState(visitInfo.status)}">
+                    {{getDictLabel(visitInfo.status,'letter_status') }}
                   </span>
               </template>
             </van-cell>
@@ -69,14 +69,14 @@ export default {
       activeNames:['1'],
       visitInfo: {},
       userInfos:[],
-      approveStatus:null,
-      approveRemark:null,
+      // approveStatus:null,
+      // approveRemark:null,
       reformData: {
         reformDate: null,
         description: null,
         images: null,
       },
-      dicts:['out_in_approve_status','out_in_type','letter_id_type']
+      dicts:['out_in_approve_status','out_in_type','letter_id_type','letter_status']
     }
   },
   computed:{
@@ -95,16 +95,14 @@ export default {
         case 1:
           return '#009240';
         case 2:
-          return '#bc9f71';
-        case 3:
           return '#D7000F';
       }
     },
     getInfo(){
       visitDetails(this.visitId).then(res=>{
         this.visitInfo = res.data;
-        this.approveStatus = this.visitInfo.approveLog.approveStatus;
-        this.approveRemark = this.visitInfo.approveLog.approveRemark;
+        // this.approveStatus = this.visitInfo.approveLog.approveStatus;
+        // this.approveRemark = this.visitInfo.approveLog.approveRemark;
         if(res.data.letterFile){
           let imgArr = res.data.letterFile.map(v=>{
             return JSON.parse(v)
@@ -136,7 +134,7 @@ export default {
   }
 }
 </script>
-<style lang="scss">
+<style scoped lang="scss">
 .intro-add{
   .van-card{
     padding: 20px;

+ 32 - 22
src/views/menu/visitRegister/index.vue

@@ -9,9 +9,8 @@
         :isAll="true"
         :border="false"
         :isRow="true"
-        :prop="prop"
         v-model="query.type"
-        :data-list="typeList"
+        :data-list="getDictItem('out_in_type')"
         @change="refreshData"/>
       <div class="card-list">
         <Scroll
@@ -28,9 +27,10 @@
                 :title="`介绍信类型: ${getDictLabel(v.type,'out_in_type')}`"
                 @click="clickItem(v.id)">
                   <template #right-icon>
-                    <span :style="{color:getState(getDictLabel(v.approveStatus,'out_in_approve_status'))}">
-                      {{getDictLabel(v.approveStatus,'out_in_approve_status') }}
-                    </span>
+                    <span v-if="v.status==2" :style="{color:getState(getDictLabel(v.status,'letter_status'))}">
+                      {{getDictLabel(v.status,'letter_status') }}
+                    </span>                 
+                   <van-button v-if="v.status==1" @click.stop="clickItem(v.id,true)" type="info" size="mini">出入申请</van-button>             
                   </template>
               </van-cell>
               <van-cell :border="false" @click="clickItem(v.id)">
@@ -97,17 +97,17 @@ export default {
         label:'name',
         value:'value'
       },
-      typeList:[
-        {
-          name:'纸质',
-          value:2
-        },
-        {
-          name:'紧急',
-          value:3
-        }
-      ],
-      dicts:['out_in_approve_status','out_in_type']
+      // typeList:[
+      //   {
+      //     name:'纸质',
+      //     value:2
+      //   },
+      //   {
+      //     name:'紧急',
+      //     value:3
+      //   }
+      // ],
+      dicts:['out_in_approve_status','out_in_type','letter_status']
     }
   },
   beforeRouteEnter(to,from,next){
@@ -180,12 +180,22 @@ export default {
         query:{type:'add'}
       });
     },
-    clickItem(id){
-      console.log(id,'idddddddd')
-      this.$router.push({
-        path:'/visitDetail',
-        query: {id}
-      });
+    clickItem(id,isAddOutInRequest){     
+      if(isAddOutInRequest)
+      {
+        console.log(id,'isAddOutInRequest')
+        this.$router.push({
+          path:'/visitAddOutInRequset',
+          query: {id}
+        });
+      }
+      else{
+        console.log(id,'visitDetail')
+        this.$router.push({
+          path:'/visitDetail',
+          query: {id}
+        });
+      }
     }
   }
 }