ソースを参照

Merge branch 'V0.0.2' of http://10.87.10.227:4000/jzyd_yyds/soc_app into V0.0.2

coys 2 年 前
コミット
41839b94c6

+ 2 - 1
package.json

@@ -13,10 +13,12 @@
     "@riophae/vue-treeselect": "0.4.0",
     "amfe-flexible": "^2.2.1",
     "axios": "^1.3.4",
+    "better-scroll": "^2.5.1",
     "browser-fs-access": "^0.34.1",
     "core-js": "^3.23.3",
     "dayjs": "^1.11.9",
     "js-image-compressor": "^2.0.0",
+    "pdfjs-dist": "2.5.207",
     "regenerator-runtime": "^0.13.5",
     "v-calendar": "^2.4.1",
     "vant": "^2.12.54",
@@ -24,7 +26,6 @@
     "vue-easytable": "^2.27.1",
     "vue-esign": "^1.1.4",
     "vue-pdf": "4.2.0",
-    "pdfjs-dist": "2.5.207",
     "vue-router": "^3.6.5",
     "vuex": "^3.6.2"
   },

+ 166 - 0
src/components/SearchSelectCell/SelectPicker.vue

@@ -0,0 +1,166 @@
+<template>
+  <van-popup class="search-data-popup" round lazy-render v-model="show" position="bottom" >
+    <div class="header-line">
+      <div class="cancel" @click="onSearchCancel">取消</div>
+      <div class="title">{{ title }}</div>
+      <div class="sure" @click="onSearchConfirm">确定</div>
+    </div>
+    <van-search v-if="showSearch" placeholder="输入您想搜索的内容" v-model="searchValue" @input="inputSearchValue" />
+<!--    <div class="tip">已选{{temp_datas.length}}条</div>-->
+    <div v-if="itemList?.length >0"  class="lists">
+      <div  class="line" v-for="(item, index) in itemList" :key="item[valueKey]">
+
+        <van-cell
+          clickable
+          :key="item[valueKey]"
+          :title="item[valueKey]"
+          @click="click(item,index)">
+          <template #right-icon>
+            <van-checkbox v-model="item.checked"/>
+          </template>
+        </van-cell>
+      </div>
+    </div>
+    <div v-else class="lists">
+      <van-empty description="暂无数据" />
+    </div>
+  </van-popup>
+</template>
+<script>
+export default {
+  props: {
+    showPicker: {
+      types:Boolean,
+      default:false
+    }, //是否显示
+    options: {
+      type:Array,
+      default: ()=>[],
+    }, //未根据搜索内容筛选的所有列表数据
+    value: {
+      type:Array,
+      default: ()=>[],
+    },//默认选中数据
+    //自定义字段
+    valueKey:{
+      type: String,
+      default:'label'
+    },
+    showSearch:{
+      type:Boolean,
+      default:true
+    },
+    title: String //标题
+  },
+  data(){
+    return {
+      searchValue: "", //搜索框内容
+      itemList:[],
+    }
+  },
+  watch:{
+    temp_datas:{
+      handler(val){
+        this.itemList = val;
+      },
+      deep:true
+    },
+  },
+  computed: {
+    columns(){
+      return this.options
+    },
+    temp_datas(){
+      this.columns.forEach(v=>{
+        this.value.forEach((item)=>{
+          if(v[this.valueKey] === item[this.valueKey]){
+            v.checked = true;
+          }else {
+            v.checked = false;
+          }
+        })
+      })
+      return this.columns
+    },
+    show:{
+      get(){
+        return this.showPicker;
+      },
+      set(){
+        this.$emit("cancel");
+      },
+    },
+  },
+  methods: {
+    click(v,i){
+      this.$set(this.columns[i],'checked',!this.columns[i].checked);
+    },
+    inputSearchValue(query) {
+      if(query == ''){return this.itemList = this.options }
+      //搜索框值发生改变
+      setTimeout(() => {
+        this.itemList= this.temp_datas.filter(item => {
+          return item[this.valueKey].indexOf(query.toLowerCase()) > -1;
+        });
+      }, 200);
+    },
+    onSearchCancel() {
+      //取消
+      this.$emit("cancel");
+    },
+    onSearchConfirm() {
+      let arr = this.columns.filter(v=>v.checked === true)
+      //确认
+      this.$emit("confirm", arr);
+      this.show = false;
+    },
+  },
+}
+</script>
+<style scoped>
+.search-data-popup .tip {
+  color: #666;
+  padding-bottom: 5px;
+}
+.search-data-popup .header-line {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  height: 90px;
+}
+.search-data-popup .header-line .cancel {
+  padding: 0 30px;
+  font-size: 28px;
+  color: #969799;
+}
+.search-data-popup .header-line .title {
+  font-weight: 500;
+  font-size: 30px;
+  color: #343434;
+}
+.search-data-popup .header-line .sure {
+  padding: 0 30px;
+  font-size: 28px;
+  color: #1989fa;
+}
+.search-data-popup .lists {
+  display: flex;
+  flex-direction: column;
+  padding: 10px 12px 20px 12px;
+  min-height: 300px;
+  max-height: 700px;
+  overflow: auto;
+}
+.search-data-popup .lists .line {
+  line-height: 40px;
+  font-size: 16px;
+  color: #000;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+.search-data-popup .lists .line img {
+  width: 20px;
+  height: 20px;
+}
+</style>

+ 107 - 0
src/components/SearchSelectCell/index.vue

@@ -0,0 +1,107 @@
+<template>
+  <div class="date-cell">
+    <van-cell v-if="disabled" :required="required" :title="title" :label="label"/>
+    <van-cell v-else  :required="required" :title="title" :label="label" is-link  @click="clickItem"/>
+    <Select-picker
+      :options="dataList"
+      v-bind="$attrs"
+      :showPicker="showPicker"
+      title="选择角色"
+      :value-key="prop.label"
+      :value="selected"
+      @confirm="pickerConfirm"
+      @cancel="cancelPicker">
+    </Select-picker>
+  </div>
+</template>
+
+<script>
+import SelectPicker from './SelectPicker.vue'
+export default {
+  components:{
+    SelectPicker
+  },
+  props:{
+    //禁用
+    disabled:{
+      type: [Boolean,String],
+      default: false,
+    },
+    //双向绑定的数据
+    value:{
+      type: [String,Number],
+      default: null,
+    },
+    required:{
+      type: [Boolean,String],
+      default: false,
+    },
+    //标题
+    title:{
+      type: String,
+      default: null,
+    },
+    //父组件给的列表数据
+    dataList:{
+      type: Array,
+      default: ()=>[],
+    },
+    //自定义字段
+    prop:{
+      type: Object,
+      default: ()=>(
+        {
+          label:'label',
+          value:'value'
+        }
+      ) ,
+    }
+  },
+  data(){
+    return{
+      showPicker:false,
+      label:'',
+    }
+  },
+  computed:{
+    columns(){
+      return this.dataList;
+    },
+    selected(){
+      let val;
+      this.columns.forEach(v=> {
+        if (v[this.prop.value] === this.value) {
+          val.push(v[this.prop.label]);
+          this.label = val.toString();
+        }
+      });
+      return val;
+    },
+  },
+  methods:{
+    cancelPicker(){
+      this.showPicker = false;
+    },
+    pickerConfirm(val){
+      console.log(val,'234')
+      this.label = val.map(v=>v[this.prop.label]).toString();
+      this.showPicker = false;
+      let arr = val.map(v=>v[this.prop.value]);
+      this.$emit('change',arr)
+    },
+    clickItem(){
+      this.showPicker = true;
+    },
+  },
+  model:{
+    prop: 'value',
+    event: 'change',
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.van-cell__label{
+  margin: 0;
+}
+</style>

+ 1 - 0
src/components/dateCell/index.vue

@@ -84,6 +84,7 @@ export default {
      let h = new Date().getHours();
      this.defaultTime = `${h}:00`;
     }
+    this.defaultTime = new Date();
   },
   methods:{
     cancelPicker(){

+ 4 - 1
src/components/list/index.vue

@@ -39,7 +39,10 @@ export default {
     }
   },
   props: {
-    list: { type: Function, required: true },
+    list: {
+      type: [Function, Array],
+      required: true
+    },
     params: {},
     wrap: {
       default() {

+ 11 - 4
src/components/orgTree/index.vue

@@ -5,10 +5,10 @@
       @select="onSelect"
       v-model="selected"
       :options="orgTree"
-      :clearable="false"
+      :clearable="clearable"
       label='检查机构'
       :backspaceRemoves="false"
-      placeholder="请选择机构"
+      :placeholder="placeholder"
       :normalizer="tenantIdnormalizer"
       :show-count="true"
       :noChildrenText="''">
@@ -27,6 +27,14 @@ export default {
     value: {
       type: [String,Number],
       default: null
+    },
+    placeholder: {
+      type: String,
+      default: '请选择机构'
+    },
+    clearable:{
+      type:Boolean,
+      default:false
     }
   },
   data() {
@@ -99,7 +107,6 @@ export default {
     height: 90px;
     line-height: 90px;
   }
-
   .vue-treeselect__menu {
     padding: 20px;
     width: 100%;
@@ -119,7 +126,7 @@ export default {
   }
   .vue-treeselect--open-below .vue-treeselect__menu{
     border: 1px solid #cfcfcf;
-    margin-top:6px;
+    margin-top:3px;
     box-shadow: 0 0 10px 0 rgba(0,0,0,.1);
   }
   .vue-treeselect--focused:not(.vue-treeselect--open) .vue-treeselect__control{

+ 242 - 0
src/components/scroll/scroll.vue

@@ -0,0 +1,242 @@
+<template>
+  <div ref="wrapper" class="better-scroll">
+    <div class="content">
+      <div v-if="pulldown" class="pulldown-tip">
+        <span>{{pulldownTip.text}}</span>
+      </div>
+      <div class="list">
+        <slot></slot>
+      </div>
+      <div v-if="pullupShow" class="pullup-tip">
+        <span>{{pullupTip.text}}</span>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+  import BScroll from 'better-scroll'
+    export default {
+      name: "scroll",
+      props: {
+        // 滚动的时候会触发scroll事件,会截流
+        // 滚动的时候实时触发scroll事件,不会截流
+        // 在swipe的情况下也能使用scroll事件
+        probeType: {
+          type: Number,
+          default: 3
+        },
+        //点击列表触发click事件
+        click: {
+          type: Boolean,
+          default: true
+        },
+         //开启横向滚动
+        scrollX: {
+          type: Boolean,
+          default: false
+        },
+        //滚动事件
+        listenScroll: {
+          type: Boolean,
+          default: false
+        },
+        //列表数据
+        data: {
+          type: Array,
+          default: null,
+        },
+        //滚动到底部事件,用于上拉加载
+        pullup: {
+          type: Boolean,
+          default: true
+        },
+        //顶部下拉事件,用于下拉刷新
+        pulldown: {
+          type: Boolean,
+          default: true
+        },
+        //列表滚动事件
+        beforeScroll: {
+          type: Boolean,
+          default: false
+        },
+        //刷新scroll延时。
+        refreshDelay: {
+          type: Number,
+          default: 20
+        },
+      },
+      data(){
+        return{
+          loadingConnecting: false,
+          pullupShow:false,
+          pulldownTip: {
+            text: '下拉刷新',
+          },
+          pullupTip: {
+            text: '上拉加载',
+          },
+        }
+      },
+      mounted() {
+          this.initScroll();
+      },
+      watch: {
+        pullup(v){
+          console.log(v,'监听pullup事件')
+          //this.pullup = v;
+        },
+        data(v) {
+          setTimeout(() => {
+            this.refresh()
+          }, this.refreshDelay)
+        }
+      },
+      methods: {
+        initScroll() {
+          if (!this.$refs.wrapper) {
+            return;
+          }
+          // better-scroll的初始化
+          this.scroll = new BScroll(this.$refs.wrapper, {
+            probeType: this.probeType,
+            click: this.click,
+            scrollX: this.scrollX
+          });
+
+          // 是否触发滚动事件
+          if (this.listenScroll || this.pulldown || this.pullup) {
+            //监听滚动事件
+            this.scroll.on('scroll', (pos) => {
+              if (this.listenScroll) {
+                this.$emit('scroll', pos);
+              }
+              // 下拉刷新
+              if (this.pulldown) {
+                if (pos.y > 50) {
+                  this.pulldownTip = {
+                    text: '松开立即刷新',
+                  }
+                } else {
+                  this.pulldownTip = {
+                    text: '下拉刷新',
+                  }
+                }
+              }
+
+              //上拉加载
+              if (this.pullup) {
+                if (pos.y < (this.scroll.maxScrollY + -50)) {
+                  this.pullupTip = {
+                    text: '加载中..',
+                  };
+                }else {
+                  this.pullupTip = {
+                    text: '上拉加载',
+                  };
+                }
+                this.pullupShow = true;
+              }
+
+            })
+          }
+          console.log(this.pullup,'pullup')
+          // 底部上拉事件,上拉加载
+          if (this.pullup) {
+            this.scroll.on('touchEnd', (pos) => {
+
+              // 下拉动作
+              if (pos.y < -40) {
+                // this.pullupTip = {
+                //   text: '111',     // 松开立即刷新
+                // };
+                console.log('上拉加载,touchEnd')
+                this.$emit('pullup');
+              }
+            });
+          }
+
+          //顶部下拉事件,下拉刷新
+          if (this.pulldown) {
+            this.scroll.on('touchEnd', (pos) => {
+              // 下拉动作
+              if (pos.y > 50) {
+                // 重置提示信息
+                // this.pulldownTip = {
+                //   text: '222',     // 松开立即刷新
+                // };
+                console.log('下拉刷新,touchEnd')
+                this.$emit('pulldown');
+              }
+            });
+          }
+
+          // 是否派发列表滚动开始的事件
+          if (this.beforeScroll) {
+            this.scroll.on('beforeScrollStart', () => {
+              this.$emit('beforeScroll')
+            });
+          }
+        },
+        disable() {
+          // 代理better-scroll的disable方法
+          this.scroll && this.scroll.disable();
+        },
+        enable() {
+          // 代理better-scroll的enable方法
+          this.scroll && this.scroll.enable();
+        },
+        refresh() {
+          // 代理better-scroll的refresh方法
+          this.scroll && this.scroll.refresh();
+        },
+        scrollTo() {
+          // 代理better-scroll的scrollTo方法
+          this.scroll && this.scroll.scrollTo.apply(this.scroll, arguments);
+        },
+        scrollToElement() {
+          // 代理better-scroll的scrollToElement方法
+          this.scroll && this.scroll.scrollToElement.apply(this.scroll, arguments);
+        }
+      },
+    }
+</script>
+<style lang="scss">
+  .better-scroll{
+    height: 100%;
+    position: relative;
+    overflow: hidden;
+    .content {
+      min-height: calc(100% + 1px);
+      border-top: 1px solid #f2f2f2;
+      overflow: auto;
+    }
+    .list{
+      overflow: auto;
+    }
+    .pulldown-tip {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      position: absolute;
+      top: -80px;
+      height: 80px;
+      line-height: 80px;
+      color: #bbb;
+      font-size: 3.5vw;
+      z-index: 1;
+    }
+    .pullup-tip{
+      box-sizing: border-box;
+      line-height: 80px;
+      width: 100%;
+      color: #bbb;
+      font-size: 3.5vw;
+      text-align: center;
+      margin: 0 auto;
+    }
+
+  }
+</style>

+ 6 - 2
src/components/upload/uploader.vue

@@ -34,6 +34,7 @@ export default {
     },
     data() {
       return {
+        //组件显示用
         fileList:[],
         //上传之后的图片列表,双向绑定之后覆盖fileList
         imageList:[]
@@ -47,7 +48,10 @@ export default {
       value:{
         handler(val){
           console.log(val,'ttttt')
-          if(!val || val.length === 0) return;
+          if(!val || val.length === 0) {
+            this.imageList = [];
+            return
+          }
           this.fileList = val.map(v=>{
             v.url = imgUrl(v.imgPath);
             return v
@@ -81,7 +85,7 @@ export default {
                 this.$toast('图片压缩失败')
                 reject(e);
               },
-             });
+            });
         });
       },
       //上传到服务器

+ 20 - 2
src/router/router.config.js

@@ -7,7 +7,7 @@ export let routers = [
     path: '/',
     redirect:'/login'
   },
-  
+
   {
     path: '/login',
     component: () => import('@/views/login'),
@@ -200,7 +200,25 @@ export let routers = [
         path: '/securityCheckRegister',
         name: 'securityCheckRegister',
         component: () => import('@/views/menu/securityCheckRegister/index'),
-        meta: { title: '安全检查登记', keepAlive: false }
+        meta: { title: '安全检查登记', keepAlive: true }
+      },
+      {
+        path: '/securityDetail',
+        name: 'securityDetail',
+        component: () => import('@/views/menu/securityCheckRegister/detail'),
+        meta: { title: '安全检查详情', keepAlive: true }
+      },
+      {
+        path: '/addCheck',
+        name: 'addCheck',
+        component: () => import('@/views/menu/securityCheckRegister/addCheck'),
+        meta: { title: '添加检查内容', keepAlive: false ,hideTabBar:true}
+      },
+      {
+        path: '/addWorker',
+        name: 'addWorker',
+        component: () => import('@/views/menu/securityCheckRegister/addWorker'),
+        meta: { title: '选择授权人员', keepAlive: false ,hideTabBar:true}
       },
       {
         path: '/problemItem',

+ 5 - 7
src/utils/globalMixins.js

@@ -12,11 +12,6 @@ export default {
     /** 组件中设置dicts数组,会将字典存储在vuex中*/
     if(this.dicts && this.dicts.length > 0){
       this.setDicts()
-      // this.dicts.forEach(item=>{
-      //   this.getDictHandler(item,(res)=>{
-      //     this[item] = res
-      //   })
-      // })
     }
   },
   methods: {
@@ -27,21 +22,24 @@ export default {
       })
     },
     /** 获取字典值
+     * key: String 字典类型
      * 组件页面中需要设置:mapGetters(['dictionary']']),
      * */
     getDictItem(key){
       let item = this.dictionary.find((v)=>{
         return  v.key === key
       })
-      return item.value
+      console.log(item,'item')
+      return item?.value
     },
+    //查询字典具体类型的中的某一项
     getDictLabel(key,dictType){
       let item = this.dictionary?.find((v)=>{
         return  v.key === dictType
       })
       let dictLabel = item?.value?.find(v=>{
         if( v.dictValue == key){
-          return v.dictLabel
+          return v?.dictLabel
         }
       })
       return dictLabel?.dictLabel

+ 2 - 2
src/views/home/menu.vue

@@ -2,7 +2,7 @@
   <div class="menu-container">
     <top-bar></top-bar>
     <!-- 天气预警 -->
-    <van-swipe style="height: 50px" vertical autoplay="2000">
+    <van-swipe v-if="list.length > 0" style="height: 50px" vertical autoplay="2000">
       <van-swipe-item v-for="item in list" :key="item.id" @click="clickHandler(item)">
         <div class="color" :style="{ color: item.bgc, backgroundColor: '#fff' }">
           <van-icon name="warn-o" /> {{ item.alarmTitle }}
@@ -28,7 +28,7 @@
       </div>
     </div>
     <van-dialog v-model="show" title="标题" confirmButtonText="关闭">
-      
+
       <p class="text">
         {{ info }}
       </p>

+ 3 - 3
src/views/menu/LZRegister/edit.vue

@@ -159,9 +159,9 @@
         </div >
         <p v-if="enable" class="warning-msg">需要完成所有区域的履职内容才能提交内容</p>
         <div v-if="enable" class="flex-box">
-          <van-button type="default" style="width: 28%;" plain  @click="goBack">取消</van-button>
-          <van-button type="info" style="width: 28%;" plain hairline @click="saveData">保存</van-button>
-          <van-button type="info" style="width: 28%;"  @click="submitData">提交</van-button>
+          <van-button type="default" style="width: 30%;" plain  @click="goBack">取消</van-button>
+          <van-button type="info" style="width: 30%;" plain hairline @click="saveData">保存</van-button>
+          <van-button type="info" style="width: 30%;"  @click="submitData">提交</van-button>
         </div>
       </fieldset>
     </div>

+ 42 - 22
src/views/menu/problemItem/detail.vue

@@ -37,18 +37,18 @@
       <div class="card" v-if="taskInfo.confirm" >
         <van-panel title="处理">
           <div class="panel-box">
-            <van-cell title="确认结果" :label="taskInfo.confirm.executeStatus === 0 ? '确认' : '提出异议'"></van-cell>
-            <van-cell title="确认人" :label="taskInfo.confirm.executorName"></van-cell>
-            <van-cell v-show="taskInfo.confirm.executeStatus===1" title="审核结果" :label="taskInfo.confirm.description"></van-cell>
+            <van-cell title="处理意见" :label="taskInfo.confirm.executeStatus === 0 ? '确认' : '提出异议'"></van-cell>
+            <van-cell v-show="taskInfo.confirm.executeStatus===1" title="异议内容" :label="taskInfo.confirm.description"></van-cell>
+            <van-cell title="异议人" :label="taskInfo.confirm.executorName"></van-cell>
           </div>
         </van-panel>
       </div>
 
       <div class="card" v-if="taskInfo.confirmDissent" >
-        <van-panel title="审">
+        <van-panel title="审">
           <div class="panel-box">
             <van-cell title="审核结果" :label="taskInfo.confirmDissent.executeStatus === 0 ? '同意' : '不同意'"></van-cell>
-            <van-cell title="审核人" :label="taskInfo.confirmDissent.executorName"></van-cell>
+<!--            <van-cell title="审核人" :label="taskInfo.confirmDissent.executorName"></van-cell>-->
             <van-cell v-show="taskInfo.confirmDissent.executeStatus===1" title="原因" :label="taskInfo.confirmDissent.description"></van-cell>
           </div>
         </van-panel>
@@ -57,13 +57,13 @@
       <div class="card" v-if="taskInfo.reform" >
         <van-panel title="整改">
           <div class="panel-box">
-            <van-cell title="整改期" :label="formatDate(taskInfo.reform.executeTime,'YYYY-MM-DD')"></van-cell>
-            <van-cell title="审核结果" :label="taskInfo.reform.executeStatus === 0 ? '已整改' : '未整改'"></van-cell>
-            <van-cell title="审核结果" :label="taskInfo.reform.description"></van-cell>
+            <van-cell title="整改期" :label="formatDate(taskInfo.reform.executeTime,'YYYY-MM-DD')"></van-cell>
+<!--            <van-cell title="审核结果" :label="taskInfo.reform.executeStatus === 0 ? '已整改' : '未整改'"></van-cell>-->
+            <van-cell title="整改描述" :label="taskInfo.reform.description"></van-cell>
             <div class="upload-box" v-if="taskInfo.reform.images?.length > 0">
               <van-cell>
-                <div class="nfc-img van-hairline--surround" v-for="(v,i) in taskInfo.reform.images" :key="v.url" @click="clickImage(taskInfo.reform.images,i)">
-                  <img :src="imgUrl(v.url)" alt="" >
+                <div class="nfc-img van-hairline--surround" v-for="(v,i) in taskInfo.reform.images" :key="v" @click="clickImage(taskInfo.reform.images,i)">
+                  <img :src="imgUrl(v)" alt="" >
                 </div>
               </van-cell>
             </div>
@@ -80,19 +80,19 @@
               <van-cell-group>
                 <van-cell title="确认情况" clickable>
                   <template #right-icon>
-                    <van-radio :name="1" />
+                    <van-radio :name="0" />
                   </template>
                 </van-cell>
                 <van-cell title="提出异议" clickable>
                   <template #right-icon>
-                    <van-radio :name="0" />
+                    <van-radio :name="1" />
                   </template>
                 </van-cell>
               </van-cell-group>
             </van-radio-group>
 
             <van-field
-              v-show="!confirmData.status"
+              v-show="confirmData.status"
               v-model="confirmData.description"
               rows="1"
               autosize
@@ -113,19 +113,19 @@
               <van-cell-group>
                 <van-cell title="同意" clickable>
                   <template #right-icon>
-                    <van-radio :name="1" />
+                    <van-radio :name="0" />
                   </template>
                 </van-cell>
                 <van-cell title="不同意" clickable>
                   <template #right-icon>
-                    <van-radio :name="0" />
+                    <van-radio :name="1" />
                   </template>
                 </van-cell>
               </van-cell-group>
             </van-radio-group>
 
             <van-field
-              v-show="!confirmDissentData.status"
+              v-show="confirmDissentData.status"
               v-model="confirmDissentData.description"
               rows="1"
               autosize
@@ -142,7 +142,7 @@
       <div class="card" v-if="type === 'reform'">
         <van-panel title="整改">
           <div class="panel-box">
-            <select-cell required  title="整改期限" v-model="reformData.reformDate"  :data-list="getDictItem('rectification_deadline')" />
+            <date-cell required  title="整改日期" v-model="reformData.reformDate" dateType="date" />
             <van-field
               required
               v-model="reformData.description"
@@ -154,7 +154,7 @@
             <div class="upload-box" >
               <uploader :maxCount="5" v-model="reformData.images"/>
             </div>
-            <div class="big-btn-box" v-if="taskInfo.orgId==orgId && taskInfo.confirmStatus==2 && taskInfo.reformStatus==10">
+            <div class="big-btn-box" v-if="taskInfo.orgId==orgId && taskInfo.confirmStatus==2 && taskInfo.reformStatus!=11">
               <van-button  type="info" size="large"  @click="onSubmit('整改')">提交</van-button>
             </div>
           </div>
@@ -214,7 +214,7 @@ export default {
     formatDate,
     //图片预览
     clickImage(arr,i){
-      this.preViewImages.images = arr.map(v=>imgUrl(v.imgPath));
+      this.preViewImages.images = arr.map(v=>imgUrl(v));
       this.preViewImages.startPosition = i;
       ImagePreview(this.preViewImages);
     },
@@ -234,8 +234,16 @@ export default {
           data = this.reformData;
           queryMethod = reform;
       }
-      if(!data.reformDate || !data.description){
-        return this.$toast("请填写完整信息");
+      if(type === '确认' || type === '审核'){
+        if(!data.description) {
+          return this.$toast("请填写完整信息");
+        }
+      }else {
+        if(!data.reformDate || !data.description){
+          return this.$toast("请填写完整信息");
+        }
+        let img = data.images.map(v=>{return v.imgPath});
+        data.images = img.toString();
       }
       data.id = this.taskInfo.id;
       queryMethod(data).then((r) => {
@@ -282,6 +290,15 @@ export default {
   }
 }
 </script>
+
+<style lang="scss">
+//.question-edit{
+//  .van-panel__header{
+//    color:red
+//  }
+//}
+
+</style>
 <style lang="scss" scoped>
 
 .question-edit{
@@ -289,7 +306,7 @@ export default {
   overflow: hidden;
 }
 .page-container{
-  height: calc(100vh - 100px);
+  height: calc(100vh - 194px);
   overflow: auto;
   padding: 20px;
 }
@@ -305,6 +322,9 @@ export default {
   margin-bottom: 20px;
   box-shadow: 0 10px 10px #eaeaea;
 }
+.card:last-child{
+  margin-bottom: 0;
+}
 .panel-box{
   padding:0 20px;
 }

+ 74 - 64
src/views/menu/problemItem/index.vue

@@ -3,70 +3,70 @@
     <NavBar />
     <div class="page-container">
       <van-search v-model="query.searchKey" class="van-hairline--bottom" placeholder="请输入搜索关键词" />
-      <org-tree v-model="query.orgId"  @change="getDataList"></org-tree>
+      <org-tree v-model="query.orgId"  @change="refreshData"></org-tree>
       <div class="search-flex">
-        <select-cell class="van-hairline--right" title="确认状态" v-model="query.confirmStatus" :data-list="getDictItem('question_confirm_status')" @change="getDataList"/>
-        <date-cell title="发现日期"  v-model="query.submitTime" date-type="date" @change="getDataList"/>
+        <select-cell class="van-hairline--right" title="确认状态" v-model="query.confirmStatus" :data-list="getDictItem('question_confirm_status')" @change="refreshData"/>
+        <date-cell title="发现日期"  v-model="query.submitTime" date-type="date" @change="refreshData"/>
       </div>
       <div class="card-list">
-        <van-list
-          v-model="loading"
-          :finished="finished"
-          finished-text="没有更多了"
-          @load="getDataList"
-        >
-          <van-empty description="暂无数据" v-if="!dataList || dataList.length === 0" />
-            <template v-else>
-              <van-cell-group  v-for="(v,i) in dataList">
-                <van-cell :title="v.orgName">
-                  <template #extra>
-                    <van-button
-                      style="width: 60px;"
-                      v-if="v.orgId==orgId && v.confirmStatus==0"
-                      hairline
-                      size="mini"
-                      type="info"
-                      @click.stop="clickItem(v.id,'confirm')">
-                      隐患确认
-                    </van-button>
-                    <van-button
-                      style="width: 60px;"
-                      v-if="v.submitorId== id && v.confirmStatus==1"
-                      hairline
-                      size="mini"
-                      type="info"
-                      @click.stop="clickItem(v.id,'confirmDissent')">
-                      异议审批
-                    </van-button>
-                    <van-button
-                      style="width: 60px;"
-                      v-if="v.orgId==orgId && v.confirmStatus==2 && v.reformStatus==10"
-                      hairline
-                      size="mini"
-                      type="info"
-                      @click.stop="clickItem(v.id,'reform')">
-                      整改
-                    </van-button>
-                    <van-button
-                      style="width: 60px;"
-                      v-if="v.confirmStatus ===3"
-                      hairline
-                      size="mini"
-                      type="info"
-                      @click.stop="clickItem(v.id,'detail')">
-                      详情
-                    </van-button>
-                  </template>
-                  <template #label>
-                    <div class="info-box">
-                      <div class="info-desc">隐患描述:<span>{{v.questionDesc}}</span></div>
-                      <div class="info-item">发现日期:<span>{{v.submitTime}}</span></div>
-                    </div>
-                  </template>
-                </van-cell>
-              </van-cell-group>
-            </template>
-        </van-list>
+        <van-empty description="暂无数据" v-if="!dataList || dataList.length === 0" />
+        <Scroll
+          v-else
+          @pulldown="refreshData"
+          @pullup="getDataList"
+          :data='dataList'
+          :pullup="pullup"
+          class="wrapper"
+          ref="wrapper">
+            <van-cell-group  v-for="(v,i) in dataList">
+              <van-cell :title="v.orgName">
+                <template #extra>
+                  <van-button
+                    style="width: 60px;"
+                    v-if="v.orgId==orgId && v.confirmStatus==0"
+                    hairline
+                    size="mini"
+                    type="info"
+                    @click.stop="clickItem(v.id,'confirm')">
+                    隐患确认
+                  </van-button>
+                  <van-button
+                    style="width: 60px;"
+                    v-if="v.submitorId== id && v.confirmStatus==1"
+                    hairline
+                    size="mini"
+                    type="info"
+                    @click.stop="clickItem(v.id,'confirmDissent')">
+                    异议审批
+                  </van-button>
+                  <van-button
+                    style="width: 60px;"
+                    v-if="v.orgId==orgId && v.confirmStatus==2 && v.reformStatus!=11"
+                    hairline
+                    size="mini"
+                    type="info"
+                    @click.stop="clickItem(v.id,'reform')">
+                    整改
+                  </van-button>
+                  <van-button
+                    style="width: 60px;"
+                    v-if="v.confirmStatus ===3"
+                    hairline
+                    size="mini"
+                    type="info"
+                    @click.stop="clickItem(v.id,'detail')">
+                    详情
+                  </van-button>
+                </template>
+                <template #label>
+                  <div class="info-box">
+                    <div class="info-desc">隐患描述:<span>{{v.questionDesc}}</span></div>
+                    <div class="info-item">发现日期:<span>{{v.submitTime}}</span></div>
+                  </div>
+                </template>
+              </van-cell>
+            </van-cell-group>
+        </Scroll>
       </div>
     </div>
   </div>
@@ -74,15 +74,17 @@
 <script>
 import NavBar from '@/components/NavBar'
 import OrgTree from '@/components/orgTree'
+import Scroll from '@/components/scroll/scroll'
 import dateCell from '@/components/dateCell'
 import selectCell from '@/components/selectCell'
-import {dataList,planList} from './api'
+import {dataList} from './api'
 import {mapGetters} from "vuex";
 import {formatDate} from "@/filters/filter";
 export default {
   components: {
     NavBar,
     OrgTree,
+    Scroll,
     dateCell,
     selectCell
   },
@@ -92,7 +94,7 @@ export default {
         submitTime:null,
         orgId:null,
         confirmStatus:'0',
-        pageSize:20,
+        pageSize:10,
         pageNum:1,
       },
       planList:[],
@@ -115,6 +117,7 @@ export default {
         { field: "finishRate", key: "d", title: "完成率", align: "center" },
       ],
       dataList:[],
+      pullup:false,
       dicts:['question_confirm_status','question_reform_status']
     }
   },
@@ -125,6 +128,12 @@ export default {
     ...mapGetters(['orgId','id','dictionary']),
   },
   methods: {
+    refreshData(){
+      this.query.pageNum = 1;
+      this.pullup = false;
+      this.dataList = [];
+      this.getDataList();
+    },
     //初始化数据
     initData(){
       this.query.orgId = this.orgId;
@@ -138,6 +147,7 @@ export default {
       }
       if(!this.query.orgId) return this.$toast('请选择机构');
       dataList(data).then(res=>{
+        this.loading = false;
         this.dataList = [...this.dataList,...res.rows];
         this.query.pageNum = res.pageNum;
       })
@@ -176,7 +186,7 @@ export default {
 }
 .card-list{
   padding: 20px;
-  height: calc(100vh - 420px);
+  height: calc(100vh - 518px);
   overflow:  auto;
 }
 .card-num{

+ 134 - 0
src/views/menu/securityCheckRegister/addCheck.vue

@@ -0,0 +1,134 @@
+<template>
+  <div class="addCheck">
+    <NavBar />
+    <div class="addCheck-container">
+      <div class="search-flex">
+        <van-search v-model="query.key" placeholder="请输入检查子项"  @change="refreshData"/>
+        <select-cell class="van-hairline--right" title="选择检查内容库" v-model="query.ruleId" :dataList="ruleList" :prop="prop" @change="refreshData"/>
+      </div>
+      <div class="card-list">
+        <Scroll
+          @pulldown="refreshData"
+          @pullup="getDataList"
+          :data='dataList'
+          :pullup="pullup"
+          class="wrapper">
+          <van-empty description="暂无数据" v-if="!dataList || dataList.length === 0" />
+          <div  v-else class="list-item">
+            <van-cell
+              :class="{'active':item.checked}"
+              v-for="(item, index) in dataList"
+              clickable
+              :key="item.id"
+              :title="item.itemName"
+              :label="item.pointName"
+              @click="click(item,index)">
+              <template #right-icon>
+                <van-checkbox v-model="item.checked"/>
+              </template>
+            </van-cell>
+          </div>
+        </Scroll>
+      </div>
+      <div>
+        <van-button  type="info" size="large" @click="addItem">确认选中</van-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import NavBar from '@/components/NavBar'
+import SelectCell from '@/components/selectCell'
+import Scroll from '@/components/scroll/scroll'
+import {checkItemList,checkList} from './api'
+export default {
+  name: "addCheck",
+  components: {
+    NavBar,
+    Scroll,
+    SelectCell,
+  },
+  data(){
+    return {
+      id:null,
+      query:{
+        key:'',
+        ruleId:null,
+        pageNum:1,
+        pageSize:2,
+      },
+      dataList:[],
+      ruleList:[],
+      selected:[],
+      prop:{
+        label:'name',
+        value:'id'
+      },
+      pullup:false,
+    }
+  },
+  mounted(){
+    this.id = this.$route.query.id;
+    this.getCheckItem();
+  },
+  methods:{
+    refreshData(){
+      this.query.pageNum = 1;
+      this.pullup = false;
+      this.dataList = [];
+      this.getDataList();
+    },
+    click(v,i){
+      this.$set(this.dataList[i],'checked',!this.dataList[i].checked);
+    },
+    addItem(){
+      this.selected = this.dataList.filter(v=>v.checked);
+      if(this.selected.length === 0) return this.$toast('请选择检查项');
+      sessionStorage.setItem('selected',JSON.stringify(this.selected));
+      this.$router.push({
+        path:'/securityDetail',
+        name:'securityDetail',
+        query:{
+          id:this.id,
+        },
+      })
+    },
+    getCheckItem(){
+      let data = {orgType:4};
+      checkItemList(data).then(res=>{
+        this.ruleList = res.data;
+        this.query.ruleId = res.data[0].id;
+        this.getDataList()
+      })
+    },
+    getDataList(){
+      checkList(this.query).then(res=>{
+        res.rows.forEach(v=>{
+          v.checked = false;
+        });
+        this.query.pageNum === 1 ? this.dataList = res.rows : this.dataList = [...this.dataList,...res.rows];
+        console.log(this.dataList.length,res.total,'this.dataList')
+        if(this.dataList.length < res.total){
+          this.pullup = true;
+          this.query.pageNum++;
+        }else {
+          this.pullup = false;
+        }
+      })
+    },
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.addCheck{
+  .card-list{
+    height: calc(100vh - 424px);
+    overflow: auto;
+  }
+  .active{
+    color:#1989fa;
+  }
+}
+</style>

+ 136 - 0
src/views/menu/securityCheckRegister/addWorker.vue

@@ -0,0 +1,136 @@
+<template>
+  <div class="addWork">
+    <NavBar />
+    <div class="addWork-container">
+      <div class="search-flex">
+        <van-search v-model="query.name" placeholder="请输入姓名"  @change="refreshData"/>
+      </div>
+      <div class="card-list">
+        <Scroll
+          @pulldown="refreshData"
+          @pullup="getDataList"
+          :data='dataList'
+          :pullup="pullup"
+          class="wrapper"
+          ref="wrapper">
+          <van-empty description="暂无数据" v-if="!dataList || dataList.length === 0" />
+          <div v-else class="list-item">
+            <van-cell
+              :class="{'active':item.checked}"
+              v-for="(item, index) in dataList"
+              clickable
+              :key="item.id"
+              :title="item.name"
+              :value="item.orgName"
+              :label="item.phone || '无'"
+              @click="click(item,index)">
+            </van-cell>
+          </div>
+        </Scroll>
+      </div>
+      <div>
+        <van-button :disabled="!selected" type="info" size="large" @click="onSubmit">确认授权</van-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import NavBar from '@/components/NavBar'
+import Scroll from '@/components/scroll/scroll'
+import {workerList,accredit} from './api'
+export default {
+  components: {
+    NavBar,
+    Scroll,
+  },
+  data(){
+    return {
+      query:{
+        name:'',
+        orgId:null,
+        checkSub:true,
+        pageNum:1,
+        pageSize:10
+      },
+      formData:{
+        planId:null,
+        beCheckedOrgId:null,
+        taskId:null,
+        ymdDate:null,
+        userId:null,
+      },
+      dataList:[],
+      ruleList:[],
+      selected:null,
+      prop:{
+        label:'name',
+        value:'id'
+      },
+      pullup:false,
+    }
+  },
+  mounted(){
+    console.log(this.$route,'this.$route')
+    this.query.orgId = this.$route.query.orgId;
+    this.formData.planId = this.$route.query.planId;
+    this.formData.beCheckedOrgId = this.$route.query.beCheckedOrgId;
+    this.formData.taskId = this.$route.query.taskId;
+    this.formData.ymdDate = this.$route.query.ymdDate;
+    this.getDataList();
+  },
+  methods:{
+    onSubmit(){
+      this.formData.userId = this.selected;
+      accredit(this.formData).then(res=>{
+        this.$toast('授权成功');
+        this.$router.go(-2);
+      })
+    },
+    click(v,i){
+      this.dataList.forEach(v=>v.checked = false);
+      this.$set(this.dataList[i],'checked',!this.dataList[i].checked);
+      this.selected = v.id;
+    },
+    refreshData(){
+      this.query.pageNum = 1;
+      this.pullup = false;
+      this.dataList = [];
+      this.getDataList();
+    },
+    getDataList(){
+      workerList(this.query).then(res=>{
+        res.data.rows.forEach(v=>{
+          v.checked = false;
+        });
+        this.dataList = res.data.rows;
+      })
+    },
+  }
+}
+</script>
+<style lang="scss">
+.addWork{
+  .active{
+    color:#1989fa;
+    .van-cell__value{
+      color:#1989fa;
+    }
+  }
+}
+</style>
+<style lang="scss" scoped>
+.addWork{
+  .card-list{
+    height: calc(100vh - 300px);
+    overflow: auto;
+  }
+  .list-item{
+    padding:20px;
+  }
+  .active{
+    color:#1989fa;
+    border-left: 5px solid #1989fa;
+  }
+}
+</style>

+ 42 - 11
src/views/menu/securityCheckRegister/api.js

@@ -1,38 +1,69 @@
 import request from "@/utils/request";
 //获取列表
-export function dataList(params) {
+export function dataList(data) {
   return request({
     url: "/core/safetycheck/register/page",
-    method: "get",
-    params,
+    method: "post",
+    data,
   });
 }
 
 //获取详情
 export function registerDetail(id){
   return request({
-    url: "/core/safetycheck/register/"+id,
+    url: "/core/safetycheck/register/app/"+id,
     method: "get",
   });
 }
 
-//查询机构可用的规范
+//保存提交
 export function registerSubmit(data){
   return request({
-    url: "/core/safetycheck/register/submit",
+    url: "/core/safetycheck/register/appsubmit",
     method: "post",
     data
   });
 }
 
-//查询授权
-export function registerGrant(data){
+//查询角色
+export function registerRole(orgId){
   return request({
-    url: "/core/safetycheck/register/grant",
-    method: "post",
-    data
+    url: "/system/role/getnamesbyorgid/"+orgId,
+    method: "get",
   });
 }
 
+//获取检查内容库
+export function checkItemList(params){
+  return request({
+    url: "/core/safetycheck/rule/ruleListForOrg",
+    method: "get",
+    params
+  });
+}
+//
+export function checkList(params){
+  return request({
+    url: "/core/safetycheck/ruleItem/pointSelectionPage",
+    method: "get",
+    params
+  });
+}
 
+//授权人员列表
+export function workerList(params){
+  return request({
+    url: "/system/user/list",
+    method: "get",
+    params
+  });
+}
 
+//授权提交
+export function accredit(data){
+  return request({
+    url: "/core/safetycheck/register/grant",
+    method: "post",
+    data
+  });
+}

+ 441 - 0
src/views/menu/securityCheckRegister/detail.vue

@@ -0,0 +1,441 @@
+<template>
+  <div class="register-edit">
+    <nav-bar></nav-bar>
+    <div class="page-container">
+      <!--   基本信息   -->
+      <div class="card" v-if="taskInfo">
+        <van-panel :title="taskInfo.taskName"  :status="getDictLabel(taskInfo.status,'safety_check_status')">
+          <van-cell title="日期时间" :value="rangDate(taskInfo.planstarttime,taskInfo.planendtime)" />
+          <van-cell title="受检机构" :value="taskInfo.beCheckedOrgName" />
+          <van-field
+            :disabled="!enable"
+            v-model="taskInfo.checkTeam"
+            label="检查组成员"
+            rows="2"
+            autosize
+            type="textarea"
+            placeholder="请输入" />
+        </van-panel>
+      </div>
+
+
+      <!--  检查项目    -->
+      <fieldset class="fieldset"  :disabled="!enable">
+        <div class="card" >
+          <p class="legend">检查项目 <span v-if="enable" @click="addCheck">添加检查内容</span></p>
+          <van-collapse v-model="activeNames" v-for="v in checkList" :key="v.itemId">
+            <van-collapse-item :title="v.itemName" :name="v.itemName" >
+              <div v-for="(item,index) in v.pointList" :key="item.pointId">
+                <van-cell :title="item.pointName">
+                  <template #right-icon>
+                    <img v-if="enable && item.nfcList.length > 0" :src="require('../../../assets/svg/NFC.svg')" class="nfc-icon" @click="clickNFC(item.nfcList)"/>
+                    <van-switch
+                      v-if="enable"
+                      style="margin-left: 10px;"
+                      v-model="item.status"
+                      :active-value="1"
+                      :inactive-value="0"
+                      inactive-color="#4fc08d"
+                      active-color="#ee0a24"
+                      @change="switchChange(item)"
+                      size="20" />
+                    <span v-else>
+                      <van-tag v-if="item.status" type="warning">隐患</van-tag>
+                      <van-tag v-else type="success">正常</van-tag>
+                    </span>
+                  </template>
+                </van-cell>
+                <van-cell-group v-show="item.status">
+                  <van-cell v-show="item.nfcList.length > 0" :border="false" >
+                    <div v-if="img.img" class="nfc-img" v-for="(img,i) in item.nfcList" :key="img.img" @click="preViewNFC(i)">
+                      <img :src="imgUrl(img.img)" alt="" >
+                      <span>{{img.checkName}}</span>
+                    </div>
+                  </van-cell>
+                  <select-cell required :disabled="!enable" title="整改期限" v-model="item.rectificationDeadline"  :data-list="dayList" />
+                  <van-field
+                    required
+                    v-model="item.remark"
+                    rows="1"
+                    autosize
+                    label="情况描述:"
+                    type="textarea"
+                    placeholder="请输入"/>
+                  <div class="upload-box" >
+                    <uploader :maxCount="5" v-if="enable" v-model="item.imgData"/>
+                    <van-cell v-else>
+                      <div class="nfc-img van-hairline--surround" v-for="(v,i) in item.imgData" :key="v.imgPath" @click="clickWarnImage(item.imgData,i)">
+                        <img :src="imgUrl(v.imgPath)" alt="" >
+                        <span>{{v.checkName}}</span>
+                      </div>
+<!--                      <img class="nfc-img" v-for="v in item.imgData" :src="imgUrl(v.imgPath)" alt="" :key="v.id">-->
+                    </van-cell>
+                  </div>
+                </van-cell-group>
+                <date-cell
+                  :disabled="!enable"
+                  v-if="item.businessType === 1"
+                  v-for="(val,ind) in item.protectionVo"
+                  :title="val.protectionName"
+                  v-model="val.statusUpdateTime"
+                  :key="val.id"
+                  date-type="datetime" />
+              </div>
+            </van-collapse-item>
+          </van-collapse>
+        </div >
+
+        <div v-if="enable" class="flex-box">
+          <van-button type="default" style="width: 30%;" plain  @click="accredit">授权</van-button>
+          <van-button type="info" style="width: 30%;" plain hairline @click="saveData">保存</van-button>
+          <van-button type="info" style="width: 30%;"  @click="submitData">提交</van-button>
+        </div>
+      </fieldset>
+    </div>
+
+<!--    <van-image-preview v-model="showPreView" :images="preViewImages.images" :startPosition="preViewImages.startPosition">-->
+<!--      <template v-slot:index>第{{ index }}页</template>-->
+<!--    </van-image-preview>-->
+
+    <!--  nfc弹窗  -->
+    <nfc-popup v-if="enable" ref="NfcPopup" @change="changeNfcImg"></nfc-popup>
+  </div>
+</template>
+
+<script>
+import NavBar from '@/components/NavBar';
+import SelectCell from '@/components/selectCell';
+import DateCell from '@/components/dateCell';
+import Uploader from '@/components/upload/uploader';
+import NfcPopup from '@/components/nfcPopup/more';
+import {registerDetail,registerSubmit} from "./api";
+import {formatDate} from "@/filters/filter";
+import {getDict} from "@/api/toConsult";
+import {imgUrl} from "@/utils";
+import { ImagePreview } from 'vant';
+import {mapGetters} from "vuex";
+import taskInfo from "@/views/menu/monitoringCall/components/taskInfo";
+export default {
+  name:'securityDetail',
+  components:{NavBar,SelectCell,DateCell,Uploader,NfcPopup},
+  data(){
+    return {
+      id:null,
+      activeNames: ['1'],
+      //基本信息
+      taskInfo:[],
+      NFCList:[],
+      //区域下检查内容列表
+      checkList:[],
+      //检查内容具体项列表
+      checkItemList:[],
+      //nfc扫描数量
+      NFCNum:0,
+      //所有检查项数量
+      allCheckNum:0,
+      //区域下检查项数量
+      checkNum:0,
+      //nfc图片
+      nfcImage:[],
+      enable:false,
+      stateList:[],
+      dayList:[],
+      preViewImages:{
+        images:[],
+        startPosition:0
+      },
+      dicts:['safety_check_status'],
+      showPreView:false,
+      selected:null,
+    }
+  },
+  beforeRouteEnter: (to, from, next) => {
+    if(from.name === 'addCheck'){
+      let str = sessionStorage.getItem('selected') ;
+      next(vm => {
+        vm.selected = JSON.parse(str);
+        sessionStorage.removeItem('selected');
+      })
+    }
+    next()
+  },
+  watch:{
+    selected:{
+      handler(val){
+        console.log(val,'val')
+        if(!val)return
+
+        val.forEach((valItem) => {
+          // 查找是否有与 valItem.itemId 相同的项
+          const existingItem = this.checkList.find((checkItem) => checkItem.itemId === valItem.itemId);
+
+          if (existingItem) {
+            // 如果存在相同 itemId 的项,查找 pointList 是否有与 valItem.pointId 相同的项
+            const existingPoint = existingItem.pointList.find((pointItem) => pointItem.pointId === valItem.id);
+
+            if (!existingPoint) {
+              console.log(existingItem,'point添加成功')
+              // 如果不存在相同 pointId 的项,将 valItem 添加到 pointList 中
+              existingItem.pointList.push({
+                pointId: valItem.id,
+                pointName: valItem.pointName,
+                mustCheck: valItem.checked ? 1 : 0,
+              });
+            }
+          } else {
+            console.log(valItem,'item添加成功')
+            // 如果不存在相同 itemId 的项,创建一个新的项并添加到 checkList 数组中
+            this.checkList.push({
+              itemId: valItem.itemId,
+              itemName: valItem.itemName,
+              pointList: [valItem],
+            });
+          }
+        });
+      },
+      deep:true
+    },
+  },
+  computed:{
+    ...mapGetters(['dictionary'])
+  },
+  created() {
+    getDict( 'resumption_status' ).then(res => {
+      let { data } = res
+      this.stateList = data;
+    })
+    getDict( 'rectification_deadline' ).then(res => {
+      let { data } = res
+      this.dayList = data;
+    })
+  },
+  mounted() {
+    this.id = this.$route.query.id;
+    this.getData();
+  },
+  methods:{
+    addCheck(){
+      this.$router.push({path:'/addCheck',query:{id:this.id}});
+    },
+    clickWarnImage(arr,i){
+      this.preViewImages.images = arr.map(v=>imgUrl(v.imgPath));
+      this.preViewImages.startPosition = i;
+      ImagePreview(this.preViewImages)
+    },
+    preViewNFC(i){
+      this.preViewImages.images = this.nfcImage.map(v=>imgUrl(v.img));
+      this.preViewImages.startPosition = i;
+      ImagePreview(this.preViewImages)
+    },
+    getDicts(s){
+      return this.stateList.find(v=> s == v.dictValue)?.dictLabel;
+    },
+    //初始化数据
+    getData() {
+      let taskId = this.$route.query.id;
+      registerDetail(taskId).then(res=>{
+        console.log(res,'res')
+        this.taskInfo = res.data;
+        this.enable = this.taskInfo.status === 1 || this.taskInfo.status === 2; //是否可编辑
+        this.checkList = res.data.checkList;
+        //设置默认展开项
+        this.activeNames = this.checkList.map(v=>v.itemName);
+      })
+    },
+    //保存数据
+    saveData(){
+      //验证必填项
+      let pointData = [];
+      this.checkList.forEach(v=>{
+        v.pointList.forEach(item=>{
+          pointData.push(item);
+        })
+      })
+      let arr = pointData.filter(v=>{
+        if(v.status === 1 ){
+          return !v.remark || !v.rectificationDeadline
+        }
+      })
+      if(arr.length) return this.$toast(`${arr[0].itemName}:该信息不完整请填写`);
+      //console.log( this.taskInfo,' this.taskInfo')
+      this.taskInfo.isSubmit = 0;
+      registerSubmit(this.taskInfo).then(res=>{
+        this.$toast('保存成功');
+        this.$router.go(-1);
+      })
+    },
+
+    //提交数据
+    submitData(){
+      //验证必填项
+      let pointData = [];
+      this.checkList.forEach(v=>{
+        v.pointList.forEach(item=>{
+          pointData.push(item);
+        })
+      })
+      let arr = pointData.filter(v=>{
+        if(v.status === 1 ){
+          return !v.remark || !v.rectificationDeadline
+        }
+      })
+      if(arr.length) return this.$toast(`${arr[0].itemName}:该信息不完整请填写`);
+      //console.log( this.taskInfo,' this.taskInfo')
+      this.taskInfo.isSubmit = 1;
+      registerSubmit(this.taskInfo).then(res=>{
+        this.$toast('提交成功');
+        this.$router.go(-1);
+      })
+    },
+
+    //授权
+    accredit(){
+      let {checkOrgId,ymdDate,planId,beCheckedOrgId,id } = this.taskInfo;
+      console.log(checkOrgId,'checkOrgId')
+      this.$router.push({
+        path: '/addWorker',
+        query:{
+          orgId:checkOrgId,
+          ymdDate,
+          planId,
+          beCheckedOrgId,
+          taskId:id
+        }
+      });
+    },
+    //点击NFC图标
+    clickNFC(arr){
+      //if(arr.length === 0) return;
+      // let arr = this.selectArea.nfclist.filter(item=>{
+      //   return item.status == 0;
+      // })
+      this.$refs.NfcPopup.show(arr);
+    },
+    //清空数据
+    clearData(){
+      this.areaList = [];
+      this.taskInfo= [];
+      this.selectArea = [];
+      this.NFCList = [];
+      this.checkList = [];
+      this.checkItemList = [];
+      this.NFCNum = 0;
+      this.enable = false;
+    },
+    //切换开关时添加操作时间
+    switchChange(item){
+      console.log(item,'666')
+      item.resTime = formatDate(new Date());
+    },
+    //添加图片时的回调
+    changeNfcImg(imgItem){
+      console.log(imgItem,this.selectArea.nfclist,'imgItem')
+      this.selectArea.nfclist.forEach(v=>{
+        if(v.nfccdoe === imgItem.nfcCode){
+          v.img = imgItem.url;
+          v.status = 1;
+          v.scanMethod = 1;
+          this.nfcImage.push(v);
+        }
+      })
+      console.log( this.selectArea.nfclist,this.nfcImage,'nfcObj')
+    },
+  }
+}
+</script>
+<style lang="scss" scoped>
+  .register-edit{
+    height: 100%;
+    overflow: hidden;
+    .page-container{
+      height: calc(100vh - 194px);
+      overflow: auto;
+      padding: 20px;
+    }
+    .flex-box{
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      >span{
+        margin: 0 20px;
+      }
+    }
+    .legend{
+      background-color: #fff;
+      padding: 0 20px;
+      height: 80px;
+      line-height: 80px;
+      font-size: 30px;
+      display: flex;
+      justify-content: space-between;
+      >span{
+        color: orange;
+      }
+    }
+    .card{
+      margin-bottom: 20px;
+      box-shadow: 0 10px 10px #eaeaea;
+    }
+    .check-area{
+      background-color: #f1f1f1;
+      margin: 10px;
+      padding:20px;
+      color:#aaa;
+      border-radius: 6px;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      box-shadow: 0 2px 6px #ddd;
+    }
+    .nfc-icon{
+      width: 50px;
+      height: 50px;
+      margin-left: 20px;
+    }
+    .custom-title {
+      align-self: center;
+      vertical-align: middle;
+    }
+    .upload-box{
+      margin: 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;
+        bottom: 0;
+        left: 0;
+        display: block;
+        width: 100%;
+        background-color: rgba(0,0,0,.2 );
+        color: #eaeaea;
+        font-size: 20px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        line-height: 30px;
+        height: 30px;
+      }
+    }
+  }
+</style>

+ 199 - 104
src/views/menu/securityCheckRegister/index.vue

@@ -3,58 +3,112 @@
     <NavBar />
     <div class="statistics-container">
       <!--   搜索   -->
-      <van-collapse v-model="active">
-        <van-collapse-item title="搜索条件" name="1">
-          <div class="org-line van-hairline--bottom">
-            <van-row>
-              <van-col span="5">
-                <div class="org-label">检查机构</div>
-              </van-col>
-              <van-col span="19">
-                <org-tree v-model="query.checkOrgId" @change="getDataList"></org-tree>
-              </van-col>
-            </van-row>
-          </div>
-          <div class="org-line van-hairline--bottom">
-            <van-row>
-              <van-col span="5">
-                <div class="org-label">受检机构</div>
-              </van-col>
-              <van-col span="19">
-                <org-tree v-model="query.beCheckedOrgId" @change="getDataList"></org-tree>
-              </van-col>
-            </van-row>
-          </div>
-          <div class="search-box van-hairline--bottom">
-            <select-cell title="检查角色" v-model="query.roldIds" :dataList="planList" :prop="prop" @change="getDataList"/>
-          </div>
-          <div class="search-box van-hairline--bottom">
-            <select-cell title="状态" v-model="query.planId" :dataList="planList" :prop="prop" @change="getDataList"/>
-            <date-cell title="截止日期"  v-model="query.taskTime" date-type="date" @change="getDataList"/>
-          </div>
-        </van-collapse-item>
-      </van-collapse>
+      <div style="background-color: #fff;">
+        <div class="org-line van-hairline--bottom">
+          <van-row>
+<!--            <van-col span="5">-->
+<!--              <div class="org-label">检查机构</div>-->
+<!--            </van-col>-->
+            <van-col span="24">
+              <org-tree v-model="query.checkOrgId" placeholder="选择检查机构" @change="refreshData"></org-tree>
+            </van-col>
+          </van-row>
+        </div>
+        <div class="org-line van-hairline--bottom">
+          <van-row>
+<!--            <van-col span="5">-->
+<!--              <div class="org-label">受检机构</div>-->
+<!--            </van-col>-->
+            <van-col span="24">
+              <org-tree v-model="query.beCheckedOrgId" clearable placeholder="选择受检机构" @change="refreshData"></org-tree>
+            </van-col>
+          </van-row>
+        </div>
+      </div>
+
+      <div class="van-hairline--bottom">
+        <search-select-cell title="检查角色" v-model="query.roldIds" :dataList="rolesList" :prop="prop" @change="refreshData"/>
+      </div>
+      <div class="van-hairline--bottom">
+        <date-cell title="检查日期"  v-model="query.taskTime" date-type="date" @change="refreshData"/>
+<!--        <select-cell title="状态" v-model="query.state" :dataList="getDictItem('safety_check_status')" @change="getDataList"/>-->
+      </div>
 
       <div class="card-list">
-        <k-list :list="dataList" :params="query" :auto="false" ref="list" >
-          <template slot-scope="{ data }">
-            <van-cell-group>
-              <van-cell :title="data.orgName" >
-                <template #extra>
-                  <div class="card-num">
-                    {{data.finishRate}}
-                  </div>
-                </template>
-                <template #label>
-                  <div class="flex-box">
-                    <div>应培训数:{{data.shouldFinish}}</div>
-                    <div>已培训数:{{data.finish}}</div>
-                  </div>
-                </template>
-              </van-cell>
-            </van-cell-group>
-          </template>
-        </k-list>
+        <Scroll
+          @pulldown="refreshData"
+          @pullup="getDataList"
+          :data='dataList'
+          :pullup="pullup"
+          class="wrapper"
+          ref="wrapper">
+          <van-empty description="暂无数据" v-if="!dataList || dataList.length === 0" />
+          <div  v-else class="list-item">
+            <van-panel v-for="(v,i) in dataList" :title="v.taskName" :desc="`${formatDate(v.planStartTime,'YYYY-MM-DD')}~${formatDate(v.planEndTime,'YYYY-MM-DD')}`" >
+<!--              <van-tabs v-model="active">-->
+<!--                <van-tab title="完成">-->
+<!--                  <van-collapse v-if="v.completed.length > 0" v-model="activeNames" :key="v.planId">-->
+<!--                    <van-collapse-item title="标题1" name="1"  >-->
+<!--                      <van-cell-->
+<!--                        v-for="(a,index) in v.completed" :key="a.taskId"-->
+<!--                        :title="a.beCheckedOrgName"-->
+<!--                        :value="getDictLabel(a.status,'safety_check_status')"-->
+<!--                        :to="{path:path,query:{id:a.taskId,enable:1}}"-->
+<!--                        is-link/>-->
+<!--                    </van-collapse-item>-->
+<!--                  </van-collapse>-->
+<!--                </van-tab>-->
+<!--                <van-tab title="未完成">-->
+<!--                  <van-collapse v-if="v.uncompleted.length > 0" v-model="activeNames" :key="v.planId">-->
+<!--                    <van-collapse-item title="标题1" name="1" >-->
+<!--                      <van-cell-->
+<!--                        v-for="(a,index) in v.uncompleted" :key="a.taskId"-->
+<!--                        :title="a.beCheckedOrgName"-->
+<!--                        :value="getDictLabel(a.status,'safety_check_status')"-->
+<!--                        :to="{path:path,query:{id:a.taskId,enable:1}}"-->
+<!--                        is-link/>-->
+<!--                    </van-collapse-item>-->
+<!--                  </van-collapse>-->
+<!--                </van-tab>-->
+<!--              </van-tabs>-->
+              <van-collapse v-model="activeNames" :key="v.planId">
+                <van-collapse-item name="1" >
+                  <template #title>
+                    <div class="collapse-title">
+                      <div :class="{'active':v.active==1}" @click.stop="changeList(v,1)">完成</div>
+                      <div :class="{'active':v.active==2}" @click.stop="changeList(v,2)">未完成</div>
+                    </div>
+                  </template>
+                    <van-cell
+                      v-if="v.active==1? v.completed.length > 0 : v.uncompleted.length > 0"
+                      v-for="(a,index) in v.active==1? v.completed:v.uncompleted" :key="a.taskId"
+                      :title="a.beCheckedOrgName"
+                      :value="getDictLabel(a.status,'safety_check_status')"
+                      :to="{path:path,query:{id:a.taskId,enable:1}}"
+                      is-link/>
+                </van-collapse-item>
+              </van-collapse>
+            </van-panel>
+          </div>
+
+
+<!--            <van-button type="info" @click="to">详情</van-button>-->
+<!--            <van-cell-group v-for="v in dataList">-->
+<!--              <van-cell :title="v.orgName" >-->
+<!--                <template #extra>-->
+<!--                  <div class="card-num">-->
+<!--                    {{v.finishRate}}-->
+<!--                  </div>-->
+<!--                </template>-->
+<!--                <template #label>-->
+<!--                  <div class="flex-box">-->
+<!--                    <div>应培训数:{{v.shouldFinish}}</div>-->
+<!--                    <div>已培训数:{{v.finish}}</div>-->
+<!--                  </div>-->
+<!--                </template>-->
+<!--              </van-cell>-->
+<!--            </van-cell-group>-->
+        </Scroll>
       </div>
 
     </div>
@@ -64,67 +118,93 @@
 import NavBar from '@/components/NavBar'
 import OrgTree from '@/components/orgTree'
 import KList from '@/components/list'
-import dateCell from '@/components/dateCell'
-import selectCell from '@/components/selectCell'
-import {dataList} from './api'
+import DateCell from '@/components/dateCell'
+import SelectCell from '@/components/selectCell'
+import SearchSelectCell from '@/components/SearchSelectCell'
+import Scroll from '@/components/scroll/scroll'
+import {dataList,registerRole} from './api'
 import {mapGetters} from "vuex";
 import {formatDate} from "@/filters/filter";
 export default {
   components: {
     NavBar,
     OrgTree,
-    dateCell,
-    selectCell,
-    KList
+    DateCell,
+    SelectCell,
+    SearchSelectCell,
+    KList,
+    Scroll
   },
   data() {
     return {
-      active:['1'],
+      activeNames:['1'],
+      //配置子页面路径
+      path:'/securityDetail',
       query:{
-        taskTime:null,
+        taskTime: null,
         checkOrgId:null,
         beCheckedOrgId:null,
         roldIds:null,
+        state:'1',
       },
-      planList:[],
+      rolesList:[],
       prop:{
         label:'name',
         value:'id',
       },
       loading:false,
-      //dataList:[]
+      dataList:[],
+      dicts:['safety_check_status'],
+      //控制上拉加载
+      pullup:false,
+      finishList:[],
+      unfinishedList:[],
     }
   },
   mounted() {
     this.initData();
   },
   computed:{
-    ...mapGetters(['orgId']),
+    ...mapGetters(['orgId','dictionary']),
   },
   watch:{
     'query.checkOrgId':{
       handler(v){
         this.getRoleList();
-      },
-      immediate:true
+      }
     }
   },
   methods: {
-    dataList,
+    formatDate,
+    changeList(item,type){
+      this.$set(item,'active',type);
+    },
+    refreshData(){
+      this.query.pageNum = 1;
+      this.pullup = false;
+      this.dataList = [];
+      this.getDataList();
+    },
     initData(){
       this.query.checkOrgId = this.orgId;
-      this.getPlanList();
+      this.query.taskTime = formatDate(new Date(),'YYYY-MM-DD');
+      this.getDataList();
     },
     getRoleList(){
-
+      registerRole(this.query.checkOrgId).then(res=>{
+        this.rolesList = res.data;
+      })
     },
     getDataList(){
       let data = {
         ...this.query
       }
-      if(!this.query.orgId) return this.$toast('请选择机构');
+      if(!this.query.checkOrgId) return this.$toast('请选择机构');
       dataList(data).then(res=>{
-        this.dataList = res.data;
+        this.dataList = res.rows.map(v=>{
+          v.active = 1
+          return v
+        });
       })
     }
   }
@@ -146,43 +226,58 @@ export default {
 </style>
 <style lang="scss" scoped>
 .check-register{
-
-}
-.org-line{
-  padding-left:30px;
-  background-color: #fff;
-}
-.org-label{
-  height: 90px;
-  width: 100%;
-  display: flex;
-  align-items: center;
-  font-size: 28px;
-}
-.card-list{
-  padding: 20px;
-  height: calc(100vh - 550px);
-  overflow: auto;
-}
-.card-num{
-  display: flex;
-  align-items: center;
-  font-size: 28px;
-  color: #009dff;
-}
-.flex-box{
-  display: flex;
-  align-items: center;
-  >div{
-    margin-right: 40px;
+  .org-line{
+    padding:0 10px;
+    background-color: #fff;
   }
-}
-.search-box{
-display: flex;
-  justify-content: space-between;
-  align-items: center;
-  >div{
-    width: 50%;
+  .org-label{
+    height: 90px;
+    width: 100%;
+    display: flex;
+    align-items: center;
+    font-size: 28px;
+  }
+  .card-list{
+    height: calc(100vh - 580px);
+    overflow: auto;
+  }
+  .list-item{
+    padding: 20px;
+  }
+  .card-num{
+    display: flex;
+    align-items: center;
+    font-size: 28px;
+    color: #009dff;
+  }
+  .collapse-title{
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+    font-size: 28px;
+    color: #ccc;
+    >div{
+      width: 40%;
+      display: flex;
+    }
+    >div.active{
+      color: #009dff;
+    }
+  }
+  .flex-box{
+    display: flex;
+    align-items: center;
+    >div{
+      margin-right: 40px;
+    }
+  }
+  .search-box{
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    >div{
+      width: 50%;
+    }
   }
 }
 </style>

+ 123 - 0
yarn.lock

@@ -1206,6 +1206,109 @@
     "@babel/helper-validator-identifier" "^7.19.1"
     to-fast-properties "^2.0.0"
 
+"@better-scroll/core@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/core/-/core-2.5.1.tgz#de53f089a2f53f51e58e5042556fe0d3e1655aa9"
+  integrity sha512-koKOuYA55dQ04FJRIVUpMGDr1hbCfWmfX0MGp1hKagkQSWSRpwblqACiwtggVauoj9aaJRJZ9hDsTM4weaavlg==
+  dependencies:
+    "@better-scroll/shared-utils" "^2.5.1"
+
+"@better-scroll/indicators@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/indicators/-/indicators-2.5.1.tgz#a5d2da343fc6d0865846f1f8d2153eb423301be1"
+  integrity sha512-Hk+Y00pR6fTsu6C9HGg1yYZtsu1gAcTgcs4C9aM5h6fQANX/T2YIYrOSjZmdL+js2PTcXJWZS8VM4Xjoi1PbfQ==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+
+"@better-scroll/infinity@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/infinity/-/infinity-2.5.1.tgz#f834e9b31d4174eff25c42793efb0cf705b7fe8f"
+  integrity sha512-GKHrrasIh0KlGzhASHDo5hEEBJcDFpP4XaZGPH9Ey8+QBH6/O1ykAXS2ixkVAOTkBrv+KgFXoCUr4oN1xWeM+g==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+
+"@better-scroll/mouse-wheel@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/mouse-wheel/-/mouse-wheel-2.5.1.tgz#002d16264238122ecc7713c86eddc282ea52b79c"
+  integrity sha512-DGnrirRMY6zMM7xwgx09D/cA9A//3J1/uDkq8iBVEyE5p0sEr/keQpjEfFHGkBRa505BnbBwdbN6f5lugEDSPw==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+
+"@better-scroll/movable@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/movable/-/movable-2.5.1.tgz#65a8e0942087723172f91283363e2339ad567eaf"
+  integrity sha512-8bLPRY15bbK4K5+tjrtdaKsFFKmJx72wRdg+xz3xQGFcTD940HFkJiORSOcz8Ufue7eOJfcmreQJBw6XY+TqTw==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+
+"@better-scroll/nested-scroll@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/nested-scroll/-/nested-scroll-2.5.1.tgz#8aa07da6be3444eeaafe3f4b610f82785fd7f98a"
+  integrity sha512-3cRsARxf9tq1VWBq7YAaET0xGAmgY1ERMmnXDo2gHFrmsJoNOionlpAeHdZvKQp2jG7JrzJ1O27nGCXf40gnkw==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+
+"@better-scroll/observe-dom@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/observe-dom/-/observe-dom-2.5.1.tgz#7e69e46cba1a5b4aa36c498204e60379ac4191d8"
+  integrity sha512-TCMGFLRfpXBPIwtUV/efliUmfmrhSNI7NXdSyjdWjsLOS7dh3eFkmcom5ERVWMaXVELSmujGXLqobT+dT0C/jg==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+
+"@better-scroll/observe-image@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/observe-image/-/observe-image-2.5.1.tgz#2c8279e44fa8d24614d39b14063c0483c874827c"
+  integrity sha512-0Lhfj83o8EESwOxr8bfStCzNOokTm3KB7JeyMS8u/xl+3tyTuls9889cyAukYk4Yly1cS49pCGfj2P8YOiwtUg==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+
+"@better-scroll/pull-down@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/pull-down/-/pull-down-2.5.1.tgz#ad1c741ddda8f771767dc455906637d0567ae449"
+  integrity sha512-Y6XcGu2NlevPg3k9VBRRFvpmfoTA+rO96JGdog2qKHclIPNXnsVwsIHtZfAm9weE/f9UuC4BnB+VUFRlucfupg==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+
+"@better-scroll/pull-up@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/pull-up/-/pull-up-2.5.1.tgz#d5bcfd8343cdb0601b96484f410ee678c22a3a44"
+  integrity sha512-1hu3xSMxdB8T391KffpNZ7g93lMwZEHjfb1F1Y4KvIkciDt8nXqkGpqrZF+YwR+EJTgYcWqUO8kgmI6XXu7Pkg==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+
+"@better-scroll/scroll-bar@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/scroll-bar/-/scroll-bar-2.5.1.tgz#89f8aea8f6beec93ecefbf98e0cb9aa51322e62b"
+  integrity sha512-i6r60pWG/ztkFK2j5Gj54I0LJb2jGh5TWJNQBoW0gUkp28B+0JvBFTwZn9tF7beZCBorKR7Hvvu4O9A1TJy94Q==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+
+"@better-scroll/shared-utils@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/shared-utils/-/shared-utils-2.5.1.tgz#ed6a1b5713462fa50afd8bb7d172ca218a0b7f2e"
+  integrity sha512-AplkfSjXVYP9LZiD6JsKgmgQJ/mG4uuLmBuwLz8W5OsYc7AYTfN8kw6GqZ5OwCGoXkVhBGyd8NeC4xwYItp0aw==
+
+"@better-scroll/slide@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/slide/-/slide-2.5.1.tgz#d61788b304f305915231430e7c38b22598bcb5b9"
+  integrity sha512-aDOrfsmjAcz6DXN7mDX3tPieAn195R43Yn9e3waI19TIEok/mQlI1a/kb5quqWOoxkiaZQ8xe3vx5ZTj9C+F6Q==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+
+"@better-scroll/wheel@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/wheel/-/wheel-2.5.1.tgz#941745457780584e2ccd385b1588c88c0550f2b0"
+  integrity sha512-fYLcEvkh88Z/2L+P5/+SGMunuc+HzAjGOiORIa/x21qb/knO2RFH4A/V1Rt3OIW4QluWzuFnU6jJRPlsQVZ4fg==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+
+"@better-scroll/zoom@^2.5.1":
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/@better-scroll/zoom/-/zoom-2.5.1.tgz#f43813c9c6cf8aa0c5745fd0cf7c605416f84f1b"
+  integrity sha512-aGvFY5ooeZWS4RcxQLD+pGLpQHQxpPy0sMZV3yadcd2QK53PK9gS4Dp+BYfRv8lZ4/P2LoNEhr6Wq1DN6+uPlA==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+
 "@discoveryjs/json-ext@0.5.7":
   version "0.5.7"
   resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
@@ -2199,6 +2302,26 @@ batch@0.6.1:
   resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
   integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==
 
+better-scroll@^2.5.1:
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/better-scroll/-/better-scroll-2.5.1.tgz#36680afff3756b84296f40c70d9d1793527a7e63"
+  integrity sha512-OiF3cQroRfTzf+CRQH2z1G52ZAlNHINI6lCAvDmyFu0o0nRuTaV9F+fmBGIU2BL5p5IplUQ4E7sYa1TLfZarzQ==
+  dependencies:
+    "@better-scroll/core" "^2.5.1"
+    "@better-scroll/indicators" "^2.5.1"
+    "@better-scroll/infinity" "^2.5.1"
+    "@better-scroll/mouse-wheel" "^2.5.1"
+    "@better-scroll/movable" "^2.5.1"
+    "@better-scroll/nested-scroll" "^2.5.1"
+    "@better-scroll/observe-dom" "^2.5.1"
+    "@better-scroll/observe-image" "^2.5.1"
+    "@better-scroll/pull-down" "^2.5.1"
+    "@better-scroll/pull-up" "^2.5.1"
+    "@better-scroll/scroll-bar" "^2.5.1"
+    "@better-scroll/slide" "^2.5.1"
+    "@better-scroll/wheel" "^2.5.1"
+    "@better-scroll/zoom" "^2.5.1"
+
 big.js@^5.2.2:
   version "5.2.2"
   resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"