فهرست منبع

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

wuyunfeng 1 سال پیش
والد
کامیت
308c2ecf28

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
dist/index.html


+ 13 - 2
languages/en.js

@@ -1,3 +1,4 @@
+// 英文语言包
 module.exports = {
   action: {
     wdklCallingSystem: 'System Configuration',
@@ -1035,7 +1036,8 @@ module.exports = {
     boolDooLightAlwaysOn: 'Is the door light always on',
     convenientServiceEnabled: 'Convenient service',
     ledServiceEnabled: 'Server control LED',
-    autoPositionEnabled: 'Enable automatic positioning'
+    autoPositionEnabled: 'Enable automatic positioning',
+    boolDisplayNcTitle: 'Enable nursing title display'
   },
   role: {
     roleName: 'Role name',
@@ -1182,7 +1184,8 @@ module.exports = {
     S433_TRANSFER_BOX: 'Wireless conversion box',
     S433_RECEIVER: 'Signal receiver',
     SLEEPMATTRESS: 'sleep mattress',
-    S4G_INTERCOM: '4G intercom'
+    S4G_INTERCOM: '4G intercom',
+    WATCH_IW: 'Smart Watch - IW'
   },
   vitalSignsDeviceType: {
     BLOOD_SUGAR: 'Blood Pressure Meter',
@@ -1582,5 +1585,13 @@ module.exports = {
     refreshJsonData: 'Refresh JSON data',
     selectHospitalPls: 'Please select a hospital',
     selectRegionPls: 'Please select an administrative region'
+  },
+  wnn20231225: {
+    WATCH_IW: ''
+  },
+  zy20240108: {
+    nurseWatch: 'Nurse watch equipment',
+    customerAgeHidden: 'Extension user age hidden',
+    customerAgeHiddenOnDoor: 'Door machine user age hidden',
   }
 }

+ 63 - 52
languages/es.js

@@ -1,3 +1,4 @@
+// 西班牙语言包
 module.exports = {
   action: {
     wdklCallingSystem: 'Configuración del sistema',
@@ -333,13 +334,13 @@ module.exports = {
     suffix: 'Sufijo de nombre completo',
     suffixExample: 'Cama',
     renamePrefixExample: '2-',
-    namePreview: 'Vista previa del nombre',
+    namePreview: 'Vista previa por  nombre',
     fullNamePreview: 'Vista previa de nombre completo',
-    orderInPart: 'Pedidos parciales',
-    orderInRoom: 'Pedidos en la habitación',
-    renameRule: 'Cambiar las reglas de nombre',
+    orderInPart: 'Ordenes  parciales',
+    orderInRoom: 'Ordenes habitación',
+    renameRule: 'Renombrar reglas',
     roomSuffix: 'Sufijo del nombre de la habitación',
-    updateForAllPart: 'Actualizar todas las piezas',
+    updateForAllPart: 'Actualizar todas las partes',
     skipMsg1: 'introduzca los números, separados por punto y coma',
     skipMsg2: '1,2,3'
   },
@@ -464,27 +465,27 @@ module.exports = {
     inputActIntent: 'Introduzca los parámetros de la actividad'
   },
   deviceMenuDetailManage: {
-    type: 'Tipo',
-    chooseType: 'Por favor, elija el tipo de perfil',
-    user: 'Usuarios',
-    chooseUser: 'No seleccione la pantalla predeterminada para todos los usuarios',
+    type: 'Tipos de',
+    chooseType: 'Por favor, elija el tipo de introducción',
+    user: 'Usuario',
+    chooseUser: 'Deseleccionar y mostrar todos los usuarios por defecto',
     title: 'Título',
     inputTitle: 'Por favor, introduzca el título',
-    titleBg: 'Fondo de la cabeza',
+    titleBg: 'Fondo principal',
     titleIcon: 'Icono del título',
-    summary: 'Introducción',
-    inputSummary: 'Por favor, introduzca el perfil',
+    summary: 'Resumen',
+    inputSummary: 'Por favor, introduzca una breve introducción',
     detail: 'Contenido',
-    tags: 'Etiquetas',
-    inputTags: 'Por favor, introduzca la etiqueta',
+    tags: 'Etiqueta',
+    inputTags: 'Por favor, introduzca una etiqueta',
     hospitalAddr: 'Dirección del Hospital',
     inputHospitalAddr: 'Por favor, introduzca la dirección del hospital.',
     hospitalTel: 'Teléfono del Hospital',
     inputHospitalTel: 'Por favor, ingrese el teléfono del hospital.',
     hospital_web: 'Sitio web del Hospital',
     inputHospitalWeb: 'Por favor, ingrese al sitio web del hospital.',
-    partClerk: 'Miembros importantes relevantes',
-    choosePartClerk: 'Por favor, elija miembros importantes relevantes.'
+    partClerk: 'Familiares relevantes',
+    choosePartClerk: 'Por favor, seleccione familiares relevantes.'
   },
   clerkManage: {
     clerkEdit: 'Editar información del miembro',
@@ -578,12 +579,12 @@ module.exports = {
     feeUnit: 'Unidades',
     feeDescription: 'Descripción',
     feeKeyType: 'Tipo de parámetro',
-    outBed: 'Alta de cama',
+    outBed: 'Alta',
     outBed2: 'Anular registro',
     outBed3: 'Anular registro',
     sureOutBed: '¿Estás seguro de desasignar la cama? ',
     outBedSuccess: '¡Cama desasignada correctamente! ',
-    changeBed: 'Cambio de cama',
+    changeBed: 'Cambio',
     changeBed2: 'Cambiar ubicación',
     changeBed3: 'cambiar',
     ChangeBedSuccess: '',
@@ -912,8 +913,8 @@ module.exports = {
     part: 'Departamento',
     shop: 'Institución',
     organization: 'Organización',
-    partDirector: 'director de departamento',
-    partNurseHead: 'jefe de enfermeras',
+    partDirector: 'Director de Departamento',
+    partNurseHead: 'Jefe de enfermeria',
     shopMemberName: 'Cuenta de administrador',
     shopMemberNameMsg: 'Se debe completar la cuenta de administrador',
     inputShopMemberName: 'introduzca la cuenta de administrador',
@@ -1016,8 +1017,8 @@ module.exports = {
     entraceguard_device: 'Control de acceso APP',
     organizationAdd: 'Nueva Organización',
     boardShowEmptyBed: 'El  panel muestra camas vacías',
-    iotproductid: 'nb Equipment productid',
-    iotproductkey: 'nb device productkey',
+    iotproductid: 'NB ID Dispositivo ',
+    iotproductkey: 'NB  ID de  dispositivo',
     nursingColorRgb: 'Color de la luz de la puerta de enfermería',
     twoColorDoorLightValid: 'Las luces de puerta de dos colores son compatibles o no',
     support: 'Admite luces de puerta de dos colores',
@@ -1035,7 +1036,8 @@ module.exports = {
     boolDooLightAlwaysOn: '¿¿ las luces de la puerta siempre están encendidas?',
     convenientServiceEnabled: 'Servicios convenientes',
     ledServiceEnabled: 'Control del servidor LED',
-    autoPositionEnabled: 'Activar posicionamiento automático'
+    autoPositionEnabled: 'Activar posicionamiento automático',
+    boolDisplayNcTitle: 'Abrir pantalla de títulos de enfermería'
   },
   role: {
     roleName: 'Nombre del rol',
@@ -1182,7 +1184,8 @@ module.exports = {
     S433_TRANSFER_BOX: 'Caja de conversión inalámbrica',
     S433_RECEIVER: 'Receptor de señal',
     SLEEPMATTRESS: 'Colchón para dormir',
-    S4G_INTERCOM: 'Walkie - talkie 4G'
+    S4G_INTERCOM: 'Walkie - talkie 4G',
+    WATCH_IW: 'Reloj inteligente - IW'
   },
   vitalSignsDeviceType: {
     BLOOD_SUGAR: 'Medidor de presión arterial',
@@ -1377,7 +1380,7 @@ module.exports = {
   deviceMenuDetailType: {
     HOSPITAL: 'Introducción al hospital',
     PART: 'Introducción al Departamento',
-    IN_NOTICE: 'Instrucciones para ingresar en el hospital',
+    IN_NOTICE: 'Avisos de ingresos',
     SATISFACTION: 'Encuesta de satisfacción'
   },
   entraceguardUser: {
@@ -1444,11 +1447,11 @@ module.exports = {
   boarderDesign: {
     textDisplayModuleTitle: 'Visualización de contenido',
     textDisplay2ModuleTitle: 'Pantalla personalizada',
-    bedGridCellModuleTitle: 'Celda de cama',
-    bedGridModuleTitle: 'Palacio de camas',
-    rowContainerModuleTitle: 'Contenedor de línea',
-    columnContainerModuleTitle: 'Contenedores de columnas',
-    richTextModuleTitle: 'Texto rico',
+    bedGridCellModuleTitle: 'Titulo de casilla de cama',
+    bedGridModuleTitle: 'Tabla de camas',
+    rowContainerModuleTitle: 'Titulo de filas',
+    columnContainerModuleTitle: 'Titulo de columnas',
+    richTextModuleTitle: 'Texto enriquecido',
     componentsList: 'Lista de componentes',
     loadDefaultDesign: 'Cargar diseño predeterminado',
     saveAsDefaultDesign: 'Guardar como predeterminado',
@@ -1461,23 +1464,23 @@ module.exports = {
     borderRighhWidth: 'Ancho a la derecha',
     borderBottomWidth: 'Ancho inferior',
     borderLeftWidth: 'Ancho izquierdo',
-    borderRadius: 'Radio fronterizo',
+    borderRadius: 'Ancho del borde',
     backgroundColor: 'Color de fondo',
     moduleHeight: 'Altura del módulo',
     showShadow: 'Sombra del módulo',
     shadowColor: 'Color de la sombra',
     fixedToBottom: 'Fondo fijo',
-    showWhenPatientIn: 'Mostrar no vacío',
-    moduleMarginLeft: 'Distancia izquierda del módulo',
+    showWhenPatientIn: 'Mostrar no vacios',
+    moduleMarginLeft: 'Margen izquierdo del módulo',
     moduleMarginRight: 'Margen derecho del módulo',
     moduleMarginTop: 'Margen superior del módulo',
-    moduleMarginBottom: 'Color del borde seguido',
-    borderColorSameWith: 'Цвет границы',
-    backgroundColorSameWith: 'Color de fondo seguido',
+    moduleMarginBottom: 'Color del borde inferior',
+    borderColorSameWith: 'Color del borde',
+    backgroundColorSameWith: 'Color de fondo',
     columnOccupyWidth: 'Ocupación de columnas(1-24)',
     columnOffsetLeft: 'Desplazamiento a la izquierda de la columna',
-    columnPullRight: 'La columna se tira a la derecha',
-    columnPullLeft: 'La columna se tira a la izquierda',
+    columnPullRight: 'La columna se desplaza a la derecha',
+    columnPullLeft: 'La columna se desplaza a la izquierda',
     gridRows: 'Número de líneas de la tabla',
     columnsPerRow: 'Número de columnas por línea',
     contentAlign: 'Alineación de contenidos',
@@ -1488,29 +1491,29 @@ module.exports = {
     iconSelect: 'Seleccionar icono',
     iconSize: 'Tamaño del icono',
     iconColor: 'Color del icono',
-    iconMarginLeft: 'Distancia izquierda del icono',
+    iconMarginLeft: 'Margen izquierdo del icono',
     iconMarginRight: 'Margen derecho del icono',
     iconMarginTop: 'Margen superior del icono',
     iconMarginBottom: 'Margen inferior del icono',
-    titleText: 'Texto del título',
+    titleText: 'Texto de la cabecera',
     contentText: 'Texto del contenido',
     fieldDisplay: 'Mostrar Campos',
     displayFormat: 'Formato de visualización',
     textFormat: 'Formato de texto',
     dateFormat: 'Formato de fecha',
     currentDayColor: 'Color de la fecha actual',
-    currentDayBackgroundColor: 'Antecedentes de la fecha actual',
-    formatPattern: 'Patrón formateado',
+    currentDayBackgroundColor: 'Fondo de la fecha actual',
+    formatPattern: 'Patrón formateo',
     titleTextSize: 'Tamaño del texto del título',
     titleTextMarginLeft: 'Margen izquierdo del título',
     titleTextMarginRight: 'Margen derecho del título',
     titleTextPaddingLeft: 'El título se rellena a la izquierda',
     titleTextPaddingRight: 'El título se rellena a la derecha',
-    titleTextWidth: 'Ancho de la cabeza',
+    titleTextWidth: 'Ancho del título',
     titleTextColor: 'Color del título',
-    titleTextColorSameWith: 'Los colores del título son los siguientes',
+    titleTextColorSameWith: 'Los colores del título ',
     titleBorderRightWidth: 'Ancho del borde derecho del título',
-    titleBorderBottomWidth: 'Ширина границы под заголовком',
+    titleBorderBottomWidth: 'Ancho del borde inferior',
     titleBorderColor: 'Color del Encabezado',
     titleTextAlign: 'Alineación del texto del título',
     titleTextMargin: 'Margen del título',
@@ -1518,18 +1521,18 @@ module.exports = {
     titleTextStyle: 'Estilo de texto del título',
     contentTextSize: 'Tamaño del texto del contenido',
     contentTextMarginLeft: 'Margen de contenido izquierdo',
-    contentTextMarginRight: 'Permisos de margen de contenido',
+    contentTextMarginRight: 'Margen de contenido derecho',
     contentTextColor: 'Color del texto del contenido',
-    contentTextColorSameWith: 'Seguimiento del color del contenido',
+    contentTextColorSameWith: 'Color del contenido',
     contentTextStyle: 'Estilo de texto de contenido',
-    normalStyle: 'Estilo ordinario',
+    normalStyle: 'Estilo normal',
     boldStyle: 'Estilo en negrita',
     alignLeft: 'Alinear a la izquierda',
     alignCenter: 'Alinear en el Centro',
     alignRight: 'Alinear a la derecha',
     customerDisplay: 'Pantalla personalizada',
-    manulInputDisplay: 'Entrada manual para mostrar',
-    partInfo: 'Información sectorial',
+    manulInputDisplay: 'Entrada manual en pantalla',
+    partInfo: 'Información del departamento',
     partName: 'Nombre del Departamento',
     patientInfo: 'Información del paciente',
     bedNo: 'Número de cama',
@@ -1560,8 +1563,8 @@ module.exports = {
     nurseIcon4: 'Icono de la enfermera4',
     nursingInfo: 'Información de enfermería',
     statisticInfo: 'Estadísticas',
-    patientSexMale: 'Hombre',
-    patientSexFemale: 'Mujer',
+    patientSexMale: 'Masculino',
+    patientSexFemale: 'Femenino',
     patientSexUnkonw: 'Desconocido',
     contentTextDefault: 'Contenido del texto',
     titleTextDefault: 'Título predeterminado',
@@ -1582,5 +1585,13 @@ module.exports = {
     refreshJsonData: 'Actualizar los datos de json',
     selectHospitalPls: 'Por favor, elija el hospital',
     selectRegionPls: 'Por favor, elija el área administrativa'
+  },
+  wnn20231225: {
+    WATCH_IW: ''
+  },
+  zy20240108: {
+    nurseWatch: 'Reloj de enfermera',
+    customerAgeHidden: 'Se oculta la edad de los usuarios de la extensión',
+    customerAgeHiddenOnDoor: 'La edad del usuario de la máquina de puerta está oculta',
   }
 }

+ 13 - 2
languages/ru-RU.js

@@ -1,3 +1,4 @@
+// 俄国语言包
 module.exports = {
   action: {
     wdklCallingSystem: 'Система палтной сигнализации',
@@ -1035,7 +1036,8 @@ module.exports = {
     boolDooLightAlwaysOn: 'Светит ли дверь постоянно',
     convenientServiceEnabled: 'Удобное обслуживание',
     ledServiceEnabled: 'Управление сервером LED',
-    autoPositionEnabled: 'Включить автоматическое позиционирование'
+    autoPositionEnabled: 'Включить автоматическое позиционирование',
+    boolDisplayNcTitle: 'Открыть заголовок Уход Показать'
   },
   role: {
     roleName: 'Имя роли',
@@ -1182,7 +1184,8 @@ module.exports = {
     S433_TRANSFER_BOX: '433 Беспроводная коробка',
     S433_RECEIVER: '433 Приемник',
     SLEEPMATTRESS: 'Матрас для сна',
-    S4G_INTERCOM: 'Диалог 4G'
+    S4G_INTERCOM: 'Диалог 4G',
+    WATCH_IW: 'Умные часы - IW'
   },
   vitalSignsDeviceType: {
     BLOOD_SUGAR: 'Измеритель сахара в крови',
@@ -1582,5 +1585,13 @@ module.exports = {
     refreshJsonData: 'Обновить данные JSON',
     selectHospitalPls: 'Пожалуйста, выберите больницу.',
     selectRegionPls: 'Выберите административный район'
+  },
+  wnn20231225: {
+    WATCH_IW: ''
+  },
+  zy20240108: {
+    nurseWatch: 'Часы медсестры',
+    customerAgeHidden: 'Скрыть возраст пользователя ',
+    customerAgeHiddenOnDoor: 'Скрыть возраст пользователя',
   }
 }

+ 13 - 3
languages/zh-CN.js

@@ -1,3 +1,4 @@
+// 中文语言包
 module.exports = {
   action: {
     wdklCallingSystem: '呼叫系统配置中心',
@@ -1035,7 +1036,8 @@ module.exports = {
     boolDooLightAlwaysOn: '门灯是否常亮',
     convenientServiceEnabled: '便民服务',
     ledServiceEnabled: '服务端控制点阵屏',
-    autoPositionEnabled: '开启自动定位'
+    autoPositionEnabled: '开启自动定位',
+    boolDisplayNcTitle: '开启护理标题显示'
   },
   role: {
     roleName: '角色名称',
@@ -1182,7 +1184,8 @@ module.exports = {
     S433_TRANSFER_BOX: '433无线转换盒',
     S433_RECEIVER: '433接收器',
     SLEEPMATTRESS: '睡眠床垫',
-    S4G_INTERCOM: '4G对讲器'
+    S4G_INTERCOM: '4G对讲器',
+    WATCH_IW: '智能手表-IW'
   },
   vitalSignsDeviceType: {
     BLOOD_SUGAR: '血糖仪',
@@ -1582,6 +1585,13 @@ module.exports = {
     refreshJsonData: '刷新JSON数据',
     selectHospitalPls: '请选择医院',
     selectRegionPls: '请选择行政区域'
+  },
+  wnn20231225: {
+    WATCH_IW: ''
+  },
+  zy20240108: {
+    nurseWatch: '护士腕表',
+    customerAgeHidden: '分机用户年龄隐藏',
+    customerAgeHiddenOnDoor: '门口机用户年龄隐藏',
   }
-
 }

+ 8 - 0
src/api/initialize.js

@@ -54,3 +54,11 @@ export function synchroDevice(unionId, shopId) {
     method: 'GET'
   })
 }
+
+export function getLocationList(params) {
+  return request({
+    url: OnlineSystemUrl + `/base/member_location/list`,
+    method: 'POST',
+    params
+  })
+}

+ 36 - 0
src/api/member_location.js

@@ -0,0 +1,36 @@
+import request from '@/utils/request'
+const onlineSystemUrl = domain.OnlineSystemUrl
+/** 获取实时位置 */
+export function getLocation(imei) {
+  return request({
+    url: `/system/member_location/get_location/${imei}`,
+    method: 'GET',
+    loading: true
+  })
+}
+
+/** 获取安全围栏 */
+export function getMemberSecurityFence(params) {
+  return request({
+    url: onlineSystemUrl + `/base/member_location/get_member_security_fence`,
+    method: 'POST',
+    params
+  })
+}
+
+/** 保存安全围栏 */
+export function saveMemberSecurityFence(params) {
+  return request({
+    url: onlineSystemUrl + `/base/member_location/save_member_security_fence`,
+    method: 'POST',
+    params
+  })
+}
+
+/** 删除安全围栏 */
+export function delMemberSecurityFence(id) {
+  return request({
+    url: onlineSystemUrl + `/base/member_location/del_member_security_fence/${id}`,
+    method: 'DELETE'
+  })
+}

+ 8 - 1
src/api/ncs_device.js

@@ -284,5 +284,12 @@ export function getLocationDeviceList(partid) {
     loading: false
   })
 }
-
+/** 查询定位设备 */
+export function getDeviceList(frameId, type) {
+  return request({
+    url: `/ncs/device/getDeviceList/${frameId}/${type}`,
+    method: 'get',
+    loading: false
+  })
+}
 

BIN
src/icons/images/walk.png


+ 2 - 0
src/router/index.js

@@ -271,6 +271,7 @@ export const partRoutes = [
     component: Layout,
     name: 'remark',
     redirect: '/remark/list',
+    meta: { title: i18n.t('tab.remarkManage'), icon: 'el-icon-s-order', noCache: true },
     children: [
       {
         path: 'list',
@@ -286,6 +287,7 @@ export const partRoutes = [
     component: Layout,
     name: 'task',
     redirect: '/task/list',
+    meta: { title: i18n.t('tab.taskManage'), icon: 'table', noCache: true },
     children: [
       {
         path: 'list',

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 10 - 10
src/utils/domain.js


+ 2 - 1
src/utils/enum/DeviceTypeEnum.js

@@ -46,6 +46,7 @@ export const DEVICE_TYPE = createEnum(
     S433_TRANSFER_BOX: [41, i18n.t('deviceType.S433_TRANSFER_BOX')], //433无线转换盒
     S433_RECEIVER: [42, i18n.t('deviceType.S433_RECEIVER')], //433接收器
     SLEEPMATTRESS: [43, i18n.t('deviceType.SLEEPMATTRESS')], //睡眠床垫
-    S4GINTERCOM: [44, i18n.t('deviceType.S4G_INTERCOM')] //4G对讲器
+    S4GINTERCOM: [44, i18n.t('deviceType.S4G_INTERCOM')], //4G对讲器
+    WATCH_IW: [46, i18n.t('deviceType.WATCH_IW')] //智能手表-埃微
   }
 )

+ 4 - 9
src/views/customer/components/customerManager.vue

@@ -409,8 +409,8 @@
             </div>
           </div>
         </el-tab-pane>
-        <el-tab-pane v-if="formmodel.id && boolDevice" :label="this.$t('customerManage.footprint')" name="footprint">
-          <my-map-html :map-url="mapUrl" style="width: 100%; height: 670px;"></my-map-html>
+        <el-tab-pane v-if="formmodel.id" :label="this.$t('customerManage.footprint')" name="footprint">
+<!--          <my-map-html :map-url="mapUrl" style="width: 100%; height: 670px;"></my-map-html>-->
         </el-tab-pane>
 
         <el-tab-pane v-if="formmodel.id" :label="this.$t('customerManage.fee')" name="customer-fee-sign">
@@ -732,7 +732,6 @@ export default {
       childbirthTypeEnum: CHILDBIRTH_TYPE.getValueList(),
       isChild: false,
       shop: {},
-      boolDevice: false,
       mapUrl: null
     }
   },
@@ -1139,7 +1138,7 @@ export default {
     },
     handleClick() {
       if (this.activeName === 'footprint') {
-        this.$router.push({path:'/device/map', query: {mapUrl: this.mapUrl}})
+        this.$router.push({path:'/device/map', query: {mapUrl: this.mapUrl, uuid: this.formmodel.uuid, frameId: this.formmodel.frame_id}})
       }
     },
     /** 生日选择变化,修改年龄字段 */
@@ -1293,7 +1292,6 @@ export default {
     },
 
     handleEdit(row) {
-      this.boolDevice = false
       this.relativeRules.mobile[0].required = this.isCloud
       this.formmodel = {
         ...row
@@ -1322,10 +1320,7 @@ export default {
       // 获取该用户的胸牌/手环
       const _this = this
       getWatchFootprint(row.member_id,  DEVICE_TYPE.BREASTPLATE).then(res => {
-        if (res) {
-          _this.boolDevice = true
-          _this.mapUrl = res
-        }
+        _this.mapUrl = res
       })
 
     },

+ 4 - 9
src/views/customer/components/elderlyCareManager.vue

@@ -414,8 +414,8 @@
                     </div>
                 </el-tab-pane>
 
-              <el-tab-pane v-if="formmodel.id && boolDevice" :label="this.$t('customerManage.footprint')" name="footprint">
-                <my-map-html :map-url="mapUrl" style="width: 100%; height: 670px;"></my-map-html>
+              <el-tab-pane v-if="formmodel.id" :label="this.$t('customerManage.footprint')" name="footprint">
+<!--                <my-map-html :map-url="mapUrl" style="width: 100%; height: 670px;"></my-map-html>-->
               </el-tab-pane>
                 <el-tab-pane  :label="this.$t('sleepData.SleepData')" name="sleepData">
                     <sleep-detect-data :member-id="formmodel.member_id"></sleep-detect-data>
@@ -678,7 +678,6 @@
                 deleted: this.$t('action.delete'),
               locationShow: false,
               isCloud: false,
-              boolDevice: false,
               mapUrl: null,
               relativeNameTypeEnum: RELATIVE_NAME_TYPE.getValueList(),
               isChild: false,
@@ -1086,7 +1085,7 @@
             },
             handleClick() {
               if (this.activeName === 'footprint') {
-                this.$router.push({path:'/device/map', query: {mapUrl: this.mapUrl}})
+                this.$router.push({path:'/device/map', query: {mapUrl: this.mapUrl, uuid: this.formmodel.uuid, frameId: this.formmodel.frame_id}})
               }
             },
             /** 生日选择变化,修改年龄字段 */
@@ -1249,7 +1248,6 @@
 
             handleEdit(row) {
                 this.activeName = 'customerBaseInfo'
-                this.boolDevice = false
                 this.relativeRules.mobile[0].required = this.isCloud
                 this.formmodel = {
                     ...row
@@ -1278,16 +1276,13 @@
                     this.$set(this.formmodel, 'birthday', this.formmodel.birthday * 1000)
                 }
                 this.customerFormVisible = true
-                this.handNusreColor()
+                // this.handNusreColor()
                 this.getRemarks()
                 this.getRelatives()
                 // 获取该用户的胸牌/手环
                 const _this = this
                 getWatchFootprint(row.member_id, DEVICE_TYPE.BREASTPLATE).then(res => {
-                  if (res) {
-                    _this.boolDevice = true
                     _this.mapUrl = res
-                  }
                 })
             },
             /** 出院 退床 **/

+ 4 - 9
src/views/customer/components/patientManager.vue

@@ -432,8 +432,8 @@
                     </div>
                 </el-tab-pane>
 
-              <el-tab-pane v-if="formmodel.id && boolDevice" :label="this.$t('customerManage.footprint')" name="footprint">
-                <my-map-html :map-url="mapUrl" style="width: 100%; height: 670px;"></my-map-html>
+              <el-tab-pane v-if="formmodel.id" :label="this.$t('customerManage.footprint')" name="footprint">
+<!--                <my-map-html :map-url="mapUrl" style="width: 100%; height: 670px;"></my-map-html>-->
               </el-tab-pane>
 
               <el-tab-pane v-if="formmodel.id" :label="this.$t('customerManage.fee')" name="customer-fee">
@@ -712,7 +712,6 @@
                 colour: this.$t('action.colour'),
                 deleted: this.$t('action.delete'),
                 qrCode: null,
-                boolDevice: false,
                 mapUrl: null,
               relativeNameTypeEnum: RELATIVE_NAME_TYPE.getValueList(),
               isChild: false,
@@ -1162,7 +1161,7 @@
           },
             handleClick() {
               if (this.activeName === 'footprint') {
-                this.$router.push({path:'/device/map', query: {mapUrl: this.mapUrl}})
+                this.$router.push({path:'/device/map', query: {mapUrl: this.mapUrl, uuid: this.formmodel.uuid, frameId: this.formmodel.frame_id}})
               }
             },
             /** 生日选择变化,修改年龄字段 */
@@ -1331,7 +1330,6 @@
             },
 
             handleEdit(row) {
-                this.boolDevice = false
                 this.relativeRules.mobile[0].required = this.isCloud
                 this.formmodel = {
                     ...row
@@ -1367,10 +1365,7 @@
                 // 获取该用户的胸牌/手环
                 const _this = this
                 getWatchFootprint(row.member_id, DEVICE_TYPE.BREASTPLATE).then(res => {
-                  if (res) {
-                    _this.boolDevice = true
-                    _this.mapUrl = res
-                  }
+                  _this.mapUrl = res
                 })
             },
             /** 出院 退床 **/

+ 384 - 10
src/views/customer/myMapHtml.vue

@@ -1,31 +1,405 @@
 <template>
   <div style="width: 100%; height: 800px">
-    <iframe v-bind:src="mapUrl" frameborder="0" style="width: 100%; height: 100%"></iframe>
+    <div v-if="mapUrl">
+      <iframe v-bind:src="mapUrl" frameborder="0" style="width: 100%; height: 100%"></iframe>
+    </div>
+
+    <div v-else>
+      <baidu-map v-if="isShow" style="height: 800px" :center="center" :zoom="zoom" scroll-wheel-zoom @ready="handler" @click="clickMap">
+        <bm-control>
+          <div style="margin: 20px">
+            <el-tooltip class="item" effect="dark" :content="$t('tcpType.LOCATION')" placement="right-start">
+              <el-button type="success" icon="el-icon-location-outline" :disabled="disable" circle plain @click="changeType(0)"></el-button>
+            </el-tooltip>
+            <el-tooltip class="item" effect="dark" content="刷新" placement="right-start">
+              <el-button type="primary" icon="el-icon-refresh-left" :disabled="disable" circle plain @click="changeType(1)"></el-button>
+            </el-tooltip>
+            <el-tooltip class="item" effect="dark" :content="$t('customerManage.footprint')" placement="right-start">
+              <el-button type="warning" icon="el-icon-rank" circle plain @click="changeType(-1)"></el-button>
+            </el-tooltip>
+            <el-tooltip class="item" effect="dark" content="安全围栏" placement="right-start">
+              <el-button type="danger" icon="el-icon-s-help" circle plain @click="changeType(2)"></el-button>
+            </el-tooltip>
+          </div>
+        </bm-control>
+<!--        <bm-control>-->
+<!--          <div style="margin: 20px">-->
+<!--            <button @click="addZoom(19)">缩放至最大</button>-->
+<!--            <button @click="addZoom(10)">还原</button>-->
+<!--            <button @click="addZoom(3)">缩放至最小</button>-->
+<!--          </div>-->
+<!--        </bm-control>-->
+
+        <div v-if="type === -1">
+          <!-- 轨迹 -->
+          <!-- 添加起点标记 -->
+          <bm-marker v-if="dataList.length > 1" :position="endPoint" @mouseover="clickMap">
+            <bm-label content="终点" :offset="{width: 0, height: 30}"/>
+            <bm-info-window v-if="myContent" :show="true" @close="infoWindowClose">
+              <p>{{ unixDateFormatter(dataList[dataList.length - 1].position_time) }}</p>
+              <p style="color: #4abe84">{{ myContent }}</p>
+            </bm-info-window></bm-marker>
+          <!-- 添加终点标记 -->
+          <bm-marker :position="markers[0]">
+            <bm-label content="起点" :offset="{width: 0, height: 30}"/>
+          </bm-marker>
+          <!-- 折线 -->
+          <bm-polyline :path="markers" stroke-color="#4aa4f3" :stroke-opacity="1" :stroke-weight="6" stroke-style="dashed"
+                       @lineupdate="updatePolylinePath" />
+          <!--      <bm-polyline :path="markers" stroke-color="red" :stroke-opacity="0.5" :stroke-weight="2"></bm-polyline>-->
+          <bml-lushu @stop="reset" :path="markers" :icon="icon" :play="play" :autoView="true" :speed="700"></bml-lushu>
+          <!-- 轨迹 -->
+        </div>
+        <div v-else-if="type === 2">
+          <!-- 圆形围栏 -->
+          <bm-circle v-if="boolCircle" :center="circleCenter" :radius="securityFence.radius" stroke-color="red" :stroke-opacity="0.5" :stroke-weight="2" @lineupdate="updateCirclePath" :editing="editing"></bm-circle>
+          <bm-marker v-if="boolCircle" :position="circleCenter">
+            <bm-info-window :show="true">
+              <p>{{ securityFence.address }}</p>
+              <div style="color: #4abe84">半径:{{ securityFence.radius }} 米
+                <el-button type="primary" icon="el-icon-edit" size="mini" plain @click="API_SaveFence">保存</el-button>
+                <el-button v-if="securityFence.id" type="danger" icon="el-icon-delete" size="mini" plain @click="API_DelFence">删除</el-button>
+              </div>
+
+            </bm-info-window>
+          </bm-marker>
+          <!-- 圆形围栏 -->
+        </div>
+        <div v-else>
+          <bm-marker :position="markers[0]" animation="BMAP_ANIMATION_BOUNCE" @mouseover="mouseoverMap">
+            <bm-info-window v-if="myContent" :show="true" @close="infoWindowClose">
+              <p>{{ unixDateFormatter(dataList[0].position_time) }}</p>
+              <p style="color: #4abe84">{{ myContent }}</p>
+            </bm-info-window>
+          </bm-marker>
+        </div>
+
+      </baidu-map>
+    </div>
   </div>
 </template>
 
 <script>
+import walkImg from '@/icons/images/walk.png'
+import { BmlLushu } from 'vue-baidu-map'
+import { getLocationList } from '@/api/initialize'
+import { unix2Date } from '@/utils/Foundation'
+import * as API_MemberLocation from '@/api/member_location'
+import { getDeviceList } from '@/api/ncs_device'
+import { DEVICE_TYPE } from '@/utils/enum/DeviceTypeEnum'
+
 export default {
   name: "myMapHtml",
-  // props: {
-  //   mapUrl: {
-  //     type: String,
-  //     default: ''
-  //   }
-  // },
+  components: {
+    BmlLushu
+  },
   data() {
     return {
-      mapUrl: null
+      mapUrl: null,
+      uuid: null,
+      frameId: null,
+      center: '北京',
+      zoom: 16,
+      isShow: false,
+      markers: [],
+      play: false, //是否行进
+      icon: { // 覆盖物的图标
+        url: walkImg,
+        size: { width: 220, height: 220 },
+        opts: { anchor: { width: 0, height: 113 } }
+      },
+      boolCircle: false,
+      type: 1,
+      myContent: '',
+      params: {
+        page_size: 1,
+        page_no: 1,
+        sort: 'position_time',
+        dir: 'desc',
+      },
+      dataList:[],
+      disable: false,
+      deviceList: [],
+      circleCenter: {
+        lng: 113.971151,
+        lat: 22.570388
+      },
+      securityFence: {
+        radius: 200
+      },
+      editing: false
     }
   },
   created() {
   },
+  computed: {
+    //终点计算
+    endPoint() {
+      if (this.markers && this.markers.length > 0) {
+        return this.markers[this.markers.length - 1]
+      }
+      return null;
+    }
+  },
   mounted() {
     this.mapUrl = this.$route.query.mapUrl
+    if (!this.mapUrl) {
+      this.uuid = this.$route.query.uuid
+      this.frameId = this.$route.query.frameId
+      this.params.fixedCondition = " member_union_id = '" + this.uuid + "'"
+      this.handleMapData()
+      this.API_GetDeviceList()
+    }
+  },
+  methods: {
+    //处理数据
+    handleMapData() {
+      let markers = []
+      this.myContent = null
+      getLocationList(this.params).then(res => {
+        this.disable = false
+        this.dataList = res.data
+        this.dataList.sort(function (a, b) {
+          return a.position_time - b.position_time
+        })
+        if (res.data.length > 0) {
+          this.dataList.forEach(item => {
+            markers.push({lng: item.longitude, lat: item.latitude})
+          })
+          this.markers = markers
+          this.center = this.markers[0]
+        }
+        this.play = true
+        this.isShow = true
+      })
+    },
+    handler ({BMap, map}) {
+      if (this.markers.length > 0 && this.type !== 2) {
+        let view = map.getViewport(eval(this.markers))
+        this.zoom = view.zoom
+        console.log('zoom===', this.zoom)
+      }
+    },
+    async API_GetDeviceList() {
+      getDeviceList(this.frameId, DEVICE_TYPE.WATCH_IW).then(res => {
+        this.deviceList = res
+      })
+    },
+    // 停止本次移动
+    reset() {
+      this.play = false
+    },
+    // 覆盖物的属性发生变化时触发
+    updatePolylinePath(e) {
+      this.markers = e.target.getPath()
+    },
+    updateCirclePath (e) {
+      this.circleCenter = e.target.getCenter()
+      this.securityFence.radius = Math.ceil(e.target.getRadius())
+      console.log('修改围栏参数:', this.circleCenter, this.securityFence.radius)
+    },
+    mouseoverMap(e) {
+      if (this.myContent) {
+        return
+      }
+      const geoCoder = new BMap.Geocoder()
+      // 利用坐标获取地址的详细信息
+      geoCoder.getLocation(e.point, (res) => {
+        console.log(res)
+        if (res.surroundingPois[0]) {
+          this.myContent = res.surroundingPois[0].title + '附近'
+        } else {
+          this.myContent = res.address + '附近'
+        }
+        console.log('地址为' + this.myContent)
+      })
+    },
+    clickMap(e) {
+      console.log(e.point)
+      if (this.type !== 2) {
+        return
+      }
+      this.circleCenter = e.point
+      this.boolCircle = false
+      this.getAddress(e.point)
+    },
+    getAddress(point) {
+      const geoCoder = new BMap.Geocoder()
+      // 利用坐标获取地址的详细信息
+      geoCoder.getLocation(point, (res) => {
+        console.log(res)
+        if (res.surroundingPois[0]) {
+          this.securityFence.address = res.surroundingPois[0].title + '附近'
+        } else {
+          this.securityFence.address = res.address + '附近'
+        }
+        this.boolCircle = true
+        console.log('circleContent地址为' + this.securityFence.address)
+      })
+      const _this = this
+      if (!this.editing) {
+        setTimeout(() => {
+          _this.editing = true
+        }, 1000)
+      }
+
+    },
+    changeType(type) {
+      switch (type) {
+        case 0:
+          this.type = 0
+          if (this.deviceList.length === 0) {
+            this.$message({
+              message: '没有定位设备',
+              type: 'info'
+            })
+            return
+          }
+          this.disable = true
+          this.API_GetLocation()
+          break
+        case 1:
+          this.type = 1
+          this.disable = true
+          this.params.page_size = 1
+          this.isShow = false
+          this.handleMapData()
+          break
+        case 2:
+          if (this.deviceList.length === 0) {
+            this.$message({
+              message: '没有定位设备',
+              type: 'info'
+            })
+            return
+          }
+          this.type = 2
+          this.boolCircle = true
+          this.API_GetFenceList()
+          break
+        default:
+          this.type = -1
+          this.params.page_size = 20
+          this.isShow = false
+          this.handleMapData()
+          break
+      }
+    },
+    infoWindowClose() {
+      this.myContent = null
+      this.circleCenter = null
+    },
+    /** 格式化时间函数 */
+    unixDateFormatter(time) {
+      return unix2Date(time * 1000)
+    },
+    API_GetLocation() {
+      API_MemberLocation.getLocation(this.deviceList[0].eth_mac).then(res => {
+        if (res.success) {
+          const data = JSON.parse(res.data)
+          if (data.Data.Code === 'iot.messagebroker.OFFLINE') {
+            this.$message({
+              message: '设备离线,操作失败',
+              type: 'info'
+            })
+            this.disable = false
+            return
+          }
+          this.$message({
+            message: '正在定位,请稍后',
+            type: 'info'
+          })
+          const _this = this
+          setTimeout(() => {
+            _this.params.page_size = 1
+            _this.isShow = false
+            _this.handleMapData()
+            _this.disable = false
+          }, 15000)
+        } else {
+          this.$message.error(this.$t('action.handleFailed'))
+          this.disable = false
+        }
+      }).catch(err => {
+        console.log('定位异常...', err)
+        this.disable = false
+      })
+    },
+    API_GetFenceList() {
+      const data = {
+        unionId: this.uuid,
+        imei: this.deviceList[0].eth_mac,
+        type: 0
+      }
+      const _this = this
+      API_MemberLocation.getMemberSecurityFence(data).then(res => {
+        if (res.length > 0) {
+          _this.securityFence = res[0]
+          _this.circleCenter = { lng: _this.securityFence.longitude, lat: _this.securityFence.latitude }
+          _this.center = this.circleCenter
+          _this.boolCircle = true
+        } else {
+          _this.securityFence = {
+            radius: 200,
+            imei: _this.deviceList[0].eth_mac,
+            member_union_id: _this.uuid,
+            type: 0,
+            address: ''
+          }
+          if (_this.center) {
+            _this.circleCenter = _this.center
+          }
+        }
+        console.log('this.boolCircle==', _this.boolCircle, _this.circleCenter)
+      }).catch(err => {
+        console.log('获取围栏异常...', err)
+      })
+    },
+    API_SaveFence() {
+      if (this.securityFence.radius < 200) {
+        this.$message({
+          message: '围栏半径不能小于200',
+          type: 'info'
+        })
+        return
+      }
+      if (this.securityFence.radius > 2000) {
+        this.$message({
+          message: '围栏半径不能超过2000米',
+          type: 'info'
+        })
+        return
+      }
+      this.securityFence.longitude = this.circleCenter.lng
+      this.securityFence.latitude = this.circleCenter.lat
+      API_MemberLocation.saveMemberSecurityFence(this.securityFence).then(res => {
+        this.$message.success(this.$t('action.handleSuccess'))
+      }).catch(err => {
+        console.log('设置围栏异常...', err)
+      })
+    },
+    API_DelFence() {
+      this.$confirm(this.$t('action.sureDelete'), this.$t('action.waring'), {
+        confirmButtonText: this.$t('action.yes'),
+        cancelButtonText: this.$t('action.cancel'),
+        type: 'warning'
+      }).then(() => {
+        API_MemberLocation.delMemberSecurityFence(this.securityFence.id).then(res => {
+          this.$message.success(this.$t('action.handleSuccess'))
+          this.API_GetFenceList()
+        }).catch(err => {
+          console.log('删除围栏异常...', err)
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: this.$t('action.cancelDelete')
+        })
+      })
+    },
   }
 }
 </script>
 
 <style scoped>
-
-</style>
+</style>

+ 3 - 3
src/views/hospitalFrame/frameTreeView.vue

@@ -119,7 +119,7 @@
           <el-col :span="24">
             <!--医院结构名称-->
             <el-form-item :label="this.$t('action.name')" prop="name">
-              <el-input v-model="frameInfo.name" :maxlength="20" @change="frameChange">
+              <el-input v-model="frameInfo.name" :maxlength="50" @change="frameChange">
                 <template slot="append">{{ frameInfo.type === 4? this.$t('frameManage.room') : this.$t('frameManage.bed') }}</template>
               </el-input>
             </el-form-item>
@@ -129,7 +129,7 @@
           <el-col :span="24">
             <!--医院结构别名-->
             <el-form-item :label="this.$t('action.alias')" prop="alias">
-              <el-input v-model="frameInfo.alias" :maxlength="20" />
+              <el-input v-model="frameInfo.alias" :maxlength="50" />
             </el-form-item>
           </el-col>
         </el-row>
@@ -137,7 +137,7 @@
           <el-col :span="24">
             <!--医院结构别名-->
             <el-form-item :label="this.$t('action.fullName')" prop="full_name">
-              <el-input v-model="frameInfo.full_name" :maxlength="20" />
+              <el-input v-model="frameInfo.full_name" :maxlength="50" />
             </el-form-item>
           </el-col>
         </el-row>

+ 1 - 1
src/views/ncs-menu/menuManager.vue

@@ -49,7 +49,7 @@
     >
       <el-form ref="menuForm" :model="menuForm" :rules="menuRules" label-width="100px">
         <el-form-item :label="this.$t('menu.title')" prop="title">
-          <el-input v-model="menuForm.title" :maxlength="20" />
+          <el-input v-model="menuForm.title" :maxlength="50" />
         </el-form-item>
         <el-form-item :label="this.$t('menu.identifier')" prop="identifier">
           <el-input v-model="menuForm.identifier" :maxlength="50" />

+ 24 - 2
src/views/ncs-orginazition/components/partInfoEdit.vue

@@ -419,7 +419,9 @@
                 <el-checkbox v-model="formmodel.record_enabled" :true-label="1" :false-label="0">{{ this.$t('partInfo.recordAble') }}</el-checkbox>
               </el-form-item>
             </el-col>
+          </el-row>
 
+          <el-row>
             <el-col :span="8">
               <el-form-item :label="this.$t('partInfo.customerNameHidden')" prop="customer_name_hidden">
                 <el-checkbox v-model="formmodel.customer_name_hidden" :true-label="1" :false-label="0">{{ this.$t('partInfo.hidden') }}</el-checkbox>
@@ -427,23 +429,37 @@
             </el-col>
 
             <el-col :span="8">
+              <el-form-item :label="this.$t('zy20240108.customerAgeHidden')" prop="customer_age_hidden">
+                <el-checkbox v-model="formmodel.customer_age_hidden" :true-label="1" :false-label="0">{{ this.$t('partInfo.hidden') }}</el-checkbox>
+              </el-form-item>
+            </el-col>
+
+            <el-col :span="8">
               <el-form-item :label="this.$t('partInfo.clerkNameHidden')" prop="clerk_name_hidden">
                 <el-checkbox v-model="formmodel.clerk_name_hidden" :true-label="1" :false-label="0">{{ this.$t('partInfo.hidden') }}</el-checkbox>
               </el-form-item>
             </el-col>
 
             <el-col :span="8">
-              <el-form-item :label="this.$t('partInfo.customerNameHiddenOnDoor')" prop="customer_name_hidden">
+              <el-form-item :label="this.$t('partInfo.customerNameHiddenOnDoor')" prop="customer_name_hidden_on_door">
                 <el-checkbox v-model="formmodel.customer_name_hidden_on_door" :true-label="1" :false-label="0">{{ this.$t('partInfo.hidden') }}</el-checkbox>
               </el-form-item>
             </el-col>
 
             <el-col :span="8">
-              <el-form-item :label="this.$t('partInfo.clerkNameHiddenOnDoor')" prop="clerk_name_hidden">
+              <el-form-item :label="this.$t('zy20240108.customerAgeHiddenOnDoor')" prop="customer_age_hidden_on_door">
+                <el-checkbox v-model="formmodel.customer_age_hidden_on_door" :true-label="1" :false-label="0">{{ this.$t('partInfo.hidden') }}</el-checkbox>
+              </el-form-item>
+            </el-col>
+
+            <el-col :span="8">
+              <el-form-item :label="this.$t('partInfo.clerkNameHiddenOnDoor')" prop="clerk_name_hidden_on_door">
                 <el-checkbox v-model="formmodel.clerk_name_hidden_on_door" :true-label="1" :false-label="0">{{ this.$t('partInfo.hidden') }}</el-checkbox>
               </el-form-item>
             </el-col>
+          </el-row>
 
+          <el-row>
             <el-col :span="8">
               <el-form-item :label="this.$t('partInfo.screenLight')" prop="screen_light">
                 <el-checkbox v-model="formmodel.screen_light" :true-label="1" :false-label="0">{{ this.$t('partInfo.screenLight') }}</el-checkbox>
@@ -485,6 +501,12 @@
                 <el-checkbox v-model="formmodel.auto_position" :true-label="1" :false-label="0">{{ this.$t('action.enabled') }}</el-checkbox>
               </el-form-item>
             </el-col>
+
+            <el-col :span="8">
+              <el-form-item :label="this.$t('partInfo.boolDisplayNcTitle')" prop="bool_display_nc_title">
+                <el-checkbox v-model="formmodel.bool_display_nc_title" :true-label="1" :false-label="0">{{ this.$t('action.enabled') }}</el-checkbox>
+              </el-form-item>
+            </el-col>
           </el-row>
 
           <el-row>

+ 6 - 1
src/views/ncs-orginazition/partInfoSetting.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <el-tabs v-model="activeName" style="margin:15px;" type="border-card">
+    <el-tabs tab-position="left" v-model="activeName" style="margin:15px;" type="border-card">
       <el-tab-pane :label="this.$t('partInfo.partInfoSetting')" name="partInfo">
         <keep-alive>
           <part-info-edit :part-id="part_id" />
@@ -75,6 +75,11 @@
           <app-version-manager :part-id="part_id" :device-type="7" />
         </keep-alive>
       </el-tab-pane>
+      <el-tab-pane :label="this.$t('zy20240108.nurseWatch')" name="nurseWatch">
+        <keep-alive>
+          <app-version-manager :part-id="part_id" :device-type="107" />
+        </keep-alive>
+      </el-tab-pane>
       <el-tab-pane :label="this.$t('partInfo.vistitation')" name="vistitation">
         <keep-alive>
           <app-version-manager :part-id="part_id" :device-type="19" />