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

470 lines
39 KiB

  1. const e="fe873e35-7be4-4ac8-aec8-9f4afbd4e0fd",t="custom-radios-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="1700709948418" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4023" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 65.983389c-245.919634 0-446.016611 200.095256-446.016611 446.016611 0 245.952318 200.064292 446.016611 446.016611 446.016611S958.016611 757.952318 958.016611 512C958.016611 266.080366 757.952318 65.983389 512 65.983389zM512 894.016611c-210.655557 0-382.016611-171.392017-382.016611-382.016611 0-210.655557 171.359333-382.016611 382.016611-382.016611 210.624593 0 382.016611 171.359333 382.016611 382.016611C894.016611 722.624593 722.624593 894.016611 512 894.016611z" fill="#707070" p-id="4024"></path><path d="M512 352.00086c-88.223841 0-160.00086 71.775299-160.00086 159.99914s71.775299 160.00086 160.00086 160.00086 160.00086-71.775299 160.00086-160.00086S600.223841 352.00086 512 352.00086z" fill="#707070" p-id="4025"></path></svg>',l="svg",i="基础",o="常用",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":16,"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":16,"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":"fieldset","title":"未选中外框","collapsable":true,"body":[{"type":"input-
  2. "nodes": [
  3. {
  4. "id": "88cbfa0c-7a9e-4da3-b727-a11eda60a3f0",
  5. "type": "custom-radios-node",
  6. "x": 200,
  7. "y": 200,
  8. "text": {
  9. "value": "",
  10. "x": 200,
  11. "y": 200
  12. },
  13. "properties": {
  14. "id": "88cbfa0c-7a9e-4da3-b727-a11eda60a3f0",
  15. "width": 150,
  16. "height": 30,
  17. "x": 200,
  18. "y": 200,
  19. "rotation": 0,
  20. "opacity": 1,
  21. "unselectedBorderWidth": 1,
  22. "unselectedDiameter": 16,
  23. "selectedBorderWidth": 1,
  24. "selectedDiameter": 16,
  25. "selectedInnerBorderWidth": 0,
  26. "selectedInnerDiameter": 10,
  27. "fontSize": 12,
  28. "nodeAlias": "单选按钮",
  29. "showDefaultValue": false,
  30. "showUnit": false,
  31. "valueColor": "rgba(245, 166, 35, 1)",
  32. "unselectedBorderColor": "rgba(155, 155, 155, 1)",
  33. "unselectedBackColor": "rgba(255, 255, 255, 0)",
  34. "selectedBorderColor": "rgba(74, 144, 226, 1)",
  35. "selectedBackColor": "rgba(255, 255, 255, 0)",
  36. "selectedInnerBorderColor": "rgba(74, 144, 226, 1)",
  37. "selectedInnerBackColor": "rgba(74, 144, 226, 1)",
  38. "fontColor": "rgba(74, 74, 74, 1)",
  39. "fontFamily": "Microsoft Yahei",
  40. "dynamic": {
  41. "normalData": {
  42. "dataPoint": "",
  43. "compareType": "",
  44. "conditionVariables": [],
  45. "defaultValue": "",
  46. "unit": "",
  47. "dataFilterFn": "return datas",
  48. "defaultOptions": [
  49. {
  50. "label": "电",
  51. "value": "A29"
  52. },
  53. {
  54. "label": "水",
  55. "value": "B2"
  56. }
  57. ]
  58. },
  59. "eventsData": {
  60. "eventCombo": [
  61. {
  62. "eventType": "change",
  63. "enable": false,
  64. "config": "",
  65. "customEventHandler": false,
  66. "targetParamsType": "entitys",
  67. "targetParamsEntitys": "list"
  68. }
  69. ]
  70. }
  71. }
  72. }
  73. }
  74. ]
  75. }`,javascript:`
  76. const { createApp, createVNode, render } = Vue;
  77. const app = createApp({})
  78. const Radios = {
  79. template: \`
  80. <div :style="getStyle">
  81. <div v-for="(item, index) in myRadioList" :key="item.value" :style="getRadioOuter" @click="clickHandler(item)">
  82. <input type="radio" :id="'radio' + index" name="radio" :checked="item.checked" :style="getRadioInput"/>
  83. <label :for="'radio' + index" :style="getRadioLabel(item, myRadioList, unselectedBorderWidth, unselectedBorderColor, unselectedBackColor,
  84. selectedBorderWidth, selectedBorderColor, selectedBackColor,
  85. unselectedDiameter, selectedDiameter)">
  86. <span v-if="item.checked === 'checked'" :style="getCheckedInner"></span>
  87. <span :style="labelStyle">{{item.label}}</span>
  88. </label>
  89. </div>
  90. </div>
  91. \`,
  92. props: {
  93. fontColor: {
  94. type: String,
  95. default: '#ffffff'
  96. },
  97. fontSize: {
  98. type: Number,
  99. default: 14
  100. },
  101. fontFamily: {
  102. type: String,
  103. default: '宋体'
  104. },
  105. fontStyle: {
  106. type: String,
  107. default: 'normal'
  108. },
  109. width: {
  110. type: Number,
  111. default: 80
  112. },
  113. height: {
  114. type: Number,
  115. default: 35
  116. },
  117. unselectedBorderWidth: {
  118. type: Number,
  119. default: 1,
  120. },
  121. unselectedBorderColor: {
  122. type: String,
  123. default: 'rgba(155, 155, 155, 1)'
  124. },
  125. unselectedBackColor: {
  126. type: String,
  127. default: 'rgba(255, 255, 255, 0)'
  128. },
  129. selectedBorderWidth: {
  130. type: Number,
  131. default: 1
  132. },
  133. selectedBorderColor: {
  134. type: String,
  135. default: 'rgba(74, 144, 226, 1)'
  136. },
  137. selectedBackColor: {
  138. type: String,
  139. default: 'rgba(255, 255, 255, 0)'
  140. },
  141. selectedInnerBorderWidth: {
  142. type: Number,
  143. default: 0
  144. },
  145. selectedInnerBorderColor: {
  146. type: String,
  147. default: 'rgba(74, 144, 226, 1)'
  148. },
  149. selectedInnerBackColor: {
  150. type: String,
  151. default: 'rgba(74, 144, 226, 1)'
  152. },
  153. unselectedDiameter: {
  154. type: Number,
  155. default: 16
  156. },
  157. selectedDiameter: {
  158. type: Number,
  159. default: 16
  160. },
  161. selectedInnerDiameter: {
  162. type: Number,
  163. default: 10
  164. },
  165. radioList: {
  166. type: Array,
  167. default: () => []
  168. },
  169. realValue: {
  170. type: String,
  171. default: ''
  172. }
  173. },
  174. emits: ["change"],
  175. computed: {
  176. getStyle() {
  177. // const { fontColor, fontSize, fontFamily, fontStyle, width, height, lineHeight, backgroundColor,strokeColor,strokeWidth } = this
  178. const { width, height } = this;
  179. return {
  180. width: width + 'px',
  181. height: height + 'px',
  182. display: "flex",
  183. "flex-direction": width > height ? "row" : "column",
  184. "justify-content": "flex-start",
  185. "align-items": width > height ? 'center' : 'left'
  186. }
  187. },
  188. getRadioOuter() {
  189. const { selectedDiameter } = this;
  190. return {
  191. position: "relative",
  192. width: selectedDiameter + 'px',
  193. height: selectedDiameter + 'px',
  194. flex: '1',
  195. }
  196. },
  197. getRadioInput() {
  198. return {
  199. position: 'absolute',
  200. visibility: 'hidden'
  201. }
  202. },
  203. labelStyle() {
  204. const { fontColor, fontSize, fontFamily, fontStyle, selectedDiameter, selectedInnerDiameter } = this;
  205. const pos = (selectedDiameter - selectedInnerDiameter) / 2;
  206. const style = {};
  207. if (fontStyle) {
  208. if (fontStyle.includes('bold')) {
  209. style["font-weight"] = 'bolder';
  210. }
  211. if (fontStyle.includes('italic')) {
  212. style["font-style"] = 'italic'
  213. }
  214. if (fontStyle.includes('underline,line-through')) {
  215. style["text-decoration"] = 'underline line-through'
  216. } else if (fontStyle.includes('line-through,underline')) {
  217. style["text-decoration"] = 'line-through underline'
  218. } else if (fontStyle.includes('underline')) {
  219. style["text-decoration"] = 'underline'
  220. } else if (fontStyle.includes('line-through')) {
  221. style["text-decoration"] = 'line-through'
  222. }
  223. }
  224. return {
  225. position: 'absolute',
  226. top: '0px',
  227. left: pos + selectedDiameter + 5 + 'px',
  228. 'color': fontColor,
  229. 'font-size': fontSize + 'px',
  230. 'font-family': fontFamily,
  231. height: '100%',
  232. display: 'flex',
  233. 'align-items': 'center',
  234. ...style,
  235. }
  236. },
  237. getRadioLabel: () => (item, radioList, unselectedBorderWidth, unselectedBorderColor, unselectedBackColor,
  238. selectedBorderWidth, selectedBorderColor, selectedBackColor,
  239. unselectedDiameter, selectedDiameter) => {
  240. if (radioList.length > 0) {
  241. return {
  242. position: 'absolute',
  243. left: '0px',
  244. display: 'inline-block',
  245. width: item.checked === 'checked' ? selectedDiameter + 'px' : unselectedDiameter + 'px',
  246. height: item.checked === 'checked' ? selectedDiameter + 'px' : unselectedDiameter + 'px',
  247. "border-width": item.checked === 'checked' ? selectedBorderWidth + 'px' : unselectedBorderWidth + 'px',
  248. "border-color": item.checked === 'checked' ? selectedBorderColor : unselectedBorderColor,
  249. "border-style": "solid",
  250. 'border-radius': item.checked === 'checked' ? (selectedDiameter + 2) / 2 + 'px' : (unselectedDiameter + 2) / 2 + 'px',
  251. 'background-color': item.checked === 'checked' ? selectedBackColor : unselectedBackColor,
  252. 'box-sizing': 'content-box',
  253. 'cursor': 'pointer'
  254. }
  255. }
  256. },
  257. getCheckedInner() {
  258. const {
  259. selectedInnerBorderWidth, selectedInnerBorderColor, selectedInnerBackColor,
  260. selectedDiameter, selectedInnerDiameter } = this
  261. const pos = (selectedDiameter - selectedInnerDiameter) / 2 + 'px'
  262. return {
  263. position: 'absolute',
  264. top: pos,
  265. left: pos,
  266. width: selectedInnerDiameter + 'px',
  267. height: selectedInnerDiameter + 'px',
  268. 'border-radius': selectedInnerDiameter / 2 + 'px',
  269. 'background-color': selectedInnerBackColor,
  270. 'border-width': selectedInnerBorderWidth + 'px',
  271. 'border-color': selectedInnerBorderColor,
  272. 'border-style': 'solid',
  273. 'box-sizing': 'border-box'
  274. }
  275. }
  276. },
  277. setup(props, { emit }) {
  278. const { ref, watch } = Vue
  279. const myRadioList = ref([])
  280. const clickHandler = (item) => {
  281. myRadioList.value.forEach((el) => {
  282. if (el.value === item.value) {
  283. el.checked = 'checked';
  284. } else {
  285. el.checked = false
  286. }
  287. })
  288. emit("change", item.value);
  289. }
  290. watch(() => props.radioList, (val) => {
  291. myRadioList.value = val
  292. }, {
  293. immediate: true,
  294. })
  295. watch(() => props.realValue, (val) => {
  296. if (val) {
  297. myRadioList.value.forEach((el) => {
  298. if (el.value === String(val)) {
  299. el.checked = 'checked';
  300. } else {
  301. el.checked = false
  302. }
  303. })
  304. }
  305. }, {
  306. immediate: true,
  307. })
  308. return {
  309. clickHandler,
  310. myRadioList
  311. }
  312. }
  313. }
  314. class CustomRadiosNode extends HtmlResize.view {
  315. oldProperties = {}
  316. setHtml(rootEl) {
  317. const { properties, width, height, } = this.props.model;
  318. const { fontColor, fontSize, fontFamily, fontStyle,
  319. unselectedBorderWidth, unselectedBorderColor, unselectedBackColor,
  320. selectedBorderWidth, selectedBorderColor, selectedBackColor,
  321. selectedInnerBorderWidth, selectedInnerBorderColor, selectedInnerBackColor,
  322. unselectedDiameter, selectedDiameter, selectedInnerDiameter } = properties;
  323. const { model, graphModel } = this.props;
  324. const el = document.createElement('div');
  325. rootEl.innerHTML = '';
  326. const { normalData } = properties.dynamic || {};
  327. const { defaultOptions } = normalData || {};
  328. let list = [];
  329. if (defaultOptions) {
  330. let opts = []
  331. if (typeof defaultOptions !== 'string') {
  332. opts = defaultOptions
  333. } else {
  334. opts = JSON.parse(defaultOptions);
  335. }
  336. list = window._.cloneDeep(opts).map((el, index) => {
  337. if (index === 0) {
  338. el.checked = 'checked'
  339. } else {
  340. el.checked = false
  341. }
  342. return el;
  343. })
  344. }
  345. let realValue = "";
  346. if (normalData) {
  347. realValue = window.resolveScadaNewValue(normalData.defaultValue);
  348. }
  349. const changeHandler = (e) => {
  350. graphModel.eventCenter.emit("node:change", {
  351. data: this.props.model,
  352. e,
  353. });
  354. }
  355. const instance = createVNode(Radios, {
  356. realValue,
  357. radioList: list,
  358. fontColor,
  359. fontSize, fontFamily, fontStyle, width, height,
  360. unselectedBorderWidth, unselectedBorderColor, unselectedBackColor,
  361. selectedBorderWidth, selectedBorderColor, selectedBackColor,
  362. selectedInnerBorderWidth, selectedInnerBorderColor, selectedInnerBackColor,
  363. unselectedDiameter, selectedDiameter, selectedInnerDiameter,
  364. onChange: changeHandler
  365. })
  366. instance.appContext = app._context
  367. render(instance, el)
  368. rootEl.appendChild(el);
  369. }
  370. sameProps(properties) {
  371. const isSame = window._.isEqual(this.oldProperties, properties);
  372. if (isSame) return true;
  373. this.oldProperties = properties;
  374. return false
  375. }
  376. // 生命周期 支持重写内容, 但格式需一致
  377. shouldUpdate() {
  378. const { properties } = this.props.model;
  379. const propertiesBack = window._.cloneDeep(properties);
  380. // 由于事件change 会给properties 增加一个 event 属性(见目录scadaDashboard/Diagram/useDynamicEventsHandler),会引发属性的改变,导致组件重渲染。
  381. delete propertiesBack.event;
  382. if (this.sameProps(propertiesBack)) {
  383. return false
  384. }
  385. return true;
  386. }
  387. }
  388. class CustomRadiosModel extends HtmlResize.model {
  389. initNodeData(data) {
  390. // 自定义组件,需最开始重置一下text 。
  391. data.text = {
  392. value: "",
  393. x: data.x,
  394. y: data.y,
  395. };
  396. super.initNodeData(data);
  397. const { properties } = this;
  398. this.width = properties.width || 80;
  399. this.height = properties.height || 35;
  400. }
  401. setAttributes() {
  402. // 自定义组件需重置 text
  403. const { x, y, properties } = this;
  404. const { textHorizontalMove = 0, textVerticalMove = 0 } = properties;
  405. this.text = {
  406. ...this.text,
  407. x: x + textHorizontalMove,
  408. y: y + textVerticalMove,
  409. value: "",
  410. }
  411. }
  412. }
  413. lf.register({
  414. type: 'custom-radios-node',
  415. view: CustomRadiosNode,
  416. model: CustomRadiosModel,
  417. })
  418. `,css:`.scada-radio {\r
  419. position: relative;\r
  420. width: 16px;\r
  421. height: 16px;\r
  422. }\r
  423. .scada-radio input {\r
  424. position: absolute;\r
  425. visibility: hidden\r
  426. }\r
  427. .scada-radio label {\r
  428. position: absolute;\r
  429. display: inline-block;\r
  430. width: 16px;\r
  431. height: 16px;\r
  432. border: 1px solid #d7d7d7;\r
  433. border-radius: 9px;\r
  434. }\r
  435. /*选中状态*/\r
  436. .nm-radio input:checked + label {\r
  437. border: 1px solid #1baede;\r
  438. }\r
  439. .nm-radio input:checked + label:before {\r
  440. content: "";\r
  441. position: absolute;\r
  442. top: 3px; left: 3px;\r
  443. width: 10px;\r
  444. height: 10px;\r
  445. border-radius: 5px;\r
  446. background-color: #1baede;\r
  447. }`,fakeData:""},m={id:e,name:t,aliasName:a,image:n,imageType:l,groupName:i,groupType:o,isRemote:!1,isDefault:!0,sectionType:s,config:d,files:r};export{a as aliasName,d as config,m as default,r as files,i as groupName,o as groupType,e as id,n as image,l as imageType,u as isDefault,c as isRemote,t as name,s as sectionType};