物管理前端
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.

428 lines
38 KiB

  1. const e="f4abd80f-ad2e-4e7b-a2ec-9a7d7577bf09",t="custom-checkbox-node",a="复选框",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="1700711900749" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5708" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M746.496 199.68H277.504A78.336 78.336 0 0 0 199.68 277.504v468.992a78.336 78.336 0 0 0 77.824 77.824h468.992a78.336 78.336 0 0 0 78.336-78.336V277.504a78.336 78.336 0 0 0-78.336-77.824z m-24.576 184.32L438.784 665.6a19.456 19.456 0 0 1-13.824 5.632A19.456 19.456 0 0 1 409.6 665.6l-108.032-120.32a19.456 19.456 0 0 1 29.184-26.112l95.232 105.984L694.272 358.4a19.456 19.456 0 1 1 27.648 27.648z" fill="#707070" p-id="5709"></path></svg>',l="svg",o="基础",i="常用",c=!1,u=!0,s="文字",d=`{"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":[{"type":"input-number","label":"透明","name":"opacity","id":"u:cf80f59d8d42","placeholder":"组件透明度","mode":"horizontal","size":"full","className":"m-b","keyboard":true,"step":0,"suffix":"","value":1,"inputClassName":"w-full","precision":2}],"id":"u:51ddf54ac749","md":6}],"gap":""},{"type":"grid","columns":[{"body":[{"type":"input-number","label":"边框圆角","name":"borderRadius","id":"u:bea5a408f98f","mode":"horizontal","size":"full","inputControlClassName":"inputControlClassName-bea5a408f98f","keyboard":true,"step":1,"value":2,"suffix":"px","inputClassName":"w-full"}],"id":"u:afc37bde0156","md":12}],"id":"u:235f153e5ad5","className":"m-b"},{"type":"fieldset","i
  2. "nodes": [
  3. {
  4. "id": "e56e2ab8-9ca9-4458-81fd-7c308954882b",
  5. "type": "custom-checkbox-node",
  6. "x": 200,
  7. "y": 200,
  8. "text": {
  9. "value": "",
  10. "x": 200,
  11. "y": 200
  12. },
  13. "properties": {
  14. "id": "e56e2ab8-9ca9-4458-81fd-7c308954882b",
  15. "width": 100,
  16. "height": 18,
  17. "x": 200,
  18. "y": 200,
  19. "rotation": 0,
  20. "opacity": 1,
  21. "borderRadius": 6,
  22. "unselectedFontColor": "rgba(255, 255, 255, 1)",
  23. "unselectedBorderColor": "rgba(176, 174, 174, 1)",
  24. "unselectedBack": "rgba(176, 174, 174, 1)",
  25. "unselectedBackImg": "",
  26. "unselectedFontSize": 12,
  27. "unselectedBorderWidth": 1,
  28. "selectedFontColor": "rgba(255, 255, 255, 1)",
  29. "selectedBorderColor": "rgba(74, 144, 226, 1)",
  30. "selectedBack": "rgba(74, 144, 226, 1)",
  31. "selectedBackImg": "",
  32. "selectedFontSize": 12,
  33. "selectedBorderWidth": 1,
  34. "fontSize": 12,
  35. "nodeAlias": "复选框",
  36. "showDefaultValue": false,
  37. "showUnit": false,
  38. "valueColor": "rgba(245, 166, 35, 1)",
  39. "fontColor": "rgba(74, 74, 74, 1)",
  40. "fontFamily": "Microsoft Yahei",
  41. "fontStyle": "",
  42. "dynamic": {
  43. "normalData": {
  44. "dataPoint": "",
  45. "compareType": "",
  46. "conditionVariables": [],
  47. "defaultValue": "",
  48. "unit": "",
  49. "dataFilterFn": "return datas",
  50. "defaultOptions": [
  51. {
  52. "label": "电",
  53. "value": "A29"
  54. },
  55. {
  56. "label": "水",
  57. "value": "B2"
  58. }
  59. ]
  60. },
  61. "eventsData": {
  62. "eventCombo": [
  63. {
  64. "eventType": "change",
  65. "enable": false,
  66. "config": "",
  67. "customEventHandler": false,
  68. "targetParamsType": "entitys",
  69. "targetParamsEntitys": "list"
  70. }
  71. ]
  72. }
  73. }
  74. }
  75. }
  76. ]
  77. }`,javascript:`
  78. const { createApp, createVNode, render } = Vue;
  79. const app = createApp({})
  80. const CheckBox = {
  81. template: \`<div :style="getStyle">
  82. <div v-for="item in myRadioList" style="flex: 1; display: flex; justify-content: flex-start; align-items: center; height: 100%;">
  83. <div :key="item.value" :style="getTabStyle(item, unselectedFontColor, unselectedBorderColor, unselectedBack, unselectedBackImg, unselectedFontSize,
  84. unselectedBorderWidth, selectedFontColor, selectedBorderColor, selectedBack, selectedBackImg, selectedFontSize,
  85. selectedBorderWidth, borderRadius)" @click="clickHandler(item)">
  86. <svg v-if="item.checked" t="1700717504809" class="icon" viewBox="0 0 1024 1024" version="1.1"
  87. xmlns="http://www.w3.org/2000/svg"
  88. xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%">
  89. <path d="M356.7 720.3c-12.8-15.2-10.8-37.9 4.4-50.7l441.2-370.2c15.2-12.8 37.9-10.8 50.7 4.4 12.8 15.2 10.8 37.9-4.4 50.7L407.4 724.7c-15.2 12.8-37.9 10.8-50.7-4.4z" fill="#ffffff" p-id="10094"></path>
  90. <path d="M406.7 724.7c-15.2 12.8-37.9 10.8-50.7-4.4L170.9 499.6c-12.8-15.2-10.8-37.9 4.4-50.7 15.2-12.8 37.9-10.8 50.7 4.4L411.2 674c12.7 15.2 10.8 37.9-4.5 50.7z" fill="#ffffff" p-id="10095"></path>
  91. </svg>
  92. </div>
  93. <span :style="getLabelStyle">{{item.label}}</span>
  94. </div>
  95. </div>\`,
  96. props: {
  97. realValue: {
  98. type: String,
  99. default: ''
  100. },
  101. radioList: {
  102. type: Array,
  103. default: () => []
  104. },
  105. fontColor: {
  106. type: String,
  107. default: '#ffffff'
  108. },
  109. fontSize: {
  110. type: Number,
  111. default: 14
  112. },
  113. fontFamily: {
  114. type: String,
  115. default: '宋体'
  116. },
  117. fontStyle: {
  118. type: String,
  119. default: 'normal'
  120. },
  121. width: {
  122. type: Number,
  123. default: 80
  124. },
  125. height: {
  126. type: Number,
  127. default: 35
  128. },
  129. unselectedFontColor: {
  130. type: String,
  131. default: 'rgba(255, 255, 255, 1)'
  132. },
  133. borderRadius: {
  134. type: Number,
  135. default: 2
  136. },
  137. unselectedBorderColor: {
  138. type: String,
  139. default: 'rgba(176, 174, 174, 1)'
  140. },
  141. unselectedBack: {
  142. type: String,
  143. default: 'rgba(176, 174, 174, 1)'
  144. },
  145. unselectedBackImg: {
  146. type: String,
  147. default: ''
  148. },
  149. unselectedFontSize: {
  150. type: Number,
  151. default: 12
  152. },
  153. unselectedBorderWidth: {
  154. type: Number,
  155. default: 1
  156. },
  157. selectedFontColor: {
  158. type: String,
  159. default: 'rgba(255, 255, 255, 1)'
  160. },
  161. selectedBorderColor: {
  162. type: String,
  163. default: 'rgba(74, 144, 226, 1)'
  164. },
  165. selectedBack: {
  166. type: String,
  167. default: 'rgba(74, 144, 226, 1)'
  168. },
  169. selectedBackImg: {
  170. type: String,
  171. default: ''
  172. },
  173. selectedFontSize: {
  174. type: Number,
  175. default: 12
  176. },
  177. selectedBorderWidth: {
  178. type: Number,
  179. default: 1
  180. }
  181. },
  182. emits: ["change"],
  183. computed: {
  184. getStyle() {
  185. const { width, height, borderRadius } = this;
  186. return {
  187. width: width + 'px',
  188. height: height + 'px',
  189. display: 'flex',
  190. "flex-direction": width > height ? "row" : "column",
  191. "justify-content": "flex-start",
  192. "align-items": "center",
  193. 'border-radius': borderRadius + 'px',
  194. 'overflow': 'hidden'
  195. }
  196. },
  197. getTabStyle: () => (item, unselectedFontColor, unselectedBorderColor, unselectedBack, unselectedBackImg, unselectedFontSize,
  198. unselectedBorderWidth, selectedFontColor, selectedBorderColor, selectedBack, selectedBackImg, selectedFontSize,
  199. selectedBorderWidth, borderRadius) => {
  200. if (!item.checked) {
  201. return {
  202. color: unselectedFontColor,
  203. 'font-size': unselectedFontSize + 'px',
  204. 'border-style': "solid",
  205. 'border-width': unselectedBorderWidth + 'px',
  206. 'border-color': unselectedBorderColor,
  207. 'border-radius': borderRadius + 'px',
  208. 'background-color': unselectedBack,
  209. 'background-image': unselectedBackImg ? "url(" + unselectedBackImg + ")" : 'none',
  210. 'display': 'flex',
  211. 'justify-content': 'center',
  212. 'align-items': 'center',
  213. 'flex': '1',
  214. 'height': '100%',
  215. 'width': '100%',
  216. 'cursor': 'pointer'
  217. }
  218. } else {
  219. return {
  220. color: selectedFontColor,
  221. 'font-size': selectedFontSize + 'px',
  222. 'border-style': "solid",
  223. 'border-width': selectedBorderWidth + 'px',
  224. 'border-color': selectedBorderColor,
  225. 'border-radius': borderRadius + 'px',
  226. 'background-color': selectedBack,
  227. 'background-image': selectedBackImg ? "url(" + selectedBackImg + ")" : 'none',
  228. 'display': 'flex',
  229. 'justify-content': 'center',
  230. 'align-items': 'center',
  231. 'flex': '1',
  232. 'height': '100%',
  233. 'width': '100%',
  234. 'cursor': 'pointer'
  235. }
  236. }
  237. },
  238. getLabelStyle() {
  239. const { fontStyle } = this;
  240. const style = {};
  241. if (fontStyle) {
  242. if (fontStyle.includes('bold')) {
  243. style["font-weight"] = 'bolder';
  244. }
  245. if (fontStyle.includes('italic')) {
  246. style["font-style"] = 'italic'
  247. }
  248. if (fontStyle.includes('underline,line-through')) {
  249. style["text-decoration"] = 'underline line-through'
  250. } else if (fontStyle.includes('line-through,underline')) {
  251. style["text-decoration"] = 'line-through underline'
  252. } else if (fontStyle.includes('underline')) {
  253. style["text-decoration"] = 'underline'
  254. } else if (fontStyle.includes('line-through')) {
  255. style["text-decoration"] = 'line-through'
  256. }
  257. }
  258. return {
  259. flex: 'auto',
  260. 'margin-left': '5px',
  261. color: this.fontColor,
  262. 'font-size': this.fontSize + 'px',
  263. 'font-family': this.fontFamily,
  264. ...style,
  265. }
  266. }
  267. },
  268. setup(props, { emit }) {
  269. const { ref, watch } = Vue
  270. const myRadioList = ref([])
  271. const clickHandler = (item) => {
  272. myRadioList.value.forEach((el) => {
  273. if (el.value === item.value) {
  274. el.checked = !el.checked;
  275. }
  276. })
  277. const selects = myRadioList.value.map(i => i.value);
  278. emit("change", selects);
  279. }
  280. watch(() => props.radioList, (val) => {
  281. myRadioList.value = val
  282. }, {
  283. immediate: true,
  284. })
  285. watch(() => props.realValue, (val) => {
  286. if (val) {
  287. myRadioList.value.forEach((el) => {
  288. const valArr = String(val).split(",")
  289. if (valArr.includes(el.value)) {
  290. el.checked = true;
  291. } else {
  292. el.checked = false
  293. }
  294. })
  295. }
  296. }, {
  297. immediate: true,
  298. })
  299. return {
  300. clickHandler,
  301. myRadioList
  302. }
  303. }
  304. }
  305. class CustomCheckBoxNode extends HtmlResize.view {
  306. oldProperties = {}
  307. setHtml(rootEl) {
  308. const { properties, width, height, } = this.props.model;
  309. const { fontColor, fontSize, fontFamily, fontStyle,
  310. unselectedFontColor, unselectedBorderColor, unselectedBack, unselectedBackImg, unselectedFontSize,
  311. unselectedBorderWidth, selectedFontColor, selectedBorderColor, selectedBack, selectedBackImg, selectedFontSize,
  312. selectedBorderWidth, borderRadius
  313. } = properties;
  314. const { model, graphModel } = this.props;
  315. const el = document.createElement('div');
  316. rootEl.innerHTML = '';
  317. const { normalData } = properties.dynamic || {};
  318. const { defaultOptions } = normalData || {};
  319. let list = [];
  320. if (defaultOptions) {
  321. let opts = []
  322. if (typeof defaultOptions !== 'string') {
  323. opts = defaultOptions
  324. } else {
  325. opts = JSON.parse(defaultOptions);
  326. }
  327. list = window._.cloneDeep(opts).map((el, index) => {
  328. if (index === 0) {
  329. el.checked = true
  330. } else {
  331. el.checked = false
  332. }
  333. return el;
  334. })
  335. }
  336. let realValue = "";
  337. if (normalData) {
  338. realValue = window.resolveScadaNewValue(normalData.defaultValue);
  339. }
  340. const changeHandler = (e) => {
  341. graphModel.eventCenter.emit("node:change", {
  342. data: this.props.model,
  343. e,
  344. });
  345. }
  346. const instance = createVNode(CheckBox, {
  347. realValue,
  348. radioList: list,
  349. fontColor,
  350. fontSize, fontFamily, fontStyle, width, height,
  351. unselectedFontColor, unselectedBorderColor, unselectedBack, unselectedBackImg, unselectedFontSize,
  352. unselectedBorderWidth, selectedFontColor, selectedBorderColor, selectedBack, selectedBackImg, selectedFontSize,
  353. selectedBorderWidth, borderRadius,
  354. onChange: changeHandler
  355. })
  356. instance.appContext = app._context
  357. render(instance, el)
  358. rootEl.appendChild(el);
  359. }
  360. sameProps(properties) {
  361. const isSame = window._.isEqual(this.oldProperties, properties);
  362. if (isSame) return true;
  363. this.oldProperties = properties;
  364. return false
  365. }
  366. // 生命周期 支持重写内容, 但格式需一致
  367. shouldUpdate() {
  368. const { properties } = this.props.model;
  369. const propertiesBack = window._.cloneDeep(properties);
  370. // 由于事件change 会给properties 增加一个 event 属性(见目录scadaDashboard/Diagram/useDynamicEventsHandler),会引发属性的改变,导致组件重渲染。
  371. delete propertiesBack.event;
  372. if (this.sameProps(propertiesBack)) {
  373. return false
  374. }
  375. return true;
  376. }
  377. }
  378. class CustomCheckBoxModel extends HtmlResize.model {
  379. initNodeData(data) {
  380. // 自定义组件,需最开始重置一下text 。
  381. data.text = {
  382. value: "",
  383. x: data.x,
  384. y: data.y,
  385. };
  386. super.initNodeData(data);
  387. const { properties } = this;
  388. this.width = properties.width || 80;
  389. this.height = properties.height || 35;
  390. }
  391. setAttributes() {
  392. // 自定义组件需重置 text
  393. const { x, y, properties } = this;
  394. const { textHorizontalMove = 0, textVerticalMove = 0 } = properties;
  395. this.text = {
  396. ...this.text,
  397. x: x + textHorizontalMove,
  398. y: y + textVerticalMove,
  399. value: "",
  400. }
  401. }
  402. }
  403. lf.register({
  404. type: 'custom-checkbox-node',
  405. view: CustomCheckBoxNode,
  406. model: CustomCheckBoxModel,
  407. })
  408. `,css:"",fakeData:""},m={id:e,name:t,aliasName:a,image:n,imageType:l,groupName:o,groupType:i,isRemote:!1,isDefault:!0,sectionType:s,config:d,files:r};export{a as aliasName,d 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,t as name,s as sectionType};