浏览代码

Merge branch 'master' into develop

# Conflicts:
#	src/api/ncs_device.js
wuyunfeng 2 年之前
父节点
当前提交
ff43647172

+ 4 - 1
languages/en.js

@@ -27,6 +27,7 @@ module.exports = {
     systemCreate: 'System Create',
     systemCreate: 'System Create',
     cancelHandle: 'Cancel the operation! ',
     cancelHandle: 'Cancel the operation! ',
     handleSuccess: 'The operation succeeded',
     handleSuccess: 'The operation succeeded',
+    handleFailed:'operation failed',
     saveEdit: 'Save changes',
     saveEdit: 'Save changes',
     saveSettings: 'Save settings',
     saveSettings: 'Save settings',
     deleteSettings: 'Delete settings',
     deleteSettings: 'Delete settings',
@@ -212,7 +213,9 @@ module.exports = {
     addParam: 'New parameter',
     addParam: 'New parameter',
     openWatchSosInfo: 'Whether to turn off the watch sedentary alarm. If it is turned off, the watch will not trigger the sedentary alarm again',
     openWatchSosInfo: 'Whether to turn off the watch sedentary alarm. If it is turned off, the watch will not trigger the sedentary alarm again',
     closeWatchSos: 'Turn off the watch sedentary alarm',
     closeWatchSos: 'Turn off the watch sedentary alarm',
-    openWatchSos: 'Turn on the alarm for long sitting'
+    openWatchSos: 'Turn on the alarm for long sitting',
+    opendebug:'Debug',
+    reboot:'Reboot'
   },
   },
   member: {
   member: {
     face: 'Avatar',
     face: 'Avatar',

+ 4 - 1
languages/es.js

@@ -27,6 +27,7 @@ module.exports = {
     systemCreate: 'Crear sistema',
     systemCreate: 'Crear sistema',
     cancelHandle: '¡Cancelar la operación! ',
     cancelHandle: '¡Cancelar la operación! ',
     handleSuccess: 'La operación tuvo éxito',
     handleSuccess: 'La operación tuvo éxito',
+    handleFailed:'La operación falló',
     saveEdit: 'Guardar cambios',
     saveEdit: 'Guardar cambios',
     saveSettings: 'Guardar configuración',
     saveSettings: 'Guardar configuración',
     deleteSettings: 'Eliminar configuración',
     deleteSettings: 'Eliminar configuración',
@@ -212,7 +213,9 @@ module.exports = {
     addParam: 'Nuevos parámetros',
     addParam: 'Nuevos parámetros',
     openWatchSosInfo: 'Si apagar la alarma de sedentarismo del reloj. Si se cierra, el reloj no volverá a activar la alarma sedentaria',
     openWatchSosInfo: 'Si apagar la alarma de sedentarismo del reloj. Si se cierra, el reloj no volverá a activar la alarma sedentaria',
     closeWatchSos: 'Apague la alarma de sedentarismo del reloj',
     closeWatchSos: 'Apague la alarma de sedentarismo del reloj',
-    openWatchSos: 'Sentarse durante mucho tiempo y encender la alarma'
+    openWatchSos: 'Sentarse durante mucho tiempo y encender la alarma',
+    opendebug:'depuración',
+    reboot:'reiniciar'
   },
   },
   member: {
   member: {
     face: 'Avatar',
     face: 'Avatar',

+ 4 - 1
languages/ru-RU.js

@@ -27,6 +27,7 @@ module.exports = {
     systemCreate: 'Создание системы',
     systemCreate: 'Создание системы',
     cancelHandle: 'Отменить операцию! ',
     cancelHandle: 'Отменить операцию! ',
     handleSuccess: 'Операция выполнена успешно',
     handleSuccess: 'Операция выполнена успешно',
+    handleFailed:'Ошибка операции',
     saveEdit: 'Сохранить изменения',
     saveEdit: 'Сохранить изменения',
     saveSettings: 'Сохранить настройки',
     saveSettings: 'Сохранить настройки',
     deleteSettings: 'Удалить настройки',
     deleteSettings: 'Удалить настройки',
@@ -209,7 +210,9 @@ module.exports = {
     param: 'Параметры',
     param: 'Параметры',
     inputParamName: 'Введите имя параметра',
     inputParamName: 'Введите имя параметра',
     inputParamValue: 'Введите значение параметра',
     inputParamValue: 'Введите значение параметра',
-    addParam: 'Дополнительные параметры'
+    addParam: 'Дополнительные параметры',
+    opendebug:'Отладка',
+    reboot:'Перезагрузка'
   },
   },
   member: {
   member: {
     face: 'Аватар',
     face: 'Аватар',

+ 6 - 1
languages/zh-CN.js

@@ -27,6 +27,7 @@ module.exports = {
     systemCreate: '系统创建',
     systemCreate: '系统创建',
     cancelHandle: '取消操作!',
     cancelHandle: '取消操作!',
     handleSuccess: '操作成功',
     handleSuccess: '操作成功',
+    handleFailed:'操作失败',
     saveEdit: '保存修改',
     saveEdit: '保存修改',
     saveSettings: '保存设置',
     saveSettings: '保存设置',
     deleteSettings: '清空设置',
     deleteSettings: '清空设置',
@@ -212,7 +213,9 @@ module.exports = {
     addParam: '新增参数',
     addParam: '新增参数',
     openWatchSosInfo: '是否关闭手表久坐报警,关闭的话手表不会再触发久坐报警',
     openWatchSosInfo: '是否关闭手表久坐报警,关闭的话手表不会再触发久坐报警',
     closeWatchSos: '关闭手表久坐报警',
     closeWatchSos: '关闭手表久坐报警',
-    openWatchSos: '开启手表久坐报警'
+    openWatchSos: '开启手表久坐报警',
+    opendebug:'调试',
+    reboot:'重启'
   },
   },
   member: {
   member: {
     face: '头像',
     face: '头像',
@@ -372,6 +375,8 @@ module.exports = {
     transRs485: '上属485转换盒',
     transRs485: '上属485转换盒',
     re485SipId: '485地址',
     re485SipId: '485地址',
     inputRe485SipId: '请输入485地址',
     inputRe485SipId: '请输入485地址',
+    powerControlAddress:'电源版地址',
+    controlLineNumber:'接口线路',
     sosDeviceSettingType: '报警模式',
     sosDeviceSettingType: '报警模式',
     sosDeviceSettingStatusFalse: '不开启',
     sosDeviceSettingStatusFalse: '不开启',
     sosDeviceSettingControlModel: '防控模式',
     sosDeviceSettingControlModel: '防控模式',

+ 1 - 0
package.json

@@ -38,6 +38,7 @@
     "jszip": "3.2.1",
     "jszip": "3.2.1",
     "jwt-decode": "^3.1.2",
     "jwt-decode": "^3.1.2",
     "moment": "^2.29.4",
     "moment": "^2.29.4",
+    "nanoid": "^4.0.2",
     "normalize.css": "7.0.0",
     "normalize.css": "7.0.0",
     "nprogress": "0.2.0",
     "nprogress": "0.2.0",
     "particles.js": "2.0.0",
     "particles.js": "2.0.0",

+ 18 - 0
src/api/ncs_device.js

@@ -245,6 +245,7 @@ export function update485s(data) {
     loading: true
     loading: true
   })
   })
 }
 }
+
 export function getCacheListByType(partId, deviceType) {
 export function getCacheListByType(partId, deviceType) {
   return request({
   return request({
     url: `/ncs/device/getCacheListByType/${partId}/${deviceType}`,
     url: `/ncs/device/getCacheListByType/${partId}/${deviceType}`,
@@ -252,3 +253,20 @@ export function getCacheListByType(partId, deviceType) {
     loading: true
     loading: true
   })
   })
 }
 }
+
+
+export function openDebug(id){
+  return request({
+    url: `/ncs/device/opendebug/${id}`,
+    method: 'get'
+  })
+}
+
+export function rebootDevice(id){
+  return request({
+    url: `/ncs/device/reboot/${id}`,
+    method: 'get'
+  })
+}
+
+

+ 8 - 4
src/components/AgGridCellRender/ButtonCellRender.vue

@@ -1,6 +1,6 @@
 <template>
 <template>
   <div>
   <div>
-    <el-button v-if="show" :type="buttonType" :size="buttonSize" :disabled="disabled" @click="buttonClick">{{ label }}</el-button>
+    <el-button v-if="show" :type="buttonType" :size="buttonSize" :icon="icon" :disabled="disabled" @click="buttonClick">{{ label }}</el-button>
   </div>
   </div>
 </template>
 </template>
 
 
@@ -11,18 +11,22 @@ export default {
     return {
     return {
       buttonType: 'primary',
       buttonType: 'primary',
       buttonSize: 'mini',
       buttonSize: 'mini',
-      label: 'button',
+      label: '',
       disabled: false,
       disabled: false,
-      show: true
+      show: true,
+      icon:''
     }
     }
   },
   },
   beforeMount() {
   beforeMount() {
   },
   },
   mounted() {
   mounted() {
-    const { buttonType, buttonSize, label, disabled, show } = this.params
+    const { buttonType, buttonSize, label, disabled, show,icon } = this.params
     if (buttonType) {
     if (buttonType) {
       this.buttonType = buttonType
       this.buttonType = buttonType
     }
     }
+    if (icon) {
+      this.icon = icon
+    }
     if (buttonSize) {
     if (buttonSize) {
       this.buttonSize = buttonSize
       this.buttonSize = buttonSize
     }
     }

+ 628 - 0
src/views/custom-infoboard/infoboard-designer.vue

@@ -0,0 +1,628 @@
+<template>
+    <el-container class="_fc-designer" :style="'height:'+floorContainerHeight+'px'">
+        <el-main style="height: 100%;">
+            <el-container style="height: 100%;">
+                <el-aside class="_fc-l" width="266px">
+<!--                    <template v-for="(item, index) in menuList">-->
+<!--                        <div class="_fc-l-group" :key="index">-->
+<!--                            <h4 class="_fc-l-title">{{ item.title }}</h4>-->
+<!--                            <draggable :group="{name:'default', pull:'clone',put:false}" :sort="false"-->
+<!--                                       :list="item.list">-->
+<!--                                <div class="_fc-l-item" v-for="(data, index) in item.list"-->
+<!--                                     :key="index">-->
+<!--                                    <div class="_fc-l-icon">-->
+<!--                                        <i :class="[data.icon ? (data.icon.substring(0,3) === 'el-' ? data.icon : 'fc-icon '+data.icon) : 'fc-icon icon-input']"></i>-->
+<!--                                    </div>-->
+<!--                                    <span class="_fc-l-name">{{ data.label }}</span>-->
+<!--                                </div>-->
+<!--                            </draggable>-->
+<!--                        </div>-->
+<!--                    </template>-->
+                    <draggable v-model="templateArray"  :options="tplOptions" :clone="clonedata">
+                        <div v-for="item in templateArray" :class="'item-' + item.tpl_id" class="tpl-item">
+                            <el-row>
+                                <el-col :span="24/item.tpl_id" v-for="size in item.tpl_id" :key="size" class="grid-content" :class="'bg-purple-'+size"></el-col>
+                            </el-row>
+                            <span class="text-tpl">{{ templates[item.tpl_id].title }}</span>
+                        </div>
+
+
+                    </draggable>
+
+                </el-aside>
+                <el-container class="_fc-m">
+<!--                    <el-header class="_fc-m-tools" height="45">-->
+<!--                        <slot name="handle"></slot>-->
+<!--                        <el-button type="primary" icon="fc-icon icon-preview" plain round size="mini"-->
+<!--                                   @click="previewFc">预 览-->
+<!--                        </el-button>-->
+<!--                        <el-popconfirm-->
+<!--                                title="清空后将不能恢复,确定要清空吗?"-->
+<!--                                style="margin-left: 10px;"-->
+<!--                                confirm-button-text="清空"-->
+<!--                                cancel-button-text="取消"-->
+<!--                                @confirm="clearDragRule"-->
+<!--                        >-->
+<!--                            <el-button slot="reference" type="danger" icon="fc-icon icon-delete" plain round size="mini">清 空-->
+<!--                            </el-button>-->
+<!--                        </el-popconfirm>-->
+
+<!--                    </el-header>-->
+                    <el-main style="background: #F5F5F5;padding: 20px;">
+                        <div class="_fc-m-drag">
+                            <nest-draggable :tasks="abc" @add="addItem" @delete="deleteData">
+
+                            </nest-draggable>
+
+<!--                            <draggable v-model="abc" :options="floorOptions" class="tpl-list" @add="addItem">-->
+<!--                                <div v-for="(item, index) in abc" :class="'item-' + item.tpl_id" class="floor-item">-->
+<!--                                    <nest-component :tpl-id="item.tpl_id"-->
+<!--                                                    :data="JSON.parse(JSON.stringify(item))"-->
+<!--                                    ></nest-component>-->
+<!--&lt;!&ndash;                                <component&ndash;&gt;-->
+<!--&lt;!&ndash;                                        :is="templates[item.tpl_id]"&ndash;&gt;-->
+<!--&lt;!&ndash;                                        :data="JSON.parse(JSON.stringify(item))"&ndash;&gt;-->
+<!--&lt;!&ndash;                                        is-edit&ndash;&gt;-->
+<!--&lt;!&ndash;                                        @edit-block="(...props) => {  handleEditBlock(index, ...props) }"&ndash;&gt;-->
+<!--&lt;!&ndash;                                        @edit-title="(...props) => { handleEditTitle(index, ...props) }"&ndash;&gt;-->
+<!--&lt;!&ndash;                                        @edit-tags="(...props) => { handleEditTags(index, ...props) }"&ndash;&gt;-->
+<!--&lt;!&ndash;                                ></component>&ndash;&gt;-->
+<!--                                </div>-->
+<!--                            </draggable>-->
+                        </div>
+                    </el-main>
+                </el-container>
+                <el-aside class="_fc-r" width="320px" >
+                    <el-container style="height: 100%;">
+<!--                        <el-header height="40px" class="_fc-r-tabs">-->
+<!--                            <div class="_fc-r-tab" :class="{active: activeTab==='props'}" v-if="!!activeRule || (config && config.showFormConfig === false)"-->
+<!--                                 @click="activeTab='props'">组件配置-->
+<!--                            </div>-->
+<!--                            <div class="_fc-r-tab" v-if="!config || config.showFormConfig !== false" :class="{active: activeTab==='form' && !!activeRule}"-->
+<!--                                 @click="activeTab='form'">表单配置-->
+<!--                            </div>-->
+<!--                        </el-header>-->
+<!--                        <ElMain v-show="activeTab==='form'" v-if="!config || config.showFormConfig !== false">-->
+<!--                            <component :is="FormCreate" :rule="form.rule" :option="form.option"-->
+<!--                                       :value.sync="form.value.form"></component>-->
+<!--                        </ElMain>-->
+<!--                        <ElMain v-show="activeTab==='props'" style="padding: 0 20px;"-->
+<!--                                :key="activeRule ? activeRule._id: ''">-->
+<!--                            <div>-->
+<!--                                <ElDivider v-if="showBaseRule">基础配置</ElDivider>-->
+<!--                                <component :is="FormCreate" v-show="showBaseRule" v-model="baseForm.api" :rule="baseForm.rule"-->
+<!--                                           :option="baseForm.options"-->
+<!--                                           @change="baseChange"></component>-->
+<!--                                <ElDivider>属性配置</ElDivider>-->
+<!--                                <component :is="FormCreate" v-model="propsForm.api" :rule="propsForm.rule" :option="propsForm.options"-->
+<!--                                           @change="propChange" @removeField="propRemoveField"></component>-->
+<!--                                <ElDivider v-if="showBaseRule">验证规则</ElDivider>-->
+<!--                                <component :is="FormCreate" v-show="showBaseRule" v-model="validateForm.api" :rule="validateForm.rule"-->
+<!--                                           :option="validateForm.options"-->
+<!--                                           @update:value="validateChange"></component>-->
+<!--                            </div>-->
+<!--                        </ElMain>-->
+                    </el-container>
+                </el-aside>
+<!--                <ElDialog :visible.sync="preview.state" width="800px" append-to-body>-->
+<!--                    <ViewForm :rule="preview.rule" :option="preview.option" v-if="preview.state"></ViewForm>-->
+<!--                </ElDialog>-->
+            </el-container>
+        </el-main>
+    </el-container>
+
+
+</template>
+
+<!--
+看板样式,内容设计器
+-->
+
+
+<script>
+    import Vue from 'vue'
+    import templates, {templateArray} from './templates'
+    import VueLazyload from 'vue-lazyload'
+    import draggable from 'vuedraggable'
+    import TextDisplay from "./templates/common/text-display";
+    import NestComponent from "./nest-component";
+    import NestDraggable from "./nest-draggable";
+    import { nanoid } from 'nanoid'
+    Vue.use(VueLazyload)
+    export default {
+        name: "infoboard-designer",
+        components:{NestDraggable, NestComponent, TextDisplay, draggable},
+        provide() {
+            return {
+                fcx: {
+                    active: null
+                }
+            }
+            },
+        data() {
+
+            return {
+                templates,
+                templateArray:[...templateArray],
+                props:{
+                    type:'danger',
+                    size:'small',
+                    text:'sfdf'
+                },
+                abc:[],
+                tplOptions: {
+                    group: { name: 'tplGroup', pull: 'clone', put: false },
+                    sort: false
+                },
+                tplOptions2: {
+                    group: { name: 'child', pull: 'clone', put: false },
+                    sort: false
+                },
+                floorOptions: {
+                    animation: 150,
+                    group: { name: 'tplGroup', put: true },
+                    sort: true,
+                    handle: '.handle-move'
+                },
+
+                boardInfo: {
+                    header: {
+                        tpl_id: 4, //模板id
+                        tpl_box_style: {},//标题模块样式
+                        visible: true, //是否显示模块
+                        moduleStyle: {
+                            blockHeight: 60,
+                            background:'#0081ff'
+                        },
+                        columnList: [
+                            {
+                                label: '标题',
+                                content: '内容',
+                                labelColor: '#333333',
+                                labelBgColor: '#ffffff',
+                                labelTextSize: 22,
+                                labelAlign: 'right',
+                                labelWidth: 200,
+                                contentColor: '#333333',
+
+                                contentTextSize: 22,
+                                blockWidth: 8,
+                                boardItemHisKeyVal: ''
+                            },
+                            {
+                                label: '标题',
+                                content: '内容',
+                                contentColor: '#fff',
+                                contentTextSize: 22,
+                                contentAlign:'center',
+                                blockWidth: 10
+                            }
+                            ,
+                            {
+                                label: '标题',
+                                content: '内容',
+                                labelColor: '#333333',
+                                labelBgColor: '#ffffff',
+                                labelTextSize: 22,
+                                labelAlign: 'right',
+                                labelWidth: 200,
+                                contentColor: '#fff',
+
+                                contentTextSize: 22,
+                                blockWidth: 6,
+                                boardItemHisKeyVal: ''
+                            }
+                        ]
+                    },
+                    body: {
+                        tpl_id: 5, //模板id
+                    },
+                    footer: {}
+                }
+            }
+        },
+        computed: {
+            // 楼层模板盒子样式
+            tplBoxStyle() {
+                const { sidebar } = this.$store.getters
+                let left = (sidebar.opened ? 210 : 60)
+                left = this.tplBoxShow ? left : left - 300
+                return {
+                    left: left + 'px'
+                }
+            },
+            floorContainerHeight() {
+                return  this.mainAreaHeight
+            },
+            partInfo() {
+                return this.$store.getters.organization
+            }
+        },
+        methods: {
+            /** 保存发布 */
+            handleSaveFloor() {
+                this.titleData.content_config = JSON.stringify(this.floorList)
+                API_BoardTitle.update(this.titleData.id, this.titleData).then(() => this.$message.success('保存发布成功!'))
+            },
+
+            clonedata(origin){
+                const data = JSON.parse(JSON.stringify(origin))
+                if(data.unique===''||data.unique===undefined){
+                    data.unique=nanoid(10)
+                }
+                console.log('clone',data)
+                return data
+            },
+            handleBoardItemSet(settingData) {
+                console.log(settingData)
+                const {index, target, columnIndex} = this.editOptions
+                const blockData = {...settingData}
+                target.columnList[columnIndex] = blockData
+                this.$set(this.floorList, index, target)
+            },
+            handleBoardModuleSet(settingData) {
+                const {index, blockdata} = this.editOptions
+                const moduleSetting = {...settingData}
+                blockdata.moduleStyle = moduleSetting
+                this.$set(this.floorList, index, blockdata)
+            },
+            addItem(){
+                console.log('abc',this.abc)
+                console.log('templatearray',this.templateArray)
+            },
+            /** 编辑楼层区块 */
+            handleEditBlock(index, target, columnIndex) {
+
+                const blockData = target.columnList[columnIndex]
+
+                this.settingShow = true
+                this.boardItemConfig = {...blockData}
+                // const block = target.columnList[columnIndex].blockList[blockIndex]
+                // const type = block.block_type
+                this.editOptions = {index, target, columnIndex}
+                // const blockData = JSON.parse(JSON.stringify(block))
+                // if (type === 'IMAGE') {
+                //     this.defaultImageData = blockData.block_value ? [{
+                //         url: blockData.block_value,
+                //         opt: blockData.block_opt
+                //     }] : null
+                //     this.dialogImageShow = true
+                // } else if (type === 'GOODS') {
+                //     // 填充默认数据
+                //     // this.defaultGoodsData = blockData.block_value ? [blockData.block_value.goods_id] : []
+                //     // this.dialogGoodsShow = true
+                // } else if (type === 'BRAND') {
+                //     console.log('品牌模块')
+                // }
+            },
+
+            handleModule(index, blockdata) {
+                this.boardModuleConfig = {...blockdata.moduleStyle}
+                this.editOptions = {index, blockdata}
+                this.moduleSettingShow = true
+                console.log(index, blockdata)
+            },
+
+            /** 编辑楼层标题 */
+            handleEditTitle(index, target, columnIndex) {
+                this.editOptions = {index, target, columnIndex}
+                const column = target.columnList[columnIndex]
+                const columnData = JSON.parse(JSON.stringify(column))
+                this.defaultTitleData = {
+                    text: column.title,
+                    start_color: column.titleColors[0],
+                    end_color: column.titleColors[1]
+                }
+                this.dialogTitleShow = true
+            },
+            /** 编辑楼层标签 */
+            handleEditTags(index, target, columnIndex) {
+                this.editOptions = {index, target, columnIndex}
+                const column = target.columnList[columnIndex]
+                const columnData = JSON.parse(JSON.stringify(column))
+                this.defaultTagsData = columnData.tagList
+                this.dialogTagsShow = true
+            },
+            getBoardTitle() {
+                API_BoardTitle.get(this.titleId, {}).then(
+                    res => {
+                        console.log('res', res)
+                        this.titleData = {...res}
+                        if (res.content_config !== null && res.content_config !== '') {
+                            this.floorList = JSON.parse(res.content_config)
+                            this.floorList.forEach(item => {
+                                item.columnList.forEach(col => {
+                                    if (col.boardItemHisKeyVal !== '') {
+                                        console.log('col', this.boardItems)
+                                        const boardItem = this.boardItems.filter(p => p.his_keyval === col.boardItemHisKeyVal)[0]
+                                        console.log('boardItem', boardItem)
+                                        if (boardItem !== null && boardItem !== undefined) {
+                                            col.content = boardItem.area_content
+                                            col.label = boardItem.area_label
+                                        }
+                                    }
+                                })
+                            })
+                        } else {
+                            this.floorList = []
+                        }
+                    }
+                ).catch(error => {
+                    this.$message.error(error.message)
+                })
+            },
+            deleteData(unique){
+                this.deleteArrayData(this.abc,unique)
+
+                console.log('data delete ')
+            },
+
+            deleteArrayData(data, id) {
+                let node = null
+                if (data.length > 0) {
+                    for (var i = 0; i < data.length; i++) {
+                        if (data[i].unique === id) {
+                            node = data[i]
+                            data.splice(i,1)
+                            return
+                        }
+                        if (data[i].children && data[i].children.length > 0) {
+                              this.deleteArrayData(data[i].children, id)
+                            // if (subresult !== null) {
+                            //     node = subresult
+                            //     break
+                            // }
+                        }
+                    }
+                }
+                // delete node
+            },
+
+        }
+    }
+</script>
+
+<style scoped type="text/scss">
+    ._fc-designer {
+        height: 100%;
+        min-height: 500px;
+        overflow: hidden;
+        cursor: default;
+        position: relative;
+    }
+    ._fc-m-drag,.tpl-list{
+        height: 100%;
+    }
+    .el-aside{
+        margin-bottom: 0;
+    }
+    .container {
+        min-width: 1366px;
+    }
+
+    .floor-container {
+        display: flex;
+        justify-content: space-around;
+        background-color: #E5E7EA;
+        padding: 10px;
+    }
+
+    .draggable-box {
+        position: relative;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        flex-direction: column;
+        width: 100%;
+
+    }
+
+    .header {
+        width: 1210px;
+        overflow: hidden;
+    }
+
+    @media (max-width: 1300px) {
+        .header {
+            width: 900px;
+        }
+        .container {
+            min-width: 1000px;
+        }
+    }
+
+    .draggable-box .floor {
+        width: 800px + 50px;
+        flex-shrink: 0;
+        align-items: center;
+    }
+
+    .tpl-list {
+        display: flex;
+        flex-wrap: wrap;
+        overflow: hidden;
+        width: 100%;
+        background-color: #fff;
+    }
+
+    .tpl-item {
+        display: flex;
+        width: 100%;
+        flex-direction: column;
+        justify-content: center;
+        box-sizing: border-box;
+        border-bottom: 2px solid #D9E0E7;
+        margin-bottom: 10px;
+        /*&.item-1 .img-tpl {*/
+        /*    background: url("../../../assets/pc-tpl-01.png") no-repeat;*/
+        /*    background-size: 100%;*/
+        /*}*/
+        /*&.item-2 .img-tpl {*/
+        /*    background: url("../../../assets/pc-tpl-02.png") no-repeat;*/
+        /*    background-size: 100%;*/
+        /*}*/
+        /*&.item-3 .img-tpl {*/
+        /*    background: url("../../../assets/pc-tpl-03.png") no-repeat;*/
+        /*    background-size: 100%;*/
+        /*}*/
+        /*&.item-4 .img-tpl {*/
+        /*    background: url("../../../assets/pc-tpl-04.png") no-repeat;*/
+        /*    background-size: 100%;*/
+        /*}*/
+    }
+
+    .img-tpl {
+        width: 100%;
+        min-height: 150px;
+    }
+
+    .text-tpl {
+        text-align: center;
+        margin: 5px 0;
+        color: #ACB0B9;
+        font-size: 12px;
+    }
+
+    .floor-body {
+        display: flex;
+        justify-content: center;
+        width: 100%;
+        height: 100%;
+        /*overflow-y: hidden;*/
+    }
+
+    .floor-list {
+        background-color: #E5E7EA;
+        /*min-width: 75%;*/
+        min-height: 500px;
+    }
+
+    .floor-item {
+        position: relative;
+        box-sizing: border-box;
+
+    }
+
+
+    .floor-item .panel-handle {
+        display: none;
+        position: absolute;
+        top: 0;
+        right: -25px;
+
+    }
+
+    .floor-item .panel-handle .icon-handle {
+        display: block;
+        cursor: pointer;
+        text-align: center;
+    }
+
+    .floor-item .panel-handle .svg-icon {
+        width: 25px;
+        height: 25px;
+        background-color: #fff;
+    }
+
+    .floor-item:hover .panel-handle {
+        display: block;
+    }
+
+    .floor-item:first-child .floor-layout {
+        margin-top: 0;
+    }
+
+    .tpl-box {
+        position: fixed;
+        top: 20%;
+        left: 180px;
+        z-index: 99;
+        width: 300px;
+        margin-top: (-500px - 32px + 84px) / 2;
+        border-top: 10px solid #fff;
+        box-shadow: 4px 5px 20px 0 rgba(0, 0, 0, .6);
+        transition: all ease .3s;
+    }
+
+    .tpl-box .tpl-list {
+        height: 300px;
+        overflow-y: scroll;
+    }
+
+    .tpl-box .save-btn {
+        width: 100%;
+    }
+
+    .tpl-box .tpl-btns {
+        position: absolute;
+        top: 50%;
+        right: -25px;
+        margin-top: -35px;
+        width: 25px;
+        height: 70px;
+        background-color: #fff;
+        text-align: center;
+        padding: 5px 0;
+
+    }
+
+    .tpl-box .tpl-btns .btn-item {
+        cursor: pointer;
+        padding: 5px 0;
+
+    }
+
+    .tpl-box .tpl-btns .btn-item + .btn-item {
+        margin-top: 8px;
+    }
+
+    .tpl-box .tpl-btns .btn-item:hover {
+        background-color: #46A0FC;
+        color: #fff
+    }
+
+    .bg-blue {
+        background-color: #0081ff;
+        color: #ffffff;
+    }
+
+    /deep/ .el-header {
+        line-height: 60px;
+    }
+
+    .content_title {
+        font-size: 26px
+    }
+
+    .grid-content {
+        border-radius: 4px;
+        min-height: 36px;
+    }
+
+    .el-col {
+        border-radius: 4px;
+    }
+
+    .bg-purple-1 {
+        background: #99a9bf;
+    }
+
+    .bg-purple-2 {
+        background: #d3dce6;
+    }
+
+    .bg-purple-3 {
+        background: #e5e9f2;
+    }
+
+    /deep/ .el-scrollbar__wrap {
+        overflow-x: hidden;
+        overflow-y: visible;
+        padding-bottom: 20px;
+    }
+
+    /deep/ .el-scrollbar {
+        width: 100%;
+    }
+
+</style>

+ 5 - 0
src/views/custom-infoboard/mixin.js

@@ -15,6 +15,7 @@ export default {
     components: {
     components: {
         layoutItem
         layoutItem
     },
     },
+
     methods: {
     methods: {
         /** 获取颜色相关信息 */
         /** 获取颜色相关信息 */
         colors(columnIndex = 0) {
         colors(columnIndex = 0) {
@@ -64,6 +65,10 @@ export default {
         /** 编辑标签 */
         /** 编辑标签 */
         handleEditTags(columnIndex) {
         handleEditTags(columnIndex) {
             this.$emit('edit-tags', JSON.parse(JSON.stringify(this.data)), columnIndex)
             this.$emit('edit-tags', JSON.parse(JSON.stringify(this.data)), columnIndex)
+        },
+
+        handleActive(aa){
+         console.log('aa',aa)
         }
         }
     }
     }
 }
 }

+ 76 - 0
src/views/custom-infoboard/mixinnew.js

@@ -0,0 +1,76 @@
+import dragtool from './templates/DragTool'
+export default {
+    props: {
+        /** 数据 */
+        data: {
+            type: Object,
+            default: () => ({})
+        },
+        /** 是否为编辑模式 */
+        isEdit: {
+            type: Boolean,
+            default: false
+        }
+    },
+    components: {
+        dragtool
+    },
+    methods: {
+        /** 获取颜色相关信息 */
+        colors(columnIndex = 0) {
+            const _colors = this.data.columnList[columnIndex].titleColors
+            return {
+                title: `background-color: ${_colors[0]}; background-image: linear-gradient(90deg, ${_colors.join(',')});`,
+                color: (colorIndex = 0) => `color: ${_colors[colorIndex]}`
+            }
+        },
+        // /** 获取区块链接 */
+        // blockHref(block) {
+        //     const { opt_type, opt_value } = block.block_opt
+        //     switch (opt_type) {
+        //         // 链接地址
+        //         case 'URL': return opt_value
+        //         // 商品
+        //         case 'GOODS': return `/goods/${opt_value}`
+        //         // 关键字
+        //         case 'KEYWORD': return `/goods?keyword=${encodeURIComponent(opt_value)}`
+        //         // 店铺
+        //         case 'SHOP': return `/shop/${opt_value}`
+        //         // 分类
+        //         case 'CATEGORY': return `/goods?category=${opt_value}`
+        //         default: return '/'
+        //     }
+        // },
+        /** 构建空的block */
+        emptyBlock(num = 3, type) {
+            return [...new Array(num)].map(() => ({
+                block_type: type,
+                block_value: '',
+                block_opt: {
+                    opt_type: 'NONE',
+                    opt_value: ''
+                }
+            }))
+        },
+        /** 编辑区块 */
+        handleEditBlock(columnIndex, blockIndex) {
+            console.log(JSON.stringify(this.data))
+            this.$emit('edit-block', JSON.parse(JSON.stringify(this.data)), columnIndex, blockIndex)
+        },
+        /** 编辑标题 */
+        handleEditTitle(columnIndex) {
+            this.$emit('edit-title', JSON.parse(JSON.stringify(this.data)), columnIndex)
+        },
+        /** 编辑标签 */
+        handleEditTags(columnIndex) {
+            this.$emit('edit-tags', JSON.parse(JSON.stringify(this.data)), columnIndex)
+        },
+        handleActive(aa){
+            console.log('aa',aa)
+        },
+        deleteModel(unique){
+            console.log('model delete',unique)
+            this.$emit('remove',unique)
+        }
+    }
+}

+ 46 - 0
src/views/custom-infoboard/nest-component.vue

@@ -0,0 +1,46 @@
+<template>
+<component
+        :is="templates[tplId]"
+>
+<!--    <div v-for="(child,index) in data.children" :key="index">{{-->
+<!--        child.dataTpl.tpl_id}}</div>-->
+    <component v-for="(child,index) in data.children" :is="templates[child.dataTpl.tpl_id]" :data="child" :key="index">
+    </component>
+</component>
+</template>
+
+<script>
+    import templates, {templateArray} from './templates'
+    export default {
+        name: "nest-component",
+        props: {
+            data: {
+                type:Object,
+                default:()=>{}
+            },
+            tplId:{
+                required: true,
+                type: Number
+            }
+        },
+        data(){
+            return{
+                templates,
+                templateArray,
+                floorOptions: {
+                    animation: 150,
+                    group: { name: 'tplGroup', put: true },
+                    sort: true,
+                    handle: '.handle-move'
+                },
+            }
+        },
+      mounted() {
+            console.log('child',this.data.children)
+      }
+    }
+</script>
+
+<style scoped>
+
+</style>

+ 63 - 0
src/views/custom-infoboard/nest-draggable.vue

@@ -0,0 +1,63 @@
+<template>
+    <draggable class="dragArea" tag="div" :list="tasks" :options="floorOptions" @add="additem"  :clone="clonedata">
+        <div v-for="(el,index) in tasks" :key="el.unique">
+        <component   :is="templates[el.tpl_id]" :data="el" @remove="deleteModel">
+<!--            <p>{{ el.name }}</p>-->
+            <nest-draggable :tasks="el.children" @add="additem" @delete="deleteModel"/>
+        </component>
+
+        </div>
+    </draggable>
+</template>
+<script>
+    import templates, {templateArray} from './templates'
+    import draggable from "vuedraggable";
+    export default {
+        props: {
+            tasks: {
+                required: true,
+                type: Array
+            }
+        },
+        components: {
+            draggable
+        },
+        name: "nest-draggable",
+        data(){
+            return{
+                templates:{...templates},
+                templateArray,
+                floorOptions: {
+                    animation: 150,
+                    group: { name: 'tplGroup', put: true },
+                    sort: true,
+                    handle: '.handle-move'
+                },
+            }
+        },
+        mounted() {
+            console.log(this.tasks)
+        },
+        methods:{
+            additem(){
+                this.$emit('add')
+            },
+            clonedata(origin){
+                const data = JSON.parse(JSON.stringify(origin))
+                console.log('clone',data)
+                return data
+            },
+            deleteModel(unique){
+                console.log('nested delete',unique)
+                this.$emit('delete',unique)
+            }
+        }
+    };
+</script>
+<style scoped>
+    .dragArea {
+        min-height: 60px;
+        /*outline: 1px dashed;*/
+    }
+</style>
+

+ 138 - 0
src/views/custom-infoboard/templates/DragTool.vue

@@ -0,0 +1,138 @@
+<template>
+  <div class="drag-tool" @click.stop="active" :class="{active: state.active === id}" :unique="unique">
+    <div class="drag-mask" v-if="mask"></div>
+    <div class="drag-l">
+      <div class="drag-btn _fc-drag-btn active handle-move"  style="cursor: move;">
+        <i class="fc-icon el-icon-rank"></i>
+      </div>
+    </div>
+    <div class="drag-r">
+      <div class="drag-btn" @click="$emit('add')">
+        <i class="fc-icon el-icon-circle-plus-outline"></i>
+      </div>
+      <div class="drag-btn" @click="$emit('copy')">
+        <i class="fc-icon el-icon-copy-document"></i>
+      </div>
+      <div class="drag-btn" v-if="children" @click="$emit('addChild')">
+        <i class="fc-icon el-icon-circle-plus-outline"></i>
+      </div>
+      <div class="drag-btn drag-btn-danger" @click="$emit('delete',id)">
+        <i class="fc-icon el-icon-delete"></i>
+      </div>
+    </div>
+    <slot name="default" :block="block"></slot>
+  </div>
+</template>
+
+<script>
+let id = 1;
+export default {
+    name: 'DragTool',
+    props: ['dragBtn', 'children', 'unique', 'mask','block'],
+  inject: ['fcx'],
+    data() {
+        return {
+            id: this.unique || id++,
+            state: this.fcx
+        };
+    },
+    methods: {
+        active() {
+
+            if (this.state.active === this.id) return;
+            this.state.active = this.id;
+          console.log('active',this.state)
+          console.log('fcx',this.fcx)
+            this.$emit('active');
+        }
+    },
+  mounted(){
+    console.log('unique',this.unique)
+  },
+    beforeDestroy() {
+        this.state = {};
+    }
+};
+</script>
+
+<style>
+.drag-tool {
+  position: relative;
+  min-height: 20px;
+  box-sizing: border-box;
+  padding: 2px;
+  outline: 1px dashed #2E73FF;
+  overflow: hidden;
+  word-wrap: break-word;
+  word-break: break-all;
+}
+
+.drag-tool .drag-tool {
+  margin: 5px;
+}
+
+.drag-tool + .drag-tool {
+  margin-top: 5px;
+}
+
+.drag-tool.active {
+  outline: 2px solid #2E73FF;
+}
+
+.drag-tool.active > div > .drag-btn {
+  display: flex;
+}
+
+.drag-tool .drag-btn {
+  display: none;
+}
+
+.drag-r {
+  position: absolute;
+  right: 2px;
+  bottom: 2px;
+  z-index: 1904;
+}
+
+.drag-l {
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 1904
+
+}
+
+.drag-btn {
+  height: 18px;
+  width: 18px;
+  color: #fff;
+  background-color: #2E73FF;
+  text-align: center;
+  line-height: 20px;
+  padding-bottom: 1px;
+  float: left;
+  cursor: pointer;
+  justify-content: center;
+}
+
+.drag-btn + .drag-btn {
+  margin-left: 2px;
+}
+
+.drag-btn-danger {
+  background-color: #FF2E2E;
+}
+
+.drag-btn i {
+  font-size: 13px;
+}
+
+.drag-mask{
+    z-index: 1900;
+    position: absolute;
+    top:0;
+    left:0;
+    right:0;
+    bottom: 0;
+;}
+</style>

+ 133 - 0
src/views/custom-infoboard/templates/common/cloumn-container.vue

@@ -0,0 +1,133 @@
+
+
+<template>
+
+
+
+            <el-col :span="8">
+                <drag-tool :unique="data.unique">
+                <slot></slot>
+                </drag-tool>
+            </el-col>
+
+
+
+</template>
+
+<script>
+    import draggable from 'vuedraggable'
+    import mixin from '../../mixin'
+    import DragTool from "../DragTool";
+    export default {
+        name: "cloumn-container",
+        components: {DragTool,draggable},
+        mixins: [mixin],
+        title: '列容器',
+        data(){
+            return{
+            }
+        },
+        dataTpl: {
+            tpl_id: 10,
+            tpl_type: 'BOARD_ITEM',
+            unique:'',
+            moduleStyle: {
+                borderBottomShow: true,
+                borderTopShow: true,
+                borderLeftShow: true,
+                borderRightShow: true,
+                borderWidth: 2,
+                borderColor: '#eeeeee',
+                blockHeight: 50
+            },
+            rows:[
+                {
+                    columnList: [
+                        {
+                            span:8,
+                            color:'#555555',
+                            fontSize:'14px',
+                            backgroundColor:'',
+                            fontFamily:'微软雅黑',
+                            field:'',
+                            text:'床位',
+                            textAlign:'',
+                        },
+                        {
+                            span:8,
+                            color:'#555555',
+                            fontSize:'14px',
+                            backgroundColor:'',
+                            fontFamily:'微软雅黑',
+                            field:'',
+                            text:'姓名',
+                            textAlign:'',
+                        },
+                        {
+                            span:8,
+                            color:'#555555',
+                            fontSize:'14px',
+                            backgroundColor:'',
+                            fontFamily:'微软雅黑',
+                            field:'',
+                            text:'病危',
+                            textAlign:'',
+                        }
+                    ]
+                }
+            ],
+
+
+            columnList: [
+                {
+                    label: '标题',
+                    content: '内容',
+                    labelColor: '#333333',
+                    labelBgColor: '#ffffff',
+                    labelTextSize:22,
+                    labelAlign: 'right',
+                    labelWidth: 200,
+                    contentColor: '#333333',
+                    contentBgColor: '#ffffff',
+                    contentTextSize:22,
+                    blockWidth: 8,
+                    boardItemHisKeyVal:''
+                },
+                {
+                    label: '标题',
+                    content: '内容',
+                    labelColor: '#333333',
+                    labelBgColor: '#ffffff',
+                    labelTextSize:22,
+                    labelAlign: 'right',
+                    labelWidth: 200,
+                    contentColor: '#333333',
+                    contentBgColor: '#ffffff',
+                    contentTextSize:22,
+                    blockWidth: 8,
+                    boardItemHisKeyVal:''
+                }
+                ,
+                {
+                    label: '标题',
+                    content: '内容',
+                    labelColor: '#333333',
+                    labelBgColor: '#ffffff',
+                    labelTextSize:22,
+                    labelAlign: 'right',
+                    labelWidth: 200,
+                    contentColor: '#333333',
+                    contentBgColor: '#ffffff',
+                    contentTextSize:22,
+                    blockWidth: 8,
+                    boardItemHisKeyVal:''
+                }
+            ],
+            children:[]
+        }
+    }
+</script>
+
+<style scoped>
+
+</style>

+ 15 - 1
src/views/custom-infoboard/templates/common/index.js

@@ -1,9 +1,23 @@
 import tpl_one_cloum from './tpl-one-cloum'
 import tpl_one_cloum from './tpl-one-cloum'
 import tpl_two_cloum from './tpl-two-cloum'
 import tpl_two_cloum from './tpl-two-cloum'
 import tpl_three_cloum from './tpl-three-colum'
 import tpl_three_cloum from './tpl-three-colum'
+import tpl_header from './tpl-header'
+import tpl_beds_grid from './tpl-beds-grid'
+import tpl_bed_unit from './tpl-bed-unit'
+import text_display from './text-display'
+import text_display2 from './text-display2'
+import row_container from './row-container'
+import column_container from './cloumn-container'
 
 
 export default {
 export default {
     1: tpl_one_cloum,
     1: tpl_one_cloum,
     2: tpl_two_cloum,
     2: tpl_two_cloum,
-    3: tpl_three_cloum
+    3: tpl_three_cloum,
+    4:tpl_header,
+    5:tpl_beds_grid,
+    6:tpl_bed_unit,
+    7:text_display,
+    8:text_display2,
+    9:row_container,
+    10:column_container
 }
 }

+ 129 - 0
src/views/custom-infoboard/templates/common/row-container.vue

@@ -0,0 +1,129 @@
+<template>
+
+    <div style="box-sizing: content-box;">
+        <drag-tool :unique="data.unique">
+        <el-row>
+            <slot></slot>
+        </el-row>
+        </drag-tool>
+    </div>
+
+</template>
+
+<script>
+    import draggable from 'vuedraggable'
+    import mixin from '../../mixin'
+    import DragTool from "../DragTool";
+    export default {
+        name: "row-container",
+        components: {DragTool,draggable},
+        mixins: [mixin],
+        title: '行容器',
+        data(){
+            return{
+            }
+        },
+        dataTpl: {
+            tpl_id: 9,
+            tpl_type: 'BOARD_ITEM',
+            unique:'',
+            moduleStyle: {
+                borderBottomShow: true,
+                borderTopShow: true,
+                borderLeftShow: true,
+                borderRightShow: true,
+                borderWidth: 2,
+                borderColor: '#eeeeee',
+                blockHeight: 50
+            },
+            rows:[
+                {
+                    columnList: [
+                        {
+                            span:8,
+                            color:'#555555',
+                            fontSize:'14px',
+                            backgroundColor:'',
+                            fontFamily:'微软雅黑',
+                            field:'',
+                            text:'床位',
+                            textAlign:'',
+                        },
+                        {
+                            span:8,
+                            color:'#555555',
+                            fontSize:'14px',
+                            backgroundColor:'',
+                            fontFamily:'微软雅黑',
+                            field:'',
+                            text:'姓名',
+                            textAlign:'',
+                        },
+                        {
+                            span:8,
+                            color:'#555555',
+                            fontSize:'14px',
+                            backgroundColor:'',
+                            fontFamily:'微软雅黑',
+                            field:'',
+                            text:'病危',
+                            textAlign:'',
+                        }
+                    ]
+                }
+            ],
+
+
+            columnList: [
+                {
+                    label: '标题',
+                    content: '内容',
+                    labelColor: '#333333',
+                    labelBgColor: '#ffffff',
+                    labelTextSize:22,
+                    labelAlign: 'right',
+                    labelWidth: 200,
+                    contentColor: '#333333',
+                    contentBgColor: '#ffffff',
+                    contentTextSize:22,
+                    blockWidth: 8,
+                    boardItemHisKeyVal:''
+                },
+                {
+                    label: '标题',
+                    content: '内容',
+                    labelColor: '#333333',
+                    labelBgColor: '#ffffff',
+                    labelTextSize:22,
+                    labelAlign: 'right',
+                    labelWidth: 200,
+                    contentColor: '#333333',
+                    contentBgColor: '#ffffff',
+                    contentTextSize:22,
+                    blockWidth: 8,
+                    boardItemHisKeyVal:''
+                }
+                ,
+                {
+                    label: '标题',
+                    content: '内容',
+                    labelColor: '#333333',
+                    labelBgColor: '#ffffff',
+                    labelTextSize:22,
+                    labelAlign: 'right',
+                    labelWidth: 200,
+                    contentColor: '#333333',
+                    contentBgColor: '#ffffff',
+                    contentTextSize:22,
+                    blockWidth: 8,
+                    boardItemHisKeyVal:''
+                }
+            ],
+            children:[]
+        }
+    }
+</script>
+
+<style scoped>
+
+</style>

+ 44 - 0
src/views/custom-infoboard/templates/common/text-display.vue

@@ -0,0 +1,44 @@
+<template>
+
+    <drag-tool @active="handleActive" :unique="data.unique" @delete="deleteModel">
+        <div style="width:200px;">
+    <span :style="data.labelStyle">
+      标签
+    </span>
+    <span :style="data.textStyle">
+      文字
+    </span>
+
+    </div>
+    </drag-tool>
+
+    </template>
+
+    <script>
+    import DragTool from "../DragTool";
+    import mixin from '../../mixinnew'
+    export default {
+        name: "text-display",
+        mixins:[mixin],
+        components: {DragTool},
+        title:'显示单元',
+        unique:'',
+        dataTpl:{
+            tpl_id: 7,
+            tpl_type: 'BOARD_ITEM',
+            templateName:'text-display',
+            labelStyle:{
+
+            },
+            textStyle:{
+
+            },
+            children:[]
+        },
+
+    }
+</script>
+
+<style scoped>
+
+</style>

+ 44 - 0
src/views/custom-infoboard/templates/common/text-display2.vue

@@ -0,0 +1,44 @@
+<template>
+
+    <drag-tool @active="handleActive" :unique="data.unique">
+        <div style="width:200px;">
+    <span :style="data.labelStyle">
+      标签2
+    </span>
+    <span :style="data.textStyle">
+      文字2
+    </span>
+
+    </div>
+    </drag-tool>
+
+    </template>
+
+    <script>
+    import DragTool from "../DragTool";
+    import mixin from '../../mixinnew'
+    export default {
+        name: "text-display2",
+        mixins:[mixin],
+        components: {DragTool},
+        title:'显示单元2',
+        dataTpl:{
+            tpl_id: 8,
+            tpl_type: 'BOARD_ITEM',
+            templateName:'text-display2',
+            unique:'',
+            labelStyle:{
+
+            },
+            textStyle:{
+
+            },
+            children:([])
+        },
+
+    }
+</script>
+
+<style scoped>
+
+</style>

+ 92 - 0
src/views/custom-infoboard/templates/common/tpl-bed-unit.vue

@@ -0,0 +1,92 @@
+<template>
+
+        <div style="box-sizing: content-box;">
+            <drag-tool>
+
+             <slot></slot>
+
+            </drag-tool>
+        </div>
+
+</template>
+
+<script>
+    import draggable from 'vuedraggable'
+    import mixin from '../../mixin'
+    import DragTool from "../DragTool";
+    export default {
+        name: "tpl-bed-unit",
+        components: {DragTool,draggable},
+        mixins: [mixin],
+        title: '床位单元格',
+        data(){
+            return{
+            }
+        },
+        dataTpl: {
+            tpl_id: 6,
+            tpl_type: 'BOARD_ITEM',
+            templateName:'tpl-bed-unit',
+            moduleStyle: {
+                borderBottomShow: true,
+                borderTopShow: true,
+                borderLeftShow: true,
+                borderRightShow: true,
+                borderWidth: 2,
+                borderColor: '#eeeeee',
+                blockHeight: 50
+            },
+
+            columnList: [
+                {
+                    label: '标题',
+                    content: '内容',
+                    labelColor: '#333333',
+                    labelBgColor: '#ffffff',
+                    labelTextSize:22,
+                    labelAlign: 'right',
+                    labelWidth: 200,
+                    contentColor: '#333333',
+                    contentBgColor: '#ffffff',
+                    contentTextSize:22,
+                    blockWidth: 8,
+                    boardItemHisKeyVal:''
+                },
+                {
+                    label: '标题',
+                    content: '内容',
+                    labelColor: '#333333',
+                    labelBgColor: '#ffffff',
+                    labelTextSize:22,
+                    labelAlign: 'right',
+                    labelWidth: 200,
+                    contentColor: '#333333',
+                    contentBgColor: '#ffffff',
+                    contentTextSize:22,
+                    blockWidth: 8,
+                    boardItemHisKeyVal:''
+                }
+                ,
+                {
+                    label: '标题',
+                    content: '内容',
+                    labelColor: '#333333',
+                    labelBgColor: '#ffffff',
+                    labelTextSize:22,
+                    labelAlign: 'right',
+                    labelWidth: 200,
+                    contentColor: '#333333',
+                    contentBgColor: '#ffffff',
+                    contentTextSize:22,
+                    blockWidth: 8,
+                    boardItemHisKeyVal:''
+                }
+            ],
+            children:([])
+        }
+    }
+</script>
+
+<style scoped>
+
+</style>

文件差异内容过多而无法显示
+ 473 - 0
src/views/custom-infoboard/templates/common/tpl-beds-grid.vue


文件差异内容过多而无法显示
+ 473 - 0
src/views/custom-infoboard/templates/common/tpl-header.vue


+ 2 - 1
src/views/custom-infoboard/templates/common/tpl-one-cloum.vue

@@ -73,7 +73,8 @@
                     blockWidth: 24,
                     blockWidth: 24,
                     boardItemHisKeyVal:''
                     boardItemHisKeyVal:''
                 }
                 }
-            ]
+            ],
+            children:([])
         }
         }
     }
     }
 </script>
 </script>

+ 138 - 32
src/views/ncs-device/components/deviceManager.vue

@@ -209,12 +209,24 @@
                     </el-col>
                     </el-col>
                 </el-row>
                 </el-row>
                 <el-row v-if="hasAudioId">
                 <el-row v-if="hasAudioId">
-                    <el-col :span="12">
+                    <el-col :span="8">
                         <el-form-item :label="this.$t('deviceManage.re485SipId')" prop="sip_id">
                         <el-form-item :label="this.$t('deviceManage.re485SipId')" prop="sip_id">
                             <el-input v-model="deviceModel.sip_id" clearable
                             <el-input v-model="deviceModel.sip_id" clearable
                                       :placeholder="this.$t('deviceManage.inputRe485SipId')"/>
                                       :placeholder="this.$t('deviceManage.inputRe485SipId')"/>
                         </el-form-item>
                         </el-form-item>
                     </el-col>
                     </el-col>
+                    <el-col :span="8">
+                        <el-form-item :label="this.$t('deviceManage.powerControlAddress')" prop="power_control_address">
+                            <el-input v-model="deviceModel.power_control_address" clearable
+                                      :placeholder="this.$t('deviceManage.powerControlAddress')" type="number"/>
+                        </el-form-item>
+                    </el-col>
+                    <el-col :span="8">
+                        <el-form-item :label="this.$t('deviceManage.controlLineNumber')" prop="control_line_number">
+                            <el-input v-model="deviceModel.control_line_number" clearable
+                                      :placeholder="this.$t('deviceManage.controlLineNumber')" type="number"/>
+                        </el-form-item>
+                    </el-col>
                 </el-row>
                 </el-row>
                 <el-row v-if="isVitalSigns">
                 <el-row v-if="isVitalSigns">
                     <el-col :span="12">
                     <el-col :span="12">
@@ -327,6 +339,7 @@
                 </el-row>
                 </el-row>
             </el-form>
             </el-form>
             <div slot="footer" class="dialog-footer">
             <div slot="footer" class="dialog-footer">
+
                 <el-button type="primary" @click="updateDevicesServerIp()">{{ this.$t('action.yes') }}</el-button>
                 <el-button type="primary" @click="updateDevicesServerIp()">{{ this.$t('action.yes') }}</el-button>
             </div>
             </div>
         </el-dialog>
         </el-dialog>
@@ -349,10 +362,12 @@
     import {VITAL_SIGNS_DEVICE_TYPE} from "@/utils/enum/VitalSignsDeviceEnum";
     import {VITAL_SIGNS_DEVICE_TYPE} from "@/utils/enum/VitalSignsDeviceEnum";
     import * as shop_API from "@/api/ncs_shop";
     import * as shop_API from "@/api/ncs_shop";
 
 
+    import ButtonCellRenderList from '@/components/AgGridCellRender/ButtonCellRenderList'
     const DeviceUrl = domain.DeviceUrl
     const DeviceUrl = domain.DeviceUrl
     export default {
     export default {
         name: 'DeviceManager',
         name: 'DeviceManager',
-        components: {ButtonCellRender, ListFilter, RadioFilter},
+        components: {ButtonCellRender, ListFilter, RadioFilter,
+            ButtonCellRenderList},
         props: {
         props: {
             frame: {
             frame: {
                 type: Object,
                 type: Object,
@@ -662,41 +677,102 @@
                         }
                         }
                     }
                     }
                 },
                 },
-                {
-                    headerName: this.$t('action.edit'), field: 'id',
-                    cellRendererFramework: 'ButtonCellRender',
-                    cellRendererParams: {
-                        onClick: this.handleEdit,
-                        label: this.$t('action.edit'),
-                        buttonType: 'primary',
-                        buttonSize: 'mini'
-                    },
-                    filter: false,
-                    pinned: 'right',
-                    lockPinned: true,
-                    width: 90,
-                    resizable: false,
-                    sortable: false
-                },
-                {
-                    headerName: this.$t('action.delete'), field: 'id',
-                    cellRendererFramework: 'ButtonCellRender',
+
+                { headerName: this.$t('action.handle'), field: 'id',
+                    cellRendererFramework: 'ButtonCellRenderList',
                     cellRendererParams: param => {
                     cellRendererParams: param => {
                         return {
                         return {
-                            onClick: this.deleteSingle,
-                            label: this.$t('action.delete'),
-                            buttonType: 'danger',
-                            buttonSize: 'mini',
-                            disabled: param.data['member_name'] === 'superadmin'
-                        }
+                            list: [
+                                {
+                                    onClick: this.handleEdit,
+                                    label: this.$t('action.edit'),
+                                    buttonType: 'primary',
+                                    buttonSize: 'mini'
+                                },
+                                {
+                                    onClick: this.deleteSingle,
+                                    label: this.$t('action.delete'),
+                                    buttonType: 'danger',
+                                    buttonSize: 'mini',
+                                    disabled: param.data['member_name'] === 'superadmin'
+                                },
+                                {
+                                    onClick: this.openDebug,
+                                    label: this.$t('action.opendebug'),
+                                    buttonType: 'success',
+                                    buttonSize: 'mini',
+                                    disabled: !this.androidDevice(param)
+                                },{
+                                    onClick: this.rebootDevice,
+                                    label: this.$t('action.reboot'),
+                                    buttonType: 'warning',
+                                    buttonSize: 'mini',
+                                    disabled: !this.androidDevice(param)&&!this.s485Device(param)
+                                }
+                            ]}
                     },
                     },
+                    filter: false,
                     pinned: 'right',
                     pinned: 'right',
                     lockPinned: true,
                     lockPinned: true,
-                    width: 90,
+                    minWidth: this.$i18n.locale === 'zh' ? 260 : 380,
                     resizable: false,
                     resizable: false,
-                    filter: false,
-                    sortable: false
-                }
+                    sortable: false },
+
+                // {
+                //     headerName: this.$t('action.edit'), field: 'id',
+                //     cellRendererFramework: 'ButtonCellRender',
+                //     cellRendererParams: {
+                //         onClick: this.handleEdit,
+                //         label: this.$t('action.edit'),
+                //         buttonType: 'primary',
+                //         buttonSize: 'mini'
+                //     },
+                //     filter: false,
+                //     pinned: 'right',
+                //     lockPinned: true,
+                //     width: 80,
+                //     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',
+                //             disabled: param.data['member_name'] === 'superadmin'
+                //         }
+                //     },
+                //     pinned: 'right',
+                //     lockPinned: true,
+                //     width: 80,
+                //     resizable: false,
+                //     filter: false,
+                //     sortable: false
+                // },
+                //
+                // {
+                //     headerName: this.$t('action.debug'), field: 'id',
+                //     cellRendererFramework: 'ButtonCellRender',
+                //     cellRendererParams: param => {
+                //         return {
+                //             onClick: this.deleteSingle,
+                //             label: this.$t('action.debug'),
+                //             buttonType: 'danger',
+                //             buttonSize: 'mini',
+                //             disabled: param.data['member_name'] === 'superadmin'
+                //         }
+                //     },
+                //     pinned: 'right',
+                //     lockPinned: true,
+                //     width: 80,
+                //     resizable: false,
+                //     filter: false,
+                //     sortable: false
+                // }
             ]
             ]
             this.defaultColDef = {
             this.defaultColDef = {
                 // filter: 'agTextColumnFilter',
                 // filter: 'agTextColumnFilter',
@@ -950,7 +1026,6 @@
             deviceTypeChangeToFrameTypeChange(val) {
             deviceTypeChangeToFrameTypeChange(val) {
                 if (val === DEVICE_TYPE.NURSE_HOST ||
                 if (val === DEVICE_TYPE.NURSE_HOST ||
                     val === DEVICE_TYPE.OTHER_HOST ||
                     val === DEVICE_TYPE.OTHER_HOST ||
-                    val === DEVICE_TYPE.NURSE_HOST ||
                     val === DEVICE_TYPE.DOCTOR_HOST ||
                     val === DEVICE_TYPE.DOCTOR_HOST ||
                     val === DEVICE_TYPE.LED_SCREEN ||
                     val === DEVICE_TYPE.LED_SCREEN ||
                     val === DEVICE_TYPE.LCD_SCREEN ||
                     val === DEVICE_TYPE.LCD_SCREEN ||
@@ -979,6 +1054,22 @@
                     this.typeFrames = this.partFrames
                     this.typeFrames = this.partFrames
                 }
                 }
             },
             },
+            androidDevice(param){
+                const val =param.data.device_type
+                return val === DEVICE_TYPE.NURSE_HOST ||
+                    val === DEVICE_TYPE.OTHER_HOST ||
+                    val === DEVICE_TYPE.NURSE_HOST ||
+                    val === DEVICE_TYPE.DOCTOR_HOST ||
+                    val === DEVICE_TYPE.TRANSFER_DEVICE ||
+                    val === DEVICE_TYPE.DOOR_DEVICE ||
+                    val === DEVICE_TYPE.DIGIT_BED_DEVICE
+
+            },
+            s485Device(param){
+                const val =param.data.device_type
+                return val === DEVICE_TYPE.RS485_DOOR ||
+                    val === DEVICE_TYPE.SIMULATE_BED_DEVICE && param.data.trans_rs485_id!==null
+            },
             /** 添加设备事件 **/
             /** 添加设备事件 **/
             handleAdd() {
             handleAdd() {
                 this.deviceModel = {
                 this.deviceModel = {
@@ -1216,6 +1307,21 @@
                     this.serverAddressDialogVisible = false
                     this.serverAddressDialogVisible = false
                 })
                 })
             },
             },
+
+            openDebug(param){
+                API_Device.openDebug(param.id).then(res=>{
+                    this.$message.success(this.$t('action.handleSuccess'))
+                }).catch(err=>{
+                    this.$message.error(this.$t('action.handleFailed'))
+                })
+            },
+            rebootDevice(params){
+                API_Device.rebootDevice(params.id).then(res=>{
+                    this.$message.success(this.$t('action.handleSuccess'))
+                }).catch(err=>{
+                    this.$message.error(this.$t('action.handleFailed'))
+                })
+            },
             /**
             /**
              * 判断设备是否为模拟分机这种,无法在线是设备
              * 判断设备是否为模拟分机这种,无法在线是设备
              */
              */