Commit 0fe6b0e9323fd5ead5c696ecf96338e90256d62d

Authored by xp.Huang
2 parents 31edb9d6 391c03d4

Merge branch 'ww' into 'main'

perf: fix bug && add lockUnlock button && add switch to variable image library

See merge request huang/thingskit-drawio!36
  1 +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1659059076466" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2250" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }
  2 +</style></defs><path d="M512 64C264.96 64 64 264.96 64 512s200.96 448 448 448 448-200.96 448-448S759.04 64 512 64zM512 832.352c-26.496 0-48-21.504-48-48s21.504-48 48-48 48 21.504 48 48S538.496 832.352 512 832.352zM600.576 505.184C572.736 532.992 544 561.728 544 587.552l0 54.112c0 17.664-14.336 32-32 32s-32-14.336-32-32l0-54.112c0-52.352 40-92.352 75.328-127.648C581.216 434.016 608 407.264 608 385.92c0-53.344-43.072-96.736-96-96.736-53.824 0-96 41.536-96 94.56 0 17.664-14.336 32-32 32s-32-14.336-32-32c0-87.424 71.776-158.56 160-158.56s160 72.096 160 160.736C672 433.792 635.68 470.08 600.576 505.184z" p-id="2251" fill="#dbdbdb"></path></svg>
@@ -306,7 +306,7 @@ @@ -306,7 +306,7 @@
306 var supportedDomain = (hostName.substring(hostName.length - 8, hostName.length) === '.draw.io') || 306 var supportedDomain = (hostName.substring(hostName.length - 8, hostName.length) === '.draw.io') ||
307 (hostName.substring(hostName.length - 13, hostName.length) === '.diagrams.net'); 307 (hostName.substring(hostName.length - 13, hostName.length) === '.diagrams.net');
308 308
309 - const releaseVersion = '1658915861841' 309 + const releaseVersion = '1658971884984'
310 const appMinSrc = Enable_OSS ? `${OSS_Prefix}app.min.js?v=${releaseVersion}` : `js/app.min.js?v=${releaseVersion}` 310 const appMinSrc = Enable_OSS ? `${OSS_Prefix}app.min.js?v=${releaseVersion}` : `js/app.min.js?v=${releaseVersion}`
311 function loadAppJS() { 311 function loadAppJS() {
312 mxscript(appMinSrc, function () { 312 mxscript(appMinSrc, function () {
@@ -5918,6 +5918,27 @@ App.prototype.updateButtonContainer = function() @@ -5918,6 +5918,27 @@ App.prototype.updateButtonContainer = function()
5918 { 5918 {
5919 if (this.shareButton == null) 5919 if (this.shareButton == null)
5920 { 5920 {
  5921 + // TODO thingsKit 锁定 / 解锁 按钮
  5922 + this.lockButton = document.createElement('div');
  5923 + this.lockButton.className = 'geBtn gePrimaryBtn';
  5924 + this.lockButton.style.display = 'inline-block';
  5925 + this.lockButton.style.backgroundColor = '#F2931E';
  5926 + this.lockButton.style.borderColor = '#F08705';
  5927 + this.lockButton.style.backgroundImage = 'none';
  5928 + this.lockButton.style.marginTop = '-10px';
  5929 + this.lockButton.style.lineHeight = '28px';
  5930 + this.lockButton.style.minWidth = '0px';
  5931 + this.lockButton.style.cssFloat = 'right';
  5932 + this.lockButton.setAttribute('title', '锁定 / 解锁');
  5933 + mxUtils.write(this.lockButton, '锁定 / 解锁');
  5934 + mxEvent.addListener(this.lockButton, 'click', mxUtils.bind(this, function()
  5935 + {
  5936 + if (this.actions.actions.lockUnlock.enabled){
  5937 + this.actions.actions.lockUnlock.funct()
  5938 + }
  5939 + }));
  5940 + this.buttonContainer.appendChild(this.lockButton);
  5941 +
5921 // TODO thingsKit 预览模式按钮 5942 // TODO thingsKit 预览模式按钮
5922 this.shareButton = document.createElement('div'); 5943 this.shareButton = document.createElement('div');
5923 this.shareButton.className = 'geBtn gePrimaryBtn'; 5944 this.shareButton.className = 'geBtn gePrimaryBtn';
@@ -6005,6 +6026,8 @@ App.prototype.updateButtonContainer = function() @@ -6005,6 +6026,8 @@ App.prototype.updateButtonContainer = function()
6005 this.shareButton = null; 6026 this.shareButton = null;
6006 this.saveButton.parentNode.removeChild(this.saveButton); 6027 this.saveButton.parentNode.removeChild(this.saveButton);
6007 this.saveButton = null; 6028 this.saveButton = null;
  6029 + this.lockButton.parentNode.removeChild(this.lockButton);
  6030 + this.lockButton = null;
6008 } 6031 }
6009 6032
6010 //Fetch notifications 6033 //Fetch notifications
@@ -321,9 +321,14 @@ @@ -321,9 +321,14 @@
321 SWITCH_STATE_SETTING: 'stateSetting', 321 SWITCH_STATE_SETTING: 'stateSetting',
322 322
323 /** 323 /**
324 - * @description 只有单事件 324 + * @description 只有单事件
325 */ 325 */
326 - ONLY_SINGLE_EVENT: 'onlySingleEvent' 326 + ONLY_SINGLE_EVENT: 'onlySingleEvent',
  327 +
  328 + /**
  329 + * @description 运行于停止
  330 + */
  331 + RUNNING_AND_STOP: 'runningAndStop'
327 } 332 }
328 333
329 /** 334 /**
@@ -680,9 +685,9 @@ @@ -680,9 +685,9 @@
680 //更多图形,显示出来的的标题跟id,同时包括图片 685 //更多图形,显示出来的的标题跟id,同时包括图片
681 686
682 // TODO thingsKit 设置数据绑定展示面板 687 // TODO thingsKit 设置数据绑定展示面板
683 - const { LINE_CHART_EXPAND, BAR_CHART_EXPAND, DYNAMIC_EFFECT, DATA_SOURCE, VAR_IMAGE, INTERACTION, VIDEO: VIDEO_PANEL, SWITCH_STATE_SETTING, ONLY_SINGLE_EVENT } = this.enumPermissionPanel 688 + const { LINE_CHART_EXPAND, BAR_CHART_EXPAND, DYNAMIC_EFFECT, DATA_SOURCE, VAR_IMAGE, INTERACTION, VIDEO: VIDEO_PANEL, SWITCH_STATE_SETTING, ONLY_SINGLE_EVENT, RUNNING_AND_STOP } = this.enumPermissionPanel
684 const { LINE, LINE_CHART, REAL_TIME, TITLE, VARIABLE, DEFAULT, BAR_CHART, VIDEO, SWITCH, PARAMS_SETTING_BUTTON } = this.enumComponentType 689 const { LINE, LINE_CHART, REAL_TIME, TITLE, VARIABLE, DEFAULT, BAR_CHART, VIDEO, SWITCH, PARAMS_SETTING_BUTTON } = this.enumComponentType
685 - this.setComponentPermission(LINE, [DYNAMIC_EFFECT]) 690 + this.setComponentPermission(LINE, [RUNNING_AND_STOP, DYNAMIC_EFFECT])
686 this.setComponentPermission(DEFAULT, [DYNAMIC_EFFECT]) 691 this.setComponentPermission(DEFAULT, [DYNAMIC_EFFECT])
687 this.setComponentPermission(REAL_TIME, [DYNAMIC_EFFECT]) 692 this.setComponentPermission(REAL_TIME, [DYNAMIC_EFFECT])
688 this.setComponentPermission(TITLE, [INTERACTION, DYNAMIC_EFFECT]) 693 this.setComponentPermission(TITLE, [INTERACTION, DYNAMIC_EFFECT])
@@ -697,6 +702,7 @@ @@ -697,6 +702,7 @@
697 var thingskitEntries = [ 702 var thingskitEntries = [
698 { title: mxResources.get('general'), id: 'general', image: IMAGE_PATH + '/sidebar-general.png' }, 703 { title: mxResources.get('general'), id: 'general', image: IMAGE_PATH + '/sidebar-general.png' },
699 { title: mxResources.get('arrows'), id: 'arrows2', image: IMAGE_PATH + '/sidebar-arrows2.png' }, 704 { title: mxResources.get('arrows'), id: 'arrows2', image: IMAGE_PATH + '/sidebar-arrows2.png' },
  705 + { title: '控制元件', id: 'control', image: IMAGE_PATH + '/thingskit/控制元件.png' },
700 { title: "风机", id: 'fan', image: IMAGE_PATH + '/thingskit/风机.png' }, 706 { title: "风机", id: 'fan', image: IMAGE_PATH + '/thingskit/风机.png' },
701 { title: "发动机", id: 'engine', image: IMAGE_PATH + '/thingskit/发动机.png' }, 707 { title: "发动机", id: 'engine', image: IMAGE_PATH + '/thingskit/发动机.png' },
702 { title: "阀门", id: 'valve', image: IMAGE_PATH + '/thingskit/阀门.png' }, 708 { title: "阀门", id: 'valve', image: IMAGE_PATH + '/thingskit/阀门.png' },
@@ -40,7 +40,7 @@ @@ -40,7 +40,7 @@
40 const cell = new mxCell(template, new mxGeometry(0, 0, 180, 60), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;'); 40 const cell = new mxCell(template, new mxGeometry(0, 0, 180, 60), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;');
41 cell.vertex = true; 41 cell.vertex = true;
42 this.setCellAttributes(cell, { 42 this.setCellAttributes(cell, {
43 - [basicAttr.COMPONENT_TYPE]: componentType.LINE, 43 + [basicAttr.COMPONENT_TYPE]: componentType.REAL_TIME,
44 placeholders: '1', 44 placeholders: '1',
45 currentDate: currentDate, 45 currentDate: currentDate,
46 }) 46 })
@@ -55,6 +55,11 @@ @@ -55,6 +55,11 @@
55 })); 55 }));
56 }) 56 })
57 57
  58 + this.setVariableImageLib('switch', '开关', [
  59 + { name: 'switch-on', path: '/images/thingskit/switch-on.svg', staticPath: `${Proxy_Prefix}/images/thingskit/switch-on.svg` },
  60 + { name: 'switch-off', path: '/images/thingskit/switch-on.svg', staticPath: `${Proxy_Prefix}/images/thingskit/switch-off.svg` },
  61 + ])
  62 +
58 this.setVariableImageLib(dt, label, lib) 63 this.setVariableImageLib(dt, label, lib)
59 64
60 this.addPaletteFunctions(dt, label, false, fns); 65 this.addPaletteFunctions(dt, label, false, fns);
@@ -588,6 +588,17 @@ Format.prototype.immediateRefresh = function () { @@ -588,6 +588,17 @@ Format.prototype.immediateRefresh = function () {
588 addClickHandler(label, stylePanel, idx++); 588 addClickHandler(label, stylePanel, idx++);
589 } 589 }
590 590
  591 + if (validateHasDataSourcePanel()) {
  592 + // bind data
  593 + mxUtils.write(label4, "数据绑定");
  594 + div.appendChild(label4);
  595 +
  596 + var dataPanel = div.cloneNode(false);
  597 + dataPanel.style.display = "none";
  598 + this.panels.push(new DataFormatPanel(this, ui, dataPanel));
  599 + this.container.appendChild(dataPanel);
  600 + }
  601 +
591 // Text 602 // Text
592 mxUtils.write(label2, mxResources.get("text")); 603 mxUtils.write(label2, mxResources.get("text"));
593 div.appendChild(label2); 604 div.appendChild(label2);
@@ -606,17 +617,6 @@ Format.prototype.immediateRefresh = function () { @@ -606,17 +617,6 @@ Format.prototype.immediateRefresh = function () {
606 this.panels.push(new ArrangePanel(this, ui, arrangePanel)); 617 this.panels.push(new ArrangePanel(this, ui, arrangePanel));
607 this.container.appendChild(arrangePanel); 618 this.container.appendChild(arrangePanel);
608 619
609 - if (validateHasDataSourcePanel()) {  
610 - // bind data  
611 - mxUtils.write(label4, "数据绑定");  
612 - div.appendChild(label4);  
613 -  
614 - var dataPanel = div.cloneNode(false);  
615 - dataPanel.style.display = "none";  
616 - this.panels.push(new DataFormatPanel(this, ui, dataPanel));  
617 - this.container.appendChild(dataPanel);  
618 - }  
619 -  
620 if (ss.cells.length > 0) { 620 if (ss.cells.length > 0) {
621 addClickHandler(label2, textPanel, idx++); 621 addClickHandler(label2, textPanel, idx++);
622 } else { 622 } else {
@@ -5016,7 +5016,8 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5016,7 +5016,8 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5016 FLASH: 'FLASH', 5016 FLASH: 'FLASH',
5017 ROTATE: 'ROTATE', 5017 ROTATE: 'ROTATE',
5018 IMAGE: 'IMAGE', 5018 IMAGE: 'IMAGE',
5019 - SWITCH: 'SWITCH' 5019 + SWITCH: 'SWITCH',
  5020 + RUNNING: 'RUNNING'
5020 } 5021 }
5021 5022
5022 const interactionList = [ 5023 const interactionList = [
@@ -5133,7 +5134,8 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5133,7 +5134,8 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5133 [permissionKey.VAR_IMAGE]: createVarImagePanel, 5134 [permissionKey.VAR_IMAGE]: createVarImagePanel,
5134 [permissionKey.VIDEO]: createVideoBindPanel, 5135 [permissionKey.VIDEO]: createVideoBindPanel,
5135 [permissionKey.SWITCH_STATE_SETTING]: createSwitchStateSettingPanel, 5136 [permissionKey.SWITCH_STATE_SETTING]: createSwitchStateSettingPanel,
5136 - [permissionKey.ONLY_SINGLE_EVENT]: createParamsSettingButtonPanel 5137 + [permissionKey.ONLY_SINGLE_EVENT]: createParamsSettingButtonPanel,
  5138 + [permissionKey.RUNNING_AND_STOP]: createRunningAndStopPanel
5137 } 5139 }
5138 5140
5139 5141
@@ -5404,6 +5406,17 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -5404,6 +5406,17 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5404 } 5406 }
5405 5407
5406 /** 5408 /**
  5409 + * @description 水流动效
  5410 + */
  5411 + function createRunningAndStopPanel() {
  5412 + dynamicEffectList.push({
  5413 + label: '水流动效',
  5414 + type: enumDynamicEffectType.RUNNING,
  5415 + category: enumCategory.ACT
  5416 + })
  5417 + }
  5418 +
  5419 + /**
5407 * @description 是否是折线图 5420 * @description 是否是折线图
5408 * @param {boolean} isLineChart 5421 * @param {boolean} isLineChart
5409 */ 5422 */
@@ -6412,7 +6425,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6412,7 +6425,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6412 } 6425 }
6413 6426
6414 const sendInstructionWay = { 6427 const sendInstructionWay = {
6415 - ONE_WAR: 'oneway', 6428 + ONE_WAY: 'oneway',
6416 TWO_WAY: 'twoway', 6429 TWO_WAY: 'twoway',
6417 } 6430 }
6418 6431
@@ -6493,8 +6506,8 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6493,8 +6506,8 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6493 <td> 6506 <td>
6494 <form action="" style="display: flex"> 6507 <form action="" style="display: flex">
6495 <div class="override__radio-default"> 6508 <div class="override__radio-default">
6496 - <input id="${getRowFilter(addRowNumber)}${sendInstructionWay.ONE_WAR}" type="radio" name="${enumConst.WAY}" lay-ignore value="${sendInstructionWay.ONE_WAR}" title="单向" checked="">  
6497 - <label for="${getRowFilter(addRowNumber)}${sendInstructionWay.ONE_WAR}" class="override__radio-label">单向</label> 6509 + <input id="${getRowFilter(addRowNumber)}${sendInstructionWay.ONE_WAY}" type="radio" name="${enumConst.WAY}" lay-ignore value="${sendInstructionWay.ONE_WAY}" title="单向" checked="">
  6510 + <label for="${getRowFilter(addRowNumber)}${sendInstructionWay.ONE_WAY}" class="override__radio-label">单向</label>
6498 </div> 6511 </div>
6499 <div class="override__radio-default"> 6512 <div class="override__radio-default">
6500 <input id="${getRowFilter(addRowNumber)}${sendInstructionWay.TWO_WAY}" type="radio" name="${enumConst.WAY}" lay-ignore value="${sendInstructionWay.TWO_WAY}" title="双向"> 6513 <input id="${getRowFilter(addRowNumber)}${sendInstructionWay.TWO_WAY}" type="radio" name="${enumConst.WAY}" lay-ignore value="${sendInstructionWay.TWO_WAY}" title="双向">
@@ -6784,6 +6797,18 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6784,6 +6797,18 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6784 ACTION: 'actionType', 6797 ACTION: 'actionType',
6785 PAGE_VALUE: 'pageValue', 6798 PAGE_VALUE: 'pageValue',
6786 LINK_VALUE: 'linkValue', 6799 LINK_VALUE: 'linkValue',
  6800 +
  6801 + /**
  6802 + * @description 下发指令
  6803 + */
  6804 + COMMAND: 'command',
  6805 +
  6806 + /**
  6807 + * @description 属性占位符
  6808 + */
  6809 + ATTR_PLACEHOLDER: 'attrPlaceholder',
  6810 +
  6811 + WAY: 'way'
6787 } 6812 }
6788 6813
6789 /** 6814 /**
@@ -6796,6 +6821,11 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6796,6 +6821,11 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6796 [enumActionType.LINK]: enumConst.LINK_VALUE, 6821 [enumActionType.LINK]: enumConst.LINK_VALUE,
6797 } 6822 }
6798 6823
  6824 + const enumWayType = {
  6825 + ONE_WAY: 'oneway',
  6826 + TWO_WAY: 'twoway'
  6827 + }
  6828 +
6799 const enumActionEl = { 6829 const enumActionEl = {
6800 /** 6830 /**
6801 * @description 表单 lay-filter 6831 * @description 表单 lay-filter
@@ -6821,6 +6851,18 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6821,6 +6851,18 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6821 * @description layer submit filter 6851 * @description layer submit filter
6822 */ 6852 */
6823 LAYER_SUBMIT_FILTER: 'dynamicLinkLayerFilter', 6853 LAYER_SUBMIT_FILTER: 'dynamicLinkLayerFilter',
  6854 +
  6855 + /**
  6856 + * @description JSON 编辑器容器
  6857 + */
  6858 + EDITOR_CONTAINER: 'editorContainerEL',
  6859 +
  6860 + /**
  6861 + * @description JSON 编辑器
  6862 + */
  6863 + EDITOR: 'EDITOR',
  6864 +
  6865 + WAY_SELECT: 'dynamicWaySelectEl'
6824 } 6866 }
6825 6867
6826 /** 6868 /**
@@ -6838,15 +6880,33 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6838,15 +6880,33 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6838 const val = { 6880 const val = {
6839 [enumConst.ACTION]: content.type, 6881 [enumConst.ACTION]: content.type,
6840 [enumGetValue[content.type]]: content.value, 6882 [enumGetValue[content.type]]: content.value,
  6883 + [enumConst.WAY]: content[enumConst.WAY]
6841 } 6884 }
6842 - if (content.type === enumActionType.PAGE) {  
6843 - $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'block' }) 6885 + controlFormDisplay(content.type)
  6886 + form.val(enumActionEl.FORM_FILTER, val)
  6887 + }
  6888 +
  6889 + /**
  6890 + * @description 控制form
  6891 + * @param {enumActionType} value
  6892 + */
  6893 + function controlFormDisplay(value) {
  6894 + if (value === enumActionType.PAGE) {
6844 $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'none' }) 6895 $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'none' })
6845 - } else if (content.type === enumActionType.PARAMS_SETTING) { 6896 + $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'block' })
  6897 + $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: 'none' })
  6898 + $(`#${enumActionEl.WAY_SELECT}`).css({ display: 'none' })
  6899 + } else if (value === enumActionType.LINK) {
6846 $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'none' }) 6900 $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'none' })
  6901 + $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'block' })
  6902 + $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: 'none' })
  6903 + $(`#${enumActionEl.WAY_SELECT}`).css({ display: 'none' })
  6904 + } else if (value === enumActionType.PARAMS_SETTING) {
6847 $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'none' }) 6905 $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'none' })
  6906 + $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'none' })
  6907 + $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: 'flex' })
  6908 + $(`#${enumActionEl.WAY_SELECT}`).css({ display: 'block' })
6848 } 6909 }
6849 - form.val(enumActionEl.FORM_FILTER, val)  
6850 } 6910 }
6851 6911
6852 /** 6912 /**
@@ -6854,6 +6914,15 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6854,6 +6914,15 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6854 */ 6914 */
6855 async function submit(callback) { 6915 async function submit(callback) {
6856 const formVal = form.val(enumActionEl.FORM_FILTER) 6916 const formVal = form.val(enumActionEl.FORM_FILTER)
  6917 + const isParamsSetting = formVal[enumConst.ACTION] === enumActionType.PARAMS_SETTING
  6918 + if (isParamsSetting) {
  6919 + if (!isJson(formVal[enumConst.COMMAND])) {
  6920 + console.log()
  6921 + UseLayUi.topErrorMsg('命令配置存在错误')
  6922 + return
  6923 + }
  6924 + }
  6925 +
6857 const data = { 6926 const data = {
6858 type: event.data.type, 6927 type: event.data.type,
6859 configurationId, 6928 configurationId,
@@ -6864,6 +6933,10 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6864,6 +6933,10 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6864 content: { 6933 content: {
6865 type: formVal[enumConst.ACTION], 6934 type: formVal[enumConst.ACTION],
6866 value: formVal[enumGetValue[formVal[enumConst.ACTION]]], 6935 value: formVal[enumGetValue[formVal[enumConst.ACTION]]],
  6936 + ...(isParamsSetting ? {
  6937 + [enumConst.COMMAND]: formVal[enumConst.COMMAND],
  6938 + [enumConst.WAY]: formVal[enumConst.WAY]
  6939 + } : {}),
6867 }, 6940 },
6868 } 6941 }
6869 await to(autoSaveGraphInfo()) 6942 await to(autoSaveGraphInfo())
@@ -6899,16 +6972,53 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6899,16 +6972,53 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6899 function generatorEventListen() { 6972 function generatorEventListen() {
6900 form.on(`select(${enumActionEl.ACTION_SELECT_FILTER})`, (data) => { 6973 form.on(`select(${enumActionEl.ACTION_SELECT_FILTER})`, (data) => {
6901 const { value } = data 6974 const { value } = data
6902 - if (value === enumActionType.PAGE) {  
6903 - $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'none' })  
6904 - $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'block' })  
6905 - } else if (value === enumActionType.LINK) {  
6906 - $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'none' })  
6907 - $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'block' })  
6908 - } else if (value === enumActionType.PARAMS_SETTING) {  
6909 - $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'none' })  
6910 - $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'none' }) 6975 + controlFormDisplay(value)
  6976 + })
  6977 + }
  6978 +
  6979 + function isJson(string) {
  6980 + if (typeof string === 'string') {
  6981 + try {
  6982 + const obj = JSON.parse(string)
  6983 + if (typeof obj === 'object' && obj !== null) {
  6984 + return true
  6985 + }
  6986 + } catch (e) {
  6987 + return false
6911 } 6988 }
  6989 + }
  6990 + return false
  6991 + }
  6992 +
  6993 + function jsonParse(value) {
  6994 + try {
  6995 + return JSON.parse(value)
  6996 + } catch (error) {
  6997 + return {}
  6998 + }
  6999 + }
  7000 +
  7001 +
  7002 + /**
  7003 + * @description 创建JSON编辑器
  7004 + * @param el
  7005 + * @param datum
  7006 + */
  7007 + function createEditor(record) {
  7008 + let defaultValue = { [enumConst.ATTR_PLACEHOLDER]: 0 }
  7009 + const editor = ace.edit(enumActionEl.EDITOR, {
  7010 + maxLines: 18, // 最大行数,超过会自动出现滚动条
  7011 + minLines: 10, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小
  7012 + fontSize: 14, // 编辑器内字体大小
  7013 + tabSize: 2, // 制表符设置为 4 个空格大小
  7014 + });
  7015 + if (record.content && record.content[enumConst.COMMAND]) defaultValue = jsonParse(record.content[enumConst.COMMAND])
  7016 + const stringValue = JSON.stringify(defaultValue, null, 2)
  7017 + editor.insert(stringValue)
  7018 + $(`#${enumActionEl.EDITOR_CONTAINER}`).parent().find(`textarea[name="${enumConst.COMMAND}"]`).val(stringValue)
  7019 + editor.session.setMode("ace/mode/json");
  7020 + editor.getSession().on('change', (event, editor) => {
  7021 + $(`#${enumActionEl.EDITOR_CONTAINER}`).parent().find(`textarea[name="${enumConst.COMMAND}"]`).val(editor.getValue())
6912 }) 7022 })
6913 } 7023 }
6914 7024
@@ -6919,7 +7029,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6919,7 +7029,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6919 7029
6920 const content = ` 7030 const content = `
6921 <form class="layui-form" lay-filter="${enumActionEl.FORM_FILTER}"> 7031 <form class="layui-form" lay-filter="${enumActionEl.FORM_FILTER}">
6922 - <div style="width:400px"> 7032 + <div style="width: 450px">
6923 <div class="layui-form-item"> 7033 <div class="layui-form-item">
6924 <label class="layui-form-label">事件</label> 7034 <label class="layui-form-label">事件</label>
6925 <div class="layui-input-block"> 7035 <div class="layui-input-block">
@@ -6948,6 +7058,18 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6948,6 +7058,18 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6948 </select> 7058 </select>
6949 </div> 7059 </div>
6950 </div> 7060 </div>
  7061 + <div class="layui-form-item" id="${enumActionEl.WAY_SELECT}" style="display:none">
  7062 + <label class="layui-form-label">单向/双向</label>
  7063 + <div class="layui-input-block">
  7064 + <input type="radio" name="${enumConst.WAY}" value="${enumWayType.ONE_WAY}" title="单向" checked="">
  7065 + <input type="radio" name="${enumConst.WAY}" value="${enumWayType.TWO_WAY}" title="双向">
  7066 + </div>
  7067 + </div>
  7068 + <div id="${enumActionEl.EDITOR_CONTAINER}" style="display: none;">
  7069 + <div style="width: 80px; text-align: right; padding: 9px 15px;flex: 0 0 80px;">命令</div>
  7070 + <div id="${enumActionEl.EDITOR}" style="width: 100%; height: 100%;border: 2px solid #eee;"></div>
  7071 + <textarea name="${enumConst.COMMAND}" style="display: none;" />
  7072 + </div>
6951 </div> 7073 </div>
6952 </form> 7074 </form>
6953 ` 7075 `
@@ -6976,6 +7098,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6976,6 +7098,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6976 generatorEventListen() 7098 generatorEventListen()
6977 const info = getLayerBindInfo('event', type) 7099 const info = getLayerBindInfo('event', type)
6978 Object.assign(recordData, { enabled: info.enabled }) 7100 Object.assign(recordData, { enabled: info.enabled })
  7101 + createEditor(info)
6979 form.render(null, enumActionEl.FORM_FILTER) 7102 form.render(null, enumActionEl.FORM_FILTER)
6980 if (info) echoFormData(info) 7103 if (info) echoFormData(info)
6981 }, 7104 },
@@ -6991,12 +7114,14 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6991,12 +7114,14 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6991 */ 7114 */
6992 function handleDataDynamicEffect(event) { 7115 function handleDataDynamicEffect(event) {
6993 7116
6994 - const IS_DISPLAY = event.data.type === 'DISPLAY' 7117 + const IS_DISPLAY = event.data.type === enumDynamicEffectType.DISPLAY
  7118 + const IS_RUNNING = event.data.type === enumDynamicEffectType.RUNNING
6995 7119
6996 const enumEventType = { 7120 const enumEventType = {
6997 FLASH: '闪烁', 7121 FLASH: '闪烁',
6998 DISPLAY: '显示/隐藏', 7122 DISPLAY: '显示/隐藏',
6999 ROTATE: '旋转', 7123 ROTATE: '旋转',
  7124 + RUNNING: '水流动效'
7000 } 7125 }
7001 7126
7002 const enumActionEl = { 7127 const enumActionEl = {
@@ -7031,6 +7156,18 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7031,6 +7156,18 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7031 7156
7032 const enumDisplayType = HandleDynamicEffect.enumDisplayType 7157 const enumDisplayType = HandleDynamicEffect.enumDisplayType
7033 7158
  7159 + const enumRunningType = HandleDynamicEffect.enumRunningType
  7160 +
  7161 + const displayOptions = [
  7162 + { name: '显示', id: enumDisplayType.SHOW },
  7163 + { name: '隐藏', id: enumDisplayType.HIDDEN },
  7164 + ]
  7165 +
  7166 + const runningOptions = [
  7167 + { name: '流动', id: enumRunningType.RUN },
  7168 + { name: '静止', id: enumRunningType.STOP },
  7169 + ]
  7170 +
7034 /** 7171 /**
7035 * @description 7172 * @description
7036 */ 7173 */
@@ -7040,12 +7177,8 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7040,12 +7177,8 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7040 enabled: false 7177 enabled: false
7041 } 7178 }
7042 7179
7043 - function generatorDisplayOptions() {  
7044 - const options = [  
7045 - { name: '显示', id: enumDisplayType.SHOW },  
7046 - { name: '隐藏', id: enumDisplayType.HIDDEN },  
7047 - ]  
7048 - const template = UseLayUi.generateOptionTemplate({ dataSource: options }) 7180 + function generateStateOptions(options = []) {
  7181 + const template = UseLayUi.generateOptionTemplate({ dataSource: options, addPlaceholderOption: false })
7049 return ` 7182 return `
7050 <div class="layui-form-item" style="margin-bottom: 0px"> 7183 <div class="layui-form-item" style="margin-bottom: 0px">
7051 <div class="layui-input-block" style="margin-left: 0px;"> 7184 <div class="layui-input-block" style="margin-left: 0px;">
@@ -7061,7 +7194,8 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7061,7 +7194,8 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7061 function addRecord() { 7194 function addRecord() {
7062 const content = ` 7195 const content = `
7063 <tr class="layui-form" lay-filter="${getRowFilter(addRowNumber)}"> 7196 <tr class="layui-form" lay-filter="${getRowFilter(addRowNumber)}">
7064 - ${IS_DISPLAY && `<td>${generatorDisplayOptions()}</td>`} 7197 + ${IS_DISPLAY && `<td>${generateStateOptions(displayOptions)}</td>`}
  7198 + ${IS_RUNNING && `<td>${generateStateOptions(runningOptions)}</td>`}
7065 <td> 7199 <td>
7066 <input autocomplete="off" lay-verType="tips" lay-verify="required" type="number" name="${enumConst.MIN}" class="layui-input ${enumActionEl.MIN_FILTER}"> 7200 <input autocomplete="off" lay-verType="tips" lay-verify="required" type="number" name="${enumConst.MIN}" class="layui-input ${enumActionEl.MIN_FILTER}">
7067 </td> 7201 </td>
@@ -7075,7 +7209,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7075,7 +7209,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7075 ` 7209 `
7076 addRowNumber++ 7210 addRowNumber++
7077 $(`#${enumActionEl.TABLE_BODY_EL}`).append(content) 7211 $(`#${enumActionEl.TABLE_BODY_EL}`).append(content)
7078 - if (IS_DISPLAY) { 7212 + if (IS_DISPLAY || IS_RUNNING) {
7079 form.render() 7213 form.render()
7080 } 7214 }
7081 } 7215 }
@@ -7232,6 +7366,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7232,6 +7366,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7232 <thead> 7366 <thead>
7233 <tr> 7367 <tr>
7234 ${IS_DISPLAY ? '<th style="text-align:center">类型</th>' : ''} 7368 ${IS_DISPLAY ? '<th style="text-align:center">类型</th>' : ''}
  7369 + ${IS_RUNNING ? '<th style="text-align:center">类型</th>' : ''}
7235 <th style="text-align:center">最小值(>=)</th> 7370 <th style="text-align:center">最小值(>=)</th>
7236 <th style="text-align:center">最大值(<=)</th> 7371 <th style="text-align:center">最大值(<=)</th>
7237 <th style="text-align:center">操作</th> 7372 <th style="text-align:center">操作</th>
@@ -7251,7 +7386,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7251,7 +7386,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7251 skin: 'event-layer__override', 7386 skin: 'event-layer__override',
7252 btn: ['保存', '取消'], 7387 btn: ['保存', '取消'],
7253 offset: '100px', 7388 offset: '100px',
7254 - area: IS_DISPLAY ? '1000px' : '800PX', 7389 + area: (IS_DISPLAY || IS_RUNNING) ? '1000px' : '800PX',
7255 success(layero) { 7390 success(layero) {
7256 $(layero).addClass('layui-form').find('.layui-layer-btn0').attr({ 7391 $(layero).addClass('layui-form').find('.layui-layer-btn0').attr({
7257 'lay-submit': '', 7392 'lay-submit': '',
@@ -7447,6 +7582,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7447,6 +7582,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7447 const [err, res] = await to(ConfigurationNodeApi.updateNodeAct(formModel)) 7582 const [err, res] = await to(ConfigurationNodeApi.updateNodeAct(formModel))
7448 if (err) return 7583 if (err) return
7449 overrideCurrentData('act', 'type', res) 7584 overrideCurrentData('act', 'type', res)
  7585 + echoActionType()
7450 UseLayUi.successMsg() 7586 UseLayUi.successMsg()
7451 callback() 7587 callback()
7452 } 7588 }
@@ -8129,7 +8265,6 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -8129,7 +8265,6 @@ DataFormatPanel.prototype.addDataFont = function (container) {
8129 generateUploadLayerComponent((imageState) => { 8265 generateUploadLayerComponent((imageState) => {
8130 $(el).find('img').attr('src', imageState[enumConst.IMAGE_GALLERY_IMAGE_PATH]) 8266 $(el).find('img').attr('src', imageState[enumConst.IMAGE_GALLERY_IMAGE_PATH])
8131 form.val(getFormFilter, imageState) 8267 form.val(getFormFilter, imageState)
8132 - console.log(form.val(getFormFilter))  
8133 }) 8268 })
8134 }) 8269 })
8135 } 8270 }
@@ -8138,6 +8273,10 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -8138,6 +8273,10 @@ DataFormatPanel.prototype.addDataFont = function (container) {
8138 return { getValue, setValue } 8273 return { getValue, setValue }
8139 } 8274 }
8140 8275
  8276 + function createHelpMessage() {
  8277 + return `<span class="thingskit-help-message"><img src="${Proxy_Prefix}/images/thingskit/question.svg" /></span>`
  8278 + }
  8279 +
8141 // 异步设置此处才能生效 -- 设置默认select和样式和初始化侧边栏生成组件和事件绑定 8280 // 异步设置此处才能生效 -- 设置默认select和样式和初始化侧边栏生成组件和事件绑定
8142 setTimeout(() => { 8281 setTimeout(() => {
8143 8282
@@ -8166,8 +8305,11 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -8166,8 +8305,11 @@ DataFormatPanel.prototype.addDataFont = function (container) {
8166 $(`#${enumDynamicEffectType.FLASH}`).click({ type: enumDynamicEffectType.FLASH }, proxyFn(handleDataDynamicEffect)); 8305 $(`#${enumDynamicEffectType.FLASH}`).click({ type: enumDynamicEffectType.FLASH }, proxyFn(handleDataDynamicEffect));
8167 $(`#${enumDynamicEffectType.DISPLAY}`).click({ type: enumDynamicEffectType.DISPLAY }, proxyFn(handleDataDynamicEffect)); 8306 $(`#${enumDynamicEffectType.DISPLAY}`).click({ type: enumDynamicEffectType.DISPLAY }, proxyFn(handleDataDynamicEffect));
8168 $(`#${enumDynamicEffectType.ROTATE}`).click({ type: enumDynamicEffectType.ROTATE }, proxyFn(handleDataDynamicEffect)); 8307 $(`#${enumDynamicEffectType.ROTATE}`).click({ type: enumDynamicEffectType.ROTATE }, proxyFn(handleDataDynamicEffect));
  8308 + $(`#${enumDynamicEffectType.RUNNING}`).click({ type: enumDynamicEffectType.RUNNING }, proxyFn(handleDataDynamicEffect))
8169 8309
8170 $(`#${enumDynamicEffectType.SWITCH}`).click({ type: enumDynamicEffectType.SWITCH }, proxyFn(handleStateSetting)) 8310 $(`#${enumDynamicEffectType.SWITCH}`).click({ type: enumDynamicEffectType.SWITCH }, proxyFn(handleStateSetting))
  8311 +
  8312 +
8171 }); 8313 });
8172 }; 8314 };
8173 8315
@@ -12379,14 +12521,21 @@ class UseLayUi { @@ -12379,14 +12521,21 @@ class UseLayUi {
12379 UseLayUi.msg(msg, { ...options, icon: 5 }) 12521 UseLayUi.msg(msg, { ...options, icon: 5 })
12380 } 12522 }
12381 12523
12382 - static topSuccessMsg(msg = '操作成功', options) { 12524 + static topMsg(msg, options, icon) {
12383 const { layer } = layui 12525 const { layer } = layui
12384 - layer.msg(`<div style="padding: 20px; display: flex; align-items: center;"><i class="layui-layer-ico layui-layer-ico6" style="width: 30px;height: 30px;"></i><span style="margin-left: 5px">${msg}</span></div>`, { ...options, type: 1, icon: 6, time: 2000, }) 12526 + layer.msg(`<div style="padding: 20px; display: flex; align-items: center;"><i class="layui-layer-ico layui-layer-ico6" style="width: 30px;height: 30px;"></i><span style="margin-left: 5px">${msg}</span></div>`, { ...options, type: 1, icon, time: 2000, })
  12527 + }
  12528 +
  12529 + static topSuccessMsg(msg = '操作成功', options) {
  12530 + this.topMsg(msg, options, 6)
12385 } 12531 }
12386 12532
12387 static topErrorMsg(msg = '操作失败', options) { 12533 static topErrorMsg(msg = '操作失败', options) {
12388 - const { layer } = layui  
12389 - layer.msg(`<div style="padding: 20px; display: flex; align-items: center;"><i class="layui-layer-ico layui-layer-ico5" style="width: 30px;height: 30px;"></i><span style="margin-left: 5px">${msg}</span></div>`, { ...options, type: 1, icon: 5, time: 2000, }) 12534 + this.topMsg(msg, options, 5)
  12535 + }
  12536 +
  12537 + static topInfoMsg(msg = '提示', options) {
  12538 + this.topMsg(msg, options, 0)
12390 } 12539 }
12391 } 12540 }
12392 12541
@@ -13230,20 +13379,24 @@ class HandleDataSource { @@ -13230,20 +13379,24 @@ class HandleDataSource {
13230 const [[timespan, receiveValue] = []] = data[attr] || [] 13379 const [[timespan, receiveValue] = []] = data[attr] || []
13231 const switchConfig = this.DispatchInstance.contentData.act.find(item => item.id === nodeId && item.type === 'SWITCH') 13380 const switchConfig = this.DispatchInstance.contentData.act.find(item => item.id === nodeId && item.type === 'SWITCH')
13232 const { condition = [] } = switchConfig || {} 13381 const { condition = [] } = switchConfig || {}
13233 - let reg = /image=images[^;]+/g 13382 + let reg = /image=[^;]+/g
13234 let flag = false 13383 let flag = false
13235 for (const item of condition) { 13384 for (const item of condition) {
13236 const { value, imagePath } = item || {} 13385 const { value, imagePath } = item || {}
13237 if (Number(receiveValue) === Number(value)) { 13386 if (Number(receiveValue) === Number(value)) {
13238 flag = true 13387 flag = true
13239 - const style = node.getStyle()  
13240 - node.setStyle(style.replace(reg, `image=${imagePath}`)) 13388 + this.updatePage(() => {
  13389 + const style = node.getStyle()
  13390 + node.setStyle(style.replace(reg, `image=${imagePath}`))
  13391 + }, node)
13241 break 13392 break
13242 } 13393 }
13243 } 13394 }
13244 if (!flag) { 13395 if (!flag) {
13245 - const style = node.getStyle()  
13246 - node.setStyle(style.replace(reg, `image=images/thingskit/not-standard-value.svg`)) 13396 + this.updatePage(() => {
  13397 + const style = node.getStyle()
  13398 + node.setStyle(style.replace(reg, `image=images/thingskit/not-standard-value.svg`))
  13399 + }, node)
13247 } 13400 }
13248 } 13401 }
13249 13402
@@ -13252,7 +13405,9 @@ class HandleDataSource { @@ -13252,7 +13405,9 @@ class HandleDataSource {
13252 const node = this.getNodeByCmdId(subscriptionId) 13405 const node = this.getNodeByCmdId(subscriptionId)
13253 const { attr } = this.getBindData(subscriptionId) 13406 const { attr } = this.getBindData(subscriptionId)
13254 const [[timespan, receiveValue] = []] = data[attr] || [] 13407 const [[timespan, receiveValue] = []] = data[attr] || []
13255 - node.setAttribute('label', `<button class="param-setting-button">${receiveValue}</button>`) 13408 + this.updatePage(() => {
  13409 + node.setAttribute('label', `<button class="param-setting-button">${receiveValue}</button>`)
  13410 + }, node)
13256 } 13411 }
13257 13412
13258 /** 13413 /**
@@ -13521,9 +13676,6 @@ class HandleDataSource { @@ -13521,9 +13676,6 @@ class HandleDataSource {
13521 } 13676 }
13522 13677
13523 instance.setOption(chartOption) 13678 instance.setOption(chartOption)
13524 - instance.on('dataZoom', () => {  
13525 - console.log(instance.getOption())  
13526 - })  
13527 // instance.on('mouseover', stop) 13679 // instance.on('mouseover', stop)
13528 // instance.on('mouseout', goMove) 13680 // instance.on('mouseout', goMove)
13529 // autoMove() 13681 // autoMove()
@@ -13641,6 +13793,13 @@ class HandleDataInteraction { @@ -13641,6 +13793,13 @@ class HandleDataInteraction {
13641 } 13793 }
13642 13794
13643 /** 13795 /**
  13796 + * @description 获取页面数据
  13797 + */
  13798 + get contentData() {
  13799 + return DispatchCenter.instance.contentData
  13800 + }
  13801 +
  13802 + /**
13644 * @description 事件映射 13803 * @description 事件映射
13645 */ 13804 */
13646 generatorEventMapping() { 13805 generatorEventMapping() {
@@ -13741,7 +13900,7 @@ class HandleDataInteraction { @@ -13741,7 +13900,7 @@ class HandleDataInteraction {
13741 } else if (type === DispatchCenter.enumPageType.LINK && value) { 13900 } else if (type === DispatchCenter.enumPageType.LINK && value) {
13742 window.open(value) 13901 window.open(value)
13743 } else if (type === DispatchCenter.enumPageType.PARAMS_SETTING) { 13902 } else if (type === DispatchCenter.enumPageType.PARAMS_SETTING) {
13744 - this.paramsSetting(id) 13903 + this.paramsSetting(id, content)
13745 } 13904 }
13746 } 13905 }
13747 } 13906 }
@@ -13789,15 +13948,20 @@ class HandleDataInteraction { @@ -13789,15 +13948,20 @@ class HandleDataInteraction {
13789 method: "methodThingskit", 13948 method: "methodThingskit",
13790 params: JSON.parse(value), 13949 params: JSON.parse(value),
13791 } 13950 }
13792 - if (slaveDeviceId) {  
13793 - queue.push(() => {  
13794 - fn(way, slaveDeviceId, data)  
13795 - })  
13796 - } else if (deviceId) { 13951 + if (deviceId) {
13797 queue.push(() => { 13952 queue.push(() => {
13798 fn(way, deviceId, data) 13953 fn(way, deviceId, data)
13799 }) 13954 })
13800 } 13955 }
  13956 + // if (slaveDeviceId) {
  13957 + // queue.push(() => {
  13958 + // fn(way, slaveDeviceId, data)
  13959 + // })
  13960 + // } else if (deviceId) {
  13961 + // queue.push(() => {
  13962 + // fn(way, deviceId, data)
  13963 + // })
  13964 + // }
13801 } 13965 }
13802 13966
13803 Promise.all(queue.map(fn => fn())) 13967 Promise.all(queue.map(fn => fn()))
@@ -13829,13 +13993,15 @@ class HandleDataInteraction { @@ -13829,13 +13993,15 @@ class HandleDataInteraction {
13829 /** 13993 /**
13830 * @description 参数设置 13994 * @description 参数设置
13831 */ 13995 */
13832 - paramsSetting(nodeId) { 13996 + paramsSetting(nodeId, content) {
13833 const { layer, jquery: $, form } = layui 13997 const { layer, jquery: $, form } = layui
  13998 + const contentData = this.contentData
13834 const enumConst = { 13999 const enumConst = {
13835 VALUE: 'value', 14000 VALUE: 'value',
13836 ISSUED_WAY: 'way', 14001 ISSUED_WAY: 'way',
13837 - ONE_WAR: 'oneway',  
13838 - TWO_WAY: 'twoway' 14002 + ONE_WAY: 'oneway',
  14003 + TWO_WAY: 'twoway',
  14004 + ATTR_PLACEHOLDER: 'attrPlaceholder'
13839 } 14005 }
13840 14006
13841 const enumActionEl = { 14007 const enumActionEl = {
@@ -13845,40 +14011,17 @@ class HandleDataInteraction { @@ -13845,40 +14011,17 @@ class HandleDataInteraction {
13845 14011
13846 } 14012 }
13847 14013
13848 - /**  
13849 - * @description 创建JSON编辑器  
13850 - * @param el  
13851 - * @param datum  
13852 - */  
13853 - function createEditor() {  
13854 - const editor = ace.edit(enumActionEl.EDITOR, {  
13855 - maxLines: 18, // 最大行数,超过会自动出现滚动条  
13856 - minLines: 10, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小  
13857 - fontSize: 14, // 编辑器内字体大小  
13858 - tabSize: 2, // 制表符设置为 4 个空格大小  
13859 - });  
13860 - editor.session.setMode("ace/mode/json");  
13861 - editor.getSession().on('change', (event, editor) => {  
13862 - $(`#${enumActionEl.CONTAINER}`).parent().find(`textarea[name="${enumConst.VALUE}"]`).val(editor.getValue())  
13863 - })  
13864 - }  
13865 -  
13866 function createContent() { 14014 function createContent() {
13867 return ` 14015 return `
13868 <div> 14016 <div>
13869 <div class="layui-form" lay-filter="${enumActionEl.ISSUED_WAY_FILTER}"> 14017 <div class="layui-form" lay-filter="${enumActionEl.ISSUED_WAY_FILTER}">
13870 <div class="layui-form-item"> 14018 <div class="layui-form-item">
13871 - <label class="layui-form-label">单向/双向</label> 14019 + <label class="layui-form-label">下发值</label>
13872 <div class="layui-input-block"> 14020 <div class="layui-input-block">
13873 - <input type="radio" name="${enumConst.ISSUED_WAY}" value="${enumConst.ONE_WAR}" title="单向" checked="">  
13874 - <input type="radio" name="${enumConst.ISSUED_WAY}" value="${enumConst.TWO_WAY}" title="双向"> 14021 + <input type="text" name="${enumConst.VALUE}" lay-verify="required" autocomplete="off" placeholder="请输入下发值" class="layui-input">
13875 </div> 14022 </div>
13876 </div> 14023 </div>
13877 </div> 14024 </div>
13878 - <div id="${enumActionEl.CONTAINER}">  
13879 - <div id="${enumActionEl.EDITOR}"></div>  
13880 - <textarea name="${enumConst.VALUE}" style="display: none;" />  
13881 - </div>  
13882 </div>` 14025 </div>`
13883 } 14026 }
13884 14027
@@ -13895,25 +14038,52 @@ class HandleDataInteraction { @@ -13895,25 +14038,52 @@ class HandleDataInteraction {
13895 } 14038 }
13896 return false 14039 return false
13897 } 14040 }
13898 - const submitThrottle = this.throttle(submit)  
13899 - async function submit(callback) {  
13900 - const value = $(`#${enumActionEl.CONTAINER}`).parent().find(`textarea[name="${enumConst.VALUE}"]`).val() || ''  
13901 - if (!isJson(value)) {  
13902 - UseLayUi.topErrorMsg('下发值不正确')  
13903 - return 14041 +
  14042 + function jsonParse(value) {
  14043 + try {
  14044 + return JSON.parse(value)
  14045 + } catch (error) {
  14046 + return {}
13904 } 14047 }
13905 - const { way } = form.val(enumActionEl.ISSUED_WAY_FILTER)  
13906 - const data = JSON.parse(value)  
13907 - let { deviceId, slaveDeviceId } = DispatchCenter.instance.contentData.dataSources.find(item => item.nodeId === nodeId) || {} 14048 + }
13908 14049
13909 - if (!value || !deviceId) return 14050 + function replaceAttrPlaceholder(oldValue = {}, replaceAttr = '', replaceValue = '', newValue = {},) {
  14051 + if (typeof oldValue !== 'object') return newValue
  14052 +
  14053 + for (const key of Object.keys(oldValue)) {
  14054 + if (key === enumConst.ATTR_PLACEHOLDER) {
  14055 + newValue[replaceAttr] = replaceValue
  14056 + continue
  14057 + }
  14058 + if (typeof oldValue[key] === 'object') {
  14059 + newValue[key] = replaceAttrPlaceholder(oldValue[key], replaceAttr, replaceValue)
  14060 + continue
  14061 + }
  14062 + newValue[key] = oldValue[key]
  14063 + }
  14064 +
  14065 + return newValue
  14066 + }
  14067 +
  14068 + const submitThrottle = this.throttle(submit)
  14069 + async function submit(callback) {
  14070 + const { value } = form.val(enumActionEl.ISSUED_WAY_FILTER)
  14071 + let { deviceId, attr } = contentData.dataSources.find(item => item.nodeId === nodeId) || {}
  14072 + let { command, way } = content
  14073 + const validate = new Validate([
  14074 + { value, required: true, message: '下发值是必填项' },
  14075 + { value: deviceId, required: true, message: '未绑定设备' },
  14076 + { value: way, required: true, message: '未绑定指令下发方式(单向/双向)' },
  14077 + { value: command, required: true, message: '未设置下发命令' },
  14078 + { value: attr, required: true, message: '未绑定设备属性' },
  14079 + ])
  14080 + if (!validate.begin()) return
  14081 + if (typeof command === 'string') command = jsonParse(command)
  14082 + const data = replaceAttrPlaceholder(command, attr, value)
13910 const instructionData = { 14083 const instructionData = {
13911 method: "methodThingskit", 14084 method: "methodThingskit",
13912 params: data, 14085 params: data,
13913 } 14086 }
13914 - if (slaveDeviceId) {  
13915 - deviceId = slaveDeviceId  
13916 - }  
13917 14087
13918 const [err, res = []] = await to(ConfigurationNodeApi.deviceIsOnLine(deviceId)) 14088 const [err, res = []] = await to(ConfigurationNodeApi.deviceIsOnLine(deviceId))
13919 const { value: onlineFlag } = res[0] || {} 14089 const { value: onlineFlag } = res[0] || {}
@@ -13933,7 +14103,7 @@ class HandleDataInteraction { @@ -13933,7 +14103,7 @@ class HandleDataInteraction {
13933 layer.open({ 14103 layer.open({
13934 title: '参数设置', 14104 title: '参数设置',
13935 content: createContent(), 14105 content: createContent(),
13936 - area: '600px', 14106 + area: '400px',
13937 btn: ["应用", "取消"], 14107 btn: ["应用", "取消"],
13938 yes(index) { 14108 yes(index) {
13939 submitThrottle(() => { 14109 submitThrottle(() => {
@@ -13944,12 +14114,7 @@ class HandleDataInteraction { @@ -13944,12 +14114,7 @@ class HandleDataInteraction {
13944 14114
13945 }, 14115 },
13946 async success(layero, index) { 14116 async success(layero, index) {
13947 - createEditor(enumActionEl.EDITOR)  
13948 form.render() 14117 form.render()
13949 - // $(layero).addClass('layui-form').find('.layui-layer-btn0').attr({  
13950 - // 'lay-submit': '',  
13951 - // 'lay-filter': enumActionEl.IMAGE_LAYER_FILTER,  
13952 - // })  
13953 }, 14118 },
13954 }) 14119 })
13955 } 14120 }
@@ -14001,6 +14166,7 @@ class HandleDynamicEffect { @@ -14001,6 +14166,7 @@ class HandleDynamicEffect {
14001 DISPLAY: 'DISPLAY', 14166 DISPLAY: 'DISPLAY',
14002 ROTATE: 'ROTATE', 14167 ROTATE: 'ROTATE',
14003 IMAGE: 'IMAGE', 14168 IMAGE: 'IMAGE',
  14169 + RUNNING: 'RUNNING'
14004 } 14170 }
14005 14171
14006 static enumDisplayType = { 14172 static enumDisplayType = {
@@ -14008,6 +14174,11 @@ class HandleDynamicEffect { @@ -14008,6 +14174,11 @@ class HandleDynamicEffect {
14008 HIDDEN: 'hidden', 14174 HIDDEN: 'hidden',
14009 } 14175 }
14010 14176
  14177 + static enumRunningType = {
  14178 + RUN: 'run',
  14179 + STOP: 'stop'
  14180 + }
  14181 +
14011 static enumVideoConst = { 14182 static enumVideoConst = {
14012 ORG_ID: 'orgId', 14183 ORG_ID: 'orgId',
14013 RECORD_ID: 'id', 14184 RECORD_ID: 'id',
@@ -14199,6 +14370,9 @@ class HandleDynamicEffect { @@ -14199,6 +14370,9 @@ class HandleDynamicEffect {
14199 case HandleDynamicEffect.enumActType.IMAGE: 14370 case HandleDynamicEffect.enumActType.IMAGE:
14200 invoke = this.varImage.bind(this) 14371 invoke = this.varImage.bind(this)
14201 break 14372 break
  14373 + case HandleDynamicEffect.enumActType.RUNNING:
  14374 + invoke = this.running.bind(this)
  14375 + break
14202 } 14376 }
14203 return invoke 14377 return invoke
14204 } 14378 }
@@ -14327,15 +14501,35 @@ class HandleDynamicEffect { @@ -14327,15 +14501,35 @@ class HandleDynamicEffect {
14327 } 14501 }
14328 } 14502 }
14329 14503
  14504 + running(message) {
  14505 + const { subscriptionId, data = {} } = message
  14506 + const { flag, condition } = this.validate(subscriptionId, HandleDynamicEffect.enumActType.RUNNING, data)
  14507 + if (!flag) return
  14508 + const node = this.getNodeByCmdId(subscriptionId)
  14509 + let isRun = false
  14510 + if (condition.type === HandleDynamicEffect.enumRunningType.RUN) {
  14511 + isRun = true
  14512 + } else if (condition.type === HandleDynamicEffect.enumRunningType.STOP) {
  14513 + isRun = false
  14514 + }
  14515 +
  14516 + const updateFn = () => {
  14517 + const reg = /flowAnimation[^;]+/
  14518 + const style = node.getStyle()
  14519 + node.setStyle(style.replace(reg, `flowAnimation=${isRun ? 1 : 0}`))
  14520 + }
  14521 + this.insertOnceUpdateFn(node, updateFn)
  14522 + }
  14523 +
14330 /** 14524 /**
14331 * @description 播放视频 14525 * @description 播放视频
14332 */ 14526 */
14333 videoPlay() { 14527 videoPlay() {
14334 const basicAttr = Sidebar.prototype.enumCellBasicAttribute 14528 const basicAttr = Sidebar.prototype.enumCellBasicAttribute
14335 const enumAccessMode = HandleDynamicEffect.enumVideoAccessMode 14529 const enumAccessMode = HandleDynamicEffect.enumVideoAccessMode
14336 -  
14337 const videoPlayConfig = { 14530 const videoPlayConfig = {
14338 controls: true, 14531 controls: true,
  14532 + autoPlay: true,
14339 // bigPlayButton: true, 14533 // bigPlayButton: true,
14340 // textTrackDisplay: false, 14534 // textTrackDisplay: false,
14341 // posterImage: false, 14535 // posterImage: false,
@@ -14362,7 +14556,6 @@ class HandleDynamicEffect { @@ -14362,7 +14556,6 @@ class HandleDynamicEffect {
14362 ...videoPlayConfig 14556 ...videoPlayConfig
14363 }, 14557 },
14364 function () { 14558 function () {
14365 - console.log(idEl)  
14366 this.play() 14559 this.play()
14367 }) 14560 })
14368 } 14561 }
@@ -14677,3 +14870,37 @@ function RAFSetInterval(callback, time) { @@ -14677,3 +14870,37 @@ function RAFSetInterval(callback, time) {
14677 } 14870 }
14678 14871
14679 14872
  14873 +class Validate {
  14874 + /**
  14875 + * @description
  14876 + * @type {{value: any, message: string, required?: boolean, validator?: any}[]} list
  14877 + */
  14878 + list = []
  14879 +
  14880 + /**
  14881 + * @description
  14882 + * @param {{value: any, message: string, required?: boolean, validator?: any}[]} ruleList
  14883 + */
  14884 + constructor(ruleList = []) {
  14885 + this.list = ruleList
  14886 + }
  14887 +
  14888 + /**
  14889 + * @description 设置规则
  14890 + * @param {{value: any, message: string, required?: boolean, validator?: any}} rule
  14891 + */
  14892 + set(rule) {
  14893 + this.list.push(rule)
  14894 + }
  14895 +
  14896 + begin() {
  14897 + for (const rule of this.list) {
  14898 + const { required, value, message, validator } = rule
  14899 + if (required && !value) {
  14900 + UseLayUi.topErrorMsg(message)
  14901 + return false
  14902 + }
  14903 + }
  14904 + return true
  14905 + }
  14906 +}