Ver código fonte

Merge branch 'master' of http://git.wdklian.com/allen/ncs_ui

vothin 3 anos atrás
pai
commit
5e382c992f

+ 10 - 0
languages/zh-CN.js

@@ -460,17 +460,23 @@ module.exports = {
     actionType: '交互类型',
     actionEnd: '交互结果',
     actionTime: '交互次数',
+    actionTime2: '通话次数',
     success: '成功',
     successInteraction: '已响应交互',
+    successInteraction2: '已接通通话',
     unSuccessInteraction: '未完成交互',
+    unSuccessInteraction2: '未接通通话',
     unSuccessTime: '未完成次数',
+    unSuccessTime2: '未接通次数',
     failedInteraction: '未正常挂断交互',
+    failedInteraction2: '未正常挂断通话',
     notOperated: '未响应',
     data: '交互数据',
     createDate: '交互时间',
     fromDevice: '发起设备',
     toDevice: '接收设备',
     interactionRecord: '交互记录',
+    interactionRecord2: '通话记录',
     all: '全部',
     customerAndClerk: '客户与员工',
     clerkAndClerk: '同事与同事',
@@ -482,8 +488,12 @@ module.exports = {
     interactionCensus: '交互记录统计',
     quantityCensus: '数量统计',
     avgResponseNum: '平均响应时间',
+    avgResponseNum2: '平均接通时间',
     MinNum: '最小响应时间',
+    MinNum2: '最短接通时间',
     MaxNum: '最大响应时间',
+    MaxNum2: '最大接通时间',
+    SumNum: '总通话时间',
     total: '总量'
   },
   frameGroup: {

+ 7 - 0
src/api/initialize.js

@@ -32,4 +32,11 @@ export function bindDeviceTransAudio() {
     url: `/initialize/bind_device_trans_audio`,
     method: 'GET'
   })
+}
+
+export function changeRs485Debug(param) {
+  return request({
+    url: `/initialize/change_rs485_debug/${param}`,
+    method: 'GET'
+  })
 }

+ 8 - 2
src/api/ncs_interaction.js

@@ -28,7 +28,6 @@ export function clearRecord(id) {
 }
 
 export function getLogChars(params) {
-  console.log(params)
   return request({
     url: `/ncs/interaction/getLogChars`,
     method: 'GET',
@@ -38,7 +37,6 @@ export function getLogChars(params) {
 }
 
 export function getLogTable(params) {
-  console.log(params)
   return request({
     url: `/ncs/interaction/getLogTable`,
     method: 'GET',
@@ -46,6 +44,14 @@ export function getLogTable(params) {
     params
   })
 }
+export function getLogTableSubTable(params) {
+  return request({
+    url: `/ncs/interaction/getLogTableSubTable`,
+    method: 'GET',
+    loading: true,
+    params
+  })
+}
 export function getListByHonePage(partId) {
   return request({
     url: `/ncs/interaction/getListByHonePage/${partId}`,

+ 2 - 1
src/utils/enum/TcpTypeEnum.js

@@ -17,6 +17,7 @@ export const TCP_TYPE = createEnum(
     TIME: ['TIME', i18n.t('tcpType.TIME')],
     ENTRACEGUARD: ['ENTRACEGUARD', i18n.t('tcpType.ENTRACEGUARD')],
     CHANNELIM: ['CHANNELIM', i18n.t('tcpType.CHANNELIM')],
-    LOCATION: ['LOCATION', i18n.t('tcpType.LOCATION')]
+    LOCATION: ['LOCATION', i18n.t('tcpType.LOCATION')],
+    PHONE: ['PHONE', i18n.t('tcpType.PHONE')]
   }
 )

+ 15 - 1
src/views/ncs-485/index.vue

@@ -4,6 +4,9 @@
       <el-select v-model="shopId" @change="changeShop" filterable>
         <el-option v-for="(item, index) in partList" :key="index" :label="item.shop_name" :value="item.shop_id" />
       </el-select>
+      <el-tooltip class="item" effect="dark" content="是否开启485调试,开了的话485连接时,不会在自动刷新了" placement="top-start">
+        <el-switch v-model="boolOpenRs485Debug" active-text="开启485调试" inactive-text="不开启调试" style="margin-bottom: 10px;margin-left: 10px;" @change="open485Debug"></el-switch>
+      </el-tooltip>
     </div>
     <el-tabs v-if="zhhList.length > 0" v-model="activeName" type="card" @tab-click="handleClick">
       <el-tab-pane name="id-0" label="无转换盒"></el-tab-pane>
@@ -71,6 +74,7 @@
 import { listByType } from '@/api/ncs_partInfo'
 import { get485DeviceAndFrame, getDeviceByType } from '@/api/ncs_device'
 import { unix2Date } from '@/utils/Foundation'
+import {changeRs485Debug} from "@/api/initialize";
 const DeviceUrl = domain.DeviceUrl
 export default {
   name: "index",
@@ -84,7 +88,8 @@ export default {
       tid: null,
       activities: [],
       multipleSelection: [],
-      boolOpen: false
+      boolOpen: false,
+      boolOpenRs485Debug: false
     }
   },
   mounted() {
@@ -229,6 +234,15 @@ export default {
       } else {
         return secondTime + this.$t('action.millisecond')
       }
+    },
+    open485Debug() {
+      const s = this.boolOpenRs485Debug ? 1 : 0
+      changeRs485Debug(s).then(res =>{
+        this.$message({
+          type: 'success',
+          message: '修改成功'
+        })
+      })
     }
   }
 }

+ 86 - 16
src/views/ncs-chars/index.vue

@@ -116,32 +116,48 @@
         </el-tab-pane>
       </el-tabs>
       <div style="padding: 10px;margin: 10px;">
+        <el-switch v-if="activeName === 'EVENT'" v-model="sssparams.eventType" active-text="按人" inactive-text="按事件" style="margin-bottom: 10px" @change="Api_getLogTable"></el-switch>
         <div class="table-wrapper">
+          <div style="padding-bottom: 10px;">
+            <el-button type="primary" @click="exportExcel">导出</el-button>
+          </div>
           <el-table :data="userActionList" stripe border :default-sort = "{prop: 'num', order: 'descending'}" style="width: 100%">
             <el-table-column type="index" width="100" :label="this.$t('action.index')" align="center" />
-            <el-table-column prop="name" :label="this.$t('member.name')" min-width="130" align="center" />
-            <el-table-column prop="num" :label="this.$t('interaction.actionTime')" min-width="130" align="center" sortable />
-            <el-table-column prop="error_num" :label="this.$t('interaction.unSuccessTime')" min-width="130" align="center" sortable />
-            <el-table-column prop="avg_num" :label="this.$t('interaction.avgResponseNum')" min-width="130" align="center" sortable >
+            <el-table-column prop="name" :label="sssparams.eventType ? this.$t('member.name') : this.$t('tcpType.EVENT')" min-width="130" align="center" sortable>
+              <template slot-scope="scope">
+                <el-link v-if="activeName === 'EVENT'" @click="clickLook(scope.row)">{{ scope.row.name }}</el-link>
+                <span v-if="activeName !== 'EVENT'">{{ scope.row.name }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column prop="num" :label="boolShow ? this.$t('interaction.actionTime2') : this.$t('interaction.actionTime')" min-width="130" align="center" sortable />
+            <el-table-column prop="error_num" :label="boolShow ? this.$t('interaction.unSuccessTime2') : this.$t('interaction.unSuccessTime')" min-width="130" align="center" sortable />
+            <el-table-column prop="avg_num" :label="boolShow ? this.$t('interaction.avgResponseNum2') : this.$t('interaction.avgResponseNum')" min-width="130" align="center" sortable >
               <template slot-scope="scope">
                 <span>{{ formateSeconds(scope.row.avg_num) }}</span>
               </template>
             </el-table-column>
-            <el-table-column prop="min_num" :label="this.$t('interaction.MinNum')" min-width="130" align="center" sortable >
+            <el-table-column prop="min_num" :label="boolShow ? this.$t('interaction.MinNum2') : this.$t('interaction.MinNum')" min-width="130" align="center" sortable >
               <template slot-scope="scope">
                 <span>{{ formateSeconds(scope.row.min_num) }}</span>
               </template>
             </el-table-column>
-            <el-table-column prop="max_num" :label="this.$t('interaction.MaxNum')" min-width="130" align="center" sortable >
+            <el-table-column prop="max_num" :label="boolShow ? this.$t('interaction.MaxNum2') : this.$t('interaction.MaxNum')" min-width="130" align="center" sortable >
               <template slot-scope="scope">
                 <span>{{ formateSeconds(scope.row.max_num) }}</span>
               </template>
             </el-table-column>
+            <el-table-column v-if="boolShow" prop="sum_num" :label="this.$t('interaction.SumNum')" min-width="130" align="center" sortable >
+              <template slot-scope="scope">
+                <span>{{ formateSeconds(scope.row.sum_num) }}</span>
+              </template>
+            </el-table-column>
           </el-table>
         </div>
       </div>
     </div>
-
+    <el-drawer :title="infoName+'统计子表'" :visible.sync="infoVisible" :append-to-body="true" size="70%">
+      <my-info :sssparams="sssparams" :uid="uid" :info-name="infoName"></my-info>
+    </el-drawer>
   </div>
 </template>
 
@@ -150,9 +166,10 @@ import echarts from 'echarts'
 import CountTo from 'vue-count-to'
 import * as API_interaction from '@/api/ncs_interaction'
 import Storage from '@/utils/storage'
+import myInfo from '@/views/ncs-chars/info'
 export default {
   name: 'Index',
-  components: { CountTo },
+  components: { CountTo, myInfo },
   data() {
     return {
       sssparams: {
@@ -162,7 +179,8 @@ export default {
         day: '',
         seller_id: null,
         fromToType: 0,
-        lookType: 0
+        lookType: 0,
+        eventType: true
       },
       chart: null,
       chartData: {},
@@ -177,7 +195,12 @@ export default {
       dataList: [this.$t('tcpType.VOICE'), this.$t('tcpType.VIDEO'), this.$t('tcpType.IM'), this.$t('tcpType.EVENT'), this.$t('tcpType.ENTRACEGUARD'), this.$t('tcpType.SOS'), this.$t('tcpType.PHONE')],
       activeName: 'ALL',
       userActionList: [],
-      activeName2: 'user'
+      activeName2: 'user',
+      boolShow: false,
+      uid: null,
+      infoVisible: false,
+      infoName: '',
+      infoDay: ''
     }
   },
   mounted() {
@@ -355,7 +378,7 @@ export default {
       this.chart.clear()
       const mySeries = [
         {
-          name: this.$t('interaction.interactionRecord'),
+          name: this.boolShow ? this.$t('interaction.interactionRecord2') : this.$t('interaction.interactionRecord'),
           type: 'bar',
           emphasis: {
             focus: 'series'
@@ -363,7 +386,7 @@ export default {
           data: res.zztDate
         },
         {
-          name: this.$t('interaction.successInteraction'),
+          name: this.boolShow ? this.$t('interaction.successInteraction2') : this.$t('interaction.successInteraction'),
           type: 'bar',
           stack: 'Ad',
           barWidth: 5,
@@ -373,7 +396,7 @@ export default {
           data: res.hasZztDate
         },
         {
-          name: this.$t('interaction.unSuccessInteraction'),
+          name: this.boolShow ? this.$t('interaction.unSuccessInteraction2') : this.$t('interaction.unSuccessInteraction'),
           type: 'bar',
           stack: 'Ad',
           barWidth: 5,
@@ -385,7 +408,7 @@ export default {
       ]
       if (res.errorDate) {
         mySeries.push({
-          name: this.$t('interaction.failedInteraction'),
+          name: this.boolShow ? this.$t('interaction.failedInteraction2') : this.$t('interaction.failedInteraction'),
           type: 'bar',
           stack: 'Ad',
           barWidth: 5,
@@ -434,10 +457,12 @@ export default {
         this.sssparams.year = object.date_val.getFullYear()
         this.sssparams.month = this.checkTime(object.date_val.getMonth() + 1)
         this.sssparams.day = this.checkTime(object.date_val.getDate())
+        this.infoDay = this.sssparams.year + '年' + this.sssparams.month + '月' + this.sssparams.day + '日'
       } else {
         this.sssparams.year = object.year
         this.sssparams.month = object.month
         this.sssparams.cycle_type = object.type
+        this.infoDay = this.sssparams.year + '年' + this.sssparams.month
       }
       this.getLogCharsJS()
       if (this.activeName !== 'ALL') {
@@ -472,9 +497,11 @@ export default {
     },
     handleClick(tab, event) {
       console.log('this.activeName==', this.activeName)
+      this.sssparams.eventType = true
       if (this.activeName === 'ALL') {
         delete this.sssparams.type
       } else {
+        this.boolShow = this.activeName === 'VOICE' || this.activeName === 'VIDEO' || this.activeName === 'PHONE'
         this.sssparams.type = this.activeName
         this.Api_getLogTable()
       }
@@ -491,12 +518,11 @@ export default {
     Api_getLogTable() {
       const _this = this
       API_interaction.getLogTable(this.sssparams).then(res => {
-        console.log(res)
         // _this.buildChart(res.dataList, res.tilStr, res.xAxis, 'actionChar', '详情')
         _this.userActionList = res.interactionChars
       })
     },
-    //将秒转化为时分秒
+    // 将秒转化为时分秒
     formateSeconds(endTime){
       if (endTime === 0) {
         return this.$t('action.oneSecond')
@@ -519,6 +545,50 @@ export default {
       } else {
         return secondTime + this.$t('action.second')
       }
+    },
+    clickLook(row) {
+      this.infoName = row.name
+      if (this.sssparams.eventType) {
+        this.uid = row.uid + ''
+      } else {
+        this.uid = row.name
+      }
+      this.infoVisible = true
+    },
+    exportExcel() {
+      const _this = this
+      this.$confirm('将导出Excel文件,是否继续?', '提示', {
+        type: 'warning'
+      }).then(() => {
+        _this.loading = false
+        import('@/vendor/Export2Excel').then(excel => {
+          let tHeader = [_this.sssparams.eventType ? _this.$t('member.name') : _this.$t('tcpType.EVENT'), _this.boolShow ? _this.$t('interaction.actionTime2') : _this.$t('interaction.actionTime'),
+            _this.boolShow ? _this.$t('interaction.unSuccessTime2') : _this.$t('interaction.unSuccessTime'), _this.boolShow ? _this.$t('interaction.avgResponseNum2') : _this.$t('interaction.avgResponseNum'),
+            _this.boolShow ? _this.$t('interaction.MinNum2') : _this.$t('interaction.MinNum'), _this.boolShow ? _this.$t('interaction.MaxNum2') : _this.$t('interaction.MaxNum')] // 表头
+          let filterVal = ['name', 'num', 'error_num', 'avg_num', 'min_num', 'max_num']
+          if (_this.boolShow) {
+            tHeader.push(this.$t('interaction.SumNum'))
+            filterVal.push('sum_num')
+          }
+          const tit = _this.infoDay + _this.formatterType(_this.activeName) + '统计表'
+          const data = _this.formatJson(filterVal, _this.userActionList)
+          excel.export_json_to_excel({
+            header: tHeader,
+            data,
+            filename: tit,
+            autoWidth: true
+          })
+        })
+      })
+    },
+    formatJson(filterVal, jsonData) {
+      return jsonData.map(v => filterVal.map(j => {
+        if (j === 'avg_num' || j === 'min_num' || j === 'max_num' || j === 'sum_num') {
+          return this.formateSeconds(v[j])
+        } else {
+          return v[j]
+        }
+      }))
     }
   }
 

+ 143 - 0
src/views/ncs-chars/info.vue

@@ -0,0 +1,143 @@
+<template>
+  <div>
+    <div style="padding: 10px;margin: 10px;">
+      <div style="padding: 10px;">
+        <el-button type="primary" @click="exportExcel">导出</el-button>
+      </div>
+      <div class="table-wrapper">
+        <el-table :data="userActionList" stripe border :default-sort = "{prop: 'num', order: 'descending'}" style="width: 100%">
+          <el-table-column type="index" width="75" :label="this.$t('action.index')" align="center" />
+          <el-table-column prop="name" :label="sssparams.eventType ? this.$t('member.name') : this.$t('tcpType.EVENT')" min-width="130" align="center" sortable>
+            <template slot-scope="scope">
+              <span>{{ scope.row.name }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="num" :label="this.$t('interaction.actionTime')" min-width="130" align="center" sortable />
+          <el-table-column prop="error_num" :label="this.$t('interaction.unSuccessTime')" min-width="130" align="center" sortable />
+          <el-table-column prop="avg_num" :label="this.$t('interaction.avgResponseNum')" min-width="130" align="center" sortable >
+            <template slot-scope="scope">
+              <span>{{ formateSeconds(scope.row.avg_num) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="min_num" :label="this.$t('interaction.MinNum')" min-width="130" align="center" sortable >
+            <template slot-scope="scope">
+              <span>{{ formateSeconds(scope.row.min_num) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="max_num" :label="this.$t('interaction.MaxNum')" min-width="130" align="center" sortable >
+            <template slot-scope="scope">
+              <span>{{ formateSeconds(scope.row.max_num) }}</span>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+
+  </div>
+</template>
+
+<script>
+import * as API_interaction from '@/api/ncs_interaction'
+import Storage from '@/utils/storage'
+
+export default {
+  name: 'DeviceInfo',
+  props: {
+    uid: {
+      type: String,
+      default: 0
+    },
+    infoName: {
+      type: String,
+      default: ''
+    },
+    sssparams: {
+      type: Object,
+      default: null
+    },
+
+  },
+  data: function() {
+    return {
+      /** 列表数据 */
+      userActionList: []
+    }
+  },
+  watch: {
+    uid: function() {
+      console.log('this.uid=', this.uid)
+      this.GET_List()
+    }
+  },
+  mounted() {
+    this.GET_List()
+  },
+  methods: {
+    /** 加载设备信息列表 */
+    GET_List() {
+      const _this = this
+      this.sssparams.queryStr = this.uid
+      API_interaction.getLogTableSubTable(this.sssparams).then(res => {
+        _this.userActionList = res.interactionChars
+      })
+    },
+    // 将秒转化为时分秒
+    formateSeconds(endTime){
+      if (endTime === 0) {
+        return this.$t('action.oneSecond')
+      } else if (endTime === -1) {
+        return this.$t('action.null')
+      }
+      let secondTime = endTime//将传入的秒的值转化为Number
+      let min = 0// 初始化分
+      let h =0// 初始化小时
+      if(secondTime>60){//如果秒数大于60,将秒数转换成整数
+        min=parseInt(secondTime/60)//获取分钟,除以60取整数,得到整数分钟
+        secondTime=parseInt(secondTime%60)//获取秒数,秒数取佘,得到整数秒数
+        if(min>60){//如果分钟大于60,将分钟转换成小时
+          h=parseInt(min/60)//获取小时,获取分钟除以60,得到整数小时
+          min=parseInt(min%60) //获取小时后取佘的分,获取分钟除以60取佘的分
+          return h + this.$t('action.time2') + min + this.$t('action.minute2') + secondTime + this.$t('action.second')
+        } else {
+          return min +this.$t('action.minute2') + secondTime + this.$t('action.second')
+        }
+      } else {
+        return secondTime + this.$t('action.second')
+      }
+    },
+    exportExcel() {
+      const _this = this
+      this.$confirm('将导出Excel文件,是否继续?', '提示', {
+        type: 'warning'
+      }).then(() => {
+        _this.loading = false
+        import('@/vendor/Export2Excel').then(excel => {
+          const tHeader = [this.sssparams.eventType ? this.$t('member.name') : this.$t('tcpType.EVENT'), this.$t('interaction.actionTime'),
+            this.$t('interaction.unSuccessTime'), this.$t('interaction.avgResponseNum'), this.$t('interaction.MinNum'), this.$t('interaction.MaxNum')] // 表头
+          const filterVal = ['name', 'num', 'error_num', 'avg_num', 'min_num', 'max_num']
+          const tit = this.infoName + '事件统计表'
+          const data = _this.formatJson(filterVal, this.userActionList)
+          excel.export_json_to_excel({
+            header: tHeader,
+            data,
+            filename: tit,
+            autoWidth: true
+          })
+        })
+      })
+    },
+    formatJson(filterVal, jsonData) {
+      return jsonData.map(v => filterVal.map(j => {
+        if (j === 'avg_num' || j === 'min_num' || j === 'max_num') {
+          return this.formateSeconds(v[j])
+        } else {
+          return v[j]
+        }
+      }))
+    }
+  }
+}
+</script>
+
+<style type="text/scss" scoped>
+</style>