Просмотр исходного кода

添加倒计时组件、屏幕提示语组件配置.调整菜单叠加

wuyunfeng 2 лет назад
Родитель
Сommit
53898b7fc1

+ 33 - 2
languages/en.js

@@ -70,7 +70,7 @@ module.exports = {
     alias: 'Alias',
     tips: 'Tips',
     time: 'Hour',
-    time2: 'Time',
+    time2: 'Hour',
     minute: 'Minute',
     minute2: 'Minute',
     second: 'Second',
@@ -994,7 +994,9 @@ module.exports = {
     hisManage: 'His query',
     interactionChars: 'Interaction statistics',
     partSetting: 'Organization settings',
-    functionRoleMapping: 'Function Role Setting',
+    functionRoleMapping: 'Component Permissions',
+    countdownConfig:'Countdown Component Configuration',
+    screentip:'ScreenTip Component Configuration',
     interactionChain: 'Interaction Accept Order',
     allClerk: 'All employees',
     allCustomer: 'All users',
@@ -1155,6 +1157,35 @@ module.exports = {
     ROOMCHECK_COMPONENT:'Room patrol',
     SCREEN_TIP_SET_COMPONENT:'Set screen prompt'
   },
+  countdownConfig:{
+    countDownItmes:'Countdown items',
+    countDownTimes:'Countdown time item',
+    addNewItem:'New item',
+    addNewTimeItem:'Add a time item',
+    numberRequired:'You must enter a number',
+    errorTip:'At least one item in the hour, minute, and second must be greater than 0',
+  },
+  screenTip:{
+    tipAdd:'Add a prompt',
+    tipEdit:'Edit prompt',
+    showText:'Display content',
+    textColor:'Text color',
+    textSize:'Text Size',
+    screenBgColor:'Screen background color',
+    displayMinutes:'Maximum display time (minutes)',
+    displayLongest:'Maximum display time',
+    boolScroll:'Whether to scroll display',
+    scrollDirect:'Scroll direction',
+    leftToRight:'From left to right',
+    rightToLeft:'From right to left',
+    upToDown:'From top to bottom',
+    downToUp:'From bottom to top',
+    showTextRequired:'Display text must be filled in',
+    scrollDirectRequired:'The scroll direction must be selected',
+    displayMinutesRequired:'The maximum display time must be filled in',
+    textSizeRequired:'Text size must be filled in',
+    numberRequired:'You must enter a number'
+  },
   clerkFrameManage: {
     employeeView: 'Staff View',
     frameView: 'Structure View',

+ 33 - 1
languages/es.js

@@ -995,7 +995,9 @@ module.exports = {
     hisManage: 'Su consulta',
     interactionChars: 'Interacción Estadísticas',
     partSetting: 'Organización construir',
-    functionRoleMapping: 'Configuración funciones',
+    functionRoleMapping: 'Permisos de componentes',
+    countdownConfig:'Configuración del componente de cuenta atrás',
+    screentip:'Configuración del componente de recordatorio de pantalla',
     interactionChain: 'Aceptar órdenes de forma interactiva',
     allClerk: 'Todos los empleados',
     allCustomer: 'Todos los usuarios',
@@ -1155,6 +1157,36 @@ module.exports = {
     ROOMCHECK_COMPONENT:'patrulla de casas',
     SCREEN_TIP_SET_COMPONENT:'configurar el recordatorio de pantalla'
   },
+  countdownConfig:{
+    countDownItmes:'proyecto de cuenta atrás',
+    countDownTimes:'entrada de tiempo de cuenta atrás',
+    addNewItem:'nuevo proyecto',
+    addNewTimeItem:'añadir elemento de tiempo',
+    numberRequired:'se debe introducir el número',
+    errorTip:'el tiempo, el minuto y el segundo deben tener al menos uno mayor que 0',
+
+  },
+  screenTip:{
+    tipAdd:'nuevo recordatorio',
+    tipEdit:'editar indicaciones',
+    showText:'mostrar contenido',
+    textColor:'color del texto',
+    textSize:'tamaño del texto',
+    screenBgColor:'color de fondo de la pantalla',
+    displayMinutes:'tiempo máximo de visualización (min)',
+    displayLongest:'tiempo máximo de visualización',
+    boolScroll:'si se desplaza a la pantalla',
+    scrollDirect:'dirección de desplazamiento',
+    leftToRight:'de izquierda a derecha',
+    rightToLeft:'de derecha a izquierda',
+    upToDown:'de arriba a abajo',
+    downToUp:'de abajo hacia arriba',
+    showTextRequired:'el texto de visualización debe rellenarse',
+    scrollDirectRequired:'la dirección de desplazamiento debe seleccionarse',
+    displayMinutesRequired:'el tiempo máximo de visualización debe completarse',
+    textSizeRequired:'el tamaño del texto debe rellenarse',
+    numberRequired:'se debe introducir el número'
+  },
   clerkFrameManage: {
     employeeView: 'Vista de empleados',
     frameView: 'Vista de estructura',

+ 32 - 0
languages/ru-RU.js

@@ -960,6 +960,8 @@ module.exports = {
     boardManage: 'Настройки информационной доски',
     eventManage: 'Управление событиями кнопки',
     interactionChars: 'Статистика взаимодействия',
+    functionRoleMapping:'Права компонентов ',
+    countdownConfig:'Настройка компонентов обратного отсчета',
     partSetting: 'Настройки организации',
     allClerk: 'Все сотрудники',
     allCustomer: 'Все пользователи',
@@ -996,6 +998,7 @@ module.exports = {
     REMOTE_CONTROL: 'Удаленное управление',
     BEACON: 'Маяки',
     INFORMATION_BOARD: 'Информационная доска',
+    screentip:'Настройка компонентов подсказок экрана',
     ENTRANCE_GUARD: 'Устройство контроля доступа',
     VISITATION: 'Машина посетителя',
     RS485_TRANSFER: 'Коробка преобразования 485',
@@ -1136,7 +1139,36 @@ module.exports = {
     ROOMCHECK_COMPONENT:'Патрульный дом',
     SCREEN_TIP_SET_COMPONENT:'Настройка подсказок экрана'
   },
+  countdownConfig:{
+    countDownItmes:'Проект обратного отсчета',
+    countDownTimes:'Время обратного отсчета',
+    addNewItem:'Новый проект',
+    addNewTimeItem:'Добавить элемент времени',
+    numberRequired:'Необходимо ввести числа',
+    errorTip:'Часы и секунды» должны иметь по крайней мере один элемент больше 0',
 
+  },
+  screenTip:{
+    tipAdd:'Новые подсказки',
+    tipEdit:'Правка подсказок',
+    showText:'Показать контент',
+    textColor:' Цвет текста',
+    textSize:'Размер текста',
+    screenBgColor:'Цвет фона экрана',
+    displayMinutes:'Максимальное время отображения (минут)',
+    displayLongest:'Максимальное время показа',
+    boolScroll:'Показывать ли прокрутку',
+    scrollDirect:'Направление прокрутки',
+    leftToRight:'Слева направо',
+    rightToLeft:'Справа налево',
+    upToDown:'сверху донизу',
+    downToUp:'Внизу вверх',
+    showTextRequired:'Показать текст должен быть заполнен',
+    scrollDirectRequired:' Направление прокрутки должно быть выбрано',
+    displayMinutesRequired:'Максимальное время отображения должно быть заполнено',
+    textSizeRequired:'Размер текста должен быть заполнен',
+    numberRequired:'Необходимо ввести числа'
+  },
   entraceguardUser:{
     named: 'Имя пользователя',
     idNo:'Номер удостоверения личности',

+ 34 - 1
languages/zh-CN.js

@@ -995,7 +995,10 @@ module.exports = {
     hisManage: 'his查询',
     interactionChars: '交互统计',
     partSetting: '机构设置',
-    functionRoleMapping:'功能角色设置',
+    functionRoleMapping:'组件权限配置',
+    countdownConfig:'倒计时组件配置',
+    screentip:'屏幕提示语组件配置',
+    bedsideInteration:'床旁交互组件',
     interactionChain:'交互接收顺序',
     allClerk: '所有员工',
     allCustomer: '所有用户',
@@ -1156,6 +1159,36 @@ module.exports = {
     ROOMCHECK_COMPONENT:'巡房',
     SCREEN_TIP_SET_COMPONENT:'设置屏幕提示语'
   },
+  countdownConfig:{
+    countDownItmes:'倒计时项目',
+    countDownTimes:'倒计时时间项',
+    addNewItem:'新项目',
+    addNewTimeItem:'添加时间项',
+    numberRequired:'必须输入数字',
+    errorTip:'时分秒必须至少有一项大于0',
+
+  },
+  screenTip:{
+    tipAdd:'新增提示语',
+    tipEdit:'编辑提示语',
+    showText:'显示内容',
+    textColor:'文字颜色',
+    textSize:'文字大小',
+    screenBgColor:'屏幕背景色',
+    displayMinutes:'最长显示时间(分钟)',
+    displayLongest:'最长显示时间',
+    boolScroll:'是否滚动显示',
+    scrollDirect:'滚动方向',
+    leftToRight:'从左到右',
+    rightToLeft:'从右到左',
+    upToDown:'从上到下',
+    downToUp:'从下到上',
+    showTextRequired:'显示文字必须填写',
+    scrollDirectRequired:'滚动方向必须选择',
+    displayMinutesRequired:'最长显示时间必须填写',
+    textSizeRequired:'文字大小必须填写',
+    numberRequired:'必须输入数字'
+  },
   clerkFrameManage:{
     employeeView:'职员视图',
     frameView:'空间视图',

+ 3 - 2
package.json

@@ -16,6 +16,7 @@
   },
   "dependencies": {
     "@moefe/vue-aplayer": "^2.0.0-beta.5",
+    "@toast-ui/editor": "^3.1.3",
     "ag-grid-community": "^25.0.0",
     "ag-grid-vue": "^25.0.0",
     "axios": "0.18.1",
@@ -45,7 +46,7 @@
     "screenfull": "4.2.0",
     "script-loader": "0.7.2",
     "sortablejs": "1.8.4",
-    "@toast-ui/editor": "^3.1.3",
+    "vant": "^2.12.54",
     "vcolorpicker": "^1.0.3",
     "vue": "2.6.10",
     "vue-baidu-map": "^0.21.22",
@@ -53,13 +54,13 @@
     "vue-count-to": "^1.0.13",
     "vue-draggable-resizable": "^2.3.0",
     "vue-i18n": "^8.26.1",
+    "vue-lazyload": "^1.2.6",
     "vue-property-decorator": "^9.1.2",
     "vue-qr": "^3.2.4",
     "vue-router": "3.0.2",
     "vue-seamless-scroll": "^1.1.23",
     "vue-splitpane": "1.0.4",
     "vuedraggable": "^2.20.0",
-    "vue-lazyload": "^1.2.6",
     "vuex": "3.1.0",
     "xlsx": "0.14.1"
   },

+ 56 - 0
src/api/ncs_screentip.js

@@ -0,0 +1,56 @@
+import request from '@/utils/request'
+
+/**
+ * 屏幕提示语设置相关接口
+ * @param params
+ * @returns {*|Promise|Promise<unknown>}
+ */
+export function getList(params) {
+    return request({
+        url: '/ncs/screentip/page',
+        method: 'POST',
+        loading: true,
+        data: params,
+        headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
+    })
+}
+
+/** 新增屏幕提示语设置 */
+export function add(params) {
+    return request({
+        url: '/ncs/screentip',
+        method: 'POST',
+        loading: true,
+        data: params
+    })
+}
+
+/** 删除屏幕提示语设置 */
+export function remove(params) {
+    const ids = params.toString()
+    return request({
+        url: `/ncs/screentip/${ids}`,
+        method: 'DELETE',
+        loading: true,
+        data: params
+    })
+}
+
+/** 更新屏幕提示语设置 */
+export function update(id, params) {
+    return request({
+        url: `/ncs/screentip/${id}`,
+        method: 'put',
+        data: params
+    })
+}
+
+/** 查询屏幕提示语设置 */
+export function get(id, params) {
+    return request({
+        url: `/ncs/screentip/${id}`,
+        method: 'get',
+        loading: false,
+        params
+    })
+}

Разница между файлами не показана из-за своего большого размера
+ 1 - 0
src/icons/svg/countdown.svg


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
src/icons/svg/devices.svg


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
src/icons/svg/infomation_board.svg


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
src/icons/svg/screen_tip.svg


+ 7 - 0
src/main.js

@@ -49,9 +49,16 @@ if (process.env.NODE_ENV === 'production') {
 // 全局注册echarts、jsonp
 import * as echarts from 'echarts'
 import 'echarts/theme/vintage.js'
+import Grid from 'vant/lib/grid';
+import GridItem from 'vant/lib/grid-item'
+import 'vant/lib/grid/style'
+import 'vant/lib/grid-item/style'
+
 
 Vue.prototype.$echarts = echarts
 Vue.component('AgGridVue', AgGridVue)
+Vue.component('Grid',Grid)
+Vue.component('GridItem',GridItem)
 Vue.use(vcolorpicker)
 Vue.use(Components)
 Vue.use(scroll)

+ 94 - 56
src/router/index.js

@@ -109,12 +109,12 @@ export const partRoutes = [
     ]
   },
   {
-    path: '/',
+    path: '/device',
     component: Layout,
     name: 'part-device',
     meta: {
-      title: i18n.t('tab.deviceManage'),
-      icon: 'component'
+      title: i18n.t('deviceManage.deviceManage'),
+      icon: 'devices'
     },
     children: [
       {
@@ -147,6 +147,20 @@ export const partRoutes = [
         name: 'myMapHtml',
         meta: { title: i18n.t('customerManage.footprint'), icon: 'area', noCache: true }, // 足迹
         hidden: true
+      },
+      {
+        path: 'information-board',
+        component: () => import('@/views/calling-board/index'),
+        name: 'CallingBoard',
+        meta: { title: i18n.t('tab.boardManage'), icon: 'infomation_board', noCache: true },
+        hidden: uiVersion === 2
+      },
+      {
+        path: 'custom-infoboard',
+        component: () => import('@/views/custom-infoboard/board-title'),
+        name: 'BoardTitle',
+        meta: { title: i18n.t('tab.customBoardManage'), icon: 'designer', noCache: true },
+        hidden: uiVersion === 2
       }
     ]
   },
@@ -432,35 +446,35 @@ export const partRoutes = [
     ],
     hidden: uiVersion !== 1
   },
-  {
-    path: '/calling-board',
-    component: Layout,
-    redirect: '/calling-board/index',
-    children: [
-      {
-        path: 'index',
-        component: () => import('@/views/calling-board/index'),
-        name: 'CallingBoard',
-        meta: { title: i18n.t('tab.boardManage'), icon: 'el-icon-data-board', noCache: true }
-      }
-    ],
-    hidden: uiVersion === 2
-  },
+  // {
+  //   path: '/calling-board',
+  //   component: Layout,
+  //   redirect: '/calling-board/index',
+  //   children: [
+  //     {
+  //       path: 'index',
+  //       component: () => import('@/views/calling-board/index'),
+  //       name: 'CallingBoard',
+  //       meta: { title: i18n.t('tab.boardManage'), icon: 'el-icon-data-board', noCache: true }
+  //     }
+  //   ],
+  //
+  // },
 
-  {
-    path: '/board-title',
-    component: Layout,
-    redirect: '/custom-infoboard/board-title',
-    children: [
-      {
-        path: 'index',
-        component: () => import('@/views/custom-infoboard/board-title'),
-        name: 'BoardTitle',
-        meta: { title: i18n.t('tab.customBoardManage'), icon: 'designer', noCache: true }
-      }
-    ],
-    hidden: uiVersion === 2
-  },
+  // {
+  //   path: '/board-title',
+  //   component: Layout,
+  //   redirect: '/custom-infoboard/board-title',
+  //   children: [
+  //     {
+  //       path: 'index',
+  //       component: () => import('@/views/custom-infoboard/board-title'),
+  //       name: 'BoardTitle',
+  //       meta: { title: i18n.t('tab.customBoardManage'), icon: 'designer', noCache: true }
+  //     }
+  //   ],
+  //   hidden: uiVersion === 2
+  // },
   {
     path: '/calling-board-designer',
     component: Layout,
@@ -516,45 +530,69 @@ export const partRoutes = [
       }
     ]
   },
+  // {
+  //   path: '/function-mapping',
+  //   component: Layout,
+  //   redirect: '/function-mapping/index',
+  //   children: [
+  //
+  //   ]
+  // },
   {
-    path: '/function-mapping',
+    path: '/components',
     component: Layout,
-    redirect: '/function-mapping/index',
+    meta: {
+      title: i18n.t('tab.bedsideInteration'),
+      icon: 'component'
+    },
     children: [
       {
-        path: 'index',
+        path: '/function-mapping/index',
         component: () => import('@/views/function-mapping/index'),
         name: 'functionMapping',
         meta: { title: i18n.t('tab.functionRoleMapping'), icon: 'function', noCache: true }
-      }
-    ]
-  },
-  {
-    path: '/countdown-config',
-    component: Layout,
-    redirect: '/ncs-countdown-config/index',
-    children: [
-      {
-        path: 'index',
-        component: () => import('@/views/ncs-countdown-config/index'),
-        name: 'countdownConfig',
-        meta: { title: i18n.t('tab.functionRoleMapping'), icon: 'function', noCache: true }
-      }
-    ]
-  },
-  {
-    path: '/interaction-chain',
-    component: Layout,
-    redirect: '/interaction-chain/index',
-    children: [
+      },
       {
-        path: 'index',
+        path: '/interaction-chain/index',
         component: () => import('@/views/interaction-chain/index'),
         name: 'interactionChain',
         meta: { title: i18n.t('tab.interactionChain'), icon: 'squence', noCache: true }
+      },
+      {
+        path: '/countdonw/index',
+        component: () => import('@/views/ncs-countdown-config/index'),
+        name: 'countdownConfig',
+        meta: { title: i18n.t('tab.countdownConfig'), icon: 'countdown', noCache: true }
+      },
+      {
+        path: '/screentip/index',
+        component: () => import('@/views/ncs-screentip/index'),
+        name: 'screenTip',
+        meta: { title: i18n.t('tab.screentip'), icon: 'screen_tip', noCache: true }
       }
     ]
   },
+  // {
+  //   path: '/screen-tip',
+  //   component: Layout,
+  //   redirect: '/ncs-screentip/index',
+  //   children: [
+  //     {
+  //       path: 'index',
+  //       component: () => import('@/views/ncs-screentip/index'),
+  //       name: 'screenTip',
+  //       meta: { title: i18n.t('tab.screentip'), icon: 'screen_tip', noCache: true }
+  //     }
+  //   ]
+  // },
+  // {
+  //   path: '/interaction-chain',
+  //   component: Layout,
+  //   redirect: '/interaction-chain/index',
+  //   children: [
+  //
+  //   ]
+  // },
   {
     path: '/calling-setting',
     component: Layout,

+ 1 - 1
src/views/ncs-channel/index.vue

@@ -452,7 +452,7 @@ export default {
       this.getList()
     },
 
-    handEdit(row) {
+    handleEdit(row) {
       this.formmodel = {
         ...row
       }

+ 2 - 2
src/views/ncs-clerk-frame-manage/components/employeeView.vue

@@ -81,7 +81,7 @@
                                      :label="group[0]" :name="'zone-'+idx">
                             <el-scrollbar wrap-class="scrollbar-wrapper" :style="{height: (asideHeight-171)+'px'}">
                                 <div style="padding: 0 15px">
-                            <el-row v-if="group[1].length > 1" :gutter="20" type="flex">
+                            <el-row v-if="group[1].length > 0" :gutter="20" type="flex">
                                 <el-col v-for="(item,index) in group[1]" :key="index" :xs="6" :sm="6" :md="4" :lg="4"
                                         :xl="4">
                                     <el-card class="box-card">
@@ -186,7 +186,7 @@
                                      :label="group[0]" :name="'zone-'+idx">
                             <el-scrollbar wrap-class="scrollbar-wrapper" :style="{height: (asideHeight-171)+'px'}">
                                 <div style="padding: 0 15px">
-                                    <el-row v-if="group[1].length > 1" :gutter="20" type="flex">
+                                    <el-row v-if="group[1].length > 0" :gutter="20" type="flex">
                                         <el-col v-for="(item,index) in group[1]" :key="index" :xs="8" :sm="8" :md="6"
                                                 :lg="4" :xl="4">
                                             <el-card class="box-card">

+ 75 - 31
src/views/ncs-countdown-config/index.vue

@@ -3,13 +3,13 @@
     <el-card style="margin: 15px" :style="{height: mainHeight +'px'}">
         <el-form ref="editform"  label-width="140px" :model="model">
             <fieldset>
-                <legend>倒计时项目</legend>
+                <legend>{{this.$t('countdownConfig.countDownItmes')}}</legend>
                 <el-tag
                         :key="tag"
-                        v-for="tag in model.countdown_items"
+                        v-for="(tag,index) in model.countdown_items"
                         closable
                         :disable-transitions="false"
-                        @close="handleClose(tag)">
+                        @close="handleClose(index)">
                     {{tag}}
                 </el-tag>
                 <el-input
@@ -22,41 +22,32 @@
                         @blur="handleInputConfirm"
                 >
                 </el-input>
-                <el-button v-else class="button-new-tag" size="small" @click="showInput">+ 新项目</el-button>
+                <el-button v-else class="button-new-tag" size="small" @click="showInput">+ {{this.$t('countdownConfig.addNewItem')}}</el-button>
             </fieldset>
 
             <fieldset class="margin-top-sm">
-                <legend>倒计时时间项</legend>
+                <legend>{{this.$t('countdownConfig.countDownTimes')}}</legend>
                 <el-tag
-                        :key="tag"
-                        v-for="tag in model.countdown_times"
+                        :key="tag.time_display"
+                        v-for="(tag,index) in model.countdown_times"
                         closable
                         :disable-transitions="false"
-                        @close="handleClose(tag.timeDisplay)">
-                    {{tag.timeDisplay}}
+                        @close="handleCloseTimeItem(index)">
+                    {{tag.time_display}}
                 </el-tag>
 
-                <el-form :inline="true" :model="formInline" class="demo-form-inline margin-top-sm"  >
-                    <el-form-item >
-                        <el-input v-model="formInline.hour" placeholder="小时"><span slot="append">时</span></el-input>
-                    </el-form-item>
-                    <el-form-item >
-                        <el-input v-model="formInline.minute" placeholder="分钟"><span slot="append">分</span></el-input>
-                    </el-form-item>
-                    <el-form-item >
-                        <el-input v-model="formInline.second" placeholder="秒"><span slot="append">秒</span></el-input>
+                <el-form :inline="true" :rules="inlineRule" ref="formInline" :model="formInline" class="demo-form-inline margin-top-sm"  >
+                    <el-form-item prop="hour">
+                        <el-input v-model.number="formInline.hour" placeholder="小时"><span slot="append">{{this.$t('action.time2')}}</span></el-input>
                     </el-form-item>
-                    <el-form-item >
-                        <el-input v-model="formInline.second" placeholder="秒"><span slot="append">秒</span></el-input>
+                    <el-form-item prop="minute">
+                        <el-input v-model.number="formInline.minute" placeholder="分钟"><span slot="append">{{this.$t('action.minute2')}}</span></el-input>
                     </el-form-item>
-                    <el-form-item >
-                        <el-input v-model="formInline.second" placeholder="秒"><span slot="append">秒</span></el-input>
-                    </el-form-item>
-                    <el-form-item >
-                        <el-input v-model="formInline.second" placeholder="秒"><span slot="append">秒</span></el-input>
+                    <el-form-item prop="second">
+                        <el-input v-model.number="formInline.second" placeholder="秒"><span slot="append">{{this.$t('action.second')}}</span></el-input>
                     </el-form-item>
                     <el-form-item>
-                        <el-button type="primary" @click="addTimeItem">添加时间项</el-button>
+                        <el-button type="primary" @click="addTimeItem">{{this.$t('countdownConfig.addNewTimeItem')}}</el-button>
                     </el-form-item>
                 </el-form>
 
@@ -65,6 +56,7 @@
                 <el-button type="success" @click="onSubmit">{{ this.$t('partInfo.saveSettings') }}</el-button>
             </el-form-item>
         </el-form>
+
     </el-card>
 
     </div>
@@ -73,6 +65,8 @@
 
 <script>
     import * as API_CountdownConfig from '@/api/ncs_countdown_config'
+
+
     export default {
         name: "index",
         computed: {
@@ -85,17 +79,30 @@
                 model:{},
                 inputVisible: false,
                 inputValue: '',
-                formInline:{}
+                formInline:{
+                    hour: 0,
+                    minute: 0,
+                    second: 0
+
+                },
+                inlineRule:{
+                   hour:[{ required: false }, { type: 'number', message: this.$t('countdownConfig.numberRequired')}],
+                    minute:[ { required: false }, { type: 'number', message: this.$t('countdownConfig.numberRequired')}],
+                    second:[ { required: false }, { type: 'number', message: this.$t('countdownConfig.numberRequired')}]
+                }
             }
         },
         mounted(){
             this.getCountDownByPartId()
         },
         methods:{
-            handleClose(tag) {
-                this.model.countdown_items.splice(this.model.countdown_items.indexOf(tag), 1);
+            handleClose(index) {
+                this.model.countdown_items.splice(index, 1);
             },
 
+            handleCloseTimeItem(index){
+                this.model.countdown_times.splice(index, 1);
+            },
             showInput() {
                 this.inputVisible = true;
                 this.$nextTick(_ => {
@@ -116,11 +123,43 @@
                     const {countdown_items,countdown_times}=res
                     this.model={...res,countdown_items:JSON.parse(countdown_items),countdown_times:JSON.parse(countdown_times)}
                 })
+            },
+            addTimeItem(){
+                this.$refs['formInline'].validate((valid) => {
+                    if (valid) {
+                       const {hour,minute,second} = this.formInline
+                        if(hour===0&&minute===0&&second===0){
+                            this.$message.error(this.$t('countdownConfig.errorTip'))
+                            return false
+                        }
+                        const seconds = hour*60*60+minute*60+second
+                        const display =(hour>0?hour+this.$t('action.time2'):'')+(minute>0?minute+this.$t('action.minute2'):'')+(second>0?second+this.$t('action.second'):'')
+                        this.model.countdown_times.push({
+                            time_display:display,
+                            time_seconds:seconds
+                        })
+
+
+                    } else {
+                        this.$message.error(this.$t('action.fromError'))
+                        return false;
+                    }
+                });
+            },
+            onSubmit(){
+                const {countdown_items,countdown_times}=this.model
+            API_CountdownConfig.update(this.model.id,{...this.model,countdown_items:JSON.stringify(countdown_items),countdown_times:JSON.stringify(countdown_times)}).then(res=>{
+                this.$message.success(this.$t('action.saveSuccess'))
+            }).catch(err=>{
+                this.$message.error(this.$t('action.saveFailed'))
+            })
             }
         }
 
     }
 
+
+
 </script>
 
 <style scoped>
@@ -147,7 +186,12 @@
     .margin-top-sm{
         margin-top: 20px;
     }
-    /deep/ .el-input-group{
-        width: 60%;
+
+    /deep/.van-grid-item__content::after{
+        border: 0 !important;
     }
+    /deep/ .van-grid-item__content--center{
+      box-shadow:   1px 0 0 0 #e8eaec, 0 1px 0 0 #e8eaec, 1px 1px 0 0 #e8eaec, inset 1px 0 0 0 #e8eaec, inset 0 1px 0 0 #e8eaec
+    }
+
 </style>

+ 799 - 0
src/views/ncs-screentip/index.vue

@@ -0,0 +1,799 @@
+<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"
+                :enable-cell-change-flash="true"
+                @filterChanged="filterModifed"
+                @sortChanged="gridSortChange"
+        >
+            <!--        @rowDoubleClicked="getList"-->
+            <div slot="toolbar" class="inner-toolbar">
+                <div class="toolbar-search">
+                    <en-table-search :placeholder="this.$t('action.keywords')" @search="handlerSearch" />
+                </div>
+                <div class="toolbar-btns">
+                    <el-button type="primary" size="mini" @click="createScreenTip">{{ this.$t('screenTip.tipAdd') }}</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.sync="formtitle" :visible.sync="formshow" width="35%">
+            <div>
+                <el-form ref="editform" :rules="rules" label-width="120px" :model="formmodel">
+
+                    <el-row>
+                        <el-col :span="24">
+                            <el-form-item :label="this.$t('screenTip.showText')" prop="show_text">
+                                <el-input
+                                        v-model="formmodel.show_text"
+                                        clearable
+                                        :maxlength="100"
+                                        :placeholder="this.$t('screenTip.showText')"
+                                />
+                            </el-form-item>
+                            <el-form-item :label="this.$t('screenTip.textColor')">
+                                <el-input :placeholder="this.$t('screenTip.textColor')" v-model="formmodel.text_color">
+                                    <el-color-picker slot="append" color-format="hex" v-model="formmodel.text_color" size="mini"></el-color-picker>
+                                </el-input>
+
+                            </el-form-item>
+                            <el-form-item prop="text_size" :label="this.$t('screenTip.textSize')">
+                                <el-input v-model.number="formmodel.text_size" :placeholder="this.$t('screenTip.textSize')"><span slot="append">dp</span></el-input>
+                            </el-form-item>
+
+                            <el-form-item :label="this.$t('screenTip.screenBgColor')">
+                                <el-input :placeholder="this.$t('screenTip.screenBgColor')" v-model="formmodel.screen_bg_color">
+                                    <el-color-picker slot="append" color-format="hex" v-model="formmodel.screen_bg_color" size="mini"></el-color-picker>
+                                </el-input>
+
+                            </el-form-item>
+                            <el-form-item prop="display_minutes" :label="this.$t('screenTip.displayLongest')">
+                                <el-input v-model.number="formmodel.display_minutes" :placeholder="this.$t('screenTip.displayLongest')"><span slot="append">{{this.$t('action.minute2')}}</span></el-input>
+                            </el-form-item>
+                            <el-form-item prop="bool_scroll" >
+                                <el-checkbox v-model="formmodel.bool_scroll" @change="scrollChange">{{this.$t('screenTip.boolScroll')}}</el-checkbox>
+                            </el-form-item>
+                            <el-form-item :label="this.$t('screenTip.scrollDirect')" prop="scroll_direct">
+                                <el-select v-model="formmodel.scroll_direct"
+                                           :placeholder="this.$t('screenTip.scrollDirect')"
+                                           filterable clearable >
+                                    <el-option v-for="(item,index) in animateRender" :key="index" :label="item.key" :value="item.value" />
+                                </el-select>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                </el-form>
+
+            </div>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click="formshow = false">{{ this.$t('action.cancel') }}</el-button>
+                <el-button type="primary" @click="handlerFormSubmit('editform')">{{ this.$t('action.yes') }}</el-button>
+            </div>
+        </el-dialog>
+<!--        <el-dialog :title.sync="subscribeTitle" :visible.sync="formSubscribe" width="50%">-->
+
+<!--            <div>-->
+<!--                <fieldset v-for="(item,index) in channelSubscribers" v-if="item.roleName!=='管理员'" :key="index" style="margin-top: 10px">-->
+<!--                    <legend><span style="margin-right: 10px">{{ item.roleName }} </span><el-checkbox v-model="item.allCkeck" style="float: right;" :indeterminate="item.indeterminate" @change="(checked)=>{handleCheckAll(checked,item)}">{{ choiceAll }}</el-checkbox></legend>-->
+<!--                    <el-row :gutter="20" type="flex" style="padding: 10px">-->
+<!--                        <el-col :span="24">-->
+<!--                            <el-checkbox v-for="(clerk,_index) in item.clerks" :key="_index" v-model="clerk.checked" @change="handleCheckboxChanged(item)">{{ clerk.clerk_name }}</el-checkbox>-->
+<!--                        </el-col>-->
+<!--                    </el-row>-->
+<!--                </fieldset>-->
+<!--            </div>-->
+<!--            <div slot="footer" class="dialog-footer">-->
+<!--                <el-button @click="formSubscribe = false">{{ this.$t('action.cancel') }}</el-button>-->
+<!--                <el-button type="primary" @click="handlerSubscribeSubmit">{{ this.$t('action.yes') }}</el-button>-->
+<!--            </div>-->
+<!--        </el-dialog>-->
+    </div>
+</template>
+
+<script>
+    import { AG_GRID_LOCALE_CN } from '@/utils/AgGridVueLocaleCn'
+    import ButtonCellRender from '../../components/AgGridCellRender/ButtonCellRender'
+    import * as API_ScreenTip from '@/api/ncs_screentip'
+    import { unix2Date } from '@/utils/Foundation'
+    import * as API_Clerk from '@/api/ncs_clerk'
+    import ListFilter from '@/components/AgGridCustomFilter/ListFilter'
+    import RadioFilter from '@/components/AgGridCustomFilter/RadioFilter'
+    import ButtonCellRenderList from "@/components/AgGridCellRender/ButtonCellRenderList";
+    export default {
+        name: "index",
+        components: { ButtonCellRenderList, ButtonCellRender, ListFilter, RadioFilter },
+        data() {
+            return {
+                tableData: [],
+                /** 列表参数 */
+                params: {
+                    page_size: 20,
+                    page_no: 1,
+                    fixedCondition: ' part_id = ' + this.$store.getters.partId
+                },
+                /** 新建组织弹出参数 **/
+                formtitle: this.$t('screenTip.tipAdd'),
+                formshow: false,
+                /** 频道订阅设置 */
+                // formSubscribe: false,
+                formmodel: {},
+                // frameGroups: [],
+                rules: {
+                    show_text: [
+                        { required: true, message: this.$t('screenTip.showTextRequired'), trigger: 'blur' }
+                    ],
+                    scroll_direct:[{ required: false, message: this.$t('screenTip.scrollDirectRequired'), trigger: 'blur' }],
+                    display_minutes:[{ required: true, message: this.$t('screenTip.displayMinutesRequired'), trigger: 'blur' },{ type: 'number', message: this.$t('screenTip.numberRequired')}],
+                    text_size:[{ required: true, message: this.$t('screenTip.textSizeRequired'), trigger: 'blur' },{ type: 'number', message: this.$t('screenTip.numberRequired')}]
+                },
+                // timeRange: [new Date(2020, 11, 11, 7, 0), new Date(2020, 11, 11, 8, 0)],
+                // checkWeek: [],
+                /** ag-grid参数 **/
+                pageData: [],
+                loading: false,
+                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,
+                /** 频道订阅者情况数组 */
+                // channelSubscribers: [],
+                // subscribeTitle: '',
+                choiceAll: this.$t('action.choiceAll'),
+                booleanRender: [
+                    { key: this.$t('entraceguardUser.yes'), value: true, color: 'green' },
+                    { key: this.$t('entraceguardUser.nop'), value: false, color: 'red' }
+                ],
+                animateRender:[
+                    {key:this.$t('screenTip.leftToRight'),value:1},
+                    {key:this.$t('screenTip.rightToLeft'),value:2},
+                    {key:this.$t('screenTip.upToDown'),value:3},
+                    {key:this.$t('screenTip.downToUp'),value:4}
+                ]
+            }
+        },
+        computed: {
+            tableHeight() {
+                return this.mainAreaHeight - 130
+            }
+
+        },
+        beforeMount() {
+            this.gridOptions = {}
+            this.columnDefs = [
+                {
+                    headerName: '#',
+                    headerCheckboxSelection: true,
+                    headerCheckboxSelectionFilteredOnly: true,
+                    checkboxSelection: true,
+                    sortable: false, filter: false,
+                    width: 100,
+                    resizable: false,
+                    valueGetter: this.hashValueGetter
+                },
+                { headerName: 'ID', field: 'id', sortable: true, filter: 'agNumberColumnFilter', width: 130 },
+                {
+                    headerName: this.$t('screenTip.showText'), field: 'show_text', sortable: true, filter: 'agTextColumnFilter', flex: 1,
+                    cellRenderer: (para) => {
+                        return this.textShow(para)
+                    }
+                },
+                {
+                    headerName: this.$t('screenTip.textColor'), field: 'text_color', sortable: true, filter: 'agTextColumnFilter',  width: 130,
+                    cellRenderer: (para) => {
+                        return this.colorFormatter(para)
+                    }
+                },
+                {
+                    headerName: this.$t('screenTip.textSize'), field: 'text_size', sortable: true, filter: 'agNumberColumnFilter',  width: 130
+                },
+                {
+                    headerName: this.$t('screenTip.screenBgColor'), field: 'screen_bg_color', sortable: true, filter: 'agTextColumnFilter',  width: 130,
+                    cellRenderer: (para) => {
+                        return this.colorFormatter(para)
+                    }
+                },
+                {
+                    headerName: this.$t('screenTip.displayMinutes'), field: 'display_minutes', sortable: true, filter: 'agNumberColumnFilter',  width: 180
+                },
+                {
+                    headerName: this.$t('screenTip.boolScroll'), field: 'bool_scroll', sortable: true, filterFramework: 'RadioFilter', filterParams: {
+                        listData: this.booleanRender
+                    }, width: 150,
+                    cellRenderer: (para) => {
+                        return this.radioFilterFormatter(para, this.booleanRender)
+                    }
+                },
+
+                {
+                    headerName: this.$t('screenTip.scrollDirect'), field: 'scroll_direct', sortable: true, filterFramework: 'ListFilter', filterParams: {
+                        listData: this.animateRender
+                    }, width: 150,
+                    cellRenderer: (para) => {
+                        return this.scrollDirectFormatter(para, this.animateRender)
+                    }
+                },
+                // {
+                //     headerName: this.$t('screenTip.boolScroll'), field: 'bool_scroll', sortable: true, filter: 'agTextColumnFilter',  width: 130
+                // },
+
+                // lockPosition 锁定位置,会在第一列
+                // lockPinned = true 不能拖动然后固定
+                // resizeable 单元个大小是否可以调整
+
+                { headerName: this.$t('action.handle'), field: 'id',
+                    cellRendererFramework: 'ButtonCellRenderList',
+                    cellRendererParams: param => {
+                        return {
+                            list: [
+                                {
+                                    onClick: this.handleEdit,
+                                    label: this.$t('action.edit'),
+                                    buttonType: 'primary',
+                                    buttonSize: 'mini'
+                                },
+                                // {
+                                //     onClick: this.manageSubscribe,
+                                //     label: this.$t('channel.subscribeManage'),
+                                //     buttonType: 'warning',
+                                //     buttonSize: 'mini',
+                                // },
+                                // {
+                                //     onClick: this.channelImHistory,
+                                //     label: this.$t('channel.channelImHistory'),
+                                //     buttonType: 'success',
+                                //     buttonSize: 'mini',
+                                // },
+                                {
+                                    onClick: this.deleteSingle,
+                                    label: this.$t('action.delete'),
+                                    buttonType: 'danger',
+                                    buttonSize: 'mini',
+                                }
+                            ]}
+                    },
+                    filter: false,
+                    pinned: 'right',
+                    lockPinned: true,
+                    minWidth: this.$i18n.locale === 'zh' ? 200 : 300,
+                    resizable: false,
+                    sortable: false
+                }
+                // {
+                //   headerName: this.$t('action.edit'), field: 'id',
+                //   cellRendererFramework: 'ButtonCellRender',
+                //   cellRendererParams: {
+                //     onClick: this.handEdit,
+                //     label: this.$t('action.edit'),
+                //     buttonType: 'primary',
+                //     buttonSize: 'mini'
+                //   },
+                //   filter: false,
+                //   pinned: 'right',
+                //   lockPinned: true,
+                //   width: 100,
+                //   resizable: false,
+                //   sortable: false
+                // },
+                //
+                // {
+                //   headerName: this.$t('channel.subscribeManage'), field: 'id',
+                //   cellRendererFramework: 'ButtonCellRender',
+                //   cellRendererParams: {
+                //     onClick: this.manageSubscribe,
+                //     label: this.$t('channel.subscribeManage'),
+                //     buttonType: 'success',
+                //     buttonSize: 'mini'
+                //   },
+                //   filter: false,
+                //   pinned: 'right',
+                //   lockPinned: true,
+                //   width: 100,
+                //   resizable: false,
+                //   sortable: false
+                // },
+                //
+                // {
+                //   headerName: "留言历史", field: 'id',
+                //   cellRendererFramework: 'ButtonCellRender',
+                //   cellRendererParams: {
+                //     onClick: this.channelImHistory,
+                //     label: "留言历史",
+                //     buttonType: 'success',
+                //     buttonSize: 'mini'
+                //   },
+                //   filter: false,
+                //   pinned: 'right',
+                //   lockPinned: true,
+                //   width: 100,
+                //   resizable: false,
+                //   sortable: false
+                // },
+                //
+                // {
+                //   headerName: this.$t('action.delete'), field: 'id',
+                //   cellRendererFramework: 'ButtonCellRender',
+                //   cellRendererParams: param => {
+                //     return {
+                //       onClick: this.deleteSingle,
+                //       label: this.$t('action.delete'),
+                //       buttonType: 'danger',
+                //       buttonSize: 'mini'
+                //     }
+                //   },
+                //   pinned: 'right',
+                //   lockPinned: true,
+                //   width: 100,
+                //   resizable: false,
+                //   filter: false,
+                //   sortable: false
+                // }
+            ]
+            this.defaultColDef = {
+                sortable: true,
+                resizable: true,
+                comparator: this.dateCustomComparator,
+                filterParams: {
+                    debounceMs: 200,
+                    newRowsAction: 'keep',
+                    textCustomComparator: this.textCustomComparator,
+                    comparator: this.dateCustomComparator
+                }
+            }
+            this.rowSelection = 'multiple'
+        },
+        mounted() {
+            window.onresize = this.windowResize
+            this.gridApi = this.gridOptions.api
+            this.gridColumnApi = this.gridOptions.columnApi
+            // 设置默认排序字段,应用列状态之后会触发 gridSortChange 函数,会调用getlist,后面不需要再调用this.getlist
+            this.gridColumnApi.applyColumnState({
+                state: [
+                    {
+                        colId: 'id',
+                        sort: 'asc'
+                    }
+                ]
+            })
+            // this.getEmployees()
+        },
+        methods: {
+            windowResize() {
+                this.$set(this, 'mainAreaHeight', Number(document.documentElement.clientHeight) - 84)
+            },
+            handlerDelete(ids) {
+                this.$confirm(this.$t('action.sureDelete'), this.$t('action.waring'), {
+                    confirmButtonText: this.$t('action.yes'),
+                    cancelButtonText: this.$t('action.cancel'),
+                    type: 'warning'
+                }).then(() => {
+                    API_ScreenTip.remove(ids).then(
+                        response => {
+                            this.getList()
+                            this.$message({
+                                type: 'success',
+                                message: this.$t('action.deleted')
+                            })
+                        }
+                    ).catch(response => {
+                        this.$message({
+                            type: 'info',
+                            message: response.message
+                        })
+                    })
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: this.$t('action.cancelDelete')
+                    })
+                })
+            },
+            deleteSingle(row) {
+                this.handlerDelete(row.id)
+            },
+
+            /**
+             * 创建频道
+             */
+            createScreenTip() {
+                this.formshow = true
+                this.formmodel = {
+                    text_color: '#FFFFFF',
+                    screen_bg_color:'#409EFF',
+                    part_id: this.$store.getters.partId
+                }
+            },
+            /** 分页大小发生改变 */
+            handlePageSizeChange(size) {
+                this.params.page_size = size
+                this.getList()
+            },
+
+            /** 分页页数发生改变 */
+            handlePageCurrentChange(page) {
+                this.params.page_no = page
+                this.getList()
+            },
+            /** 加载列表数据 */
+            getList() {
+                this.loading = true
+                const param = this.MixinClone(this.params)
+                this.gridApi.showLoadingOverlay()
+                API_ScreenTip.getList(param).then(response => {
+                    this.loading = false
+                    // this.tableData = [...response.data]
+                    this.pageData = {
+                        page_no: response.page_no,
+                        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.rowData = [...response.data]
+                    this.refreshPlayStatus()
+                }).catch(() => {
+                    this.loading = false
+                })
+            },
+            /** 处理搜索 */
+            handlerSearch(keywords) {
+                this.params.query = keywords
+                this.getList()
+            },
+            /** 处理字段排序 */
+            tableSort(column) {
+                if (column.order !== null) {
+                    this.params.sort = column.prop
+                    this.params.dir = column.order === 'ascending' ? 'asc' : 'desc'
+                } else {
+                    this.params.sort = null
+                    this.params.dir = null
+                }
+                this.getList()
+            },
+            /**
+             * 格式化unix时间戳
+             **/
+            unixDateFormatter(param) {
+                if (!param.value) return ''
+                return unix2Date(param.value * 1000)
+            },
+
+            gridSortChange(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()
+            },
+
+            filterModifed(param) { // todo 通过转换后的数值过滤,需要转回原始数值
+                var model = param.api.getFilterModel()
+                this.params.filter = JSON.stringify(model)
+                this.getList()
+            },
+
+            handleEdit(row) {
+                this.formmodel = {
+                    ...row
+                }
+                this.formtitle=this.$t('screenTip.tipEdit')
+                this.formshow = true
+            },
+            /**
+             * 提交新增表单
+             * @param formname
+             */
+            handlerFormSubmit(formName) {
+                this.$refs[formName].validate((valid) => {
+                    if (valid) {
+                        if (!this.formmodel.id) {
+                            /** 新增 */
+                            this.formmodel.part_id = this.$store.getters.partId
+
+                            API_ScreenTip.add(this.formmodel).then(() => {
+                                this.formshow = false
+                                this.$message.success(this.$t('action.addSuccess'))
+                                this.getList()
+                            })
+                        } else {
+                            API_ScreenTip.update(this.formmodel.id, this.formmodel).then(() => {
+                                this.formshow = false
+                                this.$message.success(this.$t('action.editSuccess'))
+                                this.getList()
+                            })
+                        }
+                    } else {
+                        this.$message.error(this.$t('action.fromError'))
+                    }
+                })
+            },
+            radioFilterFormatter(params, array) {
+                const item = array.filter(p => p.value === params.value)[0]
+                if (item) {
+                    if (item.color) {
+                        return '<span style="color:' + item.color + '">' + item.key + '</span>'
+                    } else {
+                        return item.key
+                    }
+                } else {
+                    return ''
+                }
+            },
+            scrollDirectFormatter(params,array){
+                const item = array.filter(p => p.value === params.value)[0]
+                if (item) {
+                        return item.key
+                } else {
+                    return ''
+                }
+            },
+            colorFormatter(params){
+                return '<div  style="background:' + params.value+ ';width:100%;height: 100%;"></div>'
+            },
+
+            textShow(params){
+                console.log('pms',params)
+                return '<div  style="background:' + params.data.screen_bg_color+ ';color:'+params.data.text_color+';width:100%;height: 100%;overflow: hidden;text-align: center;"><div class="'+(params.data.bool_scroll?('animate'+params.data.scroll_direct):'')+'">'+params.value+'</div></div>'
+            },
+
+            scrollChange(val){
+              this.rules.scroll_direct[0].required=val
+            },
+
+            // handlerSubscribeSubmit() {
+            //     let subscribeIds = []
+            //     this.channelSubscribers.forEach(item => {
+            //         subscribeIds = [...item.clerks.filter(p => p.checked).map(p => p.member_id), ...subscribeIds]
+            //     })
+            //     API_ScreenTip.setChannelSubscribers({ channel_id: this.formmodel.id, member_ids: subscribeIds.length === 0 ? null : [...subscribeIds] }).then(() => {
+            //         this.formSubscribe = false
+            //         this.$message.success(this.$t('action.editSuccess'))
+            //     })
+            // },
+            // manageSubscribe(row) {
+            //     this.formmodel = { ...row }
+            //     API_ScreenTip.getChannelSubscribers(row.id).then(res => {
+            //         this.channelSubscribers.forEach(item => {
+            //             item.clerks.map(k => {
+            //                 k.checked = res.map(p => p.member_id).includes(k.member_id)
+            //                 return k
+            //             })
+            //             const checkedLength = item.clerks.filter(p => p.checked).length
+            //             this.$set(item, 'allCkeck', item.clerks.length === checkedLength)
+            //             this.$set(item, 'indeterminate', (checkedLength !== 0) && (item.clerks.length !== checkedLength))
+            //         })
+            //     })
+            //     this.subscribeTitle = row.channel_name + this.$t('channel.subscribeManage')
+            //     this.formSubscribe = true
+            // },
+            // channelImHistory(row) {
+            //     this.$router.push({ name: 'channelImHistory', params: { id: row.id, callback: this.getList() }})
+            // },
+            // getEmployees() {
+            //     const _this = this
+            //     _this.nurses = []
+            //     API_Clerk.listByPartRoleId({ partId: this.$store.getters.partId }).then(res => {
+            //         _this.clerks = res
+            //         const groupBy = (arr, func) =>
+            //             arr.map(typeof func === 'function' ? func : val => val[func]).reduce((acc, val, i) => {
+            //                 acc[val] = (acc[val] || []).concat(arr[i])
+            //                 return acc
+            //             }, {})
+            //         const groupData = groupBy(res, item => item.role_name)
+            //         _this.nurses = Object.entries(groupData)
+            //
+            //         _this.nurses.forEach(item => {
+            //             this.channelSubscribers.push({ 'roleName': item[0], 'clerks': item[1].map(i => { return { ...i, 'checked': false } }), 'allCheck': false, 'indeterminate': false })
+            //         })
+            //
+            //     })
+            // },
+            handleCheckboxChanged(item) {
+                this.countAllRole(item)
+            },
+            /** 计算传入角色组的选择情况 */
+            countAllRole(role) {
+                const _list = []
+                if (!Array.isArray(role)) {
+                    if (role.clerks) _list.push(...this.countAllRole(role.clerks))
+                } else {
+                    role.forEach(item => {
+                        _list.push(item)
+                    })
+                }
+                const length = _list.length
+                const length_checked = _list.filter(_item => _item.checked).length
+                this.$set(role, 'allCkeck', length === _list.filter(_item => _item.checked).length)
+                this.$set(role, 'indeterminate', (length_checked !== 0) && (length !== length_checked))
+                return _list
+            },
+            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.clerks && item.clerks.length) {
+                        this.$set(item, 'clerks', this.setFrameCheck(item.clerks, checked))
+                    }
+                } else {
+                    perm.map(item => {
+                        item.checked = checked
+                        this.$set(item, 'checked', checked)
+                        if (item.clerks && item.clerks.length) {
+                            this.$set(item, 'clerks', this.setFrameCheck(item.clerks, checked))
+                        }
+                    })
+                }
+                return perm
+            }
+        }
+    }
+</script>
+
+<style >
+
+    .animate1 {
+         white-space: nowrap;
+         animation: 10s wordsLoop1 linear infinite normal;
+     }
+    .animate2 {
+        white-space: nowrap;
+        animation: 10s wordsLoop2 linear infinite normal;
+    }
+    .animate3 {
+        white-space: nowrap;
+        animation: 10s wordsLoop3 linear infinite normal;
+    }
+    .animate4 {
+        white-space: nowrap;
+        animation: 10s wordsLoop4 linear infinite normal;
+    }
+
+    @keyframes wordsLoop1 {
+        0% {
+            transform: translateX(-100%);
+            -webkit-transform: translateX(-100%);
+        }
+        100% {
+            transform: translateX(100%);
+            -webkit-transform: translateX(100%);
+        }
+    }
+
+    @-webkit-keyframes wordsLoop1 {
+        0% {
+            transform: translateX(-100%);
+            -webkit-transform: translateX(-100%);
+        }
+        100% {
+            transform: translateX(100%);
+            -webkit-transform: translateX(100%);
+        }
+    }
+
+    @keyframes wordsLoop2 {
+        0% {
+            transform: translateX(100%);
+            -webkit-transform: translateX(100%);
+        }
+        100% {
+            transform: translateX(-100%);
+            -webkit-transform: translateX(-100%);
+        }
+    }
+
+    @-webkit-keyframes wordsLoop2 {
+        0% {
+            transform: translateX(100%);
+            -webkit-transform: translateX(100%);
+        }
+        100% {
+            transform: translateX(-100%);
+            -webkit-transform: translateX(-100%);
+        }
+    }
+
+    @keyframes wordsLoop4 {
+        0% {
+            transform: translateY(100%);
+            -webkit-transform: translateY(100%);
+        }
+        100% {
+            transform: translateY(-100%);
+            -webkit-transform: translateY(-100%);
+        }
+    }
+
+    @-webkit-keyframes wordsLoop4 {
+        0% {
+            transform: translateY(100%);
+            -webkit-transform: translateY(100%);
+        }
+        100% {
+            transform: translateY(-100%);
+            -webkit-transform: translateY(-100%);
+        }
+    }
+
+    @keyframes wordsLoop3 {
+        0% {
+            transform: translateY(-100%);
+            -webkit-transform: translateY(-100%);
+        }
+        100% {
+            transform: translateY(100%);
+            -webkit-transform: translateY(100%);
+        }
+    }
+
+    @-webkit-keyframes wordsLoop3 {
+        0% {
+            transform: translateY(-100%);
+            -webkit-transform: translateY(-100%);
+        }
+        100% {
+            transform: translateY(100%);
+            -webkit-transform: translateY(100%);
+        }
+    }
+</style>