Commit f5e8fcc44d99b3eaaeda8ef02c31ae82dd040427

Authored by xp.Huang
2 parents 2c6927d7 38faf704

Merge branch 'ww' into 'main'

feat: switch component cancel fill commond

See merge request huang/thingskit-drawio!39
... ... @@ -21,7 +21,7 @@
21 21 <meta name="msapplication-config" content="images/browserconfig.xml">
22 22 <meta name="mobile-web-app-capable" content="yes">
23 23 <meta name="theme-color" content="#d89000">
24   -
  24 +
25 25 <link rel="stylesheet" href="./js/plugin/layui/css/layui.css?v=1659336383769">
26 26
27 27 <!-- load configure file -->
... ... @@ -577,7 +577,8 @@
577 577 <body class="geEditor">
578 578 <div id="geInfo">
579 579 <div class="geBlock">
580   - <h1>ThingsKit云组态启动中,请耐心等待</h1>
  580 + <!-- ThingsKit云组态启动中,请耐心等待 -->
  581 + <h1 id="textSpecialEffects" style="width: 100%; height: 300px"></h1>
581 582 </div>
582 583 <figure>
583 584 <div class="dot white"></div>
... ... @@ -587,6 +588,77 @@
587 588 <div class="dot"></div>
588 589 </figure>
589 590 </div>
  591 + <script>
  592 + var timeInterval = setInterval(() => {
  593 + if (!echarts) return
  594 + clearInterval(timeInterval)
  595 + timeInterval = null
  596 + var chartDom
  597 + var myChart
  598 + try {
  599 + chartDom = document.getElementById('textSpecialEffects');
  600 + myChart = echarts.init(chartDom);
  601 + } catch (Error) {
  602 +
  603 + }
  604 +
  605 + var option;
  606 +
  607 + option = {
  608 + graphic: {
  609 + elements: [
  610 + {
  611 + type: 'text',
  612 + left: 'center',
  613 + top: 'center',
  614 + style: {
  615 + text: 'ThingsKit Scada',
  616 + fontSize: 70,
  617 + fontWeight: 'bold',
  618 + lineDash: [0, 200],
  619 + lineDashOffset: 0,
  620 + fill: 'transparent',
  621 + stroke: '#000',
  622 + lineWidth: 1
  623 + },
  624 + keyframeAnimation: {
  625 + duration: 3000,
  626 + loop: true,
  627 + keyframes: [
  628 + {
  629 + percent: 0.7,
  630 + style: {
  631 + fill: 'transparent',
  632 + lineDashOffset: 200,
  633 + lineDash: [200, 0]
  634 + }
  635 + },
  636 + {
  637 + // Stop for a while.
  638 + percent: 0.8,
  639 + style: {
  640 + fill: 'transparent'
  641 + }
  642 + },
  643 + {
  644 + percent: 1,
  645 + style: {
  646 + fill: 'black'
  647 + }
  648 + }
  649 + ]
  650 + }
  651 + }
  652 + ]
  653 + }
  654 + };
  655 +
  656 + try {
  657 + option && myChart.setOption(option);
  658 + } catch (error) { }
  659 + }, 300);
  660 +
  661 + </script>
590 662 <script type="text/javascript">
591 663 /**
592 664 * Main
... ...
... ... @@ -249,8 +249,23 @@
249 249 */
250 250 DEFAULT: 'default',
251 251
  252 + /**
  253 + * @description 开关组件 value
  254 + */
  255 + SWITCH_VALUE: 'switchValue',
  256 +
  257 + /**
  258 + * @description 开关组件状态 {true | false | null}
  259 + */
  260 + SWITCH_STATE: 'switchState'
252 261 }
253 262
  263 + Sidebar.prototype.enumComponentTypeValue = {
  264 + SWITCH_STATE_ENABLED: 'enabled',
  265 + SWITCH_STATE_CLOSE: 'close',
  266 + SWITCH_STATE_NONE: 'none',
  267 + }
  268 +
254 269 /**
255 270 * @description 组件权限map
256 271 * @type {Map<string, string[]>}
... ...
... ... @@ -119,10 +119,15 @@
119 119 function initRealTimeComponent() {
120 120 RAFSetInterval(() => {
121 121 const allTimeNode = document.querySelectorAll('.thingKit-component__real-time .real-time__now')
  122 + const allDateNode = document.querySelectorAll('.thingKit-component__real-time .real-time__date')
122 123 for (const time of allTimeNode) {
123 124 const date = new Date()
124 125 time.innerHTML = `${date.getHours() < 10 ? '0' : ''}${date.getHours()}:${date.getMinutes() < 10 ? '0' : ''}${date.getMinutes()}:${date.getSeconds() < 10 ? '0' : ''}${date.getSeconds()}`
125 126 }
  127 +
  128 + for (const date of allDateNode) {
  129 + date.innerHTML = getCurrentDate()
  130 + }
126 131 }, 1000)
127 132 }
128 133
... ...
... ... @@ -4,7 +4,8 @@
4 4 // Control Component 控制元件
5 5 Sidebar.prototype.addControlComponentsPalette = function () {
6 6 const { COMPONENT_TYPE } = this.enumCellBasicAttribute
7   - const { SWITCH, PARAMS_SETTING_BUTTON } = this.enumComponentType
  7 + const { SWITCH, PARAMS_SETTING_BUTTON, SWITCH_VALUE, SWITCH_STATE } = this.enumComponentType
  8 + const { SWITCH_STATE_NONE } = this.enumComponentTypeValue
8 9 const gn = 'mxgraph.control';
9 10 const dt = 'control';
10 11 const label = '控制元件'
... ... @@ -15,14 +16,14 @@
15 16 const defaultStyle = ';imageAspect=0;'
16 17 this.setCurrentSearchEntryLibrary(dt);
17 18
18   -
19   -
20 19 const fns = [
21 20 this.addEntry(this.getTagsForStencil(gn, 'Switch', dt).join(' '), mxUtils.bind(this, function () {
22 21 const cell = new mxCell('', new mxGeometry(0, 0, 48, 48), `image;image=images/thingskit/switch-on.svg;${defaultStyle}`);
23 22 // 自定义属性
24 23 const cellAttribute = {
25   - [COMPONENT_TYPE]: SWITCH
  24 + [COMPONENT_TYPE]: SWITCH,
  25 + [SWITCH_VALUE]: 1,
  26 + [SWITCH_STATE]: SWITCH_STATE_NONE
26 27 }
27 28 cell.setVertex(true)
28 29 this.setCellAttributes(cell, cellAttribute)
... ...
... ... @@ -6923,9 +6923,17 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6923 6923 async function submit(callback) {
6924 6924 const formVal = form.val(enumActionEl.FORM_FILTER)
6925 6925 const isParamsSetting = formVal[enumConst.ACTION] === enumActionType.PARAMS_SETTING
  6926 + const { COMPONENT_TYPE } = Sidebar.prototype.enumCellBasicAttribute
  6927 + const { SWITCH } = Sidebar.prototype.enumComponentType
  6928 + const isSwitchComponent = vertices[0].getAttribute(COMPONENT_TYPE) === SWITCH
  6929 +
  6930 + if (isParamsSetting && isSwitchComponent && (!currentNodeData.act || !currentNodeData.act.find(item => item.type === enumDynamicEffectType.SWITCH))) {
  6931 + UseLayUi.topErrorMsg('请先配置数据动效中的状态设置')
  6932 + return
  6933 + }
  6934 +
6926 6935 if (isParamsSetting) {
6927 6936 if (!isJson(formVal[enumConst.COMMAND])) {
6928   - console.log()
6929 6937 UseLayUi.topErrorMsg('命令配置存在错误')
6930 6938 return
6931 6939 }
... ... @@ -12994,6 +13002,7 @@ class DispatchCenter {
12994 13002 DISPLAY: 'DISPLAY',
12995 13003 FLASH: 'FLASH',
12996 13004 ROTATE: 'ROTATE',
  13005 + SWITCH: 'SWITCH',
12997 13006 }
12998 13007
12999 13008 static enumPageType = {
... ... @@ -13396,13 +13405,18 @@ class HandleDataSource {
13396 13405 const { condition = [] } = switchConfig || {}
13397 13406 let reg = /image=[^;]+/g
13398 13407 let flag = false
  13408 + const { SWITCH_STATE, SWITCH_VALUE } = Sidebar.prototype.enumComponentType
  13409 + const { SWITCH_STATE_NONE } = Sidebar.prototype.enumComponentTypeValue
13399 13410 for (const item of condition) {
13400   - const { value, imagePath } = item || {}
  13411 + const { value, imagePath, type } = item || {}
13401 13412 if (Number(receiveValue) === Number(value)) {
13402 13413 flag = true
13403 13414 this.updatePage(() => {
13404 13415 const style = node.getStyle()
13405 13416 node.setStyle(style.replace(reg, `image=${imagePath}`))
  13417 + node.setAttribute('label', '')
  13418 + node.setAttribute(SWITCH_VALUE, receiveValue)
  13419 + node.setAttribute(SWITCH_STATE, type)
13406 13420 }, node)
13407 13421 break
13408 13422 }
... ... @@ -13411,6 +13425,9 @@ class HandleDataSource {
13411 13425 this.updatePage(() => {
13412 13426 const style = node.getStyle()
13413 13427 node.setStyle(style.replace(reg, `image=images/thingskit/not-standard-value.svg`))
  13428 + node.setAttribute('label', receiveValue)
  13429 + node.setAttribute(SWITCH_VALUE, receiveValue)
  13430 + node.setAttribute(SWITCH_STATE, SWITCH_STATE_NONE)
13414 13431 }, node)
13415 13432 }
13416 13433 }
... ... @@ -14010,7 +14027,12 @@ class HandleDataInteraction {
14010 14027 */
14011 14028 paramsSetting(nodeId, content) {
14012 14029 const { layer, jquery: $, form } = layui
  14030 + const { SWITCH_STATE, SWITCH_VALUE, SWITCH, PARAMS_SETTING_BUTTON } = Sidebar.prototype.enumComponentType
  14031 + const { SWITCH_STATE_ENABLED, SWITCH_STATE_NONE, SWITCH_STATE_CLOSE } = Sidebar.prototype.enumComponentTypeValue
  14032 + const { COMPONENT_TYPE } = Sidebar.prototype.enumCellBasicAttribute
14013 14033 const contentData = this.contentData
  14034 + const currentNode = this.DispatchInstance.contentAllCell.find(item => item.id === nodeId)
  14035 +
14014 14036 const enumConst = {
14015 14037 VALUE: 'value',
14016 14038 ISSUED_WAY: 'way',
... ... @@ -14040,20 +14062,6 @@ class HandleDataInteraction {
14040 14062 </div>`
14041 14063 }
14042 14064
14043   - function isJson(string) {
14044   - if (typeof string === 'string') {
14045   - try {
14046   - const obj = JSON.parse(string)
14047   - if (typeof obj === 'object' && obj !== null) {
14048   - return true
14049   - }
14050   - } catch (e) {
14051   - return false
14052   - }
14053   - }
14054   - return false
14055   - }
14056   -
14057 14065 function jsonParse(value) {
14058 14066 try {
14059 14067 return JSON.parse(value)
... ... @@ -14062,6 +14070,46 @@ class HandleDataInteraction {
14062 14070 }
14063 14071 }
14064 14072
  14073 + function handleSwitchComponent() {
  14074 + const state = currentNode.getAttribute(SWITCH_STATE)
  14075 + const value = currentNode.getAttribute(SWITCH_VALUE)
  14076 + if (state === SWITCH_STATE_NONE) {
  14077 + return
  14078 + }
  14079 + layer.confirm('是否确认下发命令?', async function (index) {
  14080 + let { deviceId, attr } = contentData.dataSources.find(item => item.nodeId === nodeId) || {}
  14081 + let { command, way } = content
  14082 + const validate = new Validate([
  14083 + { value, required: true, message: '下发值是必填项' },
  14084 + { value: deviceId, required: true, message: '未绑定设备' },
  14085 + { value: way, required: true, message: '未绑定指令下发方式(单向/双向)' },
  14086 + { value: command, required: true, message: '未设置下发命令' },
  14087 + { value: attr, required: true, message: '未绑定设备属性' },
  14088 + ])
  14089 + if (!validate.begin()) return
  14090 + if (typeof command === 'string') command = jsonParse(command)
  14091 + const data = replaceAttrPlaceholder(command, attr, value)
  14092 + const instructionData = {
  14093 + method: "methodThingskit",
  14094 + params: data,
  14095 + }
  14096 +
  14097 + const [err, res = []] = await to(ConfigurationNodeApi.deviceIsOnLine(deviceId))
  14098 + const { value: onlineFlag } = res[0] || {}
  14099 + if (onlineFlag) {
  14100 + const [err, res] = await to(ConfigurationNodeApi.sendInstruction(way, deviceId, instructionData))
  14101 + if (!err) {
  14102 + UseLayUi.topSuccessMsg('操作成功')
  14103 + layer.close(index);
  14104 + }
  14105 + } else {
  14106 + UseLayUi.topErrorMsg('设备不在线!')
  14107 + }
  14108 + });
  14109 +
  14110 +
  14111 + }
  14112 +
14065 14113 function replaceAttrPlaceholder(oldValue = {}, replaceAttr = '', replaceValue = '', newValue = {},) {
14066 14114 if (typeof oldValue !== 'object') return newValue
14067 14115
... ... @@ -14135,7 +14183,22 @@ class HandleDataInteraction {
14135 14183 })
14136 14184 }
14137 14185
14138   - createLayer()
  14186 +
  14187 + function startProcess() {
  14188 + const componentType = currentNode.getAttribute(COMPONENT_TYPE)
  14189 + const handle = {
  14190 + [SWITCH]: handleSwitchComponent,
  14191 + [PARAMS_SETTING_BUTTON]: createLayer
  14192 + }
  14193 +
  14194 + try {
  14195 + handle[componentType]()
  14196 + } catch (error) {
  14197 +
  14198 + }
  14199 + }
  14200 + console.log('enter')
  14201 + startProcess()
14139 14202 }
14140 14203 }
14141 14204
... ... @@ -14541,8 +14604,10 @@ class HandleDynamicEffect {
14541 14604 * @description 播放视频
14542 14605 */
14543 14606 videoPlay() {
14544   - const basicAttr = Sidebar.prototype.enumCellBasicAttribute
14545 14607 const enumAccessMode = HandleDynamicEffect.enumVideoAccessMode
  14608 + const reg = /(?:.*)(?<=\.)/
  14609 + const graph = this.graph
  14610 + const createVideoTemplate = this.createVideoTemplate
14546 14611 const videoPlayConfig = {
14547 14612 controls: true,
14548 14613 autoPlay: true,
... ... @@ -14556,56 +14621,38 @@ class HandleDynamicEffect {
14556 14621 const { accessMode, videoUrl, id } = additional
14557 14622 const cell = this.getCellByCellId(nodeId)
14558 14623 if (!cell) continue
14559   - const { geometry = {} } = cell
14560   - const { width, height } = geometry
14561   - const idEl = getIdEl()
14562 14624 if (Number(accessMode) === enumAccessMode.MANUAL_ENTER) {
14563   - this.graph.getModel().beginUpdate()
14564   - try {
14565   - const template = this.createVideoTemplate(idEl, width, height, videoUrl)
14566   - cell.setAttribute('label', template)
14567   - this.graph.refresh(cell);
14568   - } finally {
14569   - this.graph.getModel().endUpdate()
14570   - videojs(idEl,
14571   - {
14572   - ...videoPlayConfig
14573   - },
14574   - function () {
14575   - this.play()
14576   - })
14577   - }
  14625 + handleVideoPlay(videoPlayConfig, cell, videoUrl)
14578 14626 } else {
14579   - getStreamingVideoPlayUrl.call(this, id, nodeId)
  14627 + getStreamingVideoPlayUrl(id, nodeId)
14580 14628 }
14581 14629 }
14582 14630
14583   - async function getStreamingVideoPlayUrl(id, nodeId) {
  14631 + async function getStreamingVideoPlayUrl(id, cell) {
14584 14632 const [err, res = {}] = await to(ConfigurationNodeApi.getStreamingVideoPlayUrl(id))
14585 14633 const { url } = res?.data || {}
14586 14634 if (!url) return
14587   - const cell = this.getCellByCellId(nodeId)
  14635 + handleVideoPlay({ ...videoPlayConfig, hls: { withCredentials: true } }, cell, url)
  14636 + }
  14637 +
  14638 + function handleVideoPlay(videoPlayConfig, cell, videoUrl) {
14588 14639 if (!cell) return
14589 14640 const { geometry = {} } = cell
14590 14641 const { width, height } = geometry
14591 14642 const idEl = getIdEl()
14592   - this.graph.getModel().beginUpdate()
  14643 + console.log({ idEl })
  14644 + graph.getModel().beginUpdate()
14593 14645 try {
14594   - const template = this.createVideoTemplate(idEl, width, height, url, 'application/x-mpegURL')
  14646 + let type
  14647 + if (videoUrl.replace(reg, '') === 'm3u8') type = 'application/x-mpegURL'
  14648 + const template = createVideoTemplate(idEl, width, height, videoUrl, type)
14595 14649 cell.setAttribute('label', template)
14596   - this.graph.refresh(cell);
  14650 + graph.refresh(cell);
14597 14651 } finally {
14598   - this.graph.getModel().endUpdate()
14599   - videojs(idEl,
14600   - {
14601   - ...videoPlayConfig,
14602   - hls: {
14603   - withCredentials: true
14604   - }
14605   - },
14606   - function () {
14607   - this.play()
14608   - })
  14652 + graph.getModel().endUpdate()
  14653 + videojs(idEl, videoPlayConfig, function () {
  14654 + this.play()
  14655 + })
14609 14656 }
14610 14657 }
14611 14658
... ...