13 Commits cd070752f7 ... 7cc6be7858

Author SHA1 Message Date
  manywhy 7cc6be7858 Merge branch 'dev' 5 months ago
  manywhy 73f3cc2e7c 更新dev分支 5 months ago
  manywhy 71e6644c92 更新dev分支 5 months ago
  manywhy 08f74fc659 提交feature分支 5 months ago
  walter cda940b9ea 长连接粘贴板 6 months ago
  walter 048f9acd2b 长连接 6 months ago
  walter b87a6b5288 积分规则取消编辑 6 months ago
  walter 3d938a7cb2 积分规则取消编辑 6 months ago
  walter f328bbaf40 部门对比 6 months ago
  walter 1d87cafd63 任务详情 6 months ago
  walter 4e6ef7ae51 取消规则编辑 6 months ago
  walter 8da90ea37b 部门对比优化websocket 6 months ago
  walter 723fd1ec4a 积分规则组件 6 months ago

+ 5 - 0
package-lock.json

@@ -11862,6 +11862,11 @@
         "resolve": "^1.1.6"
         "resolve": "^1.1.6"
       }
       }
     },
     },
+    "reconnecting-websocket": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmmirror.com/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz",
+      "integrity": "sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng=="
+    },
     "redent": {
     "redent": {
       "version": "1.0.0",
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/redent/-/redent-1.0.0.tgz",
       "resolved": "https://registry.npmmirror.com/redent/-/redent-1.0.0.tgz",

+ 1 - 0
package.json

@@ -28,6 +28,7 @@
     "qrcode.vue": "^1.6.3",
     "qrcode.vue": "^1.6.3",
     "qrcodejs2": "0.0.2",
     "qrcodejs2": "0.0.2",
     "qs": "^6.9.6",
     "qs": "^6.9.6",
+    "reconnecting-websocket": "^4.4.0",
     "sortablejs": "^1.14.0",
     "sortablejs": "^1.14.0",
     "swiper": "^5.2.1",
     "swiper": "^5.2.1",
     "vant": "^2.12.51",
     "vant": "^2.12.51",

+ 2 - 1
src/attendance/view/AttendanceNew/ApplyRecord.vue

@@ -13,7 +13,7 @@
             <div class="content">
             <div class="content">
               <div class="title">
               <div class="title">
                 <div class="detail">{{ item.type_mark }}申请</div>
                 <div class="detail">{{ item.type_mark }}申请</div>
-                <div :class="{ wait: item.status == 0, refuse: item.status == -1 }" class="status">{{ filterStatus(item.status) }}</div>
+                <div :class="{ wait: item.status == 0, refuse: item.status == -1 }" class="status">{{ filtetatus(item.status) }}</div>
               </div>
               </div>
               <div v-if="item.type == 4" class="desc">请假类型:{{ item.holiday_name }}</div>
               <div v-if="item.type == 4" class="desc">请假类型:{{ item.holiday_name }}</div>
               <div class="desc">申请时间:{{ item.application_time }}</div>
               <div class="desc">申请时间:{{ item.application_time }}</div>
@@ -422,6 +422,7 @@ export default {
 }
 }
 .leftkep {
 .leftkep {
   padding: 0.2rem 0.12rem 0.2rem 0.32rem;
   padding: 0.2rem 0.12rem 0.2rem 0.32rem;
+  box-sizing: border-box;
 }
 }
 .headAll {
 .headAll {
   height: calc(100% - 3rem) !important;
   height: calc(100% - 3rem) !important;

File diff suppressed because it is too large
+ 883 - 774
src/attendance/view/AttendanceNew/Index.vue


+ 3 - 1
src/components/DeptSelectorDropdown.vue

@@ -3,7 +3,7 @@
     <div class="dept_path" style="white-space:nowrap;" v-if="list.length==0">
     <div class="dept_path" style="white-space:nowrap;" v-if="list.length==0">
       <div class="dept_paths">
       <div class="dept_paths">
         <a href="javascript:void(0);" @click="backToIndex(-1)">全公司</a>
         <a href="javascript:void(0);" @click="backToIndex(-1)">全公司</a>
-        <a v-for="(item, i) in selectedDeptStack" :key="i" href="javascript:void(0);" @click.stop="backToIndex(i)">
+        <a v-for="(item, i) in selectedDeptStack" style="display: flex; align-items: center;" :key="i" href="javascript:void(0);" @click.stop="backToIndex(i)">
           <van-icon name="arrow" />
           <van-icon name="arrow" />
           {{ item.name }}
           {{ item.name }}
         </a>
         </a>
@@ -187,6 +187,8 @@ export default {
 }
 }
 
 
 .employee_cell {
 .employee_cell {
+  display: flex;
+  align-items: center;
   padding: 0.16rem 0.32rem;
   padding: 0.16rem 0.32rem;
   touch-action: none;
   touch-action: none;
 }
 }

+ 2 - 1
src/components/EmployeeSelectorCell.vue

@@ -27,8 +27,9 @@
           <em v-show="index > 0">,</em>
           <em v-show="index > 0">,</em>
           {{ item.name }}
           {{ item.name }}
         </span>
         </span>
-        等{{ selected_data.employee.length }}人
+        等
       </div>
       </div>
+      <div>{{ selected_data.employee.length }}人</div>
     </template>
     </template>
     <EmployeeSelector
     <EmployeeSelector
       :title="bar_title"
       :title="bar_title"

+ 14 - 6
src/components/NumberInput.vue

@@ -8,6 +8,7 @@
     :required="required"
     :required="required"
     :id="com_id"
     :id="com_id"
     :class="{'v-input': show_dept_selector}"
     :class="{'v-input': show_dept_selector}"
+    style="display: flex; align-items: center;"
   >
   >
     <template slot="right-icon">
     <template slot="right-icon">
       <div class="picker-box" @click="activeIsAdd" v-if="chosePoint&&!isForbidSet">
       <div class="picker-box" @click="activeIsAdd" v-if="chosePoint&&!isForbidSet">
@@ -22,7 +23,7 @@
      <div class="flex-box-ce">
      <div class="flex-box-ce">
           <span v-if="isAdd" class="red">+</span>
           <span v-if="isAdd" class="red">+</span>
           <span v-else class="green">-</span>
           <span v-else class="green">-</span>
-          <van-field  style="padding: 0.1rem 0;" @input="onInput" type="digit" :readonly="onReadonly" @blur="onBlur"  v-model.number="numVal" placeholder="分值"/>
+          <van-field  style="padding: 0.1rem 0;" @input="onInput" type="digit" :readonly="onReadonly"  @focus="onFocus" @blur="onBlur"  v-model.number="numVal" placeholder="分值"/>
       </div>
       </div>
 <!--     <div @click.stop="show_keyboard">
 <!--     <div @click.stop="show_keyboard">
         <span v-if="input_value > 0" class="red">+</span>
         <span v-if="input_value > 0" class="red">+</span>
@@ -126,11 +127,14 @@ export default {
   },
   },
   computed:{
   computed:{
     onReadonly(){
     onReadonly(){
-      if((this.min&&this.min == this.max)||this.isForbidSet){
-        return true
-      }else{
-       return false
-      }
+      // 防止传入的this.min, this.max为 '', undefined, null的情况
+      if((!!this.min && !!this.max && this.min == this.max) || this.isForbidSet) return true
+      else return false
+      // if((this.min&&this.min == this.max)||this.isForbidSet){
+      //   return true
+      // }else{
+      //  return false
+      // }
     }
     }
   },
   },
   watch: {
   watch: {
@@ -228,7 +232,11 @@ export default {
         // }
         // }
         this.$emit('value', value * 1)
         this.$emit('value', value * 1)
     },
     },
+    onFocus() {
+      this.$emit("inputing", "")
+    },
     onBlur() {
     onBlur() {
+       this.$emit("inputed", "")
       let value=this.numVal;
       let value=this.numVal;
       if (!this.isAdd) {
       if (!this.isAdd) {
         value = value * 1 * -1
         value = value * 1 * -1

+ 3 - 1
src/components/RuleCategorySelDropdown.vue

@@ -2,7 +2,7 @@
   <div class="dept-select-drodown__wrap">
   <div class="dept-select-drodown__wrap">
       <div class="dept_path" style=" white-space:nowrap;">
       <div class="dept_path" style=" white-space:nowrap;">
         <div class="dept_paths">
         <div class="dept_paths">
-          <a href="javascript:void(0);" @click="backToIndex(-1)" >全部</a>
+          <a href="javascript:void(0);" style="display: flex; align-items: center;" @click="backToIndex(-1)" >全部</a>
           <a
           <a
             v-for="(item, i) in selectedDeptStack"
             v-for="(item, i) in selectedDeptStack"
             :key="i"
             :key="i"
@@ -182,6 +182,8 @@ export default {
   }
   }
 
 
   .employee_cell {
   .employee_cell {
+    display: flex;
+    align-items: center;
     padding: 0.16rem 0.32rem;
     padding: 0.16rem 0.32rem;
     touch-action: none;
     touch-action: none;
   }
   }

+ 147 - 32
src/components/RuleScopeSelector.vue

@@ -92,28 +92,49 @@
       </div>
       </div>
     </template>
     </template>
     <div class="container">
     <div class="container">
-      <scroller>
+<!--      <scroller>-->
+<!--        <van-cell-group inset>-->
+<!--          <van-cell-->
+<!--            v-for="(item,index) in list"-->
+<!--            :key="index"-->
+<!--            @click="onSelected(item)"-->
+<!--          >-->
+<!--            <template slot="label">-->
+<!--              <span class="record green" v-if="item.min_point <= 0">{{(item.range_type == 1 ? item.min_point : item.min_point+'~'+item.max_point)}}</span>-->
+<!--              <span class="record red" v-if="item.min_point > 0">+ {{(item.range_type == 1 ? item.min_point : item.min_point+'~'+item.max_point)}}</span>-->
+<!--              <span class="type">{{$getTypesName(item.pt_id)}}</span>-->
+<!--            </template>-->
+<!--            <template slot="icon">-->
+<!--              <van-checkbox v-model="item.selected" shape="square" style="margin-right: 0.16rem;" />-->
+<!--            </template>-->
+<!--            <template slot="title">-->
+<!--              <div class="item-remark">{{item.remark}}</div>-->
+<!--            </template>-->
+<!--          </van-cell>-->
+
+<!--        </van-cell-group>-->
+<!--        <div style="height: 1rem;"></div>-->
+<!--      </scroller>-->
+      <scroller ref="scroller" :on-refresh="onRefresh" :on-infinite="onInfinite" no-data-text="没有了噢" :list="pageList">
         <van-cell-group inset>
         <van-cell-group inset>
           <van-cell
           <van-cell
-            v-for="(item,index) in list"
+            v-for="(item,index) in pageList"
             :key="index"
             :key="index"
             @click="onSelected(item)"
             @click="onSelected(item)"
           >
           >
-            <template slot="label">
+            <template #label>
               <span class="record green" v-if="item.min_point <= 0">{{(item.range_type == 1 ? item.min_point : item.min_point+'~'+item.max_point)}}</span>
               <span class="record green" v-if="item.min_point <= 0">{{(item.range_type == 1 ? item.min_point : item.min_point+'~'+item.max_point)}}</span>
               <span class="record red" v-if="item.min_point > 0">+ {{(item.range_type == 1 ? item.min_point : item.min_point+'~'+item.max_point)}}</span>
               <span class="record red" v-if="item.min_point > 0">+ {{(item.range_type == 1 ? item.min_point : item.min_point+'~'+item.max_point)}}</span>
               <span class="type">{{$getTypesName(item.pt_id)}}</span>
               <span class="type">{{$getTypesName(item.pt_id)}}</span>
             </template>
             </template>
-            <template slot="icon">
+            <template #icon>
               <van-checkbox v-model="item.selected" shape="square" style="margin-right: 0.16rem;" />
               <van-checkbox v-model="item.selected" shape="square" style="margin-right: 0.16rem;" />
             </template>
             </template>
-            <template slot="title">
+            <template #title>
               <div class="item-remark">{{item.remark}}</div>
               <div class="item-remark">{{item.remark}}</div>
             </template>
             </template>
           </van-cell>
           </van-cell>
-
         </van-cell-group>
         </van-cell-group>
-        <div style="height: 1rem;"></div>
       </scroller>
       </scroller>
     </div>
     </div>
 
 
@@ -150,7 +171,7 @@
           >
           >
             全部
             全部
           </el-button>
           </el-button>
-          <el-tree
+           <!-- <el-tree
             ref="ruleTree"
             ref="ruleTree"
             node-key="id"
             node-key="id"
             :data="ruleTree"
             :data="ruleTree"
@@ -158,7 +179,9 @@
             highlight-current
             highlight-current
             style="margin-top: 16px"
             style="margin-top: 16px"
             @node-click="onRuleClick"
             @node-click="onRuleClick"
-          />
+          /> -->
+          <collapse :ruleTree="ruleTree" :current-rule-id="currentRuleId" @open="onRuleClick"/>
+          <!-- <collapse :current-rule-id="currentRuleId" :ruleTree="ruleTree"  /> -->
           <div style="height: 0.5rem;"></div>
           <div style="height: 0.5rem;"></div>
         </div>
         </div>
       </template>
       </template>
@@ -167,8 +190,13 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import {_debounce} from "../utils/auth";
+import collapse from "./collapse/index.vue";
 export default {
 export default {
   name:'RuleScopeSelector',
   name:'RuleScopeSelector',
+  components: {
+    collapse
+  },
   props:{
   props:{
     visible:{
     visible:{
       type:Boolean,
       type:Boolean,
@@ -196,11 +224,15 @@ export default {
       showSelector:false,
       showSelector:false,
       itemObject:null,
       itemObject:null,
       ruleTree:[],
       ruleTree:[],
+      activeNames: ['0'],
       items:[],
       items:[],
       itemSelected:[],
       itemSelected:[],
       currentRuleId:0,
       currentRuleId:0,
       keyword:'',
       keyword:'',
-      showRule:false
+      showRule:false,
+      page:1,
+      pageSize:10,
+      pageList:[],
     }
     }
   },
   },
   watch:{
   watch:{
@@ -217,20 +249,28 @@ export default {
         this.getRuleScope()
         this.getRuleScope()
       }
       }
     },
     },
+    currentRuleId(v){
+      this.$refs.scroller.triggerPullToRefresh()
+    },
+    keyword:_debounce(function (v){
+      this.$refs.scroller.triggerPullToRefresh()
+    }),
+
+
   },
   },
   computed:{
   computed:{
-    list(){
-      if (this.currentRuleId > 0){
-        if (!this.itemObject[`rule_${this.currentRuleId}`]) return []
-        this.items = []
-        this.initItems({1:this.itemObject[`rule_${this.currentRuleId}`]})
-      } else {
-        if (!this.itemObject) return []
-        this.items = []
-        this.initItems(this.itemObject)
-      }
-      return this.items.filter(item => this.keyword ? item.remark.indexOf(this.keyword) > -1 : true)
-    },
+    // list(){
+    //   if (this.currentRuleId > 0){
+    //     if (!this.itemObject[`rule_${this.currentRuleId}`]) return []
+    //     this.items = []
+    //     this.initItems({1:this.itemObject[`rule_${this.currentRuleId}`]})
+    //   } else {
+    //     if (!this.itemObject) return []
+    //     this.items = []
+    //     this.initItems(this.itemObject)
+    //   }
+    //   return this.items.filter(item => this.keyword ? item.remark.indexOf(this.keyword) > -1 : true)
+    // },
   },
   },
   methods:{
   methods:{
     initItems(itemObj){
     initItems(itemObj){
@@ -238,7 +278,7 @@ export default {
         item.forEach((record) => {
         item.forEach((record) => {
           let temp = {
           let temp = {
             ...record,
             ...record,
-            selected:this.itemSelected.some(i => i.id === record.id)
+            selected: this.itemSelected.some(i => i.id === record.id)
           }
           }
           this.items.push(temp)
           this.items.push(temp)
         })
         })
@@ -258,9 +298,9 @@ export default {
       this.$axiosUser('get','/api/pro/integral/rule/trees/scope',data)
       this.$axiosUser('get','/api/pro/integral/rule/trees/scope',data)
         .then(res => {
         .then(res => {
           if (res.data.code === 1){
           if (res.data.code === 1){
-            this.ruleTree = res.data.data.rule_tree
-            this.itemObject = res.data.data.item_list
-            this.initItems(this.itemObject)
+            this.ruleTree = res.data.data.rule_tree; // 分类列表,树结构
+            this.itemObject = res.data.data.item_list; // 细节列表
+             this.$refs.scroller.triggerPullToRefresh()
           }
           }
         })
         })
     },
     },
@@ -282,14 +322,15 @@ export default {
       }
       }
     },
     },
     onRuleClick(rule){
     onRuleClick(rule){
-      this.currentRuleId = rule.id || 0
+      this.currentRuleId = rule.id || 0;
+      console.log(this.currentRuleId);
     },
     },
     onRuleClear(){
     onRuleClear(){
-      this.$refs['ruleTree'].setCurrentKey(null)
+      this.$refs['ruleTree'] && this.$refs['ruleTree'].setCurrentKey(null)
       this.currentRuleId = 0
       this.currentRuleId = 0
     },
     },
     onConfirm(){
     onConfirm(){
-      this.$emit("confirm",this.itemSelected.map(item => {
+      this.$emit("confirm", this.itemSelected.map(item => {
         return {...item}
         return {...item}
       }))
       }))
       this.close()
       this.close()
@@ -301,9 +342,63 @@ export default {
       this.onConfirm()
       this.onConfirm()
     },
     },
     clear(){
     clear(){
-      this.itemSelected = []
-      this.initItems(this.itemObject)
-    }
+      this.itemSelected = [];
+      this.onRefresh();
+    },
+    calculateItem(){
+      this.items = [];
+      let itemObjects = [];
+      if (!this.itemObject) return
+      if (this.currentRuleId > 0){
+        if (!this.itemObject[`rule_${this.currentRuleId}`]) {
+          this.items = []
+          return
+        }
+        itemObjects = {1: this.itemObject[`rule_${this.currentRuleId}`]}
+      } else {
+        itemObjects = this.itemObject
+      }
+      Object.values(itemObjects)
+        .forEach((item) => {
+          item.filter(record => this.keyword ? record.remark.indexOf(this.keyword) > -1 : true)
+            .forEach((record) => {
+              let temp = {
+                ...record,
+                selected:this.itemSelected.some(i => i.id === record.id)
+              }
+              this.items.push(temp)
+            })
+        })
+    },
+    calculatePage(callback){
+      if (this.items.length <= 0) {
+        this.pageList = []
+        return
+      }
+      let start = (this.page - 1) * this.pageSize
+      let end = start + this.pageSize
+
+      let appends = this.items.slice(start,end)
+
+      if (this.page === 1){
+        this.pageList= appends
+      }else {
+        if (appends.length) this.pageList.splice(this.pageList.length,0,...appends)
+      }
+
+      if (typeof callback === 'function') callback(appends.length < this.pageSize)
+    },
+    onRefresh(done){
+      console.log('on refresh')
+      this.page = 1
+      this.calculateItem()      //计算需要展示的数据
+      this.calculatePage(done)
+    },
+    onInfinite(done){
+      console.log('on infinite')
+      this.page += 1
+      this.calculatePage(done)
+    },
   },
   },
   mounted() {}
   mounted() {}
 }
 }
@@ -385,4 +480,24 @@ export default {
   padding: 0;
   padding: 0;
 }
 }
 
 
+/deep/ .el-tree-node {
+  margin: 0 0.24rem;
+  border-bottom: 0.02rem solid #ebedf0;
+}
+/deep/ .el-tree-node__content {
+  height: 1rem;
+}
+
+/deep/ .el-tree-node__children .el-tree-node__content{
+  border-bottom: none;
+}
+
+/deep/ .el-tree-node__label {
+  font-size: 0.32rem;
+}
+
+/deep/ .el-tree-node__expand-icon {
+  font-size: 0.3rem;
+}
+
 </style>
 </style>

+ 11 - 4
src/components/YearMonthPicker.vue

@@ -1,8 +1,15 @@
 <template>
 <template>
   <div class="bg-fff">
   <div class="bg-fff">
     <van-row>
     <van-row>
-      <van-col span="9"><div class="btn-left"><van-icon name="arrow-left" @click="prev" /></div></van-col>
-      <van-col span="6"><icon name="YMPicker_item_icon" class="YMPicker_item_icon"></icon><div class="date-text" @click="show = true">{{currentDate_show}}</div></van-col>
+      <van-col span="9">
+        <div class="btn-left">
+          <van-icon name="arrow-left" @click="prev" />
+        </div>
+      </van-col>
+      <van-col span="6" style="display: flex; align-items: center;">
+        <icon name="YMPicker_item_icon" class="YMPicker_item_icon"></icon>
+        <div class="date-text" @click="show = true">{{currentDate_show}}</div>
+      </van-col>
       <van-col span="9"><div class="btn-right"><van-icon name="arrow" @click="next" /></div></van-col>
       <van-col span="9"><div class="btn-right"><van-icon name="arrow" @click="next" /></div></van-col>
     </van-row>
     </van-row>
 
 
@@ -135,8 +142,8 @@
      background:#238dfa;
      background:#238dfa;
    }
    }
   .YMPicker_item_icon{
   .YMPicker_item_icon{
-    width:0.23rem;
-    height:auto;
+    width: 0.25rem;
+    height: 0.25rem;
     padding-right: 0.15rem;
     padding-right: 0.15rem;
     color:#323233;
     color:#323233;
   }
   }

+ 156 - 0
src/components/collapse/index.vue

@@ -0,0 +1,156 @@
+<template>
+  <div class="collspseBox">
+    <van-row class="collspse_item" v-for="(item, index) in  ruleTree" :key="item.id" >
+      <van-col class="icon" span="2"  @click.stop="open(item, index)">
+        <van-icon v-if="item.child && item.child.length > 0" size="16" :name="item.active ? 'arrow-down' : 'arrow'" />
+      </van-col>
+      <van-col span="22" class="title" :class="currentRuleId == item.id ? 'item-active' : 'item-gray'"  @click.stop="open(item, index)">
+        <label style="display: flex; align-items: center;">
+          <input class="radio_button" type="radio" :checked="currentRuleId == item.id" :value="item.id" name="treeGroup" @change="handleChange(item)">
+          {{ item.name }}
+        </label>
+      </van-col>
+
+      <van-col span="24" class="content" v-if="item.child && item.child.length > 0" :style="{ height: item.active ? 'auto' : '0' }">
+        <collapse :currentRuleId="currentRuleId" :ruleTree="item.child" @open="$emit('open', $event)" />
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<!--  -->
+
+<script>
+  export default {
+    name: "collapse",
+    props: {
+      ruleTree: Array,
+      currentRuleId: {
+        type: [String, Number],
+        default: 0
+      },
+    },
+
+    data() {
+      return {
+        selectId: 0,
+      }
+    },
+
+    methods: {
+      handleChange(item) {
+        this.$emit("open", item);
+      },
+      open(item, index) {
+        this.$set(this.ruleTree[index], 'active', !this.ruleTree[index].active);
+      },
+
+
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .item-active {
+    color: #409EFF !important;
+  }
+  .item-gray {
+    color: #323233 !important;
+  }
+
+.collspseBox {
+  padding: 14px 10px;
+
+  .collspse_item {
+    background-color: #fff;
+    padding: 15px 12px;
+    border-radius: 8px;
+    overflow: hidden;
+    margin-bottom: 10px;
+    box-shadow: 0 0px 6px rgba(100, 101, 102, 0.1);
+
+    .icon {
+      text-align: center;
+      vertical-align: middle;
+      color: #d2d2d2;
+    }
+
+    .title {
+      font-size: 0.32rem;
+      color: #323233;
+      display: flex;
+      align-items: center;
+      white-space: nowrap;
+      text-wrap: nowrap;
+      word-break: keep-all;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      /* 单选框样式 */
+      .radio_button {
+        -webkit-appearance: none; /* 移除默认样式 */
+        appearance: none; /* 移除默认样式 */
+        outline: none; /* 移除轮廓 */
+        display: inline-block;
+        width: 0.3rem; /* 设置宽度 */
+        height: 0.3rem; /* 设置高度 */
+        border-radius: 50%; /* 设置为圆形 */
+        background-color: white; /* 初始背景颜色为白色 */
+        position: relative; /* 设置相对定位 */
+        margin: 0 8px 0 0; /* 设置边距 */
+        border: 1px solid #d2d2d2;
+        cursor: pointer; /* 设置鼠标指针为手型 */
+      }
+
+      .radio_button:checked {
+        width: 0.3rem; /* 设置宽度 */
+        height: 0.3rem; /* 设置高度 */
+        background-color: #409EFF; /* 选中时中心白色 */
+        border: none; /* 选中时去掉边框 */
+        z-index: 2; /* 确保在最上面 */
+      }
+
+      .radio_button:checked::before {
+        content: "";
+        position: absolute;
+        top: 50%; /* 使伪元素垂直居中 */
+        left: 50%; /* 使伪元素水平居中 */
+        transform: translate(-50%, -50%); /* 使伪元素水平垂直居中 */
+        width: 0.12rem;
+        height: 0.12rem;
+        border-radius: 50%; /* 使伪元素变成圆形 */
+        background-color: #ffffff; /* 外部红色 */
+        z-index: 1; /* 确保伪元素在最前面 */
+      }
+    }
+
+    .content {
+      transition: all .5s;
+
+      .collspseBox {
+        padding: 0;
+
+        .collspse_item {
+          padding: 16px 0 0 12px;
+          margin-bottom: 0;
+          box-shadow: none;
+
+          .title {
+            display: flex;
+            align-items: center;
+            font-size: 0.3rem;
+            color: #2F3541;
+            font-family: "PingFang SC";
+            font-weight: 400;
+            position: relative;
+            padding-left: 5px;
+          }
+
+
+        }
+      }
+    }
+  }
+
+}
+
+</style>

+ 60 - 11
src/main.js

@@ -1,4 +1,3 @@
-
 import Vue from 'vue'
 import Vue from 'vue'
 import App from './App'
 import App from './App'
 import router from './router'
 import router from './router'
@@ -23,7 +22,39 @@ import axiosKc from '@/utils/axiosKc'
 import 'shepherd.js/dist/css/shepherd.css';
 import 'shepherd.js/dist/css/shepherd.css';
 
 
 // import 'vant/lib/index.css';
 // import 'vant/lib/index.css';
-import { Tabbar, Empty, TabbarItem, ShareSheet, Loading, Divider, Overlay,Grid, GridItem, Form, Field, NavBar, Row, Col, List, Picker, Cell, CellGroup, Toast, Popup, Dialog, RadioGroup, Radio, Notify, Button, Icon, Tab, Tabs } from 'vant'
+import {
+  Tabbar,
+  Empty,
+  TabbarItem,
+  ShareSheet,
+  Loading,
+  Divider,
+  Overlay,
+  Grid,
+  GridItem,
+  Form,
+  Field,
+  NavBar,
+  Row,
+  Col,
+  List,
+  Picker,
+  Cell,
+  CellGroup,
+  Toast,
+  Popup,
+  Dialog,
+  RadioGroup,
+  Radio,
+  Notify,
+  Button,
+  Icon,
+  Tab,
+  Tabs,
+  Collapse,
+  CollapseItem
+} from 'vant'
+
 
 
 /*element ui*/
 /*element ui*/
 import {
 import {
@@ -34,7 +65,23 @@ import {
 import 'element-ui/lib/theme-chalk/index.css';
 import 'element-ui/lib/theme-chalk/index.css';
 
 
 
 
-import { getWxToken, setWxToken, getIsIdentity, supremeAuthority, getIsWx, getTypes, getTypesName, getUserData, getEmployeeMap, getCache, setCache, removeCache, returnDeptName, getEmployeeMapItem, returnFh } from '@/utils/auth'
+import {
+  getWxToken,
+  setWxToken,
+  getIsIdentity,
+  supremeAuthority,
+  getIsWx,
+  getTypes,
+  getTypesName,
+  getUserData,
+  getEmployeeMap,
+  getCache,
+  setCache,
+  removeCache,
+  returnDeptName,
+  getEmployeeMapItem,
+  returnFh
+} from '@/utils/auth'
 Vue.prototype.$echarts = echarts
 Vue.prototype.$echarts = echarts
 Vue.prototype.$moment = moment
 Vue.prototype.$moment = moment
 Vue.prototype.$getTypesName = getTypesName
 Vue.prototype.$getTypesName = getTypesName
@@ -52,8 +99,8 @@ Vue.prototype.$axiosKq = axiosKq
 Vue.prototype.$axiosKc = axiosKc
 Vue.prototype.$axiosKc = axiosKc
 Vue.prototype.$removeCache = removeCache
 Vue.prototype.$removeCache = removeCache
 Vue.prototype.$returnDeptName = returnDeptName
 Vue.prototype.$returnDeptName = returnDeptName
-Vue.prototype.$socketApi = socketApi   //长连接
-Vue.prototype.$socketApiTow = socketApiTow   //长连接
+Vue.prototype.$socketApi = socketApi //长连接
+Vue.prototype.$socketApiTow = socketApiTow //长连接
 Vue.prototype.$returnFh = returnFh
 Vue.prototype.$returnFh = returnFh
 Vue.prototype.$isWx = getIsWx()
 Vue.prototype.$isWx = getIsWx()
 
 
@@ -70,10 +117,12 @@ Vue.component('userImage', userImage)
 /*element ui 按需引入*/
 /*element ui 按需引入*/
 Vue.use(ELTree).use(ELButton).use(ELDrawer)
 Vue.use(ELTree).use(ELButton).use(ELDrawer)
 
 
-Vue.use(Button).use(Tabbar).use(TabbarItem).use(ShareSheet).use(Grid).use(Overlay).use(Loading).use(Divider).use(GridItem).use(Picker).use(Form).use(Field).use(List).use(Tabs).use(Tab).use(NavBar).use(Row).use(Col).use(Cell).use(CellGroup).use(Toast).use(Popup).use(Dialog).use(RadioGroup).use(Radio).use(Icon).use(Notify).use(Empty)
+Vue.use(Button).use(Tabbar).use(TabbarItem).use(ShareSheet).use(Grid).use(Overlay).use(Loading).use(Divider).use(
+  GridItem).use(Picker).use(Form).use(Field).use(List).use(Tabs).use(Tab).use(NavBar).use(Row).use(Col).use(Cell).use(
+  CellGroup).use(Toast).use(Popup).use(Dialog).use(RadioGroup).use(Radio).use(Icon).use(Notify).use(Empty).use(Collapse).use(CollapseItem)
 
 
-Vue.prototype.$route_back = function (setp) {
-  if (typeof (setp) == 'undefined') {
+Vue.prototype.$route_back = function(setp) {
+  if (typeof(setp) == 'undefined') {
     setp = -1
     setp = -1
   }
   }
   if (window.history.length <= 1 && window.plus) {
   if (window.history.length <= 1 && window.plus) {
@@ -87,7 +136,7 @@ Vue.prototype.$route_back = function (setp) {
   }
   }
 }
 }
 
 
-Vue.directive('isKeyboard', function (el) {
+Vue.directive('isKeyboard', function(el) {
   let isAndroid = true;
   let isAndroid = true;
   if (navigator.userAgent.indexOf('Android') > 0) {
   if (navigator.userAgent.indexOf('Android') > 0) {
     isAndroid = true;
     isAndroid = true;
@@ -97,7 +146,7 @@ Vue.directive('isKeyboard', function (el) {
   if (isAndroid) {
   if (isAndroid) {
     //获取原窗口的高度
     //获取原窗口的高度
     var originalHeight = document.documentElement.clientHeight || document.body.clientHeight;
     var originalHeight = document.documentElement.clientHeight || document.body.clientHeight;
-    window.onresize = function () {
+    window.onresize = function() {
       //键盘弹起与隐藏都会引起窗口的高度发生变化
       //键盘弹起与隐藏都会引起窗口的高度发生变化
       var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
       var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
       if (resizeHeight - 0 < originalHeight - 0) {
       if (resizeHeight - 0 < originalHeight - 0) {
@@ -108,7 +157,7 @@ Vue.directive('isKeyboard', function (el) {
         el.style['display'] = 'block'
         el.style['display'] = 'block'
       }
       }
     };
     };
-  } else {  // ios:focusin和focusout支持冒泡,对应focus和blur, 使用focusin和focusout的原因是focusin和focusout可以冒泡,focus和blur不会冒泡,这样就可以使用事件代理,处理多个输入框存在的情况。
+  } else { // ios:focusin和focusout支持冒泡,对应focus和blur, 使用focusin和focusout的原因是focusin和focusout可以冒泡,focus和blur不会冒泡,这样就可以使用事件代理,处理多个输入框存在的情况。
     document.body.addEventListener("focusin", () => {
     document.body.addEventListener("focusin", () => {
       //软键盘弹出的事件处理
       //软键盘弹出的事件处理
       el.style['display'] = 'none'
       el.style['display'] = 'none'

+ 1 - 1
src/okr/view/okrHome.vue

@@ -169,7 +169,7 @@ export default {
   },
   },
   computed:{
   computed:{
     barColor(){
     barColor(){
-      return function (item) { 
+      return function (item) {
         return item.day<0 ? (item.composite_state == 4?'#2879ff':'#f56c6c'):'#2879ff'
         return item.day<0 ? (item.composite_state == 4?'#2879ff':'#f56c6c'):'#2879ff'
        }
        }
     },
     },

+ 2 - 2
src/okr/view/okrHome/okrBack.vue

@@ -24,9 +24,9 @@
             <div v-else v-for="(item, index) in backlogList" :key="index">
             <div v-else v-for="(item, index) in backlogList" :key="index">
               <div class="backlog_list_tit">{{ item.time }}</div>
               <div class="backlog_list_tit">{{ item.time }}</div>
               <div v-for="(arr, keys) in item.list" :key="keys" @click="openDetail(arr)" :style="'z-index:' + (item.list.length - keys)" class="performanceList backlog_list">
               <div v-for="(arr, keys) in item.list" :key="keys" @click="openDetail(arr)" :style="'z-index:' + (item.list.length - keys)" class="performanceList backlog_list">
-                  <div class="flex-box">
+                  <div class="flex-box" style="align-items: center;">
                      <span class="flex-1" v-html="arr.content"></span>
                      <span class="flex-1" v-html="arr.content"></span>
-                     <van-icon name="arrow" />
+                     <van-icon name="arrow" color="#b1b1b1" />
                   </div>
                   </div>
               </div>
               </div>
             </div>
             </div>

+ 3 - 1
src/performance/components/statementcontent/statement_details.vue

@@ -3,7 +3,9 @@
     <van-nav-bar :title="barTItle" left-text="" left-arrow @click-left="$route_back"></van-nav-bar>
     <van-nav-bar :title="barTItle" left-text="" left-arrow @click-left="$route_back"></van-nav-bar>
     <header class="performanceList" v-if="moduleshow">
     <header class="performanceList" v-if="moduleshow">
       <van-row>
       <van-row>
-        <van-col span="24"><van-search v-model="keyword" placeholder="请输入员工姓名搜索" @input="keyInput" style="padding: 0.2rem 0.12rem .2rem .32rem;" /></van-col>
+        <van-col span="24">
+          <van-search v-model="keyword" placeholder="请输入员工姓名搜索" @input="keyInput" style="padding: 0.2rem 0.32rem .2rem .32rem;" />
+        </van-col>
       </van-row>
       </van-row>
     </header>
     </header>
     <div class="headScreen flex-no-wrap" v-if="moduleshow">
     <div class="headScreen flex-no-wrap" v-if="moduleshow">

+ 10 - 10
src/performance/components/workbenchcontent/messageInform.vue

@@ -25,15 +25,16 @@
               <div class="backlog_list_tit">{{ item.time }}</div>
               <div class="backlog_list_tit">{{ item.time }}</div>
               <div v-for="(arr, keys) in item.list" :key="keys" @click="unreadCli(arr)" :style="'z-index:' + (item.list.length - keys)" class="performanceList backlog_list">
               <div v-for="(arr, keys) in item.list" :key="keys" @click="unreadCli(arr)" :style="'z-index:' + (item.list.length - keys)" class="performanceList backlog_list">
                 <div class="flex-box">
                 <div class="flex-box">
-                <userImage
-                  class="about-me__avatar"
-                  :id="arr.userInfo.id"
-                  :img_url="arr.userInfo.img_url"
-                  :user_name="arr.userInfo.name"
-                  fontSize="0.24"
-                  width="0.65rem"
-                  height="0.65rem"
-                ></userImage>
+                  <userImage
+                    class="about-me__avatar"
+                    :id="arr.userInfo.id"
+                    :img_url="arr.userInfo.img_url"
+                    :user_name="arr.userInfo.name"
+                    fontSize="0.24"
+                    width="0.65rem"
+                    height="0.65rem"
+                  >
+                  </userImage>
                   <span v-html="arr.content"></span>
                   <span v-html="arr.content"></span>
                 </div>
                 </div>
               </div>
               </div>
@@ -67,7 +68,6 @@ export default {
         page: 1, // 当期页
         page: 1, // 当期页
         page_size: 10 // 一页多少数据
         page_size: 10 // 一页多少数据
       },
       },
-
       theBackupListcc: []
       theBackupListcc: []
     }
     }
   },
   },

+ 20 - 3
src/point/view/integral/batchList.vue

@@ -66,6 +66,8 @@
                  name="积分"
                  name="积分"
                  required
                  required
                  v-if="item.pid==0"
                  v-if="item.pid==0"
+                 @inputing="inputing"
+                 @inputed="inputed"
                  v-validate="'required'">
                  v-validate="'required'">
                  </NumberInput>
                  </NumberInput>
                  <div class="flex-box flex-v-ce jf" v-else>
                  <div class="flex-box flex-v-ce jf" v-else>
@@ -124,7 +126,9 @@
                   name="积分"
                   name="积分"
                   required
                   required
                   v-if="item.pid==0"
                   v-if="item.pid==0"
-                  v-validate="'required'">
+                  v-validate="'required'"
+                  @inputing="inputing"
+                  @inputed="inputed">
                   </NumberInput>
                   </NumberInput>
                   <div class="flex-box flex-v-ce jf" v-else>
                   <div class="flex-box flex-v-ce jf" v-else>
                     <div>填写积分</div>
                     <div>填写积分</div>
@@ -212,6 +216,8 @@
                      title="填写积分"
                      title="填写积分"
                      name="积分"
                      name="积分"
                      required
                      required
+                     @inputing="inputing"
+                     @inputed="inputed"
                      v-validate="'required'">
                      v-validate="'required'">
                      </NumberInput>
                      </NumberInput>
                  </div>
                  </div>
@@ -223,6 +229,8 @@
                      title="填写积分"
                      title="填写积分"
                      name="积分"
                      name="积分"
                      required
                      required
+                     @inputing="inputing"
+                     @inputed="inputed"
                      v-validate="'required'">
                      v-validate="'required'">
                      </NumberInput>
                      </NumberInput>
                  </div>
                  </div>
@@ -266,7 +274,7 @@
       </scroller>
       </scroller>
       <div class="flex-box btns" v-show="rightText" :class="{ isIos: isIos }" >
       <div class="flex-box btns" v-show="rightText" :class="{ isIos: isIos }" >
         <van-button plain type="danger" class="flex-1" style="margin-right: 0.24rem" @click="reject()">拒绝</van-button>
         <van-button plain type="danger" class="flex-1" style="margin-right: 0.24rem" @click="reject()">拒绝</van-button>
-        <van-button plain type="info" class="flex-1" @click="pass()">通过</van-button>
+        <van-button plain type="info" class="flex-1" @click="pass()" :disabled="isDisabled">通过</van-button>
       </div>
       </div>
       <van-dialog v-model="showReject" title="批量拒绝" class="reject_popup" show-cancel-button :beforeClose="save_btn">
       <van-dialog v-model="showReject" title="批量拒绝" class="reject_popup" show-cancel-button :beforeClose="save_btn">
         <van-cell-group>
         <van-cell-group>
@@ -319,7 +327,8 @@ export default {
       },
       },
       isIos: this.$getCache('iPhone'),
       isIos: this.$getCache('iPhone'),
       showReject: false, // 驳回弹窗
       showReject: false, // 驳回弹窗
-      reject_text: ''// 驳回意见
+      reject_text: '',// 驳回意见
+      isDisabled: false
     }
     }
   },
   },
   created () {
   created () {
@@ -360,6 +369,14 @@ export default {
 
 
       })
       })
     },
     },
+    // 用户输入中
+    inputing() {
+      this.isDisabled = true;
+    },
+    // 用户输入完
+    inputed() {
+      this.isDisabled = false;
+    },
     // 通过
     // 通过
     pass () {
     pass () {
       var obj, is = true, items = []
       var obj, is = true, items = []

+ 125 - 26
src/point/view/integral/deptRank.vue

@@ -6,8 +6,12 @@
       <van-dropdown-item @open="calendarOpen">
       <van-dropdown-item @open="calendarOpen">
         <van-icon name="calendar-o" slot="title" size="1.5em" />
         <van-icon name="calendar-o" slot="title" size="1.5em" />
       </van-dropdown-item>
       </van-dropdown-item>
-      <van-dropdown-item :title="searchForm.deptName" ref="deptDropdownItem"><DeptSelectorDropdown @onConfirm="onConfirmDept" /></van-dropdown-item>
-      <van-dropdown-item title="规则" ref="ruleDropdownItem"><RuleCategorySelDropdown @onConfirm="onConfirmRule" @onCancel="searchForm.ruleId = 0"/></van-dropdown-item>
+      <van-dropdown-item :title="searchForm.deptName" ref="deptDropdownItem">
+        <DeptSelectorDropdown @onConfirm="onConfirmDept" />
+      </van-dropdown-item>
+      <van-dropdown-item title="规则" ref="ruleDropdownItem">
+        <RuleCategorySelDropdown @onConfirm="onConfirmRule" @onCancel="searchForm.ruleId = 0"/>
+      </van-dropdown-item>
       <van-dropdown-item>
       <van-dropdown-item>
         <van-icon name="list-switch" slot="title" size="1.5em" />
         <van-icon name="list-switch" slot="title" size="1.5em" />
         <template slot="default">
         <template slot="default">
@@ -30,7 +34,7 @@
     <div class="mrd-content">
     <div class="mrd-content">
       <scroller
       <scroller
         ref="scroller"
         ref="scroller"
-        :on-refresh="onRefresh"
+        :on-refresh="getDataList"
       >
       >
         <van-cell v-for="item in dataList" :key="item.id" :title="item.name" :value="item.point"/>
         <van-cell v-for="item in dataList" :key="item.id" :title="item.name" :value="item.point"/>
         <noData :list="dataList" />
         <noData :list="dataList" />
@@ -85,6 +89,8 @@ import moment from "moment/moment";
 import { DropdownMenu, DropdownItem ,Calendar,Switch} from 'vant';
 import { DropdownMenu, DropdownItem ,Calendar,Switch} from 'vant';
 import DeptSelectorDropdown from '@/components/DeptSelectorDropdown';
 import DeptSelectorDropdown from '@/components/DeptSelectorDropdown';
 import RuleCategorySelDropdown from '@/components/RuleCategorySelDropdown';
 import RuleCategorySelDropdown from '@/components/RuleCategorySelDropdown';
+import ReconnectingWebSocket from "reconnecting-websocket";
+import {generateUUID, getToken} from "../../../utils/auth";
 
 
 Vue.use(DropdownMenu).use(DropdownItem).use(Calendar).use(Switch);
 Vue.use(DropdownMenu).use(DropdownItem).use(Calendar).use(Switch);
 
 
@@ -131,7 +137,9 @@ export default {
       minDate:minDate,
       minDate:minDate,
       maxDate:maxDate,
       maxDate:maxDate,
       timeScope:[new Date(startDate),new Date(endDate)],
       timeScope:[new Date(startDate),new Date(endDate)],
-      showSearchBar:!this.$supremeAuthority('employee')
+      showSearchBar:!this.$supremeAuthority('employee'),
+      rws:null,
+      rwsHasAuth:false,
     }
     }
   },
   },
   computed:{
   computed:{
@@ -152,29 +160,31 @@ export default {
       })
       })
     },
     },
     'searchForm.startDate'(val){
     'searchForm.startDate'(val){
-      this.onRefresh()
+      this.getDataList()
     },
     },
     'searchForm.endDate'(val){
     'searchForm.endDate'(val){
-      this.onRefresh()
+      this.getDataList()
     },
     },
     'searchForm.deptId'(val){
     'searchForm.deptId'(val){
-      this.onRefresh()
+      this.getDataList()
     },
     },
     'searchForm.deptIncludeSub'(val){
     'searchForm.deptIncludeSub'(val){
-      this.onRefresh()
+      this.getDataList()
     },
     },
     'searchForm.ptId'(val){
     'searchForm.ptId'(val){
-      this.onRefresh()
+      this.getDataList()
     },
     },
     'searchForm.ruleId'(val){
     'searchForm.ruleId'(val){
-      this.onRefresh()
+      this.getDataList()
     },
     },
     'searchForm.ruleIncludeSub'(val){
     'searchForm.ruleIncludeSub'(val){
-      this.onRefresh()
+      this.getDataList()
+    },
+    rwsHasAuth(v){
+      // console.log('rws auth',v)
+      if (v) this.getDataList();
     },
     },
-
   },
   },
-  created() {},
   methods:{
   methods:{
     timeScopeThisWeek(){
     timeScopeThisWeek(){
       this.timeScope = [new Date(moment().startOf('week').format('YYYY-MM-DD')),new Date(moment().endOf('week').format('YYYY-MM-DD'))]
       this.timeScope = [new Date(moment().startOf('week').format('YYYY-MM-DD')),new Date(moment().endOf('week').format('YYYY-MM-DD'))]
@@ -222,12 +232,38 @@ export default {
       this.searchForm.ruleId = ruleId || 0;
       this.searchForm.ruleId = ruleId || 0;
       this.$refs.ruleDropdownItem.toggle();
       this.$refs.ruleDropdownItem.toggle();
     },
     },
-    onRefresh(done){
-      if (!this.searchForm.startDate || !this.searchForm.endDate || !this.searchForm.ptId){
+    // onRefresh(done){
+    //   if (!this.searchForm.startDate || !this.searchForm.endDate || !this.searchForm.ptId){
+    //     if (typeof done === 'function') done();
+    //     return;
+    //   }
+    //
+    //   let msg = {
+    //     type:'dr',
+    //     start_date:this.searchForm.startDate,
+    //     end_date:this.searchForm.endDate,
+    //     pt_id:this.searchForm.ptId,
+    //     dept_id:this.searchForm.deptId,
+    //     dept_include_sub:this.searchForm.deptIncludeSub ? 1 : 0,
+    //     item_id:0,
+    //     rule_id:this.searchForm.ruleId,
+    //     rule_include_sub:this.searchForm.ruleIncludeSub ? 1 : 0
+    //   }
+    //
+    //   this.$socketApiTow.sendData(msg,(res) => {
+    //     if (res.code !== 1 || res.type !== msg.type){
+    //       if (typeof done === 'function') done();
+    //       return;
+    //     }
+    //     this.dataList = res.result.list;
+    //     if (typeof done === 'function') done();
+    //   })
+    // },
+    getDataList(done){
+      if (!this.rws || !this.rwsHasAuth || !this.searchForm.startDate || !this.searchForm.endDate || !this.searchForm.ptId){
         if (typeof done === 'function') done();
         if (typeof done === 'function') done();
         return;
         return;
       }
       }
-
       let msg = {
       let msg = {
         type:'dr',
         type:'dr',
         start_date:this.searchForm.startDate,
         start_date:this.searchForm.startDate,
@@ -238,20 +274,75 @@ export default {
         item_id:0,
         item_id:0,
         rule_id:this.searchForm.ruleId,
         rule_id:this.searchForm.ruleId,
         rule_include_sub:this.searchForm.ruleIncludeSub ? 1 : 0
         rule_include_sub:this.searchForm.ruleIncludeSub ? 1 : 0
-      }
+      };
 
 
-      this.$socketApiTow.sendData(msg,(res) => {
-        if (res.code !== 1 || res.type !== msg.type){
-          if (typeof done === 'function') done();
-          return;
-        }
-        this.dataList = res.result.list;
-        if (typeof done === 'function') done();
-      })
+      this.rws.send(JSON.stringify(msg));
 
 
+      if (typeof done === 'function') done();
+    },
 
 
+    onWsOpen(){
+      // console.log('on ws open');
+      let params = {
+        type:'auth',
+        token: getToken(),
+        machine: generateUUID(),
+      }
+      this.rws.send(JSON.stringify(params));
+    },
+    onWsMessage(event){
+      let msg = event.data ?  JSON.parse(event.data) : null;
+      if (!msg) return;
+      switch (msg.type){
+        case 'ping':
+          this.rws.send("dept rank keep connecting")
+          break;
+        case 'auth':
+          this.rwsHasAuth = msg.code === 1;
+          break;
+        case 'dr':
+          if (msg.code === 1) this.dataList = msg.result.list;
+          break;
+      }
+    },
+    onWsError(event){
+      this.rwsHasAuth = false;
+      // console.log('on ws error',event);
+    },
+    onWsClose(event){
+      this.rwsHasAuth = false;
+      // console.log('on ws close',event);
+    },
+    initRws(){
+      if (this.rws){
+        this.rws.close();
+        this.rws = null;
+        this.rwsHasAuth = false;
+      }
+      this.rws = new ReconnectingWebSocket(process.env.VUE_APP_WEBSCOKET_TOW);
+      this.rws.onopen = this.onWsOpen;
+      this.rws.onmessage = this.onWsMessage;
+      this.rws.onerror = this.onWsError;
+      this.rws.onclose = this.onWsClose;
+    },
+    clearRws(){
+      if (this.rws) this.rws.close();
+      this.rws = null;
+      this.rwsHasAuth = false;
     }
     }
-  }
+  },
+  created() {},
+  mounted() {},
+  activated() {
+    this.initRws();
+  },
+  deactivated() {
+    this.clearRws();
+  },
+  beforeDestroy() {
+    this.clearRws();
+  },
+  destroyed() {},
 }
 }
 
 
 </script>
 </script>
@@ -269,4 +360,12 @@ export default {
   }
   }
 
 
 }
 }
+
+/deep/ .van-calendar__header-subtitle {
+  width: 100%;
+  font-size: 0.28rem;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
 </style>
 </style>

+ 253 - 31
src/point/view/integral/integral_application.vue

@@ -89,40 +89,66 @@
     </div>
     </div>
     <div style="padding:0.32rem;" class="flex-box-ce">
     <div style="padding:0.32rem;" class="flex-box-ce">
       <van-button size="large" plain type="info" style="margin-right: 0.2rem;width: 2rem;" @click="openSelect" v-if="rule_switch">已选{{items.length}}条</van-button>
       <van-button size="large" plain type="info" style="margin-right: 0.2rem;width: 2rem;" @click="openSelect" v-if="rule_switch">已选{{items.length}}条</van-button>
-      <van-button size="large" @click="data_verify" :disabled="subloading" type="info">提交</van-button>
+<!--      <van-button size="large" @click="data_verify" :disabled="subloading" type="info">提交</van-button>-->
+      <van-button size="large" @click="rwsBusinessVerify" :disabled="subloading || !rwsHasAuth" type="info">提交</van-button>
     </div>
     </div>
 
 
     <!-- 提交结果 -->
     <!-- 提交结果 -->
-    <van-popup v-model="isResult" style="width: 90%;border-radius: 5px;">
-    	<div v-if="!isShowError" style="padding: 0.24rem;">
-        <van-progress :percentage="percentage" />
-    		<div style="margin-top: 10px;border: 1px solid #f1f1f1;max-height: 7rem;overflow-y: auto;" class="scroll-bar">
-    			<div class="flex-box-ce results" style="font-weight: 600;">
-    				<div style="border-right: 1px solid #f1f1f1;width: 40px;">序号</div>
-    				<div class="flex-1" style="border-right: 1px solid #f1f1f1;">申请对象</div>
-    				<div class="flex-1" >处理结果</div>
-    			</div>
-    			<div class="flex-box-ce results" v-for="(item, index) in results" :key="index">
-    				<div style="border-right: 1px solid #f1f1f1;width: 40px;">{{results.length-index}}</div>
-    				<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.target }}</div>
-    				<div class="flex-1 font-flex-word" v-if="item.status == 1">
-    					<span class="green">提交成功</span>
-    				</div>
-    				<div class="flex-1 red" v-else>{{ item.msg }}</div>
-    			</div>
-    		</div>
-        <div class="flex-box-end" style="margin-top: 20px;" v-show="results.length==resultList.length">
-          <van-button type="info" @click="isResult = false" size="small">确 定</van-button>
-        </div>
-    	</div>
-    	<div v-else>
-    		<div style="text-align: center;" class="red">{{errorMsg}}</div>
-    		<div>
-    			<div class="flex-box-end" style="margin-top: 10px;">
-            <van-button type="info" @click="isResult = false" size="small">确 定</van-button>
+<!--    <van-popup v-model="isResult" style="width: 90%;border-radius: 5px;">-->
+<!--    	<div v-if="!isShowError" style="padding: 0.24rem;">-->
+<!--        <van-progress :percentage="percentage" />-->
+<!--    		<div style="margin-top: 10px;border: 1px solid #f1f1f1;max-height: 7rem;overflow-y: auto;" class="scroll-bar">-->
+<!--    			<div class="flex-box-ce results" style="font-weight: 600;">-->
+<!--    				<div style="border-right: 1px solid #f1f1f1;width: 40px;">序号</div>-->
+<!--    				<div class="flex-1" style="border-right: 1px solid #f1f1f1;">申请对象</div>-->
+<!--    				<div class="flex-1" >处理结果</div>-->
+<!--    			</div>-->
+<!--    			<div class="flex-box-ce results" v-for="(item, index) in results" :key="index">-->
+<!--    				<div style="border-right: 1px solid #f1f1f1;width: 40px;">{{results.length-index}}</div>-->
+<!--    				<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.target }}</div>-->
+<!--    				<div class="flex-1 font-flex-word" v-if="item.status == 1">-->
+<!--    					<span class="green">提交成功</span>-->
+<!--    				</div>-->
+<!--    				<div class="flex-1 red" v-else>{{ item.msg }}</div>-->
+<!--    			</div>-->
+<!--    		</div>-->
+<!--        <div class="flex-box-end" style="margin-top: 20px;" v-show="results.length==resultList.length">-->
+<!--          <van-button type="info" @click="isResult = false" size="small">确 定</van-button>-->
+<!--        </div>-->
+<!--    	</div>-->
+<!--    	<div v-else>-->
+<!--    		<div style="text-align: center;" class="red">{{errorMsg}}</div>-->
+<!--    		<div>-->
+<!--    			<div class="flex-box-end" style="margin-top: 10px;">-->
+<!--            <van-button type="info" @click="isResult = false" size="small">确 定</van-button>-->
+<!--          </div>-->
+<!--    		</div>-->
+<!--    	</div>-->
+<!--    </van-popup>-->
+
+<!--  rws提交结果  -->
+    <van-popup v-model="rwsBusinessData.showBusiness" :close-on-click-overlay="false" style="width: 90%;border-radius: 5px;">
+      <div style="padding: 0.24rem;">
+        <van-progress :percentage="rwsBusinessProgress" />
+        <div style="margin-top: 10px;border: 1px solid #f1f1f1;max-height: 7rem;overflow-y: auto;" class="scroll-bar">
+          <div class="flex-box-ce results" style="font-weight: 600;">
+            <div style="border-right: 1px solid #f1f1f1;width: 40px;">序号</div>
+            <div class="flex-1" style="border-right: 1px solid #f1f1f1;">申请对象</div>
+            <div class="flex-1" >处理结果</div>
+          </div>
+          <div class="flex-box-ce results" v-for="(item, index) in rwsBusinessData.dataList" :key="index">
+            <div style="border-right: 1px solid #f1f1f1;width: 40px;">{{`${index + 1}`}}</div>
+            <div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.employee_name }}</div>
+            <div class="flex-1">
+              <span :class="{'cyan':item.status === -2,'origin':item.status === -1,'green':item.status === 1,'red':item.status === 0}">{{item.msg}}</span>
+            </div>
           </div>
           </div>
-    		</div>
-    	</div>
+        </div>
+        <div class="flex-box-end" style="margin-top: 20px;" >
+          <van-button type="info" :disabled="rwsBusinessProgress < 100" @click="rwsBusinessData.showBusiness = false" size="small">确 定</van-button>
+          <van-tag ref="copyResult" style="margin-left: 0.2rem;" @click.prevent.stop="rwsClipResult">{{rwsBusinessData.result.length}} / {{rwsBusinessData.dataList.length}}</van-tag>
+        </div>
+      </div>
     </van-popup>
     </van-popup>
   </div>
   </div>
 </template>
 </template>
@@ -136,6 +162,9 @@ import moment from 'moment'
 import Vue from 'vue'
 import Vue from 'vue'
 import {Switch,Progress,Icon  } from 'vant'
 import {Switch,Progress,Icon  } from 'vant'
 import RuleScopeSelector from "../../../components/RuleScopeSelector.vue";
 import RuleScopeSelector from "../../../components/RuleScopeSelector.vue";
+import ReconnectingWebSocket from "reconnecting-websocket";
+import {generateUUID, getToken} from "../../../utils/auth";
+import Clipboard from "clipboard";
 
 
 Vue.use(Switch).use(Progress).use(Icon)
 Vue.use(Switch).use(Progress).use(Icon)
 
 
@@ -159,6 +188,7 @@ export default {
       superior_list:this.$userInfo().employee_detail.superior_list,
       superior_list:this.$userInfo().employee_detail.superior_list,
       employee_list: [this.$userInfo()],
       employee_list: [this.$userInfo()],
       employeeid:this.$userInfo().id,
       employeeid:this.$userInfo().id,
+      employeeName:this.$userInfo().name,
       ptId:3,
       ptId:3,
       change_reviewer:Number(this.$userInfo().site_config.change_reviewer),//是否允许员工修改审批人
       change_reviewer:Number(this.$userInfo().site_config.change_reviewer),//是否允许员工修改审批人
       userName:'',
       userName:'',
@@ -193,6 +223,21 @@ export default {
       resultIndex:0,
       resultIndex:0,
       isShowError:false,
       isShowError:false,
       errorMsg:'服务器繁忙,请稍后再试',
       errorMsg:'服务器繁忙,请稍后再试',
+      rws:null,
+      rwsHasAuth:false,
+      rwsBusinessData:{
+        showBusiness:false,
+        dataList:[],
+        msgQueue:[],
+        result:[],
+        intervalId:null,
+      },
+      rwsCopyResult:null,
+    }
+  },
+  computed:{
+    rwsBusinessProgress(){
+      return this.rwsBusinessData.dataList.length === 0 ? 0 : Math.floor(this.rwsBusinessData.dataList.filter(item => item.status >= 0).length / this.rwsBusinessData.dataList.length * 100)
     }
     }
   },
   },
   watch: {
   watch: {
@@ -227,9 +272,11 @@ export default {
     employee_list(val) {
     employee_list(val) {
       if (val.length > 0) {
       if (val.length > 0) {
         this.employeeid=val[0].id;
         this.employeeid=val[0].id;
+        this.employeeName=val[0].name;
         this.initializesReviewer(val[0].id);
         this.initializesReviewer(val[0].id);
       } else {
       } else {
         this.employeeid = ''
         this.employeeid = ''
+        this.employeeName = ''
         this.items.forEach(item=>{
         this.items.forEach(item=>{
           item.reviewer_id='';
           item.reviewer_id='';
           item.reviewer_list=[];
           item.reviewer_list=[];
@@ -247,6 +294,14 @@ export default {
     		this.$socketApi.closewebsocket();
     		this.$socketApi.closewebsocket();
     	}
     	}
     },
     },
+    'rwsBusinessData.showBusiness'(v){
+      if (!v) {
+        this.initRwsBusinessData();
+        this.items = [];
+        this.itemRule=[];//规则数组
+        this.rule_switch=true;
+      }
+    }
   },
   },
   mounted() {
   mounted() {
     this.initializesReviewer(this.employeeid);
     this.initializesReviewer(this.employeeid);
@@ -257,6 +312,14 @@ export default {
        }
        }
     }
     }
   },
   },
+  activated() {
+    console.log('activated');
+    this.initRws();
+  },
+  beforeDestroy() {
+    console.log('before destroy');
+    this.clearRws();
+  },
   methods: {
   methods: {
     openText(){
     openText(){
        this.$dialog.alert({
        this.$dialog.alert({
@@ -439,7 +502,166 @@ export default {
     		this.isShowError = true;
     		this.isShowError = true;
     	}
     	}
     },
     },
-  }
+    initRws(){
+      if (this.rws){
+        this.rws.close();
+        this.rws = null;
+        this.rwsHasAuth = false;
+      }
+      this.rws = new ReconnectingWebSocket(process.env.VUE_APP_WEBSCOKET);
+      this.rws.onopen = this.onWsOpen;
+      this.rws.onmessage = this.onWsMessage;
+      this.rws.onerror = this.onWsError;
+      this.rws.onclose = this.onWsClose;
+    },
+    initRwsBusinessData(){
+      this.rwsBusinessData.dataList = [];
+      this.rwsBusinessData.msgQueue = [];
+      this.rwsBusinessData.result = [];
+      this.rwsBusinessData.copyResult = null;
+      if (this.rwsBusinessData.intervalId) clearInterval(this.rwsBusinessData.intervalId);
+      this.rwsBusinessData.intervalId = null;
+    },
+    onWsOpen(){
+      let params = {
+        type:'auth',
+        token: getToken(),
+        machine: generateUUID(),
+      }
+      this.rws.send(JSON.stringify(params));
+    },
+    onWsMessage(event){
+      let msg = event.data ?  JSON.parse(event.data) : null;
+      if (!msg) return;
+      let type = msg.type || 'none';
+      switch (type){
+        case 'ping':
+          this.rws.send('integral application keep connecting');
+          break;
+        case 'auth':
+          this.rwsHasAuth = msg.code === 1;
+          break;
+        case 'point_apply':
+          this.rwsBusinessData.result.push(msg);
+          let businessId = msg.result.task.msg.businessId;
+          this.rwsBusinessData.dataList.forEach(item => {
+            if (item.businessId !== businessId) return;
+            item.status = msg.result.status;
+            item.msg = msg.result.msg;
+          })
+          this.rwsIntegralApplication();
+          break;
+      }
+    },
+    onWsError(event){
+      console.log('on ws error',event);
+      this.rwsHasAuth = false;
+    },
+    onWsClose(event){
+      console.log('on ws close',event)
+      this.rwsHasAuth = false;
+    },
+    clearRws(){
+      if (this.rws) this.rws.close();
+      this.rws = null;
+      this.rwsHasAuth = false;
+      this.initRwsBusinessData();
+    },
+    rwsBusinessVerify() {
+      if(!this.employeeid){
+        this.showMessage('请选择录入对象')
+        return false
+      }
+      if(this.items.length === 0){
+        this.showMessage('请选择规则')
+        return false
+      }
+
+      let now = moment();
+      let businessId = 1;
+      for (var i = 0; i < this.items.length; i++){
+        let item = this.items[i];
+        if (!item.remark){
+          this.showMessage(`第${i + 1}条申请,请输入时间内容及描述`);
+          return false;
+        }
+        if (item.reviewer_list.length <= 0){
+          this.showMessage(`第${i + 1}条申请,请选择审批人`);
+          return false;
+        }
+        if (moment(item.event_time).isAfter(now)){
+          this.showMessage(`第${i + 1}条申请,发生时间不能大于今天`);
+          return false;
+        }
+
+        this.rwsBusinessData.dataList.push({
+          rule_id: item.rule_id || 0,
+          employee_id: this.employeeid || 0,
+          item_id: item.item_id || 0,
+          remark: item.remark,
+          event_time: item.event_time,
+          files: item.files,
+          type:'point_apply',
+          reviewer_id:item.reviewer_list[0].id,
+          employee_name:this.employeeName,
+          status:-2,
+          msg:'待处理',
+          businessId:businessId,
+        });
+        /*队列数据*/
+        let msg = {
+          rule_id: item.rule_id || 0,
+          employee_id: this.employeeid || 0,
+          item_id: item.item_id || 0,
+          remark: item.remark,
+          event_time: item.event_time,
+          files: item.files,
+          type:'point_apply',
+          reviewer_id:item.reviewer_list[0].id,
+          businessId:businessId,
+        }
+        this.rwsBusinessData.msgQueue.push(msg);
+
+        businessId++;
+      }
+      if (this.rwsBusinessData.dataList.length <= 0){
+        this.showMessage("请重新指定规则");
+        return false;
+      }
+
+      this.rwsBusinessData.showBusiness = true;
+
+      /*开始提交*/
+      this.rwsIntegralApplication();
+    },
+    rwsClipResult(event){
+      const clipboard = new Clipboard(event.target,{
+        text: () => JSON.stringify(this.rwsBusinessData.result)
+      });
+      clipboard.on('success',() => {
+        this.$notify({type: 'info', message: '复制成功'});
+        clipboard.destroy();
+      });
+      clipboard.on('error', () => {
+        this.$notify({type: 'info', message: '复制失败,请联系系统管理员'});
+        clipboard.destroy();
+      });
+      clipboard.onClick(event);
+
+      // navigator.clipboard.writeText(JSON.stringify(this.rwsBusinessData.result));
+      // this.$notify({type: 'info', message: '结果已经复制到剪切板'})
+    },
+    rwsIntegralApplication(){
+      let msg = this.rwsBusinessData.msgQueue.shift();
+      if (!msg) return;
+      this.rwsBusinessData.dataList.forEach(item => {
+        if (item.businessId !== msg.businessId) return;
+        item.status = -1;
+        item.msg = '处理中';
+      })
+      this.rws.send(JSON.stringify(msg));
+    }
+  },
 }
 }
 </script>
 </script>
 <style scoped>
 <style scoped>

+ 323 - 44
src/point/view/integral/integral_entry_n.vue

@@ -88,46 +88,78 @@
     <div v-isKeyboard>
     <div v-isKeyboard>
       <div class="flex-box-ce footer">
       <div class="flex-box-ce footer">
         <van-button size="large" plain type="info" style="margin-right: 0.2rem;width: 2rem;" @click="openSelect">已选{{items.length}}条</van-button>
         <van-button size="large" plain type="info" style="margin-right: 0.2rem;width: 2rem;" @click="openSelect">已选{{items.length}}条</van-button>
-        <van-button size="large" @click="data_verify" type="info">提交</van-button>
+<!--        <van-button size="large" @click="data_verify" type="info" :disabled="!rwsHasAuth" >提交</van-button>-->
+        <van-button size="large" @click="rwsBusinessVerify" type="info" :disabled="!rwsHasAuth" >提交</van-button>
       </div>
       </div>
     </div>
     </div>
 
 
     <!-- 提交结果 -->
     <!-- 提交结果 -->
-    <van-popup v-model="isResult" style="width: 90%;border-radius: 5px;">
-    	<div v-if="!isShowError" style="padding: 0.24rem;">
-        <van-progress :percentage="percentage" />
-    		<div style="margin-top: 10px;border: 1px solid #f1f1f1;max-height: 7rem;overflow-y: auto;" class="scroll-bar">
-    			<div class="flex-box-ce results" style="font-weight: 600;">
-    				<div style="border-right: 1px solid #f1f1f1;width: 40px;">序号</div>
-    				<div class="flex-1" style="border-right: 1px solid #f1f1f1;">奖扣对象</div>
-    				<div class="flex-1" style="border-right: 1px solid #f1f1f1;">积分</div>
-    				<div class="flex-1" >处理结果</div>
-    			</div>
-    			<div class="flex-box-ce results" v-for="(item, index) in results" :key="index">
-    				<div style="border-right: 1px solid #f1f1f1;width: 40px;">{{results.length-index}}</div>
-    				<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.target }}</div>
-    				<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.point>0? '+'+item.point:item.point }}<span> {{ $getTypesName(ptId) }}</span></div>
-    				<div class="flex-1" v-if="item.status == 1">
-    					<span v-if="item.msg=='奖扣成功'" class="green">{{ item.msg }}</span>
-    					<span class="blue" v-else>{{ item.msg }}</span>
-    				</div>
-    				<div class="flex-1 red" v-else>{{ item.msg }}</div>
-    			</div>
-    		</div>
-        <div class="flex-box-end" style="margin-top: 20px;" v-show="results.length==resultList.length">
-          <van-button type="info" @click="isResult = false" size="small">确 定</van-button>
-        </div>
-    	</div>
-    	<div v-else>
-    		<div style="text-align: center;" class="red">{{errorMsg}}</div>
-    		<div>
-    			<div class="flex-box-end" style="margin-top: 10px;">
-            <van-button type="info" @click="isResult = false" size="small">确 定</van-button>
+<!--    <van-popup v-model="isResult" style="width: 90%;border-radius: 5px;">-->
+<!--    	<div v-if="!isShowError" style="padding: 0.24rem;">-->
+<!--        <van-progress :percentage="percentage" />-->
+<!--    		<div style="margin-top: 10px;border: 1px solid #f1f1f1;max-height: 7rem;overflow-y: auto;" class="scroll-bar">-->
+<!--    			<div class="flex-box-ce results" style="font-weight: 600;">-->
+<!--    				<div style="border-right: 1px solid #f1f1f1;width: 40px;">序号</div>-->
+<!--    				<div class="flex-1" style="border-right: 1px solid #f1f1f1;">奖扣对象</div>-->
+<!--    				<div class="flex-1" style="border-right: 1px solid #f1f1f1;">积分</div>-->
+<!--    				<div class="flex-1" >处理结果</div>-->
+<!--    			</div>-->
+<!--    			<div class="flex-box-ce results" v-for="(item, index) in results" :key="index">-->
+<!--    				<div style="border-right: 1px solid #f1f1f1;width: 40px;">{{results.length-index}}</div>-->
+<!--    				<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.target }}</div>-->
+<!--    				<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.point>0? '+'+item.point:item.point }}<span> {{ $getTypesName(ptId) }}</span></div>-->
+<!--    				<div class="flex-1" v-if="item.status == 1">-->
+<!--    					<span v-if="item.msg=='奖扣成功'" class="green">{{ item.msg }}</span>-->
+<!--    					<span class="blue" v-else>{{ item.msg }}</span>-->
+<!--    				</div>-->
+<!--    				<div class="flex-1 red" v-else>{{ item.msg }}</div>-->
+<!--    			</div>-->
+<!--    		</div>-->
+<!--        <div class="flex-box-end" style="margin-top: 20px;" v-show="results.length==resultList.length">-->
+<!--          <van-button type="info" @click="isResult = false" size="small">确 定</van-button>-->
+<!--        </div>-->
+<!--    	</div>-->
+<!--    	<div v-else>-->
+<!--    		<div style="text-align: center;" class="red">{{errorMsg}}</div>-->
+<!--    		<div>-->
+<!--    			<div class="flex-box-end" style="margin-top: 10px;">-->
+<!--            <van-button type="info" @click="isResult = false" size="small">确 定</van-button>-->
+<!--          </div>-->
+<!--    		</div>-->
+<!--    	</div>-->
+<!--    </van-popup>-->
+    <RuleScopeSelector :visible.sync = showRuleSelector :selected="itemRule" multi @confirm="selected => itemRule = selected" :pt-id="ptId" />
+
+<!--  rws提交结果  -->
+    <van-popup v-model="rwsBusinessData.showBusiness" :close-on-click-overlay="false" style="width: 90%; border-radius: 5px;">
+      <div style="padding: 0.24rem;">
+        <van-progress :percentage="rwsBusinessProgress" />
+        <div style="margin-top: 10px;border: 1px solid #f1f1f1;max-height: 7rem;overflow-y: auto;" class="scroll-bar">
+          <div class="flex-box-ce results" style="font-weight: 600;">
+            <div style="border-right: 1px solid #f1f1f1;width: 40px;">序号</div>
+            <div class="flex-1" style="border-right: 1px solid #f1f1f1;">奖扣对象</div>
+            <div class="flex-1" style="border-right: 1px solid #f1f1f1;">积分</div>
+            <div class="flex-1" >处理结果</div>
+          </div>
+          <div class="flex-box-ce results" v-for="(item,index) in rwsBusinessData.dataList" :key="index">
+            <div style="border-right: 1px solid #f1f1f1;width: 40px;">{{`${index + 1}`}}</div>
+            <div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.employee_name }}</div>
+            <div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.point>0? '+'+item.point:item.point }}<span> {{ $getTypesName(ptId) }}</span></div>
+            <div class="flex-1">
+              <span :class="{'cyan':item.status === -2,'origin':item.status === -1,'green':item.status === 1,'red':item.status === 0}" >{{item.msg}}</span>
+            </div>
           </div>
           </div>
-    		</div>
-    	</div>
+        </div>
+<!--        <div class="flex-box-end" style="margin-top: 20px;" v-show="rwsBusinessProgress >= 100">-->
+<!--          <van-button type="info" @click="rwsBusinessData.showBusiness = false" size="small">确 定</van-button>-->
+<!--        </div>-->
+        <div class="flex-box-end" style="margin-top: 20px;">
+          <van-button type="info" :disabled="rwsBusinessProgress < 100" @click="rwsBusinessData.showBusiness = false" size="small" >确 定</van-button>
+          <van-tag style="margin-left: 0.2rem;" @click.prevent.stop="rwsClipResult">{{rwsBusinessData.result.length}} / {{rwsBusinessData.dataList.length}}</van-tag>
+        </div>
+      </div>
     </van-popup>
     </van-popup>
-    <RuleScopeSelector :visible.sync = showRuleSelector :selected="itemRule" multi @confirm="selected => itemRule = selected" :pt-id="ptId" />
+
   </div>
   </div>
 </template>
 </template>
 <script>
 <script>
@@ -142,6 +174,9 @@ import Vue from 'vue'
 import ImageCamera from '@/attendance/components/image-camera';
 import ImageCamera from '@/attendance/components/image-camera';
 import {Switch,Progress} from 'vant'
 import {Switch,Progress} from 'vant'
 import RuleScopeSelector from "../../../components/RuleScopeSelector.vue";
 import RuleScopeSelector from "../../../components/RuleScopeSelector.vue";
+import ReconnectingWebSocket from "reconnecting-websocket";
+import {generateUUID, getToken} from "../../../utils/auth";
+import Clipboard from "clipboard";
 
 
 Vue.use(Switch).use(Progress)
 Vue.use(Switch).use(Progress)
 export default {
 export default {
@@ -210,7 +245,16 @@ export default {
       resultIndex:0,
       resultIndex:0,
       isShowError:false,
       isShowError:false,
       errorMsg:'服务器繁忙,请稍后再试',
       errorMsg:'服务器繁忙,请稍后再试',
-
+      rws:null,
+      rwsHasAuth:false,
+      rwsBusinessData:{
+        showBusiness:false,
+        dataList:[],
+        msgQueue:[],
+        result:[],
+        employees:[],
+        items:[],
+      }
     }
     }
   },
   },
   watch: {
   watch: {
@@ -272,14 +316,17 @@ export default {
       }
       }
     },
     },
     employee_list(val) {
     employee_list(val) {
-      if (val.length > 0) {
-        this.dialogData.members = []
-        this.dialogData.members=val.map(element => {
-          return element.id
-        })
-      } else {
-        this.dialogData.members = []
-      }
+      // if (val.length > 0) {
+      //   this.dialogData.members = []
+      //   this.dialogData.members=val.map(element => {
+      //     return element.id
+      //   })
+      // } else {
+      //   this.dialogData.members = []
+      // }
+      //
+      // console.log(val);
+      this.rwsBusinessData.employees = val && val.length > 0 ? val : [];
     },
     },
     isResult(val){
     isResult(val){
     	if(!val){
     	if(!val){
@@ -297,6 +344,25 @@ export default {
     		this.$socketApi.closewebsocket();
     		this.$socketApi.closewebsocket();
     	}
     	}
     },
     },
+    'rwsBusinessData.showBusiness'(v){
+      if (!v){
+        this.initRwsBusinessData();
+        this.dialogData = {
+          members: [],
+          items: []
+        };
+        this.itemRule = [];
+        this.ruleCate = [];
+        this.rule_switch = true;
+        this.items = [];
+        this.employee_list = [];
+      }
+    }
+  },
+  computed:{
+    rwsBusinessProgress(){
+      return this.rwsBusinessData.dataList.length === 0 ? 0 : Math.floor(this.rwsBusinessData.dataList.filter(item => item.status >= 0).length / this.rwsBusinessData.dataList.length * 100);
+    }
   },
   },
   methods: {
   methods: {
     openText(){
     openText(){
@@ -317,6 +383,7 @@ export default {
       this.$notify({type: 'danger', message: str})
       this.$notify({type: 'danger', message: str})
     },
     },
     data_verify () {
     data_verify () {
+      // console.log(this.dialogData,this.items);return ;
       let dialogData=this.dialogData
       let dialogData=this.dialogData
       dialogData.items=this.items.map(e=>{
       dialogData.items=this.items.map(e=>{
         if(e.reviewer_list.length>0){
         if(e.reviewer_list.length>0){
@@ -401,7 +468,9 @@ export default {
             files: element.files
             files: element.files
           });
           });
       });
       });
-      this.webSocket(data);
+      // console.log(data,this.dialogData);this.isResult = true; return ;
+      this.rwsBusinessSubmit(data.members,data.items);
+      // this.webSocket(data);
     },
     },
     webSocket(data){
     webSocket(data){
     	let {members,items}=data;
     	let {members,items}=data;
@@ -485,6 +554,212 @@ export default {
 
 
       }).catch(() => {});
       }).catch(() => {});
     },
     },
+    initRws(){
+      if (this.rws){
+        this.rws.close();
+        this.rws = null;
+        this.rwsHasAuth = false;
+      }
+      this.rws = new ReconnectingWebSocket(process.env.VUE_APP_WEBSCOKET);
+      this.rws.onopen = this.onWsOpen;
+      this.rws.onmessage = this.onWsMessage;
+      this.rws.onerror = this.onWsError;
+      this.rws.onclose = this.onWsClose;
+    },
+    initRwsBusinessData(){
+      this.rwsBusinessData.dataList = [];
+      this.rwsBusinessData.msgQueue = [];
+      this.rwsBusinessData.result = [];
+      this.rwsBusinessData.items = [];
+    },
+    onWsOpen(){
+      let params = {
+        type:'auth',
+        token: getToken(),
+        machine: generateUUID(),
+      }
+      this.rws.send(JSON.stringify(params));
+    },
+    onWsMessage(event){
+      let msg = event.data ?  JSON.parse(event.data) : null;
+      if (!msg) return;
+      let type = msg.type || 'none';
+      switch (type){
+        case 'ping':
+          this.rws.send('point entry keep connecting');
+          break;
+        case 'auth':
+          this.rwsHasAuth = msg.code === 1;
+          break;
+        case 'pea':
+        case 'peb':
+          this.rwsBusinessData.result.push(msg);
+          let businessId = msg.result.task.msg.businessId;
+          this.rwsBusinessData.dataList.forEach(item => {
+            if (item.businessId !== businessId) return;
+            item.status = msg.result.status;
+            item.msg = msg.result.msg;
+          })
+          this.rwsPointEntry();
+          break;
+      }
+    },
+    onWsError(event){
+      console.log('on ws error',event);
+      this.rwsHasAuth = false;
+    },
+    onWsClose(event){
+      console.log('on ws close',event)
+      this.rwsHasAuth = false;
+    },
+    clearRws(){
+      if (this.rws) this.rws.close();
+      this.rws = null;
+      this.rwsHasAuth = false;
+      this.initRwsBusinessData();
+    },
+    rwsPointEntry(){
+      let msg = this.rwsBusinessData.msgQueue.shift();
+      if (!msg) return;
+      this.rwsBusinessData.dataList.forEach(item => {
+        if (item.businessId !== msg.businessId) return;
+        item.status = -1;
+        item.msg = '处理中';
+      })
+
+      this.rws.send(JSON.stringify(msg));
+    },
+    rwsBusinessSubmit(members,items){
+      if (!members || members.length <= 0 || !items || items.length <= 0) {
+        this.showMessage('规则/分类以及录入对象必须选择');
+        return;
+      }
+
+      let employeeMap = {}
+      this.rwsBusinessData.employees.forEach(employee => {
+        employeeMap[employee.id] = employee;
+      });
+      let businessId = 1;
+      this.initRwsBusinessData();   //清空提交业务数据
+      members.forEach(memberId => {
+        items.forEach(item => {
+          item.type = this.ptId === 2 ? 'pea' : 'peb';
+          item.employee_id = memberId;
+          item.employee_name = employeeMap[memberId] ? employeeMap[memberId].name : '';
+          item.status = -2;
+          item.msg = '待处理';
+          item.businessId = businessId;
+          this.rwsBusinessData.dataList.push(JSON.parse(JSON.stringify(item)))
+          businessId++;
+
+          /*队列数据*/
+          let msg = {
+            type:item.type,
+            employee_id:item.employee_id,
+            event_time:item.event_time,
+            files:item.files,
+            item_id:item.item_id,
+            point:item.point,
+            pt_id:item.pt_id,
+            remark:item.remark,
+            reviewer_id:item.reviewer_id,
+            rule_id:item.rule_id,
+            businessId:item.businessId,
+          }
+          this.rwsBusinessData.msgQueue.push(JSON.parse(JSON.stringify(msg)))
+        })
+      })
+      this.rwsBusinessData.showBusiness = true;
+
+
+      /*开始提交*/
+      this.rwsPointEntry();
+    },
+    rwsBusinessVerify(){
+      if (this.items.length === 0) {
+        this.showMessage("请选择规则或者分类");
+        return false;
+      }
+
+      if (this.rwsBusinessData.employees.length === 0) {
+        this.showMessage("请选择录入对象");
+        return false;
+      }
+
+      this.rwsBusinessData.items = this.items.map(item => {
+        item.reviewer_id = item.reviewer_list.length > 0 ? item.reviewer_list[0].id : '';
+        return item;
+      })
+
+
+      let userMaxPoint = null;
+      let userMinPoint = null;
+
+      this.$userInfo().point_config.point_limit.forEach(point => {
+        if (this.ptId !== point.pt_id) return;
+        userMaxPoint = Math.abs(point.point);
+        userMinPoint = userMaxPoint * -1;
+      });
+
+
+      let members = this.rwsBusinessData.employees.map(employee => employee.id);
+      let items = [];
+
+      // for ([item,index] of this.rwsBusinessData.items){
+      for (var i = 0; i < this.rwsBusinessData.items.length; i++){
+        let item = this.rwsBusinessData.items[i];
+        items.push({
+          rule_id: item.rule_id || 0,
+          item_id: item.item_id || 0,
+          point: item.point,
+          remark: item.remark,
+          event_time: item.event_time,
+          pt_id: this.ptId,
+          reviewer_id: item.reviewer_id || 0,
+          files: item.files
+        })
+
+        if (item.point === 0){
+          this.showMessage(`第${i + 1}条奖扣输入积分分值不能为0`);
+          return false;
+        }
+        if (!item.remark){
+          this.showMessage(`第${i + 1}条奖扣请输入事件内容及描述`);
+          return false;
+        }
+
+        /*非创始人并且奖扣A分/指定分类/企业配置规则内要验证权限分时,验证权限分*/
+        if (!this.isCreator && (this.ptId === 2 || !this.rule_switch || this.$userInfo().site_config.rule_limit_check > 0) && userMaxPoint !== null && userMinPoint !== null){
+          if (item.reviewer_id > 0) continue;
+
+          if (item.point > 0 && item.point > userMaxPoint){
+            this.showMessage(`第${i + 1}条奖扣输入积分分值超出权限分,请选择审批人递交`);
+            return false;
+          }else if (item.point <= 0 && item.point < userMinPoint){
+            this.showMessage(`第${i + 1}`);
+            return false;
+          }
+        }
+      }
+
+      this.rwsBusinessSubmit(members,items);
+    },
+
+    rwsClipResult(event){
+      const clipboard = new Clipboard(event.target,{
+        text: () => JSON.stringify(this.rwsBusinessData.result)
+      });
+      clipboard.on('success',() => {
+        this.$notify({type: 'info', message: '复制成功'});
+        clipboard.destroy();
+      });
+      clipboard.on('error', () => {
+        this.$notify({type: 'info', message: '复制失败,请联系系统管理员'});
+        clipboard.destroy();
+      });
+      clipboard.onClick(event);
+      // navigator.clipboard.writeText(JSON.stringify(this.rwsBusinessData.result));
+      // this.$notify({type: 'info', message: '结果已经复制到剪切板'})
   },
   },
   created () {
   created () {
     this.itemRule=[];
     this.itemRule=[];
@@ -503,6 +778,10 @@ export default {
     this.$nextTick(()=>{
     this.$nextTick(()=>{
       this.rule_switch=true;
       this.rule_switch=true;
     })
     })
+    this.initRws();
+  },
+  beforeDestroy() {
+    this.clearRws();
   }
   }
 }
 }
 </script>
 </script>

+ 22 - 16
src/point/view/integral/rule_category.vue

@@ -1,11 +1,11 @@
 <template>
 <template>
   <div>
   <div>
     <van-nav-bar title="积分规则" left-text="返回" left-arrow class="headerbar no-down-icon">
     <van-nav-bar title="积分规则" left-text="返回" left-arrow class="headerbar no-down-icon">
-      <template slot="right">
-        <van-dropdown-menu duration="0.3" text="text" class="department_right_nav" v-if="this.getRole_noe">
-          <van-dropdown-item title="+" @change="plus_menu" :options="options" />
-        </van-dropdown-menu>
-      </template>
+<!--      <template slot="right">-->
+<!--        <van-dropdown-menu duration="0.3" text="text" class="department_right_nav" v-if="this.getRole_noe">-->
+<!--          <van-dropdown-item title="+" @change="plus_menu" :options="options" />-->
+<!--        </van-dropdown-menu>-->
+<!--      </template>-->
 
 
       <template slot="left" v-if="pid > 0">
       <template slot="left" v-if="pid > 0">
         <div @click="back">
         <div @click="back">
@@ -13,7 +13,7 @@
           <span class="van-nav-bar__text">返回</span>
           <span class="van-nav-bar__text">返回</span>
         </div>
         </div>
       </template>
       </template>
-      <template slot="left" v-if="pid == 0">
+      <template slot="left" v-else-if="pid === 0">
         <div @click="$route_back">
         <div @click="$route_back">
           <van-icon name="arrow-left" />
           <van-icon name="arrow-left" />
           <span class="van-nav-bar__text">返回</span>
           <span class="van-nav-bar__text">返回</span>
@@ -23,23 +23,24 @@
     <van-search v-model="keyword" placeholder="请输入分类名称或规则内容" />
     <van-search v-model="keyword" placeholder="请输入分类名称或规则内容" />
     <div class="dept_path" v-show="pid_list_arr.length > 0">
     <div class="dept_path" v-show="pid_list_arr.length > 0">
       <a href="javascript:void(0);" @click="back_by_index(0)">全部</a>
       <a href="javascript:void(0);" @click="back_by_index(0)">全部</a>
-      <a v-for="(item, index) in pid_list_arr" :key="index" href="javascript:void(0);" @click="back_by_index(index + 1)">
-        <van-icon name="arrow" />
+      <a v-for="(item, index) in pid_list_arr" :key="index" href="javascript:void(0);" @click="back_by_index(index + 1)" style="margin-left: 0.1rem;">
+        <van-icon name="arrow" size="12" />
         {{ item.name }}
         {{ item.name }}
       </a>
       </a>
     </div>
     </div>
     <div class="body_com" :class="{ show_dept_path: pid_list_arr.length > 0 }">
     <div class="body_com" :class="{ show_dept_path: pid_list_arr.length > 0 }">
       <scroller :on-refresh="get_department_list" :isInitRefresh="false">
       <scroller :on-refresh="get_department_list" :isInitRefresh="false">
         <van-cell-group v-if="pid > 0 && keyword == ''">
         <van-cell-group v-if="pid > 0 && keyword == ''">
-          <van-cell :title="pid_list_arr[pid_list_arr.length - 1].name" class="employee_cell" @click="edit_cate">
+<!--          <van-cell :title="pid_list_arr[pid_list_arr.length - 1].name" class="employee_cell" @click="edit_cate">-->
+          <van-cell :title="pid_list_arr[pid_list_arr.length - 1].name" class="employee_cell">
             <template slot="icon">
             <template slot="icon">
               <img src="static/images/e66f.jpg" class="employee_cell_head_img" />
               <img src="static/images/e66f.jpg" class="employee_cell_head_img" />
             </template>
             </template>
 
 
-            <van-icon v-if="!select_mode && this.getRole_noe" name="edit" slot="right-icon" />
-            <template v-else slot="right-icon">
-              <span></span>
-            </template>
+<!--            <van-icon v-if="!select_mode && this.getRole_noe" name="edit" slot="right-icon" />-->
+<!--            <template v-else slot="right-icon">-->
+<!--              <span></span>-->
+<!--            </template>-->
           </van-cell>
           </van-cell>
         </van-cell-group>
         </van-cell-group>
 
 
@@ -61,7 +62,8 @@
         </van-cell-group>
         </van-cell-group>
 
 
         <van-cell-group v-for="(item, index) in list" :key="index" v-show="item.remark.indexOf(keyword) >= 0">
         <van-cell-group v-for="(item, index) in list" :key="index" v-show="item.remark.indexOf(keyword) >= 0">
-          <van-cell :title="item.remark" class="employee_cell rule_list_item" @click="employee_click(item)">
+<!--          <van-cell :title="item.remark" class="employee_cell rule_list_item" @click="employee_click(item)">-->
+          <van-cell :title="item.remark" class="employee_cell rule_list_item">
             <template slot="label">
             <template slot="label">
               <div v-show="item.cycle_type == 2"><van-tag size="medium" plain>自动规则</van-tag></div>
               <div v-show="item.cycle_type == 2"><van-tag size="medium" plain>自动规则</van-tag></div>
               <span class="record green" v-if="item.min_point < 0">{{ item.range_type == 1 ? item.min_point : item.min_point + '~' + item.max_point }}</span>
               <span class="record green" v-if="item.min_point < 0">{{ item.range_type == 1 ? item.min_point : item.min_point + '~' + item.max_point }}</span>
@@ -72,7 +74,7 @@
           </van-cell>
           </van-cell>
         </van-cell-group>
         </van-cell-group>
 
 
-        <van-empty description="暂无内容" v-show="list != null && rule_category_list != null && list.length == 0 && rule_category_list.length == 0" />
+        <van-empty description="暂无规则,请在PC端设置" v-show="list != null && rule_category_list != null && list.length === 0 && rule_category_list.length === 0" />
       </scroller>
       </scroller>
     </div>
     </div>
 
 
@@ -555,6 +557,8 @@ export default {
   margin-right: 0.1rem;
   margin-right: 0.1rem;
 }
 }
 .dept_path a {
 .dept_path a {
+  display: flex;
+  align-items: center;
   color: #238dfa;
   color: #238dfa;
   font-size: 0.28rem;
   font-size: 0.28rem;
 }
 }
@@ -565,13 +569,15 @@ export default {
   vertical-align: middle;
   vertical-align: middle;
 }
 }
 .dept_path {
 .dept_path {
+  display: flex;
+  align-items: center;
+  background-color: #fff;
   height: 0.6rem;
   height: 0.6rem;
   position: relative;
   position: relative;
   font-size: 0.32rem;
   font-size: 0.32rem;
   line-height: 0.4rem;
   line-height: 0.4rem;
   overflow-x: scroll;
   overflow-x: scroll;
   padding: 0 0.32rem;
   padding: 0 0.32rem;
-  background-color: #fff;
 }
 }
 .dept_path:after {
 .dept_path:after {
   content: ' ';
   content: ' ';

+ 3 - 2
src/point/view/integral/rule_item_edit.vue

@@ -1,6 +1,7 @@
 <template>
 <template>
   <div class="rule_item_edit_box">
   <div class="rule_item_edit_box">
-    <van-nav-bar title="修改规则" left-text="返回" @click-left="$route_back" left-arrow right-text="删除" @click-right="del"></van-nav-bar>
+<!--    <van-nav-bar title="修改规则" left-text="返回" @click-left="$route_back" left-arrow right-text="删除" @click-right="del"></van-nav-bar>-->
+    <van-nav-bar title="规则内容" left-text="返回" @click-left="$route_back" left-arrow ></van-nav-bar>
     <div class="body_com has_header">
     <div class="body_com has_header">
       <scroller>
       <scroller>
         <van-cell-group>
         <van-cell-group>
@@ -29,7 +30,7 @@
             </van-radio-group>
             </van-radio-group>
           </van-cell>
           </van-cell>
         </van-cell-group>
         </van-cell-group>
-        <div style="padding:0.32rem;"><van-button size="large" @click="data_verify" type="info">保存</van-button></div>
+        <div style="padding:0.32rem;"><van-button size="large" disabled @click="data_verify" type="info">保存</van-button></div>
       </scroller>
       </scroller>
     </div>
     </div>
   </div>
   </div>

+ 133 - 13
src/point/view/pointHome.vue

@@ -53,8 +53,9 @@
           </van-grid-item>
           </van-grid-item>
           <van-grid-item @click="goDeptRank">
           <van-grid-item @click="goDeptRank">
             <template #text>
             <template #text>
-              <van-loading v-if="!deptRank" type="spinner" size="10px"/>
-              <span class="van-grid-item__text" v-else>部门对比</span>
+<!--              <van-loading v-if="!deptRank" type="spinner" size="10px"/>-->
+<!--              <span class="van-grid-item__text" v-else>部门对比</span>-->
+              <span class="van-grid-item__text">部门对比</span>
             </template>
             </template>
             <template #icon>
             <template #icon>
               <img src="static/images/callback1.png" style="-webkit-touch-callout: none;"/>
               <img src="static/images/callback1.png" style="-webkit-touch-callout: none;"/>
@@ -168,12 +169,14 @@
         </van-row>
         </van-row>
       </div>
       </div>
 
 
-<!--  团队PK    -->
-      <div class="rankingList" style="border-top: 0.2rem solid #f1f1f1;" v-if="pk.pkDocList.length > 0">
+      <!--  团队PK    -->
+      <div class="rankingList"  v-if="pk.pkDocList.length > 0">
         <van-cell title="团队PK" :value="pk.pkTimeScopeStr" is-link @click="openCalendar"></van-cell>
         <van-cell title="团队PK" :value="pk.pkTimeScopeStr" is-link @click="openCalendar"></van-cell>
         <van-tabs
         <van-tabs
           v-model="pk.pkDocIndex"
           v-model="pk.pkDocIndex"
           @click="clickPkDoc"
           @click="clickPkDoc"
+          animated
+          swipeable
         >
         >
           <van-tab v-for="(doc,index) in pk.pkDocList" :key="index" :title="doc.name">
           <van-tab v-for="(doc,index) in pk.pkDocList" :key="index" :title="doc.name">
             <van-cell-group v-if="pk.pkTeamList.length > 0">
             <van-cell-group v-if="pk.pkTeamList.length > 0">
@@ -236,6 +239,8 @@ import {getToken, setToken} from '@/utils/auth';
 import moment, {min} from 'moment';
 import moment, {min} from 'moment';
 import Vue from 'vue';
 import Vue from 'vue';
 import { NoticeBar, Swipe, SwipeItem, Cell, Dialog,Popup,Loading  } from 'vant';
 import { NoticeBar, Swipe, SwipeItem, Cell, Dialog,Popup,Loading  } from 'vant';
+import ReconnectingWebSocket from "reconnecting-websocket";
+import {generateUUID} from "../../utils/auth";
 Vue.use(NoticeBar)
 Vue.use(NoticeBar)
   .use(Swipe)
   .use(Swipe)
   .use(SwipeItem)
   .use(SwipeItem)
@@ -247,7 +252,7 @@ export default {
   name: 'pointHome',
   name: 'pointHome',
   data() {
   data() {
     return {
     return {
-      deptRank:false,
+      // deptRank:false,
       userMonth:{task:{reward:{},deduction:{},exec:{}},ratio:{}},
       userMonth:{task:{reward:{},deduction:{},exec:{}},ratio:{}},
 
 
       // rankingList: [], // 我的排名列表
       // rankingList: [], // 我的排名列表
@@ -305,6 +310,8 @@ export default {
         left:0,
         left:0,
         top:0
         top:0
       },
       },
+      rws:null,
+      rwsHasAuth:false,
     };
     };
   },
   },
   created() {
   created() {
@@ -339,6 +346,9 @@ export default {
       this.getMenu(res);
       this.getMenu(res);
     });
     });
   },
   },
+  beforeDestroy() {
+    this.clearRws();
+  },
   methods: {
   methods: {
     timeScopeThisWeek(){
     timeScopeThisWeek(){
       this.pkTimeScope = [new Date(moment().startOf('week').format('YYYY-MM-DD')),new Date(moment().endOf('week').format('YYYY-MM-DD'))]
       this.pkTimeScope = [new Date(moment().startOf('week').format('YYYY-MM-DD')),new Date(moment().endOf('week').format('YYYY-MM-DD'))]
@@ -608,10 +618,11 @@ export default {
       });
       });
       var http1 = this.$axiosUser('get', '/api/pro/integral/statistics', { employee_id: this.userInfo.id, month: this.month }, 'v3'); // 获取个人统计
       var http1 = this.$axiosUser('get', '/api/pro/integral/statistics', { employee_id: this.userInfo.id, month: this.month }, 'v3'); // 获取个人统计
       this.rankingListname(); //排行榜
       this.rankingListname(); //排行榜
-      this.$socketApiTow.authWebSocket(() =>{
-        // this.getPkDocList();    //团队pk
-        this.opneWebSocket();   //本月B分奖扣
-      });
+      // this.$socketApiTow.authWebSocket(() =>{
+      //   // this.getPkDocList();    //团队pk
+      //   this.opneWebSocket();   //本月B分奖扣
+      // });
+      this.initRws();   //初始化websocket数据
 
 
       Promise.all([http1]).then(res => {
       Promise.all([http1]).then(res => {
           if (res[0].data.code === 1) {
           if (res[0].data.code === 1) {
@@ -718,7 +729,8 @@ export default {
       this.saveScrollerPosition();
       this.saveScrollerPosition();
       if (this.pk.currentDocIndex !== index && this.pk.pkDocList.length > index){
       if (this.pk.currentDocIndex !== index && this.pk.pkDocList.length > index){
         this.pk.currentDocIndex = index;
         this.pk.currentDocIndex = index;
-        this.getPkRankList(this.pk.pkDocList[index].id)
+        // this.getPkRankList(this.pk.pkDocList[index].id)
+        this.rwsPkRankList(this.pk.pkDocList[index].id)
       }
       }
     },
     },
     getPkDocList(){
     getPkDocList(){
@@ -747,7 +759,7 @@ export default {
         this.pk.teamLoading = false;
         this.pk.teamLoading = false;
 
 
         //ws数据初始化完成,部门排名才可以点击
         //ws数据初始化完成,部门排名才可以点击
-        this.deptRank = true;
+        // this.deptRank = true;
       })
       })
       this.$nextTick(() => {
       this.$nextTick(() => {
         setTimeout(() => {
         setTimeout(() => {
@@ -756,11 +768,110 @@ export default {
       })
       })
     },
     },
     goDeptRank(){
     goDeptRank(){
-      if (!this.deptRank) return;
+      // if (!this.deptRank) return;
       this.$router.push({ name: 'dept_rank' });
       this.$router.push({ name: 'dept_rank' });
     },
     },
     goAppeal(){
     goAppeal(){
       this.$router.push({name:'appeal'})
       this.$router.push({name:'appeal'})
+    },
+    initRws(){
+      if (this.rws){
+        this.rws.close();
+        this.rws = null;
+        this.rwsHasAuth = false;
+      }
+      this.rws = new ReconnectingWebSocket(process.env.VUE_APP_WEBSCOKET_TOW);
+      this.rws.onopen = this.onWsOpen;
+      this.rws.onmessage = this.onWsMessage;
+      this.rws.onerror = this.onWsError;
+      this.rws.onclose = this.onWsClose;
+    },
+    onWsOpen(){
+      let params = {
+        type:'auth',
+        token: getToken(),
+        machine: generateUUID(),
+      }
+      this.rws.send(JSON.stringify(params));
+    },
+    onWsMessage(event){
+      let msg = event.data ?  JSON.parse(event.data) : null;
+      if (!msg) return;
+      let type = msg.type || 'none';
+      switch (type){
+        case 'ping':
+          this.rws.send('point home keep connecting');
+          break;
+        case 'auth':
+          this.rwsHasAuth = msg.code === 1;
+          this.rwsEsInfo();
+          this.rwsPkDoc();
+          break;
+        case 'es_info':
+          if (msg.code !== 1) return;
+          let data = msg.result;
+          let task = data.task;
+          let ratio = task.ratio.enable === 0 ? '-' : `${task.ratio.reward_ratio}:1`;
+          let target_ratio = task.ratio.target <= 0 ? '0:1' : `${task.ratio.target}:1`;
+          data.ratio = {
+            ratio: ratio,
+            target_ratio: target_ratio
+          }
+          this.userMonth=data;
+          break;
+        case 'team_pk':
+          if (msg.code !== 1) return;
+          this.pk.pkTeamList = msg.result.teams;
+          this.pk.teamLoading = false;
+          this.$nextTick(() => {
+            setTimeout(() => {
+              this.restoreScrollerPosition()
+            },50)
+          })
+          break;
+      }
+    },
+    onWsError(event){
+      this.rwsHasAuth = false;
+    },
+    onWsClose(event){
+      this.rwsHasAuth = false;
+    },
+    clearRws(){
+      if (this.rws) this.rws.close();
+      this.rws = null;
+      this.rwsHasAuth = false;
+    },
+    rwsEsInfo(){
+      if (!this.rws || this.rws.readyState !== ReconnectingWebSocket.OPEN || !this.rwsHasAuth) return;
+      let params = {
+        type:'es_info',
+        recorder_id: this.userInfo.id,
+        month:this.month
+      };
+      this.rws.send(JSON.stringify(params))
+    },
+    rwsPkDoc(){
+      this.$axiosUser('get','/api/pro/pk/doc/list/visible')
+        .then(res => {
+          this.pk.pkDocList = res.data.data.list;
+          if(this.pk.pkDocList.length > 0) this.rwsPkRankList(this.pk.pkDocList[0].id)
+        })
+    },
+    rwsPkRankList(docId){
+      if (!this.rws || this.rws.readyState !== ReconnectingWebSocket.OPEN || !this.rwsHasAuth || this.pk.teamLoading) return;
+      if (!this.pk.pkTimeScope || this.pk.pkTimeScope.length !== 2) {
+        this.pk.pkTeamList = [];
+        return;
+      }
+      let type = "team_pk";
+      let params = {
+        type:type,
+        doc_id:docId,
+        start_date:this.$moment(this.pk.pkTimeScope[0]).format("YYYY-MM-DD"),
+        end_date:this.$moment(this.pk.pkTimeScope[1]).format("YYYY-MM-DD"),
+      };
+      this.rws.send(JSON.stringify(params));
     }
     }
   },
   },
   watch: {
   watch: {
@@ -768,7 +879,8 @@ export default {
       this.pk.pkTimeScope[0] = val[0]
       this.pk.pkTimeScope[0] = val[0]
       this.pk.pkTimeScope[1] = val[1]
       this.pk.pkTimeScope[1] = val[1]
       this.pk.pkTimeScopeStr = this.$moment(this.pk.pkTimeScope[0]).format("MM/DD") + "-" + this.$moment(this.pk.pkTimeScope[1]).format("MM/DD");
       this.pk.pkTimeScopeStr = this.$moment(this.pk.pkTimeScope[0]).format("MM/DD") + "-" + this.$moment(this.pk.pkTimeScope[1]).format("MM/DD");
-      if (this.pk.pkDocList.length > this.pk.currentDocIndex) this.getPkRankList(this.pk.pkDocList[this.pk.currentDocIndex].id)
+      // if (this.pk.pkDocList.length > this.pk.currentDocIndex) this.getPkRankList(this.pk.pkDocList[this.pk.currentDocIndex].id)
+      if (this.pk.pkDocList.length > this.pk.currentDocIndex) this.rwsPkRankList(this.pk.pkDocList[this.pk.currentDocIndex].id)
     }
     }
   }
   }
 };
 };
@@ -1077,4 +1189,12 @@ export default {
   background-color: #F1F1F1;
   background-color: #F1F1F1;
 }
 }
 
 
+/deep/ .van-calendar__header-subtitle {
+  width: 100%;
+  font-size: 0.28rem;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
 </style>
 </style>

+ 16 - 0
src/point/view/task/taskFile.vue

@@ -149,6 +149,22 @@
             title="提前奖分"
             title="提前奖分"
             :value="`${info.point_config.ahead_award_point} B分/天`"
             :value="`${info.point_config.ahead_award_point} B分/天`"
           />
           />
+          <van-cell
+            title-class="align_self"
+            value-class="align_self"
+            :border="false"
+            v-if="info.task_file_list.length > 0"
+          >
+            <template #title>
+              <div class="time">
+                <span>任务图片</span>
+                <span>
+                  <van-image v-for="(items, index) in info.task_file_list" :key="index" @click="open_image(info.task_file_list)" width="45" height="45" radius="3" :src="items" />
+                </span>
+              </div>
+            </template>
+          </van-cell>
+
 
 
 
 
 
 

+ 1 - 1
src/utils/auth.js

@@ -241,7 +241,7 @@ export function getTypesName(id) {
 //是否平台管理或者平台创始人
 //是否平台管理或者平台创始人
 export function getIsAdministrator() {
 export function getIsAdministrator() {
   var userInfo = getUserData();
   var userInfo = getUserData();
-  if(userInfo.is_site_owner||userInfo.is_site_manager){
+  if(userInfo.is_site_owner || userInfo.is_site_manager){
     return true
     return true
   }else{
   }else{
     return false
     return false

+ 4 - 2
src/view/body/initHome.vue

@@ -1,7 +1,9 @@
 <template>
 <template>
     <div class="html-box">
     <div class="html-box">
       <van-nav-bar class="left-text-bold" left-text="首页">
       <van-nav-bar class="left-text-bold" left-text="首页">
-       <template slot="right"><van-icon v-if="is_app" class="icon-box"  name="scan" @click="$router.push({ name: 'scanqr' })"></van-icon></template>
+       <template slot="right">
+        <van-icon v-if="is_app" class="icon-box"  name="scan" @click="$router.push({ name: 'scanqr' })"></van-icon>
+        </template>
       </van-nav-bar>
       </van-nav-bar>
       <div class="flex-box-ce" style="padding: 0.16rem 0.32rem;background-color: #FFFAE5;font-size: 0.28rem;" @click="openUrl" v-if="ggData.name">
       <div class="flex-box-ce" style="padding: 0.16rem 0.32rem;background-color: #FFFAE5;font-size: 0.28rem;" @click="openUrl" v-if="ggData.name">
         <van-icon name="bullhorn-o" />
         <van-icon name="bullhorn-o" />
@@ -155,7 +157,7 @@
         shepherd.start();
         shepherd.start();
       },
       },
       ActiveactiveName(val){
       ActiveactiveName(val){
-        this.activeName=val;
+        this.activeName = val;
       },
       },
       initTab(){
       initTab(){
         this.tabs=[
         this.tabs=[

+ 4 - 3
src/view/course/user.vue

@@ -148,7 +148,7 @@
       </van-overlay>
       </van-overlay>
     </div>
     </div>
   </template>
   </template>
-  
+
   <script>
   <script>
   import Clipboard from "clipboard";
   import Clipboard from "clipboard";
   import QRCode from "qrcodejs2";
   import QRCode from "qrcodejs2";
@@ -336,7 +336,7 @@
           e.clearSelection(); //清除选中的文字的选择状态
           e.clearSelection(); //清除选中的文字的选择状态
           that.$toast.success("ID复制成功~");
           that.$toast.success("ID复制成功~");
         });
         });
-  
+
         that.clipboard.on("error", function(e) {
         that.clipboard.on("error", function(e) {
           console.error(e);
           console.error(e);
         });
         });
@@ -347,6 +347,8 @@
           path: url
           path: url
         });
         });
       }
       }
+
+
     }
     }
   };
   };
   </script>
   </script>
@@ -543,4 +545,3 @@
     font-weight: 600;
     font-weight: 600;
   }
   }
   </style>
   </style>
-  

+ 53 - 19
src/view/index.vue

@@ -22,11 +22,11 @@
         </van-tabbar-item>
         </van-tabbar-item>
       </van-tabbar>
       </van-tabbar>
 
 
-      <van-popup v-model="updateVisible" :close-on-click-overlay="false" style="border-radius: 0.15rem; background: #fff0;">
+      <van-popup v-model="updateVisible" :close-on-click-overlay="false" style="border-radius: 0.15rem; background: #fff0; overflow: visible;">
         <div class="buyPopupBody" style="width: 85vw;">
         <div class="buyPopupBody" style="width: 85vw;">
           <div class="buyPopupContent">
           <div class="buyPopupContent">
-            <div class="buyPopupTitle"> {{announcement.type==1? '版本更新':'系统公告'}}</div>
-            <div style="max-height: 400px;overflow-y: auto;font-size: 0.3rem;" v-html="announcement.focus"></div>
+            <div class="buyPopupTitle"> {{announcement.type == 1? '版本更新':'系统公告'}}</div>
+            <div style="padding: 0.5rem 0.3rem 0.3rem 0.3rem; overflow-y: auto;font-size: 0.3rem; box-sizing: border-box;" v-html="announcement.focus"></div>
             <van-row gutter="20">
             <van-row gutter="20">
               <van-col span="12"><van-button block type="info" @click="updateVisible=false">我知道了</van-button></van-col>
               <van-col span="12"><van-button block type="info" @click="updateVisible=false">我知道了</van-button></van-col>
               <van-col span="12"><van-button block type="default" @click="getItemBuyPopupPage">查看详情</van-button></van-col>
               <van-col span="12"><van-button block type="default" @click="getItemBuyPopupPage">查看详情</van-button></van-col>
@@ -182,26 +182,60 @@
     margin-bottom: 0.08rem;
     margin-bottom: 0.08rem;
   }
   }
 
 
+  // .buyPopupBody {
+  //   width: 85vw;
+  // }
+  // .buyPopupContent{
+  //   background: white;
+  //   padding:0.2rem 0.24rem;
+  //   border-radius: 0.15rem;
+  // }
+
+  // .buyPopupTitle{
+  //   background: #1a89fa;
+  //   text-align: center;
+  //   border-radius: 0.1rem;
+  //   font-weight: normal;
+  //   font-size: 0.32rem;
+  //   height: 0.8rem;
+  //   line-height: 0.8rem;
+  //   color: #fff;
+  //   margin-top: 0.24rem;
+  // }
+
   .buyPopupBody {
   .buyPopupBody {
     width: 85vw;
     width: 85vw;
+    .buyPopupContent {
+      position: relative;
+      background: white;
+      padding: 0 5vw 5vw 5vw;
+      border-radius: 0.15rem;
+      .buyPopupTitle {
+        background: #1a89fa;
+        position: absolute;
+        left: 0.6rem;
+        right: 0.6rem;
+        top: -0.3rem;
+        text-align: center;
+        border-radius: 0.1rem;
+        line-height: 2;
+        font-weight: normal;
+        font-size: 0.36rem;
+        color: #fff;
+      }
+      .buyPopupTxt {
+        font-size: 0.32rem;
+        line-height: 1.8;
+        padding-top: 0.8rem;
+      }
+      .buyPopupTel {
+        color: #1a89fa;
+        font-weight: bold;
+      }
+    }
   }
   }
-  .buyPopupContent{
-    background: white;
-    padding:0.2rem 0.24rem;
-    border-radius: 0.15rem;
-  }
+
   .buyPopupContent /deep/ img,.buyPopupContent /deep/ ul,.buyPopupContent /deep/ li,.buyPopupContent /deep/ p{
   .buyPopupContent /deep/ img,.buyPopupContent /deep/ ul,.buyPopupContent /deep/ li,.buyPopupContent /deep/ p{
     width: 100%;
     width: 100%;
   }
   }
-  .buyPopupTitle{
-    background: #1a89fa;
-    text-align: center;
-    border-radius: 0.1rem;
-    font-weight: normal;
-    font-size: 0.32rem;
-    height: 0.8rem;
-    line-height: 0.8rem;
-    color: #fff;
-    margin-top: 0.24rem;
-  }
 </style>
 </style>

+ 27 - 2
src/view/system/scan_qr.vue

@@ -30,7 +30,7 @@ export default {
   },
   },
   watch:{
   watch:{
     $route(to, from) {
     $route(to, from) {
-      if(to.path=='/home'&&this.barcode){
+      if(to.path=='/home' && this.barcode){
         this.barcode.close();
         this.barcode.close();
       }
       }
     }
     }
@@ -39,7 +39,7 @@ export default {
     routeBack(is){
     routeBack(is){
       this.barcode.close();
       this.barcode.close();
       this.$nextTick(()=>{
       this.$nextTick(()=>{
-          this.$route_back()
+        this.$route_back()
       })
       })
     },
     },
     backButtons(){
     backButtons(){
@@ -137,7 +137,32 @@ export default {
       });
       });
     },
     },
 
 
+    backChange() {
+      this.barcode.close();
+      this.$nextTick(()=>{
+        this.$route_back()
+      })
+    },
+    wulifanhui() {
+      console.log("监听到了");
+    }
+
+  },
+  mounted(){
+    // 如果支持 popstate 一般移动端都支持了
+    if (window.history && window.history.pushState) {
+      // 往历史记录里面添加一条新的当前页面的url
+      // history.pushState(null, null, document.URL);
+      // 给 popstate 绑定一个方法 监听页面刷新
+      window.addEventListener('popstate', this.backChange, false); //false阻止默认事件
+    }
   },
   },
+
+  destroyed(){
+    window.removeEventListener('popstate', this.wulifanhui, false);//false阻止默认事件
+  },
+
+
   created () {
   created () {
     setTimeout(() => {
     setTimeout(() => {
       plus.navigator.setStatusBarStyle('light')
       plus.navigator.setStatusBarStyle('light')

+ 4 - 3
src/view/user/account.vue

@@ -17,7 +17,7 @@
           <span class="per-info__tel">{{ user_info.name }}</span>
           <span class="per-info__tel">{{ user_info.name }}</span>
         </template>
         </template>
       </van-cell> -->
       </van-cell> -->
-      
+
       <van-cell title="手机号" is-link to="user_mobile">
       <van-cell title="手机号" is-link to="user_mobile">
         <template slot="default">
         <template slot="default">
           <span class="per-info__tel">{{ user_info.tel | mobile }}</span>
           <span class="per-info__tel">{{ user_info.tel | mobile }}</span>
@@ -67,7 +67,7 @@ export default {
       auths: [],
       auths: [],
       aweixin: null,
       aweixin: null,
       wo_token:'',
       wo_token:'',
-      isUploader:this.$getCache('isUploader'),
+      isUploader: this.$getCache('isUploader'),
     };
     };
   },
   },
   created() {
   created() {
@@ -89,7 +89,7 @@ export default {
         message: '当您在我们的产品中使用拍照、拍摄、扫描二维码、图片上传等功能时,我们需要获取您设备的相机权限,以便您正常使用图片上传、图片下载、附件上传、头像设置等服务',
         message: '当您在我们的产品中使用拍照、拍摄、扫描二维码、图片上传等功能时,我们需要获取您设备的相机权限,以便您正常使用图片上传、图片下载、附件上传、头像设置等服务',
       }).then(() => {
       }).then(() => {
         this.$setCache('isUploader',true)
         this.$setCache('isUploader',true)
-        this.isUploader=true
+        this.isUploader = true
       })
       })
     },
     },
     // 判断是否获取微信登录认证
     // 判断是否获取微信登录认证
@@ -294,6 +294,7 @@ export default {
     background-color: #fff;
     background-color: #fff;
     justify-content: center;
     justify-content: center;
     touch-action: none;
     touch-action: none;
+    color: #ff5f4e;
   }
   }
 }
 }
 </style>
 </style>

+ 52 - 24
src/view/user/company_info.vue

@@ -1,20 +1,22 @@
 <template>
 <template>
   <div>
   <div>
     <van-nav-bar :title="title" left-text="返回" @click-left="$route_back" left-arrow></van-nav-bar>
     <van-nav-bar :title="title" left-text="返回" @click-left="$route_back" left-arrow></van-nav-bar>
-    <div class="body_com has_header">
-      <scroller>
-        <van-cell-group>
-          <van-cell title="公司LOGO" is-link class="company_info">
-            <template slot="default">
-              <img :src="site_info.logo_url?site_info.logo_url:'static/images/default_company_logo.png'" class="needsclick company_img" @click.stop="select_img" />
-            </template>
-          </van-cell>
-        </van-cell-group>
-        <van-cell-group class="company_name">
-          <van-cell title="公司名称" is-link :value="site_info.name" @click="showPopup" />
-        </van-cell-group>
-      </scroller>
-      <vue-img-cropper
+    <van-cell-group>
+      <van-cell title="公司LOGO" is-link class="company_info">
+        <template solt="default">
+          <vue-img-cropper v-if="isUploader" ref="cropper" :height="400" :width="400" :maxScale="6" :compressionRatio="0.5"  @cutImg="showCutImg" @showLoading="showLoading" @hideLoading="hideLoading">
+            <img :src="site_info.logo_url?site_info.logo_url : 'static/images/default_company_logo.png'" class="needsclick company_img" />
+          </vue-img-cropper>
+          <div v-else @click="openText()">
+            <img :src="site_info.logo_url?site_info.logo_url : 'static/images/default_company_logo.png'" class="needsclick company_img" />
+          </div>
+        </template>
+      </van-cell>
+    </van-cell-group>
+    <van-cell-group class="company_name">
+      <van-cell title="公司名称" is-link :value="site_info.name" @click="showPopup" />
+    </van-cell-group>
+      <!-- <vue-img-cropper
         ref="cropper"
         ref="cropper"
         :height="400"
         :height="400"
         :width="400"
         :width="400"
@@ -24,7 +26,7 @@
         @showLoading="showLoading"
         @showLoading="showLoading"
         @hideLoading="hideLoading"
         @hideLoading="hideLoading"
         @showError="showError">
         @showError="showError">
-      </vue-img-cropper>
+      </vue-img-cropper> -->
 
 
       <van-dialog v-model="show" title="修改公司名称" class="edit_com_popup" show-cancel-button @confirm="save_btn">
       <van-dialog v-model="show" title="修改公司名称" class="edit_com_popup" show-cancel-button @confirm="save_btn">
         <van-cell-group>
         <van-cell-group>
@@ -56,7 +58,8 @@ export default {
       user_info: this.$userInfo(),
       user_info: this.$userInfo(),
       click_count: 0,
       click_count: 0,
       edit_com_name: '',
       edit_com_name: '',
-      company_info:{}
+      company_info:{},
+      isUploader: this.$getCache('isUploader'),
     }
     }
   },
   },
   // 组件
   // 组件
@@ -66,14 +69,39 @@ export default {
   },
   },
   // 方法
   // 方法
   methods: {
   methods: {
-    select_img () {
-      let self = this
-      if (this.click_count == 0) {
-        self.$refs.cropper.getImg()
-        setTimeout(function () {
-          self.click_count = 0
-        }, 20)
-      }
+    // select_img () {
+    //   if (this.click_count == 0) {
+    //     // if(self.$getCache("isUploader")) {
+    //     //   self.$refs.cropper.getImg()
+    //     //   // setTimeout(() => {
+    //     //   //   self.click_count = 0
+    //     //   // }, 20)
+    //     // }else {
+
+    //     // }
+    //     this.$dialog.confirm({
+    //       title: '权限获取',
+    //       message: '当您在我们的产品中使用拍照、拍摄、扫描二维码、图片上传等功能时,我们需要获取您设备的相机权限,以便您正常使用图片上传、图片下载、附件上传、头像设置等服务',
+    //     }).then(() => {
+    //       this.$refs.cropper.getImg()
+
+    //       // setTimeout(() => {
+    //       //   this.click_count = 0
+    //       // }, 20)
+    //     })
+
+    //   }
+    // },
+
+    openText(){
+      // 功道云需要使用媒体、相册、文件等权限,以便您正常使用图片上传、图片分享、图片下载等服务。
+      this.$dialog.confirm({
+        title: '权限获取',
+        message: '当您在我们的产品中使用拍照、拍摄、扫描二维码、图片上传等功能时,我们需要获取您设备的相机权限,以便您正常使用图片上传、图片下载、附件上传、头像设置等服务',
+      }).then(() => {
+        this.$setCache('isUploader',true)
+        this.isUploader = true
+      })
     },
     },
     showCutImg (d) {
     showCutImg (d) {
       this.$toast.loading({
       this.$toast.loading({

+ 20 - 10
src/view/user/department.vue

@@ -25,7 +25,9 @@
       <scroller ref="scroller_com"  :isInitRefresh="false" :on-refresh="refresh">
       <scroller ref="scroller_com"  :isInitRefresh="false" :on-refresh="refresh">
 
 
         <div style="padding: 0.2rem 0.32rem;background-color: #fff;" @click="parent_click">
         <div style="padding: 0.2rem 0.32rem;background-color: #fff;" @click="parent_click">
-          <div style="background-color: #f7f8fa;border-radius:0.04rem;color:#c8c9cc;padding: 0.12rem 0.32rem;"><van-icon name="search" /> 请输入搜索姓名</div>
+          <div style="background-color: #f7f8fa;border-radius:0.04rem;color:#c8c9cc;padding: 0.12rem 0.32rem;">
+            <van-icon name="search" /> 请输入搜索姓名
+          </div>
         </div>
         </div>
 <!--
 <!--
         <van-search  placeholder="请输入搜索姓名" :disabled="true" @click="parent_click" /> -->
         <van-search  placeholder="请输入搜索姓名" :disabled="true" @click="parent_click" /> -->
@@ -40,14 +42,18 @@
 
 
         <div>
         <div>
           <van-cell-group :border="false" v-show="pid==0" >
           <van-cell-group :border="false" v-show="pid==0" >
-            <van-cell label-class="employee_count"
-            :title="company_info.name"
-            :border="false" clickable class="company_info"
-            @click="edit_site_info"
-            :is-link="getRole_noe"
-            :label="total +'人'">
+            <van-cell
+              label-class="employee_count"
+              :title="company_info.name"
+              :border="false"
+              clickable
+              class="company_info"
+              @click="edit_site_info"
+              :is-link="getRole_noe"
+              :label="total +'人'"
+            >
               <template slot="icon">
               <template slot="icon">
-                <img :src="company_info.logo_url?company_info.logo_url:'static/images/default_company_logo.png'" class="company_dept_img"/>
+                <img :src="company_info.logo_url ? company_info.logo_url : 'static/images/default_company_logo.png'" class="company_dept_img"/>
               </template>
               </template>
             </van-cell>
             </van-cell>
           </van-cell-group>
           </van-cell-group>
@@ -60,7 +66,7 @@
             </van-cell>
             </van-cell>
           </van-cell-group>
           </van-cell-group>
           <div v-show="pid != 0">
           <div v-show="pid != 0">
-            <div class="fontColorC" style="padding: 0 0.32rem;font-size: 0.28rem;">管理员</div>
+            <div class="fontColorC" style="padding: 0.1rem 0.32rem;font-size: 0.28rem;">管理员</div>
             <div class="manager flex-box flex-v-ce">
             <div class="manager flex-box flex-v-ce">
                <div class="flex-box flex-v-ce flex-1 flex-d-wrap" style="padding-right: 0.2rem;" v-if="showDepart">
                <div class="flex-box flex-v-ce flex-1 flex-d-wrap" style="padding-right: 0.2rem;" v-if="showDepart">
                   <van-tag closeable size="medium" type="primary" @close="closeManager(item)" v-for="(item,index) in dept_info.manager" :key="index" style="margin-right: 5px;margin-top: 5px;">{{item.name}}</van-tag>
                   <van-tag closeable size="medium" type="primary" @close="closeManager(item)" v-for="(item,index) in dept_info.manager" :key="index" style="margin-right: 5px;margin-top: 5px;">{{item.name}}</van-tag>
@@ -68,7 +74,7 @@
                <div v-else style="color: #F56C6C;font-size: 14px" class="flex-1">管理员未设置</div>
                <div v-else style="color: #F56C6C;font-size: 14px" class="flex-1">管理员未设置</div>
                <van-button icon="plus" type="info" size="small" plain @click="show_dept_selector=true" />
                <van-button icon="plus" type="info" size="small" plain @click="show_dept_selector=true" />
             </div>
             </div>
-            <div style="text-align: center;font-size: 12px;" class="fontColorC">只能选择直属部门的员工作为部门管理员</div>
+            <div style="text-align: center; padding: 0.2rem 0 0 0; font-size: 12px;" class="fontColorC">只能选择直属部门的员工作为部门管理员</div>
           </div>
           </div>
           <van-cell-group>
           <van-cell-group>
             <van-cell  v-if="isApp && false" is-link title="邀请成员" @click="show_share" class="new_employee_cell employee_cell">
             <van-cell  v-if="isApp && false" is-link title="邀请成员" @click="show_share" class="new_employee_cell employee_cell">
@@ -786,6 +792,8 @@ export default {
   }
   }
   .pageIndexBtnText{font-size:0.24rem;}
   .pageIndexBtnText{font-size:0.24rem;}
 .dept_path a {
 .dept_path a {
+  display: flex;
+  align-items: center;
   color: #238dfa;
   color: #238dfa;
   font-size: 0.28rem;
   font-size: 0.28rem;
 }
 }
@@ -800,6 +808,8 @@ export default {
   vertical-align: middle;
   vertical-align: middle;
 }
 }
 .dept_path {
 .dept_path {
+  display: flex;
+  align-items: center;
   position: relative;
   position: relative;
   font-size: 0.32rem;
   font-size: 0.32rem;
   line-height: 0.4rem;
   line-height: 0.4rem;

+ 2 - 0
src/view/user/employee_info.vue

@@ -240,6 +240,8 @@ export default {
     padding-top: 0;
     padding-top: 0;
     font-size:0.32rem;
     font-size:0.32rem;
     color: #323233;
     color: #323233;
+    display: flex;
+    align-items: center;
     &.disabled{
     &.disabled{
       color: #959595;
       color: #959595;
     }
     }

Some files were not shown because too many files changed in this diff