Browse Source

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

* 'master' of http://git.wdklian.com/allen/ncs_ui:
  优化
  医院级空间结构开发
  医院级空间结构开发
  优化
  将登陆改成登录
  增加护士组长,护士成员功能
  腕表完善
  优化
wuyunfeng 4 năm trước cách đây
mục cha
commit
8f9df94a10
77 tập tin đã thay đổi với 3659 bổ sung930 xóa
  1. 1 1
      dist/index.html
  2. 0 1
      dist/static/css/app.848c2287.css
  3. 0 1
      dist/static/css/chunk-06faafad.c4469a3f.css
  4. 0 1
      dist/static/css/chunk-33c220b5.5e69ac7c.css
  5. 0 1
      dist/static/css/chunk-3e9c6b25.5f95877f.css
  6. 0 1
      dist/static/css/chunk-3fc04dc7.646ba2db.css
  7. 0 1
      dist/static/css/chunk-4decaba3.95168f18.css
  8. 0 1
      dist/static/css/chunk-536dc705.05e6c10a.css
  9. 0 1
      dist/static/css/chunk-537d7593.b22894e7.css
  10. 0 1
      dist/static/css/chunk-7c5298e1.516f9bb1.css
  11. 0 1
      dist/static/css/chunk-95ac90b6.3a7928f9.css
  12. 0 1
      dist/static/css/chunk-c4207b36.31192868.css
  13. 0 1
      dist/static/css/chunk-d5ed0cd6.5cbe9b13.css
  14. 0 1
      dist/static/css/chunk-libs.854468b4.css
  15. BIN
      dist/static/img/loginBg.238668d2.jpg
  16. 0 1
      dist/static/js/app.af067b6f.js
  17. 0 1
      dist/static/js/chunk-06faafad.2aab81cd.js
  18. 0 6
      dist/static/js/chunk-107fdb58.bb729d73.js
  19. 0 1
      dist/static/js/chunk-1d9ec8ab.c4d651da.js
  20. 0 1
      dist/static/js/chunk-2d0bdbb6.352c6034.js
  21. 0 1
      dist/static/js/chunk-2d0c8694.a3443a88.js
  22. 0 1
      dist/static/js/chunk-30ca8599.35aae577.js
  23. 0 1
      dist/static/js/chunk-33c220b5.07f68482.js
  24. 0 1
      dist/static/js/chunk-3e9c6b25.ae9262c2.js
  25. 0 1
      dist/static/js/chunk-3fc04dc7.2aa1b151.js
  26. 0 1
      dist/static/js/chunk-4decaba3.10847f33.js
  27. 0 1
      dist/static/js/chunk-536dc705.b9f9f39d.js
  28. 0 1
      dist/static/js/chunk-537d7593.5b70e487.js
  29. 0 1
      dist/static/js/chunk-5c92bfb9.7e52b7ae.js
  30. 0 1
      dist/static/js/chunk-5f4cdadc.aa7f35e8.js
  31. 0 1
      dist/static/js/chunk-665577f1.dd5b3358.js
  32. 0 1
      dist/static/js/chunk-7c5298e1.db0cc428.js
  33. 0 1
      dist/static/js/chunk-95ac90b6.33943a7d.js
  34. 0 1
      dist/static/js/chunk-c4207b36.3aa5951e.js
  35. 0 1
      dist/static/js/chunk-d5ed0cd6.d2eb0448.js
  36. 0 1
      dist/static/js/chunk-elementUI.d21c1ac9.js
  37. 0 457
      dist/static/js/chunk-libs.f11dcb7f.js
  38. 5 5
      src/api/calling-patient.js
  39. 14 0
      src/api/ncs_clerk.js
  40. 9 0
      src/api/ncs_customer.js
  41. 16 0
      src/api/ncs_device.js
  42. 8 0
      src/api/ncs_event.js
  43. 15 0
      src/api/ncs_hospitalFrame.js
  44. 1 1
      src/components/AgGridLayout/src/main.vue
  45. 1 0
      src/icons/svg/bad_people.svg
  46. 1 0
      src/icons/svg/empty_bed.svg
  47. 16 16
      src/layout/components/Navbar.vue
  48. 24 1
      src/router/index.js
  49. 48 23
      src/store/modules/permission.js
  50. 3 3
      src/utils/device_type.js
  51. 1 1
      src/views/customer/components/customerManager.vue
  52. 19 6
      src/views/customer/customerEdit.vue
  53. 4 4
      src/views/customer/customer_relative.vue
  54. 62 25
      src/views/customer/list.vue
  55. 6 6
      src/views/dashboard/calling-admin/components/partUserManager.vue
  56. 2 2
      src/views/dashboard/calling/components/PanelGroup.vue
  57. 4 4
      src/views/dashboard/calling/components/SickBedBoard.vue
  58. 2 2
      src/views/dashboard/calling/index.vue
  59. 1212 0
      src/views/hospital/ncs_customer/customerManager.vue
  60. 590 0
      src/views/hospital/ncs_device/deviceManager.vue
  61. 780 0
      src/views/hospital/ncs_frame/frameTreeView.vue
  62. 1 1
      src/views/hospitalFrame/frameGroupEdit.vue
  63. 4 7
      src/views/hospitalFrame/frameTreeView.vue
  64. 186 186
      src/views/hospitalFrame/hospitalFrame.vue
  65. 187 0
      src/views/hospitalFrame/nurse_watch_frame.vue
  66. 2 2
      src/views/login/index.vue
  67. 7 7
      src/views/ncs-auth/compontents/roleEdit.vue
  68. 72 2
      src/views/ncs-auth/superadmin/defaultRoleManager.vue
  69. 94 10
      src/views/ncs-clerk/clerkList.vue
  70. 30 6
      src/views/ncs-device/components/deviceManager.vue
  71. 1 1
      src/views/ncs-device/device-admin.vue
  72. 22 4
      src/views/ncs-device/device-edit.vue
  73. 83 24
      src/views/ncs-device/nurse_watch.vue
  74. 33 57
      src/views/ncs-event/index.vue
  75. 80 15
      src/views/ncs-nurse-config/index.vue
  76. 6 6
      src/views/ncs-orginazition/components/partUserManager.vue
  77. 7 6
      src/views/ncs-task/index.vue

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/index.html


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/css/app.848c2287.css


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/css/chunk-06faafad.c4469a3f.css


+ 0 - 1
dist/static/css/chunk-33c220b5.5e69ac7c.css

@@ -1 +0,0 @@
-fieldset[data-v-c1a826a4]{border-style:solid;border-color:#dcdfe6;border-width:1px}.margin-top-sm[data-v-c1a826a4]{margin-top:20px}

+ 0 - 1
dist/static/css/chunk-3e9c6b25.5f95877f.css

@@ -1 +0,0 @@
-.el-drawer.rtl{overflow:scroll}

+ 0 - 1
dist/static/css/chunk-3fc04dc7.646ba2db.css

@@ -1 +0,0 @@
-[data-v-92eb0d7e] .avatar-uploader .el-upload{border:1px dashed #d9d9d9;border-radius:6px;cursor:pointer;position:relative;overflow:hidden}.avatar-uploader .el-upload[data-v-92eb0d7e]:hover{border-color:#409eff}.avatar-uploader-icon[data-v-92eb0d7e]{font-size:28px;color:#8c939d;width:178px;height:178px;line-height:178px;text-align:center}.avatar[data-v-92eb0d7e]{width:178px;height:178px;display:block}.green-text[data-v-92eb0d7e]{color:green}.red-text[data-v-92eb0d7e]{color:red}

+ 0 - 1
dist/static/css/chunk-4decaba3.95168f18.css

@@ -1 +0,0 @@
-fieldset[data-v-023c7e3b]{border-style:solid;border-color:#dcdfe6;border-width:1px}.margin-top-sm[data-v-023c7e3b]{margin-top:20px}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/css/chunk-536dc705.05e6c10a.css


+ 0 - 1
dist/static/css/chunk-537d7593.b22894e7.css

@@ -1 +0,0 @@
-[data-v-34ab69ba] .avatar-uploader .el-upload{border:1px dashed #d9d9d9;border-radius:6px;cursor:pointer;position:relative;overflow:hidden}.avatar-uploader .el-upload[data-v-34ab69ba]:hover{border-color:#409eff}.avatar-uploader-icon[data-v-34ab69ba]{font-size:28px;color:#8c939d;width:178px;height:178px;line-height:178px;text-align:center}.avatar[data-v-34ab69ba]{width:178px;height:178px;display:block}

+ 0 - 1
dist/static/css/chunk-7c5298e1.516f9bb1.css

@@ -1 +0,0 @@
-fieldset[data-v-c2106f28]{border-style:solid;border-color:#dcdfe6;border-width:1px}.margin-top-sm[data-v-c2106f28]{margin-top:20px}fieldset[data-v-8812c67a]{border-style:solid;border-color:#dcdfe6;border-width:1px}.margin-top-sm[data-v-8812c67a]{margin-top:20px}

+ 0 - 1
dist/static/css/chunk-95ac90b6.3a7928f9.css

@@ -1 +0,0 @@
-[data-v-7f6faf30] .colorBtn{width:80px!important;height:40px!important}[data-v-7f6faf30] .m-colorPicker .box.open{z-index:1000!important}

+ 0 - 1
dist/static/css/chunk-c4207b36.31192868.css

@@ -1 +0,0 @@
-[data-v-5dbb8868] .avatar-uploader .el-upload{border:1px dashed #d9d9d9;border-radius:6px;cursor:pointer;position:relative;overflow:hidden}.avatar-uploader .el-upload[data-v-5dbb8868]:hover{border-color:#409eff}.avatar-uploader-icon[data-v-5dbb8868]{font-size:28px;color:#8c939d;width:178px;height:178px;line-height:178px;text-align:center}.avatar[data-v-5dbb8868]{width:178px;height:178px;display:block}.green-text[data-v-5dbb8868]{color:green}.red-text[data-v-5dbb8868]{color:red}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/css/chunk-d5ed0cd6.5cbe9b13.css


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/css/chunk-libs.854468b4.css


BIN
dist/static/img/loginBg.238668d2.jpg


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/app.af067b6f.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-06faafad.2aab81cd.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 6
dist/static/js/chunk-107fdb58.bb729d73.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-1d9ec8ab.c4d651da.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-2d0bdbb6.352c6034.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-2d0c8694.a3443a88.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-30ca8599.35aae577.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-33c220b5.07f68482.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-3e9c6b25.ae9262c2.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-3fc04dc7.2aa1b151.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-4decaba3.10847f33.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-536dc705.b9f9f39d.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-537d7593.5b70e487.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-5c92bfb9.7e52b7ae.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-5f4cdadc.aa7f35e8.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-665577f1.dd5b3358.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-7c5298e1.db0cc428.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-95ac90b6.33943a7d.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-c4207b36.3aa5951e.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-d5ed0cd6.d2eb0448.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
dist/static/js/chunk-elementUI.d21c1ac9.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 457
dist/static/js/chunk-libs.f11dcb7f.js


+ 5 - 5
src/api/calling-patient.js

@@ -1,10 +1,10 @@
 /**
- * 病人信息接口请求
+ * 用户信息接口请求
  * @param params
  * @returns {Promise<any>}
  */
 import request from '@/utils/request'
-/** 新增病人 */
+/** 新增用户 */
 export function add(params) {
   return request({
     url: '/mgr/patient',
@@ -14,7 +14,7 @@ export function add(params) {
   })
 }
 
-/** 病人出院 */
+/** 用户出院 */
 export function remove(patientId, bedId) {
   return request({
     url: `/mgr/patient/${patientId}/${bedId}`,
@@ -23,7 +23,7 @@ export function remove(patientId, bedId) {
   })
 }
 
-/** 更新病人 */
+/** 更新用户 */
 export function update(id, params) {
   return request({
     url: `/mgr/patient/${id}`,
@@ -32,7 +32,7 @@ export function update(id, params) {
   })
 }
 
-/** 查询单个病人 */
+/** 查询单个用户 */
 export function get(id, params) {
   return request({
     url: `/mgr/patient/${id}`,

+ 14 - 0
src/api/ncs_clerk.js

@@ -55,4 +55,18 @@ export function getRoles(params) {
     loading: true,
     data: params
   })
+}
+export function getNurseByRoleId(role_id, clerk_id) {
+  return request({
+    url: `/ncs/clerk/getNurseByRoleId/${role_id}/${clerk_id}`,
+    method: 'GET'
+  })
+}
+export function updateParentById(params) {
+  return request({
+    url: '/ncs/clerk/updateParentById',
+    method: 'POST',
+    loading: true,
+    data: params
+  })
 }

+ 9 - 0
src/api/ncs_customer.js

@@ -50,4 +50,13 @@ export function remove(id) {
     method: 'DELETE',
     loading: true
   })
+}
+export function customerListByHospital(params) {
+  return request({
+    url: '/ncs/customer/customerListByHospital',
+    method: 'POST',
+    loading: true,
+    data: params,
+    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
+  })
 }

+ 16 - 0
src/api/ncs_device.js

@@ -161,4 +161,20 @@ export function updateByIds(params) {
     data: params
   })
 }
+export function getFrameByDeviceId(id) {
+  return request({
+    url: `/ncs/device/getFrameByDeviceId/${id}`,
+    method: 'GET',
+    loading: false
+  })
+}
+export function listByHospital(params) {
+  return request({
+    url: '/ncs/device/listByHospital',
+    method: 'POST',
+    loading: true,
+    data: params,
+    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
+  })
+}
 

+ 8 - 0
src/api/ncs_event.js

@@ -31,3 +31,11 @@ export function add(params) {
     data: params
   })
 }
+/** 批量修改roleId */
+export function updateRoleId(params) {
+  return request({
+    url: '/ncs/event/updateRoleId',
+    method: 'POST',
+    data: params
+  })
+}

+ 15 - 0
src/api/ncs_hospitalFrame.js

@@ -89,3 +89,18 @@ export function getFramesPartId(part_id) {
     loading: false
   })
 }
+export function getFrameByType(id, deviceId, roleId) {
+  return request({
+    url: `/ncs/frame/getFrameByType/${id}/${deviceId}/${roleId}`,
+    method: 'GET',
+    loading: false
+  })
+}
+export function updateDeviceFrameManage(params) {
+  return request({
+    url: '/ncs/frame/updateDeviceFrameManage',
+    method: 'POST',
+    loading: true,
+    data: params
+  })
+}

+ 1 - 1
src/components/AgGridLayout/src/main.vue

@@ -81,7 +81,7 @@ export default {
   },
   watch: {
     rowData(value) {
-      console.log('rows', value)
+      // console.log('rows', value)
     }
   },
   methods: {

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 0
src/icons/svg/bad_people.svg


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 0
src/icons/svg/empty_bed.svg


+ 16 - 16
src/layout/components/Navbar.vue

@@ -82,22 +82,22 @@ export default {
     }
   },
   mounted() {
-    if (Number(this.$store.getters.partId) > 0) {
-      API_Part.getExpire().then(res => {
-        if (res.timeout === 'nolimt') {
-          this.licence = '永久授权'
-        } else {
-          const days = Math.floor(((Number(res.timeout) * 1000) - new Date()) / (1000 * 60 * 60 * 24))
-          if (days > 30) {
-            this.licence = '授权有效期至: ' + new Date((Number(res.timeout) * 1000)).toLocaleString()
-          } else {
-            this.licence = '授权剩余有效期:' + days + '天,请联系售后获得授权'
-          }
-        }
-      }).catch(err => {
-        this.$message.error(err)
-      })
-    }
+    // if (Number(this.$store.getters.partId) > 0) {
+    //   API_Part.getExpire().then(res => {
+    //     if (res.timeout === 'nolimt') {
+    //       this.licence = '永久授权'
+    //     } else {
+    //       const days = Math.floor(((Number(res.timeout) * 1000) - new Date()) / (1000 * 60 * 60 * 24))
+    //       if (days > 30) {
+    //         this.licence = '授权有效期至: ' + new Date((Number(res.timeout) * 1000)).toLocaleString()
+    //       } else {
+    //         this.licence = '授权剩余有效期:' + days + '天,请联系售后获得授权'
+    //       }
+    //     }
+    //   }).catch(err => {
+    //     this.$message.error(err)
+    //   })
+    // }
   },
   methods: {
     toggleSideBar() {

+ 24 - 1
src/router/index.js

@@ -174,7 +174,7 @@ export const partRoutes = [
         path: 'index',
         component: () => import('@/views/ncs-device/nurse_watch'),
         name: 'nurse_watch',
-        meta: { title: '腕表管理', icon: 'component', noCache: true }
+        meta: { title: '腕表管理', icon: 'el-icon-watch', noCache: true }
       }
     ]
   },
@@ -248,6 +248,13 @@ export const partRoutes = [
         name: 'frameGroupEdit',
         meta: { title: '编辑区域信息', icon: 'area', noCache: true },
         hidden: true
+      },
+      {
+        path: 'nurse_watch_frame/:id?',
+        component: () => import('@/views/hospitalFrame/nurse_watch_frame'),
+        name: 'nurseWatchFrame',
+        meta: { title: '腕表管理空间', icon: 'area', noCache: true },
+        hidden: true
       }
     ]
   },
@@ -337,6 +344,22 @@ export const partRoutes = [
   },
   { path: '*', redirect: '/404', hidden: true }
 ]
+export const hospitalRoutes = [
+  {
+    path: '/hospital/ncs_frame',
+    component: Layout,
+    redirect: '/ncs_frame/index',
+    children: [
+      {
+        path: 'index',
+        component: () => import('@/views/hospital/ncs_frame/frameTreeView'),
+        name: 'hospital_frameTreeView',
+        meta: { title: '空间管理', icon: 'component', noCache: true }
+      }
+    ]
+  },
+  { path: '*', redirect: '/404', hidden: true }
+]
 export const adminRoutes = [
   {
     path: '/ncs-device',

+ 48 - 23
src/store/modules/permission.js

@@ -1,4 +1,4 @@
-import { constantRoutes, partRoutes, adminRoutes } from '@/router'
+import { constantRoutes, partRoutes, adminRoutes, hospitalRoutes } from '@/router'
 import store from '@/store'
 import { getUserRolesPermissions } from '@/api/user'
 /**
@@ -47,36 +47,61 @@ const mutations = {
   }
 }
 
+function getUserRoutes(role_id, routes) {
+  getUserRolesPermissions(role_id).then(response => {
+    return filterRoleRouter(routes, response)
+  })
+}
 const actions = {
   async generateRoutes({ commit }) {
     return new Promise(resolve => {
       const accessedRoutes = [] // asyncRoutes || []
       let lastRoutes = []
       const userInfo = store.getters.userInfo
-      if (userInfo && userInfo.founder === 1) { // 机构管理
-        if (userInfo.username === 'superadmin') { // 超级管理员
-          lastRoutes = accessedRoutes.concat(adminRoutes)
-        } else { // 普通机构管理员
-          lastRoutes = accessedRoutes.concat(partRoutes)
+      if (userInfo.username === 'superadmin') { // 超级管理员
+        lastRoutes = accessedRoutes.concat(adminRoutes)
+      } else {
+        const shopInfo = store.getters.organization // 机构信息
+        if (shopInfo.shop_type === '6') { // 为医院
+          if (userInfo && userInfo.founder === 1) { // 科室管理
+            lastRoutes = accessedRoutes.concat(hospitalRoutes)
+          } else {
+            lastRoutes = accessedRoutes.concat(getUserRoutes(userInfo.role_id, hospitalRoutes))
+          }
+        } else if (shopInfo.shop_type === '5') { // 为科室
+          if (userInfo && userInfo.founder === 1) { // 科室管理
+            lastRoutes = accessedRoutes.concat(partRoutes)
+          } else {
+            lastRoutes = accessedRoutes.concat(getUserRoutes(userInfo.role_id, partRoutes))
+          }
         }
-        commit('SET_ROUTES', lastRoutes)
-        resolve(lastRoutes)
-      } else if (userInfo) { // 普通医护人员
-        getUserRolesPermissions(userInfo.role_id).then(response => {
-          const filtered = filterRoleRouter(partRoutes, response)
-          console.log(filtered)
-          // 过滤路由之后,因为首页不会匹配,需要根据店铺类型加入不同首页
-          // let lastAccessedRouters = []
-          // if (shopt.getters.shopInfo.shop_type !== '3' && shopt.getters.shopInfo.shop_type !== '2') {
-          //   lastAccessedRouters = careIndexRouter.concat(accessedRouters)
-          // } else {
-          //   lastAccessedRouters = shopDashboardRouter.concat(accessedRouters)
-          // }
-          lastRoutes = accessedRoutes.concat(filtered)
-          commit('SET_ROUTES', lastRoutes)
-          resolve(lastRoutes)
-        })
       }
+      commit('SET_ROUTES', lastRoutes)
+      resolve(lastRoutes)
+      // if (userInfo && userInfo.founder === 1) { // 机构管理
+      //   if (userInfo.username === 'superadmin') { // 超级管理员
+      //     lastRoutes = accessedRoutes.concat(adminRoutes)
+      //   } else { // 普通机构管理员
+      //     lastRoutes = accessedRoutes.concat(partRoutes)
+      //   }
+      //   commit('SET_ROUTES', lastRoutes)
+      //   resolve(lastRoutes)
+      // } else if (userInfo) { // 普通医护人员
+      //   getUserRolesPermissions(userInfo.role_id).then(response => {
+      //     const filtered = filterRoleRouter(partRoutes, response)
+      //     console.log(filtered)
+      //     // 过滤路由之后,因为首页不会匹配,需要根据店铺类型加入不同首页
+      //     // let lastAccessedRouters = []
+      //     // if (shopt.getters.shopInfo.shop_type !== '3' && shopt.getters.shopInfo.shop_type !== '2') {
+      //     //   lastAccessedRouters = careIndexRouter.concat(accessedRouters)
+      //     // } else {
+      //     //   lastAccessedRouters = shopDashboardRouter.concat(accessedRouters)
+      //     // }
+      //     lastRoutes = accessedRoutes.concat(filtered)
+      //     commit('SET_ROUTES', lastRoutes)
+      //     resolve(lastRoutes)
+      //   })
+      // }
     })
   },
   /** 退出时清除 动态挂载的路由 */

+ 3 - 3
src/utils/device_type.js

@@ -13,9 +13,9 @@ export function returnDeviceType(value) {
     case 6:
       return 'LED点阵屏'
     case 7:
-      return '护士腕表'
-    case 8:
-      return '护工腕表'
+      return '移动设备'
+    // case 8:
+    //   return '护工腕表'
     case 9:
       return '病人腕表'
     case 10:

+ 1 - 1
src/views/customer/components/customerManager.vue

@@ -72,7 +72,7 @@
                       <el-select slot="append" v-model="formmodel.age_unit" placeholder="请选择年龄单位">
                         <el-option label="岁" value="岁" />
                         <el-option label="月" value="月" />
-                        <el-option label="天" value="" />
+                        <el-option label="天" value="" />
                       </el-select>
                     </el-input>
                   </el-form-item>

+ 19 - 6
src/views/customer/customerEdit.vue

@@ -5,13 +5,13 @@
         <el-form :model="formmodel" :rules="rules" ref="editForm" label-width="140px">
           <el-row>
             <el-col :span="8">
-              <el-form-item label="病人姓名" prop="named">
+              <el-form-item label="用户姓名" prop="named">
                 <el-input v-model="formmodel.named" clearable placeholder="请输入姓名" :maxlength="20"></el-input>
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="病人编号">
-                <el-input v-model="formmodel.card_no" clearable placeholder="请输入病人编号" :maxlength="20"></el-input>
+              <el-form-item label="用户编号">
+                <el-input v-model="formmodel.card_no" clearable placeholder="请输入用户编号" :maxlength="20"></el-input>
               </el-form-item>
             </el-col>
             <el-col :span="8">
@@ -20,7 +20,7 @@
                   <el-select slot="append" v-model="formmodel.age_unit" placeholder="请选择年龄单位">
                     <el-option label="岁" value="岁" />
                     <el-option label="月" value="月" />
-                    <el-option label="天" value="" />
+                    <el-option label="天" value="" />
                   </el-select>
                 </el-input>
               </el-form-item>
@@ -31,7 +31,7 @@
             <el-col :span="8">
               <el-form-item label="性别" class="form-item-sex">
                 <el-radio v-model="formmodel.sex" :label="1">男</el-radio>
-                <el-radio v-model="formmodel.sex" :label="2">女</el-radio>
+                <el-radio v-model="formmodel.sex" :label="0">女</el-radio>
                 <el-radio v-model="formmodel.sex" :label="3">未知</el-radio>
               </el-form-item>
             </el-col>
@@ -213,7 +213,7 @@
           </el-form>
         </el-dialog>
       </el-tab-pane>
-      <el-tab-pane v-if="customerId != 0" label="病人亲属" name="customer-relative">
+      <el-tab-pane v-if="customerId != 0" label="用户亲属" name="customer-relative">
         <customer-relative :member-id="memberId"></customer-relative>
       </el-tab-pane>
     </el-tabs>
@@ -369,6 +369,13 @@
             _this.formmodel.doctor_mapping_id = null
             _this.formmodel.nurse_Mapping_id = null
             _this.formmodel.worker_mapping_id = null
+            if (_this.formmodel.in_date) {
+              _this.formmodel.in_date = _this.formmodel.in_date * 1000
+            }
+            if (_this.formmodel.out_date) {
+              _this.formmodel.out_date = _this.formmodel.out_date * 1000
+            }
+            console.log(_this.formmodel.in_date, _this.formmodel.out_date)
             _this.getRemarks()
             if (res.list !== null) {
               _this.nurseData.forEach((item, index)=> {
@@ -413,6 +420,12 @@
         this.$refs[formName].validate(valid => {
           if (valid) {
             this.isDisabled = true
+            if (this.formmodel.in_date) {
+              this.formmodel.in_date = this.formmodel.in_date / 1000
+            }
+            if (this.formmodel.out_date) {
+              this.formmodel.out_date = this.formmodel.out_date / 1000
+            }
             if (this.customerId === 0) {
               this.formmodel.frame_id = this.frameId
               this.formmodel.list = this.nurseConfigDtos

+ 4 - 4
src/views/customer/customer_relative.vue

@@ -49,7 +49,7 @@
       </el-pagination>
     </en-table-layout>
 
-    <el-dialog title="添加病人亲属" :visible.sync="dialogAddVisible" :append-to-body="true" width="80%">
+    <el-dialog title="添加用户亲属" :visible.sync="dialogAddVisible" :append-to-body="true" width="80%">
       <el-form :model="formmodel" :rules="rules" ref="editForm" label-width="140px">
         <el-row>
           <el-col :span="12">
@@ -67,7 +67,7 @@
           <el-col :span="12">
             <el-form-item label="性别" class="form-item-sex">
               <el-radio v-model="formmodel.sex" :label="1">男</el-radio>
-              <el-radio v-model="formmodel.sex" :label="2">女</el-radio>
+              <el-radio v-model="formmodel.sex" :label="0">女</el-radio>
               <el-radio v-model="formmodel.sex" :label="3">未知</el-radio>
             </el-form-item>
           </el-col>
@@ -192,7 +192,7 @@
       },
       /** 单条数据删除处理 */
       handlerDelete(ids) {
-        let test = '你确定要删除此病人亲属信息?'
+        let test = '你确定要删除此用户亲属信息?'
         let _this = this
         this.$confirm(test, '警告', {
           confirmButtonText: '确定',
@@ -255,7 +255,7 @@
       formatterSex(row, column, cellValue) {
         if (row.sex === 1) {
           return '男'
-        } else if (row.sex === 2) {
+        } else if (row.sex === 0) {
           return '女'
         } else {
           return '未知'

+ 62 - 25
src/views/customer/list.vue

@@ -4,18 +4,18 @@
     <div class="toolbar" style="padding-left: 20px">
       <el-form :inline="true" label-width="120px">
         <el-form-item>
-          <el-input v-model="searchStr" placeholder="请输入病人姓名、编号、病床" clearable @clear="clickSearch" @keyup.native.enter="clickSearch">
+          <el-input v-model="searchStr" placeholder="请输入用户姓名、编号、病床" clearable @clear="clickSearch" @keyup.native.enter="clickSearch">
             <el-button slot="append" icon="el-icon-search" @click="clickSearch"></el-button>
           </el-input>
         </el-form-item>
-        <el-form-item label="病人状态">
-          <el-select v-model="callingType" placeholder="请选择病人状态" clearable @change="changeStatus">
+        <el-form-item label="用户状态">
+          <el-select v-model="callingType" placeholder="请选择用户状态" clearable @change="changeStatus">
             <el-option label="在院" :value="0" />
             <el-option label="已出院" :value="1" />
           </el-select>
         </el-form-item>
         <el-form-item>
-          <el-button type="danger" :disabled="multipleSelection.length === 0" @click="batchDelete">批量删除</el-button>
+          <el-button type="danger" @click="batchDelete">批量删除</el-button>
         </el-form-item>
       </el-form>
     </div>
@@ -45,7 +45,7 @@
               @current-change="handlePageCurrentChange"
       />
     </ag-grid-layout>
-    <el-dialog title="编辑病人信息" :visible.sync="dialogAddVisible" :append-to-body="true" width="85%">
+    <el-dialog title="编辑用户信息" :visible.sync="dialogAddVisible" :append-to-body="true" width="85%">
       <customer-edit :customer-id="customerId" :frame-id="frameId" @saved="handlePatientFinished"></customer-edit>
     </el-dialog>
 
@@ -70,17 +70,18 @@
 
 <script>
   import * as API_customer from '@/api/ncs_customer'
-  import {unix2Date} from "@/utils/Foundation"
+  import { unixToDate } from "@/utils/Foundation"
   import customerEdit from '@/views/customer/customerEdit'
   import * as RegExp from "@/utils/RegExp"
   import * as API_hospitalFrame from "@/api/ncs_hospitalFrame"
   import { AG_GRID_LOCALE_CN } from '@/utils/AgGridVueLocaleCn'
   import {param} from "@/utils"
   import ButtonCellRender from "@/components/AgGridCellRender/ButtonCellRender";
+  import RadioFilter from "@/components/AgGridCustomFilter/RadioFilter";
 
   export default {
     name: 'customer_list',
-    components: { customerEdit, ButtonCellRender },
+    components: { customerEdit, ButtonCellRender, RadioFilter },
     data: function() {
       return {
         /** 列表loading状态 */
@@ -117,6 +118,14 @@
         columnApi: null,
         localeText: AG_GRID_LOCALE_CN,
         rowSelection: null,
+        sexTransfer: [
+          { key: '男', value: 1, color: 'green' },
+          { key: '女', value: 0, color: 'red' }
+        ],
+        statusTransfer: [
+          { key: '已出院', value: 1,  color: 'orange' },
+          { key: '在院', value: 0,  color: 'green' }
+        ]
       }
     },
     computed: {
@@ -138,13 +147,27 @@
           resizable: false,
           valueGetter: this.hashValueGetter
         },
-        { headerName: '姓名', field: 'named', sortable: true, filter: 'agTextColumnFilter', width: 160 },
-        { headerName: '病人编号', field: 'card_no', sortable: true, filter: true, width: 170 },
-        { headerName: '年龄', field: 'age', sortable: true, filter: false, valueFormatter: this.formatterAge, width: 100 },
-        { headerName: '性别', field: 'sex', sortable: true, filter: false, valueFormatter: this.formatterSex, width: 100 },
-        { headerName: '住院时间', field: 'in_date', valueFormatter: this.formatterDate, sortable: true, filter: false, width: 220 },
-        { headerName: '状态', field: 'status', sortable: true, filter: false, valueFormatter: this.formatterStatus, width: 100 },
-        { headerName: '病床', field: 'full_name', sortable: true, filter: true, width: 120 },
+        { headerName: '姓名', field: 'named', sortable: true, filter: 'agTextColumnFilter', minWidth: 160 },
+        { headerName: '用户编号', field: 'card_no', sortable: true, filter: true, minWidth: 170 },
+        { headerName: '年龄', field: 'age', sortable: true, filter: 'agNumberColumnFilter', valueFormatter: this.formatterAge, minWidth: 100 },
+        { headerName: '性别', field: 'sex', sortable: true, filter: true, cellRenderer: this.formatterSex, minWidth: 100, filterFramework: 'RadioFilter',
+          filterParams: {
+            listData: this.sexTransfer
+          }
+        },
+        { headerName: '住院时间', field: 'in_date', valueFormatter: this.formatterDate, sortable: true, minWidth: 220, filter: 'agDateColumnFilter',
+          filterParams: {
+            comparator: (filterLocalDateAtMidnight, cellValue) => { // 所有数据都由服务器端过滤,此处只需返回0 即可
+              return 0
+            }
+          }
+        },
+        { headerName: '状态', field: 'status', sortable: true, filter: false, cellRenderer: this.formatterStatus, minWidth: 100, filterFramework: 'RadioFilter',
+          filterParams: {
+            listData: this.statusTransfer
+          }
+        },
+        { headerName: '病床', field: 'full_name', sortable: true, filter: true, minWidth: 120 },
         { headerName: '操作任务', field: 'id',
           cellRendererFramework: 'ButtonCellRender',
           cellRendererParams: param => {
@@ -223,6 +246,7 @@
       GET_List() {
         this.loading = true
         this.gridApi.showLoadingOverlay()
+        this.gridApi.sizeColumnsToFit()
         API_customer.getList(this.params).then(res => {
           this.loading = false
           this.tableData = res.data
@@ -251,7 +275,7 @@
       },
       /** 单条数据删除处理 */
       handlerDelete(ids) {
-        let test = '你确定要删除此病人信息?'
+        let test = '你确定要删除此用户信息?'
         let _this = this
         this.$confirm(test, '警告', {
           confirmButtonText: '确定',
@@ -272,8 +296,13 @@
       },
       /** 批量数据删除处理(删除选中的行) */
       batchDelete: function() {
+        let rows = this.gridApi.getSelectedRows()
+        if (rows.length === 0) {
+          this.$message({ type: 'info', message: '请先勾选需要删除的数据' })
+          return
+        }
         const ids = []
-        this.multipleSelection.forEach(function(item) {
+        rows.forEach(function (item) {
           ids.push(item.id)
         })
         this.handlerDelete(ids.join(','), 'del')
@@ -320,17 +349,19 @@
       formatterAge(param) {
         return param.data.age + param.data.age_unit
       },
-      formatterStatus(param) {
-        if (param.value) {
-          return '已出院'
+      formatterStatus(params) {
+        if (params.value === null || params.value === undefined) return ''
+        const item = this.statusTransfer.filter(p => p.value === params.value)[0]
+        if (item) {
+          return '<span style="color:' + item.color + ';">' + item.key + '</span>'
         } else {
-          return '在院'
+          return '未知'
         }
       },
       formatterDate(param) {
-        let date = unix2Date(param.data.in_date, 'yyyy-MM-dd')
+        let date = unixToDate(param.data.in_date, 'yyyy-MM-dd')
         if (param.data.out_date) {
-          date += '至' + unix2Date(param.data.out_date, 'yyyy-MM-dd')
+          date += '至' + unixToDate(param.data.out_date, 'yyyy-MM-dd')
         } else {
           if (param.data.in_date) {
             date += '至今'
@@ -366,12 +397,18 @@
         })
       },
       clickSearch(value) {
-        this.params.filerStr = this.searchStr
+        this.params.query = this.searchStr
         this.GET_List()
       },
       /** 性别格式化 */
-      formatterSex(row) {
-        return row.data.sex === 1 ? '男' :  row.data.sex === 2 ? '女' : '未知'
+      formatterSex(params) {
+        if (params.value === null || params.value === undefined) return ''
+        const item = this.sexTransfer.filter(p => p.value === params.value)[0]
+        if (item) {
+          return '<span style="color:' + item.color + ';">' + item.key + '</span>'
+        } else {
+          return '未知'
+        }
       },
       filterModifed(param) {
         let model = param.api.getFilterModel()

+ 6 - 6
src/views/dashboard/calling-admin/components/partUserManager.vue

@@ -29,7 +29,7 @@
         />
 
         <el-table-column prop="id" sortable="custom" label="ID" width="200" align="center" />
-        <el-table-column prop="user_name" sortable="custom" label="登账号" width="300" align="center" />
+        <el-table-column prop="user_name" sortable="custom" label="登账号" width="300" align="center" />
         <el-table-column prop="user_password" sortable="custom" label="密码" width="300" align="center" />
 
         <el-table-column
@@ -67,11 +67,11 @@
       <div>
         <el-form ref="editform" :rules="rules" label-width="120px" :model="formmodel">
 
-          <el-form-item label="登账号" prop="user_name">
-            <el-input v-model="formmodel.user_name" clearable :maxlength="20" placeholder="请输入登账号" />
+          <el-form-item label="登账号" prop="user_name">
+            <el-input v-model="formmodel.user_name" clearable :maxlength="20" placeholder="请输入登账号" />
           </el-form-item>
 
-          <el-form-item label="登密码" prop="user_password">
+          <el-form-item label="登密码" prop="user_password">
             <el-input v-model="formmodel.user_password" clearable :maxlength="20" placeholder="请输入密码" />
           </el-form-item>
 
@@ -114,10 +114,10 @@ export default {
       /** 表单校验 */
       rules: {
         user_name: [
-          { required: true, message: '请输入登账号', trigger: 'blur' }
+          { required: true, message: '请输入登账号', trigger: 'blur' }
         ],
         user_password: [
-          { required: true, message: '请输入登密码', trigger: 'blur' }
+          { required: true, message: '请输入登密码', trigger: 'blur' }
         ]
       },
       /** 列表参数 */

+ 2 - 2
src/views/dashboard/calling/components/PanelGroup.vue

@@ -103,8 +103,8 @@ export default {
 
 <style lang="scss" title="style1" scoped>
   :root{
-    --icon-special-care:#f4516c;
-    --icon-primary-care:#34bfa3;
+    --icon-special-care: #f3556f;
+    --icon-primary-care: #469787;
   }
 .panel-group {
   margin-top: 0px;

+ 4 - 4
src/views/dashboard/calling/components/SickBedBoard.vue

@@ -96,7 +96,7 @@
                   <el-form-item label="性别" prop="patient_sex">
                     <el-select v-model="formmodel.patient_sex" placeholder="请选择性别" clearable>
                       <el-option label="男" :value="1" />
-                      <el-option label="女" :value="2" />
+                      <el-option label="女" :value="0" />
                       <el-option label="未知" :value="3" />
                     </el-select>
                   </el-form-item>
@@ -383,7 +383,7 @@ export default {
         notice_text: null
       },
       /** 弹出窗口标题信息 */
-      formtitle: '编辑病人信息',
+      formtitle: '编辑用户信息',
       formshow: false, // 编辑表单显示开关
       formshow1: false, // 换床dialog
       noticehow: false, // 推送通知弹窗
@@ -513,7 +513,7 @@ export default {
     /** 入院登记 */
     inHospital(bedinfo) {
       this.editflag = 0
-      this.formtitle = '病人入院登记【' + bedinfo.DEVICE_ROOM_NUM + '房' + bedinfo.DEVICE_BED_NUM + '床】'
+      this.formtitle = '用户入院登记【' + bedinfo.DEVICE_ROOM_NUM + '房' + bedinfo.DEVICE_BED_NUM + '床】'
       this.formshow = true
       this.formmodel = {
         bed_id: bedinfo.ID,
@@ -570,7 +570,7 @@ export default {
         this.$refs.editform.resetFields()
       }
       this.getPatientInfo(bedinfo.DEVICE_HUMAN_ID)
-      this.formtitle = '编辑病人资料【' + bedinfo.DEVICE_ROOM_NUM + '房' + bedinfo.DEVICE_BED_NUM + '床】'
+      this.formtitle = '编辑用户资料【' + bedinfo.DEVICE_ROOM_NUM + '房' + bedinfo.DEVICE_BED_NUM + '床】'
       this.formshow = true
     },
     getPatientInfo(id) {

+ 2 - 2
src/views/dashboard/calling/index.vue

@@ -71,7 +71,7 @@
       </el-col>
     </el-row>
 
-    <el-row :gutter="20">
+    <el-row :gutter="20" style="margin-top: 20px">
       <el-col :span="16">
         <el-card style="maring:10px">
           <div slot="header" class="clearfix">
@@ -93,7 +93,7 @@
       <el-col :span="8">
         <el-card>
           <div slot="header" class="clearfix">
-            <span style="float: left">最近患者备注</span>
+            <span style="float: left">最近用户备注</span>
             <el-link type="primary" style="float: right" @click="goMove('customerList')">更多</el-link>
           </div>
           <div style="clear:both;font-size: 14px;height: 300px;">

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1212 - 0
src/views/hospital/ncs_customer/customerManager.vue


+ 590 - 0
src/views/hospital/ncs_device/deviceManager.vue

@@ -0,0 +1,590 @@
+<template>
+  <div>
+    <ag-grid-layout
+      toolbar
+      :table-height="tableHeight"
+      theme="ag-theme-alpine"
+      :column-defs="columnDefs"
+      :row-data="rowData"
+      :locale-text="localeText"
+      :grid-options="gridOptions"
+      :default-col-def="defaultColDef"
+      :animate-rows="true"
+      :row-selection="rowSelection"
+      :framework-components="frameworkComponents"
+      @filterChanged="filterModifed"
+      @sortChanged="gridSortChange"
+    >
+      <div slot="toolbar" class="inner-toolbar">
+        <div class="toolbar-search">
+          <en-table-search placeholder="请输入搜索关键字" @search="handlerSearch" />
+        </div>
+        <div v-if="hasAdd" class="toolbar-btns">
+          <el-button type="primary" size="mini" @click="handleAdd">新增设备</el-button>
+        </div>
+      </div>
+      <el-pagination
+        v-if="pageData"
+        slot="pagination"
+        :current-page="pageData.page_no"
+        :page-sizes="[10, 20, 50, 100]"
+        :page-size="pageData.page_size"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="pageData.data_total"
+        @size-change="handlePageSizeChange"
+        @current-change="handlePageCurrentChange"
+      />
+    </ag-grid-layout>
+
+    <!-- 设备编辑弹窗 -->
+    <el-dialog :title="deviceEditTitle" :visible.sync="deviceDialogVisible" width="60%">
+      <el-form ref="deviceEditForm" :rules="deviceRules" label-width="120px" :model="deviceModel">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="设备类型" prop="device_type">
+              <el-select v-model="deviceModel.device_type" placeholder="请选择设备类型" :disabled="deviceTypeDisabled" clearable @change="deviceTypeChange">
+                <el-option v-for="(item,index) in deviceTypeTransfer" :key="index" :label="item.key" :value="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="设备别名" prop="name">
+              <el-input v-model="deviceModel.name" clearable :maxlength="20" placeholder="请输入设备别名" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="出厂编号" prop="code">
+              <el-input v-model="deviceModel.code" clearable placeholder="请输入出厂编号" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="设备型号" prop="model">
+              <el-input v-model="deviceModel.model" clearable placeholder="请输入设备型号" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="有线物理地址" prop="eth_mac">
+              <el-input v-model="deviceModel.eth_mac" clearable placeholder="请输入物理MAC地址" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="有线IP地址" prop="eth_ip">
+              <el-input v-model="deviceModel.eth_ip" clearable placeholder="请输入IP地址" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="WIFI物理地址" prop="wifi_mac">
+              <el-input v-model="deviceModel.wifi_mac" clearable placeholder="请输入WIFI MAC地址" readonly />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="WIFIIP地址" prop="wifi_ip">
+              <el-input v-model="deviceModel.wifi_ip" clearable placeholder="请输入WIFI IP地址" readonly />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="软件版本" prop="soft_ver">
+              <el-input v-model="deviceModel.soft_ver" clearable placeholder="请输入软件版本号" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="硬件版本" prop="hard_ver">
+              <el-input v-model="deviceModel.hard_ver" clearable placeholder="请输入硬件版本号" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="WIFI热点">
+              <el-input v-model="deviceModel.wifi_hostname" :readonly="true" clearable placeholder="请输入WIFI热点名称" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="WIFI密码">
+              <el-input v-model="deviceModel.wifi_password" :readonly="true" clearable placeholder="请输入WIFI热点密码" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="设备位置">
+              <span>{{ deviceModel.full_name }}</span>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="后备设备ID">
+              <el-input v-model="deviceModel.backup_id" clearable placeholder="" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="设备优先级">
+              <el-input-number v-model="deviceModel.priority" controls-position="right" :min="1" :max="99" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="是否启用">
+              <el-checkbox v-model="deviceModel.status" :true-label="1" :false-label="0">启用设备</el-checkbox>
+              <!--              <el-radio v-model="formmodel.status" :label="1">启用</el-radio>-->
+              <!--              <el-radio v-model="formmodel.status" :label="0">不启用</el-radio>-->
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row v-if="hasRoleId">
+          <el-col :span="12">
+            <el-form-item label="适用角色" prop="role_id">
+              <el-select v-model="deviceModel.role_id" placeholder="适用角色" clearable>
+                <el-option v-for="item in rolesOptions" :key="item.role_id" :label="item.role_name" :value="item.role_id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="handlerFormSubmit('deviceEditForm')">确 定</el-button>
+      </div>
+    </el-dialog>
+    <!-- 设备编辑弹窗 -->
+  </div>
+</template>
+
+<script>
+import { AG_GRID_LOCALE_CN } from '@/utils/AgGridVueLocaleCn'
+import { unix2Date } from '@/utils/Foundation'
+import ButtonCellRender from '@/components/AgGridCellRender/ButtonCellRender'
+import ListFilter from '@/components/AgGridCustomFilter/ListFilter'
+import RadioFilter from '@/components/AgGridCustomFilter/RadioFilter'
+import * as API_Device from '@/api/ncs_device'
+import * as clerk_API from '@/api/ncs_clerk'
+export default {
+  name: 'DeviceManager',
+  components: { ButtonCellRender, ListFilter, RadioFilter },
+  props: {
+    frame: {
+      type: Object,
+      default: () => {}
+    }
+  },
+  data() {
+    return {
+      /** ag-grid参数 **/
+      pageData: {}, // 翻页数据
+      errorId: null,
+      shopVisible: false,
+      columnDefs: null,
+      rowData: null,
+      defaultColDef: null,
+      gridOptions: null,
+      gridApi: null,
+      columnApi: null,
+      localeText: AG_GRID_LOCALE_CN,
+      filterState: null,
+      rowSelection: null,
+      frameworkComponents: null,
+      /** 列表参数 */
+      params: {
+        page_size: 20,
+        page_no: 1,
+        hospital_id: this.$store.getters.partId,
+        fixedCondition: '1=1'
+      },
+      /** device 弹窗 **/
+      deviceDialogVisible: false,
+      deviceEditTitle: '添加设备',
+      deviceModel: {},
+      deviceTypeDisabled: false,
+      deviceRules: {
+        name: [
+          this.MixinRequired('请输入设备别名!')
+        ],
+        device_type: [
+          { required: true, message: '请选择设备类型', trigger: 'blur' }
+        ],
+        code: [
+          { required: true, message: '请输入设备编码', trigger: 'blur' }
+        ],
+        model: [
+          { required: true, message: '请输入设备型号', trigger: 'blur' }
+        ],
+        eth_mac: [
+          { required: true, message: '请输入设备MAC地址', trigger: 'blur' },
+          { pattern: /^([0-9A-Fa-f]{2}:?){6}/gi, message: '请输入正确的MAC地址', trigger: 'blur' }
+        ],
+        frame_id: [
+          { required: Object.keys(this.frame).length === 0, message: '请选安装位置!', trigger: 'blur' } // 没有传入frame 属性,必须选择安装位置
+        ],
+        role_id: [
+          { required: true, message: '请选择适用人', trigger: 'blur' }
+        ]
+      },
+      /** 设备类型转换数组 **/
+      deviceTypeTransfer: [
+        { key: '护士主机', value: 1 },
+        { key: '医生主机', value: 2 },
+        { key: '门口机', value: 3 },
+        { key: '病床分机', value: 4 },
+        { key: 'LCD走廊屏', value: 5 },
+        { key: 'LED点阵屏', value: 6 },
+        { key: '移动设备', value: 7 },
+        // { key: '护工腕表', value: 8 },
+        { key: '病人腕表', value: 9 },
+        { key: '手机App', value: 10 },
+        { key: '总线转换盒', value: 11 },
+        { key: '模拟分机', value: 12 },
+        { key: '模拟紧急按钮', value: 13 },
+        { key: '模拟门灯', value: 14 },
+        { key: '遥控器', value: 15 },
+        { key: '信标', value: 16 },
+        { key: '看板', value: 17 }
+      ],
+      deviceStatusTransfer: [
+        { key: '启用', value: 1, color: 'green' },
+        { key: '未启用', value: 0, color: 'red' }
+      ],
+      rolesOptions: [],
+      hasRoleId: false,
+      hasAdd: true
+    }
+  },
+  computed: {
+    tableHeight() {
+      return Object.keys(this.frame).length === 0 ? this.mainAreaHeight - 130 : this.mainAreaHeight - 174
+    },
+    frameSelectabled() { return Object.keys(this.frame).length > 0 }
+  },
+  watch: {
+    frame(val, oldvalue) {
+      console.log('watch22', val)
+      if (val.type === 1) {
+        this.params.fixedCondition = '1=1'
+        this.hasAdd = false
+      } else {
+        this.params.fixedCondition = Object.keys(this.frame).length === 0 ? '1=1' : ' frame_id =' + this.frame.id
+        this.hasAdd = true
+      }
+      this.getList()
+    }
+  },
+  beforeMount() {
+    this.gridOptions = {
+    }
+    this.columnDefs = [
+      {
+        headerName: '#',
+        headerCheckboxSelection: true,
+        headerCheckboxSelectionFilteredOnly: true,
+        checkboxSelection: true,
+        sortable: false, filter: false,
+        width: 80,
+        resizable: false,
+        valueGetter: this.hashValueGetter
+      },
+      // { headerName: 'ID', field: 'id', sortable: true, filter: 'agNumberColumnFilter', width: 100 },
+      { headerName: '设备类型', field: 'device_type', sortable: true, filterFramework: 'ListFilter', width: 160,
+        filterParams: {
+          listData: this.deviceTypeTransfer
+        },
+        valueGetter: this.deviceTypeGetter
+      },
+      // lockPosition 锁定位置,会在第一列
+      // lockPinned = true 不能拖动然后固定
+      // resizeable 单元个大小是否可以调整
+      { headerName: '设备别名', field: 'name', sortable: true, filter: 'agTextColumnFilter' },
+      { headerName: '设备状态', field: 'status', sortable: true, filterFramework: 'RadioFilter',
+        filterParams: {
+          listData: this.deviceStatusTransfer
+        },
+        cellRenderer: this.deviceStatusFormatter
+      },
+
+      { headerName: '部署位置', field: 'full_name', sortable: true, filter: 'agTextColumnFilter', valueFormatter: this.fullNameFormatter },
+      { headerName: '以太网MAC地址', field: 'eth_mac', sortable: true, filter: 'agTextColumnFilter' },
+      { headerName: '以太网IP地址', field: 'eth_ip', sortable: true, filter: 'agTextColumnFilter' },
+      { headerName: '通讯端口', field: 'eth_ip_port', sortable: true, filter: 'agNumberColumnFilter' },
+      { headerName: '设备型号', field: 'model', sortable: true, filter: 'agTextColumnFilter' },
+      { headerName: '出厂编号', field: 'code', sortable: true, filter: 'agTextColumnFilter' },
+      { headerName: '软件版本', field: 'soft_ver', sortable: true, filter: 'agTextColumnFilter' },
+      { headerName: '硬件版本', field: 'hard_ver', sortable: true, filter: 'agTextColumnFilter' },
+      { headerName: '无线MAC地址', field: 'wifi_mac', sortable: true, filter: 'agTextColumnFilter' },
+      { headerName: '无线IP地址', field: 'wifi_ip', sortable: true, filter: 'agTextColumnFilter' },
+      { headerName: 'SIP账号', field: 'sip_id', sortable: true, filter: 'agTextColumnFilter' },
+      { headerName: '更新时间', field: 'update_time', sortable: true, filter: 'agDateColumnFilter', valueFormatter: this.unixDateFormatter, filterParams: {
+        comparator: (filterLocalDateAtMidnight, cellValue) => { // 所有数据都由服务器端过滤,此处只需返回0 即可
+          return 0
+        }
+      }},
+      { headerName: '编辑', field: 'shop_id',
+        cellRendererFramework: 'ButtonCellRender',
+        cellRendererParams: {
+          onClick: this.handleEdit,
+          label: '编辑',
+          buttonType: 'primary',
+          buttonSize: 'mini'
+        },
+        filter: false,
+        pinned: 'right',
+        lockPinned: true,
+        width: 90,
+        resizable: false,
+        sortable: false },
+      { headerName: '删除', field: 'shop_id',
+        cellRendererFramework: 'ButtonCellRender',
+        cellRendererParams: param => {
+          return {
+            onClick: this.deleteSingle,
+            label: '删除',
+            buttonType: 'danger',
+            buttonSize: 'mini',
+            disabled: param.data['member_name'] === 'superadmin'
+          }
+        },
+        pinned: 'right',
+        lockPinned: true,
+        width: 90,
+        resizable: false,
+        filter: false,
+        sortable: false }
+    ]
+    this.defaultColDef = {
+      // filter: 'agTextColumnFilter',
+      sortable: true,
+      resizable: true,
+      // comparator: this.dateCustomComparator,
+      filterParams: {
+        debounceMs: 500,
+        newRowsAction: 'keep',
+        textCustomComparator: this.textCustomComparator
+      }
+    }
+    this.rowSelection = 'multiple'
+  },
+  mounted() {
+    this.gridApi = this.gridOptions.api
+    this.gridColumnApi = this.gridOptions.columnApi
+    this.gridColumnApi.applyColumnState({
+      state: [
+        {
+          colId: 'status',
+          sort: 'asc'
+        }
+      ]
+    })
+  },
+  methods: {
+    /** 加载列表数据 */
+    getList() {
+      const param = this.MixinClone(this.params)
+      this.gridApi.showLoadingOverlay()
+      API_Device.listByHospital(param).then(response => {
+        this.rowData = [...response.data]
+        this.pageData = {
+          page_no: response.page_no,
+          page_size: response.page_size,
+          data_total: response.data_total
+        }
+      }).catch(err => {
+        this.$message.error(err)
+      })
+    },
+
+    /**
+     * 过滤状态发生变化,发送到服务器检索数据
+     */
+    filterModifed(param) {
+      var model = param.api.getFilterModel()
+      this.params.filter = JSON.stringify(model)
+      this.getList()
+    },
+    gridSortChange(param) {
+      console.log('sortparam', param)
+      const columnState = param.columnApi.getColumnState()
+      // 排序状态
+      const sortState = columnState.filter(function(s) {
+        return s.sort != null
+      }).map(function(s) {
+        return {
+          colId: s.colId,
+          sort: s.sort,
+          sortIndex: s.sortIndex
+        }
+      }).sort(function(a, b) {
+        return a.sortIndex - b.sortIndex
+      })
+      if (sortState.length > 0) {
+        if (sortState.length === 1) {
+          this.params.sort = sortState[0].colId
+          this.params.dir = sortState[0].sort
+        } else {
+          let sortstring = ''
+          sortState.forEach(function(item) {
+            sortstring += item.colId + ' ' + item.sort + ','
+          })
+          this.params.sort = sortstring.substring(0, sortstring.length - 1)
+          this.params.dir = ' '
+        }
+      } else {
+        delete this.params.sort
+        delete this.params.dir
+      }
+
+      this.getList()
+    },
+    /** 处理搜索 */
+    handlerSearch(keywords) {
+      this.params.query = keywords
+      this.getList()
+    },
+    /** 获取设备类型文字显示,从deviceTypeTransfer 中找出value值对应的key显示出来 */
+    deviceTypeGetter(params) {
+      const gridVal = params.data.device_type
+      return this.deviceTypeTransfer.filter(p => p.value === gridVal).map(p => p.key)
+    },
+    /** 格式化时间函数 */
+    unixDateFormatter(param) {
+      if (!param.value) return ''
+      return unix2Date(param.value * 1000)
+    },
+    /** 设备状态格式化 **/
+    deviceStatusFormatter(params) {
+      if (params.value === null || params.value === undefined) return ''
+      const item = this.deviceStatusTransfer.filter(p => p.value === params.value)[0]
+      if (item) {
+        return '<span style="color:' + item.color + ';">' + item.key + '</span>'
+      } else {
+        return ''
+      }
+    },
+    fullNameFormatter(params) {
+      if (params.data.type === 3) {
+        return params.value
+      } else {
+        return params.data.shop_name + '-' + params.value
+      }
+    },
+    /** 删除设备 **/
+    deleteSingle(row) {
+      this.handlerDelete(row.id)
+    },
+    /** 删除设备 **/
+    handlerDelete(id) {
+      this.$confirm('删除操作后数据不可复原,您确定要删除此数据?', '警告', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        API_Device.remove(id).then(
+          response => {
+            this.getList()
+          }
+        ).catch(response => {
+          this.$message({
+            type: 'info',
+            message: response.message
+          })
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消删除'
+        })
+      })
+    },
+    /** 设备类型选中变化  **/
+    deviceTypeChange(val) {
+      this.deviceRules.eth_mac[0].required = !(val === 12 || val === 13 || val === 14)
+      this.hasRoleId = val === 7
+    },
+    /** 添加设备事件 **/
+    handleAdd() {
+      this.deviceModel = {
+        soft_ver: 'SV1.0',
+        hard_ver: 'HV1.0',
+        code: 'C' + parseInt(Math.random() * 100000),
+        model: 'M' + parseInt(Math.random() * 100000)
+      }
+      if (Object.keys(this.frame).length > 0) {
+        this.$set(this.deviceModel, 'frame_id', this.frame.id)
+      }
+      delete this.deviceModel.id
+      this.hasRoleId = false
+      this.getRoles({ page_size: 200, page_no: 1, fixedCondition: ' shop_id = -1', sort: ' role_id', dir: 'desc' })
+      this.deviceEditTitle = '添加设备'
+      this.deviceDialogVisible = true
+      this.deviceTypeDisabled = false // 新增设备可以选择设备类型
+      this.deviceModel.full_name = this.frame.full_name
+    },
+    /** 修改设备  **/
+    handleEdit(params) {
+      this.getRoles({ page_size: 200, page_no: 1, fixedCondition: ' shop_id = -1', sort: ' role_id', dir: 'desc' })
+      console.log('param', params)
+      this.hasRoleId = params.device_type === 7
+      this.deviceModel = {
+        ...params
+      }
+      this.deviceEditTitle = '修改设备'
+      this.deviceDialogVisible = true
+      this.deviceTypeDisabled = true // 修改设备时,不能改变设备类型
+    },
+    /** 新增 提交表单 */
+    handlerFormSubmit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          /** 新增 */
+          if (!this.deviceModel.id) {
+            this.deviceModel.part_id = this.frame.part_id
+            this.deviceModel.frame_id = this.frame.id
+            API_Device.add(this.deviceModel).then(() => {
+              this.$message.success('保存成功!')
+              this.deviceDialogVisible = false
+              this.getList()
+            }).catch(err => {
+              this.$message.error(err)
+            })
+          } else {
+            /** 修改 */
+            API_Device.update(this.deviceModel.id, this.deviceModel).then(() => {
+              this.$message.success('修改成功!')
+              this.deviceDialogVisible = false
+              this.getList()
+            }).catch(error => {
+              this.$message.error(error)
+            })
+          }
+        }
+      })
+    },
+    /** 分页大小发生改变 */
+    handlePageSizeChange(size) {
+      this.params.page_size = size
+      this.getList()
+    },
+
+    /** 分页页数发生改变 */
+    handlePageCurrentChange(page) {
+      this.params.page_no = page
+      this.getList()
+    },
+    getRoles(param) {
+      // 获取角色
+      clerk_API.getRoles(param).then(response => {
+        this.rolesOptions = response.data
+      })
+    }
+
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 780 - 0
src/views/hospital/ncs_frame/frameTreeView.vue

@@ -0,0 +1,780 @@
+<template>
+  <div>
+    <el-container :style="{height: asideHeight+'px'}">
+      <el-aside width="280px" style="border-color: rgb(238, 241, 246)">
+        <div class="el-row--flex">
+          <el-input
+            v-model="filterText"
+            placeholder="输入关键字进行过滤"
+            clearable
+          />
+<!--          <el-button-->
+<!--            type="text"-->
+<!--            size="mini"-->
+<!--            style="margin-left: 10px;color: #67C23A"-->
+<!--            @click="quickCreateFrame"-->
+<!--          >快速创建-->
+<!--          </el-button>-->
+
+        </div>
+        <el-tree
+          ref="frameTree"
+          :data="treeData"
+          :show-checkbox="false"
+          node-key="id"
+          :default-expand-all="true"
+          :auto-expand-parent="true"
+          :expand-on-click-node="false"
+          :highlight-current="true"
+          :current-node-key="selectedNodeId"
+          draggable
+          :accordion="true"
+          :filter-node-method="filterNode"
+          @node-drag-start="nodeDragStart"
+          @node-drop="nodeDrop"
+          @node-click="nodeClick"
+        >
+          <span slot-scope="{ node, data }" class="custom-tree-node">
+            <span v-if="data.type === 3"><svg-icon
+              icon-class="area"
+            />{{ data.name }}</span>
+            <span v-else><svg-icon
+              :style="data.customer_id ? 'color: #0a901c' : ''"
+              :icon-class="data.type===4?'sickroom':data.type===5?'bed':'area'"
+            />{{ data.full_name }}</span>
+            <span>
+              <el-button
+                v-if="data.type!==5"
+                type="text"
+                size="mini"
+                icon="el-icon-plus"
+                @click.stop="() => append(data)"
+              />
+              <el-button
+                type="text"
+                size="mini"
+                icon="el-icon-edit"
+                @click.stop="() => edit(data)"
+              />
+              <el-button
+                type="text"
+                :disabled="data.id===1"
+                size="mini"
+                icon="el-icon-delete"
+                @click.stop="() => remove(data)"
+              />
+            </span>
+          </span>
+        </el-tree>
+      </el-aside>
+      <el-main>
+        <el-row :gutter="40" class="panel-group">
+          <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
+            <div class="card-panel">
+              <div class="card-panel-icon-wrapper icon-people">
+                <svg-icon icon-class="sickroom" class-name="card-panel-icon" />
+              </div>
+              <div class="card-panel-description">
+                <div class="card-panel-text">
+                  病房数
+                </div>
+                <count-to :start-val="0" :end-val="bfCount" :duration="2600" class="card-panel-num" />
+              </div>
+            </div>
+          </el-col>
+          <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
+            <div class="card-panel">
+              <div class="card-panel-icon-wrapper icon-message">
+                <svg-icon icon-class="sickbed" class-name="card-panel-icon" />
+              </div>
+              <div class="card-panel-description">
+                <div class="card-panel-text">
+                  病床数
+                </div>
+                <count-to :start-val="0" :end-val="bcCount" :duration="2000" class="card-panel-num" />
+              </div>
+            </div>
+          </el-col>
+          <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
+            <div class="card-panel">
+              <div class="card-panel-icon-wrapper icon-special-care">
+                <svg-icon icon-class="bad_people" class-name="card-panel-icon" />
+              </div>
+              <div class="card-panel-description">
+                <div class="card-panel-text">
+                  在床数
+                </div>
+                <count-to :start-val="0" :end-val="zcCount" :duration="1900" class="card-panel-num" />
+              </div>
+            </div>
+          </el-col>
+          <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
+            <div class="card-panel">
+              <div class="card-panel-icon-wrapper icon-primary-care">
+                <svg-icon icon-class="empty_bed" class-name="card-panel-icon" />
+              </div>
+              <div class="card-panel-description primary-care">
+                <div class="card-panel-text primary-care">
+                  空床数
+                </div>
+                <count-to :start-val="0" :end-val="kcCount" :duration="1500" class="card-panel-num" />
+              </div>
+            </div>
+          </el-col>
+        </el-row>
+        <el-tabs v-model="activeName" style="margin:0;" type="border-card">
+          <el-tab-pane label="用户列表" name="frameInfo">
+            <keep-alive>
+              <customer-manager :frame="selectedNode" @saved="handleCustomerChange" />
+            </keep-alive>
+          </el-tab-pane>
+          <el-tab-pane label="设备列表" name="deviceList">
+            <keep-alive>
+              <device-manager :frame="selectedNode" />
+            </keep-alive>
+          </el-tab-pane>
+          <el-tab-pane label="机构成员" name="clerkList">
+            <keep-alive>
+              <clerk-list :part-id="selectedNode.part_id" />
+            </keep-alive>
+          </el-tab-pane>
+        </el-tabs>
+      </el-main>
+    </el-container>
+
+    <!---添加空间结构弹窗 -->
+    <el-dialog :title="frameEditTitle" :visible.sync="frameDialogVisible" width="500px">
+      <el-form ref="editForm" :model="frameInfo" :rules="rules" label-width="110px">
+        <el-row>
+          <el-col :span="24">
+            <!--医院结构名称-->
+            <el-form-item label="名称" prop="name">
+              <el-input v-model="frameInfo.name" :maxlength="20">
+                <template slot="append">{{ frameInfo.type === 4?"房":"床" }}</template>
+              </el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <!--医院结构别名-->
+            <el-form-item label="别名" prop="alias">
+              <el-input v-model="frameInfo.alias" :maxlength="20" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row hidden>
+          <el-col :span="12">
+            <el-form-item label="类型">
+              <el-radio v-model="frameInfo.type" :label="1">病房</el-radio>
+              <el-radio v-model="frameInfo.type" :label="2">床位</el-radio>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-form-item>
+          <el-button type="primary" class="save" @click="handleFrameSubmit('editForm')">确定</el-button>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+    <!---添加空间结构弹窗 -->
+
+    <!---快速创建结构弹窗 -->
+    <el-dialog title="快速构建结构" :visible.sync="frameQuickCreateVisible" width="500px">
+      <el-form ref="createFrameForm" :model="createFrameModel" :rules="createFrameRules" label-width="110px">
+        <el-row>
+          <el-col :span="24">
+            <!--开始房间号-->
+            <el-form-item label="开始房间号" prop="start_no">
+              <el-input-number
+                v-model="createFrameModel.room_start_no"
+                :min="1"
+                @change="roomStartChange"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <!--结束房间号-->
+            <el-form-item label="结束房间号" prop="end_no">
+              <el-input-number
+                v-model="createFrameModel.room_end_no"
+                :min="createFrameModel.room_start_no"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <!--每房床位数-->
+            <el-form-item label="每房床位数" prop="beds_per_room">
+              <el-input-number v-model="createFrameModel.beds_per_room" :min="1" :max="20" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col :span="18">
+            <!--每房床位数-->
+            <el-form-item label="房号显示位数" prop="room_num_bits">
+              <el-input-number
+                v-model="createFrameModel.room_num_bits"
+                :min="1"
+                :max="4"
+                @change="(val)=>{bitNumChange(val,'room')}"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <div class="el-form-item__label">
+              示例:{{ room_num_demo }}
+            </div>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col :span="18">
+            <!--每房床位数-->
+            <el-form-item label="床号显示位数" prop="bed_num_bits">
+              <el-input-number
+                v-model="createFrameModel.bed_num_bits"
+                :min="1"
+                :max="4"
+                @change="(val)=>{bitNumChange(val,'bed')}"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <div class="el-form-item__label">
+              示例:{{ bed_num_demo }}
+            </div>
+          </el-col>
+        </el-row>
+
+        <el-form-item>
+          <el-button type="primary" class="save" @click="quickCreateSubmit()">确定</el-button>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+    <!---快速创建结构弹窗 -->
+
+    <!-- 新建科室弹窗 -->
+    <el-dialog :title.sync="formtitle" :visible.sync="formshow" width="50%">
+      <div>
+        <el-form ref="editform" :rules="rules" label-width="120px" :model="formmodel">
+          <el-form-item label="科室名称" prop="shop_name">
+            <el-input v-model="formmodel.shop_name" clearable :maxlength="100" placeholder="请输入科室名称" />
+          </el-form-item>
+          <el-form-item label="管理员账号" prop="member_name">
+            <el-input v-model="formmodel.member_name" clearable :maxlength="100" placeholder="请输入管理员账号" />
+          </el-form-item>
+          <el-form-item label="管理员密码" prop="member_password">
+            <el-input v-model="formmodel.member_password" type="password" clearable :maxlength="100" placeholder="请输入管理员密码" />
+          </el-form-item>
+        </el-form>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="formshow = false">取 消</el-button>
+        <el-button type="primary" @click="handlerFormSubmit('editform')">确 定</el-button>
+      </div>
+    </el-dialog>
+    <!-- 新建科室弹窗结束 -->
+  </div>
+</template>
+
+<script>
+import * as HospitalFrame_API from '@/api/ncs_hospitalFrame'
+import * as API_FrameGroup from '@/api/ncs_frameGroup'
+import CustomerManager from '@/views/hospital/ncs_customer/customerManager'
+import DeviceManager from '@/views/hospital/ncs_device/deviceManager'
+import ClerkList from '@/views/ncs-clerk/clerkList'
+import CountTo from 'vue-count-to'
+import * as API_PartInfo from '@/api/ncs_partInfo'
+
+export default {
+  name: 'FrameTreeView',
+  components: { DeviceManager, CustomerManager, CountTo, ClerkList },
+  data() {
+    return {
+      treeData: [],
+      treeDataClone: [],
+      /** 当前选中的树节点 */
+      selectedNodeId: 0,
+      selectedNode: {},
+      filterText: '',
+      activeName: 'frameInfo',
+      /** 上级机构数组 **/
+      parents: [],
+      /** frame 编辑弹窗 **/
+      frameEditTitle: '添加',
+      frameDialogVisible: false,
+      frameInfo: {},
+      rules: {
+        name: [
+          this.MixinRequired('请输入结构名称!'),
+          { min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' }
+        ],
+        alias: [
+          { min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' }
+        ],
+        shop_name: [
+          { required: true, message: '组织名称必须选择', trigger: 'blur' }
+        ],
+        member_name: [
+          { required: true, message: '管理员账号必须填写', trigger: 'blur' }
+        ],
+        member_password: [
+          { required: true, message: '管理员密码必须填写', trigger: 'blur' }
+        ]
+      },
+      /** 快速创建空间结构弹窗 **/
+      frameQuickCreateVisible: false,
+      createFrameModel: {
+        room_start_no: 1,
+        room_end_no: 2,
+        beds_per_room: 4,
+        room_num_bits: 2,
+        bed_num_bits: 2
+      },
+      bed_num_demo: '01',
+      room_num_demo: '01',
+      createFrameRules: {},
+      bfCount: 1232,
+      zcCount: 632,
+      kcCount: 82,
+      bcCount: 56,
+      /** 新建组织弹出参数 **/
+      formtitle: '新建组织',
+      formshow: false,
+      formmodel: {}
+    }
+  },
+  computed: {
+    asideHeight() {
+      return this.mainAreaHeight
+    }
+  },
+  watch: {
+    selectedNodeId(newval, old) {
+      console.log('watch', newval)
+      this.selectedNode = this.findNodeById(this.treeData, newval)
+      console.log(this.selectedNode)
+    },
+    filterText(val) {
+      this.$refs.frameTree.filter(val)
+    }
+  },
+  mounted() {
+    this.getFrameTree().then(() => {
+      if (this.treeData.length > 0) {
+        this.selectedNodeId = this.treeData[0].id
+        this.$refs.frameTree.setCurrentKey(this.selectedNodeId)
+      }
+    }).catch(err => {
+      this.$message.error(err)
+    })
+  },
+  methods: {
+    /**
+     * 获取空间结构树形数据
+     * */
+    getFrameTree() {
+      return new Promise((resolve, reject) => {
+        API_FrameGroup.getframestruct(this.$store.getters.partId, 1).then(res => {
+          console.log(res)
+          this.bfCount = res.bfCount
+          this.zcCount = res.zcCount
+          this.kcCount = res.kcCount
+          this.bcCount = res.bcCount
+          this.treeData = res.frameTree
+          resolve()
+        }).catch(err => {
+          reject(err)
+        })
+      })
+    },
+
+    append(data) {
+      if (data.type === 1) {
+        this.formmodel = {}
+        this.formmodel.parent_id = data.hospital_id
+        this.formmodel.frame_parent_id = data.id
+        this.formmodel.full_name = data.name
+        console.log('this.formmodel.parent_id=', this.formmodel.parent_id)
+        this.formshow = true
+      } else {
+        if (data.type === 4) {
+          this.frameEditTitle = '【' + data.full_name + '】添加床位'
+        } else {
+          this.frameEditTitle = '【' + data.full_name + '】添加房间'
+        }
+        this.frameInfo = {
+          parent_id: data.id,
+          type: data.type === 4 ? 5 : 4,
+          parent_name: data.name,
+          name: '',
+          alias: ''
+        }
+        this.frameDialogVisible = true
+        console.log('append', data)
+      }
+    },
+    edit(data, e) {
+      if (data.type === 3 || data.type === 1) {
+        console.log('暂未开发')
+        return
+      }
+      const parentNode = this.findNodeById(this.treeData, data.parent_id)
+      this.frameInfo = {
+        ...data,
+        parent_name: parentNode === null ? '' : parentNode.name
+      }
+      this.frameEditTitle = '编辑节点'
+      this.frameDialogVisible = true
+    },
+    remove(data) {
+      let warning = ''
+      if (data.type === 4) {
+        warning = '确定要删除【' + data.full_name + '】及其中的所有床位吗?'
+      } else {
+        warning = '确定删除床位【' + data.full_name + '】吗?'
+      }
+      this.$confirm(warning, '警告', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        HospitalFrame_API.deleteHospitalFrame(data.id).then(response => {
+          this.$message({
+            type: 'success',
+            message: '已删除!'
+          })
+          this.getFrameTree().then(() => {
+            // 判断选中节点是否被删除,如果被删除需要重新选择根节点
+            const selectNode = this.findNodeById(this.treeData, this.selectedNodeId)
+            if (selectNode === null) {
+              this.selectedNodeId = this.treeData[0].id
+            }
+            this.$refs.frameTree.setCurrentKey(this.selectedNodeId)
+          })
+        }).catch(response => {
+          this.$message({
+            type: 'info',
+            message: response.message
+          })
+        })
+      }).catch(() => {
+
+      })
+    },
+
+    handleFrameSubmit(formName) {
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          const params = this.MixinClone(this.frameInfo)
+          if (params.id) {
+            if (params.type === 4) {
+              params.full_name = params.name
+            } else {
+              params.full_name = params.parent_name + '-' + params.name + '床'
+            }
+            HospitalFrame_API.updateHospitalFrame(params.id, params).then(response => {
+              this.$message.success('修改成功!')
+              this.frameDialogVisible = false
+              this.getFrameTree().then(() => {
+                this.selectedNodeId = response.id
+                this.$refs.frameTree.setCurrentKey(this.selectedNodeId)
+              })
+            })
+          } else {
+            if (!params.part_id) {
+              params.part_id = this.$store.getters.partId
+            }
+            if (params.type === 4) {
+              params.full_name = params.name
+            } else {
+              params.full_name = params.parent_name + '-' + params.name + '床'
+            }
+
+            HospitalFrame_API.addHospitalFrame(params).then(response => {
+              this.$message.success('添加成功!')
+              this.frameDialogVisible = false
+              this.getFrameTree()
+            })
+          }
+        } else {
+          this.$message.error('表单填写有误,请检查!')
+          return false
+        }
+      })
+    },
+    /** 开始拖拽之前保存treeData数据,拖拽完成后判定能否拖拽到目标节点,不允许拖拽把初始数据覆盖拖拽后的数据,否则拖拽成功
+             * @param node
+             * @param event
+             */
+    nodeDragStart(node, event) {
+      this.treeDataClone = this.MixinClone(this.treeData)
+    },
+    /** 拖拽结束 **/
+    nodeDrop(node, target, position, event) {
+      var success = true
+      const nparent = this.findNodeById(this.treeDataClone, node.data.parent_id)
+      const tparent = this.findNodeById(this.treeDataClone, target.data.parent_id)
+      if (position === 'inner') { // 进入了某个节点之中,不能将某一节点拖入同级节点,也不能跨级拖动
+        if (Number(node.data.type) <= Number(target.data.type) || Number(node.data.type) - Number(target.data.type) > 1) {
+          this.treeData = this.treeDataClone
+          success = false
+        }
+      } else {
+        // 查找Target和node的parent 判定target的parent类型与node的parent类型是否一致
+        if (nparent === null || tparent === null || nparent.type !== tparent.type) {
+          this.treeData = this.treeDataClone
+          success = false
+        }
+      }
+      if (success) { // 拖拽完成,更新node和target排序
+        HospitalFrame_API.sort(node.data.id, target.data.id, position).then(res => {
+          this.selectedNodeId = node.data.id
+          this.getFrameTree().then(() => {
+            this.$refs.frameTree.setCurrentKey(this.selectedNodeId)
+            console.log('sid', this.selectedNodeId)
+          })
+        })
+      }
+    },
+    /** 树形结构中查找指定Id节点 */
+    findNodeById(data, id) {
+      let node = null
+      if (data.length > 0) {
+        for (var i = 0; i < data.length; i++) {
+          if (data[i].id === id) {
+            node = data[i]
+            break
+          }
+          if (data[i].children && data[i].children.length > 0) {
+            const subresult = this.findNodeById(data[i].children, id)
+            if (subresult !== null) {
+              node = subresult
+              break
+            }
+          }
+        }
+      }
+      return node
+    },
+    /** 节点过滤方法 **/
+    filterNode(value, data) {
+      if (!value) return true
+      return data.full_name.indexOf(value) !== -1
+    },
+    /** 点击树形节点  **/
+    nodeClick(data, node, leaf) {
+      this.$set(this, 'selectedNodeId', data.id)
+      console.log(data)
+    },
+    /** 快速创建空间结构弹窗 **/
+    quickCreateFrame() {
+      this.frameQuickCreateVisible = true
+    },
+
+    quickCreateSubmit(formname) {
+      const params = this.createFrameModel
+      params.part_frame_id = this.treeData[0].id
+      HospitalFrame_API.quickCreate(params).then(res => {
+        this.$message.success('创建成功!')
+        this.frameQuickCreateVisible = false
+        this.getFrameTree().then(() => {
+          this.$refs.frameTree.setCurrentKey(this.selectedNodeId)
+        })
+      }).catch(err => {
+        this.$message.error(err)
+      })
+    },
+
+    /** 显示位数变化 **/
+    bitNumChange(val, frame_type) {
+      const s = Array(val).join(0) + 1
+      if (frame_type === 'room') {
+        this.room_num_demo = s
+      } else {
+        this.bed_num_demo = s
+      }
+    },
+    /** 起始位数变化 结束位置要根据起始位置的大小来变化 */
+    roomStartChange(val) {
+      console.log(val)
+      if (val > this.createFrameModel.room_end_no) {
+        this.createFrameModel.room_end_no = val
+      }
+    },
+    /**
+     * 提交新增表单
+     * @param formName
+     */
+    handlerFormSubmit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          /** 新增 */
+          delete this.formmodel.id
+          this.formmodel.shop_type = 5
+          this.formmodel.full_name = this.formmodel.full_name + '-' + this.formmodel.shop_name
+          const _this = this
+          API_PartInfo.add(this.formmodel).then(() => {
+            _this.formshow = false
+            _this.$message.success('保存成功!')
+            _this.getFrameTree()
+          }).catch(err => {
+            _this.formshow = false
+            _this.formmodel.member_password = ''
+            _this.$message.error(err)
+          })
+        }
+      })
+    },
+    handleCustomerChange() {
+      this.getFrameTree()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+    .el-aside {
+        margin: 8px;
+        padding: 8px;
+        border-width: 1px;
+        border-style: solid;
+        background: #fff;
+    }
+
+    .custom-tree-node {
+        flex: 1;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        font-size: 14px;
+        padding-right: 8px;
+    }
+
+    :root {
+        --icon-special-care: #f1526c;
+        --icon-primary-care: #34bfa3;
+    }
+
+    .panel-group {
+        margin-top: 0;
+
+        .card-panel-col {
+            margin-bottom: 0;
+        }
+
+        .special-care {
+            color: var(--icon-special-care) !important;
+        }
+
+        .primary-care {
+            color: var(--icon-primary-care) !important;
+        }
+
+        .card-panel {
+            height: 73px;
+            cursor: pointer;
+            font-size: 12px;
+            position: relative;
+            overflow: hidden;
+            color: #666;
+            background: #fff;
+            box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
+            border-color: rgba(0, 0, 0, .05);
+
+            &:hover {
+                .card-panel-icon-wrapper {
+                    color: #fff;
+                }
+
+                .icon-people {
+                    background: #40c9c6;
+                }
+
+                .icon-message {
+                    background: #36a3f7;
+                }
+
+                .icon-special-care {
+                    background: rgba(246, 42, 16, 0.42);
+                }
+
+                .icon-primary-care {
+                    background: rgba(16, 173, 246, 0.42);
+                }
+            }
+
+            .icon-people {
+                color: #40c9c6;
+            }
+
+            .icon-message {
+                color: #36a3f7;
+            }
+
+            .icon-special-care {
+                color: rgba(255, 143, 82, 0.42);
+            }
+
+            .icon-primary-care {
+                color: var(--icon-primary-care)
+            }
+
+            .card-panel-icon-wrapper {
+                float: left;
+                margin: 7px 0 0 14px;
+                padding: 6px;
+                transition: all 0.38s ease-out;
+                border-radius: 6px;
+            }
+
+            .card-panel-icon {
+                float: left;
+                font-size: 48px;
+            }
+
+            .card-panel-description {
+                float: right;
+                font-weight: bold;
+                margin: 10px 14px 10px;
+                margin-left: 0px;
+
+                .card-panel-text {
+                    line-height: 18px;
+                    color: rgba(0, 0, 0, 0.45);
+                    font-size: 16px;
+                    margin-bottom: 12px;
+                }
+
+                .card-panel-num {
+                    font-size: 20px;
+                }
+            }
+        }
+    }
+
+    @media (max-width: 550px) {
+        .card-panel-description {
+            display: none;
+        }
+
+        .card-panel-icon-wrapper {
+            float: none !important;
+            width: 100%;
+            height: 100%;
+            margin: 0 !important;
+
+            .svg-icon {
+                display: block;
+                margin: 14px auto !important;
+                float: none !important;
+            }
+        }
+    }
+</style>

+ 1 - 1
src/views/hospitalFrame/frameGroupEdit.vue

@@ -74,7 +74,7 @@ export default {
 
     getRoomStructs() {
       API_FrameGroup.getframestruct(this.$store.getters.partId, 4).then(res => {
-        this.rooms = this.filterGroupFrames(res, this.groupId)
+        this.rooms = this.filterGroupFrames(res.frameTree, this.groupId)
         console.log('rooms', this.rooms)
       }).catch(err => {
         this.$message.error(err)

+ 4 - 7
src/views/hospitalFrame/frameTreeView.vue

@@ -136,7 +136,7 @@
           <el-col :span="24">
             <!--每房床位数-->
             <el-form-item label="每房床位数" prop="beds_per_room">
-              <el-input-number v-model="createFrameModel.beds_per_room" :min="1" />
+              <el-input-number v-model="createFrameModel.beds_per_room" :min="1" :max="20" />
             </el-form-item>
           </el-col>
         </el-row>
@@ -234,7 +234,7 @@ export default {
   },
   watch: {
     selectedNodeId(newval, old) {
-      console.log('watch',newval)
+      console.log('watch', newval)
       this.selectedNode = this.findNodeById(this.treeData, newval)
     },
     filterText(val) {
@@ -256,7 +256,7 @@ export default {
     getFrameTree() {
       return new Promise((resolve, reject) => {
         API_FrameGroup.getframestruct(this.$store.getters.partId, 3).then(res => {
-          this.treeData = [...res]
+          this.treeData = res.frameTree
           resolve()
         }).catch(err => {
           reject(err)
@@ -356,10 +356,7 @@ export default {
             HospitalFrame_API.addHospitalFrame(params).then(response => {
               this.$message.success('添加成功!')
               this.frameDialogVisible = false
-              this.getFrameTree().then(() => {
-                this.selectedNodeId = response.id
-                this.$refs.frameTree.setCurrentKey(this.selectedNodeId)
-              })
+              this.getFrameTree()
             })
           }
         } else {

+ 186 - 186
src/views/hospitalFrame/hospitalFrame.vue

@@ -37,12 +37,12 @@
               <el-button style="width: 150px;" size="mini" plain round @click="handleEditPatient(subItem.customer_id,subItem.frame_bed.id)">
                 <i class="el-icon-user" /> {{ subItem.customer_name+ ' '+ subItem.customer_age+subItem.customer_age_unit }}
                 <span v-if="subItem.customer_sex === 1">男</span>
-                <span v-else-if="subItem.customer_sex === 2">女</span>
+                <span v-else-if="subItem.customer_sex === 0">女</span>
                 <span v-else>未知</span>
               </el-button>
             </span>
             <span v-else>
-              <el-button size="mini" type="success" plain round @click="handleAddPatient(subItem.frame_bed)"><i class="el-icon-circle-plus-outline" /> 病人</el-button>
+              <el-button size="mini" type="success" plain round @click="handleAddPatient(subItem.frame_bed)"><i class="el-icon-circle-plus-outline" /> 用户</el-button>
             </span>
             <span>
               <el-dropdown size="mini" @command="handleGroupCommand">
@@ -66,9 +66,9 @@
     </div>
 
     <el-dialog
-      title="病人信息"
-      :visible.sync="dialogPatientVisible"
-      width="85%"
+            title="用户信息"
+            :visible.sync="dialogPatientVisible"
+            width="85%"
     >
       <customer-edit :customer-id="customerId" :frame-id="frameId" @saved="handlePatientFinished" />
     </el-dialog>
@@ -109,10 +109,10 @@
     </el-dialog>
 
     <el-drawer
-      :title="selectedFrame.full_name+' 设备'"
-      :visible.sync="deviceVisible"
-      :append-to-body="true"
-      size="60%"
+            :title="selectedFrame.full_name+' 设备'"
+            :visible.sync="deviceVisible"
+            :append-to-body="true"
+            size="60%"
     >
       <device-info :frame-id="frameId" :frame="selectedFrame" />
     </el-drawer>
@@ -120,206 +120,206 @@
 </template>
 
 <script>
-import * as HospitalFrame_API from '@/api/ncs_hospitalFrame'
-import * as RegExp from '@/utils/RegExp'
-import customerEdit from '@/views/customer/customerEdit'
-import DeviceInfo from '@/views/ncs-device/deviceInfo'
+  import * as HospitalFrame_API from '@/api/ncs_hospitalFrame'
+  import * as RegExp from '@/utils/RegExp'
+  import customerEdit from '@/views/customer/customerEdit'
+  import DeviceInfo from '@/views/ncs-device/deviceInfo'
 
-export default {
-  name: 'HospitalFrame',
-  components: { DeviceInfo, customerEdit },
-  data: function() {
-    return {
-      hospital_frame: null,
-      frameAddVisible: false,
-      frameName: '',
-      dialogPatientVisible: false,
-      customerId: null,
-      dialogFrameVisible: false,
-      frameInfo: {},
-      deviceVisible: false,
-      frameId: 0,
-      selectedFrame: {},
-      rules: {
-        name: [
-          this.MixinRequired('请输入名称!'),
-          { min: 1, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' },
-          {
-            validator: (rule, value, callback) => {
-              if (!RegExp.userName.test(value)) {
-                callback(new Error('只支持汉字、字母、数字、“-”、“_”的组合!'))
-              } else {
-                callback()
+  export default {
+    name: 'HospitalFrame',
+    components: { DeviceInfo, customerEdit },
+    data: function() {
+      return {
+        hospital_frame: null,
+        frameAddVisible: false,
+        frameName: '',
+        dialogPatientVisible: false,
+        customerId: null,
+        dialogFrameVisible: false,
+        frameInfo: {},
+        deviceVisible: false,
+        frameId: 0,
+        selectedFrame: {},
+        rules: {
+          name: [
+            this.MixinRequired('请输入名称!'),
+            { min: 1, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' },
+            {
+              validator: (rule, value, callback) => {
+                if (!RegExp.userName.test(value)) {
+                  callback(new Error('只支持汉字、字母、数字、“-”、“_”的组合!'))
+                } else {
+                  callback()
+                }
               }
             }
-          }
-        ],
-        alias: [
-          { min: 1, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' },
-          {
-            validator: (rule, value, callback) => {
-              if (!value) {
-                callback()
-              }
-              if (!RegExp.userName.test(value)) {
-                callback(new Error('只支持汉字、字母、数字、“-”、“_”的组合!'))
-              } else {
-                callback()
+          ],
+          alias: [
+            { min: 1, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' },
+            {
+              validator: (rule, value, callback) => {
+                if (!value) {
+                  callback()
+                }
+                if (!RegExp.userName.test(value)) {
+                  callback(new Error('只支持汉字、字母、数字、“-”、“_”的组合!'))
+                } else {
+                  callback()
+                }
               }
             }
-          }
-        ]
-      },
-      fullName: null
-    }
-  },
-  watch: {
-    deviceVisible: function(newData) {
-      if (!newData) {
-        this.GET_All()
+          ]
+        },
+        fullName: null
       }
-    }
-  },
-  mounted() {
-    this.GET_All()
-  },
-  methods: {
-    GET_All() {
-      HospitalFrame_API.getHospitalFrameList(this.$store.getters.userInfo.last_login_shopid).then(response => {
-        if (response) {
-          console.log(response)
-          this.hospital_frame = response
-        }
-      }).catch(response => {
-        this.$message({
-          type: 'info',
-          message: response.message
-        })
-      })
-    },
-    /** 下拉触发 */
-    handleGroupCommand(object) {
-      console.log(object)
-      this.selectedFrame = object.frame
-      switch (object.type) {
-        case 'edit':
-          this.handelEditFrame(object.frame)
-          break
-        case 'delete':
-          this.handlerDeleteFrame(object.frame.id)
-          break
-        case 'device':
-          this.frameId = object.frame.id
-          this.openDeviceList()
-          break
-      }
-    },
-    handleAddPatient(bedFrame) {
-      this.customerId = 0
-      this.frameId = bedFrame.id
-      this.dialogPatientVisible = true
-    },
-    handlePatientFinished() {
-      this.dialogPatientVisible = false
-      this.GET_All()
-    },
-    handleEditPatient(id, frameId) {
-      this.dialogPatientVisible = true
-      this.customerId = id
-      this.frameId = frameId
     },
-    // frame handle
-    handleAddRoom() {
-      let parent_id = null
-      if (this.hospital_frame) {
-        parent_id = this.hospital_frame.frame_part.id
+    watch: {
+      deviceVisible: function(newData) {
+        if (!newData) {
+          this.GET_All()
+        }
       }
-      const params = { type: 4, name: this.frameName, part_id: this.$store.getters.partId, parent_id: parent_id }
-      params.full_name = params.name + '房'
-      HospitalFrame_API.addHospitalFrame(params).then(response => {
-        this.$message.success('添加成功!')
-        this.GET_All()
-      })
-    },
-    handleAddFrame(id, name) { // 新增床位
-      this.frameInfo = {}
-      this.frameInfo = { parent_id: id, type: 5 }
-      this.fullName = name
-      this.dialogFrameVisible = true
     },
-    handelEditFrame(frame) {
-      this.frameInfo = { id: frame.id, type: frame.type, name: frame.name, alias: frame.alias, full_name: frame.full_name }
-      this.dialogFrameVisible = true
-    },
-    handleFrameFinished() {
-      this.dialogFrameVisible = false
+    mounted() {
       this.GET_All()
     },
-    /** 单条数据删除处理 */
-    handlerDeleteFrame(ids) {
-      this.$confirm('确定要删除此结构及其所有下级吗?', '警告', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(() => {
-        HospitalFrame_API.deleteHospitalFrame(ids).then(response => {
-          this.$message({
-            type: 'success',
-            message: '已删除!'
-          })
-          this.GET_All()
+    methods: {
+      GET_All() {
+        HospitalFrame_API.getHospitalFrameList(this.$store.getters.userInfo.last_login_shopid).then(response => {
+          if (response) {
+            console.log(response)
+            this.hospital_frame = response
+          }
         }).catch(response => {
           this.$message({
             type: 'info',
             message: response.message
           })
         })
-      })
-    },
+      },
+      /** 下拉触发 */
+      handleGroupCommand(object) {
+        console.log(object)
+        this.selectedFrame = object.frame
+        switch (object.type) {
+          case 'edit':
+            this.handelEditFrame(object.frame)
+            break
+          case 'delete':
+            this.handlerDeleteFrame(object.frame.id)
+            break
+          case 'device':
+            this.frameId = object.frame.id
+            this.openDeviceList()
+            break
+        }
+      },
+      handleAddPatient(bedFrame) {
+        this.customerId = 0
+        this.frameId = bedFrame.id
+        this.dialogPatientVisible = true
+      },
+      handlePatientFinished() {
+        this.dialogPatientVisible = false
+        this.GET_All()
+      },
+      handleEditPatient(id, frameId) {
+        this.dialogPatientVisible = true
+        this.customerId = id
+        this.frameId = frameId
+      },
+      // frame handle
+      handleAddRoom() {
+        let parent_id = null
+        if (this.hospital_frame) {
+          parent_id = this.hospital_frame.frame_part.id
+        }
+        const params = { type: 4, name: this.frameName, part_id: this.$store.getters.partId, parent_id: parent_id }
+        params.full_name = params.name + '房'
+        HospitalFrame_API.addHospitalFrame(params).then(response => {
+          this.$message.success('添加成功!')
+          this.GET_All()
+        })
+      },
+      handleAddFrame(id, name) { // 新增床位
+        this.frameInfo = {}
+        this.frameInfo = { parent_id: id, type: 5 }
+        this.fullName = name
+        this.dialogFrameVisible = true
+      },
+      handelEditFrame(frame) {
+        this.frameInfo = { id: frame.id, type: frame.type, name: frame.name, alias: frame.alias, full_name: frame.full_name }
+        this.dialogFrameVisible = true
+      },
+      handleFrameFinished() {
+        this.dialogFrameVisible = false
+        this.GET_All()
+      },
+      /** 单条数据删除处理 */
+      handlerDeleteFrame(ids) {
+        this.$confirm('确定要删除此结构及其所有下级吗?', '警告', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          HospitalFrame_API.deleteHospitalFrame(ids).then(response => {
+            this.$message({
+              type: 'success',
+              message: '已删除!'
+            })
+            this.GET_All()
+          }).catch(response => {
+            this.$message({
+              type: 'info',
+              message: response.message
+            })
+          })
+        })
+      },
 
-    // --------------------设备管理
-    handlePartDevice() {
-      this.frameId = this.hospital_frame.frame_part.id
-      this.selectedFrame = this.hospital_frame.frame_part
-      this.openDeviceList()
-    },
-    openDeviceList() {
-      this.deviceVisible = true
-    },
-    handlerSubmit(formName) {
-      this.$refs[formName].validate(valid => {
-        if (valid) {
-          const params = this.MixinClone(this.frameInfo)
-          if (params.id) {
-            if (params.type === 5) {
-              const name = params.full_name.split('-')
-              params.full_name = name[0] + '-' + params.name + '床'
-            } else if (params.type === 4) {
-              params.full_name = params.name + '房'
+      // --------------------设备管理
+      handlePartDevice() {
+        this.frameId = this.hospital_frame.frame_part.id
+        this.selectedFrame = this.hospital_frame.frame_part
+        this.openDeviceList()
+      },
+      openDeviceList() {
+        this.deviceVisible = true
+      },
+      handlerSubmit(formName) {
+        this.$refs[formName].validate(valid => {
+          if (valid) {
+            const params = this.MixinClone(this.frameInfo)
+            if (params.id) {
+              if (params.type === 5) {
+                const name = params.full_name.split('-')
+                params.full_name = name[0] + '-' + params.name + '床'
+              } else if (params.type === 4) {
+                params.full_name = params.name + '房'
+              }
+              HospitalFrame_API.updateHospitalFrame(params.id, params).then(response => {
+                this.$message.success('修改成功!')
+                this.handleFrameFinished()
+              })
+            } else {
+              if (!params.part_id) {
+                params.part_id = this.$store.getters.partId
+              }
+              params.full_name = this.fullName + '房-' + params.name + '床'
+              HospitalFrame_API.addHospitalFrame(params).then(response => {
+                this.$message.success('添加成功!')
+                this.handleFrameFinished()
+              })
             }
-            HospitalFrame_API.updateHospitalFrame(params.id, params).then(response => {
-              this.$message.success('修改成功!')
-              this.handleFrameFinished()
-            })
           } else {
-            if (!params.part_id) {
-              params.part_id = this.$store.getters.partId
-            }
-            params.full_name = this.frameInfo.name + '房-' + params.name + '床'
-            HospitalFrame_API.addHospitalFrame(params).then(response => {
-              this.$message.success('添加成功!')
-              this.handleFrameFinished()
-            })
+            this.$message.error('表单填写有误,请检查!')
+            return false
           }
-        } else {
-          this.$message.error('表单填写有误,请检查!')
-          return false
-        }
-      })
-    }
+        })
+      }
 
+    }
   }
-}
 </script>
 
 <style type="text/scss" lang="scss" scoped>

+ 187 - 0
src/views/hospitalFrame/nurse_watch_frame.vue

@@ -0,0 +1,187 @@
+<template>
+  <div>
+    <el-card style="margin: 15px">
+      <el-form ref="editform" label-width="80px">
+        <fieldset class="margin-top-sm">
+          <legend>腕表管辖空间</legend>
+          <el-row :gutter="20">
+            <el-col v-for="(item,index) in rooms" :key="index" gut :xs="8" :sm="6" :md="4" :lg="4" :xl="4">
+              <el-card class="box-card">
+                <div slot="header" class="clearfix">
+                  <el-checkbox v-model="item.checked" @change="handleCheckboxChanged(item)"><svg-icon icon-class="sickroom" style="color: #9aaabf;margin-right: 5px" /><span>{{ item.name }}</span></el-checkbox>
+<!--                  <svg-icon icon-class="sickroom" style="color: #9aaabf;margin-right: 5px" /><span>{{ item.name }}房</span>-->
+                  <el-checkbox v-model="item.allCkeck" style="float: right;" :indeterminate="item.indeterminate" @change="(checked)=>{handleCheckAll(checked,item)}">全选</el-checkbox>
+                </div>
+                <div v-for="(bed,_index) in item.children" :key="_index" class="text item">
+                  <el-checkbox v-model="bed.checked" @change="handleCheckboxChanged(item)"><svg-icon icon-class="bed" style="color: #9aaabf;margin-right: 5px" />{{ bed.name }}床</el-checkbox>
+                </div>
+              </el-card>
+            </el-col>
+          </el-row>
+        </fieldset>
+        <el-form-item align="center" class="margin-top-sm">
+          <el-button type="success" @click="onSubmit">保存设置</el-button>
+          <el-button @click="back">返回</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+  </div>
+</template>
+
+<script>
+/**
+     * 编辑病区信息
+     */
+import * as API_hospitalFrame from '@/api/ncs_hospitalFrame'
+import * as API_device from '@/api/ncs_device'
+
+export default {
+  name: 'FrameGroupEdit',
+  data() {
+    return {
+      deviceId: this.$route.params.id,
+      roleId: this.$route.params.role_id,
+      deviceFrames: [],
+      /** 空间结构房间 **/
+      rooms: [],
+      checkList: [],
+      checkDate: []
+    }
+  },
+  mounted() {
+    this.getGroup()
+  },
+  methods: {
+
+    getGroup() {
+      const _this = this
+      API_device.getFrameByDeviceId(this.deviceId).then(res => {
+        _this.deviceFrames = res
+        _this.getFrameByType()
+      })
+    },
+
+    getFrameByType() {
+      const _this = this
+      API_hospitalFrame.getFrameByType(this.$store.getters.partId, this.deviceId, this.roleId).then(res => {
+        _this.rooms = _this.filterGroupFrames(res)
+      }).catch(err => {
+        this.$message.error(err)
+      })
+    },
+    /** 递归筛选被选空间节点 */
+    filterGroupFrames(frames) {
+      this.deviceFrames.forEach(t => {
+        frames.forEach(item => {
+          if (t.frame_id === item.id) {
+            item.checked = true
+          }
+        })
+      })
+      console.log(frames[0])
+      frames.forEach(item => {
+        if (item.children) {
+          this.$set(item, 'children', this.filterGroupFrames(item.children, item.id))
+        }
+        this.countAllFrame(item)
+      })
+      return frames
+    },
+    /** 获取所有frame的长度、被选中的长度 */
+    countAllFrame(frame) {
+      const _list = []
+      if (!Array.isArray(frame)) {
+        _list.push(frame)
+        if (frame.children) _list.push(...this.countAllFrame(frame.children))
+      } else {
+        frame.forEach(item => {
+          _list.push(item)
+          if (item.children) _list.push(...this.countAllFrame(item.children))
+        })
+      }
+      const length = _list.length
+      const length_checked = _list.filter(_item => _item.checked).length
+      this.$set(frame, 'allCkeck', length === _list.filter(_item => _item.checked).length)
+      this.$set(frame, 'indeterminate', (length_checked !== 0) && (length !== length_checked))
+      console.log('list', _list)
+      return _list
+    },
+    /** 选择 */
+    handleCheckboxChanged(item) {
+      this.countAllFrame(item)
+    },
+    handleCheckAll(checked, item) {
+      this.$set(item, 'indeterminate', false)
+      this.setFrameCheck(item, checked)
+    },
+    /** 设置选择状态 */
+    setFrameCheck(item, checked) {
+      const perm = this.MixinClone(item)
+      if (!Array.isArray(perm)) {
+        this.$set(item, 'checked', checked)
+        if (item.children && item.children.length) {
+          this.$set(item, 'children', this.setFrameCheck(item.children, checked))
+        }
+      } else {
+        perm.map(item => {
+          item.checked = checked
+          this.$set(item, 'checked', checked)
+          if (item.children && item.children.length) {
+            this.$set(item, 'children', this.setFrameCheck(item.children, checked))
+          }
+        })
+      }
+      return perm
+    },
+    onSubmit() {
+      const data = []
+      this.rooms.forEach(item => {
+        if (item.checked) {
+          data.push(item.id)
+        }
+        item.children.forEach(t => {
+          if (t.checked) {
+            data.push(t.id)
+          }
+        })
+      })
+      if (data.length === 0) {
+        this.$message.info('请选择病床!')
+        return
+      }
+      console.log(data)
+      API_hospitalFrame.updateDeviceFrameManage({ deviceId: this.deviceId, frameIds: data }).then(res => {
+        this.$message.success('保存成功!')
+      }).catch(err => {
+        this.$message.error(err.message)
+      })
+    },
+    back() {
+      window.history.back()
+    }
+  }
+
+}
+</script>
+
+<style scoped type="text/scss">
+  /deep/ .el-checkbox__input.is-checked + .el-checkbox__label svg{
+    color: #1890ff !important;
+  }
+  .item {
+    margin-bottom: 10px;
+  }
+  /deep/ .el-card__body {
+      min-height: 130px;
+    }
+  /deep/ .el-card__header{
+      padding:10px 20px;
+    }
+  .margin-top-sm{
+    margin-top: 20px;
+  }
+fieldset{
+  border:1px solid #DCDFE6;
+  border-radius: 5px;
+}
+</style>

+ 2 - 2
src/views/login/index.vue

@@ -48,7 +48,7 @@
             </el-form-item>
           </el-tooltip>
 
-          <el-button :loading="loading" type="primary" size="midum" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">登  </el-button>
+          <el-button :loading="loading" type="primary" size="midum" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">登  </el-button>
         </el-form>
 
         <el-dialog title="Or connect with" :visible.sync="showDialog">
@@ -82,7 +82,7 @@ export default {
       },
       loginRules: {
         username: [{ required: true, trigger: 'blur', message: '用户名必须填写' }],
-        password: [{ required: true, trigger: 'blur', message: '登密码必须填写' }]
+        password: [{ required: true, trigger: 'blur', message: '登密码必须填写' }]
       },
       passwordType: 'password',
       capsTooltip: false,

+ 7 - 7
src/views/ncs-auth/compontents/roleEdit.vue

@@ -7,12 +7,12 @@
       <el-form-item label="角色描述" prop="role_describe">
         <el-input v-model="permissionForm.role_describe" placeholder="最多200字" :maxlength="200" />
       </el-form-item>
-      <el-form-item label="不用生成到科室" prop="role_describe">
-        <el-checkbox
-          v-model="permissionForm.hidden_in_seller"
-          label="是/否(勾选此项,该角色在创建科室时,不会在科室中创建此角色,不勾选则创建)。不同的科室对同一个角色可能分配不同的功能菜单,所以在创建科室时,将系统内的角色生成到科室上"
-        />
-      </el-form-item>
+<!--      <el-form-item label="不用生成到科室" prop="role_describe">-->
+<!--        <el-checkbox-->
+<!--          v-model="permissionForm.hidden_in_seller"-->
+<!--          label="是/否(勾选此项,该角色在创建科室时,不会在科室中创建此角色,不勾选则创建)。不同的科室对同一个角色可能分配不同的功能菜单,所以在创建科室时,将系统内的角色生成到科室上"-->
+<!--        />-->
+<!--      </el-form-item>-->
       <el-form-item label="角色权限" prop="permission">
         <el-checkbox v-model="allCheck" :indeterminate="allIndeterminate" @change="handleCheckAll">全部选择</el-checkbox>
         <div v-for="(item, index) in permissions" :key="item.identifier" class="level_1">
@@ -198,7 +198,7 @@ export default {
           API_Auth.getRolePermission(this.role_id).then(response => {
             this.permissionForm.role_name = response.role_name
             this.permissionForm.role_describe = response.role_describe
-            this.permissionForm.hidden_in_seller = response.hidden_in_seller
+            // this.permissionForm.hidden_in_seller = response.hidden_in_seller
             const checkedIds = this.expandRouters(response.menus)
             this.$set(this, 'permissions', this.filterRoleRouter(res, checkedIds))
             this.countAllPermissions()

+ 72 - 2
src/views/ncs-auth/superadmin/defaultRoleManager.vue

@@ -20,18 +20,33 @@
       <el-main>
         <el-header style="text-align: right; font-size: 12px;height: 30px">
           <el-button type="primary" size="mini" @click="createRole">新建角色</el-button>
-          <el-button type="danger" size="mini" @click="deleteRole">删除角色</el-button>
+          <el-button :disabled="role_id === 0" type="success" size="mini" @click="roleEvent">角色事件</el-button>
+          <el-button :disabled="role_id === 0" type="danger" size="mini" @click="deleteRole">删除角色</el-button>
         </el-header>
         <role-edit :role_id="role_id" @aftersave="getRoleList" />
       </el-main>
     </el-container>
+    <el-dialog title="编辑角色事件" :visible.sync="formShow" width="50%">
+      <el-form ref="editform" label-width="80px">
+        <el-checkbox v-model="allCheck" :indeterminate="indeterminate" @change="handleCheckAllChange">全选</el-checkbox>
+        <div style="margin: 15px 0;"></div>
+        <el-checkbox-group v-model="newCheckList" @change="handleCheckedCitiesChange">
+          <el-checkbox v-for="(item, index) in eventList" :key="index" :label="item.id" style="width: 200px;">{{ item.name }}</el-checkbox>
+        </el-checkbox-group>
+        <div align="center" class="margin-top-sm">
+          <el-button type="success" @click="onSubmit">保存设置</el-button>
+          <el-button @click="formShow = false">取消</el-button>
+        </div>
+      </el-form>
 
+    </el-dialog>
   </div>
 </template>
 
 <script>
 import RoleEdit from '../compontents/roleEdit'
 import * as API_Auth from '@/api/role'
+import * as API_event from '@/api/ncs_event'
 export default {
   name: 'DefaultRoleManager',
   components: { RoleEdit },
@@ -40,7 +55,13 @@ export default {
       /** 角色列表 **/
       tableData: [],
       /** 当前选中的角色id */
-      role_id: 0
+      role_id: 0,
+      formShow: false,
+      eventList: [],
+      indeterminate: false,
+      allCheck: false,
+      newCheckList: [],
+      oldCheckList: []
     }
   },
   computed: {
@@ -85,6 +106,7 @@ export default {
     deleteRole() {
       if (this.role_id === 0) {
         this.$message.error('没有选中任何角色!')
+        return
       }
       this.$confirm('删除操作后数据不可复原,您确定要删除此数据?', '警告', {
         confirmButtonText: '确定',
@@ -112,6 +134,54 @@ export default {
           message: '已取消删除'
         })
       })
+    },
+    roleEvent() {
+      this.formShow = true
+      this.getEventList({ page_size: 200, page_no: 1, fixedCondition: ' (role_id = ' + this.role_id + ' or ISNULL(role_id))', sort: ' id', dir: 'desc' })
+    },
+    getEventList(params) {
+      this.newCheckList = []
+      this.oldCheckList = []
+      this.indeterminate = false
+      this.allCheck = false
+      const _this = this
+      API_event.getList(params).then(res => {
+        this.eventList = res.data
+        res.data.forEach(item => {
+          if (item.role_id === this.role_id) {
+            _this.newCheckList.push(item.id)
+            _this.oldCheckList.push(item.id)
+            _this.indeterminate = true
+          }
+        })
+      })
+    },
+    handleCheckAllChange(val) {
+      this.newCheckList = []
+      if (val) {
+        this.eventList.forEach(item => {
+          this.newCheckList.push(item.id)
+        })
+      } else {
+        this.newCheckList = []
+      }
+      this.indeterminate = false
+    },
+    handleCheckedCitiesChange(value) {
+      const checkedCount = value.length
+      this.allCheck = checkedCount === this.eventList.length
+      this.indeterminate = checkedCount > 0 && checkedCount < this.eventList.length
+    },
+    onSubmit() {
+      const data = {
+        roleId: this.role_id,
+        newIds: this.newCheckList.join(','),
+        oldIds: this.oldCheckList.join(',')
+      }
+      API_event.updateRoleId(data).then(res => {
+        this.formShow = false
+        this.$message.success('设置成功!')
+      })
     }
   }
 }

+ 94 - 10
src/views/ncs-clerk/clerkList.vue

@@ -88,7 +88,7 @@
           <el-col :span="12">
             <el-form-item label="性别" class="form-item-sex">
               <el-radio v-model="addMemberForm.sex" :label="1">男</el-radio>
-              <el-radio v-model="addMemberForm.sex" :label="2">女</el-radio>
+              <el-radio v-model="addMemberForm.sex" :label="0">女</el-radio>
             </el-form-item>
           </el-col>
           <el-col :span="12">
@@ -144,6 +144,15 @@
             </el-form-item>
           </el-col>
         </el-row>
+        <el-row v-if="nurseList.length > 0">
+          <el-col :span="24">
+            <el-form-item label="小组成员">
+              <el-checkbox-group v-model="newCheckList">
+                <el-checkbox v-for="(item, index) in nurseList" :key="index" :label="item.clerk_id" style="width: 200px;">{{ item.clerk_name }}</el-checkbox>
+              </el-checkbox-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
 
 
 <!--        <el-row>-->
@@ -185,11 +194,19 @@
   import ButtonCellRender from "@/components/AgGridCellRender/ButtonCellRender"
   import AgGridImg from "@/components/AgGridImg/AgGridImg"
   import ImageViewer from "element-ui/packages/image/src/image-viewer"
+  import RadioFilter from "@/components/AgGridCustomFilter/RadioFilter";
+  import * as API_event from "@/api/ncs_event";
   let prevOverflow = ''
 
   export default {
     name: 'careDoctorManager',
-    components: { ButtonCellRender, AgGridImg, ImageViewer },
+    components: { ButtonCellRender, AgGridImg, ImageViewer, RadioFilter },
+    props: {
+      partId: {
+        type: Number,
+        default: 0
+      }
+    },
     data: function() {
       return {
         uploadurl: serverUrl + '/ncs/upload/uploadFile',
@@ -201,7 +218,7 @@
           page_size: 10,
           page_no: 1,
           sort: 'nc.member_id',
-          dir: 'asc',
+          dir: 'asc'
         },
         /** 列表数据 */
         tableData: [],
@@ -262,7 +279,17 @@
         columnApi: null,
         localeText: AG_GRID_LOCALE_CN,
         rowSelection: null,
-        showViewer: false
+        showViewer: false,
+        sexTransfer: [
+          { key: '男', value: 1 },
+          { key: '女', value: 0 }
+        ],
+        roleId: null,
+        roleZzId: null,
+        newCheckList: [],
+        oldCheckList: [],
+        nurseList: [],
+        shopId: null
       }
     },
     computed: {
@@ -270,6 +297,17 @@
         return this.mainAreaHeight - 130
       }
     },
+    watch: {
+      partId(val, oldvalue) {
+        if (val === null) {
+          this.shopId = this.$store.getters.partId
+        } else {
+          this.shopId = val
+        }
+        this.params.fixedCondition =  'nc.shop_id=' + this.shopId
+        this.GET_MemberList()
+      }
+    },
     beforeMount() {
       this.gridOptions = {
       }
@@ -293,9 +331,13 @@
             }
           },
         },
-        { headerName: '登名', field: 'uname', sortable: true, filter: true, minWidth: 170 },
+        { headerName: '登名', field: 'uname', sortable: true, filter: true, minWidth: 170 },
         { headerName: '真实名字', field: 'clerk_name', sortable: true, filter: true, minWidth: 120 },
-        { headerName: '性别', field: 'sex', sortable: true, filter: false, valueFormatter: this.formatterSex, width: 100 },
+        { headerName: '性别', field: 'sex', sortable: true, valueFormatter: this.formatterSex, width: 100, filterFramework: 'RadioFilter',
+          filterParams: {
+            listData: this.sexTransfer
+          }
+        },
         { headerName: '手机', field: 'mobile', sortable: true, filter: true, minWidth: 170 },
         { headerName: '角色', field: 'role_name', sortable: true, filter: false, valueFormatter: this.formatterRole, width: 120 },
         { headerName: '操作', field: 'id',
@@ -333,6 +375,12 @@
     mounted() {
       this.gridApi = this.gridOptions.api
       this.getRoles({ page_size: 200, page_no: 1, fixedCondition: ' shop_id = -1', sort: ' role_id', dir: 'desc' })
+      if (this.partId === 0) {
+        this.shopId = this.$store.getters.partId
+      } else {
+        this.shopId = this.partId
+      }
+      this.params.fixedCondition =  'nc.shop_id=' + this.shopId
       this.GET_MemberList()
     },
     activated() {
@@ -402,8 +450,16 @@
       },
       getRoles(param) {
         // 获取角色
-        clerk_API.getRoles(param).then(response => {
-          this.rolesOptions = response.data
+        clerk_API.getRoles(param).then(res => {
+          this.rolesOptions = res.data
+          const nurseZz = res.data.find(item => item.role_name === '护士组长')
+          if (nurseZz) {
+            this.roleZzId = nurseZz.role_id
+            const nurse = res.data.find(item => item.role_name === '护士')
+            if (nurse) {
+              this.roleId = nurse.role_id
+            }
+          }
         })
       },
       /** 批量数据删除处理(删除选中的行) */
@@ -427,7 +483,7 @@
 
       /** 性别格式化 */
       formatterSex(row) {
-        return row.data.sex === 1 ? '男' :  row.data.sex === 2 ? '女' : '未知'
+        return row.data.sex === 1 ? '男' :  row.data.sex === 0 ? '女' : '未知'
       },
 
       formatterRole(row) {
@@ -451,13 +507,21 @@
               params.face = this.imageUrl
             }
             if (params.member_id) {
+              if (this.roleZzId === params.role_id) {
+                const data = {
+                  clerkId: params.clerk_id,
+                  newIds: this.newCheckList.join(','),
+                  oldIds: this.oldCheckList.join(',')
+                }
+                clerk_API.updateParentById(data)
+              }
               clerk_API.update(params.clerk_id, params).then(response => {
                 this.dialogAddMemberVisible = false
                 this.imageUrl = null
                 this.GET_MemberList()
               })
             } else {
-              params.shop_id = this.$store.getters.partId
+              params.shop_id = this.shopId
               clerk_API.add(params).then(response => {
                 this.dialogAddMemberVisible = false
                 this.imageUrl = null
@@ -473,6 +537,7 @@
       },
       /** 添加会员 */
       handleAddMember() {
+        this.nurseList = []
         this.imageUrl = null
         this.addMemberForm = { sex: 1 }
         this.addMemberRules.password[0].required = true
@@ -481,6 +546,10 @@
       /** 编辑用户 */
       handlerEdit(row) {
         this.addMemberForm = Object.assign({}, row)
+        if (this.roleZzId && this.roleZzId === row.role_id) { // 只有护士组长才能编辑小组成员
+          this.getNurseByRoleId(row.clerk_id)
+        }
+        this.nurseList = []
         this.imageUrl = row.face
         delete this.addMemberForm.password
         this.addMemberRules.password[0].required = false
@@ -489,6 +558,21 @@
         }
         this.dialogAddMemberVisible = true
       },
+      getNurseByRoleId(id) {
+        const _this = this
+        this.newCheckList = []
+        this.oldCheckList = []
+        clerk_API.getNurseByRoleId(_this.roleId, id).then(r => {
+          _this.nurseList = r
+          r.forEach(item => {
+            if (item.parent_id=== id) {
+              _this.newCheckList.push(item.clerk_id)
+              _this.oldCheckList.push(item.clerk_id)
+            }
+          })
+        })
+
+      },
       /** 分页大小发生改变 */
       handlePageSizeChange(size) {
         this.params.page_size = size

+ 30 - 6
src/views/ncs-device/components/deviceManager.vue

@@ -142,7 +142,15 @@
             </el-form-item>
           </el-col>
         </el-row>
-
+        <el-row v-if="hasRoleId">
+          <el-col :span="12">
+            <el-form-item label="适用角色" prop="role_id">
+              <el-select v-model="deviceModel.role_id" placeholder="适用角色" clearable>
+                <el-option v-for="item in rolesOptions" :key="item.role_id" :label="item.role_name" :value="item.role_id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
       </el-form>
       <div slot="footer" class="dialog-footer">
         <el-button type="primary" @click="handlerFormSubmit('deviceEditForm')">确 定</el-button>
@@ -160,6 +168,7 @@ import ListFilter from '@/components/AgGridCustomFilter/ListFilter'
 import RadioFilter from '@/components/AgGridCustomFilter/RadioFilter'
 import * as API_Device from '@/api/ncs_device'
 import * as API_Frame from '@/api/ncs_hospitalFrame'
+import * as clerk_API from '@/api/ncs_clerk'
 export default {
   name: 'DeviceManager',
   components: { ButtonCellRender, ListFilter, RadioFilter },
@@ -215,6 +224,9 @@ export default {
         ],
         frame_id: [
           { required: Object.keys(this.frame).length === 0, message: '请选安装位置!', trigger: 'blur' } // 没有传入frame 属性,必须选择安装位置
+        ],
+        role_id: [
+          { required: true, message: '请选择适用人', trigger: 'blur' }
         ]
       },
       partFrames: [],
@@ -226,8 +238,8 @@ export default {
         { key: '病床分机', value: 4 },
         { key: 'LCD走廊屏', value: 5 },
         { key: 'LED点阵屏', value: 6 },
-        { key: '护士腕表', value: 7 },
-        { key: '护工腕表', value: 8 },
+        { key: '移动设备', value: 7 },
+        // { key: '护工腕表', value: 8 },
         { key: '病人腕表', value: 9 },
         { key: '手机App', value: 10 },
         { key: '总线转换盒', value: 11 },
@@ -241,7 +253,9 @@ export default {
       deviceStatusTransfer: [
         { key: '启用', value: 1, color: 'green' },
         { key: '未启用', value: 0, color: 'red' }
-      ]
+      ],
+      rolesOptions: [],
+      hasRoleId: false
     }
   },
   computed: {
@@ -252,7 +266,7 @@ export default {
   },
   watch: {
     frame(val, oldvalue) {
-      console.log('watch',val)
+      console.log('watch', val)
       this.params.fixedCondition = Object.keys(this.frame).length === 0 ? 'part_id=' + this.$store.getters.partId : 'part_id=' + this.$store.getters.partId + ' and frame_id =' + this.frame.id
       this.getList()
     }
@@ -448,7 +462,6 @@ export default {
     deviceStatusFormatter(params) {
       if (params.value === null || params.value === undefined) return ''
       const item = this.deviceStatusTransfer.filter(p => p.value === params.value)[0]
-      console.log('item', item)
       if (item) {
         return '<span style="color:' + item.color + ';">' + item.key + '</span>'
       } else {
@@ -490,6 +503,7 @@ export default {
       } else {
         this.deviceRules.eth_mac[0].required = true
       }
+      this.hasRoleId = val === 7
     },
     /** 添加设备事件 **/
     handleAdd() {
@@ -504,13 +518,17 @@ export default {
         this.$set(this.deviceModel, 'frame_id', this.frame.id)
       }
       delete this.deviceModel.id
+      this.hasRoleId = false
+      this.getRoles({ page_size: 200, page_no: 1, fixedCondition: ' shop_id = -1', sort: ' role_id', dir: 'desc' })
       this.deviceEditTitle = '添加设备'
       this.deviceDialogVisible = true
       this.deviceTypeDisabled = false // 新增设备可以选择设备类型
     },
     /** 修改设备  **/
     handleEdit(params) {
+      this.getRoles({ page_size: 200, page_no: 1, fixedCondition: ' shop_id = -1', sort: ' role_id', dir: 'desc' })
       console.log('param', params)
+      this.hasRoleId = params.device_type === 7
       this.deviceModel = {
         ...params
       }
@@ -554,6 +572,12 @@ export default {
     handlePageCurrentChange(page) {
       this.params.page_no = page
       this.getList()
+    },
+    getRoles(param) {
+      // 获取角色
+      clerk_API.getRoles(param).then(response => {
+        this.rolesOptions = response.data
+      })
     }
 
   }

+ 1 - 1
src/views/ncs-device/device-admin.vue

@@ -587,7 +587,7 @@ export default {
     formatterSex(row, column, cellValue) {
       if (row.staff_sex === 1) {
         return '男'
-      } else if (row.staff_sex === 2) {
+      } else if (row.staff_sex === 0) {
         return '女'
       } else {
         return '未知'

+ 22 - 4
src/views/ncs-device/device-edit.vue

@@ -13,8 +13,8 @@
                 <el-option label="病床分机" :value="4" />
                 <el-option label="LCD走廊屏" :value="5" />
                 <el-option label="LED点阵屏" :value="6" />
-                <el-option label="护士腕表" :value="7" />
-                <el-option label="护工腕表" :value="8" />
+                <el-option label="移动设备" :value="7" />
+<!--                <el-option label="护工腕表" :value="8" />-->
                 <el-option label="病人腕表" :value="9" />
                 <el-option label="手机App" :value="10" />
                 <el-option label="总线转换盒" :value="11" />
@@ -109,6 +109,13 @@
 <!--              <el-radio v-model="formmodel.status" :label="0">不启用</el-radio>-->
             </el-form-item>
           </el-col>
+          <el-col :span="12">
+            <el-form-item label="适用角色" prop="device_type">
+              <el-select v-model="formmodel.role_id" placeholder="适用角色" :disabled="deviceTypeDisabled" clearable @change="deviceTypeChange">
+                <el-option v-for="item in rolesOptions" :key="item.role_id" :label="item.role_name" :value="item.role_id"></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
         </el-row>
       </el-form>
 
@@ -123,6 +130,7 @@
 <script>
 import * as API_Device from '@/api/ncs_device'
 import { returnDeviceType } from "@/utils/device_type"
+import * as clerk_API from "@/api/ncs_clerk";
 
 export default {
 
@@ -182,7 +190,8 @@ export default {
       deviceEthIPReadonly: false,
       wifiHostReadonly: true,
       /** 设备类型选择禁用 编辑时不允许修改设备类型 */
-      deviceTypeDisabled: false
+      deviceTypeDisabled: false,
+      rolesOptions: []
     }
   },
   computed: {
@@ -209,8 +218,15 @@ export default {
     } else {
       this.handlerAdd()
     }
+    this.getRoles({ page_size: 200, page_no: 1, fixedCondition: ' shop_id = -1', sort: ' role_id', dir: 'desc' })
   },
   methods: {
+    getRoles(param) {
+      // 获取角色
+      clerk_API.getRoles(param).then(response => {
+        this.rolesOptions = response.data
+      })
+    },
     /** 新增按钮 */
     async handlerAdd() {
       console.log('nextip', this.nextIp)
@@ -326,8 +342,10 @@ export default {
       }
     },
     getDeviceById() {
+      const _this = this
       API_Device.getDeviceById(this.deviceId).then((res) => {
-        this.formmodel = res
+        _this.formmodel = res
+        _this.getRoles({ page_size: 200, page_no: 1, fixedCondition: ' shop_id = -1', sort: ' role_id', dir: 'desc' })
       })
     }
   }

+ 83 - 24
src/views/ncs-device/nurse_watch.vue

@@ -100,9 +100,12 @@ import { unixToDate } from '@/utils/Foundation'
 import { AG_GRID_LOCALE_CN } from '@/utils/AgGridVueLocaleCn'
 import { DeviceUrl } from '@/utils/domain'
 import * as clerk_API from '@/api/ncs_clerk'
+import ButtonCellRender from "@/components/AgGridCellRender/ButtonCellRender"
+import RadioFilter from "@/components/AgGridCustomFilter/RadioFilter";
 
 export default {
   name: 'Index',
+  components: { ButtonCellRender, RadioFilter },
   data: function() {
     return {
       /** 表格数据 */
@@ -137,7 +140,12 @@ export default {
       columnApi: null,
       localeText: AG_GRID_LOCALE_CN,
       rowSelection: null,
-      showViewer: false
+      showViewer: false,
+      timer: '',
+      deviceStatusTransfer: [
+        { key: '启用', value: 1, color: 'green' },
+        { key: '未启用', value: 0, color: 'red' }
+      ]
     }
   },
   computed: {
@@ -159,23 +167,49 @@ export default {
         resizable: false,
         valueGetter: this.hashValueGetter
       },
-      { headerName: '设备别名', field: 'name', sortable: true, minWidth: 150 },
-      { headerName: '设备状态', field: 'status', sortable: true, cellRenderer: this.formatterSatus, minWidth: 100 },
-      { headerName: '绑定人', field: 'member_name', sortable: true, minWidth: 140 },
-      { headerName: '所属位置', field: 'full_name', sortable: true, minWidth: 140 },
-      { headerName: '有线物理地址', field: 'eth_mac', sortable: true, minWidth: 150 },
-      { headerName: '有线IP地址', field: 'eth_ip', sortable: true, minWidth: 150 },
-      { headerName: '设备型号', field: 'model', sortable: true, minWidth: 150 },
-      { headerName: '出厂编号', field: 'code', sortable: true, minWidth: 150 },
-      { headerName: '软件版本', field: 'soft_ver', sortable: true, minWidth: 150 },
-      { headerName: '硬件版本', field: 'hard_ver', sortable: true, minWidth: 150 },
-      { headerName: 'WIFI物理地址', field: 'wifi_mac', sortable: true, minWidth: 150 },
-      { headerName: 'WIFIIP地址', field: 'wifi_ip', sortable: true, minWidth: 150 },
-      { headerName: 'SIP账号', field: 'sip_id', sortable: true, minWidth: 150 },
-      { headerName: '最后修改时间', field: 'update_time', sortable: true, valueFormatter: this.formatterDate, minWidth: 170 }
+      { headerName: '设备别名', field: 'name', sortable: true, filter: 'agTextColumnFilter', minWidth: 150 },
+      { headerName: '设备状态', field: 'status', sortable: true, cellRenderer: this.formatterSatus, minWidth: 120, filterFramework: 'RadioFilter',
+        filterParams: {
+          listData: this.deviceStatusTransfer
+        }
+      },
+      { headerName: '绑定人', field: 'member_name', sortable: true, filter: 'agTextColumnFilter', minWidth: 140, valueFormatter: this.formatterName },
+      { headerName: '所属位置', field: 'full_name', sortable: true, filter: 'agTextColumnFilter', minWidth: 140 },
+      { headerName: '有线物理地址', field: 'eth_mac', sortable: true, filter: 'agTextColumnFilter', minWidth: 150 },
+      { headerName: '有线IP地址', field: 'eth_ip', sortable: true, filter: 'agTextColumnFilter', minWidth: 150 },
+      { headerName: '设备型号', field: 'model', sortable: true, filter: 'agTextColumnFilter', minWidth: 150 },
+      { headerName: '出厂编号', field: 'code', sortable: true, filter: 'agTextColumnFilter', minWidth: 150 },
+      { headerName: '软件版本', field: 'soft_ver', sortable: true, filter: 'agTextColumnFilter', minWidth: 150 },
+      { headerName: '硬件版本', field: 'hard_ver', sortable: true, filter: 'agTextColumnFilter', minWidth: 150 },
+      { headerName: 'WIFI物理地址', field: 'wifi_mac', sortable: true, filter: 'agTextColumnFilter', minWidth: 150 },
+      { headerName: 'WIFIIP地址', field: 'wifi_ip', sortable: true, filter: 'agTextColumnFilter', minWidth: 150 },
+      { headerName: 'SIP账号', field: 'sip_id', sortable: true, filter: 'agTextColumnFilter', minWidth: 150 },
+      // { headerName: '最后修改时间', field: 'update_time', sortable: true, valueFormatter: this.formatterDate, minWidth: 170 },
+      { headerName: '更新时间', field: 'update_time', sortable: true, filter: 'agDateColumnFilter', minWidth: 170, valueFormatter: this.formatterDate,
+        filterParams: {
+          comparator: (filterLocalDateAtMidnight, cellValue) => { // 所有数据都由服务器端过滤,此处只需返回0 即可
+            return 0
+          }
+        }
+      },
+      {
+        headerName: '编辑', field: 'shop_id',
+        cellRendererFramework: 'ButtonCellRender',
+        cellRendererParams: {
+          onClick: this.handEdit,
+          label: '编辑',
+          buttonType: 'primary',
+          buttonSize: 'mini'
+        },
+        filter: false,
+        pinned: 'right',
+        lockPinned: true,
+        minWidth: 100,
+        resizable: false,
+        sortable: false
+      }
     ]
     this.defaultColDef = {
-      filter: false,
       sortable: true,
       resizable: true,
       comparator: this.testComparator,
@@ -193,6 +227,12 @@ export default {
     this.getList()
     this.initWebSocket()
   },
+  beforeDestroy() {
+    clearTimeout(this.timer)
+  },
+  destroyed() {
+    clearTimeout(this.timer)
+  },
   methods: {
     initWebSocket: function() {
       const stockbase = DeviceUrl.replace('http', 'ws')
@@ -220,12 +260,13 @@ export default {
     websocketclose: function(e) {
       const _this = this
       console.log('socket连接关闭connection closed (' + e.code + ')')
-      this.$alert('连接已断开,需重新连接', '连接确定', {
-        confirmButtonText: '确定',
-        callback: action => {
-          _this.initWebSocket()
-        }
-      })
+      _this.timer = setTimeout(_this.initWebSocket, 30000)
+      // this.$alert('连接已断开,需重新连接', '连接确定', {
+      //   confirmButtonText: '确定',
+      //   callback: action => {
+      //     _this.initWebSocket()
+      //   }
+      // })
     },
     /** 选择行变化时,记录选中的行数据 */
     selectFun(val) {
@@ -299,10 +340,21 @@ export default {
     formatterDate(params) {
       return unixToDate(params.value)
     },
+    formatterName(params) {
+      if (params.value && params.data.role_name) {
+        return params.value + params.data.role_name
+      } else {
+        if (params.value) {
+          return params.value
+        } else if (params.data.role_name) {
+          return '未绑定' + params.data.role_name
+        }
+      }
+    },
     filterModifed(param) {
       const model = param.api.getFilterModel()
       this.params.filter = JSON.stringify(model)
-      this.GET_List()
+      this.getList()
     },
     gridSortChange(param) {
       const columnState = param.columnApi.getColumnState()
@@ -334,7 +386,7 @@ export default {
         delete this.params.sort
         delete this.params.dir
       }
-      this.GET_List()
+      this.getList()
     },
     formatterSatus(param) {
       if (param.value === 1) {
@@ -360,6 +412,13 @@ export default {
           })
         }
       })
+    },
+    handEdit(row) {
+      if (row.role_id) {
+        this.$router.push({ name: 'nurseWatchFrame', params: { id: row.id, role_id: row.role_id, callback: this.getList() }})
+      } else {
+        this.$message.error('请先设置适用人')
+      }
     }
   }
 }

+ 33 - 57
src/views/ncs-event/index.vue

@@ -1,55 +1,5 @@
 <template>
     <div class="formwrap">
-<!--        <en-table-layout-->
-<!--                toolbar-->
-<!--                @selection-change="selectFun"-->
-<!--                @sort-change="tableSort"-->
-<!--                pagination-->
-<!--                :tableData="tableData"-->
-<!--                :height="600"-->
-<!--                :loading="loading"-->
-<!--                :default-sort="{prop: 'id', order: 'ascending'}"-->
-<!--        >-->
-<!--            &lt;!&ndash;表头&ndash;&gt;-->
-<!--            <template slot="table-columns">-->
-<!--                <el-table-column type="selection" width="55" align="center"></el-table-column>-->
-<!--                <el-table-column style="text-align: left;" label="图标" width="70">-->
-<!--                    <template slot-scope="scope">-->
-<!--                        <el-image :src="scope.row.icon_src" lazy fit="cover" :preview-src-list="srcList" @click="lookBigImg(scope.row.icon_src)">-->
-<!--                            <div slot="error" class="image-slot">-->
-<!--                                <i class="el-icon-picture-outline"></i>-->
-<!--                            </div>-->
-<!--                        </el-image>-->
-<!--                    </template>-->
-<!--                </el-table-column>-->
-<!--                <el-table-column prop="name" label="名称" min-width="150" align="center" />-->
-<!--                <el-table-column prop="desc" label="描述" min-width="150" align="center" />-->
-<!--                <el-table-column prop="key_code" label="唯一标识码" width="160" align="center" />-->
-<!--                <el-table-column prop="min_x" label="x轴范围" align="center" width="150" :formatter="formatterX" />-->
-<!--                <el-table-column prop="min_y" label="y轴范围" width="150" align="center" :formatter="formatterY" />-->
-<!--                <el-table-column prop="create_time" label="创建时间" width="170" align="center" :formatter="formatterDate" />-->
-<!--                <el-table-column style="text-align: left;" label="操作" width="150">-->
-<!--                    <template slot-scope="scope">-->
-<!--                        <el-button type="success" size="mini"  @click="handlerEdit(scope.$index,scope.row)">编辑</el-button>-->
-<!--                        <el-button type="danger" size="mini"  @click="handlerDelete(scope.row.id)">删除</el-button>-->
-<!--                    </template>-->
-<!--                </el-table-column>-->
-<!--            </template>-->
-
-<!--            &lt;!&ndash;翻页&ndash;&gt;-->
-<!--            <el-pagination-->
-<!--                    slot="pagination"-->
-<!--                    v-if="pageData"-->
-<!--                    :current-page="pageData.page_no"-->
-<!--                    :page-sizes="[10, 20, 50, 100]"-->
-<!--                    :page-size="pageData.page_size"-->
-<!--                    @size-change="handlePageSizeChange"-->
-<!--                    @current-change="handlePageCurrentChange"-->
-<!--                    layout="total, sizes, prev, pager, next, jumper"-->
-<!--                    :total="pageData.data_total">-->
-<!--            </el-pagination>-->
-<!--        </en-table-layout>-->
-
         <ag-grid-layout
                 :table-height="tableHeight"
                 theme="ag-theme-alpine"
@@ -115,6 +65,11 @@
                             <el-option label="SOS紧急按钮" value="SOS紧急按钮" />
                         </el-select>
                     </el-form-item>
+                    <el-form-item label="适用角色" prop="role_id">
+                        <el-select v-model="formmodel.role_id" placeholder="适用角色" clearable>
+                            <el-option v-for="item in rolesOptions" :key="item.role_id" :label="item.role_name" :value="item.role_id"></el-option>
+                        </el-select>
+                    </el-form-item>
                     <el-form-item label="图标">
                         <el-upload
                                 class="avatar-uploader"
@@ -145,6 +100,7 @@
     import ButtonCellRender from "@/components/AgGridCellRender/ButtonCellRender"
     import AgGridImg from "@/components/AgGridImg/AgGridImg"
     import ImageViewer from "element-ui/packages/image/src/image-viewer"
+    import * as clerk_API from "@/api/ncs_clerk";
     let prevOverflow = ''
 
     export default {
@@ -161,6 +117,9 @@
                 rules: {
                     name: [
                         {required: true, message: '请输入名称', trigger: 'blur'}
+                    ],
+                    role_id: [
+                        { required: true, message: '请选择适用人', trigger: 'blur' }
                     ]
                 },
                 pageData: [],
@@ -183,7 +142,8 @@
                 columnApi: null,
                 localeText: AG_GRID_LOCALE_CN,
                 rowSelection: null,
-                showViewer: false
+                showViewer: false,
+                rolesOptions: [],
             }
         },
         computed: {
@@ -216,10 +176,15 @@
                 },
                 { headerName: '名称', field: 'name', sortable: true, minWidth: 150 },
                 { headerName: '描述', field: 'desc', sortable: true, minWidth: 220 },
-                { headerName: '唯一标识码', field: 'key_code', sortable: true, width: 160 },
-                { headerName: 'x轴范围', field: 'min_x', sortable: true, filter: false, valueFormatter: this.formatterX, minWidth: 150 },
-                { headerName: 'y轴范围', field: 'min_y', sortable: true, filter: false, valueFormatter: this.formatterY, width: 150 },
-                { headerName: '创建时间', field: 'create_time', sortable: true, filter: false, valueFormatter: this.formatterDate, width: 170 },
+                { headerName: '唯一标识码', field: 'key_code', sortable: true, minWidth: 160 },
+                { headerName: 'x轴范围', field: 'min_x', sortable: true, filter: false, valueFormatter: this.formatterX, minWidth: 100 },
+                { headerName: 'y轴范围', field: 'min_y', sortable: true, filter: false, valueFormatter: this.formatterY, minWidth: 100 },
+                { headerName: '创建时间', field: 'create_time', sortable: true,  valueFormatter: this.formatterDate, minWidth: 170, filter: 'agDateColumnFilter',
+                    filterParams: {
+                        comparator: (filterLocalDateAtMidnight, cellValue) => { // 所有数据都由服务器端过滤,此处只需返回0 即可
+                            return 0
+                        }
+                    } },
                 { headerName: '编辑', field: 'id',
                     cellRendererFramework: 'ButtonCellRender',
                     cellRendererParams: param => {
@@ -270,6 +235,7 @@
                 this.rowSelection = 'multiple'
         },
         mounted() {
+            this.gridApi = this.gridOptions.api
             this.getList()
         },
         methods: {
@@ -278,6 +244,7 @@
                 if (this.$refs.editform) {
                     this.$refs.editform.resetFields()
                 }
+                this.getRoles({ page_size: 200, page_no: 1, fixedCondition: ' shop_id = -1', sort: ' role_id', dir: 'desc' })
                 this.imageUrl = null
                 this.formmodel.type = '遥控器'
                 this.editflag = 0
@@ -285,6 +252,7 @@
             },
             handlerEdit: function (row) {
                 this.formmodel = Object.assign({}, row)
+                this.getRoles({ page_size: 200, page_no: 1, fixedCondition: ' shop_id = -1', sort: ' role_id', dir: 'desc' })
                 this.imageUrl = row.icon_src
                 this.editflag = 1
                 this.formshow = true
@@ -337,6 +305,8 @@
             /** 加载通知列表 */
             getList() {
                 this.loading = true
+                this.gridApi.showLoadingOverlay()
+                this.gridApi.sizeColumnsToFit()
                 API_event.getList(this.params).then(response => {
                     this.loading = false
                     this.tableData = response.data
@@ -496,7 +466,7 @@
             filterModifed(param) {
                 let model = param.api.getFilterModel()
                 this.params.filter = JSON.stringify(model)
-                this.GET_List()
+                this.getList()
             },
             gridSortChange(param) {
                 const columnState = param.columnApi.getColumnState()
@@ -528,7 +498,13 @@
                     delete this.params.sort
                     delete this.params.dir
                 }
-                this.GET_List()
+                this.getList()
+            },
+            getRoles(param) {
+                // 获取角色
+                clerk_API.getRoles(param).then(response => {
+                    this.rolesOptions = response.data
+                })
             }
         }
     }

+ 80 - 15
src/views/ncs-nurse-config/index.vue

@@ -1,16 +1,17 @@
 <template>
   <div  class="app-container">
     <el-row>
-      <el-col :span="8">
-        <el-row>
-          <el-col :span="24" class="toolbar">
-            <el-form :inline="true">
-              <el-form-item>
-                <el-button type="primary" @click="addNurseConfig(1,null,1)">添加护理</el-button>
-              </el-form-item>
-            </el-form>
-          </el-col>
-        </el-row>
+      <el-col :span="24" class="toolbar">
+        <el-form :inline="true">
+          <el-form-item>
+            <el-button type="primary" @click="addNurseConfig(1,null,1)">添加护理</el-button>
+          </el-form-item>
+        </el-form>
+      </el-col>
+    </el-row>
+    <el-container :style="{height: tableHeight+'px'}">
+
+      <el-aside width="360px" style="background-color: rgb(238, 241, 246)">
         <el-table :data="tagList1" highlight-current-row v-loading="listLoading" stripe
                   @cell-click="tableClick" class="mytable">
           <el-table-column v-if="false" prop="id"></el-table-column>
@@ -28,12 +29,12 @@
             </template>
           </el-table-column>
         </el-table>
-      </el-col>
-
-      <el-col :span="15">
+      </el-aside>
+      <el-main>
         <el-row>
           <el-col>当前选择:<h4>{{pName}}</h4></el-col>
         </el-row>
+<!--        <el-header style="text-align: right; font-size: 12px;height: 30px">当前选择:<h4>{{pName}}</h4></el-header>-->
         <el-table :data="tagList2" highlight-current-row v-loading="listLoading" stripe class="mytable">
           <el-table-column v-if="false" prop="id"></el-table-column>
           <el-table-column prop="option_name" label="护理项名"></el-table-column>
@@ -49,8 +50,60 @@
             </template>
           </el-table-column>
         </el-table>
-      </el-col>
-    </el-row>
+      </el-main>
+    </el-container>
+
+<!--    <el-row>-->
+<!--      <el-col :span="8">-->
+<!--        <el-row>-->
+<!--          <el-col :span="24" class="toolbar">-->
+<!--            <el-form :inline="true">-->
+<!--              <el-form-item>-->
+<!--                <el-button type="primary" @click="addNurseConfig(1,null,1)">添加护理</el-button>-->
+<!--              </el-form-item>-->
+<!--            </el-form>-->
+<!--          </el-col>-->
+<!--        </el-row>-->
+<!--        <el-table :data="tagList1" highlight-current-row v-loading="listLoading" stripe-->
+<!--                  @cell-click="tableClick" class="mytable">-->
+<!--          <el-table-column v-if="false" prop="id"></el-table-column>-->
+<!--          <el-table-column prop="config_name" label="护理名"></el-table-column>-->
+<!--          <el-table-column-->
+<!--                  label=""-->
+<!--                  width="180">-->
+<!--            <template slot-scope="scope">-->
+<!--              <el-button type="success" icon="el-icon-circle-plus-outline" circle-->
+<!--                         @click.native.prevent="addNurseConfig(scope.$index, scope.row,2)"></el-button>-->
+<!--              <el-button type="primary" icon="el-icon-edit" circle-->
+<!--                         @click.native.prevent="updateRow(scope.$index, scope.row, 1)"></el-button>-->
+<!--              <el-button type="danger" icon="el-icon-delete" circle-->
+<!--                         @click.native.prevent="deleteRow(scope.$index, scope.row,1)"></el-button>-->
+<!--            </template>-->
+<!--          </el-table-column>-->
+<!--        </el-table>-->
+<!--      </el-col>-->
+
+<!--      <el-col :span="15">-->
+<!--        <el-row>-->
+<!--          <el-col>当前选择:<h4>{{pName}}</h4></el-col>-->
+<!--        </el-row>-->
+<!--        <el-table :data="tagList2" highlight-current-row v-loading="listLoading" stripe class="mytable">-->
+<!--          <el-table-column v-if="false" prop="id"></el-table-column>-->
+<!--          <el-table-column prop="option_name" label="护理项名"></el-table-column>-->
+<!--          <el-table-column prop="nursecfg_color" label="颜色标识" width="160" align="center">-->
+<!--            <template slot-scope="scope">-->
+<!--              <el-button :style="'width: 120px;height: 30px;background-color: #'+scope.row.color_rgb" />-->
+<!--            </template>-->
+<!--          </el-table-column>-->
+<!--          <el-table-column label="" width="140">-->
+<!--            <template slot-scope="scope">-->
+<!--              <el-button type="primary" icon="el-icon-edit" circle @click.native.prevent="updateRow(scope.$index, scope.row, 2)"></el-button>-->
+<!--              <el-button type="danger" icon="el-icon-delete" circle @click.native.prevent="deleteRow(scope.$index, scope.row,2)"></el-button>-->
+<!--            </template>-->
+<!--          </el-table-column>-->
+<!--        </el-table>-->
+<!--      </el-col>-->
+<!--    </el-row>-->
     <!--新增护理界面-->
     <el-dialog :title="myTitle" v-model="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false">
       <el-form :model="addForm" label-width="140px" :rules="addFormRules" ref="addForm">
@@ -127,6 +180,11 @@
         pName: null
       }
     },
+    computed: {
+      tableHeight() {
+        return this.mainAreaHeight - 40
+      }
+    },
     methods: {
       gettagList1() {
         this.params.fixedCondition = ' part_id=' + this.partId,
@@ -287,6 +345,13 @@
 </script>
 
 <style scoped>
+  .permission-container {
+    padding: 10px;
+    background-color: #fff;
+  }
+  .el-aside{
+    padding: 8px 10px;
+  }
   .mytable {
     width: 100%;
     padding: 20px;

+ 6 - 6
src/views/ncs-orginazition/components/partUserManager.vue

@@ -29,7 +29,7 @@
         />
 
         <el-table-column prop="id" sortable="custom" label="ID" width="200" align="center" />
-        <el-table-column prop="user_name" sortable="custom" label="登账号" width="300" align="center" />
+        <el-table-column prop="user_name" sortable="custom" label="登账号" width="300" align="center" />
         <el-table-column prop="user_password" sortable="custom" label="密码" width="300" align="center" />
 
         <el-table-column
@@ -67,11 +67,11 @@
       <div>
         <el-form ref="editform" :rules="rules" label-width="120px" :model="formmodel">
 
-          <el-form-item label="登账号" prop="user_name">
-            <el-input v-model="formmodel.user_name" clearable :maxlength="20" placeholder="请输入登账号" />
+          <el-form-item label="登账号" prop="user_name">
+            <el-input v-model="formmodel.user_name" clearable :maxlength="20" placeholder="请输入登账号" />
           </el-form-item>
 
-          <el-form-item label="登密码" prop="user_password">
+          <el-form-item label="登密码" prop="user_password">
             <el-input v-model="formmodel.user_password" clearable :maxlength="20" placeholder="请输入密码" />
           </el-form-item>
 
@@ -114,10 +114,10 @@ export default {
       /** 表单校验 */
       rules: {
         user_name: [
-          { required: true, message: '请输入登账号', trigger: 'blur' }
+          { required: true, message: '请输入登账号', trigger: 'blur' }
         ],
         user_password: [
-          { required: true, message: '请输入登密码', trigger: 'blur' }
+          { required: true, message: '请输入登密码', trigger: 'blur' }
         ]
       },
       /** 列表参数 */

+ 7 - 6
src/views/ncs-task/index.vue

@@ -157,7 +157,7 @@
         },
         computed: {
             tableHeight() {
-                return this.mainAreaHeight - 130
+                return this.mainAreaHeight - 220
             }
         },
         beforeMount() {
@@ -180,17 +180,17 @@
                         content: 'task_content'
                     },
                 },
-                { headerName: '计划任务时间', field: 'task_plan_time', valueFormatter: this.formatterDate, sortable: true, filter: false, width: 170 },
-                { headerName: '实际任务时间', field: 'task_do_time', valueFormatter: this.formatterDate, sortable: true, filter: false, width: 170 },
-                { headerName: '任务状态', field: 'task_success', filter: false, cellRenderer: this.formatterStasus, width: 100 },
+                { headerName: '计划任务时间', field: 'task_plan_time', valueFormatter: this.formatterDate, sortable: true, filter: false, minWidth: 170 },
+                { headerName: '实际任务时间', field: 'task_do_time', valueFormatter: this.formatterDate, sortable: true, filter: false, minWidth: 170 },
+                { headerName: '任务状态', field: 'task_success', filter: false, cellRenderer: this.formatterStasus, minWidth: 100 },
                 // { headerName: '任务结果', field: 'task_result', sortable: true, filter: false, width: 220,
                 //     cellRendererFramework: 'Tooltip',
                 //     cellRendererParams: {
                 //         content: 'task_result'
                 //     },
                 // },
-                { headerName: '任务操作人', field: 'task_do_name', sortable: true, filter: true, width: 120 },
-                { headerName: '创建人', field: 'create_name', valueFormatter: this.formatterName, sortable: true, filter: true, width: 120},
+                { headerName: '任务操作人', field: 'task_do_name', sortable: true, filter: true, minWidth: 120 },
+                { headerName: '创建人', field: 'create_name', valueFormatter: this.formatterName, sortable: true, filter: true, minWidth: 120},
                 { headerName: '操作任务', field: 'id',
                     cellRendererFramework: 'ButtonCellRender',
                     cellRendererParams: param => {
@@ -340,6 +340,7 @@
             getList() {
                 this.loading = true
                 this.gridApi.showLoadingOverlay()
+                this.gridApi.sizeColumnsToFit()
                 API_task.getList(this.params).then(response => {
                     this.loading = false
                     this.tableData = response.data