物管理前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

395 lines
46 KiB

  1. const e="31116105-722c-4b75-82de-74e976a9f7eb",a="command-send",t="命令下发",n='<?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="1704359593539" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14923" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M448 652.8h153.6v204.8h74.752a10.24 10.24 0 0 1 6.656 18.0224l-151.552 129.8432a10.24 10.24 0 0 1-13.312 0l-151.552-129.8432a10.24 10.24 0 0 1 6.656-18.0224h74.752v-204.8z m460.8-601.6a89.6 89.6 0 0 1 89.2928 82.2272l0.3072 7.3728v512a89.6 89.6 0 0 1-82.2272 89.2928l-7.3728 0.3072h-168.448a38.4 38.4 0 0 1-5.1712-76.4416L740.352 665.6h168.3968a12.8 12.8 0 0 0 12.4416-9.8816L921.6 652.8v-512a12.8 12.8 0 0 0-9.8816-12.4416L908.8 128h-768a12.8 12.8 0 0 0-12.4416 9.8816L128 140.8v512a12.8 12.8 0 0 0 9.8816 12.4416L140.8 665.6h162.4576a38.4 38.4 0 0 1 5.1712 76.4416l-5.1712 0.3584H140.8a89.6 89.6 0 0 1-89.2928-82.2272L51.2 652.8v-512a89.6 89.6 0 0 1 82.2272-89.2928L140.8 51.2h768zM265.472 278.6816l4.1984 3.4304 119.296 114.1248a33.28 33.28 0 0 1 4.096 43.3664l-3.584 4.1984-119.296 119.296a33.28 33.28 0 0 1-50.5344-42.9568l3.5328-4.096 95.1808-95.2832-94.72-90.5728a33.28 33.28 0 0 1-4.4032-42.8544l3.3792-4.1984a33.28 33.28 0 0 1 42.8544-4.4544z m281.5488 103.168l266.24 2.048a38.4 38.4 0 0 1 4.608 76.4416l-5.1712 0.3072-266.24-1.9968a38.4 38.4 0 0 1-4.608-76.4928l5.12-0.3072z" fill="#4D6BFF" p-id="14924"></path></svg>',l="svg",o="基础",i="常用",c=!1,u=!0,d="时间",s=`{"type":"page","id":"u:270584784ce1","name":"page1","asideResizor":false,"style":{"boxShadow":" 0px 0px 0px 0px transparent"},"pullRefresh":{"disabled":true},"body":[{"type":"tabs","name":"tab","tabs":[{"title":"样式","icon":"fa fa-th-large","body":[{"type":"form","title":"","name":"basicPropForm","body":[{"type":"input-text","label":"名称","name":"nodeAlias","id":"u:6b126f0520cb","size":"full","mode":"horizontal","inputControlClassName":"w-100","className":"m-b"},{"type":"input-text","label":"ID&nbsp;&nbsp;&nbsp;&nbsp;","name":"id","id":"u:6232710ac003","size":"full","mode":"horizontal","inputControlClassName":"w-100","className":"m-b"},{"type":"grid","id":"u:c605398a724c","className":"m-b","columns":[{"body":[{"type":"input-number","label":"宽度","name":"width","keyboard":true,"id":"u:dcc0c21d16f6","step":1,"suffix":"px","placeholder":"组件左边距","size":"full","mode":"horizontal","className":"m-b","value":200,"labelAlign":"left","precision":2,"inputClassName":"w-full","labelClassName":"w-8"}],"id":"u:14cc19d6ffb0","md":6},{"body":[{"type":"input-number","label":"高度","name":"height","keyboard":true,"id":"u:cd6fdff9ca88","step":1,"suffix":"px","placeholder":"组件上边距","size":"full","mode":"horizontal","className":"m-b","value":200,"labelAlign":"left","precision":2,"inputClassName":"w-full","labelClassName":"w-8"}],"id":"u:4931801ca9b8","md":6}]},{"type":"grid","id":"u:da449a94908a","className":"m-b","columns":[{"body":[{"type":"input-number","label":"X 轴","name":"x","keyboard":true,"id":"u:29852d093d9d","step":1,"suffix":"px","placeholder":"组件左边距","size":"full","mode":"horizontal","className":"m-b","value":200,"labelAlign":"left","precision":2,"inputClassName":"w-full","labelClassName":"w-8"}],"id":"u:1b561d652acc","md":6},{"body":[{"type":"input-number","label":"Y 轴","name":"y","keyboard":true,"id":"u:dc8c1daed8ed","step":1,"suffix":"px","placeholder":"组件上边距","size":"full","mode":"horizontal","className":"m-b","value":200,"labelAlign":"left","precision":2,"inputClassName":"w-full","labelClassName":"w-8"}],"id":"u:9672575193ac","md":6}]},{"type":"grid","id":"u:a332a7bf83c1","className":"m-b","columns":[{"body":[{"type":"input-number","label":"旋转","name":"rotation","id":"u:f6a2dbb518f9","placeholder":"组件旋转角度","mode":"horizontal","size":"full","className":"","keyboard":true,"step":1,"suffix":"deg","value":0,"labelAlign":"left","inputClassName":"w-full"}],"id":"u:646cd98b7955","md":6},{"body
  2. "nodes": [
  3. {
  4. "id": "b143f017-8d3e-4f2a-8f8a-f4dacafffe30",
  5. "type": "command-send",
  6. "x": 200,
  7. "y": 200,
  8. "text": {
  9. "value": "设定",
  10. "x": 200,
  11. "y": 200
  12. },
  13. "properties": {
  14. "id": "b143f017-8d3e-4f2a-8f8a-f4dacafffe30",
  15. "width": 32,
  16. "height": 22,
  17. "x": 200,
  18. "y": 200,
  19. "rotation": 0,
  20. "opacity": 1,
  21. "fontSize": 12,
  22. "showDefaultValue": false,
  23. "showUnit": false,
  24. "valueColor": "rgba(245, 166, 35, 1)",
  25. "nodeAlias": "命令下发",
  26. "lineHeight": 20,
  27. "strokeWidth": 1,
  28. "strokeColor": "rgba(74, 144, 226, 1)",
  29. "borderRadius": 2,
  30. "backgroundColor": "rgba(74, 144, 226, 1)",
  31. "fontColor": "rgba(255, 255, 255, 1)",
  32. "fontFamily": "Microsoft Yahei",
  33. "fontStyle": "",
  34. "fontSpace": 0,
  35. "content": "设定",
  36. "dynamic": {
  37. "normalData": {
  38. "dataPoint": "",
  39. "compareType": "",
  40. "conditionVariables": [],
  41. "defaultValue": "",
  42. "unit": ""
  43. },
  44. "eventsData": {
  45. "eventCombo": [
  46. {
  47. "eventType": "click",
  48. "enable": false,
  49. "config": "",
  50. "users": ""
  51. }
  52. ]
  53. },
  54. "uiData": {
  55. "dataPoint": "",
  56. "compareType": "",
  57. "conditionVariables": []
  58. },
  59. "animationData": {
  60. "animationCombo": [
  61. {
  62. "dataPoint": "",
  63. "min": "",
  64. "max": "",
  65. "animationName": "旋转"
  66. }
  67. ]
  68. },
  69. "hiddenData": {
  70. "hiddenCombo": [
  71. {
  72. "dataPoint": "",
  73. "min": "",
  74. "max": "",
  75. "showOrHiddenName": "隐藏"
  76. }
  77. ]
  78. }
  79. }
  80. }
  81. }
  82. ]
  83. }`,javascript:`const { createApp, createVNode, render } = Vue;
  84. const app = createApp({})
  85. const defaultVal = 0;
  86. const Button = {
  87. template: '<div :style="getStyle" @click="clickHandler">{{content}}</div>',
  88. props: {
  89. name: {
  90. type: String,
  91. default: '命令下发'
  92. },
  93. content: {
  94. type: String,
  95. default: ''
  96. },
  97. currentData: {
  98. type: Number,
  99. default: 10
  100. },
  101. fontColor: {
  102. type: String,
  103. default: '#ffffff'
  104. },
  105. fontSize: {
  106. type: Number,
  107. default: 14
  108. },
  109. fontSpace: {
  110. type: Number,
  111. default: 0
  112. },
  113. fontFamily: {
  114. type: String,
  115. default: '宋体'
  116. },
  117. fontStyle: {
  118. type: String,
  119. default: 'normal'
  120. },
  121. borderRadius: {
  122. type: Number,
  123. default: 4
  124. },
  125. width: {
  126. type: Number,
  127. default: 80
  128. },
  129. height: {
  130. type: Number,
  131. default: 35
  132. },
  133. lineHeight: {
  134. type: Number,
  135. default: 35,
  136. },
  137. backgroundColor: {
  138. type: String,
  139. default: '#1890ff',
  140. },
  141. strokeColor: {
  142. type: String,
  143. default: '#1890ff',
  144. },
  145. strokeWidth: {
  146. type: Number,
  147. default: 1,
  148. },
  149. validatePermission: {
  150. type: Function,
  151. default: () => { }
  152. }
  153. },
  154. emits: ['sendCommand'],
  155. computed: {
  156. getStyle() {
  157. const { fontColor, fontSize, fontFamily, fontStyle, fontSpace, borderRadius, width, height, lineHeight, backgroundColor, strokeColor, strokeWidth } = this
  158. const style = {}
  159. if (fontStyle) {
  160. if (fontStyle.includes('bold')) {
  161. style.fontWeight = 'bolder';
  162. }
  163. if (fontStyle.includes('italic')) {
  164. style.fontStyle = 'italic'
  165. }
  166. if (fontStyle.includes('underline,line-through')) {
  167. style.textDecoration = 'underline line-through'
  168. } else if (fontStyle.includes('line-through,underline')) {
  169. style.textDecoration = 'line-through underline'
  170. } else if (fontStyle.includes('underline')) {
  171. style.textDecoration = 'underline'
  172. } else if (fontStyle.includes('line-through')) {
  173. style.textDecoration = 'line-through'
  174. }
  175. }
  176. return {
  177. color: fontColor,
  178. "font-size": parseInt(fontSize) + 'px',
  179. "font-family": fontFamily,
  180. width: parseInt(width) - parseInt(strokeWidth) * 2 + 'px',
  181. height: parseInt(height) - parseInt(strokeWidth) * 2 + 'px',
  182. lineHeight: parseInt(lineHeight) - parseInt(strokeWidth) * 2 + 'px',
  183. "text-align": 'center',
  184. 'background-color': backgroundColor,
  185. "border-radius": \`\${borderRadius}px\`,
  186. "border-color": strokeColor,
  187. "border-style": "solid",
  188. "border-width": parseInt(strokeWidth) + 'px',
  189. 'letter-spacing': fontSpace + 'px',
  190. 'cursor': 'pointer',
  191. ...style
  192. }
  193. }
  194. },
  195. setup(props, { emit }) {
  196. const { toRefs } = Vue
  197. const { currentData } = toRefs(props)
  198. const clickHandler = () => {
  199. if (window.isPreviewEnv) {
  200. if (props.validatePermission()) {
  201. window.layer.confirm('是否要修改该设备的设定值?', {
  202. btn: ['确定', '取消'] //按钮
  203. }, function (confirmIdx) {
  204. layer.prompt({ title: '设定值', value: currentData.value, formType: 0, btn2: function(){
  205. //取消验证回调
  206. window.layer.close(confirmIdx);
  207. } }, function (value, index) {
  208. emit("sendCommand", +value);
  209. window.layer.close(index);
  210. window.layer.close(confirmIdx)
  211. });
  212. }, function () {
  213. });
  214. }
  215. }
  216. }
  217. return {
  218. clickHandler
  219. }
  220. }
  221. }
  222. class CustomButtonNode extends HtmlResize.view {
  223. realValue = defaultVal
  224. oldProperties = {}
  225. chartRendered = false
  226. instance = null
  227. setHtml(rootEl) {
  228. const { properties, width, height, } = this.props.model;
  229. const { content, nodeAlias, fontColor, fontSize, fontFamily, fontStyle, fontSpace, borderRadius, lineHeight, backgroundColor, strokeColor, strokeWidth } = properties;
  230. const { model, graphModel } = this.props;
  231. const commandHandler = (val) => {
  232. graphModel.eventCenter.emit("myNode:click", {
  233. data: model,
  234. e: val,
  235. });
  236. }
  237. const validatePermission = () => {
  238. const { eventsData } = properties.dynamic || {};
  239. const findClick = eventsData?.eventCombo.find(i => i.eventType === 'click');
  240. const cacheToken = sessionStorage.getItem('v1@CacheToken');
  241. if (!cacheToken) {
  242. window.createLoginDialog();
  243. return false;
  244. }
  245. const tokenParsed = JSON.parse(cacheToken || '{}');
  246. if (findClick.users && !findClick.users.includes(tokenParsed.userid)) {
  247. messageFn('无用户权限');
  248. return false;
  249. }
  250. return true;
  251. }
  252. if (this.instance) {
  253. // 实时数据不能推送一次就创建一次图表,可以在原有实例基础之上更改数据。
  254. Object.assign(this.instance.component.props, {
  255. name: nodeAlias,
  256. content,
  257. borderRadius,
  258. currentData: this.realValue,
  259. fontColor, fontSpace,
  260. fontSize, fontFamily, fontStyle, width, height, lineHeight,
  261. backgroundColor: backgroundColor,
  262. strokeColor, strokeWidth,
  263. onSendCommand: commandHandler,
  264. validatePermission,
  265. })
  266. return
  267. }
  268. const el = document.createElement('div');
  269. rootEl.innerHTML = '';
  270. const instance = createVNode(Button, {
  271. name: nodeAlias,
  272. content,
  273. borderRadius,
  274. currentData: this.realValue,
  275. fontColor, fontSpace,
  276. fontSize, fontFamily, fontStyle, width, height, lineHeight,
  277. backgroundColor: backgroundColor,
  278. strokeColor, strokeWidth,
  279. onSendCommand: commandHandler,
  280. validatePermission
  281. })
  282. instance.appContext = app._context
  283. render(instance, el)
  284. rootEl.appendChild(el);
  285. this.instance = instance;
  286. }
  287. sameProps(properties) {
  288. const isSame = window._.isEqual(this.oldProperties, properties);
  289. if (isSame) return true;
  290. this.oldProperties = properties;
  291. return false
  292. }
  293. // 生命周期 支持重写内容, 但格式需一致
  294. shouldUpdate() {
  295. const { properties } = this.props.model;
  296. const { normalData } = properties.dynamic || {};
  297. if (normalData && !normalData.dataPoint && !normalData.defaultValue) {
  298. this.realValue = defaultVal;
  299. return true
  300. }
  301. if (normalData) {
  302. const { defaultValue } = normalData || {};
  303. if (defaultValue) {
  304. const realValue = window.resolveScadaNewValue(defaultValue)
  305. if (this.realValue !== Number(realValue)) {
  306. this.realValue = Number(realValue);
  307. return true;
  308. }
  309. }
  310. }
  311. const propertiesBack = window._.cloneDeep(properties);
  312. if (propertiesBack.dynamic.normalData) {
  313. const isSameProps = this.sameProps(propertiesBack);
  314. if (isSameProps && this.chartRendered) {
  315. return false
  316. } else {
  317. if (!this.chartRendered) {
  318. this.chartRendered = true
  319. return true
  320. }
  321. if (!isSameProps) {
  322. return true;
  323. }
  324. }
  325. }
  326. }
  327. updateHtml() {
  328. this.setHtml(this.rootEl);
  329. }
  330. componentDidMount() {
  331. // 防止拖动时候频繁渲染图表
  332. this.updateHtmlDebounced = window._.debounce(this.updateHtml.bind(this), 500);
  333. if (this.shouldUpdate()) {
  334. this.setHtml(this.rootEl);
  335. }
  336. }
  337. componentDidUpdate() {
  338. if (this.shouldUpdate()) {
  339. this.updateHtmlDebounced();
  340. }
  341. }
  342. }
  343. class CustomButtonModel extends HtmlResize.model {
  344. initNodeData(data) {
  345. // 自定义组件,需最开始重置一下text 。
  346. data.text = {
  347. value: "",
  348. x: data.x,
  349. y: data.y,
  350. };
  351. super.initNodeData(data);
  352. const { properties } = this;
  353. this.width = properties.width || 80;
  354. this.height = properties.height || 35;
  355. this.text.editable = false; // 不允许文本被编辑
  356. }
  357. setAttributes() {
  358. // 自定义组件需重置 text
  359. const { x, y, properties } = this;
  360. const { textHorizontalMove = 0, textVerticalMove = 0 } = properties;
  361. this.text = {
  362. ...this.text,
  363. x: x + textHorizontalMove,
  364. y: y + textVerticalMove,
  365. value: "",
  366. }
  367. }
  368. }
  369. lf.register({
  370. type: 'command-send',
  371. view: CustomButtonNode,
  372. model: CustomButtonModel,
  373. })
  374. `,css:"",fakeData:""},m={id:e,name:a,aliasName:t,image:n,imageType:l,groupName:o,groupType:i,isRemote:!1,isDefault:!0,sectionType:d,config:s,files:r};export{t as aliasName,s as config,m as default,r as files,o as groupName,i as groupType,e as id,n as image,l as imageType,u as isDefault,c as isRemote,a as name,d as sectionType};