Browse Source

小程序页面

wzh 2 years ago
parent
commit
5edbc22eb9

+ 64 - 6
api/device/device.js

@@ -10,24 +10,27 @@ export function listDeviceGroup(userId) {
 
 
 // 查询设备
-export function listDevice(pageNum,deviceName) {
+export function listDevice(pageNum,deviceName,deptId) {
     let url = '/iot/device/shortList?pageNum='+pageNum+'&pageSize=12';
     if(deviceName){
         url  = url +"&deviceName="+encodeURIComponent(deviceName)
     }
+    if(deptId){
+        url  = url +"&deptId="+deptId
+    }
     return request({
         url: url,
         method: 'get'
     })
 }
-
+//获取设备详情
 export function getDetail(id){
     return request({
         url: '/iot/device/'+id,
         method: 'get'
     })
 }
-
+//获取设备状态
 export function getDeviceStatus(id,childId){
     let url = '/iot/device/runningStatus/'+id;
     if(childId){
@@ -38,7 +41,7 @@ export function getDeviceStatus(id,childId){
         method: 'get'
     })
 }
-
+//物模型缓存
 export function cacheJsonThingsModel(id){
     let url = '/iot/model/cache/'+id;
     return request({
@@ -47,7 +50,7 @@ export function cacheJsonThingsModel(id){
     })
 }
 
-
+//获取设备消息列表
 export function getDeviceMsg(){
     let url = '/iot/configqrcode/list';
     return request({
@@ -55,7 +58,7 @@ export function getDeviceMsg(){
         method: 'get'
     })
 }
-
+//绑定设备码
 export function bindDeviceQrcode(qrcode,deviceNo){
     let url = '/iot/device/bind?deviceNo='+deviceNo+"&qrcode="+qrcode;
     return request({
@@ -63,3 +66,58 @@ export function bindDeviceQrcode(qrcode,deviceNo){
         method: 'get',
     })
 }
+//获取警报列表
+export function getAlertList(pageNum,pageSize){
+    let url = '/iot/alertLog/list?pageNum='+pageNum+'&pageSize='+pageSize;
+    return request({
+        url: url,
+        method: 'get',
+    })
+}
+//处理报警
+export function handleAlert(alertLog){
+    return request({
+        url: '/iot/alertLog',
+        data:alertLog,
+        method: 'put',
+    })
+}
+//查询详情
+export function getAlertLog(id){
+    return request({
+        url: '/iot/alertLog/'+id,
+        method: 'get',
+    })
+}
+//根据二维码找到设备详情
+export function getDevcieByQrcode(id){
+    return request({
+        url: '/iot/device/getDeviceByQrcode?qrcode='+id,
+        method: 'get',
+    })
+}
+
+//根据二维码找到设备详情
+export function bingDeviceDept(device){
+    return request({
+        url: '/iot/device',
+        data:device,
+        method: 'put',
+    })
+}
+//主动上报错误
+export function reportError(err){
+    return request({
+        url: '/iot/desc',
+        data:err,
+        method: 'post',
+    })
+}
+export function errorList(pageNum,pageSize){
+    let url = '/iot/desc/list?pageNum='+pageNum+'&pageSize='+pageSize;
+    return request({
+        url: url,
+        method: 'get',
+    })
+}
+

+ 14 - 4
api/user/user.js

@@ -4,9 +4,14 @@ import request from '@/utils/request'
  * 获取部门列表
  * @returns {*}
  */
-export function getDeptList(){
+export function getDeptList(deptName){
+    let url = '/system/dept/list';
+    if(deptName){
+        deptName = encodeURIComponent(deptName);
+        url = url+"?deptName="+deptName
+    }
     return request({
-        url: '/system/dept/list',
+        url:url,
         method: 'get'
     })
 }
@@ -15,9 +20,14 @@ export function getDeptList(){
  * 获取部门用户列表
  * @returns {*}
  */
-export function getUserListByDept(deptId){
+export function getUserListByDept(deptId,username){
+    let url='/system/user/list?pageNum=1&pageSize=20&deptId='+deptId;
+    if(username){
+        username = encodeURIComponent(username);
+        url = url+"&userName="+userName
+    }
     return request({
-        url: '/system/user/list?pageNum=1&pageSize=20&deptId='+deptId,
+      url:url,
         method: 'get'
     })
 }

+ 118 - 81
pages.json

@@ -1,109 +1,146 @@
 {
-  "pages": [{
-    "path": "pages/login",
-    "style": {
-      "navigationBarTitleText": "登录"
-    }
-  }, {
-    "path": "pages/index",
-    "style": {
-      "navigationBarTitleText": "若依移动端框架",
-      "navigationStyle": "custom"
-    }
-  }, {
-    "path": "pages/work/index",
-    "style": {
-      "navigationBarTitleText": "工作台"
-    }
-  }, {
-    "path": "pages/mine/index",
-    "style": {
-      "navigationBarTitleText": "我的"
-    }
-  }, {
-    "path": "pages/mine/avatar/index",
-    "style": {
-      "navigationBarTitleText": "修改头像"
-    }
-  }, {
-    "path": "pages/mine/info/index",
-    "style": {
-      "navigationBarTitleText": "个人信息"
-    }
-  }, {
-    "path": "pages/mine/info/edit",
-    "style": {
-      "navigationBarTitleText": "编辑资料"
-    }
-  }, {
-    "path": "pages/mine/pwd/index",
-    "style": {
-      "navigationBarTitleText": "修改密码"
-    }
-  }, {
-    "path": "pages/mine/setting/index",
-    "style": {
-      "navigationBarTitleText": "应用设置"
-    }
-  }, {
-    "path": "pages/mine/help/index",
-    "style": {
-      "navigationBarTitleText": "常见问题"
-    }
-  }, {
-    "path": "pages/mine/about/index",
-    "style": {
-      "navigationBarTitleText": "关于我们"
-    }
-  }, {
-    "path": "pages/common/webview/index",
-    "style": {
-      "navigationBarTitleText": "浏览网页"
-    }
-  }, {
-    "path": "pages/common/textview/index",
-    "style": {
-      "navigationBarTitleText": "浏览文本"
-    }
-  },{
-    "path": "pages/device/index",
-    "style": {
-      "navigationBarTitleText": "设备列表"
-    }
-  }
-      ,{
-            "path" : "pages/device/detail",
+  "pages": [
+    {
+      "path": "pages/login",
+      "style": {
+        "navigationBarTitleText": "登录"
+      }
+    },
+    {
+      "path": "pages/index",
+      "style": {
+        "navigationBarTitleText": "若依移动端框架",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/work/index",
+      "style": {
+        "navigationBarTitleText": "工作台"
+      }
+    },
+    {
+      "path": "pages/mine/index",
+      "style": {
+        "navigationBarTitleText": "我的"
+      }
+    },
+    {
+      "path": "pages/mine/avatar/index",
+      "style": {
+        "navigationBarTitleText": "修改头像"
+      }
+    },
+    {
+      "path": "pages/mine/info/index",
+      "style": {
+        "navigationBarTitleText": "个人信息"
+      }
+    },
+    {
+      "path": "pages/mine/info/edit",
+      "style": {
+        "navigationBarTitleText": "编辑资料"
+      }
+    },
+    {
+      "path": "pages/mine/pwd/index",
+      "style": {
+        "navigationBarTitleText": "修改密码"
+      }
+    },
+    {
+      "path": "pages/mine/setting/index",
+      "style": {
+        "navigationBarTitleText": "应用设置"
+      }
+    },
+    {
+      "path": "pages/mine/help/index",
+      "style": {
+        "navigationBarTitleText": "常见问题"
+      }
+    },
+    {
+      "path": "pages/mine/about/index",
+      "style": {
+        "navigationBarTitleText": "关于我们"
+      }
+    },
+    {
+      "path": "pages/common/webview/index",
+      "style": {
+        "navigationBarTitleText": "浏览网页"
+      }
+    },
+    {
+      "path": "pages/common/textview/index",
+      "style": {
+        "navigationBarTitleText": "浏览文本"
+      }
+    },
+    {
+      "path": "pages/device/index",
+      "style": {
+        "navigationBarTitleText": "设备列表"
+      }
+    },
+    {
+      "path": "pages/device/detail",
       "style": {
         "navigationBarTitleText": "详情"
       }
-
-        },{
+    },
+    {
       "path": "pages/wifi/index",
       "style": {
         "navigationBarTitleText": "配网"
       }
-    },{
+    },
+    {
       "path": "pages/device/scan",
       "style": {
         "navigationBarTitleText": "绑定设备"
       }
-    },{
+    },
+    {
       "path": "pages/user/index",
       "style": {
         "navigationBarTitleText": "客户列表"
-      }}
+      }
+    },
+    {
+      "path": "pages/user/list",
+      "style": {
+        "navigationBarTitleText": "用户列表"
+      }
+    },
+    {
+      "path": "pages/device/alert",
+      "style": {
+        "navigationBarTitleText": "报警列表"
+      }
+    },
+    {
+      "path": "pages/device/error",
+      "style": {
+        "navigationBarTitleText": "异常列表"
+      }
+    }
   ],
   "tabBar": {
     "color": "#000000",
     "selectedColor": "#000000",
     "borderStyle": "white",
     "backgroundColor": "#ffffff",
-    "list": [ {
+    "list": [
+      {
         "pagePath": "pages/work/index",
         "iconPath": "static/images/tabbar/work.png",
         "selectedIconPath": "static/images/tabbar/work_.png",
         "text": "工作台"
-      }, {
+      },
+      {
         "pagePath": "pages/mine/index",
         "iconPath": "static/images/tabbar/mine.png",
         "selectedIconPath": "static/images/tabbar/mine_.png",

+ 188 - 0
pages/device/alert.vue

@@ -0,0 +1,188 @@
+<template>
+  <view class="work-container">
+    <view style="margin-top: 10px">
+      <uni-card v-for="item in alertList" :title="item.deviceName" :extra="item.createTime">
+
+        <view style="position: relative">
+          <view>报警名称:{{item.alertName}}</view>
+          <view>报警级别:{{alertLevel[item.alertLevel-1]}}</view>
+          <view v-if="item.status == 3">状态:已处理</view>
+          <view v-if="item.status != 3">状态:未处理</view>
+
+          <view v-if="item.status == 3" style="width: 50px;position: absolute;right:-10px;bottom:0px"><u-button @click="watchResult(item)" type="primary" :plain="true" size="mini" text="查看结果"></u-button>
+          </view>
+          <view v-if="item.status != 3" style="width: 50px;position: absolute;right:-10px;bottom:0px"><u-button @click="handle(item)" type="error" :plain="true" size="mini" text="处理"></u-button>
+          </view>
+
+        </view>
+      </uni-card>
+      <uni-load-more @clickLoadMore="getMore" :contentText="contenText" :status="loadStatus"></uni-load-more>
+
+      <uni-popup ref="popup" type="dialog">
+        <uni-popup-dialog title="输入处理结果" :value="chooseItem.remark" placeholder="请输入处理结果" mode="input" message="成功消息" :duration="2000" :before-close="true" @close="close" @confirm="confirm"></uni-popup-dialog>
+      </uni-popup>
+    </view>
+  </view>
+</template>
+
+<script>
+import {getAlertList,handleAlert} from '@/api/device/device';
+import UText from "../../uni_modules/uview-ui/components/u-text/u-text";
+export default {
+  components: {UText},
+  data() {
+    return {
+      show:true,
+      alertList:[],
+      search:{
+        deptName:""
+      },
+      alertLevel:['提醒通知','轻微问题','严重警告'],
+      pageNum:1,
+      pageSize:10,
+      chooseItem: {},
+      contenText:{contentdown: "点击加载更多",contentrefresh: "正在加载...",contentnomore: "没有更多数据了"},
+      loadStatus:"more"
+    }
+  },
+  onLoad(){
+    this.getAlertList();
+  },
+  methods: {
+    getMore(){
+      this.pageNum ++;
+      this.getAlertList();
+    },
+    open(item) {
+      this.chooseItem = item;
+      this.$refs.popup.open()
+    },
+    close() {
+      this.chooseItem = {};
+      this.$refs.popup.close()
+    },
+    confirm(text){
+
+      if(!text){
+        uni.showToast({
+          icon:"error",
+          title:"请输入内容"
+        })
+        return;
+      }
+      let item = this.chooseItem;
+      item.remark = text;
+      this.close();
+      handleAlert(item).then(res=>{
+        if(res.code == 200){
+          item.status = 3;
+        }
+      })
+    },
+    searchDept(){
+      this.getDeptList();
+    },
+    watchResult(item){
+      this.open(item);
+    },
+    handle(item){
+      this.open(item);
+    },
+    getAlertList(){
+      this.loadStatus = "loading"
+      getAlertList(this.pageNum,this.pageSize).then(res=>{
+        if(res.total == this.alertList.length){
+          uni.showToast({
+            icon:"none",
+            title:"没有更多了"
+          })
+          this.loadStatus = "noMore"
+          return;
+        }
+        this.loadStatus = "more"
+        this.alertList = this.alertList.concat(res.rows);
+      });
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+/* #ifndef APP-NVUE */
+.u-collapse-content{
+  display: flex;
+  flex-direction: column;
+}
+page {
+  display: flex;
+  flex-direction: column;
+  box-sizing: border-box;
+  background-color: #fff;
+  min-height: 100%;
+  height: auto;
+}
+
+view {
+  font-size: 14px;
+  line-height: inherit;
+}
+
+/* #endif */
+
+.text {
+  text-align: center;
+  font-size: 26rpx;
+  margin-top: 10rpx;
+}
+
+.grid-item-box {
+  flex: 1;
+  /* #ifndef APP-NVUE */
+  display: flex;
+  /* #endif */
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 15px 0;
+}
+
+.uni-margin-wrap {
+  width: 690rpx;
+  width: 100%;
+;
+}
+
+.swiper {
+  height: 300rpx;
+}
+
+.swiper-box {
+  height: 150px;
+}
+
+.swiper-item {
+  /* #ifndef APP-NVUE */
+  display: flex;
+  /* #endif */
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  color: #fff;
+  height: 300rpx;
+  line-height: 300rpx;
+}
+
+@media screen and (min-width: 500px) {
+  .uni-swiper-dot-box {
+    width: 400px;
+    /* #ifndef APP-NVUE */
+    margin: 0 auto;
+    /* #endif */
+    margin-top: 8px;
+  }
+
+  .image {
+    width: 100%;
+  }
+}
+</style>

+ 66 - 4
pages/device/detail.vue

@@ -1,6 +1,9 @@
 <template>
   <view class="content">
     <view class="header">
+      <view style="position: absolute;right:10rpx;top:30rpx;z-index: 9999">
+        <u-button @click="reportError" text="上报异常" type="error" size="mini"></u-button>
+      </view>
   <u--form>
     <u-form-item   style="border:0px"
                    label="设备名称:"
@@ -58,6 +61,19 @@
       ></u--input>
     </u-form-item>
 
+    <u-form-item   style="border:0px"
+                   label="位置信息:"
+                   labelWidth="auto"
+                   :borderBottom="false"
+                   ref="item1"
+    >
+      <view style="width: 30%">
+        <u-button @click="openLocation(deviceInfo)" type="primary" size="mini" text="查看位置"></u-button>
+
+
+      </view>
+    </u-form-item>
+
     <u-form-item   style="border:0px"
                    label="设备信号:"
                    labelWidth="auto"
@@ -203,19 +219,28 @@
 
       </view>
       <u-picker @cancel="show=null" :show="show!=null" :columns="columns" @confirm="confirmItemData" keyName="text"></u-picker>
+      <u-modal @cancel="cancel" :show="showErrDlg" title="异常上报" :showCancelButton="true" @confirm="doReportError" >
+        <view class="slot-content">
 
+          <u--textarea style="width:500rpx" autoheight v-model="errorMsg" placeholder="请输入异常内容" ></u--textarea>
+
+        </view>
+      </u-modal>
     </view>
   </view>
 </template>
 
 <script>
-import { getDetail,getDeviceStatus,cacheJsonThingsModel } from '@/api/device/device.js'
+import { getDetail,getDeviceStatus,cacheJsonThingsModel,reportError } from '@/api/device/device.js'
 import UButton from "../../uni_modules/uview-ui/components/u-button/u-button";
 import UForm from "../../uni_modules/uview-ui/components/u--form/u--form";
+import UInput from "../../uni_modules/uview-ui/components/u--input/u--input";
 export default {
-  components: {UForm, UButton},
+  components: {UInput, UForm, UButton},
   data(){
       return {
+        showErrDlg:null,
+        errorMsg:"",
         show:null,
         value:"",
         deviceInfo:{},
@@ -226,7 +251,8 @@ export default {
         oneToMul:false,
         inputProp:[],
         watchProp:[],
-        columns:[]
+        columns:[],
+        location:{},
       }
   },
   onLoad: function(opt) {
@@ -239,6 +265,38 @@ export default {
     this.mqttUnSubscribe(this.deviceInfo);
   },
   methods:{
+    cancel(){
+      this.showErrDlg = false;
+    },
+    reportError(){
+      this.showErrDlg = true;
+    },
+    doReportError(){
+        if(!this.errorMsg){
+          this.$modal.showToast('异常信息不能为空')
+        }else{
+          let self = this;
+            let errObj = {};
+          errObj.deviceId = this.deviceInfo.deviceId;
+          errObj.deviceName = this.deviceInfo.deviceName
+          errObj.desc = this.errorMsg;
+          errObj.deptId= this.deviceInfo.deptId;
+          reportError(errObj).then(res=>{
+            self.$modal.showToast(res.msg)
+            self.cancel();
+          })
+        }
+    },
+    openLocation(){
+      uni.openLocation({
+        latitude: this.location.latitude,
+        longitude: this.location.longitude,
+        success: function () {
+          console.log('success');
+        }
+      });
+
+    },
     confirmItemData(e){
       let data = e.value[0];
       this.show.text = data.text;
@@ -282,6 +340,9 @@ export default {
       let self = this;
       getDetail(this.id).then(res=>{
         self.deviceInfo = res.data;
+        self.location = {
+          latitude: self.deviceInfo.latitude,
+          longitude: self.deviceInfo.longitude};
         self.parseSummay(res.data.summary)
         self.mqttSubscribe(res.data);
         self.getDeviceStatus();
@@ -593,7 +654,8 @@ export default {
 .header{
   width: 100%;
   background: white;
-  padding:0px 20rpx
+  padding:0px 20rpx;
+  position: relative;
 
 }
 .content {

+ 193 - 0
pages/device/error.vue

@@ -0,0 +1,193 @@
+<template>
+  <view class="work-container">
+    <view style="margin-top: 10px">
+      <uni-card v-for="item in alertList" :title="item.deviceName" :extra="item.createTime">
+
+        <view style="position: relative">
+          <view>上报人:{{item.userName}}</view>
+          <view>上报内容:{{item.desc}}</view>
+          <view v-if="item.status == 3">状态:已处理</view>
+          <view v-if="item.status != 3">状态:未处理</view>
+
+          <view v-if="item.status == 3" style="width: 50px;position: absolute;right:-10px;bottom:0px"><u-button @click="watchResult(item)" type="primary" :plain="true" size="mini" text="查看结果"></u-button>
+          </view>
+<!--          <view v-if="item.status != 3" style="width: 50px;position: absolute;right:-10px;bottom:0px"><u-button @click="handle(item)" type="error" :plain="true" size="mini" text="处理"></u-button>-->
+<!--          </view>-->
+
+        </view>
+      </uni-card>
+      <uni-load-more @clickLoadMore="getMore" :contentText="contenText" :status="loadStatus"></uni-load-more>
+
+      <u-modal :show="showErrDlg" title="处理结果" @confirm="close" >
+        <view class="slot-content">
+
+          <u--textarea style="width:500rpx" autoheight v-model="chooseItem.result" disabled="" ></u--textarea>
+
+        </view>
+      </u-modal>
+    </view>
+  </view>
+</template>
+
+<script>
+import {errorList} from '@/api/device/device';
+import UText from "../../uni_modules/uview-ui/components/u-text/u-text";
+export default {
+  components: {UText},
+  data() {
+    return {
+      show:true,
+      alertList:[],
+      search:{
+        deptName:""
+      },
+      alertLevel:['提醒通知','轻微问题','严重警告'],
+      pageNum:1,
+      pageSize:10,
+      chooseItem: {},
+      contenText:{contentdown: "点击加载更多",contentrefresh: "正在加载...",contentnomore: "没有更多数据了"},
+      loadStatus:"more",
+      showErrDlg:false,
+    }
+  },
+  onLoad(){
+    this.getAlertList();
+  },
+  methods: {
+    getMore(){
+      this.pageNum ++;
+      this.getAlertList();
+    },
+    open(item) {
+      this.chooseItem = item;
+      this.showErrDlg = true;
+    },
+    close() {
+      this.chooseItem = {};
+      this.showErrDlg = false;
+    },
+    confirm(text){
+
+      if(!text){
+        uni.showToast({
+          icon:"error",
+          title:"请输入内容"
+        })
+        return;
+      }
+      let item = this.chooseItem;
+      item.remark = text;
+      this.close();
+      handleAlert(item).then(res=>{
+        if(res.code == 200){
+          item.status = 3;
+        }
+      })
+    },
+    searchDept(){
+      this.getDeptList();
+    },
+    watchResult(item){
+      this.open(item);
+    },
+    handle(item){
+      this.open(item);
+    },
+    getAlertList(){
+      this.loadStatus = "loading"
+      errorList(this.pageNum,this.pageSize).then(res=>{
+        if(res.total == this.alertList.length){
+          uni.showToast({
+            icon:"none",
+            title:"没有更多了"
+          })
+          this.loadStatus = "noMore"
+          return;
+        }
+        this.loadStatus = "more"
+        this.alertList = this.alertList.concat(res.rows);
+      });
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+/* #ifndef APP-NVUE */
+.u-collapse-content{
+  display: flex;
+  flex-direction: column;
+}
+page {
+  display: flex;
+  flex-direction: column;
+  box-sizing: border-box;
+  background-color: #fff;
+  min-height: 100%;
+  height: auto;
+}
+
+view {
+  font-size: 14px;
+  line-height: inherit;
+}
+
+/* #endif */
+
+.text {
+  text-align: center;
+  font-size: 26rpx;
+  margin-top: 10rpx;
+}
+
+.grid-item-box {
+  flex: 1;
+  /* #ifndef APP-NVUE */
+  display: flex;
+  /* #endif */
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 15px 0;
+}
+
+.uni-margin-wrap {
+  width: 690rpx;
+  width: 100%;
+;
+}
+
+.swiper {
+  height: 300rpx;
+}
+
+.swiper-box {
+  height: 150px;
+}
+
+.swiper-item {
+  /* #ifndef APP-NVUE */
+  display: flex;
+  /* #endif */
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  color: #fff;
+  height: 300rpx;
+  line-height: 300rpx;
+}
+
+@media screen and (min-width: 500px) {
+  .uni-swiper-dot-box {
+    width: 400px;
+    /* #ifndef APP-NVUE */
+    margin: 0 auto;
+    /* #endif */
+    margin-top: 8px;
+  }
+
+  .image {
+    width: 100%;
+  }
+}
+</style>

+ 5 - 3
pages/device/index.vue

@@ -49,11 +49,13 @@ export default {
         page:1,
         search:{
           deviceName:""
-        }
+        },
+        deptId:0,
 
       }
   },
-  onLoad: function() {
+  onLoad: function(opt) {
+    this.deptId = opt.deptId;
     this.connectMqtt();
   },
   destroyed() {
@@ -73,7 +75,7 @@ export default {
     },
     listDevice(){
       let self = this;
-      listDevice(this.page,this.search.deviceName).then(res=>{
+      listDevice(this.page,this.search.deviceName,this.deptId).then(res=>{
             let rows = res.rows;
             self.deviceList = rows;
             self.mqttSubscribe(self.deviceList);

+ 1 - 1
pages/login.vue

@@ -46,7 +46,7 @@
         globalConfig: getApp().globalData.config,
         loginForm: {
           username: "admin",
-          password: "admin123",
+          password: "123456",
           code: "",
           uuid: ''
         }

+ 37 - 40
pages/user/index.vue

@@ -1,76 +1,73 @@
 <template>
   <view class="work-container">
-    <u-collapse
-        @change="change"
-        @close="close"
-        @open="open"
-    >
-      <u-collapse-item v-if="item.parentId != 0" v-for="item in deptList"
-          :title="item.deptName"
-          :name="item.deptId"
-      >
+    <view class="header">
+      <u-search placeholder="请输入客户名称" :clearabled="true" @clear="searchDept" @custom="searchDept" v-model="search.deptName" @search="searchDept"></u-search>
+    </view>
+    <view style="margin-top: 10px">
+        <uni-card v-if="item.parentId !==0" v-for="item in deptList" :title="item.deptName" :extra="item.createTime">
 
-        <text class="u-collapse-content" v-for="subitem in item.list">
+          <view style="position: relative">
+            <view>联系人:{{item.leader}}</view>
+            <view>联系电话:{{item.phone}}</view>
+            <view style="width: 50px;position: absolute;right:-10px;bottom:0px"><u-button @click="toUser(item)" type="primary" :plain="true" size="mini" text="查看人员"></u-button>
+            </view>
 
-          {{ subitem.nickName }} {{ subitem.phonenumber }} {{ subitem.createTime }}
+            <view style="width: 50px;position: absolute;right:100rpx;bottom:0rpx"><u-button type="success" @click="toDeviceList(item)" :plain="true" size="mini" text="查看设备"></u-button>
+            </view>
 
-        </text>
-      </u-collapse-item>
+          </view>
 
-    </u-collapse>
+        </uni-card>
+    </view>
   </view>
 </template>
 
 <script>
 import authObj from '@/plugins/auth.js';
 import {getDeptList,getUserListByDept} from '@/api/user/user';
+import UText from "../../uni_modules/uview-ui/components/u-text/u-text";
 export default {
-    data() {
+  components: {UText},
+  data() {
       return {
-        current: 0,
-        swiperDotIndex: 0,
         deptList:[],
-        deptMap :{}
+        search:{
+          deptName:""
+        }
       }
     },
   onLoad(){
     this.getDeptList();
   },
     methods: {
-      change(item){
-        console.log(item)
+      searchDept(){
+        this.getDeptList();
+      },
+      toUser(item){
+        uni.navigateTo({
+          url: '/pages/user/list?deptId='+item.deptId
+        });
       },
-      getUser(dept){
-        let id = dept.deptId;
-        getUserListByDept(id).then(res=>{
-          debugger;
-          dept.list = res.rows;
+      toDeviceList(item){
+        uni.navigateTo({
+          url: '/pages/device/index?deptId='+item.deptId
         });
       },
       getDeptList(){
-        getDeptList().then(res=>{
+        getDeptList(this.search.deptName).then(res=>{
           this.deptList = res.data;
-          for (let i = 0; i < this.deptList.length; i++) {
-              let dept = this.deptList[i];
-              this.deptMap[dept.deptId]  = dept;
-          }
         });
-      },
-      open(deptId){
-        let dept = this.deptMap[deptId]
-        if(dept.list == null){
-          this.getUser(dept);
-        }
-      },
-      close(item){
-
-      },
+      }
     }
   }
 </script>
 
 <style lang="scss">
   /* #ifndef APP-NVUE */
+  .u-collapse-content{
+    display: flex;
+    flex-direction: column;
+  }
   page {
     display: flex;
     flex-direction: column;

+ 138 - 0
pages/user/list.vue

@@ -0,0 +1,138 @@
+<template>
+  <view class="work-container">
+    <view class="header">
+      <u-search placeholder="请输入客户名称" :clearabled="true" @clear="searchDept" @custom="searchDept" v-model="search.userName" @search="searchDept"></u-search>
+    </view>
+    <view style="margin-top: 10px">
+      <uni-list :border="true">
+        <!-- 显示圆形头像 -->
+        <view v-for="item in userList">
+
+          <uni-list-chat v-if="item.avatar != ''"  :avatar-circle="true" :title="item.nickName" :avatar="item.avatar" :note="item.phonenumber" :time="item.createTime" ></uni-list-chat>
+          <uni-list-chat  v-else :avatar-circle="true" :title="item.nickName" avatar="/static/images/device/user.png" :note="item.phonenumber" :time="item.createTime" ></uni-list-chat>
+
+        </view>
+
+
+      </uni-list>
+    </view>
+  </view>
+</template>
+
+<script>
+import authObj from '@/plugins/auth.js';
+import {getDeptList,getUserListByDept} from '@/api/user/user';
+import UText from "../../uni_modules/uview-ui/components/u-text/u-text";
+export default {
+  components: {UText},
+  data() {
+      return {
+        userList:[],
+        search:{
+          userName:""
+        },
+        deptId:0,
+      }
+    },
+  onLoad(opt){
+    this.deptId = opt.deptId;
+    this.getUser();
+  },
+    methods: {
+      searchDept(){
+        this.getUser();
+      },
+      change(item){
+        console.log(item)
+      },
+      getUser(){
+        let id = this.deptId;
+        getUserListByDept(id,this.search.userName).then(res=>{
+          this.userList = res.rows;
+          for(const user of this.userList){
+          }
+        });
+      },
+    }
+  }
+</script>
+
+<style lang="scss">
+  /* #ifndef APP-NVUE */
+  .u-collapse-content{
+    display: flex;
+    flex-direction: column;
+  }
+  page {
+    display: flex;
+    flex-direction: column;
+    box-sizing: border-box;
+    background-color: #fff;
+    min-height: 100%;
+    height: auto;
+  }
+
+  view {
+    font-size: 14px;
+    line-height: inherit;
+  }
+
+  /* #endif */
+
+  .text {
+    text-align: center;
+    font-size: 26rpx;
+    margin-top: 10rpx;
+  }
+
+  .grid-item-box {
+    flex: 1;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    padding: 15px 0;
+  }
+
+  .uni-margin-wrap {
+    width: 690rpx;
+    width: 100%;
+    ;
+  }
+
+  .swiper {
+    height: 300rpx;
+  }
+
+  .swiper-box {
+    height: 150px;
+  }
+
+  .swiper-item {
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    color: #fff;
+    height: 300rpx;
+    line-height: 300rpx;
+  }
+
+  @media screen and (min-width: 500px) {
+    .uni-swiper-dot-box {
+      width: 400px;
+      /* #ifndef APP-NVUE */
+      margin: 0 auto;
+      /* #endif */
+      margin-top: 8px;
+    }
+
+    .image {
+      width: 100%;
+    }
+  }
+</style>

+ 124 - 24
pages/work/index.vue

@@ -15,61 +15,95 @@
     <uni-section title="工作台" type="line"></uni-section>
     <view class="grid-body">
       <uni-grid :column="3" :showBorder="false" >
-        <uni-grid-item>
-          <view class="grid-item-box" @click="goPage('user')" v-if="hasRole('admin')">
-            <uni-icons type="person-filled" color="#2979ff" size="28"></uni-icons>
+        <uni-grid-item v-if="hasRole(['admin'])">
+          <view class="grid-item-box" @click="goPage('user')">
+            <u--image :showLoading="true" src="/static/images/icons/user.png" width="50rpx" height="50rpx" ></u--image>
             <text class="text">客户列表</text>
           </view>
         </uni-grid-item>
-        <uni-grid-item>
+        <uni-grid-item v-if="hasRole(['companymgr'])">
           <view class="grid-item-box" @click="goPage('device')">
-            <uni-icons type="cloud-upload" color="#2979ff" size="28"></uni-icons>
-            <text class="text">设备查看</text>
+            <u--image :showLoading="true" src="/static/images/icons/device.png" width="50rpx" height="50rpx" ></u--image>
+            <text class="text">设备列表</text>
           </view>
         </uni-grid-item>
         <uni-grid-item>
           <view class="grid-item-box" @click="goPage('wifi')">
-            <u-icon name="wifi" color="#2979ff" size="28"></u-icon>
+            <u--image :showLoading="true" src="/static/images/icons/wifi.png" width="50rpx" height="50rpx" ></u--image>
             <text class="text">设备配网</text>
           </view>
         </uni-grid-item>
-
-        <uni-grid-item>
+        <uni-grid-item v-if="hasRole(['admin'])">
           <view class="grid-item-box" @click="goPage('scan')">
-            <u-icon name="scan" color="#2979ff" size="28"></u-icon>
-            <text class="text">扫码绑定</text>
+            <u--image :showLoading="true" src="/static/images/icons/code.png" width="50rpx" height="50rpx" ></u--image>
+            <text class="text">绑码激活</text>
           </view>
         </uni-grid-item>
-        <uni-grid-item>
-          <view class="grid-item-box" @click="goPage('scan')">
-            <u-icon name="scan" color="#2979ff" size="28"></u-icon>
-            <text class="text">扫码激活</text>
+
+
+        <uni-grid-item v-if="hasRole(['companymgr'])">
+          <view class="grid-item-box" @click="scanCode()">
+            <u--image :showLoading="true" src="/static/images/icons/scan.png" width="50rpx" height="50rpx" ></u--image>
+            <text class="text">用户绑定</text>
           </view>
         </uni-grid-item>
+
         <uni-grid-item>
-          <view class="grid-item-box" @click="goPage('scan')">
-            <u-icon name="scan" color="#2979ff" size="28"></u-icon>
-            <text class="text">设备报警</text>
+          <view class="grid-item-box" @click="watchDevice()">
+            <u--image :showLoading="true" src="/static/images/icons/scan.png" width="50rpx" height="50rpx" ></u--image>
+            <text class="text">查看设备</text>
           </view>
         </uni-grid-item>
-        <uni-grid-item>
-          <view class="grid-item-box" @click="goPage('scan')">
-            <u-icon name="scan" color="#2979ff" size="28"></u-icon>
-            <text class="text">设备报警</text>
+
+        <uni-grid-item v-if="hasRole(['companymgr'])">
+          <view class="grid-item-box" @click="goPage('alert')">
+            <u--image :showLoading="true" src="/static/images/icons/alert.png" width="50rpx" height="50rpx" ></u--image>
+            <text class="text">设备告警</text>
+          </view>
+        </uni-grid-item>
+
+        <uni-grid-item v-if="hasRole(['companymgr'])">
+          <view class="grid-item-box" @click="goPage('error')">
+            <u--image :showLoading="true" src="/static/images/icons/error.png" width="50rpx" height="50rpx" ></u--image>
+            <text class="text">异常列表</text>
+          </view>
+        </uni-grid-item>
+
+        <uni-grid-item v-if="hasRole(['admin'])">
+          <view class="grid-item-box" @click="scanCode()">
+            <u--image :showLoading="true" src="/static/images/icons/scan.png" width="50rpx" height="50rpx" ></u--image>
+            <text class="text">注销设备</text>
           </view>
         </uni-grid-item>
+
       </uni-grid>
+
+      <u-modal :show="show" title="绑定设备" :showCancelButton="true" @confirm="bingDevice" >
+        <view class="slot-content">
+
+          <view>设备名称:{{ scanDevice.deviceName }}</view>
+          <view>产品名称:{{ scanDevice.productName }}</view>
+          <view>设备编号:{{ scanDevice.serialNumber }}</view>
+          <view>激活日期:{{ scanDevice.activeTime }}</view>
+
+        </view>
+      </u-modal>
     </view>
   </view>
 </template>
 
 <script>
 import authObj from '@/plugins/auth.js';
+import {getDevcieByQrcode,bingDeviceDept} from '@/api/device/device';
+import UImage from "../../uni_modules/uview-ui/components/u--image/u--image";
 export default {
-    data() {
+  components: {UImage},
+  data() {
       return {
         current: 0,
         swiperDotIndex: 0,
+        show:false,
+        scanDevice:{},
         data: [{
             image: '/static/images/banner/banner01.jpg'
           },
@@ -83,11 +117,26 @@ export default {
       }
     },
     methods: {
+      bingDevice(){
+          this.show = false;
+        bingDeviceDept(this.scanDevice).then(res=>{
+          if(res.code == 200){
+            this.$modal.showToast('绑定成功')
+          }else{
+            this.$modal.showToast(res.msg);
+          }
+
+        })
+      },
+      cancel(){
+        this.scanDevice = {};
+        this.show = false;
+      },
       clickBannerItem(item) {
         console.log();
       },
       hasRole(role){
-        return authObj.hasRole(role);
+        return authObj.authRoleAdmin(role);
       },
       changeSwiper(e) {
         this.current = e.detail.current
@@ -95,6 +144,46 @@ export default {
       changeGrid(e) {
         this.$modal.showToast('模块建设中~')
       },
+      watchDevice(){
+        let self = this;
+        uni.scanCode({
+          success: function (res) {
+            console.log('条码内容:' + res.result);
+            getDevcieByQrcode(res.result).then(res=>{
+              let device = res.data;
+              if(device != null){
+                uni.navigateTo({
+                  url: '/pages/device/detail?id='+device.deviceId
+                });
+              }else{
+                self.$modal.showToast('设备不存在或无权限')
+              }
+
+            });
+          }
+        });
+      },
+      scanCode(){
+        let self = this;
+        uni.scanCode({
+          success: function (res) {
+            console.log('条码内容:' + res.result);
+            getDevcieByQrcode(res.result).then(res=>{
+                let device = res.data;
+                if(!device){
+                  self.$modal.showToast('未查到设备信息')
+                }else{
+                  if(device.deptId != null){
+                    self.$modal.showToast('该设备已经绑定了用户')
+                  }else{
+                    self.scanDevice = device;
+                    self.show = true;
+                  }
+                }
+            });
+          }
+        });
+      },
       goPage(path){
         if('device' == path){
           uni.navigateTo({
@@ -116,6 +205,17 @@ export default {
             url: '/pages/user/index'
           });
         }
+        if('alert' == path){
+          uni.navigateTo({
+            url: '/pages/device/alert'
+          });
+        }
+        if('error' == path){
+          uni.navigateTo({
+            url: '/pages/device/error'
+          });
+        }
+
       }
     }
   }

+ 17 - 1
plugins/auth.js

@@ -24,6 +24,17 @@ function authRole(role) {
   }
 }
 
+function authRoleAdmin(role) {
+  const roles = store.getters && store.getters.roles
+  if (role && role.length > 0) {
+    return roles.some(v => {
+      return  v === role
+    })
+  } else {
+    return false
+  }
+}
+
 export default {
   // 验证用户是否具备某权限
   hasPermi(permission) {
@@ -56,5 +67,10 @@ export default {
     return roles.every(item => {
       return authRole(item)
     })
-  }
+  },
+  authRoleAdmin(roles) {
+    return roles.some(item => {
+      return authRoleAdmin(item)
+    })
+  },
 }

BIN
static/images/device/qrcode.png


BIN
static/images/device/user.png


BIN
static/images/icons/alert.png


BIN
static/images/icons/code.png


BIN
static/images/icons/device.png


BIN
static/images/icons/error.png


BIN
static/images/icons/scan.png


BIN
static/images/icons/user.png


BIN
static/images/icons/wifi.png