Browse Source

no message

DESKTOP-6NE3CFS\GAGABYTE 4 năm trước cách đây
mục cha
commit
222074444f

BIN
dist.zip


+ 18 - 0
src/api/accessrecords.js

@@ -0,0 +1,18 @@
+import request from '@/utils/request'
+
+export function fetchList(query) {
+  return request({
+    url: '/ncjtEntranceGuard/getTrafficRecordViewPageList',
+    method: 'get',
+    params: query
+  })
+}
+
+export function searchList(query) {
+  return request({
+    url: '/ncjtEntranceGuard/getTrafficRecordViewPageListByParams',
+    method: 'post',
+    params: query
+  })
+}
+

+ 41 - 0
src/api/deviceWithStatus.js

@@ -0,0 +1,41 @@
+import request from '@/utils/request'
+
+export function fetchList(query) {
+    return request({
+        url: '/ncjtEntranceGuard/getDeviceIdentityPageList',
+        method: 'get',
+        params: query
+    })
+}
+
+export function checkPowers(query) {
+    return request({
+        url: '/ncjtEntranceGuard/getDeviceIdentityById',
+        method: 'post',
+        params: query
+    })
+}
+
+export function bindPowers(data) {
+    return request({
+        url: '/ncjtEntranceGuard/bindDeviceWithIdentityIds',
+        method: 'post',
+        data
+    })
+}
+
+export function deletePowers(data) {
+    return request({
+        url: '/ncjtEntranceGuard/unbindDeviceWithIdentityIds',
+        method: 'post',
+        data
+    })
+}
+
+export function searchList(data) {
+    return request({
+        url: '/ncjtEntranceGuard/addDevice',
+        method: 'post',
+        data
+    })
+}

+ 7 - 15
src/api/devicemanagement.js

@@ -8,17 +8,9 @@ export function fetchList(query) {
   })
 }
 
-export function fetchGroupIdList(data) {
-  return request({
-    url: '/ncjtEntranceGuard/getGroupList',
-    method: 'post',
-    data
-  })
-}
-
 export function createDevice(data) {
   return request({
-    url: '/ncjtEntranceGuard/addDeviceWithGroupId',
+    url: '/ncjtEntranceGuard/addDevice',
     method: 'post',
     data
   })
@@ -32,18 +24,18 @@ export function updateDevice(data) {
   })
 }
 
-export function fetchDevice(id) {
+export function deletDevice(data) {
   return request({
-    url: '/vue-element-admin/article/detail',
+    url: '/vue-element-admin/article/pv',
     method: 'get',
-    params: { id }
+    data
   })
 }
 
-export function fetchPv(pv) {
+export function fetchDevice(id) {
   return request({
-    url: '/vue-element-admin/article/pv',
+    url: '/vue-element-admin/article/detail',
     method: 'get',
-    params: { pv }
+    params: { id }
   })
 }

+ 49 - 0
src/api/devicewithgroup.js

@@ -0,0 +1,49 @@
+import request from '@/utils/request'
+
+export function fetchList(query) {
+    return request({
+        url: '/ncjtEntranceGuard/getDeviceGroupPageList',
+        method: 'get',
+        params: query
+    })
+}
+
+export function fetchGroupList(query) {
+    return request({
+        url: '/ncjtEntranceGuard/getGroupPageList',
+        method: 'get',
+        params: query
+    })
+}
+
+export function checkGroups(query) {
+    return request({
+        url: '/ncjtEntranceGuard/getDeviceGroupById',
+        method: 'post',
+        params: query
+    })
+}
+
+export function bindGroups(data) {
+    return request({
+        url: '/ncjtEntranceGuard/bindDeviceWithGroupIds',
+        method: 'post',
+        data
+    })
+}
+
+export function deleteGroups(data) {
+    return request({
+        url: '/ncjtEntranceGuard/unbindDeviceWithGroupIds',
+        method: 'post',
+        data
+    })
+}
+
+export function searchList(data) {
+    return request({
+        url: '/ncjtEntranceGuard/addDevice',
+        method: 'post',
+        data
+    })
+}

+ 9 - 25
src/api/groupmanagement.js

@@ -2,25 +2,25 @@ import request from '@/utils/request'
 
 export function fetchList(query) {
   return request({
-    url: '/ncjtEntranceGuard/getGroupList',
+    url: '/ncjtEntranceGuard/getGroupPageList',
     method: 'get',
     params: query
   })
 }
 
-export function fetchDataList(query) {
+export function createGroup(data) {
   return request({
-    url: '/ncjtEntranceGuard/getUserByGroupId',
-    method: 'get',
-    params: query
+    url: '/ncjtEntranceGuard/addGroup',
+    method: 'post',
+    data
   })
 }
 
-export function createGroup(data) {
+export function deletGroup(query) {
   return request({
-    url: '/vue-element-admin/article/create',
-    method: 'post',
-    data
+    url: '/ncjtEntranceGuard/getUserByGroupId',
+    method: 'get',
+    params: query
   })
 }
 
@@ -31,19 +31,3 @@ export function updateGroup(data) {
     data
   })
 }
-
-// export function fetchGroup(id) {
-//   return request({
-//     url: '/vue-element-admin/article/detail',
-//     method: 'get',
-//     params: { id }
-//   })
-// }
-
-// export function fetchPv(pv) {
-//   return request({
-//     url: '/vue-element-admin/article/pv',
-//     method: 'get',
-//     params: { pv }
-//   })
-// }

+ 2 - 34
src/api/index.js

@@ -2,48 +2,16 @@ import request from '@/utils/request'
 
 export function fetchList(query) {
   return request({
-    url: '/ncjtEntranceGuard/getGroupList',
+    url: '/ncjtEntranceGuard/getTrafficRecordViewPageList',
     method: 'get',
     params: query
   })
 }
 
-export function fetchGroupIdList(query) {
+export function searchList(query) {
   return request({
     url: '/vue-element-admin/article/list',
     method: 'get',
     params: query
   })
 }
-
-// export function fetchArticle(id) {
-//   return request({
-//     url: '/vue-element-admin/article/detail',
-//     method: 'get',
-//     params: { id }
-//   })
-// }
-
-// export function fetchPv(pv) {
-//   return request({
-//     url: '/vue-element-admin/article/pv',
-//     method: 'get',
-//     params: { pv }
-//   })
-// }
-
-// export function createArticle(data) {
-//   return request({
-//     url: '/vue-element-admin/article/create',
-//     method: 'post',
-//     data
-//   })
-// }
-
-// export function updateArticle(data) {
-//   return request({
-//     url: '/vue-element-admin/article/update',
-//     method: 'post',
-//     data
-//   })
-// }

+ 49 - 0
src/api/userWithGroup.js

@@ -0,0 +1,49 @@
+import request from '@/utils/request'
+
+export function fetchUserList(query) {
+    return request({
+        url: '/ncjtEntranceGuard/getUserGroupPageList',
+        method: 'get',
+        params: query
+    })
+}
+
+export function fetchGroupList(query) {
+    return request({
+        url: '/ncjtEntranceGuard/getGroupPageList',
+        method: 'get',
+        params: query
+    })
+}
+
+export function checkGroups(query) {
+    return request({
+        url: '/ncjtEntranceGuard/getUserGroupById',
+        method: 'post',
+        params: query
+    })
+}
+
+export function bindGroups(data) {
+    return request({
+        url: '/ncjtEntranceGuard/bindUserWithGroupIds',
+        method: 'post',
+        data
+    })
+}
+
+export function deleteGroups(data) {
+    return request({
+        url: '/ncjtEntranceGuard/unbindUserWithGroupIds',
+        method: 'post',
+        data
+    })
+}
+
+export function searchList(data) {
+    return request({
+        url: '/ncjtEntranceGuard/addDevice',
+        method: 'post',
+        data
+    })
+}

+ 119 - 128
src/components/Charts/MixChart.vue

@@ -1,183 +1,174 @@
 <template>
-  <div :id="id" :class="className" :style="{height:height,width:width}" />
+  <div :id="id" :class="className" :style="{ height: height, width: width }" />
 </template>
 
 <script>
-import echarts from 'echarts'
-import resize from './mixins/resize'
+import echarts from "echarts";
+import resize from "./mixins/resize";
 
 export default {
   mixins: [resize],
   props: {
     className: {
       type: String,
-      default: 'chart'
+      default: "chart",
     },
     id: {
       type: String,
-      default: 'chart'
+      default: "chart",
     },
     width: {
       type: String,
-      default: '200px'
+      default: "200px",
     },
     height: {
       type: String,
-      default: '200px'
-    }
+      default: "200px",
+    },
+    total: {
+      type: Number,
+    },
   },
   data() {
     return {
-      chart: null
-    }
+      chart: null,
+    };
   },
   mounted() {
-    this.initChart()
+    this.initChart();
   },
   beforeDestroy() {
     if (!this.chart) {
-      return
+      return;
     }
-    this.chart.dispose()
-    this.chart = null
+    this.chart.dispose();
+    this.chart = null;
   },
   methods: {
     initChart() {
-      this.chart = echarts.init(document.getElementById(this.id))
-      const xData = (function() {
-        const data = []
+      this.chart = echarts.init(document.getElementById(this.id));
+      const xData = (function () {
+        const data = [];
+        for (let i = 1; i < 25; i++) {
+          data.push(i + ":00");
+        }
+        return data;
+      })();
+
+      const xDataitem = (function () {
+        const dataitem = [];
         for (let i = 1; i < 25; i++) {
-          data.push(i + ':00')
+          dataitem.push(i + "00");
         }
-        return data
-      }())
+        return dataitem;
+      })();
+
       this.chart.setOption({
-        backgroundColor: '#fff',
+        backgroundColor: "#fff",
         title: {
-          text: 'statistics',
-          x: '20',
-          top: '20',
+          text: "statistics",
+          x: "20",
+          top: "20",
           textStyle: {
-            color: '#fff',
-            fontSize: '22'
+            color: "#fff",
+            fontSize: "22",
           },
           subtextStyle: {
-            color: '#90979c',
-            fontSize: '16'
-          }
+            color: "#90979c",
+            fontSize: "16",
+          },
         },
         tooltip: {
-          trigger: 'axis',
+          trigger: "axis",
           axisPointer: {
             textStyle: {
-              color: '#fff'
-            }
-          }
+              color: "#fff",
+            },
+          },
         },
         grid: {
-          left: '5%',
-          right: '5%',
+          left: "5%",
+          right: "5%",
           borderWidth: 0,
-          top: '5%',
+          top: "5%",
           bottom: 95,
           textStyle: {
-            color: '#fff'
-          }
+            color: "#fff",
+          },
         },
         calculable: true,
-        xAxis: [{
-          type: 'category',
-          axisLine: {
-            lineStyle: {
-              color: '#90979c'
-            }
-          },
-          splitLine: {
-            show: false
+        xAxis: [
+          {
+            type: "category",
+            axisLine: {
+              lineStyle: {
+                color: "#90979c",
+              },
+            },
+            splitLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitArea: {
+              show: false,
+            },
+            axisLabel: {
+              interval: 0,
+            },
+            data: xData,
           },
-          axisTick: {
-            show: false
+        ],
+        yAxis: [
+          {
+            type: "value",
+            splitLine: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: "#90979c",
+              },
+            },
+            axisTick: {
+              show: false,
+            },
+            axisLabel: {
+              interval: 0,
+            },
+            splitArea: {
+              show: false,
+            },
           },
-          splitArea: {
-            show: false
-          },
-          axisLabel: {
-            interval: 0
-
-          },
-          data: xData
-        }],
-        yAxis: [{
-          type: 'value',
-          splitLine: {
-            show: false
-          },
-          axisLine: {
-            lineStyle: {
-              color: '#90979c'
-            }
-          },
-          axisTick: {
-            show: false
-          },
-          axisLabel: {
-            interval: 0
-          },
-          splitArea: {
-            show: false
-          }
-        }],
+        ],
 
         series: [
-        {
-          name: '',
-          type: 'line',
-          stack: 'total',
-          symbolSize: 10,
-          symbol: 'circle',
-          itemStyle: {
-            normal: {
-              color: '#2B95F8',
-              barBorderRadius: 0,
-              label: {
-                show: true,
-                position: 'top',
-                formatter(p) {
-                  return p.value > 0 ? p.value : ''
-                }
-              }
-            }
+          {
+            name: "",
+            type: "line",
+            stack: "total",
+            symbolSize: 10,
+            symbol: "circle",
+            itemStyle: {
+              normal: {
+                color: "#2B95F8",
+                barBorderRadius: 0,
+                label: {
+                  show: true,
+                  position: "top",
+                  formatter(p) {
+                    return p.value > 0 ? p.value : "";
+                  },
+                },
+              },
+            },
+
+            data: xDataitem,
           },
-          data: [
-            1036,
-            3693,
-            2962,
-            3810,
-            25190,
-            1915,
-            1748,
-            4675,
-            6209,
-            4323,
-            2865,
-            4298,
-            10360,
-            3693,
-            2962,
-            3810,
-            2519,
-            1915,
-            1748,
-            4675,
-            6209,
-            4323,
-            2865,
-            4298
-          ]
-        }
-        ]
-      })
-    }
-  }
-}
+        ],
+      });
+    },
+  },
+};
 </script>

+ 27 - 27
src/components/Pagination/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div :class="{'hidden':hidden}" class="pagination-container">
+  <div :class="{ hidden: hidden }" class="pagination-container">
     <el-pagination
       :background="background"
       :current-page.sync="currentPage"
@@ -15,79 +15,79 @@
 </template>
 
 <script>
-import { scrollTo } from '@/utils/scroll-to'
+import { scrollTo } from "@/utils/scroll-to";
 
 export default {
-  name: 'Pagination',
+  name: "Pagination",
   props: {
     total: {
       required: true,
-      type: Number
+      type: Number,
     },
     page: {
       type: Number,
-      default: 1
+      default: 1,
     },
     limit: {
       type: Number,
-      default: 20
+      default: 20,
     },
     pageSizes: {
       type: Array,
       default() {
-        return [4, 8, 10, 20, 30, 50]
-      }
+        return [4, 8, 10, 20, 30, 50, 100];
+      },
     },
     layout: {
       type: String,
-      default: 'total, sizes, prev, pager, next, jumper'
+      default: "total, sizes, prev, pager, next, jumper",
     },
     background: {
       type: Boolean,
-      default: true
+      default: true,
     },
     autoScroll: {
       type: Boolean,
-      default: true
+      default: true,
     },
     hidden: {
       type: Boolean,
-      default: false
-    }
+      default: false,
+    },
   },
   computed: {
     currentPage: {
       get() {
-        return this.page
+        return this.page;
       },
       set(val) {
-        this.$emit('update:page', val)
-      }
+        this.$emit("update:page", val);
+      },
     },
     pageSize: {
       get() {
-        return this.limit
+        return this.limit;
       },
       set(val) {
-        this.$emit('update:limit', val)
-      }
-    }
+        this.$emit("update:limit", val);
+      },
+    },
   },
   methods: {
     handleSizeChange(val) {
-      this.$emit('pagination', { page: this.currentPage, limit: val })
+      this.$emit("pagination", { page: this.currentPage, limit: val });
       if (this.autoScroll) {
-        scrollTo(0, 800)
+        scrollTo(0, 800);
       }
     },
     handleCurrentChange(val) {
-      this.$emit('pagination', { page: val, limit: this.pageSize })
+      this.$emit("pagination", { page: val, limit: this.pageSize });
       if (this.autoScroll) {
-        scrollTo(0, 800)
+        scrollTo(0, 800);
       }
-    }
-  }
-}
+    },
+  },
+};
 </script>
 
 <style scoped>

+ 140 - 119
src/layout/components/Navbar.vue

@@ -1,34 +1,32 @@
 <template>
   <div class="navbar">
-
     <div class="left-menu">
       <div class="navbar-img">
-        <img src="../../../public/images/title.png">
-      </div>
-      <div class="navbar-info">
-        门禁设备管理平台
+        <img src="../../../public/images/title.png" />
       </div>
+      <div class="navbar-info">门禁设备管理平台</div>
     </div>
 
     <div class="right-menu">
       <div class="right-menu-time">
-        <span>{{dateFormat(newDate)}}</span>
+        <span>{{ dateFormat(newDate) }}</span>
       </div>
-      <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
+      <el-dropdown
+        class="avatar-container right-menu-item hover-effect"
+        trigger="click"
+      >
         <div class="avatar-wrapper">
           退出
           <svg-icon class="icon" icon-class="退出" />
         </div>
         <el-dropdown-menu slot="dropdown">
-
           <router-link to="/">
             <el-dropdown-item>首页</el-dropdown-item>
           </router-link>
 
           <el-dropdown-item divided @click.native="logout">
-            <span style="display:block;">退出账号</span>
+            <span style="display: block">退出账号</span>
           </el-dropdown-item>
-
         </el-dropdown-menu>
       </el-dropdown>
     </div>
@@ -36,132 +34,155 @@
 </template>
 
 <script>
-  import {
-    mapGetters
-  } from 'vuex'
-  import ErrorLog from '@/components/ErrorLog'
-  import SizeSelect from '@/components/SizeSelect'
-  import Search from '@/components/HeaderSearch'
-  import { removeToken } from '@/utils/auth' // gsk 添加
-
-  export default {
-    components: {
-      ErrorLog,
-      SizeSelect,
-      Search
-    },
-    computed: {
-      ...mapGetters([
-        'sidebar',
-        'avatar',
-        'device'
-      ])
-    },
-    data() {
-      return {
-        newDate: new Date()
-      };
-    },
-    mounted() {
-      let that = this
-      this.timer = setInterval(function() {
-        that.newDate = new Date().toLocaleString()
-      })
+import { mapGetters } from "vuex";
+import ErrorLog from "@/components/ErrorLog";
+import SizeSelect from "@/components/SizeSelect";
+import Search from "@/components/HeaderSearch";
+import { removeToken } from "@/utils/auth"; // gsk 添加
+
+export default {
+  components: {
+    ErrorLog,
+    SizeSelect,
+    Search,
+  },
+  computed: {
+    ...mapGetters(["sidebar", "avatar", "device"]),
+  },
+  data() {
+    return {
+      newDate: new Date(),
+    };
+  },
+  mounted() {
+    let that = this;
+    this.timer = setInterval(function () {
+      that.newDate = new Date().toLocaleString();
+    });
+  },
+  // 销毁时清除计时器
+  beforeDestroy: function () {
+    if (this.timer) {
+      clearInterval(this.timer);
+    }
+  },
+  methods: {
+    async logout() {
+      //await this.$store.dispatch('user/logout')
+      removeToken();
+      this.$router.push(`/login?redirect=${this.$route.fullPath}`);
     },
-    // 销毁时清除计时器
-    beforeDestroy: function() {
-      if (this.timer) {
-        clearInterval(this.timer)
-      }
+    dateFormat() {
+      var date = new Date();
+      var year = date.getFullYear();
+      var month =
+        date.getMonth() + 1 < 10
+          ? "0" + (date.getMonth() + 1)
+          : date.getMonth() + 1;
+      var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
+      var hours =
+        date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
+      var minutes =
+        date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
+      var seconds =
+        date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
+      let week = date.getDay(); // 星期
+      let weekArr = [
+        "星期日",
+        "星期一",
+        "星期二",
+        "星期三",
+        "星期四",
+        "星期五",
+        "星期六",
+      ];
+      // 拼接 时间格式处理
+      return (
+        year +
+        "年" +
+        month +
+        "月" +
+        day +
+        "日 " +
+        hours +
+        ":" +
+        minutes +
+        ":" +
+        seconds +
+        " " +
+        weekArr[week]
+      );
     },
-    methods: {
-      async logout() {
-        //await this.$store.dispatch('user/logout')
-        removeToken()
-        this.$router.push(`/login?redirect=${this.$route.fullPath}`)
-      },
-      dateFormat() {
-        var date = new Date()
-        var year = date.getFullYear()
-        var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
-        var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
-        var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
-        var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
-        var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
-        let week = date.getDay() // 星期
-        let weekArr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
-        // 拼接 时间格式处理
-        return year + '年' + month + '月' + day + '日 ' + hours + ':' + minutes + ':' + seconds + ' ' + weekArr[week]
-      }
-    }
-  }
+  },
+};
 </script>
 
 <style lang="scss" scoped>
-  .navbar {
+.navbar {
+  display: flex;
+  margin-top: 21px;
+  line-height: 50px;
+  font-size: 30px;
+  font-weight: bold;
+  background: #fff;
+  box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
+
+  .left-menu {
     display: flex;
-    margin-top: 21px;
-    line-height: 50px;
-    font-size: 30px;
-    font-weight: bold;
-    background: #fff;
-    box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
-
-    .left-menu {
-      display: flex;
-      flex: 1;
-
-      .navbar-img {
-        margin-left: 30px;
-
-        img {
-          width: 49px;
-        }
-      }
+    flex: 1;
+
+    .navbar-img {
+      margin-left: 30px;
 
-      .navbar-info {
-        margin-left: 18px;
+      img {
+        width: 49px;
       }
     }
 
-    .right-menu {
-      display: flex;
-      font-size: 15px;
+    .navbar-info {
+      margin-left: 18px;
+    }
+  }
 
-      &:focus {
-        outline: none;
-      }
-      .right-menu-time {
-        margin-right: 50px;
-      }
+  .right-menu {
+    display: flex;
+    font-size: 15px;
 
-      .right-menu-item {
-        display: inline-block;
-        padding: 0 8px;
-        height: 100%;
-        font-size: 18px;
-        color: #5a5e66;
-        vertical-align: text-bottom;
-
-        &.hover-effect {
-          cursor: pointer;
-          transition: background .3s;
-
-          &:hover {
-            background: rgba(0, 0, 0, .025)
-          }
-        }
+    &:focus {
+      outline: none;
+    }
+    .right-menu-time {
+      margin-right: 50px;
+    }
 
-        .avatar-wrapper {
-          .icon {
-            margin-left: 10px;
-          }
+    .right-menu-item {
+      display: inline-block;
+      padding: 0 8px;
+      margin-left: 20px;
+      height: 100%;
+      font-size: 18px;
+      color: #5a5e66;
+      vertical-align: text-bottom;
+
+      &.hover-effect {
+        cursor: pointer;
+        transition: background 0.3s;
+
+        &:hover {
+          background: rgba(0, 0, 0, 0.025);
         }
       }
 
-      .avatar-container {
-        margin-right: 30px;
+      .avatar-wrapper {
+        .icon {
+          margin-left: 10px;
+        }
       }
     }
+
+    .avatar-container {
+      margin-right: 30px;
+    }
   }
+}
 </style>

+ 0 - 1
src/main.js

@@ -35,7 +35,6 @@ import * as filters from './filters' // global filters
 
 Vue.use(Element, {
   size: Cookies.get('size') || 'medium', // set element-ui default size
-  locale: enLang // 如果使用中文,无需设置,请删除
 })
 
 // register global utility filters

+ 65 - 0
src/router/index.js

@@ -109,6 +109,58 @@ export const constantRoutes = [
     ]
   },
   {
+    path: '/devicewithGroup',
+    component: Layout,
+    redirect: '/devicewithGroup/index',
+    children: [
+      {
+        path: 'index',
+        component: () => import('@/views/devicewithGroup/index'),
+        name: 'devicewithGroup',
+        meta: { title: '设备与组绑定', icon: 'tree', noCache: true }
+      }
+    ]
+  },
+  {
+    path: '/deviceWithStatus',
+    component: Layout,
+    redirect: '/deviceWithStatus/index',
+    children: [
+      {
+        path: 'index',
+        component: () => import('@/views/deviceWithStatus/index'),
+        name: 'deviceWithStatus',
+        meta: { title: '设备添加身份权限', icon: 'tab', noCache: true }
+      }
+    ]
+  },
+  {
+    path: '/userWithGroup',
+    component: Layout,
+    redirect: '/userWithGroup/index',
+    children: [
+      {
+        path: 'index',
+        component: () => import('@/views/userWithGroup/index'),
+        name: 'userWithGroup',
+        meta: { title: '用户与组绑定', icon: 'table', noCache: true }
+      }
+    ]
+  },
+  {
+    path: '/accessRecords',
+    component: Layout,
+    redirect: '/accessRecords/index',
+    children: [
+      {
+        path: 'index',
+        component: () => import('@/views/accessRecords/index'),
+        name: 'accessRecords',
+        meta: { title: '通行记录', icon: 'people', noCache: true }
+      }
+    ]
+  },
+  {
     path: '/user',
     component: Layout,
     redirect: '/user/index',
@@ -121,6 +173,19 @@ export const constantRoutes = [
       }
     ]
   },
+  // {
+  //   path: '/management',
+  //   component: Layout,
+  //   redirect: '/management/index',
+  //   children: [
+  //     {
+  //       path: 'index',
+  //       component: () => import('@/views/management/index'),
+  //       name: 'management',
+  //       meta: { title: '大门管理', icon: 'lock', noCache: true }
+  //     }
+  //   ]
+  // },
   {
     path: '/profile',
     component: Layout,

+ 11 - 6
src/utils/request.js

@@ -1,7 +1,12 @@
 import axios from 'axios'
-import { MessageBox, Message } from 'element-ui'
+import {
+  MessageBox,
+  Message
+} from 'element-ui'
 import store from '@/store'
-import { getToken } from '@/utils/auth'
+import {
+  getToken
+} from '@/utils/auth'
 
 // create an axios instance
 const service = axios.create({
@@ -35,7 +40,7 @@ service.interceptors.response.use(
   /**
    * If you want to get http information such as headers or status
    * Please return  response => response
-  */
+   */
 
   /**
    * Determine the request status by custom code
@@ -56,7 +61,8 @@ service.interceptors.response.use(
       // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
       if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
         // to re-login
-        MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
+        MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again',
+          'Confirm logout', {
           confirmButtonText: 'Re-Login',
           cancelButtonText: 'Cancel',
           type: 'warning'
@@ -78,9 +84,8 @@ service.interceptors.response.use(
       type: 'error',
       duration: 5 * 1000
     })
-    //return Promise.resolve()
+    // return Promise.resolve()
     return Promise.reject(error)
   }
 )
-
 export default service

+ 299 - 0
src/views/accessRecords/index.vue

@@ -0,0 +1,299 @@
+<template>
+  <div>
+    <!-- 条件搜索区域 -->
+    <div class="form-head">
+      <span>设备:</span>
+      <span class="input-select">
+        <el-select
+          v-model="listQuery.deviceName"
+          size="mini"
+          clearable
+          @clear="getList"
+          placeholder="请选择设备名称"
+        >
+          <el-option
+            v-for="item in list"
+            :key="item.id"
+            :label="item.deviceName"
+            :value="item.deviceName"
+          >
+          </el-option>
+        </el-select>
+      </span>
+
+      <span>卡号:</span>
+      <span class="input">
+        <el-input
+          v-model="listQuery.cardNumber"
+          size="mini"
+          placeholder="请输入卡号"
+          clearable
+          @clear="getList"
+          @keyup.enter.native="handleFilter"
+        >
+        </el-input>
+      </span>
+
+      <span>姓名:</span>
+      <span class="input">
+        <el-input
+          v-model="listQuery.userName"
+          size="mini"
+          placeholder="请输入姓名"
+          clearable
+          @clear="getList"
+          @keyup.enter.native="handleFilter"
+        >
+        </el-input>
+      </span>
+
+      <span>通行时间:</span>
+      <el-date-picker
+        v-model="listQuery.time"
+        size="mini"
+        type="datetimerange"
+        start-placeholder="开始时间"
+        end-placeholder="结束时间"
+        value-format="timestamp"
+      >
+      </el-date-picker>
+
+      <el-button type="primary" size="mini" class="button" @click="handleFilter"
+        >查询</el-button
+      >
+      <el-button
+        type="primary"
+        size="mini"
+        class="button"
+        @click="refreshGetList"
+        >刷新</el-button
+      >
+    </div>
+
+    <!-- 表格区域 -->
+    <div class="form">
+      <el-table :data="list">
+        <el-table-column label="序号" align="center">
+          <template slot-scope="{ row }">
+            <span>{{ row.id }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="卡号" width="250px" align="center">
+          <template slot-scope="{ row }">
+            <span>{{ row.cardNumber }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="姓名" align="center">
+          <template slot-scope="{ row }">
+            <span>{{ row.userName }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="身份类型" align="center">
+          <template slot-scope="{ row }">
+            <span>{{ row.identityName }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="设备名称" width="250px" align="center">
+          <template slot-scope="{ row }">
+            <span>{{ row.deviceName }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="分组名称" align="center">
+          <template slot-scope="{ row }">
+            <span>{{ row.groupName }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="信息" align="center" width="300px">
+          <template slot-scope="{ row }">
+            <span>{{ row.message }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="通行时间" width="200px" align="center">
+          <template slot-scope="{ row }">
+            <span>{{ timestampToTime(row.time) }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 底部分页区开始 -->
+      <div class="block">
+        <template>
+          <pagination
+            v-show="total > 0"
+            :total="total"
+            :page.sync="listQuery.page"
+            :limit.sync="listQuery.limit"
+            @pagination="getListTotalPage"
+          />
+        </template>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Pagination from "@/components/Pagination";
+import { fetchList, searchList } from "@/api/accessrecords";
+export default {
+  components: {
+    Pagination,
+  },
+  data() {
+    return {
+      list: [],
+      total: 0, //数据的总数//
+      listQuery: {
+        page: 1,
+        limit: 8,
+        cardNumber: "",
+        deviceName: "",
+        groupName: "",
+        identityName: "",
+        message: "",
+        time: "",
+        userName: "",
+      },
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    getList() {
+      fetchList({
+        page: this.listQuery.page,
+        limit: this.listQuery.limit,
+      }).then((response) => {
+        this.list = response.data;
+        this.total = response.total;
+      });
+    },
+    getListTotalPage() {
+      //获取分页数据
+      if (
+        this.listQuery.deviceName ||
+        this.listQuery.userName ||
+        this.listQuery.cardNumber ||
+        this.listQuery.time
+      ) {
+        this.handleFilter();
+      } else {
+        this.getList();
+      }
+    },
+    refreshGetList() {
+      //刷新页面
+      this.$router.go(0);
+    },
+    handleFilter() {
+      //搜索数据
+      searchList({
+        page: this.listQuery.page,
+        limit: this.listQuery.limit,
+        cardNumber: this.listQuery.cardNumber,
+        deviceName: this.listQuery.deviceName,
+        time1: this.listQuery.time[0],
+        time2: this.listQuery.time[1],
+        userName: this.listQuery.userName,
+      }).then((response) => {
+        this.list = response.data;
+        this.total = response.total;
+      });
+    },
+    timestampToTime(time) {
+      //格式化时间
+      var date = new Date(time);
+      var year = date.getFullYear();
+      var month =
+        date.getMonth() + 1 < 10
+          ? "0" + (date.getMonth() + 1)
+          : date.getMonth() + 1;
+      var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
+      var hours =
+        date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
+      var minutes =
+        date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
+      var seconds =
+        date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
+      return (
+        year +
+        "-" +
+        month +
+        "-" +
+        day +
+        "  " +
+        hours +
+        ":" +
+        minutes +
+        ":" +
+        seconds
+      );
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.form-head {
+  margin: 0 40px;
+  width: 1504px;
+  line-height: 118px;
+  font-size: 9px;
+
+  .input {
+    display: inline-block;
+    margin-right: 30px;
+    width: 210px;
+  }
+
+  .input-select {
+    display: inline-block;
+    margin-right: 29px;
+    width: 148px;
+  }
+
+  .button {
+    margin-left: 41px;
+  }
+}
+
+.form {
+  margin-left: 40px;
+  width: 1480px;
+
+  .button-img {
+    img {
+      width: 53.5px;
+    }
+  }
+
+  .button-info {
+    margin-top: 39px;
+  }
+
+  .button {
+    color: red;
+  }
+
+  img {
+    width: 8.5px;
+    margin-right: 8px;
+  }
+
+  .block {
+    // display: flex;
+    float: right;
+  }
+
+  .foot-button {
+    margin-top: 53px;
+  }
+}
+</style>

+ 0 - 49
src/views/clipboard/index.vue

@@ -1,49 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-tabs v-model="activeName">
-      <el-tab-pane label="use clipboard  directly" name="directly">
-        <el-input v-model="inputData" placeholder="Please input" style="width:400px;max-width:100%;" />
-        <el-button type="primary" icon="el-icon-document" @click="handleCopy(inputData,$event)">
-          copy
-        </el-button>
-      </el-tab-pane>
-      <el-tab-pane label="use clipboard by v-directive" name="v-directive">
-        <el-input v-model="inputData" placeholder="Please input" style="width:400px;max-width:100%;" />
-        <el-button v-clipboard:copy="inputData" v-clipboard:success="clipboardSuccess" type="primary" icon="el-icon-document">
-          copy
-        </el-button>
-      </el-tab-pane>
-    </el-tabs>
-  </div>
-</template>
-
-<script>
-import clip from '@/utils/clipboard' // use clipboard directly
-import clipboard from '@/directive/clipboard/index.js' // use clipboard by v-directive
-
-export default {
-  name: 'ClipboardDemo',
-  directives: {
-    clipboard
-  },
-  data() {
-    return {
-      activeName: 'directly',
-      inputData: 'https://github.com/PanJiaChen/vue-element-admin'
-    }
-  },
-  methods: {
-    handleCopy(text, event) {
-      clip(text, event)
-    },
-    clipboardSuccess() {
-      this.$message({
-        message: 'Copy successfully',
-        type: 'success',
-        duration: 1500
-      })
-    }
-  }
-}
-</script>
-

+ 351 - 402
src/views/deviceManagement/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="body">
-    <!-- 头部区域开始 -->
+    <!-- 头部区域 -->
 
     <div class="head">
       <div class="head-img">
@@ -9,503 +9,452 @@
       <div class="head-info">设备管理</div>
     </div>
 
-    <!-- 头部区域结束 -->
-
-    <!-- 开关按钮区域开始 -->
+    <!-- 开关按钮区域 -->
 
     <div class="switch">
       所有设备
       <div class="switch-sw">
-        <el-switch v-model="value" active-color="#3BAAFD" inactive-color="#CCCCCC" @change="changeMainSwitch">
+        <el-switch
+          v-model="value"
+          active-color="#3BAAFD"
+          inactive-color="#CCCCCC"
+          active-value="1"
+          inactive-value="0"
+          @change="changeMainSwitch"
+        >
         </el-switch>
       </div>
 
       <div class="switch-button">
         <el-row>
-          <el-button type="primary" size="small" @click="handleCreate"><img src="../../../public/images/img-3.png" />添加
+          <el-button type="primary" size="small" @click="handleCreate"
+            ><img src="../../../public/images/img-3.png" />添加
           </el-button>
         </el-row>
-
-        <!-- 添加按钮弹窗区域开始 -->
-
-        <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogVisible" width="30%" center>
-          <el-form ref="dataForm" :model="temp" :rules="rules">
-            <el-form-item style="white-space: pre" label="序列号:" class="switch-button-item" prop="serialNumber">
-              <el-col :span="12">
-                <el-input v-model="temp.serialNumber" autocomplete="off" placeholder="请输入序列号"></el-input>
-              </el-col>
-            </el-form-item>
-            <el-form-item style="white-space: pre" label="名    称:" class="switch-button-item" prop="deviceName">
-              <el-col :span="12">
-                <el-input v-model="temp.deviceName" autocomplete="off" placeholder="请输入名称"></el-input>
-              </el-col>
-            </el-form-item>
-            <el-form-item style="white-space: pre" label="分    组:" class="switch-button-item" prop="groupId">
-              <el-col :span="12">
-                <el-select v-model="temp.groupId" placeholder="请选择活动区域" style="width: 100%">
-                  <el-option :value="item.id" :label="item.name" v-for="item in groupidlist">{{item.name}}</el-option>
-                </el-select>
-              </el-col>
-            </el-form-item>
-          </el-form>
-          <span slot="footer">
-            <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">确 定</el-button>
-            <el-button @click="dialogVisible = false">取 消</el-button>
-          </span>
-        </el-dialog>
-
-        <!-- 添加按钮弹窗区域结束 -->
       </div>
     </div>
 
-    <!-- 开关按钮区域结束 -->
-
-    <!-- 表格区域开始 -->
+    <!-- 表格区域 -->
     <div class="form">
-      <el-table :data="list" @sort-change="sortChange">
-        
-        <!-- 不显示 -->
-        <el-table-column label="序号" align="center" v-if="false">
-          <template slot-scope="{ row }">
-            <span>{{ row.id }}</span>
-          </template>
-        </el-table-column>
-        <!-- 不显示 -->
-        
-        <el-table-column label="序列号" width="300px" align="center">
+      <el-table :data="list">
+        <el-table-column label="序列号" align="center">
           <template slot-scope="{ row }">
             <span>{{ row.serialNumber }}</span>
           </template>
         </el-table-column>
+
         <el-table-column label="名称" width="300px" align="center">
           <template slot-scope="{ row }">
             <span>{{ row.name }}</span>
           </template>
         </el-table-column>
-        <el-table-column label="分组" align="center">
+
+        <el-table-column label="厂家" align="center">
           <template slot-scope="{ row }">
-            <span>{{ row.group }}</span>
+            <span>{{ row.manufacturer }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="型号" align="center">
+          <template slot-scope="{ row }">
+            <span>{{ row.model }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="IP地址" align="center">
+          <template slot-scope="{ row }">
+            <span>{{ row.ipAddress }}</span>
           </template>
         </el-table-column>
 
         <el-table-column label="开关" align="center">
           <template slot-scope="scope">
-            <el-switch v-model="scope.row.value" active-color="#3BAAFD" inactive-color="#CCCCCC" @change="changeSwitch(scope.row)">
+            <el-switch
+              v-model="scope.row.status"
+              active-color="#3BAAFD"
+              inactive-color="#CCCCCC"
+              :active-value="1"
+              :inactive-value="0"
+              @change="changeSwitch(scope.row.status)"
+            >
             </el-switch>
           </template>
         </el-table-column>
 
-        </el-table-column>
-
         <el-table-column label="操作" width="180px" align="center">
           <template slot-scope="{ row, $index }">
-            <el-button type="text" size="small" @click="handleUpdate(row)">编辑</el-button>
-
-            <el-button @click="dialogTableVisible = true" type="text" size="small">
-              查看详情</el-button>
-
-            <el-button @click="handleDelete(row, $index)" type="text" size="small" class="button"><img
-                src="../../../public/images/img-2.png" />删除</el-button>
+            <el-button type="text" size="small" @click="handleUpdate(row)"
+              >编辑</el-button
+            >
+
+            <el-button
+              @click="handleDelete(row, $index)"
+              type="text"
+              size="small"
+              class="button"
+              ><img src="../../../public/images/img-2.png" />删除</el-button
+            >
           </template>
         </el-table-column>
       </el-table>
 
-      <!-- 查看详情弹窗区域开始 -->
+      <!-- 底部分页区 -->
+
+      <div class="block">
+        <template>
+          <pagination
+            :total="total"
+            :page.sync="listQuery.page"
+            :limit.sync="listQuery.limit"
+            @pagination="getList"
+          />
+        </template>
+      </div>
+    </div>
 
-      <el-dialog title="通行记录" :visible.sync="dialogTableVisible">
-        <el-row :gutter="20">
-          <el-col :span="7">
-            <div>
-              姓名:
-              <el-input v-model="gridData.name" autocomplete="off" placeholder="请输入姓名" style="width: 150px"></el-input>
-            </div>
+    <!-- 添加编辑按钮弹窗区域 -->
+    <el-dialog
+      :title="textMap[dialogStatus]"
+      :visible.sync="dialogVisible"
+      width="30%"
+      center
+    >
+      <el-form ref="dataForm" :model="temp" :rules="rules">
+        <el-form-item
+          style="white-space: pre"
+          label="序列号:"
+          class="switch-button-item"
+          prop="serialNumber"
+        >
+          <el-col :span="12">
+            <el-input
+              v-model="temp.serialNumber"
+              autocomplete="off"
+              placeholder="请输入序列号"
+            ></el-input>
           </el-col>
-          <el-col :span="7">
-            <div>
-              学号:
-              <el-input v-model="gridData.number" autocomplete="off" placeholder="请输入学号" style="width: 150px">
-              </el-input>
-            </div>
+        </el-form-item>
+
+        <el-form-item
+          style="white-space: pre"
+          label="名    称:"
+          class="switch-button-item"
+          prop="name"
+        >
+          <el-col :span="12">
+            <el-input
+              v-model="temp.name"
+              autocomplete="off"
+              placeholder="请输入名称"
+            ></el-input>
           </el-col>
-          <el-col :span="7">
-            <div>
-              时间:
-              <el-date-picker v-model="gridData.date" type="datetime" placeholder="选择日期时间" style="width: 150px">
-              </el-date-picker>
-            </div>
+        </el-form-item>
+
+        <el-form-item
+          style="white-space: pre"
+          label="厂      家:"
+          class="switch-button-item"
+          prop="manufacturer"
+        >
+          <el-col :span="12">
+            <el-input
+              v-model="temp.manufacturer"
+              autocomplete="off"
+              placeholder="请输入厂家"
+            ></el-input>
           </el-col>
-          <el-col :span="3">
-            <div>
-              <el-button type="primary">搜索</el-button>
-            </div>
+        </el-form-item>
+
+        <el-form-item
+          style="white-space: pre"
+          label="型      号:"
+          class="switch-button-item"
+          prop="model"
+        >
+          <el-col :span="12">
+            <el-input
+              v-model="temp.model"
+              autocomplete="off"
+              placeholder="请输入型号"
+            ></el-input>
           </el-col>
-        </el-row>
-
-        <el-table :data="gridData">
-          <el-table-column type="selection" width="55">
-            <template slot-scope="scope">
-              <el-checkbox v-model="scope.row.checked"></el-checkbox>
-            </template>
-          </el-table-column>
-          <el-table-column property="name" label="姓名"></el-table-column>
-          <el-table-column property="number" label="学号"></el-table-column>
-          <el-table-column property="date" label="通行时间"></el-table-column>
-        </el-table>
-
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <div class="foot-button">
-              <el-button type="primary">导出记录</el-button>
-            </div>
+        </el-form-item>
+
+        <el-form-item
+          style="white-space: pre"
+          label="IP  地 址:"
+          class="switch-button-item"
+          prop="ipAddress"
+        >
+          <el-col :span="12">
+            <el-input
+              v-model="temp.ipAddress"
+              autocomplete="off"
+              placeholder="请输入IP地址"
+            ></el-input>
           </el-col>
-          <el-col :span="16">
-            <div>
-              <pagination v-show="total > 0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit"
-                @pagination="getList" />
-            </div>
-          </el-col>
-        </el-row>
-      </el-dialog>
-
-      <!-- 查看详情弹窗区域结束 -->
-
-      <!-- 删除弹窗开始 -->
-
-      <!-- <el-dialog title="提示" :visible.sync="dialogremove" width="30%" center>
-        <div class="button-img" align="center">
-          <img src="../../../public/images/group-2.png" />
-        </div>
-
-        <div class="button-info" align="center">
-          删除该设备将删除设备上的所有人员信息
-        </div>
-
-        <span slot="footer">
-          <el-button type="primary" @click="handleDelete(row, $index)">确 定</el-button>
-          <el-button @click="dialogremove = false">取 消</el-button>
-        </span>
-      </el-dialog> -->
-
-      <!-- 删除弹窗结束 -->
-    </div>
-
-    <!-- 表格区域结束 -->
-
-    <!-- 底部分页区开始 -->
-
-    <div class="block">
-      <template>
-        <pagination :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
-      </template>
-    </div>
-
-    <!-- 底部分页区结束 -->
+        </el-form-item>
+      </el-form>
+      <span slot="footer">
+        <el-button
+          type="primary"
+          @click="dialogStatus === 'create' ? createData() : updateData()"
+          >确 定</el-button
+        >
+        <el-button @click="dialogVisible = false">取 消</el-button>
+      </span>
+    </el-dialog>
   </div>
 </template>
 
 <script>
-  import Pagination from "@/components/Pagination";
-  import {
-    fetchList,
-    fetchGroupIdList,
-    createDevice,
-    updateDevice,
-    // fetchDevice,
-    // fetchPv
-  } from "@/api/devicemanagement";
-  export default {
-    components: {
-      Pagination,
-    },
-    data() {
-      return {
-        list: [],
-        groupidlist: [],
-        gridData: [{
-            date: "2016-05-02 11:15:02",
-            name: "王小虎",
-            number: "1403090101",
-          },
-          {
-            date: "2016-05-04 11:15:56",
-            name: "王虎",
-            number: "1403090102",
-          },
-          {
-            date: "2016-05-04 11:15:56",
-            name: "王虎",
-            number: "1403090102",
-          },
-          {
-            date: "2016-05-04 11:15:56",
-            name: "王虎",
-            number: "1403090102",
-          },
+import Pagination from "@/components/Pagination";
+import {
+  fetchList,
+  createDevice,
+  updateDevice,
+  deletDevice,
+} from "@/api/devicemanagement";
+export default {
+  components: {
+    Pagination,
+  },
+  data() {
+    return {
+      list: [],
+      total: 0, //数据的总数//
+      listQuery: {
+        page: 1, //当前在第几页//
+        limit: 8, //一页几条//
+      },
+      value: "1",
+      dialogVisible: false,
+      dialogStatus: "",
+      textMap: {
+        update: "编辑门禁设备",
+        create: "添加门禁设备",
+      },
+      temp: {
+        id: "",
+        serialNumber: "",
+        name: "",
+        manufacturer: "",
+        model: "",
+        ipAddress: "",
+        status: "1",
+      },
+      rules: {
+        serialNumber: [
           {
-            date: "2016-05-04 11:15:56",
-            name: "王虎",
-            number: "1403090102",
+            required: true,
+            message: "请输入序列号",
+            trigger: "change",
           },
+        ],
+        name: [
           {
-            date: "2016-05-04 11:15:56",
-            name: "王虎",
-            number: "1403090102",
+            required: true,
+            message: "请输入名称",
+            trigger: "change",
           },
         ],
-        total: 0, //数据的总数//
-        listQuery: {
-          page: 1, //当前在第几页//
-          limit: 8, //一页几条//
-        },
-        groupidlistQuery:[],
-        value: false,
-        dialogVisible: false,
-        dialogTableVisible: false,
-        dialogStatus: "",
-        textMap: {
-          update: "编辑",
-          create: "添加",
-        },
-        temp: {
-          id: "",
-          serialNumber: "",
-          deviceName: "",
-          groupId: "",
-        },
-        rules: {
-          serialNumber: [{
-            required: true,
-            message: '请输入序列号',
-            trigger: 'change'
-          }],
-          deviceName: [{
-            required: true,
-            message: '请输入名称',
-            trigger: 'change'
-          }],
-          groupId: [{
-            required: true,
-            message: '请输入分组',
-            trigger: 'change'
-          }],
-        },
+      },
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    getList() {
+      fetchList(this.listQuery).then((response) => {
+        this.list = response.data;
+        this.total = response.total;
+      });
+    },
+    handleDelete(row, index) {
+      if (confirm("是否删除?")) {
+        deletDevice(this.list).then(() => {
+          this.$notify({
+            title: "删除成功",
+            type: "success",
+            duration: 2000,
+          });
+          this.list.splice(index, 1);
+        });
+      }
+    },
+    resetTemp() {
+      this.temp = {
+        id: undefined,
+        serialNumber: "",
+        name: "",
+        manufacturer: "",
+        model: "",
+        ipAddress: "",
+        status: "1",
       };
     },
-    created() {
-      this.getList();
+    handleCreate() {
+      this.resetTemp();
+      this.dialogStatus = "create";
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs["dataForm"].clearValidate();
+      });
     },
-    methods: {
-      getList() {
-        fetchList(this.listQuery).then((response) => {
-          this.list = response.data;
-          this.total = response.total;
-        });
-      },
-      handleDelete(row, index) {
-        if (confirm('是否删除?')) {
-          createGroup(this.list).then(() => {
+    handleUpdate(row) {
+      this.temp = Object.assign({}, row); // copy obj
+      this.dialogStatus = "update";
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs["dataForm"].clearValidate();
+      });
+    },
+    createData() {
+      this.$refs["dataForm"].validate((valid) => {
+        if (valid) {
+          createDevice(this.temp).then(() => {
+            this.list.push({
+              serialNumber: this.temp.serialNumber,
+              name: this.temp.name,
+              manufacturer: this.temp.manufacturer,
+              model: this.temp.model,
+              ipAddress: this.temp.ipAddress,
+              status: this.temp.status,
+            });
+            this.dialogVisible = false;
             this.$notify({
-              title: "删除成功",
+              title: "添加成功",
               type: "success",
               duration: 2000,
             });
-            this.list.splice(index, 1);
           });
         }
-      },
-      resetTemp() {
-        this.temp = {
-          id: undefined,
-          serialNumber: "",
-          deviceName: "",
-          groupId: "",
-        };
-        // this.temp.id = (this.tableData.length - 0) + 1
-      },
-      handleCreate() {
-        this.getGroupIdList();
-        this.resetTemp();
-        this.dialogStatus = "create";
-        this.dialogVisible = true;
-        this.$nextTick(() => {
-          this.$refs["dataForm"].clearValidate();
-        });
-      },
-      getGroupIdList() {
-        fetchGroupIdList(this.groupidlistQuery).then((response) => {
-          this.groupidlist = response.data;
-        });
-      },
-      createData() {
-        this.$refs["dataForm"].validate((valid) => {
-          if (valid) {
-            // this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
-            // this.temp.author = 'vue-element-admin'
-            createDevice(this.temp).then(() => {
-              this.list.push({serialNumber:this.temp.serialNumber, name:this.temp.deviceName, group:this.temp.groupId});
-              this.dialogVisible = false;
-              this.$notify({
-                title: "添加成功",
-                type: "success",
-                duration: 2000,
-              });
-            });
-          }
-        });
-      },
-      updateData() {
-        this.$refs["dataForm"].validate((valid) => {
-          if (valid) {
-            const tempData = Object.assign({}, this.temp);
-            // tempData.timestamp = +new Date(tempData
-            //   .timestamp); // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
-            updateDevice(tempData).then(() => {
-              const index = this.list.findIndex((v) => v.id === this.temp.id);
-              this.list.splice(index, 1, this.temp);
-              this.dialogVisible = false;
-              this.$notify({
-                title: "编辑成功",
-                type: "success",
-                duration: 2000,
-              });
+      });
+    },
+    updateData() {
+      this.$refs["dataForm"].validate((valid) => {
+        if (valid) {
+          const tempData = Object.assign({}, this.temp);
+          updateDevice(tempData).then(() => {
+            const index = this.list.findIndex((v) => v.id === this.temp.id);
+            this.list.splice(index, 1, this.temp);
+            this.dialogVisible = false;
+            this.$notify({
+              title: "编辑成功",
+              type: "success",
+              duration: 2000,
             });
-          }
-        });
-      },
-      handleUpdate(row) {
-        this.temp = Object.assign({}, row); // copy obj
-        this.temp.timestamp = new Date(this.temp.timestamp);
-        this.dialogStatus = "update";
-        this.dialogVisible = true;
-        this.$nextTick(() => {
-          this.$refs["dataForm"].clearValidate();
-        });
-      },
-      handleFilter() {
-        this.listQuery.page = 1
-        this.getList()
-      },
-      sortChange(data) {
-        const {
-          prop,
-          order
-        } = data
-        if (prop === 'id') {
-          this.sortByID(order)
+          });
         }
-      },
-      sortByID(order) {
-        if (order === 'ascending') {
-          this.listQuery.sort = '+id'
+      });
+    },
+    changeSwitch(status) {
+      console.log(status);
+      // this.list.status == 1 ? (this.list.status = 0) : (this.list.status = 1);
+      // console.log(this.list.status);
+    },
+    changeMainSwitch(value) {
+      console.log(value);
+      if (value == 0) {
+        if (confirm("确定关闭所有设备吗?")) {
+          alert("关闭所有设备");
+          // 执行关闭所有设备
         } else {
-          this.listQuery.sort = '-id'
+          this.value = "1";
         }
-        this.handleFilter()
-      },
-      changeSwitch(data) {
-        console.log(data.value);
-      },
-      changeMainSwitch(value) {
-        console.log(value)
       }
     },
-  };
+  },
+};
 </script>
 
 <style lang="scss" scoped>
-  .body {
-    width: 1551px;
-    height: 480.5px;
-    margin: 29px 29px 0 31px;
-
-    .head {
-      display: flex;
-      width: 1380px;
-      height: 55px;
-      margin-left: 40px;
-      border-bottom: 1px solid #cccccc;
-
-      .head-img {
-        width: 30px;
-        height: 30px;
+.body {
+  width: 1551px;
+  margin: 29px 29px 0 31px;
+  .head {
+    display: flex;
+    width: 1380px;
+    height: 55px;
+    margin-left: 40px;
+    border-bottom: 1px solid #cccccc;
+
+    .head-img {
+      width: 30px;
+      height: 30px;
 
-        img {
-          width: 30px;
-        }
-      }
-
-      .head-info {
-        width: 95px;
-        height: 22px;
-        margin-top: 5px;
-        margin-left: 16px;
-        font-weight: bold;
+      img {
+        width: 30px;
       }
     }
 
-    .switch {
-      display: flex;
-      width: 1380px;
-      line-height: 58px;
-      margin-left: 40px;
-      font-size: 9px;
+    .head-info {
+      width: 95px;
+      height: 22px;
+      margin-top: 5px;
+      margin-left: 16px;
+      font-weight: bold;
+    }
+  }
 
-      .switch-sw {
-        width: 45px;
-        margin-left: 19px;
-      }
+  .switch {
+    display: flex;
+    width: 1380px;
+    line-height: 58px;
+    margin-left: 40px;
+    font-size: 9px;
 
-      .switch-button {
-        width: 50px;
-        margin-left: 103px;
+    .switch-sw {
+      width: 45px;
+      margin-left: 19px;
+    }
 
-        img {
-          width: 10.5px;
-          margin-right: 8px;
-        }
+    .switch-button {
+      width: 50px;
+      margin-left: 103px;
 
-        .switch-button-item {
-          margin-left: 120px;
-          margin-bottom: 50px;
-        }
+      img {
+        width: 10.5px;
+        margin-right: 8px;
       }
     }
+  }
 
-    .form {
-      margin-left: 40px;
-      width: 1380px;
-      // height: 398px;
-      // overflow: hidden;
+  .form {
+    margin-left: 40px;
+    width: 1380px;
 
-      .button-img {
-        img {
-          width: 53.5px;
-        }
+    .button-img {
+      img {
+        width: 53.5px;
       }
+    }
 
-      .button-info {
-        margin-top: 39px;
-      }
+    .button-info {
+      margin-top: 39px;
+    }
 
-      .button {
-        color: red;
-      }
+    .button {
+      color: red;
+    }
 
-      img {
-        width: 8.5px;
-        margin-right: 8px;
-      }
+    img {
+      width: 8.5px;
+      margin-right: 8px;
     }
 
     .block {
-      display: flex;
-      position: absolute;
-      right: 129px;
-      bottom: 45px;
+      float: right;
     }
 
     .foot-button {
       margin-top: 53px;
     }
   }
+  .switch-button-item {
+    margin-left: 120px;
+    margin-top: 32px;
+  }
+}
 </style>

+ 355 - 0
src/views/deviceWithStatus/index.vue

@@ -0,0 +1,355 @@
+<template>
+  <div class="body">
+    <!-- 头部区域 -->
+
+    <div class="head">
+      <div class="head-img">
+        <img src="../../../public/images/img-1.png" />
+      </div>
+      <div class="head-info">设备添加身份权限</div>
+      <div class="input">
+        <el-input
+          v-model="listQuery.name"
+          size="small"
+          placeholder="请输入设备名称"
+          clearable
+          @clear="getList"
+          @keyup.enter.native="handleFilter"
+        >
+        </el-input>
+      </div>
+
+      <div class="input-serch">
+        <el-row>
+          <el-button size="small" type="primary" @click="handleFilter"
+            >搜索</el-button
+          >
+        </el-row>
+      </div>
+    </div>
+
+    <!-- 表格区域 -->
+    <div class="form">
+      <el-table :data="list">
+        <el-table-column label="序列号" align="center" width="440px">
+          <template slot-scope="{ row }">
+            <span>{{ row.serialNumber }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="名称" align="center" width="440px">
+          <template slot-scope="{ row }">
+            <span>{{ row.deviceName }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="操作" width="440px" align="center">
+          <template slot-scope="{ row }">
+            <el-button type="text" size="small" @click="checkPower(row)"
+              >查看当前权限</el-button
+            >
+            <el-button type="text" size="small" @click="bindPower(row)"
+              >添加权限</el-button
+            >
+            <el-button type="text" size="small" @click="unbindPower(row)"
+              >删除权限</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 底部分页区 -->
+
+      <div class="block">
+        <template>
+          <pagination
+            :total="total"
+            :page.sync="listQuery.page"
+            :limit.sync="listQuery.limit"
+            @pagination="getList"
+          />
+        </template>
+      </div>
+    </div>
+
+    <!-- 查看权限弹窗区域 -->
+    <el-dialog
+      title="查看当前权限"
+      :visible.sync="dialogCheckPowers"
+      width="30%"
+      center
+    >
+      <el-form>
+        <el-form-item label="已绑定权限:" class="switch-button-item">
+          <span>
+            <el-tag
+              class="groupclass"
+              v-for="item in deviceWithPowerList"
+              :key="item.idGroup"
+            >
+              {{ item.identityName }}
+            </el-tag>
+          </span>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+
+    <!-- 添加权限弹窗区域 -->
+
+    <el-dialog
+      title="添加权限"
+      :visible.sync="dialogBindPower"
+      width="30%"
+      center
+    >
+      <el-form ref="dataForm" :model="temp" :rules="rules">
+        <el-form-item
+          style="white-space: pre"
+          label="选择身份:"
+          class="switch-button-item"
+          prop="groups"
+        >
+          <el-col :span="12">
+            <el-select v-model="temp.groups" multiple placeholder="请选择">
+              <el-option
+                v-for="item in groupList"
+                :key="item.idIdentity"
+                :label="item.identityName"
+                :value="item.idIdentity"
+              >
+              </el-option>
+            </el-select>
+          </el-col>
+        </el-form-item>
+      </el-form>
+
+      <span slot="footer">
+        <el-button type="primary" @click="updateData()">确 定</el-button>
+        <el-button @click="dialogBindPower = false">取 消</el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 删除权限弹窗区域 -->
+    <el-dialog
+      title="解绑权限"
+      :visible.sync="dialogUnbindPower"
+      width="30%"
+      center
+    >
+      <el-table :data="deviceWithPowerList">
+        <el-table-column label="身份类型" align="center">
+          <template slot-scope="{ row }">
+            <span>{{ row.identityName }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="操作" width="340px" align="center">
+          <template slot-scope="{ row, $index }">
+            <el-button
+              type="text"
+              size="small"
+              @click="deletePower(row, $index)"
+              >删除</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import Pagination from "@/components/Pagination";
+import {
+  fetchList,
+  bindPowers,
+  searchList,
+  deletePowers,
+  checkPowers,
+} from "@/api/deviceWithStatus";
+export default {
+  components: {
+    Pagination,
+  },
+  data() {
+    return {
+      list: [],
+      groupList: [
+        // { id: 1, value: "学生", label: "学生" },
+        // { id: 2, value: "老师", label: "老师" },
+        // { id: 3, value: "家长", label: "家长" },
+        // { id: 4, value: "临时人员", label: "临时人员" },
+        { idIdentity: 0, identityName: "其它" },
+        { idIdentity: 1, identityName: "学生" },
+        { idIdentity: 4, identityName: "教职工" },
+        { idIdentity: 7, identityName: "临时人员" },
+      ],
+      deviceWithPowerList: [],
+      temp: {
+        serialNumber: "",
+        name: "",
+        groups: [],
+        identities: "",
+      },
+      total: 0, //数据的总数//
+      listQuery: {
+        page: 1, //当前在第几页//
+        limit: 100, //一页几条//
+        name: "",
+      },
+      dialogBindPower: false,
+      dialogUnbindPower: false,
+      dialogCheckPowers: false,
+      rules: {
+        groups: [
+          {
+            required: true,
+            message: "请选择分组",
+            trigger: "change",
+          },
+        ],
+      },
+    };
+  },
+  created() {
+    this.getList();
+    // this.getgroupList();
+  },
+  methods: {
+    getList() {
+      fetchList(this.listQuery).then((response) => {
+        this.list = response.data;
+        this.total = response.total;
+      });
+    },
+    // getgroupList() {
+    //   fetchGroupList({ page: this.listQuery.page, limit: "999" }).then(
+    //     (response) => {
+    //       this.groupList = response.data;
+    //     }
+    //   );
+    // },
+    checkPower(row) {
+      this.temp = Object.assign({}, row);
+      checkPowers({ deviceId: row.idDevice }).then((response) => {
+        this.deviceWithPowerList = response.data;
+      });
+      this.dialogCheckPowers = true;
+    },
+    bindPower(row) {
+      this.temp = Object.assign({}, row);
+      this.dialogBindPower = true;
+      this.$nextTick(() => {
+        this.$refs["dataForm"].clearValidate();
+      });
+    },
+    updateData() {
+      this.$refs["dataForm"].validate((valid) => {
+        if (valid) {
+          const tempData = Object.assign({}, this.temp);
+          bindPowers({
+            id: tempData.idDevice,
+            serialNumber: tempData.serialNumber,
+            identities: tempData.groups,
+          }).then(() => {
+            this.dialogBindPower = false;
+            this.$notify({
+              title: "添加权限成功",
+              type: "success",
+              duration: 1500,
+            });
+          });
+        }
+      });
+    },
+    unbindPower(row) {
+      this.temp = Object.assign({}, row);
+      checkPowers({ deviceId: row.idDevice }).then((response) => {
+        this.deviceWithPowerList = response.data;
+      });
+      this.dialogUnbindPower = true;
+    },
+    deletePower(row, index) {
+      if (confirm("确定删除权限吗?")) {
+        deletePowers({
+          id: this.temp.idDevice,
+          serialNumber: this.temp.serialNumber,
+          identities: [row.idIdentity],
+        }).then(() => {
+          this.$notify({
+            title: "删除权限成功",
+            type: "success",
+            duration: 1500,
+          });
+          this.deviceWithPowerList.splice(index, 1);
+        });
+      }
+    },
+    handleFilter() {
+      if (!this.listQuery.name) {
+        alert("请输入设备名称");
+      } else {
+        searchList({ name: this.listQuery.name }).then((response) => {
+          this.list = response.data;
+          this.total = response.total;
+        });
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.body {
+  width: 1551px;
+  margin: 29px 29px 0 31px;
+  .head {
+    display: flex;
+    width: 1380px;
+    height: 55px;
+    margin-left: 40px;
+    border-bottom: 1px solid #cccccc;
+
+    .head-img {
+      width: 30px;
+      height: 30px;
+
+      img {
+        width: 30px;
+      }
+    }
+
+    .head-info {
+      height: 22px;
+      margin-top: 5px;
+      margin-left: 16px;
+      font-weight: bold;
+    }
+    .input {
+      width: 240px;
+      margin-left: 21px;
+    }
+
+    .input-serch {
+      margin-left: 32px;
+    }
+  }
+
+  .form {
+    margin-left: 40px;
+    width: 1380px;
+
+    .block {
+      float: right;
+    }
+  }
+  .switch-button-item {
+    margin-left: 120px;
+    .groupclass {
+      float: left;
+      margin-right: 10px;
+      margin-bottom: 10px;
+    }
+  }
+}
+</style>

+ 357 - 0
src/views/devicewithGroup/index.vue

@@ -0,0 +1,357 @@
+<template>
+  <div class="body">
+    <!-- 头部区域 -->
+
+    <div class="head">
+      <div class="head-img">
+        <img src="../../../public/images/img-1.png" />
+      </div>
+      <div class="head-info">设备与组绑定</div>
+      <div class="input">
+        <el-input
+          v-model="listQuery.name"
+          size="small"
+          placeholder="请输入设备名称"
+          clearable
+          @clear="getList"
+          @keyup.enter.native="handleFilter"
+        >
+        </el-input>
+      </div>
+
+      <div class="input-serch">
+        <el-row>
+          <el-button size="small" type="primary" @click="handleFilter"
+            >搜索</el-button
+          >
+        </el-row>
+      </div>
+    </div>
+
+    <!-- 表格区域 -->
+    <div class="form">
+      <el-table :data="list">
+        <el-table-column label="序列号" align="center" width="440px">
+          <template slot-scope="{ row }">
+            <span>{{ row.serialNumber }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="名称" align="center" width="440px">
+          <template slot-scope="{ row }">
+            <span>{{ row.deviceName }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="操作" width="440px" align="center">
+          <template slot-scope="{ row }">
+            <el-button type="text" size="small" @click="checkGroup(row)"
+              >查看当前分组</el-button
+            >
+            <el-button type="text" size="small" @click="bindGroup(row)"
+              >绑定分组</el-button
+            >
+            <el-button type="text" size="small" @click="unbindGroup(row)"
+              >解绑分组</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 底部分页区 -->
+
+      <div class="block">
+        <template>
+          <pagination
+            :total="total"
+            :page.sync="listQuery.page"
+            :limit.sync="listQuery.limit"
+            @pagination="getList"
+          />
+        </template>
+      </div>
+    </div>
+
+    <!-- 查看分组弹窗区域 -->
+    <el-dialog
+      title="查看当前分组"
+      :visible.sync="dialogCheckGroups"
+      width="30%"
+      center
+    >
+      <el-form>
+        <el-form-item label="已绑定分组:" class="switch-button-item">
+          <span>
+            <el-tag
+              class="groupclass"
+              v-for="item in groupWithDeviceList"
+              :key="item.idGroup"
+            >
+              {{ item.groupName }}
+            </el-tag>
+          </span>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+
+    <!-- 绑定分组弹窗区域 -->
+
+    <el-dialog
+      title="绑定分组"
+      :visible.sync="dialogBindGroup"
+      width="30%"
+      center
+    >
+      <el-form ref="dataForm" :model="temp" :rules="rules">
+        <el-form-item
+          style="white-space: pre"
+          label="选择分组:"
+          class="switch-button-item"
+          prop="groups"
+        >
+          <el-col :span="12">
+            <el-select
+              v-model="temp.groups"
+              filterable
+              multiple
+              value-key="id"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in groupList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
+          </el-col>
+        </el-form-item>
+      </el-form>
+
+      <span slot="footer">
+        <el-button type="primary" @click="updateData()">确 定</el-button>
+        <el-button @click="dialogBindGroup = false">取 消</el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 解绑分组弹窗区域 -->
+    <el-dialog
+      title="解绑分组"
+      :visible.sync="dialogUnbindGroup"
+      width="30%"
+      center
+    >
+      <el-table :data="groupWithDeviceList">
+        <el-table-column label="分组" align="center">
+          <template slot-scope="{ row }">
+            <span>{{ row.groupName }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="操作" width="340px" align="center">
+          <template slot-scope="{ row, $index }">
+            <el-button
+              type="text"
+              size="small"
+              @click="deleteGroup(row, $index)"
+              >解绑</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import Pagination from "@/components/Pagination";
+import {
+  fetchList,
+  fetchGroupList,
+  bindGroups,
+  searchList,
+  deleteGroups,
+  checkGroups,
+} from "@/api/devicewithgroup";
+export default {
+  components: {
+    Pagination,
+  },
+  data() {
+    return {
+      list: [],
+      groupList: [],
+      groupWithDeviceList: [],
+      temp: {
+        serialNumber: "",
+        deviceName: "",
+        groups: [],
+        groupIds: [],
+      },
+      total: 0, //数据的总数//
+      listQuery: {
+        page: 1, //当前在第几页//
+        limit: 100, //一页几条//
+        name: "",
+      },
+      dialogBindGroup: false,
+      dialogUnbindGroup: false,
+      dialogCheckGroups: false,
+      rules: {
+        groups: [
+          {
+            required: true,
+            message: "请选择分组",
+            trigger: "change",
+          },
+        ],
+      },
+    };
+  },
+  created() {
+    this.getList();
+    this.getgroupList();
+  },
+  methods: {
+    getList() {
+      fetchList({
+        page: this.listQuery.page,
+        limit: this.listQuery.limit,
+      }).then((response) => {
+        this.list = response.data;
+        this.total = response.total;
+      });
+    },
+    getgroupList() {
+      fetchGroupList({ page: this.listQuery.page, limit: "999" }).then(
+        (response) => {
+          this.groupList = response.data;
+        }
+      );
+    },
+    checkGroup(row) {
+      this.temp = Object.assign({}, row);
+      checkGroups({ deviceId: row.idDevice }).then((response) => {
+        this.groupWithDeviceList = response.data;
+      });
+      this.dialogCheckGroups = true;
+    },
+    bindGroup(row) {
+      this.temp = Object.assign({}, row);
+      this.dialogBindGroup = true;
+      this.$nextTick(() => {
+        this.$refs["dataForm"].clearValidate();
+      });
+    },
+    updateData() {
+      this.$refs["dataForm"].validate((valid) => {
+        if (valid) {
+          const tempData = Object.assign({}, this.temp);
+          bindGroups({
+            id: tempData.idDevice,
+            serialNumber: tempData.serialNumber,
+            groups: tempData.groups,
+          }).then(() => {
+            this.dialogBindGroup = false;
+            this.$notify({
+              title: "绑定分组成功",
+              type: "success",
+              duration: 1500,
+            });
+          });
+        }
+      });
+    },
+    unbindGroup(row) {
+      this.temp = Object.assign({}, row);
+      checkGroups({ deviceId: row.idDevice }).then((response) => {
+        this.groupWithDeviceList = response.data;
+      });
+      this.dialogUnbindGroup = true;
+    },
+    deleteGroup(row, index) {
+      console.log(row, index);
+      if (confirm("确定解绑吗?")) {
+        deleteGroups({
+          id: this.temp.idDevice,
+          serialNumber: this.temp.serialNumber,
+          groups: [row.idGroup],
+        }).then(() => {
+          this.$notify({
+            title: "解绑成功",
+            type: "success",
+            duration: 1500,
+          });
+          this.groupWithDeviceList.splice(index, 1);
+        });
+      }
+    },
+    handleFilter() {
+      if (!this.listQuery.name) {
+        alert("请输入设备名称");
+      } else {
+        searchList({ name: this.listQuery.name }).then((response) => {
+          this.list = response.data;
+          this.total = response.total;
+        });
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.body {
+  width: 1551px;
+  margin: 29px 29px 0 31px;
+  .head {
+    display: flex;
+    width: 1380px;
+    height: 55px;
+    margin-left: 40px;
+    border-bottom: 1px solid #cccccc;
+
+    .head-img {
+      width: 30px;
+      height: 30px;
+
+      img {
+        width: 30px;
+      }
+    }
+
+    .head-info {
+      height: 22px;
+      margin-top: 5px;
+      margin-left: 16px;
+      font-weight: bold;
+    }
+    .input {
+      width: 240px;
+      margin-left: 21px;
+    }
+
+    .input-serch {
+      margin-left: 32px;
+    }
+  }
+
+  .form {
+    margin-left: 40px;
+    width: 1380px;
+
+    .block {
+      float: right;
+    }
+  }
+  .switch-button-item {
+    margin-left: 120px;
+    .groupclass {
+      float: left;
+      margin-right: 10px;
+      margin-bottom: 10px;
+    }
+  }
+}
+</style>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 429 - 568
src/views/groupManagement/index.vue


+ 0 - 53
src/views/groupManagement/steps.js

@@ -1,53 +0,0 @@
-const steps = [
-  {
-    element: '#hamburger-container',
-    popover: {
-      title: 'Hamburger',
-      description: 'Open && Close sidebar',
-      position: 'bottom'
-    }
-  },
-  {
-    element: '#breadcrumb-container',
-    popover: {
-      title: 'Breadcrumb',
-      description: 'Indicate the current page location',
-      position: 'bottom'
-    }
-  },
-  {
-    element: '#header-search',
-    popover: {
-      title: 'Page Search',
-      description: 'Page search, quick navigation',
-      position: 'left'
-    }
-  },
-  {
-    element: '#screenfull',
-    popover: {
-      title: 'Screenfull',
-      description: 'Set the page into fullscreen',
-      position: 'left'
-    }
-  },
-  {
-    element: '#size-select',
-    popover: {
-      title: 'Switch Size',
-      description: 'Switch the system size',
-      position: 'left'
-    }
-  },
-  {
-    element: '#tags-view-container',
-    popover: {
-      title: 'Tags view',
-      description: 'The history of the page you visited',
-      position: 'bottom'
-    },
-    padding: 0
-  }
-]
-
-export default steps

+ 147 - 157
src/views/index/index.vue

@@ -1,221 +1,211 @@
 <template>
   <div class="body">
-
     <div class="head">
       <div class="head-img">
-        <img src="../../../public/images/index-1.png">
-      </div>
-      <div class="head-info">
-        首页
+        <img src="../../../public/images/index-1.png" />
       </div>
+      <div class="head-info">首页</div>
     </div>
 
     <div class="user">
       条件:
       <div class="input">
         <el-select v-model="value" size="mini" placeholder="请选择楼栋">
-          <el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.name">
+          <el-option
+            v-for="item in list"
+            :key="item.id"
+            :label="item.deviceName"
+            :value="item.deviceName"
+          >
           </el-option>
         </el-select>
       </div>
 
       <div class="input-button">
         <el-row>
-          <el-button size="small" type="primary" @click="getGroupIdList">确定</el-button>
+          <el-button size="small" type="primary" @click="handleFilter"
+            >确定</el-button
+          >
         </el-row>
       </div>
-
     </div>
 
-    <div class="title">
-      今日统计
-    </div>
+    <div class="title">今日统计</div>
 
     <div class="add">
       <div class="add-title">累计通行(次)</div>
       <div class="add-img">
-        <img src="../../../public/images/index-2.png">
+        <img src="../../../public/images/index-2.png" />
       </div>
-      <div class="add-num">1458</div>
+      <div class="add-num">{{ total }}</div>
     </div>
 
-    <div class="title-1">
-      设备统计
-    </div>
+    <div class="title-1">设备统计</div>
 
-    <div class="title-2">
-      通行人数
-    </div>
+    <div class="title-2">通行人数</div>
 
     <div class="chart-container">
-      <chart height="100%" width="100%" />
+      <chart height="100%" width="80%" :total="total" />
     </div>
-
   </div>
 </template>
 
 <script>
-  import Chart from "@/components/Charts/MixChart";
-  import {
-    fetchList,
-    fetchGroupIdList,
-    // fetchPv,
-    // createDevice,
-    // updateArticle
-  } from "@/api/index";
-  export default {
-    components: {
-      Chart,
-      name: "MixChart"
-    },
-    data() {
-      return {
-        // options: [{
-        //   value: '选项1',
-        //   label: '一栋'
-        // }, {
-        //   value: '选项2',
-        //   label: '二栋'
-        // }],
-        list: [],
-        groupidlist: [],
-        listQuery: [],
-        groupidlistQuery: 1,
-        value: '一栋'
-      }
+import Chart from "@/components/Charts/MixChart";
+import { fetchList, searchList } from "@/api/index";
+export default {
+  components: {
+    Chart,
+    name: "MixChart",
+  },
+  data() {
+    return {
+      list: [],
+      total: 0, //数据的总数//
+      listQuery: {
+        page: 1,
+        limit: 8,
+        cardNumber: "",
+        deviceName: "",
+        groupName: "",
+        identityName: "",
+        message: "",
+        time: "",
+        userName: "",
+      },
+      value: "",
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    getList() {
+      fetchList(this.listQuery).then((response) => {
+        this.list = response.data;
+        this.total = response.total;
+      });
     },
-    created() {
-      this.getList();
-      this.getGroupIdList();
+    handleFilter() {
+      searchList({ deviceName: this.listQuery.deviceName }).then((response) => {
+        this.list = response.data;
+        this.total = response.total;
+      });
     },
-    methods:{
-      getList() {
-        fetchList(this.listQuery).then((response) => {
-          this.list = response.data;
-        });
-      },
-      getGroupIdList() {
-        // this.groupidlistQuery = key;
-        fetchGroupIdList({
-          idGroup: this.groupidlistQuery
-        }).then((response) => {
-          this.groupidlist = response.data;
-        });
-      },
-    }
-  }
+  },
+};
 </script>
 
 <style lang="scss" scoped>
-  .body {
-    width: 1551px;
-    margin: 29px 29px 0 31px;
-
-    .head {
-      display: flex;
-      width: 1380px;
-      height: 55px;
-      margin-left: 40px;
-      border-bottom: 1px solid #CCCCCC;
-
-      .head-img {
+.body {
+  width: 1551px;
+  margin: 29px 29px 0 31px;
+
+  .head {
+    display: flex;
+    width: 1380px;
+    height: 55px;
+    margin-left: 40px;
+    border-bottom: 1px solid #cccccc;
+
+    .head-img {
+      width: 30px;
+      height: 30px;
+
+      img {
         width: 30px;
-        height: 30px;
-
-        img {
-          width: 30px;
-        }
       }
+    }
 
-      .head-info {
-        width: 95px;
-        height: 22px;
-        margin-top: 5px;
-        margin-left: 16px;
-        font-weight: bold;
-      }
+    .head-info {
+      width: 95px;
+      height: 22px;
+      margin-top: 5px;
+      margin-left: 16px;
+      font-weight: bold;
     }
+  }
 
-    .user {
-      display: flex;
-      width: 1380px;
-      line-height: 112px;
-      margin-left: 40px;
-      font-size: 9px;
+  .user {
+    display: flex;
+    width: 1380px;
+    line-height: 112px;
+    margin-left: 40px;
+    font-size: 9px;
 
-      .input {
-        width: 240px;
-        margin-left: 11px;
-      }
+    .input {
+      width: 240px;
+      margin-left: 11px;
+    }
 
-      .input-button {
-        margin-left: 39px;
-      }
+    .input-button {
+      margin-left: 39px;
     }
+  }
 
-    .title {
-      width: 300px;
-      height: 40px;
-      margin-left: 40px;
+  .title {
+    width: 300px;
+    height: 40px;
+    margin-left: 40px;
+    font-weight: bold;
+  }
+
+  .add {
+    position: relative;
+    width: 300px;
+    height: 120px;
+    margin-left: 40px;
+    border-radius: 10px;
+    color: #fff;
+    background-color: #2b95f8;
+
+    .add-title {
+      width: 106px;
+      line-height: 49px;
+      font-size: 8px;
       font-weight: bold;
+      margin-left: 27px;
+      border-bottom: 1px solid #fff;
     }
 
-    .add {
-      position: relative;
-      width: 300px;
-      height: 120px;
-      margin-left: 40px;
-      border-radius: 10px;
-      color: #fff;
-      background-color: #2B95F8;
-
-      .add-title {
-        width: 106px;
-        line-height: 49px;
-        font-size: 8px;
-        font-weight: bold;
-        margin-left: 27px;
-        border-bottom: 1px solid #fff;
-      }
+    .add-img {
+      position: absolute;
+      top: 41px;
+      right: 40px;
+      width: 46px;
+      height: 39px;
 
-      .add-img {
-        position: absolute;
-        top: 41px;
-        right: 40px;
+      img {
         width: 46px;
-        height: 39px;
-
-        img {
-          width: 46px;
-        }
-      }
-
-      .add-num {
-        height: 27px;
-        margin-left: 27px;
-        margin-top: 22px;
-        font-size: 18px;
-        font-weight: bold;
       }
     }
 
-    .title-1 {
-      width: 300px;
-      height: 40px;
-      margin-left: 40px;
-      margin-top: 37px;
+    .add-num {
+      height: 27px;
+      margin-left: 27px;
+      margin-top: 22px;
+      font-size: 18px;
       font-weight: bold;
     }
+  }
 
-    .title-2 {
-      margin-left: 46px;
-      font-size: 15px;
-    }
+  .title-1 {
+    width: 300px;
+    height: 40px;
+    margin-left: 40px;
+    margin-top: 37px;
+    font-weight: bold;
+  }
 
-    .chart-container {
-      width: 1300px;
-      height: calc(100vh - 500px);
-      margin-left: 46px;
-    }
+  .title-2 {
+    margin-left: 46px;
+    font-size: 15px;
+  }
+
+  .chart-container {
+    width: 1300px;
+    height: calc(100vh - 500px);
+    margin-left: 46px;
   }
+}
 </style>

+ 32 - 28
src/views/login/index.vue

@@ -20,34 +20,38 @@
           :rules="rules"
           autocomplete="on"
         >
-          <el-form-item class="login-form-item" prop="username">
-            <span><img src="../../../public/images/denglu.png" /></span>
-            <el-input
-              class="login-form-input"
-              v-model="loginForm.username"
-              ref="username"
-              name="username"
-              placeholder="请输入您的账号"
-            ></el-input>
-          </el-form-item>
+          <label>
+            <el-form-item class="login-form-item" prop="username">
+              <span><img src="../../../public/images/denglu.png" /></span>
 
-          <el-form-item class="login-form-item" prop="password">
-            <span><img src="../../../public/images/mima.png" /></span>
-            <el-input
-              class="login-form-input"
-              type="password"
-              v-model="loginForm.password"
-              placeholder="请输入您的密码"
-              ref="password"
-              name="password"
-              autocomplete="on"
-              @keyup.native="checkCapslock"
-              @blur="capsTooltip = false"
-              @keyup.enter.native="handleLogin"
-            >
-            </el-input>
-          </el-form-item>
+              <el-input
+                class="login-form-input"
+                v-model="loginForm.username"
+                ref="username"
+                name="username"
+                placeholder="请输入您的账号"
+              ></el-input>
+            </el-form-item>
+          </label>
+          <label>
+            <el-form-item class="login-form-item" prop="password">
+              <span><img src="../../../public/images/mima.png" /></span>
 
+              <el-input
+                class="login-form-input"
+                type="password"
+                v-model="loginForm.password"
+                placeholder="请输入您的密码"
+                ref="password"
+                name="password"
+                autocomplete="on"
+                @keyup.native="checkCapslock"
+                @blur="capsTooltip = false"
+                @keyup.enter.native="handleLogin"
+              >
+              </el-input>
+            </el-form-item>
+          </label>
           <el-form-item>
             <el-button
               :loading="loading"
@@ -87,8 +91,8 @@ export default {
     };
     return {
       loginForm: {
-        username: "admin",
-        password: "123abc",
+        username: "",
+        password: "",
       },
       rules: {
         username: [

+ 11 - 0
src/views/management/index.vue

@@ -0,0 +1,11 @@
+<template>
+  <div>
+    大门管理
+  </div>
+</template>
+
+<script>
+</script>
+
+<style>
+</style>

+ 0 - 120
src/views/theme/index.vue

@@ -1,120 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-card class="box-card">
-      <div slot="header">
-        <a class="link-type link-title" target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/guide/advanced/theme.html">
-          Theme documentation
-        </a>
-      </div>
-      <div class="box-item">
-        <span class="field-label">Change Theme : </span>
-        <el-switch v-model="theme" />
-        <aside style="margin-top:15px;">
-          Tips: It is different from the theme-pick on the navbar is two different skinning methods, each with different application scenarios. Refer to the documentation for details.
-        </aside>
-      </div>
-    </el-card>
-
-    <div class="block">
-      <el-button type="primary">
-        Primary
-      </el-button>
-      <el-button type="success">
-        Success
-      </el-button>
-      <el-button type="info">
-        Info
-      </el-button>
-      <el-button type="warning">
-        Warning
-      </el-button>
-      <el-button type="danger">
-        Danger
-      </el-button>
-    </div>
-
-    <div class="block">
-      <el-button type="primary" icon="el-icon-edit" />
-      <el-button type="primary" icon="el-icon-share" />
-      <el-button type="primary" icon="el-icon-delete" />
-      <el-button type="primary" icon="el-icon-search">
-        Search
-      </el-button>
-      <el-button type="primary">
-        Upload
-        <i class="el-icon-upload el-icon-right" />
-      </el-button>
-    </div>
-
-    <div class="block">
-      <el-tag v-for="tag in tags" :key="tag.type" :type="tag.type" class="tag-item">
-        {{ tag.name }}
-      </el-tag>
-    </div>
-
-    <div class="block">
-      <el-radio-group v-model="radio">
-        <el-radio :label="3">
-          Option A
-        </el-radio>
-        <el-radio :label="6">
-          Option B
-        </el-radio>
-        <el-radio :label="9">
-          Option C
-        </el-radio>
-      </el-radio-group>
-    </div>
-
-    <div class="block">
-      <el-slider v-model="slideValue" />
-    </div>
-  </div>
-</template>
-
-<script>
-import { toggleClass } from '@/utils'
-import '@/assets/custom-theme/index.css' // the theme changed version element-ui css
-
-export default {
-  name: 'Theme',
-  data() {
-    return {
-      theme: false,
-      tags: [
-        { name: 'Tag One', type: '' },
-        { name: 'Tag Two', type: 'info' },
-        { name: 'Tag Three', type: 'success' },
-        { name: 'Tag Four', type: 'warning' },
-        { name: 'Tag Five', type: 'danger' }
-      ],
-      slideValue: 50,
-      radio: 3
-    }
-  },
-  watch: {
-    theme() {
-      toggleClass(document.body, 'custom-theme')
-    }
-  }
-}
-</script>
-
-<style scoped>
-.field-label{
-  vertical-align: middle;
-}
-.box-card {
-  width: 400px;
-  max-width: 100%;
-  margin: 20px auto;
-}
-
-.block {
-  padding: 30px 24px;
-}
-
-.tag-item {
-  margin-right: 15px;
-}
-</style>

+ 320 - 318
src/views/user/index.vue

@@ -1,7 +1,6 @@
 <template>
   <div class="body">
-    <!-- 头部区域开始 -->
-
+    <!-- 头部区域 -->
     <div class="head">
       <div class="head-img">
         <img src="../../../public/images/user-1.png" />
@@ -9,71 +8,41 @@
       <div class="head-info">账号管理</div>
     </div>
 
-    <!-- 头部区域结束 -->
-
-    <!-- 搜索添加区域开始 -->
-
+    <!-- 搜索添加区域 -->
     <div class="user">
       条件:
       <div class="input">
-        <el-input v-model="listQuery.name" size="small" placeholder="请输入账号 " clearable @clear="getList" @keyup.enter.native="handleFilter">
+        <el-input
+          v-model="listQuery.name"
+          size="small"
+          placeholder="请输入账号 "
+          clearable
+          @clear="getList"
+          @keyup.enter.native="handleFilter"
+        >
         </el-input>
       </div>
 
       <div class="input-serch">
         <el-row>
-          <el-button size="small" type="primary" v-model="listQuery.sort" @click="handleFilter">搜索</el-button>
+          <el-button size="small" type="primary" @click="handleFilter"
+            >搜索</el-button
+          >
         </el-row>
       </div>
 
       <div class="input-add">
         <el-row>
-          <el-button type="primary" size="small" @click="handleCreate"><img src="../../../public/images/img-3.png" />添加
+          <el-button type="primary" size="small" @click="handleCreate"
+            ><img src="../../../public/images/img-3.png" />添加
           </el-button>
-
-          <!-- 添加弹窗区域开始 -->
-
-          <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="40%" center>
-            <el-form ref="dataForm" :model="temp" :rules="rules">
-              <el-form-item style="white-space: pre" label="账号:" class="switch-button-item" prop="name">
-                <el-col :span="12">
-                  <el-input v-model="temp.name" autocomplete="off" placeholder="请输入账号" style="width: 110%">
-                  </el-input>
-                </el-col>
-              </el-form-item>
-
-              <el-form-item style="white-space: pre" label="昵称:" class="switch-button-item" prop="nickname">
-                <el-col :span="12">
-                  <el-input v-model="temp.nickname" autocomplete="off" placeholder="请输入昵称" style="width: 110%">
-                  </el-input>
-                </el-col>
-              </el-form-item>
-
-              <el-form-item style="white-space: pre" label="密码:" class="switch-button-item" prop="password">
-                <el-col :span="12">
-                  <el-input v-model="temp.password" autocomplete="off" type="password" placeholder="请输入密码" style="width: 110%">
-                  </el-input>
-                </el-col>
-              </el-form-item>
-            </el-form>
-            <span slot="footer">
-              <el-button type="primary" @click="dialogStatus === 'create' ? createData() : updateData()">确 定</el-button>
-              <el-button @click="dialogFormVisible = false">取 消</el-button>
-            </span>
-          </el-dialog>
-
-          <!-- 添加弹窗区域结束 -->
         </el-row>
       </div>
     </div>
 
-    <!-- 搜索添加区域结束 -->
-
-    <!-- 表格区域开始 -->
-
+    <!-- 表格区域 -->
     <div class="form">
-      <el-table :data="list" @sort-change="sortChange">
-
+      <el-table :data="list">
         <el-table-column label="账号" align="center">
           <template slot-scope="{ row }">
             <span>{{ row.name }}</span>
@@ -86,336 +55,369 @@
           </template>
         </el-table-column>
 
-        <!-- <el-table-column label="密码" align="center">
-          <template slot-scope="{ row }">
-            <span>{{ row.password }}</span>
-          </template>
-        </el-table-column> -->
-
         <el-table-column label="操作" align="center">
           <template slot-scope="{ row, $index }">
-            <el-button type="text" size="small" @click="handleUpdate(row)">编辑</el-button>
-            <el-button @click="handleDelete(row, $index)" type="text" size="small" class="button"><img
-                src="../../../public/images/img-2.png" />删除</el-button>
+            <el-button type="text" size="small" @click="handleUpdate(row)"
+              >编辑</el-button
+            >
+            <el-button
+              @click="handleDelete(row, $index)"
+              type="text"
+              size="small"
+              class="button"
+              ><img src="../../../public/images/img-2.png" />删除</el-button
+            >
           </template>
         </el-table-column>
       </el-table>
     </div>
 
-    <!-- 表格区域结束 -->
-
-    <!-- 底部分页区开始 -->
-
+    <!-- 底部分页区 -->
     <div class="block">
       <template>
-        <pagination v-show="total > 0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit"
-          @pagination="getList" />
+        <pagination
+          v-show="total > 0"
+          :total="total"
+          :page.sync="listQuery.page"
+          :limit.sync="listQuery.limit"
+          @pagination="getList"
+        />
       </template>
     </div>
 
-    <!-- 底部分页区结束 -->
+    <!-- 添加弹窗区域 -->
+    <el-dialog
+      :title="textMap[dialogStatus]"
+      :visible.sync="dialogFormVisible"
+      width="30%"
+      center
+    >
+      <el-form ref="dataForm" :model="temp" :rules="rules">
+        <el-form-item
+          style="white-space: pre"
+          label="账号:"
+          class="switch-button-item"
+          prop="name"
+        >
+          <el-col :span="12">
+            <el-input
+              v-model="temp.name"
+              autocomplete="off"
+              placeholder="请输入账号"
+              style="width: 110%"
+            >
+            </el-input>
+          </el-col>
+        </el-form-item>
+
+        <el-form-item
+          style="white-space: pre"
+          label="昵称:"
+          class="switch-button-item"
+          prop="nickname"
+        >
+          <el-col :span="12">
+            <el-input
+              v-model="temp.nickname"
+              autocomplete="off"
+              placeholder="请输入昵称"
+              style="width: 110%"
+            >
+            </el-input>
+          </el-col>
+        </el-form-item>
+
+        <el-form-item
+          style="white-space: pre"
+          label="密码:"
+          class="switch-button-item"
+          prop="password"
+        >
+          <el-col :span="12">
+            <el-input
+              v-model="temp.password"
+              autocomplete="off"
+              type="password"
+              placeholder="请输入密码"
+              style="width: 110%"
+            >
+            </el-input>
+          </el-col>
+        </el-form-item>
+      </el-form>
+      <span slot="footer">
+        <el-button
+          type="primary"
+          @click="dialogStatus === 'create' ? createData() : updateData()"
+          >确 定</el-button
+        >
+        <el-button @click="dialogFormVisible = false">取 消</el-button>
+      </span>
+    </el-dialog>
   </div>
 </template>
 
 <script>
-  import Pagination from "@/components/Pagination";
-  import {
-    createAdmin,
-    updateAdmin,
-    deleteAdmin,
-    fetchList,
-    searchList
-    // fetchPv,
-    // fetchAdmin
-  } from "@/api/getuser";
-
-  export default {
-    components: {
-      Pagination,
-    },
-    data() {
-      const validateUsername = (rule, value, callback) => {
-        if (value.length < 5) {
-          callback(new Error("账号至少五位数"));
-        } else {
-          callback();
-        }
-      };
-      const validatePassword = (rule, value, callback) => {
-        if (value.length < 6) {
-          callback(new Error("密码至少六位数"));
-        } else {
-          callback();
-        }
-      };
-      return {
-        list: [],
-        total: 0,
-        listQuery: {
-          page: 1,
-          limit: 8,
-          // importance: undefined,
-          // title: undefined,
-          // type: undefined,
-          // sort: '+id'
-          name: "",
-          nickname: "",
-          password: "",
-        },
-        temp: {
-          id: undefined,
-          name: "",
-          nickname: "",
-          password: "",
-        },
-        timer: null,
-        dialogFormVisible: false,
-        dialogStatus: "",
-        textMap: {
-          update: "编辑",
-          create: "添加",
-        },
-        rules: {
-          name: [{
+import Pagination from "@/components/Pagination";
+import {
+  createAdmin,
+  updateAdmin,
+  deleteAdmin,
+  fetchList,
+  searchList,
+} from "@/api/getuser";
+
+export default {
+  components: {
+    Pagination,
+  },
+  data() {
+    const validateUsername = (rule, value, callback) => {
+      if (value.length < 5) {
+        callback(new Error("账号至少五位数"));
+      } else {
+        callback();
+      }
+    };
+    const validatePassword = (rule, value, callback) => {
+      if (value.length < 6) {
+        callback(new Error("密码至少六位数"));
+      } else {
+        callback();
+      }
+    };
+    return {
+      list: [],
+      total: 0,
+      listQuery: {
+        page: 1,
+        limit: 8,
+        name: "",
+        nickname: "",
+        password: "",
+      },
+      temp: {
+        id: undefined,
+        name: "",
+        nickname: "",
+        password: "",
+      },
+      dialogFormVisible: false,
+      dialogStatus: "",
+      textMap: {
+        update: "编辑账号信息",
+        create: "添加账号",
+      },
+      rules: {
+        name: [
+          {
             required: true,
             message: "账号至少五位数",
             trigger: "change",
-            validator: validateUsername
-          }],
-          nickname: [{
+            validator: validateUsername,
+          },
+        ],
+        nickname: [
+          {
             required: true,
             message: "请输入昵称",
-            trigger: "change"
-          }, ],
-          password: [{
+            trigger: "change",
+          },
+        ],
+        password: [
+          {
             required: true,
             message: "密码至少六位数",
             trigger: "change",
-            validator: validatePassword
-          }, ],
-        },
+            validator: validatePassword,
+          },
+        ],
+      },
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    getList() {
+      fetchList(this.listQuery).then((response) => {
+        this.list = response.data;
+        this.total = response.total;
+      });
+    },
+    handleDelete(row, index) {
+      if (confirm("是否删除?")) {
+        deleteAdmin({ id: row.id }).then(() => {
+          this.$notify({
+            title: "删除成功",
+            type: "success",
+            duration: 2000,
+          });
+          this.list.splice(index, 1);
+        });
+      }
+    },
+    resetTemp() {
+      this.temp = {
+        id: undefined,
+        name: "",
+        nickname: "",
+        password: "",
       };
     },
-    // watch: {
-    //   input() {
-    //     if (this.timer) {
-    //       clearTimeout(this.timer)
-    //     }
-    //     this.timer = setTimeout(() => {
-    //       const result = []
-    //       for (let i in this.list) {
-    //         this.list[i].forEach((value) => {
-    //           if (value.name.indexOf(this.input) > -1 ||
-    //             value.number.indexOf(this.input) > -1) {
-    //             result.push(value)
-    //           }
-    //         })
-    //       }
-    //       this.list = result
-    //     }, 100)
-    //   }
-    // },
-    created() {
-      this.getList();
+    handleCreate() {
+      this.resetTemp();
+      this.dialogStatus = "create";
+      this.dialogFormVisible = true;
+      this.$nextTick(() => {
+        this.$refs["dataForm"].clearValidate();
+      });
     },
-    methods: {
-      handleDelete(row, index) {
-        if (confirm('是否删除?')) {
-          deleteAdmin({id:row.id}).then(() => {
+    createData() {
+      this.$refs["dataForm"].validate((valid) => {
+        if (valid) {
+          createAdmin(this.temp).then(() => {
+            this.list.unshift(this.temp);
+            this.dialogFormVisible = false;
             this.$notify({
-              title: "删除成功",
+              title: "添加成功",
               type: "success",
               duration: 2000,
             });
-            this.list.splice(index, 1);
-            this.total = this.total - 1
           });
         }
-      },
-      resetTemp() {
-        this.temp = {
-          id: undefined,
-          name: "",
-          nickname: "",
-          password: "",
-        };
-      },
-      handleCreate() {
-        this.resetTemp();
-        this.dialogStatus = "create";
-        this.dialogFormVisible = true;
-        this.$nextTick(() => {
-          this.$refs["dataForm"].clearValidate();
-        });
-      },
-      createData() {
-        this.$refs["dataForm"].validate((valid) => {
-          if (valid) {
-            // this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
-            // this.temp.author = 'vue-element-admin'
-            createAdmin(this.temp).then(() => {
-              this.list.unshift(this.temp);
-              this.dialogFormVisible = false;
-              this.$notify({
-                title: "添加成功",
-                type: "success",
-                duration: 2000,
-              });
-              // this.getList();
-            });
-          }
-        });
-      },
-      updateData() {
-        this.$refs["dataForm"].validate((valid) => {
-          if (valid) {
-            const tempData = Object.assign({}, this.temp);
-
-            updateAdmin(tempData).then(() => {
-              const index = this.list.findIndex((v) => v.id === this.temp.id);
-              this.list.splice(index, 1, this.temp);
-              this.dialogFormVisible = false;
-              this.$notify({
-                title: "编辑成功",
-                type: "success",
-                duration: 2000,
-              });
+      });
+    },
+    handleUpdate(row) {
+      this.temp = Object.assign({}, row); // copy obj
+      this.temp.password = "";
+      this.dialogStatus = "update";
+      this.dialogFormVisible = true;
+      this.$nextTick(() => {
+        this.$refs["dataForm"].clearValidate();
+      });
+    },
+    updateData() {
+      this.$refs["dataForm"].validate((valid) => {
+        if (valid) {
+          const tempData = Object.assign({}, this.temp);
+
+          updateAdmin(tempData).then(() => {
+            const index = this.list.findIndex((v) => v.id === this.temp.id);
+            this.list.splice(index, 1, this.temp);
+            this.dialogFormVisible = false;
+            this.$notify({
+              title: "编辑成功",
+              type: "success",
+              duration: 2000,
             });
-          }
-        });
-      },
-      handleUpdate(row) {
-        this.temp = Object.assign({}, row); // copy obj
-        this.temp.password = "";
-        this.dialogStatus = "update";
-        this.dialogFormVisible = true;
-        this.$nextTick(() => {
-          this.$refs["dataForm"].clearValidate();
-        });
-      },
-      handleFilter() {
-        searchList({name:this.listQuery.name}).then((response) => {
-          this.list = response.data;
-          this.total = response.total;
-        });
-      },
-      getList() {
-        fetchList(this.listQuery).then((response) => {
+          });
+        }
+      });
+    },
+    handleFilter() {
+      if (!this.listQuery.name) {
+        alert("请输入账号");
+      } else {
+        searchList({ name: this.listQuery.name }).then((response) => {
           this.list = response.data;
           this.total = response.total;
         });
-      },
-      sortChange(data) {
-        const {
-          prop,
-          order
-        } = data;
-        if (prop === "id") {
-          this.sortByID(order);
-        }
-      },
-      sortByID(order) {
-        if (order === "ascending") {
-          this.listQuery.sort = "+id";
-        } else {
-          this.listQuery.sort = "-id";
-        }
-        this.handleFilter();
-      },
+      }
     },
-  };
+  },
+};
 </script>
 
 <style lang="scss" scoped>
-  .body {
-    position: relative;
-    width: 1551px;
-    margin: 29px 29px 0 31px;
+.body {
+  position: relative;
+  width: 1551px;
+  margin: 29px 29px 0 31px;
+
+  .head {
+    display: flex;
+    width: 1380px;
+    height: 55px;
+    margin-left: 40px;
+    border-bottom: 1px solid #cccccc;
+
+    .head-img {
+      width: 30px;
+      height: 30px;
 
-    .head {
-      display: flex;
-      width: 1380px;
-      height: 55px;
-      margin-left: 40px;
-      border-bottom: 1px solid #cccccc;
-
-      .head-img {
+      img {
         width: 30px;
-        height: 30px;
-
-        img {
-          width: 30px;
-        }
-      }
-
-      .head-info {
-        width: 95px;
-        height: 22px;
-        margin-top: 5px;
-        margin-left: 16px;
-        font-weight: bold;
       }
     }
 
-    .user {
-      display: flex;
-      width: 1380px;
-      line-height: 110px;
-      margin-left: 40px;
-      font-size: 9px;
+    .head-info {
+      width: 95px;
+      height: 22px;
+      margin-top: 5px;
+      margin-left: 16px;
+      font-weight: bold;
+    }
+  }
 
-      .input {
-        width: 240px;
-        margin-left: 21px;
-      }
+  .user {
+    display: flex;
+    width: 1380px;
+    line-height: 110px;
+    margin-left: 40px;
+    font-size: 9px;
 
-      .input-serch {
-        margin-left: 32px;
-      }
+    .input {
+      width: 240px;
+      margin-left: 21px;
+    }
 
-      .input-add {
-        margin-left: 915px;
+    .input-serch {
+      margin-left: 32px;
+    }
 
-        .switch-button-item {
-          margin-left: 100px;
-          margin-bottom: 50px;
-        }
+    .input-add {
+      margin-left: 915px;
 
-        img {
-          width: 10.5px;
-          margin-right: 10px;
-        }
+      img {
+        width: 10.5px;
+        margin-right: 10px;
       }
     }
+  }
 
-    .form {
-      margin-left: 40px;
-      width: 1380px;
+  .form {
+    margin-left: 40px;
+    width: 1380px;
 
-      .button-img {
-        img {
-          width: 53.5px;
-        }
-      }
-
-      .button-info {
-        margin-top: 39px;
+    .button-img {
+      img {
+        width: 53.5px;
       }
+    }
 
-      .button {
-        color: red;
-      }
+    .button-info {
+      margin-top: 39px;
+    }
 
-      img {
-        width: 8.5px;
-        margin-right: 8px;
-      }
+    .button {
+      color: red;
     }
 
-    .block {
-      display: flex;
-      margin-bottom: 50px;
-      margin-left: 500px;
+    img {
+      width: 8.5px;
+      margin-right: 8px;
     }
   }
+
+  .block {
+    display: flex;
+    margin-bottom: 50px;
+    margin-left: 500px;
+  }
+  .switch-button-item {
+    margin-left: 100px;
+    margin-top: 30px;
+  }
+}
 </style>

+ 353 - 0
src/views/userWithGroup/index.vue

@@ -0,0 +1,353 @@
+<template>
+  <div class="body">
+    <!-- 头部区域 -->
+
+    <div class="head">
+      <div class="head-img">
+        <img src="../../../public/images/img-1.png" />
+      </div>
+      <div class="head-info">人员与组绑定</div>
+      <div class="input">
+        <el-input
+          v-model="listQuery.name"
+          size="small"
+          placeholder="请输入姓名"
+          clearable
+          @clear="getUserList"
+          @keyup.enter.native="handleFilter"
+        >
+        </el-input>
+      </div>
+
+      <div class="input-serch">
+        <el-row>
+          <el-button size="small" type="primary" @click="handleFilter"
+            >搜索</el-button
+          >
+        </el-row>
+      </div>
+    </div>
+
+    <!-- 表格区域 -->
+    <div class="form">
+      <el-table :data="list">
+        <el-table-column label="姓名" align="center" width="440px">
+          <template slot-scope="{ row }">
+            <span>{{ row.userName }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="身份证号码" align="center" width="440px">
+          <template slot-scope="{ row }">
+            <span>{{ row.cardNumber }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="操作" width="440px" align="center">
+          <template slot-scope="{ row }">
+            <el-button type="text" size="small" @click="checkGroup(row)"
+              >查看当前分组</el-button
+            >
+            <el-button type="text" size="small" @click="bindGroup(row)"
+              >绑定分组</el-button
+            >
+            <el-button type="text" size="small" @click="unbindGroup(row)"
+              >解绑分组</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 底部分页区 -->
+
+      <div class="block">
+        <template>
+          <pagination
+            :total="total"
+            :page.sync="listQuery.page"
+            :limit.sync="listQuery.limit"
+            @pagination="getUserList"
+          />
+        </template>
+      </div>
+    </div>
+
+    <!-- 查看分组弹窗 -->
+    <el-dialog
+      title="查看当前分组"
+      :visible.sync="dialogCheckGroups"
+      width="30%"
+      center
+    >
+      <el-form>
+        <el-form-item label="已绑定分组:" class="switch-button-item">
+          <span>
+            <el-tag
+              class="groupclass"
+              v-for="item in groupWithDeviceList"
+              :key="item.idGroup"
+            >
+              {{ item.groupName }}
+            </el-tag>
+          </span>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+
+    <!-- 绑定分组弹窗 -->
+
+    <el-dialog
+      title="绑定分组"
+      :visible.sync="dialogBindGroup"
+      width="30%"
+      center
+    >
+      <el-form ref="dataForm" :model="temp" :rules="rules">
+        <el-form-item
+          style="white-space: pre"
+          label="选择分组:"
+          class="switch-button-item"
+          prop="groupsId"
+        >
+          <el-col :span="12">
+            <el-select
+              v-model="temp.groupsId"
+              filterable
+              multiple
+              value-key="id"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in groupList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
+          </el-col>
+        </el-form-item>
+      </el-form>
+
+      <span slot="footer">
+        <el-button type="primary" @click="updateData()">确 定</el-button>
+        <el-button @click="dialogBindGroup = false">取 消</el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 解绑分组弹窗 -->
+    <el-dialog
+      title="解绑分组"
+      :visible.sync="dialogUnbindGroup"
+      width="30%"
+      center
+    >
+      <el-table :data="groupWithDeviceList">
+        <el-table-column label="分组" align="center">
+          <template slot-scope="{ row }">
+            <span>{{ row.groupName }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="操作" width="340px" align="center">
+          <template slot-scope="{ row, $index }">
+            <el-button
+              type="text"
+              size="small"
+              @click="deleteGroup(row, $index)"
+              >解绑</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import Pagination from "@/components/Pagination";
+import {
+  fetchUserList,
+  fetchGroupList,
+  editGroup,
+  searchList,
+  fetchList,
+  bindGroups,
+  deleteGroups,
+  checkGroups,
+} from "@/api/userWithGroup";
+export default {
+  components: {
+    Pagination,
+  },
+  data() {
+    return {
+      list: [],
+      groupList: [],
+      groupWithDeviceList: [],
+      temp: {
+        userName: "",
+        cardNumber: "",
+        groupsId: [],
+      },
+      total: 0, //数据的总数//
+      listQuery: {
+        page: 1, //当前在第几页//
+        limit: 8, //一页几条//
+        name: "",
+      },
+      dialogCheckGroups: false,
+      dialogBindGroup: false,
+      dialogUnbindGroup: false,
+      rules: {
+        groupsId: [
+          {
+            required: true,
+            message: "请选择分组",
+            trigger: "change",
+          },
+        ],
+      },
+    };
+  },
+  created() {
+    this.getUserList();
+    this.getgroupList();
+  },
+  methods: {
+    getUserList() {
+      fetchUserList(this.listQuery).then((response) => {
+        this.list = response.data;
+        this.total = response.total;
+      });
+    },
+    getgroupList() {
+      fetchGroupList({ page: this.listQuery.page, limit: "999" }).then(
+        (response) => {
+          this.groupList = response.data;
+        }
+      );
+    },
+    checkGroup(row) {
+      this.temp = Object.assign({}, row);
+      checkGroups({ userId: row.idUser }).then((response) => {
+        this.groupWithDeviceList = response.data;
+      });
+      this.dialogCheckGroups = true;
+    },
+    bindGroup(row) {
+      this.temp = Object.assign({}, row);
+      this.dialogBindGroup = true;
+      this.$nextTick(() => {
+        this.$refs["dataForm"].clearValidate();
+      });
+    },
+    updateData() {
+      this.$refs["dataForm"].validate((valid) => {
+        if (valid) {
+          const tempData = Object.assign({}, this.temp);
+          bindGroups({
+            id: tempData.idUser,
+            groups: tempData.groupsId,
+          }).then(() => {
+            this.dialogBindGroup = false;
+            this.$notify({
+              title: "绑定分组成功",
+              type: "success",
+              duration: 1500,
+            });
+          });
+        }
+      });
+    },
+    unbindGroup(row) {
+      this.temp = Object.assign({}, row);
+      checkGroups({ userId: row.idUser }).then((response) => {
+        this.groupWithDeviceList = response.data;
+      });
+      this.dialogUnbindGroup = true;
+    },
+    deleteGroup(row, index) {
+      console.log(row, index);
+      if (confirm("确定解绑吗?")) {
+        deleteGroups({
+          id: this.temp.idUser,
+          groups: [row.idGroup],
+        }).then(() => {
+          this.$notify({
+            title: "解绑成功",
+            type: "success",
+            duration: 1500,
+          });
+          this.groupWithDeviceList.splice(index, 1);
+        });
+      }
+    },
+    handleFilter() {
+      if (!this.listQuery.name) {
+        alert("请输入姓名");
+      } else {
+        searchList({ name: this.listQuery.name }).then((response) => {
+          this.list = response.data;
+          this.total = response.total;
+        });
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.body {
+  width: 1551px;
+  margin: 29px 29px 0 31px;
+  .head {
+    display: flex;
+    width: 1380px;
+    height: 55px;
+    margin-left: 40px;
+    border-bottom: 1px solid #cccccc;
+
+    .head-img {
+      width: 30px;
+      height: 30px;
+
+      img {
+        width: 30px;
+      }
+    }
+
+    .head-info {
+      height: 22px;
+      margin-top: 5px;
+      margin-left: 16px;
+      font-weight: bold;
+    }
+    .input {
+      width: 240px;
+      margin-left: 21px;
+    }
+
+    .input-serch {
+      margin-left: 32px;
+    }
+  }
+
+  .form {
+    margin-left: 40px;
+    width: 1380px;
+
+    .block {
+      float: right;
+    }
+  }
+  .switch-button-item {
+    margin-left: 120px;
+    .groupclass {
+      float: left;
+      margin-right: 10px;
+      margin-bottom: 10px;
+    }
+  }
+}
+</style>

+ 0 - 77
src/views/zip/index.vue

@@ -1,77 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-input v-model="filename" placeholder="Please enter the file name (default file)" style="width:300px;" prefix-icon="el-icon-document" />
-    <el-button :loading="downloadLoading" style="margin-bottom:20px;" type="primary" icon="el-icon-document" @click="handleDownload">
-      Export Zip
-    </el-button>
-    <el-table v-loading="listLoading" :data="list" element-loading-text="拼命加载中" border fit highlight-current-row>
-      <el-table-column align="center" label="ID" width="95">
-        <template slot-scope="scope">
-          {{ scope.$index }}
-        </template>
-      </el-table-column>
-      <el-table-column label="Title">
-        <template slot-scope="scope">
-          {{ scope.row.title }}
-        </template>
-      </el-table-column>
-      <el-table-column label="Author" width="95" align="center">
-        <template slot-scope="scope">
-          <el-tag>{{ scope.row.author }}</el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column label="Readings" width="115" align="center">
-        <template slot-scope="scope">
-          {{ scope.row.pageviews }}
-        </template>
-      </el-table-column>
-      <el-table-column align="center" label="Date" width="220">
-        <template slot-scope="scope">
-          <i class="el-icon-time" />
-          <span>{{ scope.row.display_time }}</span>
-        </template>
-      </el-table-column>
-    </el-table>
-  </div>
-</template>
-
-<script>
-import { fetchList } from '@/api/article'
-
-export default {
-  name: 'ExportZip',
-  data() {
-    return {
-      list: null,
-      listLoading: true,
-      downloadLoading: false,
-      filename: ''
-    }
-  },
-  created() {
-    this.fetchData()
-  },
-  methods: {
-    async fetchData() {
-      this.listLoading = true
-      const { data } = await fetchList()
-      this.list = data.items
-      this.listLoading = false
-    },
-    handleDownload() {
-      this.downloadLoading = true
-      import('@/vendor/Export2Zip').then(zip => {
-        const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date']
-        const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
-        const list = this.list
-        const data = this.formatJson(filterVal, list)
-        zip.export_txt_to_zip(tHeader, data, this.filename, this.filename)
-        this.downloadLoading = false
-      })
-    },
-    formatJson(filterVal, jsonData) {
-      return jsonData.map(v => filterVal.map(j => v[j]))
-    }
-  }
-}
-</script>

+ 8 - 7
vue.config.js

@@ -37,12 +37,13 @@ module.exports = {
       errors: true
     },
     // before: require('./mock/mock-server.js')
-    proxy:{
-      [process.env.VUE_APP_BASE_API]:{
-        target: 'http://192.168.31.162:8280',
-        changeOrigin:true,
-        pathRewrite:{
-          ['^'+ process.env.VUE_APP_BASE_API]: ''
+    proxy: {
+      [process.env.VUE_APP_BASE_API]: {
+        // target: 'http://192.168.31.162:8280',
+        target: 'http://127.0.0.1:8280',
+        changeOrigin: true,
+        pathRewrite: {
+          ['^' + process.env.VUE_APP_BASE_API]: ''
         }
       }
     }
@@ -97,7 +98,7 @@ module.exports = {
             .plugin('ScriptExtHtmlWebpackPlugin')
             .after('html')
             .use('script-ext-html-webpack-plugin', [{
-            // `runtime` must same as runtimeChunk name. default is `runtime`
+              // `runtime` must same as runtimeChunk name. default is `runtime`
               inline: /runtime\..*\.js$/
             }])
             .end()