Explorar o código

完成设备菜单详情

vothin hai 1 ano
pai
achega
4a885bc36a

+ 35 - 1
languages/en.js

@@ -172,6 +172,7 @@ module.exports = {
     uploaderImg2: 'Upload avatar images can only be in JPG, PNG, GIF format!',
     uploaderSize: 'The upload attachment size cannot exceed 5MB!',
     uploaderSize2: 'The size of the uploaded avatar image cannot exceed 2MB!',
+    uploaderSize3: 'The size of the uploaded image cannot exceed 10MB!',
     uploaderImgMsg: 'The width of the image must be between 100 and 500, and the aspect ratio is 1:1! ',
     uploaderImgMsg2: 'Please upload an image with an aspect ratio of 1:1',
     uploaderImgMsg3: 'The height of the image must be between 100 and 500! ',
@@ -225,7 +226,10 @@ module.exports = {
     reboot: 'Reboot',
     count: 'Number of statistics',
     system: 'System',
-    simulateSend: 'Simulate Send'
+    simulateSend: 'Simulate Send',
+    justify: 'alignment',
+    indent: 'indentation',
+    image: 'picture'
   },
   member: {
     face: 'Avatar',
@@ -456,6 +460,29 @@ module.exports = {
     actIntent: 'Parameters of Activity',
     inputActIntent: 'Please enter the parameters for the activity'
   },
+  deviceMenuDetailManage: {
+    type: 'types of',
+    chooseType: 'Please select the type of introduction',
+    user: 'user',
+    chooseUser: 'Uncheck and display to all users by default',
+    title: 'title',
+    inputTitle: 'Please enter a title',
+    titleBg: 'Head background',
+    titleIcon: 'Titles Icon',
+    summary: 'brief introduction',
+    inputSummary: 'Please enter a brief introduction',
+    detail: 'content',
+    tags: 'label',
+    inputTags: 'Please enter a label',
+    hospitalAddr: 'Hospital address',
+    inputHospitalAddr: 'Please enter the hospital address',
+    hospitalTel: 'Hospital phone number',
+    inputHospitalTel: 'Please enter the hospital phone number',
+    hospital_web: 'Hospital website',
+    inputHospitalWeb: 'Please enter the hospital website',
+    partClerk: 'Related important members',
+    choosePartClerk: 'Please select relevant important members'
+  },
   clerkManage: {
     clerkEdit: 'Edit member information',
     choiceClerk: 'Please select an employee',
@@ -1088,6 +1115,7 @@ module.exports = {
     customBoardDesigner: 'Designer Board Screen',
     staffManageFrames: 'Staff Serve Structure',
     deviceMenuManager: 'Device Menu',
+    deviceMenuDetail: 'Device Menu Details',
     nbiotDeviceStatus: 'Faulty IoT equipment',
     offlineDevice: 'off-line equipment',
     lowBatteryDevice: 'Low battery devices',
@@ -1332,6 +1360,12 @@ module.exports = {
     FILE_UPLOAD_FAILED: 'No file storage directory configured!',
     FILE_FAILED: 'file error'
   },
+  deviceMenuDetailType: {
+    HOSPITAL: 'Hospital Introduction',
+    PART: 'Department Introduction',
+    IN_NOTICE: 'Admission Notice',
+    SATISFACTION: 'Satisfaction survey'
+  },
   entraceguardUser: {
     named: 'User Name',
     idNo: 'ID number',

+ 35 - 1
languages/es.js

@@ -172,6 +172,7 @@ module.exports = {
     uploaderImg2: '¡Subir imágenes de avatar solo puede estar en formato JPG, PNG, GIF!',
     uploaderSize: '¡El tamaño del archivo adjunto cargado no puede exceder los 5 MB!',
     uploaderSize2: '¡El tamaño de la imagen de avatar cargada no puede exceder los 2 MB!',
+    uploaderSize3: '¡¡ el tamaño de la imagen subida no puede exceder los 10 megabytes!',
     uploaderImgMsg: '¡El ancho de la imagen debe estar entre 100 y 500, y la relación de aspecto es 1:1! ',
     uploaderImgMsg2: 'Sube una imagen con una relación de aspecto de 1:1',
     uploaderImgMsg3: '¡La altura de la imagen debe estar entre 100 y 500! ',
@@ -225,7 +226,10 @@ module.exports = {
     reboot: 'reiniciar',
     count: 'Estadísticas',
     system: 'Sistema',
-    simulateSend: 'Envío simulado'
+    simulateSend: 'Envío simulado',
+    justify: 'Alinear',
+    indent: 'Sangrado',
+    image: 'Imagen'
   },
   member: {
     face: 'Avatar',
@@ -456,6 +460,29 @@ module.exports = {
     actIntent: 'Parámetros de la actividad',
     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',
+    title: 'Título',
+    inputTitle: 'Por favor, introduzca el título',
+    titleBg: 'Fondo de la cabeza',
+    titleIcon: 'Icono del título',
+    summary: 'Introducción',
+    inputSummary: 'Por favor, introduzca el perfil',
+    detail: 'Contenido',
+    tags: 'Etiquetas',
+    inputTags: 'Por favor, introduzca la 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.'
+  },
   clerkManage: {
     clerkEdit: 'Editar información del miembro',
     choiceClerk: 'Por favor, elija un empleado',
@@ -1088,6 +1115,7 @@ module.exports = {
     customBoardDesigner: 'Pantalla del tablero de diseño',
     staffManageFrames: 'Estructura del servicio al personal',
     deviceMenuManager: 'Menú del dispositivo',
+    deviceMenuDetail: 'Detalles del menú del dispositivo',
     nbiotDeviceStatus: 'Equipo de Unión de objetos defectuosos',
     offlineDevice: 'Dispositivos fuera de línea',
     lowBatteryDevice: 'Equipos de baja potencia',
@@ -1332,6 +1360,12 @@ module.exports = {
     FILE_UPLOAD_FAILED: '¡Directorio de almacenamiento de archivos no configurado!',
     FILE_FAILED: 'Error de archivo'
   },
+  deviceMenuDetailType: {
+    HOSPITAL: 'Introducción al hospital',
+    PART: 'Introducción al Departamento',
+    IN_NOTICE: 'Instrucciones para ingresar en el hospital',
+    SATISFACTION: 'Encuesta de satisfacción'
+  },
   entraceguardUser: {
     named: 'Nombre de usuario',
     idNo: 'Número de identificación',

+ 38 - 4
languages/ru-RU.js

@@ -170,8 +170,9 @@ module.exports = {
     uploaderDownload: 'Загрузить вложение',
     uploaderImg: 'Загружать вложения можно только в формате txt,doc,docx,xls,xlsx,jpg,png,jpeg!',
     uploaderImg2: 'Загружать изображения аватара можно только в формате JPG, PNG, GIF!',
-    uploaderSize: 'Размер загружаемого вложения не может превышать 5 МБ!',
-    uploaderSize2: 'Размер загружаемого аватара не может превышать 2 МБ!',
+    uploaderSize: 'Размер загружаемого вложения не может превышать 5МБ!',
+    uploaderSize2: 'Размер загружаемого аватара не может превышать 2МБ!',
+    uploaderSize3: 'Размер изображения не должен превышать 10 Мб!',
     uploaderImgMsg: 'Ширина изображения должна быть от 100 до 500, а соотношение сторон 1:1! ',
     uploaderImgMsg2: 'Пожалуйста, загрузите изображение с соотношением сторон 1:1',
     uploaderImgMsg3: 'Высота изображения должна быть между 100 и 500! ',
@@ -225,7 +226,10 @@ module.exports = {
     reboot: 'Перезагрузка',
     count: 'Статистика',
     system: 'Системы',
-    simulateSend: 'аналоговая передача'
+    simulateSend: 'аналоговая передача',
+    justify: 'Выровнять',
+    indent: 'Отступ',
+    image: 'Фотографии'
   },
   member: {
     face: 'Аватар',
@@ -456,6 +460,29 @@ module.exports = {
     actIntent: 'Параметры активности',
     inputActIntent: 'Введите параметры активности'
   },
+  deviceMenuDetailManage: {
+    type: 'Тип',
+    chooseType: 'Выберите тип профиля',
+    user: 'Пользователи',
+    chooseUser: 'Показывать не по умолчанию всем пользователям',
+    title: 'Заголовок',
+    inputTitle: 'Введите заголовок',
+    titleBg: 'Фон головы',
+    titleIcon: 'Значок заголовка',
+    summary: 'Введение',
+    inputSummary: 'Введите профиль',
+    detail: 'Содержание',
+    tags: 'Метки',
+    inputTags: 'Введите вкладку',
+    hospitalAddr: 'Адрес больницы',
+    inputHospitalAddr: 'Пожалуйста, введите адрес больницы.',
+    hospitalTel: 'Больничный телефон',
+    inputHospitalTel: 'Пожалуйста, введите телефон больницы.',
+    hospital_web: 'Сайт больницы',
+    inputHospitalWeb: 'Пожалуйста, введите сайт больницы.',
+    partClerk: 'Соответствующие важные члены',
+    choosePartClerk: 'Пожалуйста, выберите значимых членов.'
+  },
   clerkManage: {
     clerkEdit: 'Редактировать информацию об участнике',
     choiceClerk: 'Пожалуйста, выберите сотрудника',
@@ -980,7 +1007,7 @@ module.exports = {
     entraceguard_device: 'Вход',
     organizationAdd: 'Новая организация',
     boardShowEmptyBed: 'На доске показаны пустые кровати',
-    iotProductID:  'Идентификатор устройства NB',
+    iotProductID: 'Идентификатор устройства NB',
     iotProductKey: 'Ключ продукта устройства NB',
     nursingColorRgb: 'Светлый цвет двери медсестер',
     twoColorDoorLightValid: 'Поддерживается или нет двухцветная дверная подсветка',
@@ -1088,6 +1115,7 @@ module.exports = {
     customBoardDesigner: 'Экран панели',
     staffManageFrames: 'Параметры управления пространством',
     deviceMenuManager: 'Меню Устройства',
+    deviceMenuDetail: 'Меню устройства Подробнее',
     nbiotDeviceStatus: 'неисправное оборудование МСУ',
     offlineDevice: 'Автономное оборудование',
     lowBatteryDevice: 'Низкоэлектрическое оборудование',
@@ -1332,6 +1360,12 @@ module.exports = {
     FILE_UPLOAD_FAILED: 'каталог без профиля!',
     FILE_FAILED: 'Ошибка файла'
   },
+  deviceMenuDetailType: {
+    HOSPITAL: 'Краткое описание больницы',
+    PART: 'Введение',
+    IN_NOTICE: 'Информация о госпитализации',
+    SATISFACTION: 'Обследование степени удовлетворенности'
+  },
   entraceguardUser: {
     named: 'Имя пользователя',
     idNo: 'Номер удостоверения личности',

+ 21 - 6
languages/zh-CN.js

@@ -171,8 +171,8 @@ module.exports = {
     uploaderImg: '上传附件只能是txt,doc,docx,xls,xlsx,jpg,png,jpeg格式!',
     uploaderImg2: '上传头像图片只能是 JPG、PNG、GIF 格式!',
     uploaderSize: '上传附件大小不能超过 5MB!',
-    uploaderSize2: '上传头像图片大小不能超过 2MB!',
-    uploaderSize3: '上传头像图片大小不能超过 10MB!',
+    uploaderSize2: '上传图片大小不能超过 2MB!',
+    uploaderSize3: '上传图片大小不能超过 10MB!',
     uploaderImgMsg: '图片宽度必须在100~500之间,宽高比为1: 1!',
     uploaderImgMsg2: '请上传宽高比为1: 1的图片',
     uploaderImgMsg3: '图片高度必须在100~500之间!',
@@ -226,7 +226,10 @@ module.exports = {
     reboot: '重启',
     count: '统计次数',
     system: '系统',
-    simulateSend: '模拟发送'
+    simulateSend: '模拟发送',
+    justify: '对齐',
+    indent: '缩进',
+    image: '图片'
   },
   member: {
     face: '头像',
@@ -460,13 +463,25 @@ module.exports = {
   deviceMenuDetailManage: {
     type: '类型',
     chooseType: '请选择简介类型',
+    user: '用户',
+    chooseUser: '不选默认显示给所有用户',
     title: '标题',
     inputTitle: '请输入标题',
     titleBg: '头部背景',
     titleIcon: '标题图标',
     summary: '简介',
     inputSummary: '请输入简介',
-    detail: '内容'
+    detail: '内容',
+    tags: '标签',
+    inputTags: '请输入标签',
+    hospitalAddr: '医院地址',
+    inputHospitalAddr: '请输入医院地址',
+    hospitalTel: '医院电话',
+    inputHospitalTel: '请输入医院电话',
+    hospital_web: '医院网址',
+    inputHospitalWeb: '请输入医院网址',
+    partClerk: '相关重要成员',
+    choosePartClerk: '请选择相关重要成员'
   },
   clerkManage: {
     clerkEdit: '编辑成员信息',
@@ -884,7 +899,7 @@ module.exports = {
     attacHisCodes: '附加HIS科室标识',
     inputHisCode: '请输入HIS系统标识',
     sharedBedHisCodes: '共享床位HIS标识',
-    distinguishSharedBeds:'区分患者',
+    distinguishSharedBeds: '区分患者',
     inputSharedBedHisCodes: '输入共享本科室床位HIS科室标识,多个科室以逗号分割',
     inputAttacHisCode: '输入附加HIS科室标识,多个科室以逗号分割',
     shopType: '组织类型',
@@ -1100,7 +1115,7 @@ module.exports = {
     customBoardDesigner: '看板屏设计',
     staffManageFrames: '空间管理设置',
     deviceMenuManager: '设备菜单',
-    deviceMenuDetail: '菜单详细信息',
+    deviceMenuDetail: '设备菜单详情',
     nbiotDeviceStatus: '故障物联设备',
     offlineDevice: '离线设备',
     lowBatteryDevice: '低电量设备',

+ 7 - 0
src/api/ncs_clerk.js

@@ -125,3 +125,10 @@ export function getClerksByShopId(partId) {
     method: 'GET'
   })
 }
+
+export function getClerkVoByPartId(partId) {
+  return request({
+    url: `/ncs/clerk/get_clerk_by_part_id/${partId}`,
+    method: 'GET'
+  })
+}

+ 26 - 0
src/api/ncs_device_menu_detail.js

@@ -0,0 +1,26 @@
+import request from '@/utils/request'
+export function getModelByMenuId(menuId) {
+  return request({
+    url: `/ncs/device_menu_detail/get_model_by_menu_id/${menuId}`,
+    method: 'GET'
+  })
+}
+
+/** 修改 */
+export function update(id, params) {
+  return request({
+    url: `/ncs/device_menu_detail/${id}`,
+    method: 'put',
+    data: params
+  })
+}
+
+/** 新增 */
+export function add(params) {
+  return request({
+    url: '/ncs/device_menu_detail',
+    method: 'POST',
+    loading: true,
+    data: params
+  })
+}

+ 46 - 16
src/components/WangEdiitor/wangEditor.vue

@@ -27,10 +27,13 @@
 import Vue from 'vue'
 import '@wangeditor/editor/dist/css/style.css'
 import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
+import { i18nChangeLanguage  } from '@wangeditor/editor'
 import * as API_Upload from "@/api/upload";
+import * as wangEditorConfig from "@/components/WangEdiitor/wangEditorConfig";
+
 
 const serverUrl = domain.serverUrl
-export default Vue.extend({
+export default {
   name: "wangEditor",
   components: { Editor, Toolbar },
   model: {
@@ -46,9 +49,10 @@ export default Vue.extend({
   data() {
     return {
       editor: null,
-      mode: 'simple', // or 'default'
-      content: '请输入内容...',
-      toolbarConfig: { },
+      mode: 'default', // 'simple' or 'default'
+      content: '',
+      toolbarConfig: wangEditorConfig.toolbarConfig,
+      // toolbarConfig: {},
       editorConfig: {
         placeholder: '请输入内容...',
         withCredentials: true,
@@ -71,7 +75,7 @@ export default Vue.extend({
             // 最多可上传几个文件,默认为 100
             maxNumberOfFiles: 100,
             // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
-            allowedFileTypes: [],
+            allowedFileTypes: ['image/*'],
             meta: {
               //官网中把token放到了这里,但是请求的时候会看不到token
             },
@@ -81,15 +85,28 @@ export default Vue.extend({
             withCredentials: false,
             // 超时时间,默认为 10 秒
             timeout: 5 * 1000, // 5 秒
-          }
+          },
+          // insertLink: {
+          //   checkLink: this.checkedLink,
+          // },
+          // editLink: {
+          //   checkLink: this.checkedLink,
+          // }
+
         },
       },
     }
   },
   watch: {
     value(val) {
-      this.html = val
-    }
+      if (this.$i18n.locale === 'zh') {
+        i18nChangeLanguage('zh-CN')
+      }
+      else {
+        i18nChangeLanguage('en')
+      }
+      this.content = val
+    },
   },
   beforeDestroy() {
     const editor = this.editor
@@ -102,18 +119,20 @@ export default Vue.extend({
     },
     onChange(editor) {
       this.$emit('input', editor.getHtml())
+      this.content = editor.getHtml()
+      this.$emit('change', this.content)
     },
     onDestroyed(editor) {
-      console.log("onDestroyed", editor);
+      // console.log("onDestroyed", editor);
     },
     onMaxLength(editor) {
-      console.log("onMaxLength", editor);
+      // console.log("onMaxLength", editor);
     },
     onFocus(editor) {
-      console.log("onFocus", editor);
+      // console.log("onFocus", editor);
     },
     onBlur(editor) {
-      console.log("onBlur", editor);
+      // console.log("onBlur", editor);
     },
     customAlert(info, type) {
       window.alert(`customAlert in Vue demo\n${type}:\n${info}`);
@@ -180,8 +199,8 @@ export default Vue.extend({
     },
 
     // 自定义插入图片
-    insertImg(file) {
-      console.log(file);
+    insertImg(file, insertFn) {
+      this.uploadImg(file, insertFn)
     },
     /**
      * 从html代码中匹配返回图片标签img的属性src的值的集合
@@ -282,9 +301,20 @@ export default Vue.extend({
       if (editor == null) return;
       editor.destroy(); // 组件销毁时,及时销毁编辑器
     },
+    checkedLink(text, link) {
+      if (link !== "") {
+        var reg = /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/;
+        if (!reg.test(link)) {
+          return '请输入正确的网址(例如 http://baidu.com)'
+        }else{
+          return true
+        }
+      }
+    }
   }
-})
+}
 </script>
 
-<style>
+<style src="@wangeditor/editor/dist/css/style.css">
+
 </style>

+ 83 - 0
src/components/WangEdiitor/wangEditorConfig.js

@@ -0,0 +1,83 @@
+import i18n from '@/utils/i18n'
+
+export const toolbarConfig = {
+  /* 工具栏配置 */
+  toolbarKeys: [
+    'headerSelect',
+    'blockquote',
+    '|',
+    'bold',
+    'underline',
+    'italic',
+    {
+      'key': 'group-more-style',
+      'title': i18n.t('action.more'),
+      'iconSvg': '<svg viewBox="0 0 1024 1024"><path d="M204.8 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M505.6 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M806.4 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path></svg>',
+      'menuKeys': [
+        'through',
+        'code',
+        'sup',
+        'sub',
+        'clearStyle'
+      ]
+    },
+    'color',
+    'bgColor',
+    '|',
+    'fontSize',
+    'fontFamily',
+    'lineHeight',
+    '|',
+    'bulletedList',
+    'numberedList',
+    'todo',
+    {
+      key: 'group-justify',
+      title: i18n.t('action.justify'),
+      iconSvg: '<svg viewBox="0 0 1024 1024"><path d="M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>',
+      menuKeys: [
+        'justifyLeft',
+        'justifyRight',
+        'justifyCenter',
+        'justifyJustify'
+      ]
+    },
+    {
+      key: 'group-indent',
+      title: i18n.t('action.indent'),
+      iconSvg: '<svg viewBox="0 0 1024 1024"><path d="M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z"></path></svg>',
+      menuKeys: [
+        'indent',
+        'delIndent'
+      ]
+    },
+    '|',
+    'emotion',
+    'insertLink',
+    // 菜单组,包含多个菜单
+    {
+      key: 'group-image', // 必填,要以 group 开头
+      title: i18n.t('action.image'), // 必填
+      iconSvg: '<svg viewBox="0 0 1024 1024"><path d="M959.877 128l0.123 0.123v767.775l-0.123 0.122H64.102l-0.122-0.122V128.123l0.122-0.123h895.775zM960 64H64C28.795 64 0 92.795 0 128v768c0 35.205 28.795 64 64 64h896c35.205 0 64-28.795 64-64V128c0-35.205-28.795-64-64-64zM832 288.01c0 53.023-42.988 96.01-96.01 96.01s-96.01-42.987-96.01-96.01S682.967 192 735.99 192 832 234.988 832 288.01zM896 832H128V704l224.01-384 256 320h64l224.01-192z"></path></svg>',
+      menuKeys: ['uploadImage',
+        'insertImage']
+    },
+    // {
+    //   "key": "group-video",
+    //   "title": "视频",
+    //   "iconSvg": "<svg viewBox=\"0 0 1024 1024\"><path d=\"M981.184 160.096C837.568 139.456 678.848 128 512 128S186.432 139.456 42.816 160.096C15.296 267.808 0 386.848 0 512s15.264 244.16 42.816 351.904C186.464 884.544 345.152 896 512 896s325.568-11.456 469.184-32.096C1008.704 756.192 1024 637.152 1024 512s-15.264-244.16-42.816-351.904zM384 704V320l320 192-320 192z\"></path></svg>",
+    //   "menuKeys": [
+    //     "insertVideo",
+    //     "uploadVideo"
+    //   ]
+    // },
+    'insertTable',
+    'codeBlock',
+    'divider',
+    '|',
+    'undo',
+    'redo',
+    '|',
+    'fullScreen'
+  ]
+}

+ 3 - 2
src/router/index.js

@@ -172,10 +172,11 @@ export const partRoutes = [
         meta: { title: i18n.t('tab.deviceMenuManager'), icon: 'el-icon-menu', noCache: true }
       },
       {
-        path: 'device_menu_detail',
+        path: 'device_menu_detail/:id',
         component: () => import('@/views/ncs-device-menu-detail/index'),
         name: 'device-menu-detail',
-        meta: { title: i18n.t('tab.deviceMenuDetail'), icon: 'el-icon-tickets', noCache: true }
+        meta: { title: i18n.t('tab.deviceMenuDetail'), icon: 'el-icon-tickets', noCache: true },
+        hidden: true
       },
       // {
       //   path: 'led',

+ 279 - 72
src/views/ncs-device-menu-detail/index.vue

@@ -1,105 +1,224 @@
 <template>
   <div>
     <el-card style="margin: 15px">
-      <el-form ref="editform" :rules="rules"  label-width="120px"  :model="formmodel" style="margin: 10px">
-        <el-row>
-          <el-form-item :label="this.$t('deviceMenuDetailManage.type')" prop="type">
-            <el-select v-model="formmodel.type"
-                       :placeholder="this.$t('deviceMenuDetailManage.chooseType')"
-                       filterable clearable>
-              <el-option v-for="(item,index) in deviceMenuDetailTypeTransfer" :key="index" :label="item.key" :value="item.value" />
-            </el-select>
-          </el-form-item>
-        </el-row>
-
-        <el-row>
-          <el-col :span="12">
-            <el-form-item :label="this.$t('deviceMenuDetailManage.title')" prop="title" maxlength="50">
-              <el-input v-model="formmodel.title" :placeholder="this.$t('deviceMenuDetailManage.inputTitle')" :maxlength="50" clearable/>
+      <div>
+        <el-form ref="editform" :rules="rules"  label-width="120px"  :model="formmodel" style="margin: 10px">
+          <el-row>
+            <el-form-item :label="this.$t('deviceMenuDetailManage.type')" prop="type">
+              <el-select v-model="formmodel.type"
+                         :placeholder="this.$t('deviceMenuDetailManage.chooseType')"
+                         filterable clearable>
+                <el-option v-for="(item,index) in deviceMenuDetailTypeTransfer" :key="index" :label="item.key" :value="item.value" />
+              </el-select>
             </el-form-item>
-          </el-col>
-        </el-row>
+          </el-row>
 
-        <el-row>
-          <el-col :span="24">
-            <el-form-item :label="this.$t('deviceMenuDetailManage.summary')" prop="summary">
-              <el-input v-model="formmodel.summary" :placeholder="this.$t('deviceMenuDetailManage.inputSummary')" type="textarea" :maxlength="200" clearable/>
+          <el-row>
+            <el-form-item :label="this.$t('deviceMenuDetailManage.user')" prop="customer_id">
+              <el-select v-model="formmodel.customer_id"
+                         :placeholder="this.$t('deviceMenuDetailManage.chooseUser')"
+                         filterable clearable>
+                <el-option v-for="(item,index) in users" :key="index" :label="item.named" :value="item.id" />
+              </el-select>
             </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row>
-          <el-col :span="24">
-            <el-form-item :label="this.$t('deviceMenuDetailManage.detail')" prop="detail">
-<!--              <wangEditor v-model="formmodel.detail" clearable/>-->
-<!--              <wangEditor/>-->
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row>
-          <el-col :span="8">
-            <el-form-item :label="this.$t('deviceMenuDetailManage.titleIcon')">
-              <el-upload
-                  class="avatar-uploader"
-                  :action="`${titleIconUploadUrl}?scene=avatar`"
-                  :show-file-list="false"
-                  :on-success="titleIconUploaded"
-                  :before-upload="handleTitleIconBefore"
-              >
-                <img v-if="titleIconUrl" :src="titleIconUrl" class="avatar">
-                <i v-else class="el-icon-plus avatar-uploader-icon" />
-              </el-upload>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-
-        <el-row>
-          <el-col :span="8">
-            <el-form-item :label="this.$t('deviceMenuDetailManage.titleBg')">
-              <el-upload
-                  class="avatar-uploader"
-                  :action="`${titleBgUploadUrl}?scene=avatar`"
-                  :show-file-list="false"
-                  :on-success="titleBgUploaded"
-                  :before-upload="handleTitleBgBefore"
-              >
-                <img v-if="titleBgUrl" :src="titleBgUrl" class="avatar">
-                <i v-else class="el-icon-plus avatar-uploader-icon" />
-              </el-upload>
+          </el-row>
+
+          <el-row>
+            <el-col :span="10">
+              <el-form-item :label="this.$t('deviceMenuDetailManage.hospitalAddr')" prop="hospital_addr" maxlength="50">
+                <el-input v-model="formmodel.hospital_addr" :placeholder="this.$t('deviceMenuDetailManage.inputHospitalAddr')" :maxlength="50" clearable/>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row>
+            <el-col :span="10">
+              <el-form-item :label="this.$t('deviceMenuDetailManage.hospitalTel')" prop="hospital_tel" maxlength="50">
+                <el-input v-model="formmodel.hospital_tel" :placeholder="this.$t('deviceMenuDetailManage.inputHospitalTel')" :maxlength="50" clearable/>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row>
+            <el-col :span="10">
+              <el-form-item :label="this.$t('deviceMenuDetailManage.hospital_web')" prop="hospital_web" maxlength="50">
+                <el-input v-model="formmodel.hospital_web" :placeholder="this.$t('deviceMenuDetailManage.inputHospitalWeb')" :maxlength="50" clearable/>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+
+          <el-row>
+            <el-form-item :label="partClerkStr"
+                          v-for="(item, index) in formmodelPartClerk" :key="'a' + index">
+              <el-col :span="4" style="margin: 0 10px 0 0">
+                <el-select v-model="item.clerk_id"
+                           :placeholder="choosePartClerkStr"
+                           filterable clearable>
+                  <el-option v-for="(_item,index) in clerks" :key="index" :label="_item.role_name + '-' + _item.clerk_name" :value="_item.clerk_id" />
+                </el-select>
+              </el-col>
+              <el-col :span="3" style="margin: auto">
+                <el-button v-if="index === 0" type="primary" @click="addInput(formmodelPartClerk)"> {{ addStr }} </el-button>
+                <el-button v-else type="danger" @click="delInput(formmodelPartClerk, index)"> {{ delStr }} </el-button>
+              </el-col>
             </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
+          </el-row>
+
+          <el-row>
+            <el-col :span="8">
+              <el-form-item :label="this.$t('deviceMenuDetailManage.titleIcon')">
+                <el-upload
+                    class="avatar-uploader"
+                    :action="`${titleIconUploadUrl}?scene=avatar`"
+                    :show-file-list="false"
+                    :on-success="titleIconUploaded"
+                    :before-upload="handleTitleIconBefore"
+                    accept=".png,.jpeg,.jpg"
+                >
+                  <img v-if="titleIconUrl" :src="titleIconUrl" class="avatar">
+                  <i v-else class="el-icon-plus avatar-uploader-icon" />
+                </el-upload>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row>
+            <el-col :span="8">
+              <el-form-item :label="this.$t('deviceMenuDetailManage.titleBg')">
+                <el-upload
+                    class="avatar-uploader"
+                    :action="`${titleBgUploadUrl}?scene=avatar`"
+                    :show-file-list="false"
+                    :on-success="titleBgUploaded"
+                    :before-upload="handleTitleBgBefore"
+                    accept=".png,.jpeg,.jpg"
+                >
+                  <img v-if="titleBgUrl" :src="titleBgUrl" class="rightullidiv">
+                  <i v-else class="el-icon-plus avatar-uploader-icon" />
+                </el-upload>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row>
+            <el-col :span="12">
+              <el-form-item :label="this.$t('deviceMenuDetailManage.title')" prop="title" maxlength="50">
+                <el-input v-model="formmodel.title" :placeholder="this.$t('deviceMenuDetailManage.inputTitle')" :maxlength="50" clearable/>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row>
+            <el-col :span="24">
+              <el-form-item :label="this.$t('deviceMenuDetailManage.summary')" prop="summary">
+                <el-input v-model="formmodel.summary" :placeholder="this.$t('deviceMenuDetailManage.inputSummary')" type="textarea" :maxlength="200" clearable/>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+
+          <el-row>
+            <el-col :span="24">
+              <el-form-item :label="this.$t('deviceMenuDetailManage.detail')" prop="detail">
+                <wangEditor v-model="formmodel.detail" clearable/>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row>
+            <el-col :span="24">
+              <el-form-item :label="this.$t('deviceMenuDetailManage.tags')" prop="tags">
+                <el-input v-model="formmodel.tags" :placeholder="this.$t('deviceMenuDetailManage.inputTags')" :maxlength="50" clearable/>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+        </el-form>
+      </div>
+
+      <div align="center" class="margin-top-sm">
+        <el-button type="primary" @click="handlerFormSubmit('editform')">{{ this.$t('action.save') }}</el-button>
+      </div>
     </el-card>
   </div>
 </template>
 
 <script>
 import {DEVICE_MENU_DETAIL_TYPE} from "@/utils/enum/DeviceMenuDetailTypeEnum";
-// import wangEditor from "@/components/WangEdiitor/wangEditor";
+import wangEditor from "@/components/WangEdiitor/wangEditor";
+import {getListByPartId} from "@/api/ncs_customer";
+import * as API_DeviceMenuDetail from '@/api/ncs_device_menu_detail'
+import * as API_Clerk from '@/api/ncs_clerk'
 
 const serverUrl = domain.serverUrl
 export default {
   name: "index",
-  // components: { wangEditor },
+  components: { wangEditor },
   data() {
     return {
       rules: {
+        type: [
+          { required: true, message: this.$t('deviceMenuDetailManage.chooseType'), trigger: 'blur' }
+        ],
+        title: [
+          { required: true, message: this.$t('deviceMenuDetailManage.inputTitle'), trigger: 'blur' }
+        ],
       },
       formmodel: {
+        menu_id: this.$route.params.id,
+        part_id: this.$route.params.part_id
       },
-
+      formmodelPartClerk: [{
+        n_index: 1,
+        type: '',
+        name: '',
+        value: ''
+      }],
+      loading: false,
+      users: [],
+      clerks: [],
       titleIconUploadUrl: serverUrl + '/ncs/upload/uploadFile',
       titleIconUrl: '',
       titleBgUploadUrl: serverUrl + '/ncs/upload/uploadFile',
       titleBgUrl: '',
       deviceMenuDetailTypeTransfer: DEVICE_MENU_DETAIL_TYPE.getKeyValueList(),
+      partClerkStr: this.$t('deviceMenuDetailManage.partClerk'),
+      choosePartClerkStr: this.$t('deviceMenuDetailManage.choosePartClerk'),
+      actIntentStr: this.$t('deviceMenuManage.actIntent'),
+      addStr: this.$t('action.add'),
+      delStr: this.$t('action.delete')
     }
   },
+  mounted() {
+    this.getModel()
+    this.getEmployees()
+    this.getClerkList()
+  },
   methods: {
-
+    getModel() {
+      this.loading = true
+      API_DeviceMenuDetail.getModelByMenuId(this.formmodel.menu_id).then(res => {
+        if (res) {
+          this.formmodel = res
+          this.titleIconUrl = res.title_icon
+          this.titleBgUrl = res.title_bg
+          this.formmodelPartClerk = this.strToId(this.formmodel.part_clerk)
+        }
+        else {
+          this.titleIconUrl = ''
+          this.titleBgUrl = ''
+        }
+        this.loading = false
+      })
+    },
+    getClerkList() {
+      const _this = this
+      API_Clerk.getClerkVoByPartId(this.formmodel.part_id).then(res => {
+        _this.clerks = res
+        this.clerks = _this.clerks.filter(item => item.role_id !== 0 && item.role_id !== 1)
+      })
+    },
     /** 上传成功后的钩子 更换图片 置空存储数组*/
     titleIconUploaded(res) {
       this.titleIconUrl = serverUrl + '/' + res
@@ -173,10 +292,98 @@ export default {
         reader.readAsDataURL(file)
       })
     },
+    handlerFormSubmit() {
+      console.log(this.formmodel)
+      this.formmodel.part_clerk = this.idToStr(this.formmodelPartClerk)
+      this.loading = true
+      if (this.formmodel.id) {
+        API_DeviceMenuDetail.update(this.formmodel.id, this.formmodel).then(res => {
+          this.loading = false
+          this.$message.success(this.$t('action.saveSuccess'))
+        })
+      }
+      else {
+        API_DeviceMenuDetail.add(this.formmodel).then(res => {
+          this.loading = false
+          this.$message.success(this.$t('action.saveSuccess'))
+          this.formmodel = res
+        })
+      }
+    },
+    getEmployees() {
+      const _this = this
+      _this.users = []
+      getListByPartId(this.$store.getters.partId).then(res => {
+        _this.users = res
+      })
+    },
+    addInput(paramsTemp){
+      paramsTemp.push({
+        clerk_id: '',
+      })
+    },
+    delInput(paramsTemp, index) {
+      paramsTemp.splice(index, 1)
+    },
+    idToStr(list) {
+      let partClerkStr = ''
+      let partClerk = []
+      let clerk = {}
+      if (list.length !== 0) {
+        console.log('list', list)
+        for (let i = 0; i < list.length; i++) {
+          console.log('list[i]', list[i])
+          if (list[i].clerk_id !== '') {
+            clerk = this.clerks.filter(item => item.clerk_id === list[i].clerk_id)[0]
+            partClerk.push({
+              clerk_id: clerk.clerk_id,
+              type: clerk.role_type,
+              name: clerk.role_name,
+              value: clerk.clerk_name
+            })
+          }
+        }
+        partClerkStr = JSON.stringify(partClerk)
+      }
+      else {
+        partClerkStr = ''
+      }
+      return partClerkStr
+    },
+    strToId(str) {
+      const partClerks = []
+      if (str) {
+        let partClerk = JSON.parse(str)
+        if (partClerk.length !== 0) {
+          for (let i = 0; i < partClerk.length; i++) {
+            partClerks.push({
+              clerk_id: partClerk[i].clerk_id
+            })
+          }
+        }
+      }
+      else {
+        partClerks.push({
+          clerk_id: ''
+        })
+      }
+      return partClerks
+    }
   }
 }
 </script>
 
 <style scoped>
-
+.rightullidiv {
+  width: 100%;
+  height: 200px;
+  background: #f2f2f2;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+    .rightulliimg {
+      max-width: 100%;
+      max-height: 200px;
+    }
+}
 </style>

+ 40 - 35
src/views/ncs-device-menu/index.vue

@@ -151,12 +151,13 @@ import {DEVICE_TYPE} from "@/utils/enum/DeviceTypeEnum";
 import {DEVICE_MENU_TYPE} from "@/utils/enum/DeviceMenuTypeEnum";
 import * as clerk_API from "@/api/ncs_clerk";
 import {ROLE_TYPE} from "@/utils/enum/RoleTypeEnum";
+import ButtonCellRenderList from "@/components/AgGridCellRender/ButtonCellRenderList";
 
 const serverUrl = domain.serverUrl
 
 export default {
   name: "index",
-  components: { ButtonCellRender, ImageViewer },
+  components: { ButtonCellRender, ImageViewer, ButtonCellRenderList },
   props: {
     part_view: { // 是否为科室视图
       type: Boolean,
@@ -272,40 +273,38 @@ export default {
       {
         headerName: this.$t('deviceMenuManage.actIntent'), field: 'act_intent', sortable: true, filter: 'agTextColumnFilter', flex: 1, valueFormatter: this.formatterUnEscape
       },
-      {
-        headerName: this.$t('action.edit'),
-        cellRendererFramework: 'ButtonCellRender',
-        cellRendererParams: {
-          onClick: this.handlerEdit,
-          label: this.$t('action.edit'),
-          buttonType: 'primary',
-          buttonSize: 'mini'
-        },
-        filter: false,
-        pinned: 'right',
-        lockPinned: true,
-        width: 100,
-        resizable: false,
-        sortable: false
-      },
-      {
-        headerName: this.$t('action.delete'),
-        cellRendererFramework: 'ButtonCellRender',
+      { headerName: this.$t('action.handle'), field: 'id',
+        cellRendererFramework: 'ButtonCellRenderList',
         cellRendererParams: param => {
           return {
-            onClick: this.deleteSingle,
-            label: this.$t('action.delete'),
-            buttonType: 'danger',
-            buttonSize: 'mini'
-          }
+            list: [
+              {
+                onClick: this.handlerEdit,
+                label: this.$t('action.edit'),
+                buttonType: 'primary',
+                buttonSize: 'mini'
+              },
+              {
+                onClick: this.handlerDetails,
+                label: this.$t('action.details'),
+                buttonType: 'success',
+                buttonSize: 'mini',
+                disabled: !this.isSys(param)
+              },
+              {
+                onClick: this.deleteSingle,
+                label: this.$t('action.delete'),
+                buttonType: 'danger',
+                buttonSize: 'mini',
+              }
+            ]}
         },
+        filter: false,
         pinned: 'right',
         lockPinned: true,
-        width: 100,
+        minWidth: this.$i18n.locale === 'zh' ? 210 : 330,
         resizable: false,
-        filter: false,
-        sortable: false
-      }
+        sortable: false },
     ]
     this.defaultColDef = {
       sortable: true,
@@ -351,12 +350,12 @@ export default {
           page_size: response.page_size,
           data_total: response.data_total
         }
-        this.$nextTick(() => {
-          const node = this.gridApi.getDisplayedRowAtIndex(0)
-          if (node !== null && node !== undefined) {
-            node.setSelected(true)
-          }
-        })
+        // this.$nextTick(() => {
+        //   const node = this.gridApi.getDisplayedRowAtIndex(0)
+        //   if (node !== null && node !== undefined) {
+        //     node.setSelected(true)
+        //   }
+        // })
       }).catch(() => {
         this.loading = false
       })
@@ -653,6 +652,12 @@ export default {
         }]
       }
     },
+    handlerDetails(row) {
+      this.$router.push({ name: 'device-menu-detail', params: { id: row.id, part_id: row.part_id, callback: this.getList() }})
+    },
+    isSys(param) {
+      return param.data.type === DEVICE_MENU_TYPE.SYS
+    }
   }
 }
 </script>