index.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <template>
  2. <div class="layout">
  3. <div class="layout-container">
  4. <!-- 左侧菜单 -->
  5. <left-menu
  6. :layerWidget="layerWidget"
  7. :widgetTools="widgetTools"
  8. :widgetIndex="widgetIndex"
  9. @widgetOnDragged="widgetOnDragged"
  10. @layerClick="layerClick"
  11. />
  12. <div
  13. class="layout-middle"
  14. :style="{
  15. width: middleWidth + 'px',
  16. height: middleHeight + 'px'
  17. }"
  18. >
  19. <!-- 顶部按钮 -->
  20. <top-bar
  21. :dashboard="dashboard"
  22. :widgets="widgets"
  23. @refresh="initEchartData"
  24. />
  25. <!-- 设计器 -->
  26. <middleScreen
  27. ref="middleScreen"
  28. :middleWidth="middleWidth"
  29. :middleHeight="middleHeight"
  30. :dashboard="dashboard"
  31. :widgets="widgets"
  32. @change="changeOptions"
  33. />
  34. </div>
  35. <!-- 右侧配置 -->
  36. <right-config
  37. :widgetOptions="widgetOptions"
  38. @widgetValueChanged="widgetValueChanged"
  39. />
  40. </div>
  41. </div>
  42. </template>
  43. <script>
  44. import { detailDashboard, importDashboard } from "@/api/bigscreen";
  45. import {
  46. swapArr,
  47. setDefaultValue,
  48. handleDefaultValue,
  49. getPXUnderScale,
  50. handleInitEchartsData,
  51. handleBigScreen,
  52. handlerLayerWidget
  53. } from "./util/screen";
  54. import { widgetTools, getToolByCode } from "./config/index.js";
  55. import leftMenu from "./layout/leftMenu.vue";
  56. import topBar from "./layout/topBar.vue";
  57. import middleScreen from "./layout/middleScreen.vue";
  58. import rightConfig from "./layout/rightConfig.vue";
  59. export default {
  60. components: {
  61. leftMenu,
  62. topBar,
  63. middleScreen,
  64. rightConfig
  65. },
  66. data() {
  67. return {
  68. // 左侧菜单
  69. layerWidget: [],
  70. widgetTools: widgetTools,
  71. widgetIndex: 0,
  72. // 顶部按钮
  73. // 中间大屏
  74. grade: false,
  75. // 工作台大屏画布,保存到表gaea_report_dashboard中
  76. dashboard: {
  77. id: null,
  78. title: "", // 大屏页面标题
  79. width: 1920, // 大屏设计宽度
  80. height: 1080, // 大屏设计高度
  81. backgroundColor: "", // 大屏背景色
  82. backgroundImage: "", // 大屏背景图片
  83. refreshSeconds: null // 大屏刷新时间间隔
  84. },
  85. // 右侧配置
  86. widthLeftForTools: 200, // 左侧工具栏宽度
  87. widthRightForOptions: 300, // 右侧属性配置区
  88. // 大屏的标记
  89. screenCode: "",
  90. // 大屏画布中的组件
  91. widgets: [
  92. {
  93. // type和value最终存到数据库中去,保存到gaea_report_dashboard_widget中
  94. type: "widget-text",
  95. value: {
  96. setup: {},
  97. data: {},
  98. position: {
  99. width: 100,
  100. height: 100,
  101. left: 0,
  102. top: 0,
  103. zIndex: 0
  104. }
  105. },
  106. // options属性是从工具栏中拿到的tools中拿到
  107. options: []
  108. }
  109. ], // 工作区中拖放的组件
  110. // 当前激活组件右侧配置属性
  111. widgetOptions: {
  112. setup: [],
  113. data: [],
  114. position: []
  115. }
  116. };
  117. },
  118. watch: {
  119. widgets: {
  120. handler(val) {
  121. this.layerWidget = handlerLayerWidget(val, getToolByCode);
  122. },
  123. deep: true
  124. }
  125. },
  126. computed: {
  127. // 中间设计器的宽度
  128. middleWidth() {
  129. return (
  130. this.bodyWidth - this.widthLeftForTools - this.widthRightForOptions
  131. );
  132. },
  133. // 中间设计器的高度
  134. middleHeight() {
  135. return this.bodyHeight;
  136. }
  137. },
  138. mounted() {
  139. this.widgets = [];
  140. window.addEventListener("mouseup", () => {
  141. this.grade = false;
  142. });
  143. this.initEchartData();
  144. },
  145. methods: {
  146. // 初始化 echrats
  147. async initEchartData() {
  148. const reportCode = this.$route.query.reportCode;
  149. const { code, data } = await detailDashboard(reportCode);
  150. if (code != 200) return;
  151. const processData = handleInitEchartsData(data, getToolByCode);
  152. const screenData = handleBigScreen(
  153. data.dashboard,
  154. getToolByCode,
  155. this.setOptionsOnClickScreen
  156. );
  157. this.widgets = processData;
  158. this.dashboard = screenData;
  159. this.bigscreenWidth = this.dashboard.width;
  160. this.bigscreenHeight = this.dashboard.height;
  161. },
  162. // 拖动一个组件放到工作区中去,在拖动结束时,放到工作区对应的坐标点上去
  163. widgetOnDragged(evt, widgetCode) {
  164. let widgetType = widgetCode;
  165. // 获取结束坐标和列名
  166. let eventX = evt.originalEvent.clientX; // 结束在屏幕的x坐标
  167. let eventY = evt.originalEvent.clientY; // 结束在屏幕的y坐标
  168. let workbenchPosition = this.getDomTopLeftById("workbench");
  169. let widgetTopInWorkbench = eventY - workbenchPosition.top;
  170. let widgetLeftInWorkbench = eventX - workbenchPosition.left;
  171. // 计算在缩放模式下的x y
  172. let x = widgetLeftInWorkbench / this.bigscreenScaleInWorkbench;
  173. let y = widgetTopInWorkbench / this.bigscreenScaleInWorkbench;
  174. // 复制一个组件
  175. let tool = getToolByCode(widgetType);
  176. let widgetJson = {
  177. type: widgetType,
  178. value: {
  179. setup: {},
  180. data: {},
  181. position: {
  182. width: 0,
  183. height: 0,
  184. left: 0,
  185. top: 0,
  186. zIndex: 0
  187. }
  188. },
  189. options: tool.options
  190. };
  191. // 处理默认值
  192. const widgetJsonValue = handleDefaultValue(widgetJson);
  193. // 将选中的复制组件,放到工作区中去
  194. this.widgets.push(this.deepClone(widgetJsonValue));
  195. // 激活新组件的配置属性
  196. this.$refs.middleScreen.setOptionsOnClickWidget(this.widgets.length - 1);
  197. },
  198. layerClick(index) {
  199. this.widgetIndex = index;
  200. this.$refs.middleScreen.widgetsClick(index);
  201. },
  202. // 将当前选中的组件,右侧属性值更新
  203. widgetValueChanged(key, val) {
  204. if (this.screenCode == "screen") {
  205. let newSetup = new Array();
  206. this.dashboard = this.deepClone(val);
  207. if (this.bigscreenWidth != this.dashboard.width) {
  208. this.bigscreenWidth = this.dashboard.width;
  209. }
  210. if (this.bigscreenHeight != this.dashboard.height) {
  211. this.bigscreenHeight = this.dashboard.height;
  212. }
  213. this.widgetOptions.setup.forEach(el => {
  214. if (el.name == "width") {
  215. el.value = this.bigscreenWidth;
  216. } else if (el.name == "height") {
  217. el.value = this.bigscreenHeight;
  218. }
  219. newSetup.push(el);
  220. });
  221. this.widgetOptions.setup = newSetup;
  222. } else {
  223. for (let i = 0; i < this.widgets.length; i++) {
  224. if (this.widgetIndex == i) {
  225. this.widgets[i].value[key] = this.deepClone(val);
  226. setDefaultValue(this.widgets[i].options[key], val);
  227. }
  228. }
  229. }
  230. },
  231. changeOptions(widgetOptions) {
  232. this.widgetOptions = widgetOptions;
  233. },
  234. datadragEnd(evt) {
  235. evt.preventDefault();
  236. this.widgets = swapArr(this.widgets, evt.oldIndex, evt.newIndex);
  237. }
  238. }
  239. };
  240. </script>
  241. <style lang="scss">
  242. @import "../../assets/styles/screenDesigner.scss";
  243. </style>