tangning преди 3 години
родител
ревизия
35089377af

+ 81 - 79
package-lock.json

@@ -1712,16 +1712,6 @@
           "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
           "dev": true
         },
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
         "cacache": {
           "version": "13.0.1",
           "resolved": "https://registry.npm.taobao.org/cacache/download/cacache-13.0.1.tgz?cache=0&sync_timestamp=1594429684526&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcacache%2Fdownload%2Fcacache-13.0.1.tgz",
@@ -1748,53 +1738,6 @@
             "unique-filename": "^1.1.1"
           }
         },
-        "chalk": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
-          "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-          "dev": true,
-          "optional": true
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-          "dev": true,
-          "optional": true
-        },
-        "loader-utils": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
-          "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "big.js": "^5.2.2",
-            "emojis-list": "^3.0.0",
-            "json5": "^2.1.2"
-          }
-        },
         "source-map": {
           "version": "0.6.1",
           "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
@@ -1811,16 +1754,6 @@
             "minipass": "^3.1.1"
           }
         },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        },
         "terser-webpack-plugin": {
           "version": "2.3.8",
           "resolved": "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-2.3.8.tgz?cache=0&sync_timestamp=1603900039438&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-2.3.8.tgz",
@@ -1837,18 +1770,6 @@
             "terser": "^4.6.12",
             "webpack-sources": "^1.4.3"
           }
-        },
-        "vue-loader-v16": {
-          "version": "npm:vue-loader@16.2.0",
-          "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.2.0.tgz",
-          "integrity": "sha512-TitGhqSQ61RJljMmhIGvfWzJ2zk9m1Qug049Ugml6QP3t0e95o0XJjk29roNEiPKJQBEi8Ord5hFuSuELzSp8Q==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "chalk": "^4.1.0",
-            "hash-sum": "^2.0.0",
-            "loader-utils": "^2.0.0"
-          }
         }
       }
     },
@@ -11617,6 +11538,87 @@
         }
       }
     },
+    "vue-loader-v16": {
+      "version": "npm:vue-loader@16.8.1",
+      "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.1.tgz",
+      "integrity": "sha512-V53TJbHmzjBhCG5OYI2JWy/aYDspz4oVHKxS43Iy212GjGIG1T3EsB3+GWXFm/1z5VwjdjLmdZUFYM70y77vtQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "chalk": "^4.1.0",
+        "hash-sum": "^2.0.0",
+        "loader-utils": "^2.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true,
+          "optional": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true,
+          "optional": true
+        },
+        "loader-utils": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+          "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^2.1.2"
+          }
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
     "vue-router": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.2.tgz",

+ 9 - 3
src/components/dialog/index.vue

@@ -10,6 +10,7 @@
           <slot />
         </div>
         <div class="floot" v-if="showFloor">
+          <el-button type="danger" v-if="showDel" @click="deleteHandle" >删 除</el-button>
           <el-button @click="closeHandle" v-if="showClose || showClose === void 0">取 消</el-button>
           <el-button type="primary" @click="enterHandle">{{enterText || '保 存'}}</el-button>
         </div>
@@ -22,12 +23,13 @@
 import { computed, ref } from "vue";
 
 export default {
-  props: ["show", "title", "hideFloor", 'enterText', 'width', 'showClose'],
+  props: ["show", "title", "hideFloor", 'enterText', 'width', 'showClose','showDelete'],
   setup(props) {
     const dialogVisible = ref(props.show);
+    console.log('props',props);
+    const showDel = ref(props.showDelete)
     const showFloor = computed(() => !(props.hideFloor || props.hideFloor === ''))
-
-    return { dialogVisible, showFloor };
+    return { dialogVisible, showFloor,showDel };
   },
   watch: {
     dialogVisible() {
@@ -50,6 +52,10 @@ export default {
       this.$emit('submit')
       // this.dialogVisible = false;
     },
+    deleteHandle() {
+      console.log('deleteHandle')
+      this.$emit('delete')
+    }
   },
 };
 </script>

+ 1 - 1
src/constant/view.js

@@ -4,4 +4,4 @@ export const keyViewMap = {
 }
 
 // 如果不加入菜单,router依附到哪里
-export const attach = { housing: 'estate' }
+export const attach = { housing: 'estate',organizationlist:'organization',organizationdetail:'organization' }

+ 5 - 0
src/request/config.js

@@ -120,7 +120,12 @@ export const bindCamera = '/api/scene/camera/bindCamera'
 export const unbindCamera = '/web/camera/unbind'
 /** ------------------------------------------ */
 
+/** ----------------组织架构---------------- */
 
+export const getTreeselect = '/web/department/treeselect'
+export const delTreeitem = '/web/department/del/'
+export const editTreeitem = '/web/department/edit'
+export const addTreeitem = '/web/department/add'
 
 /** ----------------火调项目---------------- */
 // 获取火调列表

+ 25 - 0
src/router/index.js

@@ -5,6 +5,9 @@ import ForgetView from '@/view/system'
 import ViewLayout from '@/view/layout'
 import Scene from '@/view/scene'
 import DispatchView from '@/view/dispatch'
+import OrganizationView from '@/view/organization'
+import OrganizationInfoView from '@/view/organization/info'
+import OrganizationListView from '@/view/organization/list'
 import HomeView from '@/view/home'
 import VRModelView from '@/view/vrmodel'
 // import TeachingView from '@/view/teaching'
@@ -65,6 +68,28 @@ export const routes = [
         meta: { title: '火调管理' }
       },
       {
+        name: 'organization',
+        path: 'organization',
+        component: OrganizationView,
+        meta: { title: '组织架构' },
+        redirect:'/organization/list',
+        children:[
+          {
+            name: 'organizationlist',
+            path: 'list',
+            component: OrganizationListView,
+            meta: { title: '组织架构' },
+          },
+          {
+            name: 'organizationdetail',
+            path: 'detail',
+            component: OrganizationInfoView,
+            meta: { title: '组织架构' },
+          },
+        ]
+      },
+      
+      {
         name: 'teaching',
         path: 'teaching',
         component: DispatchView,

+ 5 - 4
src/state/navs.js

@@ -2,9 +2,8 @@ import { config } from '@/router'
 import { attach } from '@/constant/view'
 import user from './user'
 import { watch, ref } from 'vue'
-
 // 所有权限都有的router
-export const MUST_JOIN_NAVS = ['viewLayout', 'login', 'register', 'forget', 'scene']
+export const MUST_JOIN_NAVS = ['viewLayout', 'login', 'register', 'forget', 'scene', 'organization']
 // router对应的icon
 const ICON_MAP = { 
   estate: 'iconfire_scenes', 
@@ -12,8 +11,9 @@ const ICON_MAP = {
   vrmodel: 'iconfire_scenes', 
   camera: 'iconfire_camera', 
   dispatch: 'iconfire_management', 
+  organization: 'iconfire_management', 
   teaching: 'iconfire_study',
-  user: 'iconfire_user'
+  user: 'iconfire_user',
 }
 
 const getNames = (config) => {
@@ -31,7 +31,7 @@ const _getNavs = (items, notJoinNavs) => {
     if (~notJoinNavs.indexOf(items[i].name)) {
       continue
     } else {
-      if (items[i].children) {
+      if (items[i].children && items[i].name !== 'organization') {
         ret.push(..._getNavs(items[i].children, notJoinNavs))
       } else if (ICON_MAP[items[i].name]){
         let item = {
@@ -47,6 +47,7 @@ const _getNavs = (items, notJoinNavs) => {
 }
 
 const getNavs = () => {
+  
   let names = getNames(config)
   let showNames = user.value.permission.map(item => item.viewName)
   let notJoinNavs = names.filter(name => 

+ 2 - 1
src/state/tableRef.js

@@ -40,7 +40,7 @@ const getOperState = (attr) => {
       operState.value.reset()
     }
   })
-
+  console.log('getOperState',operState)
   return operState
 }
 
@@ -242,5 +242,6 @@ export default ({operAttr, searchAttr, pagAttr, isSelect = true, getUrl, updateU
   // 激活再刷新一次
   onActivated(() => referListData(ret, getUrl, pagAttr))
   onMounted(() => referListData(ret, getUrl, pagAttr))
+  console.log('getTableState',ret)
   return ret
 }

+ 6 - 6
src/view/dispatch/archives.vue

@@ -2,7 +2,7 @@
   <com-dialog
     title="火调档案管理"
     enterText="上传附件"
-    :hideFloor="user.info.departmentId != organizerDeptId"
+    :hideFloor="user.info.deptId != deptId"
     :show="show"
     @submit="oper.readyInsert"
     @update:show="val => $emit('update:show', val)"
@@ -26,8 +26,8 @@
           <a class="oper-span" :href="row.fileOssUrl" target="_blank">查看</a>
           <span class="oper-span" @click="downloadFile(row.fileOssUrl, row.fileName)">下载</span>
           <span class="oper-span" 
-            :class="{disable: user.info.departmentId != organizerDeptId}" 
-            @click="user.info.departmentId == organizerDeptId && deleteItem(row)" 
+            :class="{disable: user.info.deptId != deptId}" 
+            @click="user.info.deptId == deptId && deleteItem(row)" 
             style="color: var(--primaryColor)">
           删除
           </span>
@@ -100,7 +100,7 @@ import { types } from '@/constant'
 
 export default {
   name: 'archives',
-  props: ['show', 'data', 'organizerDeptId'],
+  props: ['show', 'data', 'deptId'],
   setup(props) {
     const state = getTableState({
       getUrl: getAttachList,
@@ -133,9 +133,9 @@ export default {
       this.$emit('referList')
     },
     async unbindCamrea(data) {
-      if (data.departmentId && (await this.$confirm('解绑相机,该相机拍摄的场景也将一并解绑(场景在云端存储,不会删除)确定要解绑吗?', '提示'))) {
+      if (data.deptId && (await this.$confirm('解绑相机,该相机拍摄的场景也将一并解绑(场景在云端存储,不会删除)确定要解绑吗?', '提示'))) {
         await axios.post(unbindCamera, data)
-        data.departmentName = data.departmentId = null
+        data.departmentName = data.deptId = null
       }
 
       this.dataList.refer()

+ 11 - 11
src/view/dispatch/index.vue

@@ -19,7 +19,7 @@
           :props="{ expandTrigger: 'hover', checkStrictly: true }"></el-cascader>
       </el-form-item>
       <el-form-item label="承办单位:">
-        <com-company v-model="search.state.organizerDeptId" />
+        <com-company v-model="search.state.deptId" />
       </el-form-item>
       <el-form-item label="事故日期:">
         <el-date-picker type="date" v-model="queryAccidentDate" style="width: 100%"></el-date-picker>
@@ -119,10 +119,10 @@
         <template v-else>
           
           <span class="oper-span" @click="row.vrLink && shareHandle(row)" :class="{disable: !row.vrLink}">分享</span>
-          <span class="oper-span" @click="auth.update && user.info.departmentId == row.organizerDeptId && editInfo(row)" :class="{disable: !(auth.update && user.info.departmentId == row.organizerDeptId)}">编辑</span>
+          <span class="oper-span" @click="auth.update && user.info.deptId == row.deptId && editInfo(row)" :class="{disable: !(auth.update && user.info.deptId == row.deptId)}">编辑</span>
           <span class="oper-span" 
-            @click="auth.delete && user.info.departmentId == row.organizerDeptId && dataList.delete(row)" 
-            :class="{disable: !(auth.delete && user.info.departmentId == row.organizerDeptId)}"
+            @click="auth.delete && user.info.deptId == row.deptId && dataList.delete(row)" 
+            :class="{disable: !(auth.delete && user.info.deptId == row.deptId)}"
             style="color: var(--primaryColor)">
           删除
           </span>
@@ -139,7 +139,7 @@
       :total="pag.state.total"/>
   </div>
   
-  <com-archives @referList="dataList.refer()" v-model:show="showArchives.show" v-if="showArchives.data && showArchives.show" :organizerDeptId="showArchives.organizerDeptId" :data="showArchives.data" />
+  <com-archives @referList="dataList.refer()" v-model:show="showArchives.show" v-if="showArchives.data && showArchives.show" :deptId="showArchives.deptId" :data="showArchives.data" />
   
   <com-dialog
     title="分享"
@@ -192,7 +192,7 @@
       <div class="el-form-item">
         <el-col :span="12">
           <el-form-item label="承办单位" class="mandatory">
-            <com-company :modelValue="oper.state.organizerDeptId" hideAll :notUpdate="true" />
+            <com-company :modelValue="oper.state.deptId" hideAll :notUpdate="true" />
           </el-form-item>
         </el-col>
         <el-col :span="12">
@@ -399,7 +399,7 @@ export default {
       searchAttr: { 
         projectSn: '', projectName: '',
         __projectSite: '', projectAdrress: '',
-        organizerDeptId: '', accidentDate: null,
+        deptId: '', accidentDate: null,
         status: '', projectSiteCode: '',
         fireReason: '', sceneNum: '', organizerUsers: '',
         isTeached: '', queryType: ''
@@ -407,7 +407,7 @@ export default {
       operAttr: {
         projectSn: '', projectName: '',
         projectSite: '', projectAddress: '',
-        organizerDeptId: '', accidentDate: '',
+        deptId: '', accidentDate: '',
         projectSiteCode: '',
         fireReason: '', sceneNum: '', organizerUsers: ''
       },
@@ -540,7 +540,7 @@ export default {
     },
     insertProject() {
       this.oper.readyInsert()
-      this.oper.state.organizerDeptId = user.value.info.departmentId
+      this.oper.state.deptId = user.value.info.deptId
       // 
       this.searchScene('')
     },
@@ -564,7 +564,7 @@ export default {
     },
     archivesHandle(row) {
       this.showArchives.data = row.id
-      this.showArchives.organizerDeptId = row.organizerDeptId
+      this.showArchives.deptId = row.deptId
       this.showArchives.show = true
     },
     submit() {
@@ -576,7 +576,7 @@ export default {
         return this.$message.error('起火对象不能为空!', '提示')
       } else if (!this.oper.state.projectSite || !this.oper.state.projectSite.trim()) {
         return this.$message.error('起火场所不能为空!', '提示')
-      } else if (!this.oper.state.organizerDeptId || !this.oper.state.organizerDeptId.trim()) {
+      } else if (!this.oper.state.deptId || !this.oper.state.deptId.trim()) {
         return this.$message.error('承办单位不能为空!', '提示')
       } else if (!this.oper.state.organizerUsers || !this.oper.state.organizerUsers.trim()) {
         return this.$message.error('承办人员不能为空!', '提示')

+ 2 - 0
src/view/layout/slide/index.vue

@@ -1,5 +1,6 @@
 <template>
   <div class="slide">
+    {{activeName}}
     <el-menu :default-active="activeName" @select="selectHandle">
       <sub-menu :nav="nav" v-for="nav in navs" :key="nav.name" />
     </el-menu>
@@ -13,6 +14,7 @@ import { attach } from '@/constant/view'
 
 export default {
   setup() {
+    console.log('navs',navs)
     return { navs }
   },
   computed: {

+ 44 - 0
src/view/organization/index.vue

@@ -0,0 +1,44 @@
+<template>
+  <div class="organiza">
+    <div class="title">组织架构</div>
+    <router-view></router-view>
+  </div>
+</template>
+
+<script>
+
+export default {
+  name: "organization",
+  setup() {
+  },
+  data() {
+    return { };
+  },
+  methods: {},
+  mounted() {},
+  components: {
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.organiza {
+  .but {
+    padding: 16px;
+    background-color: #fff;
+    text-align: right;
+  }
+  .title {
+    height: 56px;
+    padding: 0 24px;
+    color: #303133;
+    font-size: 16px;
+    line-height: 56px;
+    height: 56px;
+    font-weight: 500;
+    background-color: #fff;
+    border-bottom: 1px solid #e4e7ed;
+  }
+}
+
+</style>

+ 160 - 0
src/view/organization/info.vue

@@ -0,0 +1,160 @@
+<template>
+  <div class="organiza">
+    <div class="organiza-body">
+      <see-info  :detail="seeData"/>
+      </div>
+  </div>
+</template>
+
+<script>
+import { reactive, toRefs } from "vue"; //computed watch ref
+import seeInfo from "./seeInfo.vue";
+
+export default {
+  name: "organizationinfo",
+  setup() {
+    const data = reactive({
+      seeData:{
+        name:'test',
+        type:'总队',
+        superior:'sheq',
+        principal:'pite',
+        phone:'119',
+        remark:'test',
+      },
+    });
+    
+    return {
+      ...toRefs(data),
+    };
+  },
+  methods: {},
+  mounted() {},
+
+  components: {
+    "see-info":seeInfo
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.organiza {
+  .but {
+    padding: 16px;
+    background-color: #fff;
+    text-align: right;
+  }
+  .title {
+    height: 56px;
+    padding: 0 24px;
+    color: #303133;
+    font-size: 16px;
+    line-height: 56px;
+    height: 56px;
+    font-weight: 500;
+    background-color: #fff;
+    border-bottom: 1px solid #e4e7ed;
+  }
+  .organiza-body {
+    margin-top: 15px;
+    background-color: #fff;
+    padding: 15px;
+    .tree {
+      border: 1px solid #ebeef5;
+      // margin-top: 24px;
+      .treeTile {
+        display: flex;
+        justify-content: space-between;
+        border-bottom: 1px solid #ebeef5;
+        background-color: #fafafa;
+        padding: 12px 20px;
+      }
+      .treeList {
+        display: flex;
+        justify-content: space-between;
+        .custom-tree-node {
+          flex: 1;
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          font-size: 14px;
+          padding-right: 8px;
+          .butList {
+            a {
+              margin: 0 8px;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+.table-ctrl-right {
+  .search-scene {
+    margin: 0 20px 0 26px;
+  }
+  i {
+    margin-left: 20px;
+    font-size: 1.7rem;
+    vertical-align: middle;
+    cursor: pointer;
+
+    &.active {
+      color: var(--primaryColor);
+    }
+  }
+}
+
+.camera-from {
+  margin: 0 50px;
+}
+.share-from {
+  width: 500px;
+  margin: 0 auto;
+}
+.maker {
+  font-weight: 400;
+  color: #969799;
+  line-height: 20px;
+}
+.oper-user {
+  height: 40px;
+  overflow: hidden; //超出的文本隐藏
+  text-overflow: ellipsis; //溢出用省略号显示
+  white-space: nowrap; //溢出不换行
+  cursor: pointer;
+}
+</style>
+
+<style>
+.organiza .el-tree-node__content {
+  padding: 12px 10px;
+  border-bottom: 1px solid #ebeef5;
+}
+.camera-from .el-select,
+.dispatch-file-from .el-select {
+  width: 100%;
+}
+
+.el-textarea__inner {
+  font-family: "Microsoft YaHei";
+}
+.dispatch-detial .el-form-item__content {
+  color: #323233;
+}
+.dispatch-detial .el-form-item__label {
+  color: #646566;
+}
+
+.table .tip {
+  text-overflow: -o-ellipsis-lastline;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  line-clamp: 2;
+  -webkit-box-orient: vertical;
+  height: 50px;
+  white-space: initial;
+}
+</style>

+ 455 - 0
src/view/organization/list.vue

@@ -0,0 +1,455 @@
+<template>
+  <div class="organiza">
+    <div class="but">
+      <el-button type="primary" @click="insertProject">新增组织架构</el-button>
+    </div>
+    <div class="organiza-body">
+      <div class="tree">
+        <div class="treeTile">
+          <span>全国消防火调组织架构</span>
+          <span style="padding-right: 100px;">操作</span>
+        </div>
+        <div class="treeList">
+          <el-tree
+            style="width: 100%"
+            :props="treeProps"
+            :data="treedata"
+            node-key="id"
+            default-expand-all
+            :expand-on-click-node="false"
+          >
+            <template #default="{ node, data }">
+              <span class="custom-tree-node">
+                <span>{{ data.name }}</span>
+                <span class="butList">
+                  <a @click="seeDetail(data,node)"> 查看 </a>
+                  <a @click="insertProject(data)"> 编辑 </a>
+                  <a
+                    style="color: var(--primaryColor)"
+                    @click="remove(data.id)"
+                  >
+                    删除
+                  </a>
+                </span>
+              </span>
+            </template>
+          </el-tree>
+        </div>
+      </div>
+    </div>
+    <com-dialog
+      v-model:show="show"
+      @submit="submit"
+      :title="`${detailType}组织架构`"
+    >
+      <el-form
+        ref="form"
+        :model="detail"
+        label-width="84px"
+        class="camera-from"
+      >
+        <el-form-item label="组织名称" class="mandatory">
+          <el-input
+            v-model="detail.name"
+            maxlength="50"
+            placeholder="请输入组织名称"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="组织类型" class="mandatory">
+          <el-radio-group v-model="detail.deptType">
+            <el-radio label="1">总队</el-radio>
+            <el-radio label="2">支队</el-radio>
+            <el-radio label="3">大队</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="上级组织">
+          <el-cascader
+            style="width: 100%"
+            v-model="superiorValue"
+            :options="superiorOptions"
+            :props="{ expandTrigger: 'hover' }"
+            @change="handleChange"
+          ></el-cascader>
+        </el-form-item>
+        <el-form-item label="负责人">
+          <el-input
+            v-model="detail.leader"
+            maxlength="50"
+            placeholder="请输入"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="联系电话">
+          <el-input
+            v-model="detail.phone"
+            maxlength="50"
+            placeholder="请输入联系电话"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="备注">
+          <el-input
+            v-model="detail.remark"
+            type="textarea"
+            placeholder="请输入备注"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+    </com-dialog>
+
+    <com-dialog
+      v-model:show="seeShow"
+      @submit="seeShow = false"
+      enterText="确定"
+      title="查看组织架构"
+    >
+      <see-info :required="true" :detail="seeData"/>
+    </com-dialog>
+
+    <!-- <com-dialog
+      v-model:show="infoShow"
+      @submit="
+        () => {
+          tipsShow = !tipsShow;
+        }
+      "
+      enterText="我知道了"
+      :showClose="false"
+      title="温馨提示"
+    >
+      <div>
+        当前组织下尚存在用户或绑定的相机,删除组织将一并删除,确认要删除组织吗?
+      </div>
+    </com-dialog> -->
+  </div>
+</template>
+
+<script>
+import { reactive, toRefs,onMounted } from "vue"; //computed watch ref
+import comDialog from "@/components/dialog";
+import axios from 'axios';
+import seeInfo from "./seeInfo.vue";
+import { getApp } from "@/app";
+import {
+  getTreeselect,delTreeitem,addTreeitem,editTreeitem
+} from '@/request/config'
+
+export default {
+  name: "camera",
+  setup() {
+    const data = reactive({
+      show: false,
+      tipsShow: false,
+      seeShow: false,
+      infoShow: false,
+      detailType:'新增',
+      seeData:{
+        name:'test',
+        deptType:'1',
+        superior:'sheq',
+        leader:'负责人',
+        phone:'',
+        remark:'test',
+      },
+      detail: {
+        name: "test",
+        deptType: "1",
+      },
+      treeProps: { children: "children", label: "name" },
+      superiorValue: [],
+      superiorOptions: [
+        {
+          value: "guide",
+          label: "Guide",
+          children: [
+            {
+              value: "disciplines",
+              label: "Disciplines",
+              children: [
+                {
+                  value: "consistency",
+                  label: "Consistency",
+                },
+                {
+                  value: "feedback",
+                  label: "Feedback",
+                },
+                {
+                  value: "efficiency",
+                  label: "Efficiency",
+                },
+                {
+                  value: "controllability",
+                  label: "Controllability",
+                },
+              ],
+            },
+            {
+              value: "navigation",
+              label: "Navigation",
+              children: [
+                {
+                  value: "side nav",
+                  label: "Side Navigation",
+                },
+                {
+                  value: "top nav",
+                  label: "Top Navigation",
+                },
+              ],
+            },
+          ],
+        },
+        {
+          value: "resource",
+          label: "Resource",
+          children: [
+            {
+              value: "axure",
+              label: "Axure Components",
+            },
+            {
+              value: "sketch",
+              label: "Sketch Templates",
+            },
+            {
+              value: "docs",
+              label: "Design Documentation",
+            },
+          ],
+        },
+      ],
+      treedata: [],
+    });
+    const seeDetail = (val) =>{
+      console.log('seeDetail',val)
+      data.seeData = {
+        superior:val.order,
+        ...val
+      }
+      data.seeShow = true
+    }
+    const handleNodeClick = (data) => {
+      console.log(data);
+    };
+    const submit = async () => {
+      const { name, deptType,leader,phone,remark } = data.detail;
+      if (!name) {
+        return getApp().$message.error("组织名称不能为空!", "提示");
+      } else if (!deptType) {
+        return getApp().$message.error("组织类型不能为空!", "提示");
+      }
+      //校验成功后温馨提示
+      let apidata = {
+        name,
+        deptType,
+        superior:'sheq',
+        leader,
+        phone,
+        remark,
+      }
+      let requestApi = addTreeitem
+      if(data.detailType == '编辑'){
+        requestApi = editTreeitem
+      }
+      let res = await axios.post(requestApi, apidata)
+      console.log('async',res);
+      data.show = false;
+      getApp().$confirm('组织创建成功', '删除')
+      // data.tipsShow = true;
+    };
+    const insertProject = (val) => {
+     if(val){
+      data.detailType = '编辑'
+      data.detail = {
+          ...val
+      }
+     }else{
+      data.detailType = '新增'
+     }
+      data.show = true;
+    };
+    const handleChange = (val) => {
+      console.log("点击handleChange", val);
+    };
+    const loadNode = (node, resolve) => {
+      if (node.level === 0) {
+        return resolve([{ label: "region" }]);
+      }
+      if (node.level > 1) return resolve([]);
+
+      setTimeout(() => {
+        const data = [
+          {
+            name: "leaf",
+            leaf: true,
+          },
+          {
+            name: "zone",
+          },
+        ];
+
+        resolve(data);
+      }, 500);
+    };
+    const remove = async (val) => {
+      let isOk = await getApp().$confirm('当前组织下尚存在用户或绑定的相机,删除组织将一并删除,确认要删除组织吗?', '删除')
+      if(isOk){
+        let res = await axios.post(delTreeitem+val, {})
+        console.log("isOk",isOk, val,res);
+        getApp().$message({message: '删除成功', type: 'success'});
+      }
+    };
+    
+    onMounted(async ()=>{
+      let res = await axios.get(getTreeselect, {})
+      data.treedata = res.data
+    })
+    return {
+      // treedata,
+      ...toRefs(data),
+      // ...toRefs(state),
+    //   treeProps,
+      handleNodeClick,
+      loadNode,
+      insertProject,
+      submit,
+      handleChange,
+      seeDetail,
+      remove,
+    };
+  },
+  data() {
+    return {
+      searchLoading: false,
+      searchOptions: [],
+    };
+  },
+  methods: {},
+
+  components: {
+    "com-dialog": comDialog,
+    "see-info":seeInfo
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.organiza {
+  .but {
+    padding: 16px;
+    background-color: #fff;
+    text-align: right;
+  }
+  .title {
+    height: 56px;
+    padding: 0 24px;
+    color: #303133;
+    font-size: 16px;
+    line-height: 56px;
+    height: 56px;
+    font-weight: 500;
+    background-color: #fff;
+    border-bottom: 1px solid #e4e7ed;
+  }
+  .organiza-body {
+    margin-top: 15px;
+    background-color: #fff;
+    padding: 15px;
+    .tree {
+      border: 1px solid #ebeef5;
+      // margin-top: 24px;
+      .treeTile {
+        display: flex;
+        justify-content: space-between;
+        border-bottom: 1px solid #ebeef5;
+        background-color: #fafafa;
+        padding: 12px 20px;
+      }
+      .treeList {
+        display: flex;
+        justify-content: space-between;
+        .custom-tree-node {
+          flex: 1;
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          font-size: 14px;
+          padding-right: 8px;
+          .butList {
+            a {
+              margin: 0 8px;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+.table-ctrl-right {
+  .search-scene {
+    margin: 0 20px 0 26px;
+  }
+  i {
+    margin-left: 20px;
+    font-size: 1.7rem;
+    vertical-align: middle;
+    cursor: pointer;
+
+    &.active {
+      color: var(--primaryColor);
+    }
+  }
+}
+
+.camera-from {
+  margin: 0 50px;
+}
+.share-from {
+  width: 500px;
+  margin: 0 auto;
+}
+.maker {
+  font-weight: 400;
+  color: #969799;
+  line-height: 20px;
+}
+.oper-user {
+  height: 40px;
+  overflow: hidden; //超出的文本隐藏
+  text-overflow: ellipsis; //溢出用省略号显示
+  white-space: nowrap; //溢出不换行
+  cursor: pointer;
+}
+</style>
+
+<style>
+.organiza .el-tree-node__content {
+  padding: 12px 10px;
+  border-bottom: 1px solid #ebeef5;
+}
+.camera-from .el-select,
+.dispatch-file-from .el-select {
+  width: 100%;
+}
+
+.el-textarea__inner {
+  font-family: "Microsoft YaHei";
+}
+.dispatch-detial .el-form-item__content {
+  color: #323233;
+}
+.dispatch-detial .el-form-item__label {
+  color: #646566;
+}
+
+.table .tip {
+  text-overflow: -o-ellipsis-lastline;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  line-clamp: 2;
+  -webkit-box-orient: vertical;
+  height: 50px;
+  white-space: initial;
+}
+</style>

+ 93 - 0
src/view/organization/seeInfo.vue

@@ -0,0 +1,93 @@
+<template>
+  <div class="infoDetail">
+    <el-form
+      ref="form"
+      :model="detail"
+      label-width="100px"
+      class="dispatch-detial"
+    >
+      <el-form-item label="组织名称" :class="required?'mandatory':''">
+        <p class="tip">{{ detail.name }}</p>
+      </el-form-item>
+      <el-form-item label="组织类型" :class="required?'mandatory':''">
+        <p class="tip">{{ type }}</p>
+      </el-form-item>
+      <el-form-item label="上级组织">
+        <p class="tip">{{ detail.superior }}</p>
+      </el-form-item>
+      <el-form-item label="负责人">
+        <p class="tip">{{ detail.leader }}</p>
+      </el-form-item>
+      <el-form-item label="联系电话">
+        <p class="tip">{{ detail.phone }}</p>
+      </el-form-item>
+      <el-form-item label="备注">
+        <p class="tip">{{ detail.remark }}</p>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import { reactive, toRefs,computed } from "vue"; //watch
+
+export default {
+  name: "seeInfo",
+  props: ["required", "detail"],
+  setup(props) {
+    const data = reactive({
+      searchAttr: { pageSize: 12, projectId: props.data },
+    });
+    const type = computed(() =>{
+      let leble = {
+        '1':'总队',
+        '2':'支队',
+        '3':'大队',
+      }
+      console.log('type',props);
+      return leble[props.detail.deptType] || 'zanw'
+    })
+    return { ...toRefs(data),type };
+  },
+  methods: {},
+  computed: {},
+  components: {
+    // "com-dialog": comDialog,
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.table-ctrl-right {
+  .search-scene {
+    margin: 0 20px 0 26px;
+  }
+  i {
+    margin-left: 20px;
+    font-size: 1.7rem;
+    vertical-align: middle;
+    cursor: pointer;
+
+    &.active {
+      color: var(--primaryColor);
+    }
+  }
+}
+
+.title {
+  font-weight: bold;
+  color: #26559b;
+  line-height: 19px;
+  font-size: 14px;
+}
+</style>
+
+<style>
+.upload-demo .el-upload {
+  line-height: initial;
+}
+
+.arch-name .el-input__inner {
+  padding-right: 50px;
+}
+</style>

+ 1 - 0
src/view/system/forget.vue

@@ -112,6 +112,7 @@ export default {
       ev.stopPropagation()
 
       for (let val of Object.values(this.verification)) {
+        console.log('verification',this.verification);
         if (val) return openErrorMsg(val, '提示')
       }
 

+ 1 - 0
src/view/system/login.vue

@@ -58,6 +58,7 @@ export default {
   
 
     watch(form, () => {
+      console.log('form',form)
       if (!form.phone) {
         verification.phone = '请输入手机号'
       } else {

+ 1 - 1
src/view/system/register.vue

@@ -144,7 +144,7 @@ export default {
       let psw = encryption(this.form.psw)
       try {
         await axios.post(userReg, {
-          departmentId: this.form.organize,
+          deptId: this.form.organize,
           nickName: this.form.name,
           userName: this.form.phone,
           key: this.imgKey,

+ 2 - 2
src/view/teaching/index.vue

@@ -108,12 +108,12 @@ export default {
       insertUrl: insertCamera,
       getUrl: getCameraList,
       delUrl: deleteCamera,
-      searchAttr: { startTime: "", endTime: '', departmentId: '', snCode: '' },
+      searchAttr: { startTime: "", endTime: '', deptId: '', snCode: '' },
       operAttr: {
         wifiName: '',
         snCode: '',
         childName: '',
-        departmentId: '',
+        deptId: '',
       },
       pagAttr: {totalNum: 'total'},
       delMsg: '解绑相机,该相机拍摄的场景也将一并解绑(场景在云端存储,不会删除)确定要解绑吗?'

+ 241 - 141
src/view/user/index.vue

@@ -1,115 +1,170 @@
 <template>
-  <com-head :options="headList" >
-    <el-form label-width="84px" inline="true">
-      <el-form-item label="用户名称:">
-        <el-input v-model="search.state.nickName" placeholder="请输入"></el-input>
-      </el-form-item>
-      <el-form-item label="所属架构:">
-        <com-company v-model="search.state.departmentId" />
-      </el-form-item>
-      <el-form-item label="状态:">
-        <el-select v-model="search.state.status" placeholder="全部">
-          <el-option label="全部" :value="''"></el-option>
-          <el-option label="可用" :value="1"></el-option>
-          <el-option label="禁用" :value="0"></el-option>
-        </el-select>
-      </el-form-item>
-      <el-form-item class="searh-btns">
-        <el-button type="primary" @click="search.submit">查询</el-button>
-        <el-button type="primary" plain @click="search.reset">重置</el-button>
-      </el-form-item>
-    </el-form>
-  </com-head>
+  <div>
+    <com-head :options="headList">
+      <el-form label-width="84px" inline="true">
+        <el-form-item label="用户名称:">
+          <el-input
+            v-model="search.state.nickName"
+            placeholder="请输入"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="所属架构:">
+          <com-company v-model="search.state.deptId" />
+        </el-form-item>
+        <el-form-item label="状态:">
+          <el-select v-model="search.state.status" placeholder="全部">
+            <el-option label="全部" :value="''"></el-option>
+            <el-option label="可用" :value="1"></el-option>
+            <el-option label="禁用" :value="0"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item class="searh-btns">
+          <el-button type="primary" @click="search.submit">查询</el-button>
+          <el-button type="primary" plain @click="search.reset">重置</el-button>
+        </el-form-item>
+      </el-form>
+    </com-head>
 
-  <div class="body-layer" style="padding-top: 8px">
-    <div class="body-head">
-      <!-- <h3 style="visibility: hidden;">用户列表</h3> -->
+    <div class="body-layer" style="padding-top: 8px">
+      <div class="body-but">
+          <el-button type="primary" @click="newAddclick">新增用户{{newShow}}</el-button>
+        <!-- <h3 style="visibility: hidden;">用户列表</h3> -->
+      </div>
+
+      <el-table
+        class="user-table"
+        ref="multipleTable"
+        :data="dataList.state"
+        tooltip-effect="dark"
+        style="width: 100%"
+        @row-click="selectRow"
+      >
+        <el-table-column label="序号" width="55" v-slot:default="{ $index }">
+          <div style="text-align: center">
+            {{ pag.state.size * (pag.state.currPage - 1) + $index + 1 }}
+          </div>
+        </el-table-column>
+        <el-table-column
+          label="手机号(账号)"
+          prop="userName"
+        ></el-table-column>
+        <el-table-column label="用户名称" prop="nickName"></el-table-column>
+        <el-table-column
+          label="所属架构"
+          prop="departmentName"
+        ></el-table-column>
+        <el-table-column label="角色" prop="roleName"></el-table-column>
+        <el-table-column label="状态" v-slot:default="{ row }">
+          {{ row.status ? "可用" : "禁用" }}
+        </el-table-column>
+        <el-table-column
+          label="操作"
+          v-slot:default="{ row }"
+          v-if="auth.update || auth.updatePwd || auth.delete"
+        >
+          <template v-if="row.id !== ADMIN_USER_ID && row.id !== user.info.id">
+            <span class="oper-span" @click="updateInfo(row)" v-if="auth.update"
+              >编辑</span
+            >
+            <span
+              class="oper-span"
+              @click="changeUserStatus(row)"
+              v-if="auth.delete"
+              style="color: var(--primaryColor)"
+            >
+              {{ row.status ? "禁用" : "启用" }}
+            </span>
+          </template>
+        </el-table-column>
+      </el-table>
+      <com-pagination
+        @size-change="pag.sizeChange"
+        @current-change="pag.currentChange"
+        :current-page="pag.state.currPage"
+        :page-size="pag.state.size"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="pag.state.total"
+      />
     </div>
 
-    <el-table
-      class="user-table"
-      ref="multipleTable"
-      :data="dataList.state"
-      tooltip-effect="dark"
-      style="width: 100%"
-      @row-click="selectRow"
+    <com-dialog
+      title="编辑用户"
+      v-model:show="oper.state.show"
+      @submit="operItem"
+      width="540"
     >
-      <el-table-column label="序号" width="55" v-slot:default="{ $index }">
-        <div style="text-align: center">{{ pag.state.size * (pag.state.currPage - 1) + $index + 1 }}</div>
-      </el-table-column>
-      <el-table-column label="手机号(账号)" prop="userName"></el-table-column>
-      <el-table-column label="用户名称" prop="nickName"></el-table-column>
-      <el-table-column label="所属架构" prop="departmentName"></el-table-column>
-      <el-table-column label="角色" prop="roleName"></el-table-column>
-      <el-table-column label="状态" v-slot:default="{ row }">
-        {{row.status ? '可用': '禁用'}}
-      </el-table-column>
-      <el-table-column label="操作" v-slot:default="{ row }" v-if="auth.update || auth.updatePwd || auth.delete">
-        <template v-if="row.id !== ADMIN_USER_ID && row.id !== user.info.id">
-          <span class="oper-span" @click="updateInfo(row)" v-if="auth.update">修改</span>
-          <span class="oper-span" @click="changeUserStatus(row)" v-if="auth.delete" style="color: var(--primaryColor)">
-            {{ row.status ? '禁用' : '启用' }}
-          </span>
-        </template>
-      </el-table-column>
-    </el-table>
-    <com-pagination
-      @size-change="pag.sizeChange"
-      @current-change="pag.currentChange"
-      :current-page="pag.state.currPage"
-      :page-size="pag.state.size"
-      layout="total, sizes, prev, pager, next, jumper"
-      :total="pag.state.total"/>
-  </div>
-  
+      <el-form ref="form" :model="form" label-width="90px" class="user-from">
+        <el-form-item label="用户姓名" class="mandatory" v-show="operRoleId">
+          <el-input
+            v-model="search.state.nickName"
+            placeholder="请输入"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+    </com-dialog>
 
-  <com-dialog
-    :title="(operRoleId ? '修改架构' : '启用')"
-    v-model:show="oper.state.show"
-    @submit="operItem"
-    width="540"
-  >
-    <el-form ref="form" :model="form" label-width="90px" class="user-from">
-      <el-form-item label="所属架构:" class="mandatory"  v-show="operRoleId">
-        <com-company v-model="oper.state.departmentId" @update:data="({level}) => (oper.state.roleId = level)" style="width: 100%" hideAll />
-      </el-form-item>
-      <el-form-item label="角色:" class="roleName">
-        <com-role v-model="oper.state.roleId" style="width: 100%" allText="请选择" hideAll :notDefault="true" :disabled="true" />
-      </el-form-item>
-      <el-form-item v-if="!operRoleId">
-        <p class="maker">注:首次启用,需设置用户角色;用户被启用后,可正常登录使用。</p>
-      </el-form-item>
-    </el-form>
-  </com-dialog>
-  
+    <com-dialog
+      title="新增用户"
+      v-model:show="newShow"
+      @submit="newSubmit"
+      width="540"
+    >
+      <el-form ref="form" :model="form" label-width="90px" class="user-from">
+        <el-form-item label="用户姓名" class="mandatory" >
+          <el-input
+            v-model="newData.nickName"
+            placeholder="请输入"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="用户角色" class="roleName">
+          <com-role
+            v-model="newData.roleId"
+            style="width: 100%"
+            allText="请选择"
+            hideAll
+            :notDefault="true"
+            :disabled="true"
+          />
+        </el-form-item>
+        <el-form-item label="用户账号" class="mandatory">
+          <el-input
+            v-model="newData.phone"
+            placeholder="请输入11位手机号码作为用户账号"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="登录密码" class="mandatory">
+          <el-input
+            v-model="newData.psw"
+            placeholder="请输入8-16位数字、英文大小写组合密码"
+            type="password"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+    </com-dialog>
+  </div>
 </template>
 
 
 <script>
-import { ref } from "vue";
+import { reactive, ref, toRefs } from "vue";
 import getTableState from "@/state/tableRef";
 import comDialog from "@/components/dialog";
 import comHead from "@/components/head";
 import comCompany from "@/components/company-select";
 import comPagination from "@/components/pagination";
-import roleCompany from "@/components/role-select";
+// import roleCompany from "@/components/role-select";
 import auth from "@/state/viewAuth";
 import user from "@/state/user";
-import axios from 'axios'
-import {encryption} from '@/util'
-import {PSW, PHONE} from '@/constant/REG'
-import {ADMIN_USER_ID} from "@/constant";
-
-import {
-  getUserList,
-  updateUser,
-  changeUserStatus
-} from '@/request/config'
-import { getApp } from '../../app';
+import axios from "axios";
+import { encryption } from "@/util";
+import { PSW, PHONE } from "@/constant/REG";
+import { ADMIN_USER_ID } from "@/constant";
 
+import { getUserList, updateUser, changeUserStatus } from "@/request/config";
+import { getApp } from "../../app";
 
 export default {
-  name: 'user',
+  name: "user",
   setup() {
     const state = getTableState({
       getUrl: getUserList,
@@ -117,99 +172,146 @@ export default {
       operAttr: {
         nickName: "",
         userName: "",
-        departmentId: "",
-        password: '',
-        confirmPwd: '',
+        deptId: "",
+        password: "",
+        confirmPwd: "",
         roleId: "",
         maxlevel: 1,
       },
-      searchAttr: { nickName: "", status: '', departmentId: '' },
+      searchAttr: { nickName: "", status: "", deptId: "" },
     });
     const headList = ref([{ name: "用户管理", value: 2 }]);
-    const operRoleId = ref('')
+    const operRoleId = ref("");
     const updateInfo = (row) => {
-
       if (!row.status) {
-        return getApp().$message.error('请先启用用户', '提示')
+        return getApp().$message.error("请先启用用户", "提示");
       }
-      operRoleId.value = row.roleId
-      state.oper.value.readyUpdate(row)
+      operRoleId.value = row.roleId;
+      state.oper.value.readyUpdate(row);
+    };
+    const newAddclick = () =>{
+      data.newShow = true
+      console.log('newShow = true',data.newShow)
     }
-    
-    console.log(user)
-    return { ...state, headList, updateInfo, auth, user, operRoleId, ADMIN_USER_ID };
+    const data = reactive({
+      newShow: false,
+      newData:{
+        userName: "",
+        userId: "",
+        password: "",
+        userRole: "",
+      }
+    });
+    return {
+      ...state,
+      ...toRefs(data),
+      headList,
+      updateInfo,
+      auth,
+      user,
+      operRoleId,
+      ADMIN_USER_ID,
+      newAddclick
+    };
   },
   methods: {
+    async newSubmit(){
+      await this.$confirm('每个组织只能创建一个总管理员~', '新增用户')
+      console.log('newData',this.newData)
+    },
     async operItem() {
-      const updatePhone = this.oper.state.__oldData ? this.oper.state.__oldData.userName !== this.oper.state.userName : true
-      
+      const updatePhone = this.oper.state.__oldData
+        ? this.oper.state.__oldData.userName !== this.oper.state.userName
+        : true;
+
       if (updatePhone && !PHONE.REG.test(this.oper.state.userName)) {
-        return this.$message.error(PHONE.tip, '提示')
+        return this.$message.error(PHONE.tip, "提示");
       }
       if (this.oper.state.password !== this.oper.state.confirmPwd) {
-        return this.$message.error('两次密码不一致!', '提示')
+        return this.$message.error("两次密码不一致!", "提示");
       }
 
       if (!this.oper.state.roleId) {
-        return this.$message.error('请选择用户角色', '提示')
+        return this.$message.error("请选择用户角色", "提示");
       }
 
-      if (!this.operRoleId && !(await this.$confirm('用户被启用后,可正常登录使用。确定要启用吗?', '提示'))) {
+      if (
+        !this.operRoleId &&
+        !(await this.$confirm(
+          "用户被启用后,可正常登录使用。确定要启用吗?",
+          "提示"
+        ))
+      ) {
         return;
       }
 
       if (this.oper.state.id) {
-        let updateState = {...this.oper.state, password: void 0, confirmPwd: void 0, updatePwd: void 0, userId: this.oper.state.id}
+        let updateState = {
+          ...this.oper.state,
+          password: void 0,
+          confirmPwd: void 0,
+          updatePwd: void 0,
+          userId: this.oper.state.id,
+        };
         if (!updatePhone) {
-          delete updateState.userName
+          delete updateState.userName;
         }
-        let state = {...this.oper.state}
-        await this.oper.update(updateState)
-        await this.changeUserStatus(state, true)
+        let state = { ...this.oper.state };
+        await this.oper.update(updateState);
+        await this.changeUserStatus(state, true);
       } else if (this.oper.state.password === this.oper.state.confirmPwd) {
         if (PSW.REG.test(this.oper.state.password)) {
-          let cryPsw = encryption(this.oper.state.password)
+          let cryPsw = encryption(this.oper.state.password);
           this.oper.insert({
             ...this.oper.state,
-            password: cryPsw,  
-            confirmPwd: cryPsw,  
-            updatePwd: void 0
-          })
+            password: cryPsw,
+            confirmPwd: cryPsw,
+            updatePwd: void 0,
+          });
         } else {
-          this.$message.error(PSW.tip, '提示')
+          this.$message.error(PSW.tip, "提示");
         }
       }
-
     },
-    async changeUserStatus (row, d) {
-      if (!d && (!row.roleId && !row.status)) {
-        this.operRoleId = row.roleId
-        return this.oper.readyUpdate(row)
-      }
-      let msg = row.status ? `用户被禁用后,无法登录使用。确定要禁用吗?` : `用户被启用后,可正常登录使用。确定要启用吗?`
+    async changeUserStatus(row, d) {
+      // if (!d && (!row.roleId && !row.status)) {
+      //   this.operRoleId = row.roleId
+      //   return this.oper.readyUpdate(row)
+      // }
+      let msg = row.status
+        ? `用户被禁用后,无法登录使用,无法编辑场景(可将该用户关联的相机绑定到其它管理员)。确定要禁用吗?`
+        : `用户被启用后,可正常登录使用。确定要启用吗?`;
       try {
-        if (d || (await this.$confirm(msg, '提示'))) {
-          await axios.post(changeUserStatus, {status: Number(!row.status), userId: row.id})
-          this.dataList.refer()
+        if (d || (await this.$confirm(msg, "提示"))) {
+          await axios.post(changeUserStatus, {
+            status: Number(!row.status),
+            userId: row.id,
+          });
+          this.dataList.refer();
         }
-        return true
+        return true;
       } catch {
-        return false
+        return false;
       }
-    }
+    },
   },
   components: {
     "com-dialog": comDialog,
     "com-head": comHead,
     "com-company": comCompany,
-    "com-role": roleCompany,
-    "com-pagination": comPagination
+    // "com-role": roleCompany,
+    "com-pagination": comPagination,
   },
 };
-
 </script>
 
 <style lang="scss" scoped>
+.body-layer{
+  .body-but{
+    text-align: right;
+    margin-bottom: 15px;
+  }
+}
 .table-ctrl-right {
   .search-scene {
     margin: 0 20px 0 26px;
@@ -238,7 +340,7 @@ export default {
   z-index: 999;
 
   &::before {
-    content: '密码重置为Fcb20210225,可登录修改';
+    content: "密码重置为Fcb20210225,可登录修改";
     position: absolute;
     width: 205px;
     left: 50%;
@@ -254,11 +356,10 @@ export default {
     background: #303133;
     color: #fff;
     margin-bottom: 6px;
-    
   }
 
   &::after {
-    content: '';
+    content: "";
     position: absolute;
     display: block;
     width: 0;
@@ -279,7 +380,6 @@ export default {
   color: #969799;
   line-height: 20px;
 }
-
 </style>
 
 <style>

+ 2 - 2
src/view/vrmodel/index.vue

@@ -47,7 +47,7 @@
       <el-table-column label="操作" v-slot:default="{ row }" >
         <span class="oper-span" @click="shareHandle(row)">查看</span>
         <span class="oper-span" @click="auth.update && user.info.id == row.creatorId && editModel(row)" :class="{disable: !(auth.update && user.info.id == row.creatorId)}" v-if="auth.update">编辑</span>
-        <span class="oper-span" @click="auth.delete && user.info.departmentId == row.deptId && dataList.delete(row)" :class="{disable: !(auth.delete && user.info.departmentId == row.deptId)}" style="color: var(--primaryColor)">删除</span>
+        <span class="oper-span" @click="auth.delete && user.info.deptId == row.deptId && dataList.delete(row)" :class="{disable: !(auth.delete && user.info.deptId == row.deptId)}" style="color: var(--primaryColor)">删除</span>
       </el-table-column>
     </el-table>
 
@@ -67,7 +67,7 @@
     >
       <el-form ref="form" :model="form" label-width="84px" class="vrmodel-from">
         <el-form-item label="所属架构:" class="mandatory">
-          <com-company v-model="editCompany.data.departmentId" hideAll />
+          <com-company v-model="editCompany.data.deptId" hideAll />
         </el-form-item>
       </el-form>
     </com-dialog>

+ 2 - 2
vue.config.js

@@ -17,8 +17,8 @@ module.exports = {
     // 设置代理proxy
     proxy: {
       '/__api': {
-        // target: 'http://192.168.0.98:8285/',
-        target: 'https://testhuodiao.4dkankan.com/',
+        target: 'http://192.168.0.26:8585/',
+        // target: 'https://testhuodiao.4dkankan.com/',
         changeOrigin: true,  
         pathRewrite: {      
           ['^/__api']: ''