dedsudiyu 1 rok temu
rodzic
commit
403bb6282f
30 zmienionych plików z 4766 dodań i 93 usunięć
  1. 27 0
      src/api/commonality/permission.js
  2. 100 0
      src/api/iotDevice/index.js
  3. 92 8
      src/api/serviceCenter/index.js
  4. 65 0
      src/api/systemManagement/index.js
  5. 6 0
      src/assets/styles/button.scss
  6. 3 0
      src/store/modules/permission.js
  7. 4 4
      src/utils/errorCode.js
  8. 2 2
      src/utils/ruoyi.js
  9. 339 0
      src/views/iotDevice/intelligenceIot/classConfig/index.vue
  10. 301 0
      src/views/iotDevice/intelligenceIot/iotClassification/index.vue
  11. 204 0
      src/views/iotDevice/intelligenceIot/iotClassification/infoPage.vue
  12. 188 0
      src/views/iotDevice/intelligenceIot/iotClassification/listPage.vue
  13. 193 0
      src/views/iotDevice/intelligenceIot/iotHardware/index.vue
  14. 32 0
      src/views/iotDevice/iotHome/index.vue
  15. 191 0
      src/views/iotDevice/monitoringWarning/messageTemplate/index.vue
  16. 191 0
      src/views/iotDevice/monitoringWarning/warningConfig/index.vue
  17. 204 0
      src/views/iotDevice/monitoringWarning/warningLog/index.vue
  18. 191 0
      src/views/iotDevice/monitoringWarning/warningMode/index.vue
  19. 204 0
      src/views/iotDevice/operationManagement/iotLogs/index.vue
  20. 191 0
      src/views/iotDevice/operationManagement/networkComponent/index.vue
  21. 190 0
      src/views/iotDevice/operationManagement/protocolManagement/index.vue
  22. 287 21
      src/views/serviceCenter/certificationManagement/certificationAccredit/index.vue
  23. 170 16
      src/views/serviceCenter/certificationManagement/certificationInfo/index.vue
  24. 3 2
      src/views/serviceCenter/merchantManagement/index.vue
  25. 1 1
      src/views/serviceCenter/timingTask/index.vue
  26. 1 1
      src/views/systemManagement/filePreview/index.vue
  27. 974 0
      src/views/systemManagement/roleManagement/addPage.vue
  28. 386 0
      src/views/systemManagement/roleManagement/index.vue
  29. 16 38
      src/views/systemManagement/systemUser/index.vue
  30. 10 0
      vue.config.js

+ 27 - 0
src/api/commonality/permission.js

@@ -295,3 +295,30 @@ export function systemFileUpload(data) {
     data: data
   })
 }
+
+//商户下拉列表
+export function tenantDropList(data) {
+  return request({
+    url: '/system/tenant/dropList',
+    method: 'post',
+    data: data
+  })
+}
+
+//认证信息下拉列表
+export function authCustomerDropList(data) {
+  return request({
+    url: '/auth/customer/dropList',
+    method: 'post',
+    data: data
+  })
+}
+
+//角色下拉列表
+export function systemRoleDropList(data) {
+  return request({
+    url: '/system/role/dropList',
+    method: 'post',
+    data: data
+  })
+}

+ 100 - 0
src/api/iotDevice/index.js

@@ -0,0 +1,100 @@
+import request from '@/utils/request'
+
+//物联分类列表
+export function iotTypeList(data) {
+  return request({
+    url: '/iot/type/list',
+    method: 'post',
+    data: data
+  })
+}
+
+//新增物联分类
+export function iotTypeAdd(data) {
+  return request({
+    url: '/iot/type/add',
+    method: 'post',
+    data: data
+  })
+}
+
+//编辑物联分类
+export function iotTypeUpdate(data) {
+  return request({
+    url: '/iot/type/update',
+    method: 'post',
+    data: data
+  })
+}
+
+//物联分类删除
+export function iotTypeDelete(data) {
+  return request({
+    url: '/iot/type/delete',
+    method: 'post',
+    data: data
+  })
+}
+
+//物联分类详情
+export function iotTypeDetail(query) {
+  return request({
+    url: '/iot/type/detail',
+    method: 'get',
+    params: query
+  })
+}
+
+//物联参数列表
+export function iotParamList(data) {
+  return request({
+    url: '/iot/param/list',
+    method: 'post',
+    data: data
+  })
+}
+
+//物联参数添加
+export function iotParamAdd(data) {
+  return request({
+    url: '/iot/param/add',
+    method: 'post',
+    data: data
+  })
+}
+
+//物联参数编辑
+export function iotParamUpdate(data) {
+  return request({
+    url: '/iot/param/update',
+    method: 'post',
+    data: data
+  })
+}
+
+//物联参数删除
+export function iotParamDelete(data) {
+  return request({
+    url: '/iot/param/delete',
+    method: 'post',
+    data: data
+  })
+}
+
+//物联参数详情
+export function iotParamDetail(query) {
+  return request({
+    url: '/iot/param/detail',
+    method: 'get',
+    params: query
+  })
+}
+
+//物联参数展示
+export function iotParamAll(data) {
+  return request({
+    url: '/iot/param/all',
+    method: 'post',
+    data: data
+  })
+}

+ 92 - 8
src/api/serviceCenter/index.js

@@ -154,14 +154,6 @@ export function cleanJobLog() {
 }
 /***********************商户管理***********************/
 
-//商户下拉列表
-export function tenantDropList(data) {
-  return request({
-    url: '/system/tenant/dropList',
-    method: 'post',
-    data: data
-  })
-}
 
 // 获取商户列表
 export function tenantList(data) {
@@ -207,3 +199,95 @@ export function tenantDetail(query) {
     params: query
   })
 }
+/***********************认证管理***********************/
+//认证信息列表
+export function authCustomerList(data) {
+  return request({
+    url: '/auth/customer/list',
+    method: 'post',
+    data: data
+  })
+}
+
+
+//认证信息新增
+export function authCustomerAdd(data) {
+  return request({
+    url: '/auth/customer/add',
+    method: 'post',
+    data: data
+  })
+}
+
+//认证信息编辑
+export function authCustomerUpdate(data) {
+  return request({
+    url: '/auth/customer/update',
+    method: 'post',
+    data: data
+  })
+}
+
+//认证信息删除
+export function authCustomerDelete(data) {
+  return request({
+    url: '/auth/customer/delete',
+    method: 'post',
+    data: data
+  })
+}
+
+//认证信息详情
+export function authCustomerDetail(query) {
+  return request({
+    url: '/auth/customer/detail',
+    method: 'get',
+    params: query
+  })
+}
+
+//认证授权列表
+export function authLicenseList(data) {
+  return request({
+    url: '/auth/license/list',
+    method: 'post',
+    data: data
+  })
+}
+
+
+//认证授权删除
+export function authLicenseDelete(data) {
+  return request({
+    url: '/auth/license/delete',
+    method: 'post',
+    data: data
+  })
+}
+
+//认证授权新增/编辑
+export function authLicenseSetup(data) {
+  return request({
+    url: '/auth/license/setup',
+    method: 'post',
+    data: data
+  })
+}
+
+//认证授权重置密钥
+export function authLicenseSecret(data) {
+  return request({
+    url: '/auth/license/secret',
+    method: 'post',
+    data: data
+  })
+}
+
+//认证授权详情
+export function authLicenseDetail(query) {
+  return request({
+    url: '/auth/license/detail',
+    method: 'get',
+    params: query
+  })
+}

+ 65 - 0
src/api/systemManagement/index.js

@@ -260,3 +260,68 @@ export function delNotice(data) {
     data: data
   })
 }
+/*********************************角色管理*********************************/
+//角色列表
+export function systemRoleList(data) {
+  return request({
+    url: '/system/role/list',
+    method: 'post',
+    data: data
+  })
+}
+
+//角色新增
+export function systemRoleAdd(data) {
+  return request({
+    url: '/system/role/add',
+    method: 'post',
+    data: data
+  })
+}
+
+//角色编辑
+export function systemRoleUpdate(data) {
+  return request({
+    url: '/system/role/update',
+    method: 'post',
+    data: data
+  })
+}
+
+//角色删除
+export function systemRoleDelete(data) {
+  return request({
+    url: '/system/role/delete',
+    method: 'post',
+    data: data
+  })
+}
+
+//角色详情
+export function systemRoleDetail(query) {
+  return request({
+    url: '/system/role/detail',
+    method: 'get',
+    params: query
+  })
+}
+
+//获取角色权限树
+export function systemRoleGetRoleMenu(query) {
+  return request({
+    url: '/system/role/getRoleMenu',
+    method: 'get',
+    params: query
+  })
+}
+
+//保存角色权限
+export function systemRoleSaveRolePermission(data) {
+  return request({
+    url: '/system/role/saveRolePermission',
+    method: 'post',
+    data: data
+  })
+}
+
+

+ 6 - 0
src/assets/styles/button.scss

@@ -3,6 +3,9 @@
 .cursor_hover{
   cursor:pointer;
 }
+.clickCopy{
+  cursor:pointer;
+}
 /*=========================logo======================*/
 .logo_color{
   color:$acquiesceThemeColorA;
@@ -285,6 +288,7 @@
   }
   .dialog-footer-button-info{
     width:70px;
+    height:30px;
     line-height:30px;
     text-align: center;
     border:1px solid $buttonColorG;
@@ -302,6 +306,7 @@
   }
   .dialog-footer-button-primary{
     width:70px;
+    height:30px;
     line-height:30px;
     text-align: center;
     border:1px solid $buttonColorC;
@@ -319,6 +324,7 @@
   }
   .dialog-footer-button-border{
     width:70px;
+    height:30px;
     line-height:30px;
     text-align: center;
     border:1px solid $buttonColorC;

+ 3 - 0
src/store/modules/permission.js

@@ -186,6 +186,9 @@ export const loadView = (view) => { // 路由懒加载
   }else if(pathName === 'laboratoryManagement'){
     //综合管理
     return (resolve) => require([`@/views/laboratoryManagement${pathUrl}`], resolve)
+  }else if(pathName === 'iotDevice'){
+    //物联控制
+    return (resolve) => require([`@/views/iotDevice${pathUrl}`], resolve)
   }
 }
 

+ 4 - 4
src/utils/errorCode.js

@@ -1,7 +1,7 @@
 export default {
-  '5004': '参数异常,请联系管理员',
-  '5006': '数据不存在,请联系管理员',
-  '5007': '业务异常,请联系管理员',
-  '5008': '服务异常,请联系管理员',
+  // '5004': '参数异常,请联系管理员',
+  // '5006': '数据不存在,请联系管理员',
+  // '5007': '业务异常,请联系管理员',
+  // '5008': '服务异常,请联系管理员',
   'default': '系统未知错误,请反馈给管理员'
 }

+ 2 - 2
src/utils/ruoyi.js

@@ -325,7 +325,7 @@ export function versionField() {
 /**
  * 点击复制文本
  */
-export function clickCopy(context) {
+export function clickCopy(context,name) {
   // 创建输入框元素
   let oInput = document.createElement('input');
   // 将想要复制的值
@@ -337,7 +337,7 @@ export function clickCopy(context) {
   // 执行浏览器复制命令
   document.execCommand('Copy');
   // 弹出复制成功信息
-  this.msgSuccess('复制成功');
+  this.msgSuccess(name?name+'复制成功':'复制成功');
   // 复制后移除输入框
   oInput.remove();
 }

+ 339 - 0
src/views/iotDevice/intelligenceIot/classConfig/index.vue

@@ -0,0 +1,339 @@
+<!--分类配置-->
+<template>
+  <div class="app-container classConfig">
+    <div class="title-box">
+      <el-form :model="queryParams" class="form-box" ref="queryForm"
+               :inline="true" style="width:100%;">
+        <el-form-item label="关键词" prop="searchValue " label-width="90px">
+          <el-input
+            maxLength="30"
+            v-model="queryParams.searchValue"
+            placeholder="请输入关键词"
+            clearable
+            style="width: 200px"
+          />
+        </el-form-item>
+        <el-form-item label="状态" prop="state ">
+          <el-select v-model="queryParams.state " clearable placeholder="请选择" style="width: 200px">
+            <el-option
+              v-for="dict in options"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <p class="inquire-button-one" @click="handleQuery" style="margin-right:10px;">查询</p>
+          <p class="reset-button-one" @click="resetQuery">重置</p>
+        </el-form-item>
+        <el-form-item label="" prop="title" style="float: right">
+          <el-col :span="1.5" style="margin-right:10px;">
+            <p class="add-button-one-90"
+               @click="dialogOpen"
+            >新增</p>
+          </el-col>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="content-box">
+      <el-table v-loading="loading" border :data="dataList">
+        <el-table-column label="标题" width="80" align="left" prop="label" />
+        <el-table-column label="字段" align="left" prop="field" show-overflow-tooltip/>
+        <el-table-column label="类型" align="left" prop="type" show-overflow-tooltip/>
+        <el-table-column label="数据类型" align="left" prop="dataType" show-overflow-tooltip/>
+        <el-table-column label="排序" align="left" prop="sort" show-overflow-tooltip/>
+        <el-table-column label="是否内置" align="left" prop="required" show-overflow-tooltip>
+          <template slot-scope="scope">{{scope.row.required?'是':'否'}}</template>
+        </el-table-column>
+        <el-table-column label="状态" align="left" prop="state" show-overflow-tooltip>
+          <template slot-scope="scope">{{scope.row.state?'启用':'停用'}}</template>
+        </el-table-column>
+        <el-table-column label="创建时间" align="left" prop="createTime" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.createTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="left" class-name="small-padding fixed-width" width="260">
+          <template slot-scope="scope">
+            <div class="table-button-box">
+              <p class="table-button-null"></p>
+              <p class="table-button-p"
+                 @click="tableButton(1,scope.row)"
+              >上移</p>
+              <p class="table-button-p"
+                 @click="tableButton(2,scope.row)"
+              >下移</p>
+              <p class="table-button-p"
+                 @click="tableButton(3,scope.row)"
+              >编辑</p>
+              <p class="table-button-p"
+                 @click="tableButton(4,scope.row)"
+              >配置</p>
+              <p class="table-button-p"
+                 @click="tableButton(5,scope.row)"
+              >删除</p>
+              <p class="table-button-null"></p>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :page-sizes="[20, 30, 40, 50]"
+                  v-show="total>0"
+                  :total="total"
+                  :page.sync="queryParams.page"
+                  :limit.sync="queryParams.pageSize"
+                  @pagination="getList"
+      />
+    </div>
+    <!--新增弹窗-->
+    <el-dialog class="classConfig-dialog" :title='dialogTitle' width="540px" append-to-body
+               :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
+               :close-on-click-modal="false" :close-on-press-escape="false">
+      <el-form :model="dialogForm" ref="dialogForm" :inline="true" :rules="dialogRules" class="addCheckPage-min" label-width="80px">
+        <el-form-item label="标题" prop="label">
+          <el-input v-model="dialogForm.label" placeholder="请输入名称" maxLength="10" style="width:320px;"/>
+        </el-form-item>
+        <el-form-item label="字段" prop="field">
+          <el-input v-model="dialogForm.field" placeholder="请输入标识" maxLength="20" style="width:320px;"/>
+        </el-form-item>
+        <el-form-item label="类型" prop="type">
+          <el-select v-model="dialogForm.type" placeholder="请选择类型" clearable style="width:320px;">
+            <el-option
+              v-for="dict in classOption"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="数据类型" prop="dataType">
+          <el-select v-model="dialogForm.dataType" placeholder="请选择数据类型" clearable style="width:320px;">
+            <el-option
+              v-for="dict in dataClassOption"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="排序" prop="sort">
+          <el-input-number v-model="dialogForm.sort" controls-position="right" :min="1" :max="9999" style="width:320px;"></el-input-number>
+        </el-form-item>
+        <el-form-item label="是否必须" prop="required">
+          <el-radio-group v-model="dialogForm.required" style="width:320px;">
+            <el-radio :label="true">必须</el-radio>
+            <el-radio :label="false">非必需</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="状态" prop="state">
+          <el-radio-group v-model="dialogForm.state" style="width:320px;">
+            <el-radio :label="true">启用</el-radio>
+            <el-radio :label="false">禁用</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-info" @click="dialogOff()">取消</p>
+        <p class="dialog-footer-button-primary" @click="dialogSubmit">确定</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import { iotParamList,iotParamAdd,iotParamUpdate,iotParamDelete,iotParamDetail } from "@/api/iotDevice/index";
+  export default {
+    name: 'index',
+    data(){
+      return{
+        loading:false,
+        options:[{label:'启用',value:true},{label:'停用',value:false}],
+        queryParams:{
+          page:1,
+          pageSize:20,
+          searchValue :"",
+          state :null,
+        },
+        dataList:[],
+        total:0,
+        dialogTitle:null,
+        dialogType:false,
+        dialogForm:{},
+        dialogRules:{
+          label: [
+            { required: true, message: "请输入标题", trigger: "blur" },
+            { required: true, message: "请输入标题", validator: this.spaceJudgment, trigger: "blur" }
+          ],
+          field: [
+            { required: true, message: "请输入字段", trigger: "blur" },
+            { required: true, message: "请输入字段", validator: this.spaceJudgment, trigger: "blur" }
+          ],
+          type: [
+            { required: true, message: "请选择类型", trigger: "blur" },
+          ],
+          dataType: [
+            { required: true, message: "请选择数据类型", trigger: "blur" },
+          ],
+          sort: [
+            { required: true, message: "请输入", trigger: "blur" },
+            { required: true, message: "请输入", validator: this.spaceJudgment, trigger: "blur" }
+          ],
+          required: [
+            { required: true, message: "是否必须", trigger: "blur" },
+          ],
+          state: [
+            { required: true, message: "请选择状态", trigger: "blur" },
+          ],
+        },
+        classOption:[
+          {label:'文本框',value:'text'},
+          {label:'下拉框',value:'select'},
+          {label:'单选框',value:'radiobox'},
+          {label:'复选框',value:'checkbox'},
+          {label:'密码框',value:'password'},
+        ],
+        dataClassOption:[
+          {label:'字符型',value:'string'},
+          {label:'布尔型',value:'boolean'},
+          {label:'数字型',value:'int'},
+          {label:'浮点型',value:'number'},
+        ],
+      }
+    },
+    created(){
+
+    },
+    mounted(){
+      this.getList();
+    },
+    methods:{
+      //弹层关闭
+      dialogOff(){
+        this.$set(this,'dialogType',false);
+      },
+      //弹层开启
+      dialogOpen(){
+        this.dialogFormReset();
+        this.$set(this,'dialogTitle','新增');
+        this.$set(this,'dialogType',true);
+      },
+      //弹层确定
+      dialogSubmit(){
+        this.$refs["dialogForm"].validate(valid => {
+          if (valid) {
+            if(this.dialogForm.id){
+              let obj = {
+                id:this.dialogForm.id,
+                label:this.dialogForm.label,
+                field:this.dialogForm.field,
+                type:this.dialogForm.type,
+                dataType:this.dialogForm.dataType,
+                sort:this.dialogForm.sort,
+                required:this.dialogForm.required,
+                state:this.dialogForm.state,
+              }
+              iotParamUpdate(obj).then(response => {
+                this.msgSuccess(response.message);
+                this.getList();
+                this.$set(this,'dialogType',false);
+              });
+            }else{
+              iotParamAdd(this.dialogForm).then(response => {
+                this.msgSuccess(response.message);
+                this.getList();
+                this.$set(this,'dialogType',false);
+              });
+            }
+          }
+        })
+      },
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      resetQuery(){
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          searchValue :"",
+          state :null,
+        });
+        this.getList();
+      },
+      dialogFormReset(){
+        this.$set(this,'dialogForm',{
+          label:'',
+          field:'',
+          type:'',
+          dataType:'',
+          sort:'',
+          required:true,
+          state:true,
+        });
+      },
+      //获取数据列表
+      getList(){
+        this.$set(this,'loading',true);
+        iotParamList(this.queryParams).then(response => {
+          this.$set(this,'loading',false);
+          this.$set(this,'dataList',response.data.records);
+          this.$set(this,'total',response.data.total);
+        });
+      },
+      tableButton(type,row){
+        let self = this;
+        if(type == 1){
+          //上移
+        }else if(type == 2){
+          //下移
+        }else if(type == 3){
+          //编辑
+          iotParamDetail({id:row.id}).then(response => {
+            this.dialogFormReset();
+            this.$set(this,'dialogTitle','编辑');
+            this.$set(this,'dialogForm',JSON.parse(JSON.stringify(response.data)));
+            this.$set(this,'dialogType',true);
+          });
+        }else if(type == 4){
+          //配置
+        }else if(type == 5){
+          //删除
+          this.$confirm('是否确认删除?', "警告", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          }).then(function() {
+          }).then(() => {
+            iotParamDelete({id:row.id}).then(response => {
+              self.msgSuccess(response.message)
+              self.getList();
+            });
+          }).catch(() => {});
+        }
+      },
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .classConfig{
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    .title-box{
+      padding-top:20px;
+      border-bottom:1px solid #dedede;
+      display: flex;
+    }
+    .content-box{
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      padding:20px;
+      overflow: hidden;
+    }
+  }
+</style>

+ 301 - 0
src/views/iotDevice/intelligenceIot/iotClassification/index.vue

@@ -0,0 +1,301 @@
+<!--物联分类-->
+<template>
+  <div class="app-container iotClassification">
+    <div class="iotClassification-page" v-if="pageType == 1">
+      <div class="title-box">
+        <el-form :model="queryParams" class="form-box" ref="queryForm"
+                 :inline="true" style="width:100%;">
+          <el-form-item label="关键词" prop="searchValue " label-width="90px">
+            <el-input
+              maxLength="30"
+              v-model="queryParams.searchValue "
+              placeholder="请输入关键词"
+              clearable
+              style="width: 200px"
+            />
+          </el-form-item>
+          <el-form-item label="状态" prop="state ">
+            <el-select v-model="queryParams.state " clearable placeholder="请选择" style="width: 200px">
+              <el-option
+                v-for="dict in options"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <p class="inquire-button-one" @click="handleQuery" style="margin-right:10px;">查询</p>
+            <p class="reset-button-one" @click="resetQuery">重置</p>
+          </el-form-item>
+          <el-form-item label="" prop="title" style="float: right">
+            <el-col :span="1.5" style="margin-right:10px;">
+              <p class="add-button-one-90"
+                 @click="dialogOpen"
+              >新增</p>
+            </el-col>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div class="content-box">
+        <el-table v-loading="loading" border :data="dataList">
+          <el-table-column label="名称" align="left" prop="typeName" />
+          <el-table-column label="标识" align="left" prop="typeKey" show-overflow-tooltip/>
+          <el-table-column label="是否内置" align="left" prop="isInner" show-overflow-tooltip>
+            <template slot-scope="scope">{{scope.row.isInner?'是':'否'}}</template>
+          </el-table-column>
+          <el-table-column label="状态" align="left" prop="state" show-overflow-tooltip>
+            <template slot-scope="scope">{{scope.row.state?'启用':'停用'}}</template>
+          </el-table-column>
+          <el-table-column label="创建时间" align="left" prop="createTime" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.createTime) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" align="left" class-name="small-padding fixed-width">
+            <template slot-scope="scope">
+              <div class="table-button-box">
+                <p class="table-button-null"></p>
+                <p class="table-button-p"
+                   @click="tableButton(2,scope.row)"
+                >详情</p>
+                <p class="table-button-p"
+                   @click="tableButton(3,scope.row)"
+                >编辑</p>
+                <p class="table-button-p"
+                   @click="tableButton(4,scope.row)"
+                >删除</p>
+                <p class="table-button-null"></p>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination :page-sizes="[20, 30, 40, 50]"
+                    v-show="total>0"
+                    :total="total"
+                    :page.sync="queryParams.page"
+                    :limit.sync="queryParams.pageSize"
+                    @pagination="getList"
+        />
+      </div>
+    </div>
+    <infoPage v-if="pageType == 2" :propsData="propsData"></infoPage>
+    <!--新增弹窗-->
+    <el-dialog class="iotClassification-dialog" :title='dialogTitle' width="540px" append-to-body
+               :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
+               :close-on-click-modal="false" :close-on-press-escape="false">
+      <el-form :model="dialogForm" ref="dialogForm" :inline="true" :rules="dialogRules" class="addCheckPage-min" label-width="80px">
+        <el-form-item label="名称" prop="typeName">
+          <el-input v-model="dialogForm.typeName" placeholder="请输入名称" maxLength="10" style="width:320px;"/>
+        </el-form-item>
+        <el-form-item label="标识" prop="typeKey">
+          <el-input v-model="dialogForm.typeKey" placeholder="请输入标识" maxLength="20" style="width:320px;"/>
+        </el-form-item>
+        <el-form-item label="状态" prop="state">
+          <el-radio-group v-model="dialogForm.state">
+            <el-radio :label="true">启用</el-radio>
+            <el-radio :label="false">禁用</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input
+            type="textarea"
+            placeholder="请输入内容"
+            v-model="dialogForm.remark"
+            resize="none"
+            maxLength="50"
+            style="width:320px;"
+            :rows="3"
+            show-word-limit
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-info" @click="dialogOff()">取消</p>
+        <p class="dialog-footer-button-primary" @click="dialogSubmit">确定</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import { iotTypeList,iotTypeDetail,iotTypeAdd,iotTypeUpdate,iotTypeDelete } from "@/api/iotDevice/index";
+  import infoPage from "./infoPage.vue"
+  export default {
+    name: 'index',
+    components: {
+      infoPage
+    },
+    data(){
+      return{
+        loading:false,
+        pageType:1,
+        options:[{label:'启用',value:true},{label:'停用',value:false}],
+        queryParams:{
+          page:1,
+          pageSize:20,
+          searchValue :"",
+          jobGroup:null,
+          state :null,
+        },
+        dataList:[],
+        total:0,
+        dialogTitle:null,
+        dialogType:false,
+        dialogForm:{
+          typeName:"",
+          typeKey:"",
+          state:true,
+          remark:"",
+        },
+        dialogRules:{
+          typeName: [
+            { required: true, message: "请输入名称", trigger: "blur" },
+            { required: true, message: "请输入名称", validator: this.spaceJudgment, trigger: "blur" }
+          ],
+          typeKey: [
+            { required: true, message: "请输入标识", trigger: "blur" },
+            { required: true, message: "请输入标识", validator: this.spaceJudgment, trigger: "blur" }
+          ],
+          state: [
+            { required: true, message: "请选择状态", trigger: "blur" },
+          ],
+        },
+        //组件传参
+        propsData:{},
+      }
+    },
+    created(){
+
+    },
+    mounted(){
+      this.getList();
+    },
+    methods:{
+      //弹层关闭
+      dialogOff(){
+        this.$set(this,'dialogType',false);
+      },
+      //弹层开启
+      dialogOpen(){
+        this.dialogFormReset();
+        this.$set(this,'dialogTitle','新增');
+        this.$set(this,'dialogType',true);
+      },
+      //弹层确定
+      dialogSubmit(){
+        this.$refs["dialogForm"].validate(valid => {
+          if (valid) {
+            if(this.dialogForm.typeId){
+              let obj = {
+                typeId:this.dialogForm.typeId,
+                typeName:this.dialogForm.typeName,
+                typeKey:this.dialogForm.typeKey,
+                state:this.dialogForm.state,
+                remark:this.dialogForm.remark,
+              }
+              iotTypeUpdate(obj).then(response => {
+                this.msgSuccess(response.message);
+                this.getList();
+                this.$set(this,'dialogType',false);
+              });
+            }else{
+              iotTypeAdd(this.dialogForm).then(response => {
+                this.msgSuccess(response.message);
+                this.getList();
+                this.$set(this,'dialogType',false);
+              });
+            }
+          }
+        })
+      },
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      resetQuery(){
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          searchValue :"",
+          state :null,
+        });
+        this.getList();
+      },
+      dialogFormReset(){
+        this.$set(this,'dialogForm',{
+          typeName:"",
+          typeKey:"",
+          state:true,
+          remark:"",
+        });
+      },
+      //获取数据列表
+      getList(){
+        this.$set(this,'loading',true);
+        iotTypeList(this.queryParams).then(response => {
+          this.$set(this,'dataList',response.data.records);
+          this.$set(this,'total',response.data.total);
+          this.$set(this,'loading',false);
+        });
+      },
+      tableButton(type,row){
+        let self = this;
+        if(type == 2){
+          //详情
+          this.$set(this,'propsData',JSON.parse(JSON.stringify(row)));
+          this.$set(this,'pageType',2);
+        }else if(type == 3){
+          //编辑
+          iotTypeDetail({id:row.typeId}).then(response => {
+            this.dialogFormReset();
+            this.$set(this,'dialogForm',JSON.parse(JSON.stringify(response.data)));
+            this.$set(this,'dialogType',true);
+          });
+        }else if(type == 4){
+          //删除
+          this.$confirm('是否确认删除?', "警告", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          }).then(function() {
+          }).then(() => {
+            iotTypeDelete({typeId:row.typeId}).then(response => {
+              self.msgSuccess(response.message)
+              self.getList();
+            });
+          }).catch(() => {});
+        }else if(type == 'out'){
+          this.$set(this,'pageType',1);
+        }
+      },
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+.iotClassification{
+  flex:1;
+  display: flex;
+  flex-direction: column;
+  .iotClassification-page{
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    .title-box{
+      padding-top:20px;
+      border-bottom:1px solid #dedede;
+      display: flex;
+    }
+    .content-box{
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      padding:20px;
+      overflow: hidden;
+    }
+  }
+}
+</style>

+ 204 - 0
src/views/iotDevice/intelligenceIot/iotClassification/infoPage.vue

@@ -0,0 +1,204 @@
+<!--物联分类详情-->
+<template>
+  <div class="iotClassification-info">
+    <div class="title-box">
+      <p>{{propsData.typeName}}详情</p>
+      <p class="reset-button-one" @click="outButton">返回</p>
+    </div>
+    <div class="content-box">
+      <div class="text-box">
+        <div>
+          <p>标识:</p>
+          <p>{{propsData.typeKey}}</p>
+        </div>
+        <div>
+          <p>状态:</p>
+          <p>{{propsData.state?'启用':'停用'}}</p>
+        </div>
+      </div>
+      <div class="table-button">
+        <div>
+          <p class="cursor-p" @click="tableClick(1)"
+             :class="tableType == 1? 'checkTableColor':''">模型</p>
+          <p :class="tableType == 1? 'checkTableBack':''"></p>
+        </div>
+        <div>
+          <p class="cursor-p" @click="tableClick(2)"
+             :class="tableType == 2? 'checkTableColor':''">属性</p>
+          <p :class="tableType == 2? 'checkTableBack':''"></p>
+        </div>
+        <div class="div-flex">
+          <p> </p>
+          <p></p>
+        </div>
+      </div>
+      <div class="for-form-max-box" v-if="tableType == 1">
+        <el-form :model="infoPageForm" class="form-box" ref="queryForm"
+                 :inline="true" style="width:100%;">
+          <div class="for-form-box">
+            <div>
+              <el-form-item label="设备名称:" prop="searchValue " label-width="180px">
+                <el-input
+                  maxLength="20"
+                  v-model="infoPageForm.searchValue"
+                  placeholder="请输入设备名称"
+                  clearable
+                  style="width: 160px"
+                />
+              </el-form-item>
+              <el-form-item label="" prop="searchValue " label-width="0">
+                <el-checkbox-group v-model="infoPageForm">
+                  <el-checkbox label="选择" style="margin:2px 10px 0 10px;"></el-checkbox>
+                  <el-checkbox label="必填项" style="margin-top:2px;"></el-checkbox>
+                </el-checkbox-group>
+              </el-form-item>
+            </div>
+          </div>
+          <div class="for-form-box">
+            <div>
+              <el-form-item label="设备编号:" prop="searchValue " label-width="180px">
+                <el-input
+                  maxLength="20"
+                  v-model="infoPageForm.searchValue"
+                  placeholder="请输入设备编号"
+                  clearable
+                  style="width: 160px"
+                />
+              </el-form-item>
+              <el-form-item label="" prop="searchValue " label-width="0">
+                <el-checkbox-group v-model="infoPageForm">
+                  <el-checkbox label="选择" style="margin:2px 10px 0 10px;"></el-checkbox>
+                  <el-checkbox label="必填项" style="margin-top:2px;"></el-checkbox>
+                </el-checkbox-group>
+              </el-form-item>
+            </div>
+          </div>
+        </el-form>
+      </div>
+      <listPage v-if="tableType == 2" :propsData="propsData"></listPage>
+    </div>
+  </div>
+</template>
+
+<script>
+  import listPage from "./listPage.vue"
+  export default {
+    name: 'infoPage',
+    components: {
+      listPage
+    },
+    props:{
+      propsData:{},
+    },
+    data(){
+      return{
+        tableType:1,
+        infoPageForm:{
+
+        },
+      }
+    },
+    created(){
+
+    },
+    mounted(){
+
+    },
+    methods:{
+      //table切换
+      tableClick(type){
+        if(type != this.tableType){
+          this.$set(this,'tableType',type);
+        }
+      },
+      //返回按钮
+      outButton(){
+        this.$parent.tableButton('out')
+      },
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .iotClassification-info{
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    .title-box{
+      display: flex;
+      height:80px;
+      border-bottom:1px solid #dedede;
+      p:nth-child(1){
+        flex:1;
+        line-height:80px;
+        margin-left:20px;
+        color:#0045AF;
+      }
+      p:nth-child(2){
+        margin:20px;
+      }
+    }
+    .content-box{
+      flex:1;
+      display: flex;
+      flex-direction: column;
+      .text-box{
+        display: flex;
+        div{
+          display: flex;
+          width:400px;
+          p{
+            margin-top:10px;
+            line-height:40px;
+          }
+          p:nth-child(1){
+            width:122px;
+            text-align: right;
+          }
+          p:nth-child(2){
+
+          }
+        }
+      }
+      .table-button{
+        display: flex;
+        div{
+          width:180px;
+          p{
+            text-align: center;
+          }
+          p:nth-child(1){
+            height:60px;
+            line-height:60px;
+          }
+          p:nth-child(2){
+            height:2px;
+            background-color: #dedede;
+          }
+          .cursor-p{
+            cursor: pointer;
+          }
+          .checkTableColor{
+            color:#0045AF!important;
+          }
+          .checkTableBack{
+            background-color: #0045AF!important;
+          }
+        }
+        .div-flex{
+          flex:1;
+        }
+      }
+      .for-form-max-box{
+        .for-form-box{
+          display: inline-block;
+          overflow: hidden;
+          margin-top:20px;
+          div{
+            display: flex;
+          }
+        }
+      }
+    }
+  }
+</style>

+ 188 - 0
src/views/iotDevice/intelligenceIot/iotClassification/listPage.vue

@@ -0,0 +1,188 @@
+<template>
+  <div class="iotClassification-listPage">
+    <div class="title-box">
+      <el-form :model="queryParams" class="form-box" ref="queryForm"
+               :inline="true" style="width:100%;">
+        <el-form-item label="关键词" prop="searchValue " label-width="90px">
+          <el-input
+            maxLength="30"
+            v-model="queryParams.searchValue"
+            placeholder="请输入关键词"
+            clearable
+            style="width: 200px"
+          />
+        </el-form-item>
+        <el-form-item label="状态" prop="state ">
+          <el-select v-model="queryParams.state " clearable placeholder="请选择" style="width: 200px">
+            <el-option
+              v-for="dict in options"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <p class="inquire-button-one" @click="handleQuery" style="margin-right:10px;">查询</p>
+          <p class="reset-button-one" @click="resetQuery">重置</p>
+        </el-form-item>
+        <el-form-item label="" prop="title" style="float: right">
+          <el-col :span="1.5" style="margin-right:10px;">
+            <p class="add-button-one-90"
+               @click="dialogOpen"
+            >新增</p>
+          </el-col>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="content-box">
+      <el-table v-loading="loading" border :data="dataList">
+        <el-table-column label="标题" width="80" align="left" prop="label" />
+        <el-table-column label="字段" align="left" prop="field" show-overflow-tooltip/>
+        <el-table-column label="类型" align="left" prop="type" show-overflow-tooltip/>
+        <el-table-column label="数据类型" align="left" prop="dataType" show-overflow-tooltip/>
+        <el-table-column label="排序" align="left" prop="sort" show-overflow-tooltip/>
+        <el-table-column label="是否内置" align="left" prop="required" show-overflow-tooltip>
+          <template slot-scope="scope">{{scope.row.required?'是':'否'}}</template>
+        </el-table-column>
+        <el-table-column label="状态" align="left" prop="state" show-overflow-tooltip>
+          <template slot-scope="scope">{{scope.row.state?'启用':'停用'}}</template>
+        </el-table-column>
+        <el-table-column label="创建时间" align="left" prop="createTime" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.createTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="left" class-name="small-padding fixed-width" width="260">
+          <template slot-scope="scope">
+            <div class="table-button-box">
+              <p class="table-button-null"></p>
+              <p class="table-button-p"
+                 @click="tableButton(1,scope.row)"
+              >上移</p>
+              <p class="table-button-p"
+                 @click="tableButton(2,scope.row)"
+              >下移</p>
+              <p class="table-button-p"
+                 @click="tableButton(3,scope.row)"
+              >编辑</p>
+              <p class="table-button-p"
+                 @click="tableButton(4,scope.row)"
+              >配置</p>
+              <p class="table-button-p"
+                 @click="tableButton(5,scope.row)"
+              >删除</p>
+              <p class="table-button-null"></p>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :page-sizes="[20, 30, 40, 50]"
+                  v-show="total>0"
+                  :total="total"
+                  :page.sync="queryParams.page"
+                  :limit.sync="queryParams.pageSize"
+                  @pagination="getList"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'listPage',
+    data(){
+      return{
+        loading:false,
+        options:[{label:'启用',value:true},{label:'停用',value:false}],
+        queryParams:{
+          page:1,
+          pageSize:20,
+          searchValue :"",
+          state :null,
+        },
+        dataList:[],
+        total:0,
+      }
+    },
+    created(){
+
+    },
+    mounted(){
+
+    },
+    methods:{
+      //弹层开启
+      dialogOpen(){
+        this.dialogFormReset();
+        this.$set(this,'dialogTitle','新增');
+        this.$set(this,'dialogType',true);
+      },
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      resetQuery(){
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          searchValue :"",
+          state :null,
+        });
+        this.getList();
+      },
+      getList(){
+
+      },
+      tableButton(type,row){
+        let self = this;
+        if(type == 2){
+          //详情
+          this.$set(this,'propsData',JSON.parse(JSON.stringify(row)));
+          this.$set(this,'pageType',2);
+        }else if(type == 3){
+          //编辑
+          iotTypeDetail({id:row.typeId}).then(response => {
+            this.dialogFormReset();
+            this.$set(this,'dialogForm',JSON.parse(JSON.stringify(response.data)));
+            this.$set(this,'dialogType',true);
+          });
+        }else if(type == 4){
+          //删除
+          this.$confirm('是否确认删除?', "警告", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          }).then(function() {
+          }).then(() => {
+            iotTypeDelete({typeId:row.typeId}).then(response => {
+              self.msgSuccess(response.message)
+              self.getList();
+            });
+          }).catch(() => {});
+        }else if(type == 'out'){
+          this.$set(this,'pageType',1);
+        }
+      },
+    }
+  }
+</script>
+
+<style scoped lang="scss">
+  .iotClassification-listPage{
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    .title-box{
+      padding-top:20px;
+      display: flex;
+    }
+    .content-box{
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      padding:0 20px 20px;
+      overflow: hidden;
+    }
+  }
+</style>

+ 193 - 0
src/views/iotDevice/intelligenceIot/iotHardware/index.vue

@@ -0,0 +1,193 @@
+<!--物联设备-->
+<template>
+  <div class="app-container iotHardware">
+    <div class="title-box">
+      <el-form :model="queryParams" class="form-box" ref="queryForm"
+               :inline="true" style="width:100%;">
+        <el-form-item label="关键词" prop="queryData1" label-width="90px">
+          <el-input
+            maxLength="30"
+            v-model="queryParams.queryData1"
+            placeholder="请输入关键词"
+            clearable
+            style="width: 200px"
+          />
+        </el-form-item>
+        <el-form-item label="设备类型" prop="queryData2">
+          <el-select v-model="queryParams.queryData2" clearable placeholder="请选择" style="width: 200px">
+            <el-option
+              v-for="dict in options"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <p class="inquire-button-one" @click="handleQuery" style="margin-right:10px;">查询</p>
+          <p class="reset-button-one" @click="resetQuery">重置</p>
+        </el-form-item>
+        <el-form-item label="" prop="title" style="float: right">
+          <el-col :span="1.5" style="margin-right:10px;">
+            <p class="add-button-one-90"
+               @click="dialogOpen"
+            >新增</p>
+          </el-col>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="content-box">
+      <el-table v-loading="loading" border :data="dataList">
+        <el-table-column label="设备名" width="80" align="left" prop="data1" />
+        <el-table-column label="编号" align="left" prop="data2" show-overflow-tooltip/>
+        <el-table-column label="设备类型" align="left" prop="data3" show-overflow-tooltip/>
+        <el-table-column label="网关" align="left" prop="data4" show-overflow-tooltip/>
+        <el-table-column label="位置" align="left" prop="data5" show-overflow-tooltip/>
+        <el-table-column label="是否在线" align="left" prop="data6" show-overflow-tooltip/>
+        <el-table-column label="状态" align="left" prop="data7" show-overflow-tooltip/>
+        <el-table-column label="创建时间" align="left" prop="data8" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.data8) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="left" class-name="small-padding fixed-width">
+          <template slot-scope="scope">
+            <div class="table-button-box">
+              <p class="table-button-null"></p>
+              <p class="table-button-p"
+                 @click="tableButton(2,scope.row)"
+              >编辑</p>
+              <p class="table-button-p"
+                 @click="tableButton(3,scope.row)"
+              >详情</p>
+              <p class="table-button-p"
+                 @click="tableButton(4,scope.row)"
+              >删除</p>
+              <p class="table-button-null"></p>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :page-sizes="[20, 30, 40, 50]"
+                  v-show="total>0"
+                  :total="total"
+                  :page.sync="queryParams.page"
+                  :limit.sync="queryParams.pageSize"
+                  @pagination="getList"
+      />
+    </div>
+    <!--新增弹窗-->
+    <el-dialog class="iotHardware-dialog" :title='dialogTitle' width="540px" append-to-body
+               :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
+               :close-on-click-modal="false" :close-on-press-escape="false">
+      <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-info" @click="dialogOff()">取消</p>
+        <p class="dialog-footer-button-primary" @click="dialogSubmit">确定</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'index',
+    data(){
+      return{
+        loading:false,
+        options:[{label:'启用',value:true},{label:'停用',value:false}],
+        queryParams:{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          jobGroup:null,
+          queryData2:null,
+        },
+        dataList:[],
+        total:0,
+        dialogTitle:null,
+        dialogType:false,
+        dialogForm:{},
+      }
+    },
+    created(){
+
+    },
+    mounted(){
+
+    },
+    methods:{
+      //弹层关闭
+      dialogOff(){
+        this.$set(this,'dialogType',false);
+      },
+      //弹层开启
+      dialogOpen(){
+        this.dialogFormReset();
+        this.$set(this,'dialogTitle','新增');
+        this.$set(this,'dialogType',true);
+      },
+      //弹层确定
+      dialogSubmit(){
+        this.$set(this,'dialogType',false);
+      },
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      resetQuery(){
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          queryData2:null,
+        });
+        this.getList();
+      },
+      dialogFormReset(){
+        this.$set(this,'dialogForm',{
+
+        });
+      },
+      //获取数据列表
+      getList(){
+        // this.$set(this,'loading',true);
+        // listJobLog(this.queryParams).then(response => {
+        //   this.$set(this,'loading',false);
+        //   this.$set(this,'dataList',response.data.records);
+        //   this.$set(this,'total',response.data.total);
+        // });
+      },
+      tableButton(type,row){
+        if(type == 2){
+
+        }else if(type == 3){
+          this.dialogFormReset();
+        }else if(type == 4){
+
+        }
+      },
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .iotHardware{
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    .title-box{
+      padding-top:20px;
+      border-bottom:1px solid #dedede;
+      display: flex;
+    }
+    .content-box{
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      padding:20px;
+      overflow: hidden;
+    }
+  }
+</style>

+ 32 - 0
src/views/iotDevice/iotHome/index.vue

@@ -0,0 +1,32 @@
+<!--物联首页-->
+<template>
+  <div class="app-container iotHome">
+
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'index',
+    data(){
+      return{
+
+      }
+    },
+    created(){
+
+    },
+    mounted(){
+
+    },
+    methods(){
+
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .iotHome{
+
+  }
+</style>

+ 191 - 0
src/views/iotDevice/monitoringWarning/messageTemplate/index.vue

@@ -0,0 +1,191 @@
+<!--消息模板-->
+<template>
+  <div class="app-container messageTemplate">
+    <div class="title-box">
+      <el-form :model="queryParams" class="form-box" ref="queryForm"
+               :inline="true" style="width:100%;">
+        <el-form-item label="名称" prop="queryData1" label-width="90px">
+          <el-input
+            maxLength="30"
+            v-model="queryParams.queryData1"
+            placeholder="请输入"
+            clearable
+            style="width: 200px"
+          />
+        </el-form-item>
+        <el-form-item label="方式" prop="queryData2">
+          <el-select v-model="queryParams.queryData2" clearable placeholder="请选择" style="width: 200px">
+            <el-option
+              v-for="dict in options"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <p class="inquire-button-one" @click="handleQuery" style="margin-right:10px;">查询</p>
+          <p class="reset-button-one" @click="resetQuery">重置</p>
+        </el-form-item>
+        <el-form-item label="" prop="title" style="float: right">
+          <el-col :span="1.5" style="margin-right:10px;">
+            <p class="add-button-one-90"
+               @click="dialogOpen"
+            >新增</p>
+          </el-col>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="content-box">
+      <el-table v-loading="loading" border :data="dataList">
+        <el-table-column label="模板名称" width="80" align="left" prop="data1" />
+        <el-table-column label="方式" align="left" prop="data2" show-overflow-tooltip/>
+        <el-table-column label="类型" align="left" prop="data3" show-overflow-tooltip/>
+        <el-table-column label="说明" align="left" prop="data4" show-overflow-tooltip/>
+        <el-table-column label="状态" align="left" prop="data5" show-overflow-tooltip/>
+        <el-table-column label="创建时间" align="left" prop="data6" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.data6) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="left" class-name="small-padding fixed-width">
+          <template slot-scope="scope">
+            <div class="table-button-box">
+              <p class="table-button-null"></p>
+              <p class="table-button-p"
+                 @click="tableButton(2,scope.row)"
+              >详情</p>
+              <p class="table-button-p"
+                 @click="tableButton(3,scope.row)"
+              >编辑</p>
+              <p class="table-button-p"
+                 @click="tableButton(4,scope.row)"
+              >删除</p>
+              <p class="table-button-null"></p>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :page-sizes="[20, 30, 40, 50]"
+                  v-show="total>0"
+                  :total="total"
+                  :page.sync="queryParams.page"
+                  :limit.sync="queryParams.pageSize"
+                  @pagination="getList"
+      />
+    </div>
+    <!--新增弹窗-->
+    <el-dialog class="messageTemplate-dialog" :title='dialogTitle' width="540px" append-to-body
+               :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
+               :close-on-click-modal="false" :close-on-press-escape="false">
+      <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-info" @click="dialogOff()">取消</p>
+        <p class="dialog-footer-button-primary" @click="dialogSubmit">确定</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'index',
+    data(){
+      return{
+        loading:false,
+        options:[{label:'钉钉',value:1},{label:'微信',value:2},{label:'邮件',value:3},{label:'语音',value:4},{label:'短信',value:5},{label:'电话',value:6},],
+        queryParams:{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          jobGroup:null,
+          queryData2:null,
+        },
+        dataList:[],
+        total:0,
+        dialogTitle:null,
+        dialogType:false,
+        dialogForm:{},
+      }
+    },
+    created(){
+
+    },
+    mounted(){
+
+    },
+    methods:{
+      //弹层关闭
+      dialogOff(){
+        this.$set(this,'dialogType',false);
+      },
+      //弹层开启
+      dialogOpen(){
+        this.dialogFormReset();
+        this.$set(this,'dialogTitle','新增');
+        this.$set(this,'dialogType',true);
+      },
+      //弹层确定
+      dialogSubmit(){
+        this.$set(this,'dialogType',false);
+      },
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      resetQuery(){
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          queryData2:null,
+        });
+        this.getList();
+      },
+      dialogFormReset(){
+        this.$set(this,'dialogForm',{
+
+        });
+      },
+      //获取数据列表
+      getList(){
+        // this.$set(this,'loading',true);
+        // listJobLog(this.queryParams).then(response => {
+        //   this.$set(this,'loading',false);
+        //   this.$set(this,'dataList',response.data.records);
+        //   this.$set(this,'total',response.data.total);
+        // });
+      },
+      tableButton(type,row){
+        if(type == 2){
+
+        }else if(type == 3){
+          this.dialogFormReset();
+        }else if(type == 4){
+
+        }
+      },
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .messageTemplate{
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    .title-box{
+      padding-top:20px;
+      border-bottom:1px solid #dedede;
+      display: flex;
+    }
+    .content-box{
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      padding:20px;
+      overflow: hidden;
+    }
+  }
+</style>

+ 191 - 0
src/views/iotDevice/monitoringWarning/warningConfig/index.vue

@@ -0,0 +1,191 @@
+<!--告警配置-->
+<template>
+  <div class="app-container warningConfig">
+    <div class="title-box">
+      <el-form :model="queryParams" class="form-box" ref="queryForm"
+               :inline="true" style="width:100%;">
+        <el-form-item label="名称" prop="queryData1" label-width="90px">
+          <el-input
+            maxLength="30"
+            v-model="queryParams.queryData1"
+            placeholder="请输入"
+            clearable
+            style="width: 200px"
+          />
+        </el-form-item>
+        <el-form-item label="类型" prop="queryData2">
+          <el-select v-model="queryParams.queryData2" clearable placeholder="请选择" style="width: 200px">
+            <el-option
+              v-for="dict in options"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <p class="inquire-button-one" @click="handleQuery" style="margin-right:10px;">查询</p>
+          <p class="reset-button-one" @click="resetQuery">重置</p>
+        </el-form-item>
+        <el-form-item label="" prop="title" style="float: right">
+          <el-col :span="1.5" style="margin-right:10px;">
+            <p class="add-button-one-90"
+               @click="dialogOpen"
+            >新增</p>
+          </el-col>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="content-box">
+      <el-table v-loading="loading" border :data="dataList">
+        <el-table-column label="名称" width="80" align="left" prop="data1" />
+        <el-table-column label="类型" align="left" prop="data3" show-overflow-tooltip/>
+        <el-table-column label="级别" align="left" prop="data2" show-overflow-tooltip/>
+        <el-table-column label="联动场景" align="left" prop="data4" show-overflow-tooltip/>
+        <el-table-column label="状态" align="left" prop="data5" show-overflow-tooltip/>
+        <el-table-column label="创建时间" align="left" prop="data6" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.data6) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="left" class-name="small-padding fixed-width">
+          <template slot-scope="scope">
+            <div class="table-button-box">
+              <p class="table-button-null"></p>
+              <p class="table-button-p"
+                 @click="tableButton(2,scope.row)"
+              >详情</p>
+              <p class="table-button-p"
+                 @click="tableButton(3,scope.row)"
+              >编辑</p>
+              <p class="table-button-p"
+                 @click="tableButton(4,scope.row)"
+              >删除</p>
+              <p class="table-button-null"></p>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :page-sizes="[20, 30, 40, 50]"
+                  v-show="total>0"
+                  :total="total"
+                  :page.sync="queryParams.page"
+                  :limit.sync="queryParams.pageSize"
+                  @pagination="getList"
+      />
+    </div>
+    <!--新增弹窗-->
+    <el-dialog class="warningConfig-dialog" :title='dialogTitle' width="540px" append-to-body
+               :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
+               :close-on-click-modal="false" :close-on-press-escape="false">
+      <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-info" @click="dialogOff()">取消</p>
+        <p class="dialog-footer-button-primary" @click="dialogSubmit">确定</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'index',
+    data(){
+      return{
+        loading:false,
+        options:[{label:'设备监控',value:1},{label:'硬件维护',value:2},{label:'其他',value:3}],
+        queryParams:{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          jobGroup:null,
+          queryData2:null,
+        },
+        dataList:[],
+        total:0,
+        dialogTitle:null,
+        dialogType:false,
+        dialogForm:{},
+      }
+    },
+    created(){
+
+    },
+    mounted(){
+
+    },
+    methods:{
+      //弹层关闭
+      dialogOff(){
+        this.$set(this,'dialogType',false);
+      },
+      //弹层开启
+      dialogOpen(){
+        this.dialogFormReset();
+        this.$set(this,'dialogTitle','新增');
+        this.$set(this,'dialogType',true);
+      },
+      //弹层确定
+      dialogSubmit(){
+        this.$set(this,'dialogType',false);
+      },
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      resetQuery(){
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          queryData2:null,
+        });
+        this.getList();
+      },
+      dialogFormReset(){
+        this.$set(this,'dialogForm',{
+
+        });
+      },
+      //获取数据列表
+      getList(){
+        // this.$set(this,'loading',true);
+        // listJobLog(this.queryParams).then(response => {
+        //   this.$set(this,'loading',false);
+        //   this.$set(this,'dataList',response.data.records);
+        //   this.$set(this,'total',response.data.total);
+        // });
+      },
+      tableButton(type,row){
+        if(type == 2){
+
+        }else if(type == 3){
+          this.dialogFormReset();
+        }else if(type == 4){
+
+        }
+      },
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .warningConfig{
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    .title-box{
+      padding-top:20px;
+      border-bottom:1px solid #dedede;
+      display: flex;
+    }
+    .content-box{
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      padding:20px;
+      overflow: hidden;
+    }
+  }
+</style>

+ 204 - 0
src/views/iotDevice/monitoringWarning/warningLog/index.vue

@@ -0,0 +1,204 @@
+<!--告警记录-->
+<template>
+  <div class="app-container warningLog">
+    <div class="title-box">
+      <el-form :model="queryParams" class="form-box" ref="queryForm"
+               :inline="true" style="width:100%;">
+        <el-form-item label="关键词" prop="queryData1" label-width="90px">
+          <el-input
+            maxLength="30"
+            v-model="queryParams.queryData1"
+            placeholder="请输入关键词"
+            clearable
+            style="width: 200px"
+          />
+        </el-form-item>
+        <el-form-item label="告警时间" prop="dateRange">
+          <el-date-picker
+            :clearable="false"
+            v-model="dateRange"
+            size="small"
+            style="width: 240px"
+            value-format="yyyy-MM-dd"
+            type="daterange"
+            range-separator="-"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+          ></el-date-picker>
+        </el-form-item>
+        <el-form-item>
+          <p class="inquire-button-one" @click="handleQuery" style="margin-right:10px;">查询</p>
+          <p class="reset-button-one" @click="resetQuery">重置</p>
+        </el-form-item>
+        <el-form-item label="" prop="title" style="float: right">
+          <el-col :span="1.5" style="margin-right:10px;">
+            <p class="add-button-one-90"
+               @click="dialogOpen"
+            >新增</p>
+          </el-col>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="content-box">
+      <el-table v-loading="loading" border :data="dataList">
+        <el-table-column label="告警方式" width="80" align="left" prop="data1" />
+        <el-table-column label="级别" align="left" prop="data2" show-overflow-tooltip/>
+        <el-table-column label="消息" align="left" prop="data3" show-overflow-tooltip/>
+        <el-table-column label="接收人" align="left" prop="data4" show-overflow-tooltip/>
+        <el-table-column label="告警状态" align="left" prop="data5" show-overflow-tooltip/>
+        <el-table-column label="告警时间" align="left" prop="data6" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.data6) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="left" class-name="small-padding fixed-width">
+          <template slot-scope="scope">
+            <div class="table-button-box">
+              <p class="table-button-null"></p>
+              <p class="table-button-p"
+                 @click="tableButton(2,scope.row)"
+              >详情</p>
+              <p class="table-button-p"
+                 @click="tableButton(3,scope.row)"
+              >编辑</p>
+              <p class="table-button-p"
+                 @click="tableButton(4,scope.row)"
+              >删除</p>
+              <p class="table-button-null"></p>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :page-sizes="[20, 30, 40, 50]"
+                  v-show="total>0"
+                  :total="total"
+                  :page.sync="queryParams.page"
+                  :limit.sync="queryParams.pageSize"
+                  @pagination="getList"
+      />
+    </div>
+    <!--新增弹窗-->
+    <el-dialog class="warningLog-dialog" :title='dialogTitle' width="540px" append-to-body
+               :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
+               :close-on-click-modal="false" :close-on-press-escape="false">
+      <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-info" @click="dialogOff()">取消</p>
+        <p class="dialog-footer-button-primary" @click="dialogSubmit">确定</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'index',
+    data(){
+      return{
+        loading:false,
+        options:[{label:'启用',value:true},{label:'停用',value:false}],
+        dateRange:[],
+        queryParams:{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          jobGroup:null,
+          queryData2:null,
+        },
+        dataList:[],
+        total:0,
+        dialogTitle:null,
+        dialogType:false,
+        dialogForm:{},
+      }
+    },
+    created(){
+
+    },
+    mounted(){
+
+    },
+    methods:{
+      //弹层关闭
+      dialogOff(){
+        this.$set(this,'dialogType',false);
+      },
+      //弹层开启
+      dialogOpen(){
+        this.dialogFormReset();
+        this.$set(this,'dialogTitle','新增');
+        this.$set(this,'dialogType',true);
+      },
+      //弹层确定
+      dialogSubmit(){
+        this.$set(this,'dialogType',false);
+      },
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      resetQuery(){
+        this.$set(this,'dateRange',[])
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          queryData2:null,
+        });
+        this.getList();
+      },
+      dialogFormReset(){
+        this.$set(this,'dialogForm',{
+
+        });
+      },
+      //获取数据列表
+      getList(){
+        // this.$set(this,'loading',true);
+        // let obj = JSON.parse(JSON.stringify(this.queryParams))
+        // if(this.dateRange[0]){
+        //   obj.startTime = this.dateRange[0]+'T00:00:00'
+        //   obj.endTime = this.dateRange[1]+'T23:59:59'
+        // }else{
+        //   obj.startTime = "";
+        //   obj.endTime = "";
+        // }
+        // listJobLog(obj).then(response => {
+        //   this.$set(this,'loading',false);
+        //   this.$set(this,'dataList',response.data.records);
+        //   this.$set(this,'total',response.data.total);
+        // });
+      },
+      tableButton(type,row){
+        if(type == 2){
+
+        }else if(type == 3){
+          this.dialogFormReset();
+        }else if(type == 4){
+
+        }
+      },
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .warningLog{
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    .title-box{
+      padding-top:20px;
+      border-bottom:1px solid #dedede;
+      display: flex;
+    }
+    .content-box{
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      padding:20px;
+      overflow: hidden;
+    }
+  }
+</style>

+ 191 - 0
src/views/iotDevice/monitoringWarning/warningMode/index.vue

@@ -0,0 +1,191 @@
+<!--告警方式-->
+<template>
+  <div class="app-container warningMode">
+    <div class="title-box">
+      <el-form :model="queryParams" class="form-box" ref="queryForm"
+               :inline="true" style="width:100%;">
+        <el-form-item label="名称" prop="queryData1" label-width="90px">
+          <el-input
+            maxLength="30"
+            v-model="queryParams.queryData1"
+            placeholder="请输入"
+            clearable
+            style="width: 200px"
+          />
+        </el-form-item>
+        <el-form-item label="方式" prop="queryData2">
+          <el-select v-model="queryParams.queryData2" clearable placeholder="请选择" style="width: 200px">
+            <el-option
+              v-for="dict in options"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <p class="inquire-button-one" @click="handleQuery" style="margin-right:10px;">查询</p>
+          <p class="reset-button-one" @click="resetQuery">重置</p>
+        </el-form-item>
+        <el-form-item label="" prop="title" style="float: right">
+          <el-col :span="1.5" style="margin-right:10px;">
+            <p class="add-button-one-90"
+               @click="dialogOpen"
+            >新增</p>
+          </el-col>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="content-box">
+      <el-table v-loading="loading" border :data="dataList">
+        <el-table-column label="名称" width="80" align="left" prop="data1" />
+        <el-table-column label="方式" align="left" prop="data2" show-overflow-tooltip/>
+        <el-table-column label="类型" align="left" prop="data3" show-overflow-tooltip/>
+        <el-table-column label="说明" align="left" prop="data4" show-overflow-tooltip/>
+        <el-table-column label="状态" align="left" prop="data5" show-overflow-tooltip/>
+        <el-table-column label="创建时间" align="left" prop="data6" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.data6) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="left" class-name="small-padding fixed-width">
+          <template slot-scope="scope">
+            <div class="table-button-box">
+              <p class="table-button-null"></p>
+              <p class="table-button-p"
+                 @click="tableButton(2,scope.row)"
+              >详情</p>
+              <p class="table-button-p"
+                 @click="tableButton(3,scope.row)"
+              >编辑</p>
+              <p class="table-button-p"
+                 @click="tableButton(4,scope.row)"
+              >删除</p>
+              <p class="table-button-null"></p>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :page-sizes="[20, 30, 40, 50]"
+                  v-show="total>0"
+                  :total="total"
+                  :page.sync="queryParams.page"
+                  :limit.sync="queryParams.pageSize"
+                  @pagination="getList"
+      />
+    </div>
+    <!--新增弹窗-->
+    <el-dialog class="warningMode-dialog" :title='dialogTitle' width="540px" append-to-body
+               :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
+               :close-on-click-modal="false" :close-on-press-escape="false">
+      <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-info" @click="dialogOff()">取消</p>
+        <p class="dialog-footer-button-primary" @click="dialogSubmit">确定</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'index',
+    data(){
+      return{
+        loading:false,
+        options:[{label:'钉钉',value:1},{label:'微信',value:2},{label:'邮件',value:3},{label:'语音',value:4},{label:'短信',value:5},{label:'电话',value:6},],
+        queryParams:{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          jobGroup:null,
+          queryData2:null,
+        },
+        dataList:[],
+        total:0,
+        dialogTitle:null,
+        dialogType:false,
+        dialogForm:{},
+      }
+    },
+    created(){
+
+    },
+    mounted(){
+
+    },
+    methods:{
+      //弹层关闭
+      dialogOff(){
+        this.$set(this,'dialogType',false);
+      },
+      //弹层开启
+      dialogOpen(){
+        this.dialogFormReset();
+        this.$set(this,'dialogTitle','新增');
+        this.$set(this,'dialogType',true);
+      },
+      //弹层确定
+      dialogSubmit(){
+        this.$set(this,'dialogType',false);
+      },
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      resetQuery(){
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          queryData2:null,
+        });
+        this.getList();
+      },
+      dialogFormReset(){
+        this.$set(this,'dialogForm',{
+
+        });
+      },
+      //获取数据列表
+      getList(){
+        // this.$set(this,'loading',true);
+        // listJobLog(this.queryParams).then(response => {
+        //   this.$set(this,'loading',false);
+        //   this.$set(this,'dataList',response.data.records);
+        //   this.$set(this,'total',response.data.total);
+        // });
+      },
+      tableButton(type,row){
+        if(type == 2){
+
+        }else if(type == 3){
+          this.dialogFormReset();
+        }else if(type == 4){
+
+        }
+      },
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .warningMode{
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    .title-box{
+      padding-top:20px;
+      border-bottom:1px solid #dedede;
+      display: flex;
+    }
+    .content-box{
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      padding:20px;
+      overflow: hidden;
+    }
+  }
+</style>

+ 204 - 0
src/views/iotDevice/operationManagement/iotLogs/index.vue

@@ -0,0 +1,204 @@
+<!--物联日志-->
+<template>
+  <div class="app-container iotLogs">
+    <div class="title-box">
+      <el-form :model="queryParams" class="form-box" ref="queryForm"
+               :inline="true" style="width:100%;">
+        <el-form-item label="关键词" prop="queryData1" label-width="90px">
+          <el-input
+            maxLength="30"
+            v-model="queryParams.queryData1"
+            placeholder="请输入关键词"
+            clearable
+            style="width: 200px"
+          />
+        </el-form-item>
+        <el-form-item label="请求时间" prop="dateRange">
+          <el-date-picker
+            :clearable="false"
+            v-model="dateRange"
+            size="small"
+            style="width: 240px"
+            value-format="yyyy-MM-dd"
+            type="daterange"
+            range-separator="-"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+          ></el-date-picker>
+        </el-form-item>
+        <el-form-item>
+          <p class="inquire-button-one" @click="handleQuery" style="margin-right:10px;">查询</p>
+          <p class="reset-button-one" @click="resetQuery">重置</p>
+        </el-form-item>
+        <el-form-item label="" prop="title" style="float: right">
+          <el-col :span="1.5" style="margin-right:10px;">
+            <p class="add-button-one-90"
+               @click="dialogOpen"
+            >新增</p>
+          </el-col>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="content-box">
+      <el-table v-loading="loading" border :data="dataList">
+        <el-table-column label="设备名称" width="80" align="left" prop="data1" />
+        <el-table-column label="ip" align="left" prop="data2" show-overflow-tooltip/>
+        <el-table-column label="请求路径" align="left" prop="data3" show-overflow-tooltip/>
+        <el-table-column label="请求方法" align="left" prop="data4" show-overflow-tooltip/>
+        <el-table-column label="请求时间" align="left" prop="data5" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.data5) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="请求人" align="left" prop="data6" show-overflow-tooltip/>
+        <el-table-column label="操作" align="left" class-name="small-padding fixed-width">
+          <template slot-scope="scope">
+            <div class="table-button-box">
+              <p class="table-button-null"></p>
+              <p class="table-button-p"
+                 @click="tableButton(2,scope.row)"
+              >详情</p>
+              <p class="table-button-p"
+                 @click="tableButton(3,scope.row)"
+              >编辑</p>
+              <p class="table-button-p"
+                 @click="tableButton(4,scope.row)"
+              >删除</p>
+              <p class="table-button-null"></p>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :page-sizes="[20, 30, 40, 50]"
+                  v-show="total>0"
+                  :total="total"
+                  :page.sync="queryParams.page"
+                  :limit.sync="queryParams.pageSize"
+                  @pagination="getList"
+      />
+    </div>
+    <!--新增弹窗-->
+    <el-dialog class="iotLogs-dialog" :title='dialogTitle' width="540px" append-to-body
+               :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
+               :close-on-click-modal="false" :close-on-press-escape="false">
+      <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-info" @click="dialogOff()">取消</p>
+        <p class="dialog-footer-button-primary" @click="dialogSubmit">确定</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'index',
+    data(){
+      return{
+        loading:false,
+        options:[{label:'启用',value:true},{label:'停用',value:false}],
+        dateRange:[],
+        queryParams:{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          jobGroup:null,
+          queryData2:null,
+        },
+        dataList:[],
+        total:0,
+        dialogTitle:null,
+        dialogType:false,
+        dialogForm:{},
+      }
+    },
+    created(){
+
+    },
+    mounted(){
+
+    },
+    methods:{
+      //弹层关闭
+      dialogOff(){
+        this.$set(this,'dialogType',false);
+      },
+      //弹层开启
+      dialogOpen(){
+        this.dialogFormReset();
+        this.$set(this,'dialogTitle','新增');
+        this.$set(this,'dialogType',true);
+      },
+      //弹层确定
+      dialogSubmit(){
+        this.$set(this,'dialogType',false);
+      },
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      resetQuery(){
+        this.$set(this,'dateRange',[])
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          queryData2:null,
+        });
+        this.getList();
+      },
+      dialogFormReset(){
+        this.$set(this,'dialogForm',{
+
+        });
+      },
+      //获取数据列表
+      getList(){
+        // this.$set(this,'loading',true);
+        // let obj = JSON.parse(JSON.stringify(this.queryParams))
+        // if(this.dateRange[0]){
+        //   obj.startTime = this.dateRange[0]+'T00:00:00'
+        //   obj.endTime = this.dateRange[1]+'T23:59:59'
+        // }else{
+        //   obj.startTime = "";
+        //   obj.endTime = "";
+        // }
+        // listJobLog(obj).then(response => {
+        //   this.$set(this,'loading',false);
+        //   this.$set(this,'dataList',response.data.records);
+        //   this.$set(this,'total',response.data.total);
+        // });
+      },
+      tableButton(type,row){
+        if(type == 2){
+
+        }else if(type == 3){
+          this.dialogFormReset();
+        }else if(type == 4){
+
+        }
+      },
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .iotLogs{
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    .title-box{
+      padding-top:20px;
+      border-bottom:1px solid #dedede;
+      display: flex;
+    }
+    .content-box{
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      padding:20px;
+      overflow: hidden;
+    }
+  }
+</style>

+ 191 - 0
src/views/iotDevice/operationManagement/networkComponent/index.vue

@@ -0,0 +1,191 @@
+<!--网络组件-->
+<template>
+  <div class="app-container networkComponent">
+    <div class="title-box">
+      <el-form :model="queryParams" class="form-box" ref="queryForm"
+               :inline="true" style="width:100%;">
+        <el-form-item label="关键词" prop="queryData1" label-width="90px">
+          <el-input
+            maxLength="30"
+            v-model="queryParams.queryData1"
+            placeholder="请输入关键词"
+            clearable
+            style="width: 200px"
+          />
+        </el-form-item>
+        <el-form-item label="设备类型" prop="queryData2">
+          <el-select v-model="queryParams.queryData2" clearable placeholder="请选择" style="width: 200px">
+            <el-option
+              v-for="dict in options"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <p class="inquire-button-one" @click="handleQuery" style="margin-right:10px;">查询</p>
+          <p class="reset-button-one" @click="resetQuery">重置</p>
+        </el-form-item>
+        <el-form-item label="" prop="title" style="float: right">
+          <el-col :span="1.5" style="margin-right:10px;">
+            <p class="add-button-one-90"
+               @click="dialogOpen"
+            >新增</p>
+          </el-col>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="content-box">
+      <el-table v-loading="loading" border :data="dataList">
+        <el-table-column label="名称" width="80" align="left" prop="data1" />
+        <el-table-column label="类型" align="left" prop="data2" show-overflow-tooltip/>
+        <el-table-column label="详情" align="left" prop="data3" show-overflow-tooltip/>
+        <el-table-column label="说明" align="left" prop="data4" show-overflow-tooltip/>
+        <el-table-column label="状态" align="left" prop="data5" show-overflow-tooltip/>
+        <el-table-column label="创建时间" align="left" prop="data6" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.data6) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="left" class-name="small-padding fixed-width">
+          <template slot-scope="scope">
+            <div class="table-button-box">
+              <p class="table-button-null"></p>
+              <p class="table-button-p"
+                 @click="tableButton(2,scope.row)"
+              >详情</p>
+              <p class="table-button-p"
+                 @click="tableButton(3,scope.row)"
+              >编辑</p>
+              <p class="table-button-p"
+                 @click="tableButton(4,scope.row)"
+              >删除</p>
+              <p class="table-button-null"></p>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :page-sizes="[20, 30, 40, 50]"
+                  v-show="total>0"
+                  :total="total"
+                  :page.sync="queryParams.page"
+                  :limit.sync="queryParams.pageSize"
+                  @pagination="getList"
+      />
+    </div>
+    <!--新增弹窗-->
+    <el-dialog class="networkComponent-dialog" :title='dialogTitle' width="540px" append-to-body
+               :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
+               :close-on-click-modal="false" :close-on-press-escape="false">
+      <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-info" @click="dialogOff()">取消</p>
+        <p class="dialog-footer-button-primary" @click="dialogSubmit">确定</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'index',
+    data(){
+      return{
+        loading:false,
+        options:[{label:'启用',value:true},{label:'停用',value:false}],
+        queryParams:{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          jobGroup:null,
+          queryData2:null,
+        },
+        dataList:[],
+        total:0,
+        dialogTitle:null,
+        dialogType:false,
+        dialogForm:{},
+      }
+    },
+    created(){
+
+    },
+    mounted(){
+
+    },
+    methods:{
+      //弹层关闭
+      dialogOff(){
+        this.$set(this,'dialogType',false);
+      },
+      //弹层开启
+      dialogOpen(){
+        this.dialogFormReset();
+        this.$set(this,'dialogTitle','新增');
+        this.$set(this,'dialogType',true);
+      },
+      //弹层确定
+      dialogSubmit(){
+        this.$set(this,'dialogType',false);
+      },
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      resetQuery(){
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          queryData2:null,
+        });
+        this.getList();
+      },
+      dialogFormReset(){
+        this.$set(this,'dialogForm',{
+
+        });
+      },
+      //获取数据列表
+      getList(){
+        // this.$set(this,'loading',true);
+        // listJobLog(this.queryParams).then(response => {
+        //   this.$set(this,'loading',false);
+        //   this.$set(this,'dataList',response.data.records);
+        //   this.$set(this,'total',response.data.total);
+        // });
+      },
+      tableButton(type,row){
+        if(type == 2){
+
+        }else if(type == 3){
+          this.dialogFormReset();
+        }else if(type == 4){
+
+        }
+      },
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .networkComponent{
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    .title-box{
+      padding-top:20px;
+      border-bottom:1px solid #dedede;
+      display: flex;
+    }
+    .content-box{
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      padding:20px;
+      overflow: hidden;
+    }
+  }
+</style>

+ 190 - 0
src/views/iotDevice/operationManagement/protocolManagement/index.vue

@@ -0,0 +1,190 @@
+<!--协议管理-->
+<template>
+  <div class="app-container protocolManagement">
+    <div class="title-box">
+      <el-form :model="queryParams" class="form-box" ref="queryForm"
+               :inline="true" style="width:100%;">
+        <el-form-item label="关键词" prop="queryData1" label-width="90px">
+          <el-input
+            maxLength="30"
+            v-model="queryParams.queryData1"
+            placeholder="请输入关键词"
+            clearable
+            style="width: 200px"
+          />
+        </el-form-item>
+        <el-form-item label="设备类型" prop="queryData2">
+          <el-select v-model="queryParams.queryData2" clearable placeholder="请选择" style="width: 200px">
+            <el-option
+              v-for="dict in options"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <p class="inquire-button-one" @click="handleQuery" style="margin-right:10px;">查询</p>
+          <p class="reset-button-one" @click="resetQuery">重置</p>
+        </el-form-item>
+        <el-form-item label="" prop="title" style="float: right">
+          <el-col :span="1.5" style="margin-right:10px;">
+            <p class="add-button-one-90"
+               @click="dialogOpen"
+            >新增</p>
+          </el-col>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="content-box">
+      <el-table v-loading="loading" border :data="dataList">
+        <el-table-column label="名称" width="80" align="left" prop="data1" />
+        <el-table-column label="类型" align="left" prop="data2" show-overflow-tooltip/>
+        <el-table-column label="文件地址" align="left" prop="data3" show-overflow-tooltip/>
+        <el-table-column label="状态" align="left" prop="data4" show-overflow-tooltip/>
+        <el-table-column label="创建时间" align="left" prop="data5" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.data5) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="left" class-name="small-padding fixed-width">
+          <template slot-scope="scope">
+            <div class="table-button-box">
+              <p class="table-button-null"></p>
+              <p class="table-button-p"
+                 @click="tableButton(2,scope.row)"
+              >详情</p>
+              <p class="table-button-p"
+                 @click="tableButton(3,scope.row)"
+              >编辑</p>
+              <p class="table-button-p"
+                 @click="tableButton(4,scope.row)"
+              >删除</p>
+              <p class="table-button-null"></p>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :page-sizes="[20, 30, 40, 50]"
+                  v-show="total>0"
+                  :total="total"
+                  :page.sync="queryParams.page"
+                  :limit.sync="queryParams.pageSize"
+                  @pagination="getList"
+      />
+    </div>
+    <!--新增弹窗-->
+    <el-dialog class="protocolManagement-dialog" :title='dialogTitle' width="540px" append-to-body
+               :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
+               :close-on-click-modal="false" :close-on-press-escape="false">
+      <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-info" @click="dialogOff()">取消</p>
+        <p class="dialog-footer-button-primary" @click="dialogSubmit">确定</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'index',
+    data(){
+      return{
+        loading:false,
+        options:[{label:'启用',value:true},{label:'停用',value:false}],
+        queryParams:{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          jobGroup:null,
+          queryData2:null,
+        },
+        dataList:[],
+        total:0,
+        dialogTitle:null,
+        dialogType:false,
+        dialogForm:{},
+      }
+    },
+    created(){
+
+    },
+    mounted(){
+
+    },
+    methods:{
+      //弹层关闭
+      dialogOff(){
+        this.$set(this,'dialogType',false);
+      },
+      //弹层开启
+      dialogOpen(){
+        this.dialogFormReset();
+        this.$set(this,'dialogTitle','新增');
+        this.$set(this,'dialogType',true);
+      },
+      //弹层确定
+      dialogSubmit(){
+        this.$set(this,'dialogType',false);
+      },
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      resetQuery(){
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          queryData1:"",
+          queryData2:null,
+        });
+        this.getList();
+      },
+      dialogFormReset(){
+        this.$set(this,'dialogForm',{
+
+        });
+      },
+      //获取数据列表
+      getList(){
+        // this.$set(this,'loading',true);
+        // listJobLog(this.queryParams).then(response => {
+        //   this.$set(this,'loading',false);
+        //   this.$set(this,'dataList',response.data.records);
+        //   this.$set(this,'total',response.data.total);
+        // });
+      },
+      tableButton(type,row){
+        if(type == 2){
+
+        }else if(type == 3){
+          this.dialogFormReset();
+        }else if(type == 4){
+
+        }
+      },
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .protocolManagement{
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    .title-box{
+      padding-top:20px;
+      border-bottom:1px solid #dedede;
+      display: flex;
+    }
+    .content-box{
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      padding:20px;
+      overflow: hidden;
+    }
+  }
+</style>

+ 287 - 21
src/views/serviceCenter/certificationManagement/certificationAccredit/index.vue

@@ -15,8 +15,8 @@
         </el-form-item>
         <el-form-item label="状态" prop="state" label-width="60px">
           <el-select v-model="queryParams.state" clearable placeholder="请选择分类" style="width: 200px">
-            <el-option :value="true">启用</el-option>
-            <el-option :value="false">停用</el-option>
+            <el-option :value="true" label="启用"></el-option>
+            <el-option :value="false" label="停用"></el-option>
           </el-select>
         </el-form-item>
         <el-form-item label="创建时间" prop="dateRange">
@@ -40,30 +40,51 @@
           <el-col :span="1.5" style="margin-right:10px;">
             <p class="add-button-one-90"
                @click="dialogOpen"
-            ><i class="el-icon-plus"></i>新增</p>
+            >新增</p>
           </el-col>
         </el-form-item>
       </el-form>
     </div>
     <div class="content-box">
       <el-table v-loading="loading" border :data="tableList" ref="multipleTable">
-        <el-table-column label="平台/企业" align="center" prop="fileName" show-overflow-tooltip/>
-        <el-table-column label="昵称" align="center" prop="fileSize" show-overflow-tooltip width="120"/>
-        <el-table-column label="联系人" align="center" prop="fileSize" show-overflow-tooltip width="120"/>
-        <el-table-column label="联系电话" align="center" prop="fileSize" show-overflow-tooltip width="200"/>
-        <el-table-column label="状态" align="center" prop="state" show-overflow-tooltip width="100">
+        <el-table-column label="平台/企业" align="center" prop="customerName" show-overflow-tooltip/>
+        <el-table-column label="appId" align="center" prop="appId" show-overflow-tooltip width="200">
+          <template slot-scope="scope">
+            <p class="clickCopy" @click="clickCopy(scope.row.appId,'appId')">{{scope.row.appId}}</p>
+          </template>
+        </el-table-column>
+        <el-table-column label="密钥" align="center" prop="secret" show-overflow-tooltip width="300">
+          <template slot-scope="scope">
+            <p class="clickCopy" @click="clickCopy(scope.row.secret,'密钥')">{{scope.row.secret}}</p>
+          </template>
+        </el-table-column>
+        <el-table-column label="授权类型" align="center" prop="grantType" show-overflow-tooltip width="120">
+          <template slot-scope="scope">
+            {{scope.row.grantType == 1?'指定时间':'永久有效'}}
+          </template>
+        </el-table-column>
+        <el-table-column label="授权时间" align="center" prop="createTime" show-overflow-tooltip width="180">
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.createTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="过期时间" align="center" prop="expireTime" show-overflow-tooltip width="180">
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.expireTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="状态" align="center" prop="state" show-overflow-tooltip width="80">
           <template slot-scope="scope">
             {{scope.row.state?'启用':'停用'}}
           </template>
         </el-table-column>
-        <el-table-column label="备注" align="center" prop="fileSize" show-overflow-tooltip width="240"/>
-        <el-table-column label="创建时间" align="center" prop="fileSize" show-overflow-tooltip width="120"/>
-        <el-table-column label="操作" align="center" prop="deptName" width="140">
+        <el-table-column label="操作" align="center" prop="deptName" width="200">
           <template slot-scope="scope">
             <div class="table-button-box">
               <p class="table-button-null"></p>
               <p class="table-button-p" @click="tableButton(1,scope.row)">编辑</p>
-              <p class="table-button-p" @click="tableButton(2,scope.row)">删除</p>
+              <p class="table-button-p" @click="tableButton(2,scope.row)">重置密钥</p>
+              <p class="table-button-p" @click="tableButton(3,scope.row)">删除</p>
               <p class="table-button-null"></p>
             </div>
           </template>
@@ -78,10 +99,83 @@
       />
     </div>
     <!--新增弹窗-->
-    <el-dialog class="trainingCourseAddDialog" :title='dialogTitle' width="540px"
+    <el-dialog class="certificationAccreditDialog" :title='dialogTitle' width="560px" append-to-body
                :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
                :close-on-click-modal="false" :close-on-press-escape="false">
-
+      <el-form  v-loading="loading" :rules="dialogRules"
+                :model="dialogForm" ref="dialogForm" label-width="100px">
+        <el-form-item label="平台/企业" prop="customerId">
+          <el-select
+            :disabled="dialogForm.id"
+            style="width:400px;"
+            v-model="dialogForm.customerId"
+            filterable
+            remote
+            clearable
+            reserve-keyword
+            placeholder="请输入平台/企业名称"
+            :remote-method="authCustomerDropList"
+            :loading="loading">
+            <el-option
+              v-for="item in dropList"
+              :key="item.customerId"
+              :label="item.customerName"
+              :value="item.customerId">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <div class="form-table-box">
+          <div class="form-table-title-box">
+            <span>*</span>
+            授权接口
+          </div>
+          <div class="for-api-max-box scrollbar-box">
+            <el-form-item label=""  label-width="0"
+                          :prop="'grantApis.'+ index +'.api'" :rules="dialogRules.api"
+                          v-for="(item,index) in dialogForm.grantApis" :key="index">
+              <div class="for-api-box">
+                <el-input
+                  v-model="item.api"
+                  maxLength="10"
+                  placeholder="请输入授权接口"
+                  clearable
+                  style="width: 300px"
+                />
+                <p class="el-icon-circle-plus-outline" @click="addApi"></p>
+                <p class="el-icon-remove-outline" @click="delApi(index)" v-if="dialogForm.grantApis[1]"></p>
+              </div>
+            </el-form-item>
+          </div>
+        </div>
+        <el-form-item label="授权类型" prop="grantType">
+          <el-select v-model="dialogForm.grantType" clearable placeholder="请选择授权类型" style="width: 400px">
+            <el-option v-for="item in grantTypeList" :value="item.value" :label="item.label"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="过期时间" prop="expireTime" v-if="dialogForm.grantType == 1">
+          <el-date-picker
+            v-model="dialogForm.expireTime"
+            value-format="yyyy-MM-dd"
+            type="date"
+            style="width:400px;"
+            :picker-options="pickerOptions"
+            placeholder="请选择过期时间">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="状态" prop="state" style="width:400px;">
+          <el-radio v-model="dialogForm.state" :label="true">启用</el-radio>
+          <el-radio v-model="dialogForm.state" :label="false">禁用</el-radio>
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input
+            v-model="dialogForm.remark"
+            maxLength="20"
+            placeholder="请输入备注"
+            clearable
+            style="width: 400px"
+          />
+        </el-form-item>
+      </el-form>
       <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
         <p class="dialog-footer-button-null"></p>
         <p class="dialog-footer-button-info" @click="dialogOff()">取消</p>
@@ -93,12 +187,16 @@
 </template>
 
 <script>
+  import { authLicenseList,authLicenseDelete,authLicenseDetail,authLicenseSetup,authLicenseSecret } from "@/api/serviceCenter/index";
+  import { authCustomerDropList } from "@/api/commonality/permission";
   export default {
     name: 'index',
     data(){
       return{
         loading:false,
         optionList:[{label:"启用",value:true},{label:"禁用",value:false}],
+        grantTypeList:[{label:"指定时间",value:1},{label:"永久有效",value:2}],
+        dropList:[],
         queryParams:{
           page:1,
           pageSize:20,
@@ -110,11 +208,38 @@
         total:0,
         //dialog弹层数据
         dialogTitle:"",
+        dialogForm:{},
+        dialogRules:{
+          customerId: [
+            { required: true, message: "请选择平台/企业", trigger: "blur" },
+            { required: true, message: "请选择平台/企业", validator: this.spaceJudgment, trigger: "blur" }
+          ],
+          api: [
+            { required: true, message: "请输入授权接口", trigger: "blur" },
+            { required: true, message: "请输入授权接口", validator: this.spaceJudgment, trigger: "blur" }
+          ],
+          grantType: [
+            { required: true, message: "请选择授权类型", trigger: "blur" },
+          ],
+          expireTime: [
+            { required: true, message: "请选择过期时间", trigger: "blur" },
+          ],
+          state: [
+            { required: true, message: "请选择状态", trigger: "blur" },
+          ],
+        },
         dialogType:false,
+        // 设置只能选择当前日期及之后的日期
+        pickerOptions: {
+          disabledDate(time) {
+            return time.getTime() < Date.now() - 8.64e7;//如果没有后面的-8.64e7就是不可以选择今天的
+          }
+        },
       }
     },
     created(){
-      // this.getList();
+      this.authCustomerDropList();
+      this.getList();
     },
     mounted(){
 
@@ -126,12 +251,37 @@
       },
       //弹层开启
       dialogOpen(){
-        this.$set(this,'dialogTitle','新增');
+        this.dialogFormReset();
+        this.$set(this,'dialogTitle','添加授权');
         this.$set(this,'dialogType',true);
       },
       //弹层确定
       dialogSubmit(){
-        this.$set(this,'dialogType',false);
+        let self = this;
+        this.$refs["dialogForm"].validate(valid => {
+          if (valid) {
+            let obj = {
+              customerId:this.dialogForm.customerId,
+              grantType:this.dialogForm.grantType,
+              expireTime:this.dialogForm.grantType == 1 ? this.dialogForm.expireTime + 'T23:59:59' : '2099-12-31T23:59:59',
+              state:this.dialogForm.state,
+              remark:this.dialogForm.remark,
+            };
+            obj.grantApis = [];
+            for(let i=0;i<self.dialogForm.grantApis.length;i++){
+              obj.grantApis.push(self.dialogForm.grantApis[i].api);
+            }
+            obj.grantApis = obj.grantApis + '';
+            if(this.dialogForm.id){
+              obj.id = this.dialogForm.id
+            }
+            authLicenseSetup(obj).then(response => {
+              this.msgSuccess(response.message)
+              this.getList();
+              this.$set(this,'dialogType',false);
+            });
+          }
+        })
       },
       handleQuery(){
         this.$set(this.queryParams,'page',1);
@@ -158,15 +308,93 @@
           obj.startTime = "";
           obj.endTime = "";
         }
-        tenantList(obj).then(response => {
+        authLicenseList(obj).then(response => {
           this.$set(this,'loading',false);
           this.$set(this,'tableList',response.data.records);
           this.$set(this,'total',response.data.total);
         });
       },
-      //预览
-      tableButton(){
-
+      //认证信息下拉列表
+      authCustomerDropList(name){
+        let obj = {
+          customerName:name,
+        };
+        this.$set(this,'loading',true);
+        authCustomerDropList(obj).then(response => {
+          this.$set(this,'loading',false);
+          this.$set(this,'dropList',response.data);
+        });
+      },
+      //表格按钮
+      tableButton(type,row){
+        let self = this;
+        if(type == 1){
+          authLicenseDetail({id:row.id}).then(response => {
+            this.dialogFormReset();
+            this.$set(this,'dialogTitle','编辑授权');
+            let list = response.data.grantApis.split(',');
+            let newList = [];
+            for(let i=0;i<list.length;i++){
+              newList.push({api:list[i]});
+            }
+            this.$set(this,'dialogForm',{
+              id:response.data.id,
+              customerId:response.data.appId,
+              grantApis:newList,
+              grantType:response.data.grantType,
+              expireTime:response.data.expireTime,
+              state:response.data.state,
+              remark:response.data.remark,
+            });
+            this.$set(this,'dialogType',true);
+          });
+        }else if(type == 2){
+          //重置密钥
+          this.$confirm('是否确认重置密钥?', "警告", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          }).then(function() {
+          }).then(() => {
+            authLicenseSecret({id:row.id}).then(response => {
+              self.msgSuccess(response.message)
+              self.getList();
+            });
+          }).catch(() => {});
+        }else if(type == 3){
+          //删除
+          this.$confirm('是否确认删除?', "警告", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          }).then(function() {
+          }).then(() => {
+            authLicenseDelete({id:row.id}).then(response => {
+              self.msgSuccess(response.message)
+              self.getList();
+            });
+          }).catch(() => {});
+        }
+      },
+      dialogFormReset(){
+        this.$set(this,'dialogForm',{
+          customerId:'',
+          grantApis:[{api:''}],
+          grantType:'',
+          birthday:'',
+          state:true,
+          remark:'',
+        });
+      },
+      addApi(){
+        if (!this.dialogForm.grantApis[99]){
+          this.dialogForm.grantApis.push({api:''})
+        }else{
+          this.msgError('最多添加100个接口')
+        }
+      },
+      delApi(index){
+        this.dialogForm.grantApis.splice(index,1);
       },
     },
   }
@@ -191,3 +419,41 @@
   }
 }
 </style>
+<style lang="scss">
+  .certificationAccreditDialog{
+    .form-table-box{
+      display: flex;
+      .form-table-title-box{
+        width:88px;
+        text-align: right;
+        margin-right:12px;
+        line-height: 40px;
+        span{
+          color: #FF6666;
+        }
+      }
+      .for-api-max-box{
+        max-height:300px;
+        .for-api-box{
+          display: flex;
+          p{
+            width:40px;
+            height:40px;
+            font-size:18px;
+            text-align: center;
+            line-height:38px;
+            margin-left:10px;
+            cursor: pointer;
+            font-weight: 700;
+          }
+          .el-icon-circle-plus-outline{
+            color:#00a0e9;
+          }
+          .el-icon-remove-outline{
+            color:#FF6666;
+          }
+        }
+      }
+    }
+  }
+</style>

+ 170 - 16
src/views/serviceCenter/certificationManagement/certificationInfo/index.vue

@@ -15,8 +15,8 @@
         </el-form-item>
         <el-form-item label="状态" prop="state" label-width="60px">
           <el-select v-model="queryParams.state" clearable placeholder="请选择分类" style="width: 200px">
-            <el-option :value="true">启用</el-option>
-            <el-option :value="false">停用</el-option>
+            <el-option :value="true" label="启用"></el-option>
+            <el-option :value="false" label="停用"></el-option>
           </el-select>
         </el-form-item>
         <el-form-item label="创建时间" prop="dateRange">
@@ -40,24 +40,28 @@
           <el-col :span="1.5" style="margin-right:10px;">
             <p class="add-button-one-90"
                @click="dialogOpen"
-            ><i class="el-icon-plus"></i>新增</p>
+            >新增</p>
           </el-col>
         </el-form-item>
       </el-form>
     </div>
     <div class="content-box">
       <el-table v-loading="loading" border :data="tableList" ref="multipleTable">
-        <el-table-column label="平台/企业" align="center" prop="fileName" show-overflow-tooltip/>
-        <el-table-column label="昵称" align="center" prop="fileSize" show-overflow-tooltip width="120"/>
-        <el-table-column label="联系人" align="center" prop="fileSize" show-overflow-tooltip width="120"/>
-        <el-table-column label="联系电话" align="center" prop="fileSize" show-overflow-tooltip width="200"/>
+        <el-table-column label="平台/企业" align="center" prop="customerName" show-overflow-tooltip/>
+        <el-table-column label="昵称" align="center" prop="customerNickname" show-overflow-tooltip width="120"/>
+        <el-table-column label="联系人" align="center" prop="contact" show-overflow-tooltip width="120"/>
+        <el-table-column label="联系电话" align="center" prop="mobile" show-overflow-tooltip width="200"/>
         <el-table-column label="状态" align="center" prop="state" show-overflow-tooltip width="100">
           <template slot-scope="scope">
             {{scope.row.state?'启用':'停用'}}
           </template>
         </el-table-column>
-        <el-table-column label="备注" align="center" prop="fileSize" show-overflow-tooltip width="240"/>
-        <el-table-column label="创建时间" align="center" prop="fileSize" show-overflow-tooltip width="120"/>
+        <el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip width="240"/>
+        <el-table-column label="创建时间" align="left" prop="createTime" show-overflow-tooltip width="180">
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.createTime) }}</span>
+          </template>
+        </el-table-column>
         <el-table-column label="操作" align="center" prop="deptName" width="140">
           <template slot-scope="scope">
             <div class="table-button-box">
@@ -78,10 +82,60 @@
       />
     </div>
     <!--新增弹窗-->
-    <el-dialog class="trainingCourseAddDialog" :title='dialogTitle' width="540px"
+    <el-dialog class="trainingCourseAddDialog" :title='dialogTitle' width="560px" append-to-body
                :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
                :close-on-click-modal="false" :close-on-press-escape="false">
-
+      <el-form  v-loading="loading" :rules="dialogRules" :model="dialogForm" ref="dialogForm" label-width="100px">
+        <el-form-item label="平台/企业" prop="customerName">
+          <el-input
+            v-model="dialogForm.customerName"
+            maxLength="20"
+            placeholder="请输入平台/企业"
+            clearable
+            style="width: 400px"
+          />
+        </el-form-item>
+        <el-form-item label="昵称" prop="customerNickname">
+          <el-input
+            v-model="dialogForm.customerNickname"
+            maxLength="10"
+            placeholder="请输入昵称"
+            clearable
+            style="width: 400px"
+          />
+        </el-form-item>
+        <el-form-item label="联系人" prop="contact">
+          <el-input
+            v-model="dialogForm.contact"
+            maxLength="10"
+            placeholder="请输入联系人"
+            clearable
+            style="width: 400px"
+          />
+        </el-form-item>
+        <el-form-item label="电话" prop="mobile">
+          <el-input
+            v-model="dialogForm.mobile"
+            maxLength="11"
+            placeholder="请输入11位手机号码"
+            clearable
+            style="width: 400px"
+          />
+        </el-form-item>
+        <el-form-item label="状态" prop="state" style="width:400px;">
+          <el-radio v-model="dialogForm.state" :label="true">启用</el-radio>
+          <el-radio v-model="dialogForm.state" :label="false">禁用</el-radio>
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input
+            v-model="dialogForm.remark"
+            maxLength="20"
+            placeholder="请输入备注"
+            clearable
+            style="width: 400px"
+          />
+        </el-form-item>
+      </el-form>
       <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
         <p class="dialog-footer-button-null"></p>
         <p class="dialog-footer-button-info" @click="dialogOff()">取消</p>
@@ -93,6 +147,7 @@
 </template>
 
 <script>
+  import { authCustomerList,authCustomerAdd,authCustomerUpdate,authCustomerDelete,authCustomerDetail } from "@/api/serviceCenter/index";
   export default {
     name: 'index',
     data(){
@@ -110,11 +165,35 @@
         total:0,
         //dialog弹层数据
         dialogTitle:"",
+        dialogForm:{},
+        dialogRules:{
+          customerName: [
+            { required: true, message: "请输入平台/企业", trigger: "blur" },
+            { required: true, message: "请输入平台/企业", validator: this.spaceJudgment, trigger: "blur" }
+          ],
+          customerNickname: [
+            { required: true, message: "请输入昵称", trigger: "blur" },
+            { required: true, message: "请输入昵称", validator: this.spaceJudgment, trigger: "blur" }
+          ],
+          contact: [
+            { required: true, message: "请输入联系人", trigger: "blur" },
+            { required: true, message: "请输入联系人", validator: this.spaceJudgment, trigger: "blur" }
+          ],
+          mobile: [
+            { required: true, message: "请输入11位手机号码", trigger: "blur" },
+            { validator: this.checkPhone, trigger: 'blur' },
+            { required: true, message: "请输入11位手机号码", validator: this.spaceJudgment, trigger: "blur" }
+          ],
+          state: [
+            { required: true, message: "请选择状态", trigger: "blur" },
+            { required: true, message: "请选择状态", validator: this.spaceJudgment, trigger: "blur" }
+          ],
+        },
         dialogType:false,
       }
     },
     created(){
-      // this.getList();
+      this.getList();
     },
     mounted(){
 
@@ -126,12 +205,31 @@
       },
       //弹层开启
       dialogOpen(){
+        this.dialogFormReset();
         this.$set(this,'dialogTitle','新增');
         this.$set(this,'dialogType',true);
       },
       //弹层确定
       dialogSubmit(){
-        this.$set(this,'dialogType',false);
+        this.$refs["dialogForm"].validate(valid => {
+          if (valid) {
+            if(this.dialogForm.customerId){
+              let obj = JSON.parse(JSON.stringify(this.dialogForm))
+              authCustomerUpdate(obj).then(response => {
+                this.msgSuccess(response.message)
+                this.getList();
+                this.$set(this,'dialogType',false);
+              });
+            }else{
+              let obj = JSON.parse(JSON.stringify(this.dialogForm))
+              authCustomerAdd(obj).then(response => {
+                this.msgSuccess(response.message)
+                this.getList();
+                this.$set(this,'dialogType',false);
+              });
+            }
+          }
+        })
       },
       handleQuery(){
         this.$set(this.queryParams,'page',1);
@@ -158,15 +256,71 @@
           obj.startTime = "";
           obj.endTime = "";
         }
-        tenantList(obj).then(response => {
+        authCustomerList(obj).then(response => {
           this.$set(this,'loading',false);
           this.$set(this,'tableList',response.data.records);
           this.$set(this,'total',response.data.total);
         });
       },
       //预览
-      tableButton(){
-
+      tableButton(type,row){
+        let self = this;
+        if(type == 1){
+          //编辑
+          authCustomerDetail({id:row.customerId}).then(response => {
+            this.dialogFormReset();
+            this.$set(this,'dialogTitle','编辑');
+            this.$set(this,'dialogForm',{
+              customerId:response.data.customerId,
+              customerName:response.data.customerName,
+              customerNickname:response.data.customerNickname,
+              contact:response.data.contact,
+              mobile:response.data.mobile,
+              state:response.data.state,
+              remark:response.data.remark,
+            });
+            this.$set(this,'dialogType',true);
+          });
+        }else if(type == 2){
+          //删除
+          this.$confirm('是否确认删除?', "警告", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          }).then(function() {
+          }).then(() => {
+            authCustomerDelete({customerId:row.customerId}).then(response => {
+              self.msgSuccess(response.message)
+              self.getList();
+            });
+          }).catch(() => {});
+        }
+      },
+      dialogFormReset(){
+        this.$set(this,'dialogForm',{
+          customerName:'',
+          customerNickname:'',
+          contact:'',
+          mobile:'',
+          state:true,
+          remark:'',
+        });
+      },
+      //手机号验证
+      checkPhone(rule, value, callback) {
+        if (!value) {
+          return callback(new Error('手机号码不能为空'))
+        } else {
+          if(value == '19999999999'){
+            return callback(new Error('请输入正确的手机号码'))
+          }
+          const reg = /^1[3|4|5|7|8|9][0-9]\d{8}$/
+          if (reg.test(value)) {
+            callback()
+          } else {
+            return callback(new Error('请输入正确的手机号码'))
+          }
+        }
       },
     },
   }

+ 3 - 2
src/views/serviceCenter/merchantManagement/index.vue

@@ -68,7 +68,7 @@
         />
       </div>
       <!--新增弹窗-->
-      <el-dialog class="trainingCourseAddDialog" :title='dialogTitle' width="540px"
+      <el-dialog class="trainingCourseAddDialog" :title='dialogTitle' width="540px" append-to-body
                  :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
                   :close-on-click-modal="false" :close-on-press-escape="false">
 
@@ -83,7 +83,8 @@
 </template>
 
 <script>
-  import { tenantList,tenantDropList } from "@/api/serviceCenter/index";
+  import { tenantList } from "@/api/serviceCenter/index";
+  import { tenantDropList } from "@/api/commonality/permission";
   export default {
     name: 'merchantManagement',
     data(){

+ 1 - 1
src/views/serviceCenter/timingTask/index.vue

@@ -81,7 +81,7 @@
       />
     </div>
     <!--新增弹窗-->
-    <el-dialog class="trainingCourseAddDialog" :title='dialogTitle' width="540px"
+    <el-dialog class="trainingCourseAddDialog" :title='dialogTitle' width="540px" append-to-body
                :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
                :close-on-click-modal="false" :close-on-press-escape="false">
 

+ 1 - 1
src/views/systemManagement/filePreview/index.vue

@@ -47,7 +47,7 @@
         <el-table-column label="尺寸(MB)" align="center" prop="fileSize" show-overflow-tooltip width="130"/>
         <el-table-column label="文件地址" align="center" prop="fileUrl" show-overflow-tooltip width="470">
           <template slot-scope="scope">
-            <p @click="clickCopy(scope.row.fileUrl)">{{scope.row.fileUrl}}</p>
+            <p class="clickCopy" @click="clickCopy(scope.row.fileUrl,'文件地址')">{{scope.row.fileUrl}}</p>
           </template>
         </el-table-column>
         <el-table-column label="上传时间" align="center" prop="createTime" show-overflow-tooltip width="200"/>

+ 974 - 0
src/views/systemManagement/roleManagement/addPage.vue

@@ -0,0 +1,974 @@
+<template>
+  <div class="teacher-add-page" @click="checkedButton">
+    <div class="public-form-box scrollbar-box">
+      <!--
+      <div class="top-title-box">
+        <p>{{propsData.title}}</p>
+      </div>
+      <el-form :model="form" ref="form" :inline="true" :rules="rules" label-width="120px">
+        <div class="top-info-box">
+          <div class="right-info-box">
+            <el-form-item label="身份名称:" prop="roleName">
+              <el-input
+                style="width:250px;"
+                maxlength="50"
+                v-model="form.roleName"
+                placeholder="请输入身份名称"
+                clearable
+              />
+            </el-form-item>
+          </div>
+          <div class="right-info-box">
+            <el-form-item label="权限字符:" prop="roleKey" label-width="215px">
+              <el-input
+                style="width:250px;"
+                maxlength="50"
+                v-model="form.roleKey"
+                placeholder="请输入权限字符"
+                clearable
+              />
+            </el-form-item>
+          </div>
+        </div>
+        <div class="top-tow-box">
+          <p>权限配置</p>
+        </div>
+        <div class="data_scope">
+          <div class="data_scope_l">
+            <el-form-item label="数据范围:" prop="dataScope">
+              <el-select
+                style="width:250px;"
+                @visible-change="dataScopeFun"
+                v-model="form.dataScope"
+                placeholder="请选择数据范围"
+                clearable
+              >
+                <el-option
+                  v-for="item in optionsDataList"
+                  :key="item.type"
+                  :label="item.value"
+                  :value="item.type"
+                />
+              </el-select>
+            </el-form-item>
+          </div>
+          <div class="data_scope_r" @click="dataScopeClearFun">清除</div>
+        </div>
+      </el-form>
+      -->
+
+      <div class="top-title-box">
+        <p>权限配置</p>
+      </div>
+      <!--权限模块-->
+      <div class="table-for-max-box">
+        <div class="table-title-box">
+          <p>模块菜单</p>
+          <p>权限</p>
+        </div>
+        <div class="table-for-big-box" v-for="(maxItem,maxIndex) in menuList" :key="maxIndex">
+          <!--一级目录-->
+          <div class="max-title-box" :class="!maxItem.children?'max-title-box-null':''">
+            <p><el-checkbox v-model="maxItem.checked" @change="(type)=>itemCheckClick(type,maxItem)">{{maxItem.menuName}}</el-checkbox></p>
+          </div>
+          <div class="max-right-box">
+            <div class="big-box" v-for="(bigItem,bigIndex) in maxItem.children" :key="bigIndex">
+              <!--二级页面-->
+              <div class="big-title-box" :class="bigItem.menuType == '1'?'big-title-box-null':''">
+                <p><el-checkbox v-model="bigItem.checked" @change="(type)=>itemCheckClick(type,bigItem,maxItem)">{{bigItem.menuName}}</el-checkbox></p>
+              </div>
+              <!--三级页面/四级按钮-->
+              <div class="big-right-box" v-if="bigItem.menuType !='1'">
+                <div class="min-box" v-for="(minItem,minIndex) in bigItem.children" :key="minIndex">
+                  <div class="min-title-box">
+                    <!--三级页面-->
+                    <div class="title-left-box">
+                      <p class="min-title-box-null"></p>
+                      <p><el-checkbox v-model="minItem.checked" @change="(type)=>itemCheckClick(type,minItem,bigItem,maxItem)">{{minItem.menuName}}</el-checkbox></p>
+                      <p class="min-title-box-null"></p>
+                    </div>
+                  </div>
+                  <div class="min-right-box">
+                    <!--四级按钮-->
+                    <div v-for="(btnItem,btnIndex) in minItem.children">
+                      <el-checkbox v-model="btnItem.checked"
+                                   @change="(type)=>itemCheckClick(type,btnItem,minItem,bigItem,maxItem)">
+                        {{btnItem.menuName}}
+                      </el-checkbox>
+                    </div>
+                    <p v-if="!minItem.children" style="font-weight:500;color:#999;text-align: center">该页面没有按钮</p>
+                  </div>
+                </div>
+              </div>
+              <!--三级按钮-->
+              <div class="big-right-box-null" v-if="bigItem.menuType == '1'">
+                <div v-for="(btnItem,btnIndex) in bigItem.children">
+                  <el-checkbox v-model="btnItem.checked"
+                               @change="(type)=>itemCheckClick(type,btnItem,minItem,bigItem,maxItem)">
+                    {{btnItem.menuName}}
+                  </el-checkbox>
+                </div>
+                <p v-if="!bigItem.children" style="font-weight:500;color:#999;text-align: center">该页面没有按钮</p>
+              </div>
+            </div>
+            <p class="big-box-null" v-if="!maxItem.children&&maxItem.menuName == '数据可视化'">数据可视化大屏查看权限</p>
+          </div>
+        </div>
+      </div>
+      <el-dialog title="选择指定部门(可多选)" @close="deptCancel" :visible.sync="deptOpen"
+                 :close-on-click-modal="false" v-if="deptOpen" width="500px"
+                 append-to-body class="managePermissionTemplates-dept-dialog-box">
+        <el-form :model="deptForm" ref="deptForm" :inline="true" :rules="rules" class="addCheckPage-min">
+          <el-form-item label="指定部门" prop="deptIds" label-width="90px" class="el-form-item-bottom">
+            <el-cascader
+              style="width:300px;"
+              :options="treeselectList"
+              :props="{multiple: true,value: 'id', label: 'label'}"
+              collapse-tags
+              v-model="deptForm.deptIds"
+              clearable>
+            </el-cascader>
+          </el-form-item>
+        </el-form>
+        <div slot="footer" class="managePermissionTemplates-dept-dialog-button-box">
+          <p class="reset-button-one" @click="deptCancel">取消</p>
+          <p class="inquire-button-one" @click="deptSure">确定</p>
+        </div>
+      </el-dialog>
+    </div>
+    <div class="bottom-button-box">
+      <p class="null-p"></p>
+      <p class="button-p-1 reset-button-one" @click="outPageButton">返回</p>
+      <p class="inquire-button-one" @click="upDataButton">提交</p>
+      <p class="null-p"></p>
+    </div>
+  </div>
+</template>
+
+<script>
+import { addRoleByScope, editRoleByScope } from '@/apiDemo/system/role'
+import { listMenuAll} from "@/apiDemo/system/menu";
+import { treeselect } from "@/apiDemo/system/dept";
+
+import { systemRoleGetRoleMenu,systemRoleSaveRolePermission } from "@/api/systemManagement/index";
+export default {
+  name: "addPage",
+  props:{
+    propsData:{},
+  },
+  data() {
+    return {
+      menuList:[],
+      originalMenuList:[],
+      form:{
+        roleName:"",     //姓名
+        roleKey:"",
+        dataScope:null,
+      },
+      rules:{
+        roleName: [
+          { required: true, message: "请输入姓名", trigger: "blur" },
+          { required: true, message: "请输入姓名", validator: this.spaceJudgment, trigger: "blur" }
+        ],
+        roleKey: [
+          { required: true, message: "请输入权限标识", trigger: "blur" },
+          { required: true, message: "请输入权限标识", validator: this.spaceJudgment, trigger: "blur" }
+        ],
+        dataScope: [
+          { required: true, message: "请选择数据范围", trigger: "blur" },
+        ],
+        deptIds: [
+          { required: true, message: "请选择指定部门", trigger: "blur" },
+        ],
+      },
+      //数据范围(1:全部, 2:部门及下级, 3:本部门, 4:仅本人,5:自定义)
+      optionsDataList:[
+        {type: 1, value: "所有数据",},
+        {type: 2, value: "本部门及下级部门数据",},
+        {type: 3, value: "本部门",},
+        {type: 4, value: "当前账号数据",},
+        {type: 5, value: "自定义",},
+      ],
+      //数据范围部门弹窗
+      deptOpen:false,
+      deptOpenType:'',
+      //部门数据结构树
+      treeselectList:[],
+      //指定部门数据
+      deptForm:{
+        deptIds:[],
+      },
+      checkDeptType:null,
+      checkAllType:false,
+    }
+  },
+  created(){
+
+  },
+  mounted(){
+    this.getMenu();
+  },
+  methods:{
+    //提交按钮
+    upDataButton(){
+      let obj = {
+        roleId:this.propsData.roleId,
+        menuIds : this.toArray(),
+      }
+      systemRoleSaveRolePermission(obj).then(response => {
+        if(response.code == 200){
+          this.msgSuccess(response.message);
+          this.$parent.goPage(3);
+        }
+      });
+      // this.$refs["form"].validate(valid => {
+      //   if (valid) {
+      //     if(this.propsData.roleId){
+      //       //修改
+      //       this.editRoleByScope()
+      //     }else{
+      //       //发布
+      //       this.addRoleByScope()
+      //     }
+      //   }
+      // });
+    },
+    //新增
+    addRoleByScope(){
+      let self = this;
+      let obj = JSON.parse(JSON.stringify(this.form))
+      obj.roleSort = 1;
+      obj.menuCheckStrictly = 0;
+      obj.status = 0;
+      obj.menuIds = this.toArray();
+      obj.viewDeptIds = JSON.stringify(self.deptForm.deptIds);
+      obj.deptIds = [];
+      let list = [];
+      for(let i=0;i<self.deptForm.deptIds.length;i++){
+        for(let o=0;o<self.deptForm.deptIds[i].length;o++){
+          list.push(self.deptForm.deptIds[i][o])
+        }
+      }
+      for (var i = 0,len=list.length; i < len; i++) {
+        if(obj.deptIds.indexOf(list[i]) === -1){
+          obj.deptIds.push(list[i]);
+        }
+      }
+      addRoleByScope(obj).then(response => {
+        if(response.code == 200){
+          this.msgSuccess(response.msg);
+          this.$parent.goPage(3);
+        }
+      });
+    },
+    //编辑
+    editRoleByScope(){
+      let self = this;
+      let obj = JSON.parse(JSON.stringify(this.form))
+      obj.roleSort = 1;
+      obj.menuCheckStrictly = 0;
+      obj.status = 0;
+      obj.menuIds = this.toArray();
+      obj.viewDeptIds = JSON.stringify(self.deptForm.deptIds);
+      obj.deptIds = [];
+      let list = [];
+      for(let i=0;i<self.deptForm.deptIds.length;i++){
+        for(let o=0;o<self.deptForm.deptIds[i].length;o++){
+          list.push(self.deptForm.deptIds[i][o])
+        }
+      }
+      for (var i = 0,len=list.length; i < len; i++) {
+        if(obj.deptIds.indexOf(list[i]) === -1){
+          obj.deptIds.push(list[i]);
+        }
+      }
+      editRoleByScope(obj).then(response => {
+        if(response.code == 200){
+          this.msgSuccess(response.msg);
+          this.$parent.goPage(3);
+        }
+      });
+    },
+    checkedButton(){
+      this.$set(this,'checkAllType',false);
+    },
+    //数据范围选中
+    dataScopeFun(type){
+      let self = this;
+      console.log('dataScopeFun',self.form.dataScope)
+      if(!type){
+        setTimeout(function(){
+          if(self.checkAllType){
+            if(self.form.dataScope == 5){
+              //指定范围弹窗
+              self.$set(self,'deptOpen',true)
+            }else{
+              self.$set(self,'checkDeptType',self.form.dataScope)
+              self.$set(self.deptForm,'deptIds',[])
+            }
+          }
+        },50);
+      }else{
+        this.$set(this,'checkAllType',true);
+      }
+    },
+    //数据范围选择清除
+    dataScopeClearFun(){
+      this.$set(this.form,'dataScope',null)
+      this.$set(this.deptForm,'deptIds',[])
+    },
+    //指定部门弹窗取消
+    deptCancel(){
+      this.$set(this.form,'dataScope',this.checkDeptType)
+      this.$set(this,'deptOpen',false)
+    },
+    //指定部门弹窗确定
+    deptSure(){
+      this.$refs["deptForm"].validate(valid => {
+        if (valid) {
+          this.$set(this,'checkDeptType',this.form.dataScope)
+          this.$set(this,'deptOpen',false);
+        }
+      });
+    },
+    //模块勾选逻辑
+    itemCheckClick(type,item,minItem,bigItem,maxItem){
+      if(item.children){
+        for(let i=0;i<item.children.length;i++){
+          item.children[i].checked = !!type;
+          if(item.children[i].children){
+            for(let o=0;o<item.children[i].children.length;o++){
+              item.children[i].children[o].checked = !!type;
+              if(item.children[i].children[o].children){
+                for(let x=0;x<item.children[i].children[o].children.length;x++){
+                  item.children[i].children[o].children[x].checked = !!type;
+                }
+              }
+            }
+          }
+        }
+      }
+      if(minItem&&type){
+        minItem.checked = type;
+      }
+      if(bigItem&&type){
+        bigItem.checked = type;
+      }
+      if(maxItem&&type){
+        maxItem.checked = type;
+      }
+    },
+    getMenu() {
+      let self = this;
+      this.loading = true;
+      systemRoleGetRoleMenu({roleId:this.propsData.roleId}).then(response => {
+        let newList = JSON.parse(JSON.stringify(response.data));
+        // for(let i=0;i<response.data.length;i++){
+        //   if(response.data[i].status == 0 && response.data[i].visible == 0){
+        //     newList.push(response.data[i]);
+        //   }
+        // }
+        // if(this.propsData.type == 1){
+        //   //新增
+        //     this.menuList = JSON.parse(JSON.stringify(this.handleTree(newList, "menuId")))
+        // }else {
+        //   if(this.propsData.type == 2){
+        //     //编辑
+        //     this.$set(this.form,'roleId',this.propsData.roleId);
+        //     this.$set(this.form,'roleName',this.propsData.name);
+        //     this.$set(this.form,'roleKey',this.propsData.key);
+        //   }
+        //   //页面权限处理
+        //   for(let i=0;i<self.propsData.list.length;i++){
+        //     for(let o=0;o<newList.length;o++){
+        //       if(self.propsData.list[i] == newList[o].menuId){
+        //         newList[o].checked = true;
+        //       }
+        //     }
+        //   }
+        //   //数据权限范围
+        //   this.$set(this.form,'dataScope',this.propsData.dataScope);
+        //   this.$set(this,'checkDeptType',this.propsData.dataScope)
+        //   //如果权限范围为指定部门
+        //   if (this.propsData.dataScope == 5){
+        //     this.$set(this.deptForm,'deptIds',JSON.parse(this.propsData.viewDeptIds));
+        //   }
+        // }
+        this.menuList = JSON.parse(JSON.stringify(this.handleTree(newList, "menuId")))
+        // this.getTreeselect();
+        this.loading = false;
+      });
+    },
+    /** 查询部门下拉树结构 */
+    getTreeselect() {
+      treeselect().then(response => {
+        this.deptOptions = response.data;
+        this.$set(this,'treeselectList',response.data[0].children);
+      });
+    },
+    //返回事件
+    outPageButton(){
+      this.$parent.goPage(1);
+    },
+    //结构树转数组并筛选选中项
+    toArray(){
+      let list = [];
+      let newList = JSON.parse(JSON.stringify(this.menuList));
+      for(let i=0;i<newList.length;i++){
+        pushNode(newList[i]);
+      }
+      function pushNode(node){
+        if(node.children){
+          for (let nodeItem of node.children){
+            pushNode(nodeItem)
+          }
+          delete node.children;
+          if(node.checked){
+            list.push(node)
+          }
+        }else{
+          if(node.children){
+            delete node.children
+          }
+          if(node.checked){
+            list.push(node)
+          }
+        }
+      }
+      let idList = [];
+      for(let i=0;i<list.length;i++){
+        idList.push(list[i].menuId)
+      }
+      return idList
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.teacher-add-page{
+  flex:1;
+  display: flex;
+  flex-direction: column;
+  box-shadow: 0 0 8px 2px rgba(0, 0, 0, 0.1);
+  padding:0 0 20px!important;
+  overflow: hidden;
+  *{
+    margin:0;
+  }
+  .public-form-box{
+    flex:1;
+    overflow-y: scroll;
+    overflow-x: hidden;
+  }
+  .top-title-box{
+    border-bottom:1px solid #E0E0E0;
+    margin-bottom:20px;
+    display: flex;
+    p:nth-child(1){
+      color:#0045AF;
+      line-height:80px;
+      margin-left:24px;
+      font-size:18px;
+      flex:1;
+    }
+    p:nth-child(2){
+      border:1px solid #0045AF;
+      color:#0045AF;
+      width:80px;
+      height:30px;
+      text-align: center;
+      font-size:16px;
+      border-radius: 6px;
+      line-height:30px;
+      margin:25px 20px 0 0;
+      cursor: pointer;
+    }
+  }
+  .top-info-box{
+    display: flex;
+    padding:40px 20px 0;
+    .left-info-box{
+      margin-right:20px;
+      img{
+        width:100px;
+        height:120px;
+      }
+      p{
+        width: 80px;
+        height: 26px;
+        border: 1px solid #0183FA;
+        border-radius: 6px;
+        line-height:24px;
+        font-size:12px;
+        color:#0183FA;
+        text-align: center;
+        margin:24px 10px;
+      }
+    }
+  }
+  .top-tow-box{
+    display: flex;
+    align-items: center;
+    height: 50px;
+    background: #F5F5F5;
+    >p{
+      color:#0045AF;
+      line-height:80px;
+      margin-left:24px;
+      font-size:18px;
+      flex:1;
+    }
+  }
+  /*数据范围*/
+  .data_scope{
+    margin: 40px 20px;
+    display: flex;
+    justify-content: space-between;
+    .data_scope_l{
+      display: flex;
+      justify-content: flex-start;
+      .data_scope_l_l{
+        font-size: 16px;
+        font-family: Microsoft YaHei-Regular, Microsoft YaHei;
+        font-weight: 400;
+        color: #333333;
+        line-height: 24px;
+        margin-right: 8px;
+        >i{
+          font-size: 14px;
+          color: #FF0000;
+          font-style: normal;
+          margin-right: 4px;
+        }
+      }
+      .data_scope_l_r{
+        display: flex;
+        justify-content: flex-start;
+        >i{
+          height: 40px;
+          font-style: normal;
+          display: inline-block;
+          font-size: 14px;
+          font-family: Microsoft YaHei-Regular, Microsoft YaHei;
+          font-weight: 400;
+          color: #CCCCCC;
+          line-height: 40px;
+          padding: 0 14px;
+          box-sizing: border-box;
+          border: 1px dashed #E0E0E0;
+          margin-right: 20px;
+          cursor: pointer;
+          &.on{
+            color:#0183FA;
+            border: 1px dashed #0183FA;
+          }
+        }
+
+      }
+    }
+    .data_scope_r{
+      width: 70px;
+      height: 40px;
+      border-radius: 6px 6px 6px 6px;
+      opacity: 1;
+      border: 1px solid #0045AF;
+      font-size: 14px;
+      font-family: Microsoft YaHei-Regular, Microsoft YaHei;
+      font-weight: 400;
+      color: #0045AF;
+      line-height: 40px;
+      text-align: center;
+      cursor: pointer;
+    }
+  }
+  .top-title-one{
+    display: flex;
+    border-top:1px solid #E0E0E0;
+    position: relative;
+    .title-p{
+      font-size:18px;
+      color:#0045AF;
+      line-height:80px;
+      margin-left:24px;
+    }
+    .img-p{
+      font-size:18px;
+      margin:0 10px;
+      line-height:80px;
+      color:#FFC000;
+    }
+    .position-box{
+      width: 420px;
+      height: 194px;
+      padding:20px;
+      background: #F5F5F5;
+      position: absolute;
+      top:10px;
+      left:134px;
+      p{
+        font-size:12px;
+        line-height:18px;
+        color:#333;
+      }
+    }
+  }
+  .name-input-box{
+    height:100px;
+  }
+  .for-button-list{
+    background: #E5F2FE;
+    margin:0 20px;
+    display: flex;
+    .for-title-p{
+      width:175px;
+      height:80px;
+      line-height:80px;
+      font-size:16px;
+      color:#333;
+      text-align: center;
+    }
+    .for-button-max-box{
+      flex:1;
+      .for-button-min-box{
+        font-size:16px;
+        display: inline-block;
+        overflow: hidden;
+        height:30px;
+        line-height:30px;
+        border-radius:6px;
+        margin:25px 28px 0 0;
+        cursor: pointer;
+        i{
+          height:30px;
+          line-height:30px;
+          font-size:16px;
+          color:#fff;
+          margin-right:6px;
+        }
+      }
+      .colorAA{
+        color: #ffffff;
+        background: #0183FA;
+        padding:0 26px 0 16px;
+      }
+      .colorBB{
+        padding:0 26px;
+        color: #333;
+        background: #E0E0E0;
+      }
+    }
+  }
+  .template-name-box{
+    display: flex;
+    .template-name-p{
+      font-weight:500;
+      height:80px;
+      line-height:80px;
+      font-size:16px;
+      color:#333;
+      margin-left:20px;
+      flex: 1;
+    }
+    .template-name-button{
+      width:80px;
+      height:40px;
+      line-height:40px;
+      margin:20px 20px 0 0;
+    }
+    .template-name-button-one{
+      width:180px;
+      height:40px;
+      line-height:40px;
+      margin:20px 40px 0 0;
+      color:#fff;
+      background: #0183FA;
+      border: 1px solid #E0E0E0;
+      cursor: pointer;
+      font-size: 14px;
+      text-align: center;
+      border-radius: 6px;
+    }
+  }
+  .table-for-max-box{
+    border:1px solid #D7D7D7;
+    margin:0 20px;
+    *{
+      margin:0;
+      padding:0;
+    }
+    .table-title-box{
+      background: rgba(1,131,250,0.1);
+      display: flex;
+      p{
+        font-size:14px;
+        font-weight:700;
+        color:#333;
+        line-height:48px;
+        padding-left:20px;
+      }
+      p:nth-child(1){
+        width:616px;
+        border-right:1px solid #D7D7D7;
+      }
+    }
+    .table-for-big-box{
+      border-top:1px solid #D7D7D7;
+      display: flex;
+      font-size:14px;
+      .max-title-box-null{
+        width:616px!important;
+      }
+      .max-title-box{
+        width:230px;
+        border-right:1px solid #D7D7D7;
+        min-height:48px;
+        position: relative;
+        p{
+          position: absolute;
+          top:50%;
+          left:20px;
+          height:18px;
+          line-height:18px;
+          margin-top:-9px;
+        }
+      }
+      .max-right-box{
+        flex:5;
+        min-height:48px;
+        .big-box:nth-child(1){
+          border:none!important;
+        }
+        .big-box-null{
+          line-height:48px;
+          margin-left:20px;
+          color:#606266;
+        }
+        .big-box{
+          display: flex;
+          border-top:1px solid #D7D7D7;
+          .big-title-box-null{
+            width:386px!important;
+          }
+          .big-title-box{
+            width:180px;
+            border-right:1px solid #D7D7D7;
+            min-height:48px;
+            position: relative;
+            overflow: hidden;
+            p{
+              position: absolute;
+              top:50%;
+              left:20px;
+              height:48px;
+              line-height:48px;
+              margin-top:-24px;
+            }
+          }
+          .big-right-box-null{
+            flex:1;
+            padding:14px 0 0 20px;
+            div{
+              display: inline-block;
+              margin:0 20px 14px 0;
+            }
+          }
+          .big-right-box{
+            flex:5;
+            min-height:48px;
+            .min-box:nth-child(1){
+              border:none!important;
+            }
+            .min-box{
+              display: flex;
+              border-top:1px solid #D7D7D7;
+              .min-title-box{
+                display: flex;
+                flex-direction: column;
+                border-right:1px solid #D7D7D7;
+                min-height:48px;
+                position: relative;
+                overflow: hidden;
+                .title-left-box{
+                  width:205px;
+                  display: flex;
+                  .min-title-box-null{
+                    flex:1;
+                  }
+                  p{
+                    width:205px;
+                    position: absolute;
+                    top:50%;
+                    left:20px;
+                    height:48px;
+                    line-height:48px;
+                    margin-top:-24px;
+                  }
+                }
+              }
+              .min-right-box{
+                flex:1;
+                padding:14px 0 0 20px;
+                div{
+                  display: inline-block;
+                  margin:0 20px 14px 0 ;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  .bottom-button-box{
+    display: flex;
+    width:600px;
+    margin:30px auto 10px;
+    .null-p{
+      flex:1;
+    }
+    .button-p-1{
+      width:100px;
+      margin-right:20px;
+    }
+    .button-p-2{
+      width:100px;
+      margin-right:20px;
+    }
+    .button-p-3{
+      width:180px;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.teacher-add-page{
+  .top-info-box{
+    .el-form-item{
+      height:70px;
+    }
+    .switch .el-switch__label {
+      position: absolute;
+      display: none;
+      color: #fff !important;
+    }
+    .switch .el-switch__label--right {
+      z-index: 1;
+    }
+    .switch .el-switch__label--right span{
+      margin-left: 10px;
+    }
+    .switch .el-switch__label--left {
+      z-index: 1;
+    }
+    .switch .el-switch__label--left span{
+      margin-left: 24px;
+    }
+    .switch .el-switch__label.is-active {
+      display: block;
+    }
+    .switch.el-switch .el-switch__core,
+    .el-switch .el-switch__label {
+      width: 64px !important;
+      margin: 0;
+    }
+  }
+}
+.managePermissionTemplates-permission-dialog-box{
+  *{
+    margin:0;
+  }
+  .title-p{
+    font-size:15px;
+    font-weight:700;
+    margin-bottom:30px;
+  }
+  .managePermissionTemplates-permission-dialog-form-box{
+    .title-box{
+      display: flex;
+      height: 60px;
+      background: #F5F5F5;
+      .left-title-p{
+        width:198px;
+        border-right:1px solid #E0E0E0;
+        font-size:15px;
+        font-weight:700;
+        padding-left:26px;
+        line-height:60px;
+        color:#333;
+      }
+      .right-box{
+        flex:1;
+        .right-box-min{
+          height:20px;
+          margin:20px 0 0 50px;
+          .el-checkbox__label{
+            font-size:15px;
+            font-weight:700;
+          }
+        }
+      }
+    }
+    .check-box{
+      display: flex;
+      .left-title-box{
+        width:198px;
+        border:1px solid #E0E0E0;
+        position: relative;
+        .left-title-p{
+          position: absolute;
+          left:27px;
+          height:20px;
+          line-height:20px;
+          top:50%;
+          margin-top:-10px;
+        }
+      }
+      .right-box{
+        padding:0 50px 41px 0;
+        flex:1;
+        border:1px solid #E0E0E0;
+        border-left:none;
+        .for-check-box{
+          margin:41px 0 0 50px;
+        }
+      }
+    }
+  }
+  .managePermissionTemplates-permission-dialog-button-box{
+    display: flex;
+    width:160px;
+    margin:0 auto;
+    p{
+      margin:0;
+      width:70px;
+      height:30px;
+      line-height:30px;
+      font-size:14px;
+    }
+    p:nth-child(1){
+      margin-right:20px;
+    }
+  }
+}
+.managePermissionTemplates-dept-dialog-box{
+  *{
+    margin:0;
+  }
+  .managePermissionTemplates-dept-dialog-button-box{
+    display: flex;
+    width:190px;
+    margin:0 auto;
+    p{
+      margin:0;
+      width:70px;
+      height:30px;
+      line-height:30px;
+      font-size:14px;
+    }
+    p:nth-child(1){
+      margin-right:50px;
+    }
+  }
+}
+</style>

+ 386 - 0
src/views/systemManagement/roleManagement/index.vue

@@ -0,0 +1,386 @@
+<!--角色管理-->
+<template>
+  <div class="app-container role">
+    <div class="role_n" v-if="pageType==1">
+      <el-form :model="queryParams" ref="queryForm" v-show="showSearch" :inline="true" class="form-box" >
+        <el-form-item label="角色名称" prop="roleName" style="margin-left:20px;">
+          <el-input
+            v-model="queryParams.roleName"
+            placeholder="请输入角色名称"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+        <el-form-item label="状态" prop="state">
+          <el-select
+            v-model="queryParams.state"
+            placeholder="角色状态"
+            clearable
+            size="small"
+          >
+            <el-option
+              v-for="dict in statusOptions"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="dict.dictValue"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item style="float: right;">
+          <el-col :span="1.5">
+            <p class="add-button-one-90"
+               @click="dialogOpen"
+               v-hasPermi="['system:role:add']"
+            >新增</p>
+          </el-col>
+        </el-form-item>
+        <el-form-item>
+          <p class="inquire-button-one" @click="handleQuery">查询</p>
+          <p class="reset-button-one" @click="resetQuery">重置</p>
+        </el-form-item>
+      </el-form>
+      <el-table v-loading="loading" border :data="roleList" class="table-box" v-if="pageType==1">
+        <el-table-column label="序号" width="50" align="center"  type="index"/>
+        <el-table-column label="名称" prop="roleName" align="center" :show-overflow-tooltip="true" width="200"/>
+        <el-table-column label="权限字符" prop="roleKey" align="center" :show-overflow-tooltip="true" width="200"/>
+        <el-table-column label="数据范围" prop="dataScope" align="center" :show-overflow-tooltip="true" width="296">
+          <template slot-scope="scope">
+            <p v-for="(item,index) in optionsDataList" :key="index" v-if="scope.row.dataScope == item.type">{{item.value}}</p>
+          </template>
+        </el-table-column>
+        <el-table-column label="对应身份" prop="postNameStr" align="center" :show-overflow-tooltip="true"/>
+        <el-table-column label="状态" prop="dataScope" align="state" :show-overflow-tooltip="true" width="100">
+          <template slot-scope="scope">{{scope.row.state?'启用':'停用'}}</template>
+        </el-table-column>
+        <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200" v-if="tableButtonType">
+          <template slot-scope="scope">
+            <div class="table-button-box">
+              <p class="table-button-null"></p>
+              <!--<p class="table-button-p"-->
+                 <!--@click="copyButton(scope.row)"-->
+                 <!--v-hasPermiAnd="['system:role:edit','system:role:query']"-->
+              <!--&gt;复制</p>-->
+              <p class="table-button-p"
+                 @click="handleUpdate(scope.row)"
+                 v-hasPermiAnd="['system:role:edit','system:role:query']"
+              >编辑</p>
+              <p class="table-button-p"
+                 @click="copyButton(scope.row)"
+              >权限配置</p>
+              <p class="table-button-p"
+                 @click="handleDelete(scope.row)"
+                 v-hasPermi="['system:role:remove']"
+              >删除</p>
+              <p class="table-button-null"></p>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :page-sizes="[20, 30, 40, 50]"
+                  v-if="pageType==1"
+                  v-show="total>0"
+                  :total="total"
+                  layout="total, prev, pager, next, sizes, jumper"
+                  :page.sync="queryParams.page"
+                  :limit.sync="queryParams.pageSize"
+                  @pagination="getList"
+      />
+    </div>
+    <!--新增弹窗-->
+    <el-dialog class="classConfig-dialog" :title='dialogTitle' width="540px" append-to-body
+               :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
+               :close-on-click-modal="false" :close-on-press-escape="false">
+      <el-form :model="dialogForm" ref="dialogForm" :inline="true" :rules="dialogRules" class="addCheckPage-min" label-width="100px">
+        <el-form-item label="角色名称" prop="roleName">
+          <el-input v-model="dialogForm.roleName" placeholder="请输入角色名称" maxLength="10" style="width:320px;"/>
+        </el-form-item>
+        <el-form-item label="权限字符" prop="roleKey">
+          <el-input v-model="dialogForm.roleKey" placeholder="请输入权限字符" maxLength="20" style="width:320px;"/>
+        </el-form-item>
+        <el-form-item label="描述" prop="roleDesc">
+          <el-input v-model="dialogForm.roleDesc" placeholder="请输入描述" maxLength="20" style="width:320px;"/>
+        </el-form-item>
+        <el-form-item label="排序" prop="roleSort">
+          <el-input-number v-model="dialogForm.roleSort" controls-position="right" :min="1" :max="9999" style="width:320px;"></el-input-number>
+        </el-form-item>
+        <el-form-item label="数据范围" prop="dataScope">
+          <el-select v-model="dialogForm.dataScope"
+                     placeholder="请选择数据范围"
+                     clearable style="width:320px;">
+            <el-option
+              v-for="dict in optionsDataList"
+              :key="dict.type"
+              :label="dict.value"
+              :value="dict.type"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="指定部门" prop="customDept" v-if="dialogForm.dataScope == 5">
+          <el-cascader
+            style="width:320px;"
+            :options="treeselectList"
+            :props="{multiple: true,value: 'deptId', label: 'deptName',children:'child',emitPath:false}"
+            collapse-tags
+            v-model="dialogForm.customDept"
+            clearable>
+          </el-cascader>
+        </el-form-item>
+        <el-form-item label="状态" prop="state">
+          <el-radio-group v-model="dialogForm.state" style="width:320px;">
+            <el-radio :label="true">启用</el-radio>
+            <el-radio :label="false">停用</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-info" @click="dialogOff()">取消</p>
+        <p class="dialog-footer-button-primary" @click="dialogSubmit">确定</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
+    <!--编辑-->
+    <add-page v-if="pageType == 2" :propsData="propsData"></add-page>
+  </div>
+</template>
+
+<script>
+import { systemRoleList,systemRoleDetail,systemRoleDelete,systemRoleAdd,systemRoleUpdate,systemRoleGetRoleMenu } from "@/api/systemManagement/index";
+import { getDeptDropList } from "@/api/commonality/permission";
+import { listRole, getRole, delRole, addRole, updateRole, dataScope, changeRoleStatus } from "@/apiDemo/system/role";
+import addPage from "./addPage.vue"
+
+export default {
+  components: {
+    addPage
+  },
+  name: "Role",
+  data() {
+    return {
+      tableButtonType:this.hasPermiDom(['system:role:query','system:role:edit','system:role:remove']),
+      // 遮罩层
+      loading: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 状态数据字典
+      statusOptions: [{dictValue:true,dictLabel:"启用"}, {dictValue:false,dictLabel:"禁用"}],
+      //部门列表
+      treeselectList:[],
+      // 查询参数
+      queryParams: {
+        page: 1,
+        pageSize:20,
+        roleName: null,
+        state: null
+      },
+      roleList:[],
+      pageType:1,
+      //组件传参数据
+      propsData:{},
+      //数据范围(1:全部, 2:部门及下级, 3:本部门, 4:仅本人,5:自定义)
+      optionsDataList:[
+        {type: 1, value: "所有数据",},
+        {type: 2, value: "本部门及下级部门数据",},
+        {type: 3, value: "本部门",},
+        {type: 4, value: "当前账号数据",},
+        {type: 5, value: "自定义",},
+      ],
+      //新增编辑数据
+      dialogTitle:null,
+      dialogType:false,
+      dialogForm:{},
+      dialogRules:{
+        roleName: [
+          { required: true, message: "请输入角色名称", trigger: "blur" },
+          { required: true, message: "请输入角色名称", validator: this.spaceJudgment, trigger: "blur" }
+        ],
+        roleKey: [
+          { required: true, message: "请输入权限字符", trigger: "blur" },
+          { required: true, message: "请输入权限字符", validator: this.spaceJudgment, trigger: "blur" }
+        ],
+        roleDesc: [
+          { required: true, message: "请输入描述", trigger: "blur" },
+          { required: true, message: "请输入描述", validator: this.spaceJudgment, trigger: "blur" }
+        ],
+        roleSort: [
+          { required: true, message: "请输入排序", trigger: "blur" },
+          { required: true, message: "请输入排序", validator: this.spaceJudgment, trigger: "blur" }
+        ],
+        dataScope: [
+          { required: true, message: "请选择数据范围", trigger: "blur" },
+        ],
+        state: [
+          { required: true, message: "请选择状态", trigger: "blur" },
+        ],
+      },
+    };
+  },
+  created() {
+    this.getList();
+    this.getDeptDropList();
+  },
+  methods: {
+    goPage(type){
+      if(this.pageType != type){
+        if(type == 1){
+          this.$set(this,'pageType',type);
+        }else if(type == 3){
+          this.$set(this,'pageType',1);
+          this.resetQuery();
+        }
+      }
+    },
+    /** 查询角色列表 */
+    getList() {
+      this.$set(this,'loading',true);
+      systemRoleList(this.queryParams).then(response => {
+        this.$set(this,'loading',false);
+        this.$set(this,'roleList',response.data.records);
+        this.$set(this,'total',response.data.total);
+      });
+    },
+    //部门列表
+    getDeptDropList(){
+      getDeptDropList(this.queryParams).then(response => {
+        this.$set(this,'treeselectList',response.data);
+      });
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.page = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.$set(this,"queryParams", {
+        page: 1,
+        pageSize:20,
+        roleName: null,
+        state: null
+      });
+      this.handleQuery();
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      let obj = {
+        type:1,
+        title:"新增角色",
+      };
+      this.$set(this,'propsData',obj);
+      this.$set(this,'pageType',2);
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      systemRoleDetail({roleId:row.roleId}).then(response => {
+        this.dialogFormReset();
+        let obj = JSON.parse(JSON.stringify(response.data));
+        if (obj.dataScope == 5 && obj.customDept[0]){
+          obj.customDept = obj.customDept.split(',');
+        }else{
+          obj.customDept = [];
+        }
+        this.$set(this,'dialogForm',obj);
+        this.$set(this,'dialogTitle','编辑');
+        this.$set(this,'dialogType',true);
+      });
+    },
+    /** 权限配置按钮 */
+    copyButton(row){
+        this.$set(this,'propsData',row);
+        this.$set(this,'pageType',2);
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      this.$confirm('是否确认删除角色?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return systemRoleDelete({roleId:row.roleId});
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(() => {});
+    },
+    //弹层关闭
+    dialogOff(){
+      this.$set(this,'dialogType',false);
+    },
+    //弹层开启
+    dialogOpen(){
+      this.dialogFormReset();
+      this.$set(this,'dialogTitle','新增');
+      this.$set(this,'dialogType',true);
+    },
+    //弹层确定
+    dialogSubmit(){
+      this.$refs["dialogForm"].validate(valid => {
+        if (valid) {
+          if(this.dialogForm.roleId){
+            let obj = {
+              roleId:this.dialogForm.roleId,
+              roleName:this.dialogForm.roleName,
+              roleKey:this.dialogForm.roleKey,
+              roleDesc:this.dialogForm.roleDesc,
+              roleSort:this.dialogForm.roleSort,
+              dataScope:this.dialogForm.dataScope,
+              customDept:this.dialogForm.dataScope == 5 ? this.dialogForm.customDept + '' : '',
+              state:this.dialogForm.state,
+            }
+            systemRoleUpdate(obj).then(response => {
+              this.msgSuccess(response.message);
+              this.getList();
+              this.$set(this,'dialogType',false);
+            });
+          }else{
+            systemRoleAdd(this.dialogForm).then(response => {
+              this.msgSuccess(response.message);
+              this.getList();
+              this.$set(this,'dialogType',false);
+            });
+          }
+        }
+      })
+    },
+    dialogFormReset(){
+      this.$set(this,'dialogForm',{
+        roleName:'',
+        roleKey:'',
+        roleDesc:'',
+        roleSort:'',
+        customDept:'',
+        dataScope:'',
+        state:true,
+      });
+    },
+  }
+};
+</script>
+
+<style scoped lang="scss">
+  .role {
+    display: flex!important;
+    flex-direction: column;
+    box-shadow: 0 0 8px 2px rgba(0, 0, 0, 0.1);
+    .role_n{
+      display: flex!important;
+      flex-direction: column;
+      flex: 1;
+      padding:11px 20px 20px!important;
+    }
+    .form-box{
+
+      margin-top:12px;
+     // display: flex;
+      .null-p{
+        flex:1;
+      }
+    }
+    .button-box{
+      width:390px;
+      display: flex;
+    }
+  }
+</style>

+ 16 - 38
src/views/systemManagement/systemUser/index.vue

@@ -1,9 +1,9 @@
 <!--系统用户管理-->
 <template>
   <div class="app-container user user-page-admin">
-    <el-row :gutter="20" style="flex:1;display: flex">
+    <el-row :gutter="20" style="flex:1;display: flex;overflow: hidden">
       <!--部门数据-->
-      <el-col :span="4" :xs="24" stlye="width:260px;">
+      <el-col :span="4" :xs="24" stlye="width:260px;" class=" scrollbar-box">
         <div class="head-container">
           <el-tree
             style="margin-right:20px;"
@@ -164,14 +164,13 @@
           <el-col :span="12">
             <el-form-item label="角色" prop="roleIds">
               <!--<el-select v-model="form.roleIds" placeholder="请选择" style="width:200px;">-->
-              <el-select v-model="form.roleIds" multiple collapse-tags
+              <el-select v-model="form.roleIds" collapse-tags
                          placeholder="请选择" style="width:200px;">
                 <el-option
                   v-for="item in roleOptions"
                   :key="item.roleId"
                   :label="item.roleName"
                   :value="item.roleId"
-                  :disabled="item.state == 1"
                 ></el-option>
               </el-select>
             </el-form-item>
@@ -237,7 +236,7 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css";
 
 //V3新
 import { getDeptList,systemUserList,systemUserAdd,systemUserDetail,
-  systemUserUpdate,systemUserEditState,systemUserDelete,systemUserEditPasswd } from "@/api/commonality/permission";
+  systemUserUpdate,systemUserEditState,systemUserDelete,systemUserEditPasswd,systemRoleDropList } from "@/api/commonality/permission";
 import md5 from 'js-md5';
 
 export default {
@@ -299,7 +298,7 @@ export default {
       // 岗位选项
       postOptions: [],
       // 角色选项
-      roleOptions: [{roleName:"本地测试数据1",roleId:999},{roleName:"本地测试数据2",roleId:9999},],
+      roleOptions: [],
       defaultProps: {
         children: "child",
         label: "deptName"
@@ -386,17 +385,7 @@ export default {
   created() {
     this.getDeptList();
     this.getList();
-    // this.getList();
-    // this.getDeptList();
-    // this.getDicts("sys_normal_disable").then(response => {
-    //   this.stateOptions = response.data;
-    // });
-    // this.getDicts("sys_user_sex").then(response => {
-    //   this.sexOptions = response.data;
-    // });
-    // this.getConfigKey("sys.user.initPassword").then(response => {
-    //   this.initPassword = response.message;
-    // });
+    this.systemRoleDropList();
   },
   methods: {
     /*===========V3开始===========*/
@@ -423,6 +412,13 @@ export default {
         }
       );
     },
+    //角色下拉列表
+    systemRoleDropList(){
+      systemRoleDropList({roleName :'',pageSize:10}).then(response => {
+          this.roleOptions = response.data;
+        }
+      );
+    },
     // 筛选节点
     filterNode(value, data) {
       if (!value) return true;
@@ -453,13 +449,6 @@ export default {
       this.reset();
       this.open = true;
       this.title = "添加用户";
-      // getUser().then(response => {
-      //   this.postOptions = response.posts;
-      //   this.roleOptions = response.roles;
-      //   this.open = true;
-      //   this.title = "添加用户";
-      //   this.form.password = this.initPassword;
-      // });
     },
     /** 删除按钮操作 */
     handleDelete(row) {
@@ -485,26 +474,14 @@ export default {
           mobile:response.data.mobile,
           deptId:response.data.deptId,
           state:response.data.state,
-          // roleIds:obj.roleIds[0]?response.data.roleIds.split(','):[]
-          roleIds:response.data.roleIds
+          // roleIds:obj.roleIds[0]?response.data.roleIds.split(','):[],
+          roleIds:response.data.roleIds[0]
         };
 
         this.$set(this,'form',JSON.parse(JSON.stringify(obj)));
         this.open = true;
         this.title = "修改用户";
       });
-
-      // const userId = row.userId || this.ids;
-      // getUser(userId).then(response => {
-      //   this.form = response.data;
-      //   this.postOptions = response.posts;
-      //   this.roleOptions = response.roles;
-      //   this.form.postIds = response.postIds;
-      //   this.form.roleIds = response.roleIds;
-      //   this.open = true;
-      //   this.title = "修改用户";
-      //   this.form.password = "";
-      // });
     },
     /** 提交按钮 */
     submitForm() {
@@ -614,6 +591,7 @@ export default {
     flex-direction: column;
     box-shadow: 0 0 8px 2px rgba(0, 0, 0, 0.1);
     padding:20px;
+    overflow: hidden;
   }
   ::v-deep .head-container{
     /*==========树结构开始==========*/

+ 10 - 0
vue.config.js

@@ -385,6 +385,16 @@ module.exports = {
           enforce:true,
           reuseExistingChunk: true
         },
+        //物联设备
+        iotDevice: {
+          name: 'chunk-iotDevice',
+          test: resolve('src/views/iotDevice'),
+          priority: 0,
+          minSize: 0,
+          minChunks: 1,
+          enforce:true,
+          reuseExistingChunk: true
+        },
       }
     })
     config.optimization.runtimeChunk('single'),{