Commit 02379a249d8fd03b742d9de34aff7623cd2a83e8

Authored by qianbao
1 parent 77e78622

1、大屏主数据源存储,

2、加载设计时候主数据源数据赋值
3、预览主数据源根据设置加载
Showing 22 changed files with 739 additions and 909 deletions
src/views/bigscreenDesigner/designer/index.vue
... ... @@ -296,7 +296,7 @@ import draggable from "vuedraggable";
296 296 import VueRulerTool from "vue-ruler-tool"; // 大屏设计页面的标尺插件
297 297 import contentMenu from "./components/contentMenu";
298 298 import { getToken } from "@/utils/auth";
299   -import { Revoke } from "@/utils/revoke"; //处理历史记录 2022-02-22
  299 +import { Revoke } from "@/utils/revoke";
300 300 import { mapMutations } from 'vuex';
301 301  
302 302 export default {
... ... @@ -322,7 +322,7 @@ export default {
322 322  
323 323 bigscreenWidth: 1920, // 大屏设计的大小
324 324 bigscreenHeight: 1080,
325   - revoke: null, //处理历史记录 2022-02-22
  325 + revoke: null,
326 326  
327 327 // 工作台大屏画布,保存到表gaea_report_dashboard中
328 328 dashboard: {
... ... @@ -332,14 +332,12 @@ export default {
332 332 height: 1080, // 大屏设计高度
333 333 backgroundColor: "", // 大屏背景色
334 334 backgroundImage: "", // 大屏背景图片
335   - // master: null, // 全局数据源
336   - // refreshMasterTime: 600000, // 刷新时间(毫秒)
337 335 refreshSeconds: null, // 大屏刷新时间间隔
338 336 presetLine: [], // 辅助线
339 337 presetLineVisible: true, // 辅助线是否显示
340   - data: [],
  338 + data: {},
341 339 },
342   - masterData:{"sName1":"测试文本1","sName2":"测试文本2"},
  340 + masterData:{},//主表数据源
343 341 // 大屏的标记
344 342 screenCode: "",
345 343 dragWidgetCode: "", //从工具栏拖拽的组件code
... ... @@ -497,13 +495,64 @@ export default {
497 495 const { code, data } = await detailDashboard(reportCode);
498 496 if (code != 200) return;
499 497 const processData = this.handleInitEchartsData(data);
500   -
501 498 const screenData = this.handleBigScreen(data.dashboard);
502 499 this.widgets = processData;
503 500 this.dashboard = screenData;
504 501 this.bigscreenWidth = this.dashboard.width;
505 502 this.bigscreenHeight = this.dashboard.height;
  503 + //判断数据源是否配置了主数据源,如果配置了主数据,将主数据转换成静态的保存
  504 + if(this.isNotBlankObj(screenData)){
  505 + this.setMasterData(screenData);
  506 + //将动态数据部分赋值
  507 + //console.log("将动态数据部分赋值",this.widgetOptions);
  508 + this.setWidgetOptionsData(screenData.data);
  509 + }
  510 + },
  511 + // 数据处理
  512 + setMasterData(screenData){
  513 + // 数据类型 静态 or 动态
  514 + const screenD = screenData.data;
  515 + const refreshTime = screenD["refreshTime"]||60000*30;
  516 + screenD.dataType == "staticData"
  517 + ? this.staticDataFn(screenD.staticData)
  518 + : this.dynamicDataFn(screenD.dynamicData, refreshTime);
  519 + },
  520 + staticDataFn(val) {
  521 + //获取静态数据
  522 + this.masterData=val;
  523 + this.SET_STATIC_DATA(this.masterData);
  524 + },
  525 + dynamicDataFn(val, refreshTime) {
  526 + if (!val) return;
  527 + if (this.ispreview) {
  528 + this.getEchartData(val);
  529 + this.flagInter = setInterval(() => {
  530 + this.getEchartData(val);
  531 + }, refreshTime);
  532 + } else {
  533 + this.getEchartData(val);
  534 + }
  535 + },
  536 + getEchartData(val) {
  537 + const data = this.queryEchartsData(val);
  538 + data.then(res => {
  539 + this.renderingFn(res);
  540 + });
  541 + },
  542 + renderingFn(val) {
  543 + if(this.isNotBlankArray(val)){
  544 + for (let i = 0; i < val.length; i++) {
  545 + const one = val[i];
  546 + const sValue = (this.isBlankObject(one)|| this.isBlank(one['sValue']))?"":one['sValue'];
  547 + if(this.isNotBlankObj(one) && this.isNotBlank(one['sName'])){
  548 + const sName = one['sName'];
  549 + this.masterData[sName]=sValue;
  550 + }
  551 + }
  552 + }
  553 + this.SET_STATIC_DATA(this.masterData);
506 554 },
  555 +
507 556 handleBigScreen(data) {
508 557 const optionScreen = getToolByCode("screen").options;
509 558 const setup = optionScreen.setup;
... ... @@ -520,9 +569,9 @@ export default {
520 569 backgroundImage: (data && data.backgroundImage) || "",
521 570 height: (data && data.height) || 1080,
522 571 title: (data && data.title) || "",
  572 + description: (data && data.description) || "",
523 573 width: (data && data.width) || 1920,
524   - master: (data && data.master) || null,
525   - refreshMasterTime: (data && data.refreshMasterTime) || null,
  574 + data: (data && data.data) || {},
526 575 };
527 576 },
528 577 handleInitEchartsData(data) {
... ... @@ -588,6 +637,7 @@ export default {
588 637 this.$message.error("请添加组件");
589 638 return;
590 639 }
  640 + // console.log("保存数据DATA",this.dashboard);
591 641 const screenData = {
592 642 reportCode: this.$route.query.reportCode,
593 643 dashboard: {
... ... @@ -595,8 +645,7 @@ export default {
595 645 width: this.dashboard.width,
596 646 height: this.dashboard.height,
597 647 backgroundColor: this.dashboard.backgroundColor,
598   - refreshMasterTime: this.dashboard.refreshMasterTime,
599   - master: this.dashboard.master,
  648 + data: this.dashboard.data,
600 649 backgroundImage: this.dashboard.backgroundImage,
601 650 },
602 651 widgets: this.widgets,
... ... @@ -725,7 +774,7 @@ export default {
725 774 // 处理默认值
726 775 const widgetJsonValue = this.handleDefaultValue(widgetJson);
727 776  
728   - //2022年02月22日 修复:可以拖拽放到鼠标的位置
  777 + //可以拖拽放到鼠标的位置
729 778 widgetJsonValue.value.position.left =
730 779 x - widgetJsonValue.value.position.width / 2;
731 780 widgetJsonValue.value.position.top =
... ... @@ -788,7 +837,16 @@ export default {
788 837 // 选中不同的组件 右侧都显示第一栏
789 838 this.activeName = "first";
790 839 this.widgetOptions = getToolByCode("screen")["options"];
791   - this.SET_STATIC_DATA(this.widgetOptions.data.find(item => item.name === 'staticData').value);
  840 + },
  841 + getScreenData(data){
  842 + const screenData = {};
  843 + if(this.isNotBlankArray(data)){
  844 + for (let i = 0; i < data.length; i++) {
  845 + const one =data[i];
  846 + screenData[one.name]=one.value;
  847 + }
  848 + }
  849 + return screenData;
792 850 },
793 851  
794 852 // 如果是点击某个组件,获取该组件的配置项
... ... @@ -837,6 +895,17 @@ export default {
837 895 this.$refs.widgets[i].$refs.draggable.setActive(false);
838 896 }
839 897 },
  898 + setWidgetOptionsData(val){
  899 + let newData = new Array();
  900 + const cloneVal = this.deepClone(val);
  901 + this.widgetOptions.data.forEach((el) => {
  902 + if (Object.hasOwn(cloneVal, el.name)) {
  903 + el["value"] = cloneVal[el.name];
  904 + }
  905 + newData.push(el);
  906 + });
  907 + this.widgetOptions.data = newData;
  908 + },
840 909 // 将当前选中的组件,右侧属性值更新
841 910 widgetValueChanged(key, val) {
842 911 if (this.screenCode == "screen") {
... ... @@ -863,19 +932,19 @@ export default {
863 932 });
864 933 this.widgetOptions.setup = newSetup;
865 934 } else if (key === 'data') {
866   - // 全局数据更改
867   - val.staticData && this.SET_STATIC_DATA(val.staticData);
868   - let newData = new Array();
869   - const cloneVal = this.deepClone(val);
870   - this.widgetOptions.data.forEach((el) => {
  935 + // 全局数据更改
  936 + this.dashboard.data=val;
  937 + let newData = new Array();
  938 + const cloneVal = this.deepClone(val);
  939 + this.widgetOptions.data.forEach((el) => {
871 940 if (Object.hasOwn(cloneVal, el.name)) {
872 941 el["value"] = cloneVal[el.name];
873 942 }
874 943 newData.push(el);
875 944 });
876 945 this.widgetOptions.data = newData;
  946 + this.setMasterData(this.dashboard);
877 947 }
878   -
879 948 } else {
880 949 for (let i = 0; i < this.widgets.length; i++) {
881 950 if (this.widgetIndex == i) {
... ...
src/views/bigscreenDesigner/designer/tools/configure/barlineCharts/widget-barlinechart.js
1 1 /*
2 2 * @Descripttion: 柱线图
3   - * @version:
4   - * @Author: qianlishi
5   - * @Date: 2021-08-29 07:26:48
6   - * @LastEditors: qianlishi qianlishi@anji-plus.com
7   - * @LastEditTime: 2022-11-07 15:39:29
8 3 */
9 4 export const widgetBarlinechart = {
10 5 code: 'widget-barlinechart',
... ...
src/views/bigscreenDesigner/designer/tools/configure/barlineCharts/widget-more-bar-line.js
1 1 /*
2 2 * @Descripttion: 多柱线图
3   - * @version:
4   - * @Author: foming
5   - * @Date:
6   - * @LastEditors: qianlishi qianlishi@anji-plus.com
7   - * @LastEditTime: 2022-11-07 15:39:52
8 3 */
9 4 export const widgetMoreBarLine = {
10 5 code: 'widgetMoreBarLineChart',
... ...
src/views/bigscreenDesigner/designer/tools/configure/bubbleChars/widget-bubble-chart.js 0 → 100644
  1 +/*
  2 + * @Descripttion: DIV图层次
  3 + */
  4 +export const widgetBubblechart = {
  5 + code: 'widget-bubble-chart',
  6 + type: 'html',
  7 + tabName: '图层',
  8 + label: '气泡图',
  9 + icon: 'icontupian1',
  10 + options: {
  11 + // 配置
  12 + setup: [
  13 + {
  14 + type: 'el-input-text',
  15 + label: '图层名称',
  16 + name: 'layerName',
  17 + required: false,
  18 + placeholder: '',
  19 + value: '边框',
  20 + },
  21 + {
  22 + type: 'el-select',
  23 + label: '边框类型',
  24 + name: 'divType',
  25 + required: false,
  26 + placeholder: '',
  27 + selectOptions: [
  28 + {code: 'dv-border-Box-1', name: '边框1'},
  29 + {code: 'dv-border-Box-2', name: '边框2'},
  30 + {code: 'dv-border-Box-3', name: '边框3'},
  31 + {code: 'dv-border-Box-4', name: '边框4'},
  32 + {code: 'dv-border-Box-5', name: '边框5'},
  33 + {code: 'dv-border-Box-6', name: '边框6'},
  34 + {code: 'dv-border-Box-7', name: '边框7'},
  35 + {code: 'dv-border-Box-8', name: '边框8'},
  36 + {code: 'dv-border-Box-9', name: '边框9'},
  37 + {code: 'dv-border-Box-10', name: '边框10'},
  38 + {code: 'dv-border-Box-11', name: '边框11'},
  39 + {code: 'dv-border-Box-12', name: '边框12'},
  40 + {code: 'dv-border-Box-13', name: '边框13'},
  41 + ],
  42 + value: 'dv-border-Box-1'
  43 + },
  44 + {
  45 + type: 'vue-color',
  46 + label: '颜色(主)',
  47 + name: 'colorOne',
  48 + required: false,
  49 + placeholder: '',
  50 + value: '',
  51 + },
  52 + {
  53 + type: 'vue-color',
  54 + label: '颜色(次)',
  55 + name: 'colorTwo',
  56 + required: false,
  57 + placeholder: '',
  58 + value: '',
  59 + },
  60 + {
  61 + type: 'vue-color',
  62 + label: '背景色',
  63 + name: 'backgroundColor',
  64 + required: false,
  65 + placeholder: '',
  66 + value: 'rgba(255, 0, 0, 0)',
  67 + },
  68 + {
  69 + type: 'el-input-number',
  70 + label: '单次动画时间长',
  71 + name: 'dur',
  72 + required: false,
  73 + placeholder: '',
  74 + value: 3,
  75 + },
  76 + {
  77 + type: 'el-switch',
  78 + label: '反向',
  79 + name: 'reverse',
  80 + require: false,
  81 + placeholder: '',
  82 + value: false,
  83 + },
  84 + {
  85 + type: 'el-input-text',
  86 + label: '标题',
  87 + name: 'title',
  88 + require: false,
  89 + placeholder: '',
  90 + value: '',
  91 + },
  92 + {
  93 + type: 'el-input-number',
  94 + label: '标题宽度',
  95 + name: 'titleWidth',
  96 + require: false,
  97 + placeholder: '',
  98 + value: 250,
  99 + }
  100 + ],
  101 + // 数据
  102 + data: [],
  103 + // 坐标
  104 + position: [
  105 + {
  106 + type: 'el-input-number',
  107 + label: '左边距',
  108 + name: 'left',
  109 + required: false,
  110 + placeholder: '',
  111 + value: 10,
  112 + },
  113 + {
  114 + type: 'el-input-number',
  115 + label: '上边距',
  116 + name: 'top',
  117 + required: false,
  118 + placeholder: '',
  119 + value: 10,
  120 + },
  121 + {
  122 + type: 'el-input-number',
  123 + label: '宽度',
  124 + name: 'width',
  125 + required: false,
  126 + placeholder: '该容器在1920px大屏中的宽度',
  127 + value: 500,
  128 + },
  129 + {
  130 + type: 'el-input-number',
  131 + label: '高度',
  132 + name: 'height',
  133 + required: false,
  134 + placeholder: '该容器在1080px大屏中的高度',
  135 + value: 350,
  136 + },
  137 + ],
  138 + }
  139 +}
... ...
src/views/bigscreenDesigner/designer/tools/configure/decorateCharts/widget-decorate-pie.js
1 1 /*
2 2 * @Descripttion: 装饰饼图
3   - * @version:
4   - * @Author: foming
5   - * @Date:
6   - * @LastEditors: qianlishi qianlishi@anji-plus.com
7   - * @LastEditTime: 2022-11-07 15:40:07
8 3 */
9 4 export const widgetDecoratePie = {
10 5 code: 'widgetDecoratePieChart',
... ...
src/views/bigscreenDesigner/designer/tools/configure/funnelCharts/widget-funnel.js
1 1 /*
2 2 * @Descripttion: 漏斗图 json
3   - * @version:
4   - * @Author: qianlishi
5   - * @Date: 2021-08-29 07:29:23
6   - * @LastEditors: qianlishi qianlishi@anji-plus.com
7   - * @LastEditTime: 2022-11-07 15:40:21
8 3 */
9 4 export const widgetFunnel = {
10 5 code: 'widget-funnel',
... ...
src/views/bigscreenDesigner/designer/tools/configure/heatmap/widget-heatmap.js
1 1 /*
2 2 * @Descripttion: 热力图
3   - * @version:
4   - * @Author: whw
5   - * @Date: 2021-11-3
6   - * @LastEditors: qianlishi qianlishi@anji-plus.com
7   - * @LastEditTime: 2022-11-07 15:40:35
8 3 */
9 4 export const widgetHeatmap = {
10 5 code: 'widget-heatmap',
... ...
src/views/bigscreenDesigner/designer/tools/configure/lineCharts/widget-line-compare.js
1 1 /*
2 2 * @Descripttion: 折线对比图 json
3   - * @version:
4   - * @Author: foming
5   - * @Date: 2021-08-29 07:39:35
6   - * @LastEditors: qianlishi qianlishi@anji-plus.com
7   - * @LastEditTime: 2022-11-07 15:40:44
8 3 */
9 4 export const widgetLineCompare = {
10 5 code: 'widgetLineCompareChart',
... ...
src/views/bigscreenDesigner/designer/tools/configure/mapCharts/widget-airbubble-map.js
1 1 /*
2 2 * @Descripttion: 气泡地图json
3   - * @version:
4   - * @Author: qianlishi
5   - * @Date: 2021-08-29 07:35:32
6   - * @LastEditors: qianlishi qianlishi@anji-plus.com
7   - * @LastEditTime: 2022-11-07 15:41:02
8 3 */
9 4 export const widgetAirbubbleMap = {
10 5 code: 'widgetAirBubbleMap',
... ...
src/views/bigscreenDesigner/designer/tools/configure/pieCharts/widget-pie-nightingale.js
1 1 /*
2 2 * @Descripttion: 南丁格尔玫瑰图 json
3   - * @version:
4   - * @Author: qianlishi
5   - * @Date: 2021-08-29 07:32:40
6   - * @LastEditors: qianlishi qianlishi@anji-plus.com
7   - * @LastEditTime: 2022-11-07 15:41:37
8 3 */
9 4 export const widgetPieNightingale = {
10 5 code: 'WidgetPieNightingaleRoseArea',
... ...
src/views/bigscreenDesigner/designer/tools/configure/texts/widget-video.js
1   -/*
2   - * @Descripttion: 视频json
3   - * @version:
4   - * @Author: qianlishi
5   - * @Date: 2021-08-29 07:10:22
6   - * @LastEditors: qianlishi qianlishi@anji-plus.com
7   - * @LastEditTime: 2022-11-07 15:42:46
8   - */
9 1 export const widgetVideo = {
10 2 code: 'widget-video',
11 3 type: 'text',
... ... @@ -70,4 +62,4 @@ export const widgetVideo = {
70 62 },
71 63 ],
72 64 }
73   -}
74 65 \ No newline at end of file
  66 +}
... ...
src/views/bigscreenDesigner/designer/tools/configure/widget-universal.js
1   -/*
2   - * @Descripttion: 全能组件json
3   - * @version:
4   - * @Author: qianlishi
5   - * @Date: 2021-08-29 07:20:11
6   - * @LastEditors: qianlishi
7   - * @LastEditTime: 2021-08-29 07:26:02
8   - */
9 1 export const widgetUniversal = {
10 2 code: 'widget-universal',
11 3 type: 'html',
12 4 label: '全能组件',
13 5 icon: 'univresal',
14   - }
15 6 \ No newline at end of file
  7 + }
... ...
src/views/bigscreenDesigner/designer/tools/index.js
1 1 /*
2 2 * @Descripttion: 主文件
3   - * @version:
4   - * @Author: qianlishi
5   - * @Date: 2021-08-29 06:43:07
6   - * @LastEditors: qianlishi qianlishi@anji-plus.com
7   - * @LastEditTime: 2022-11-07 15:35:42
8 3 */
9 4 import { widgetTool } from "./main"
10 5 const screenConfig = {
... ... @@ -46,22 +41,22 @@ const screenConfig = {
46 41 placeholder: '',
47 42 value: ''
48 43 },
49   - {
50   - type: 'data-source-select',
51   - label: '主数据源',
52   - name: 'master',
53   - required: false,
54   - placeholder: '主数据源[List:sName、sValue] ',/**LIST sName、sValue 后台代码自动转成 sName:sValue Map形式*/
55   - value: ''
56   - },
57   - {
58   - type: 'el-input-number',
59   - label: '刷新时间(毫秒)',
60   - name: 'refreshMasterTime',
61   - value: '600000',
62   - required: false,
63   - placeholder: '毫秒',
64   - },
  44 + // {
  45 + // type: 'data-source-select',
  46 + // label: '主数据源',
  47 + // name: 'master',
  48 + // required: false,
  49 + // placeholder: '主数据源[List:sName、sValue] ',/**LIST sName、sValue 后台代码自动转成 sName:sValue Map形式*/
  50 + // value: ''
  51 + // },
  52 + // {
  53 + // type: 'el-input-number',
  54 + // label: '刷新时间(毫秒)',
  55 + // name: 'refreshMasterTime',
  56 + // value: '600000',
  57 + // required: false,
  58 + // placeholder: '毫秒',
  59 + // },
65 60 {
66 61 type: 'vue-color',
67 62 label: '背景颜色',
... ... @@ -79,58 +74,56 @@ const screenConfig = {
79 74 value: '',
80 75 }
81 76 ],
82   - // data: [],
83 77 data: [{
84   - type: 'el-radio-group',
85   - label: '数据类型',
86   - name: 'dataType',
87   - require: false,
88   - placeholder: '',
89   - selectValue: true,
90   - selectOptions: [
91   - {
92   - code: 'staticData',
93   - name: '静态数据',
94   - },
95   - {
96   - code: 'dynamicData',
97   - name: '动态数据',
98   - },
99   - ],
100   - value: 'staticData',
101   - },
102   - {
103   - type: 'el-input-number',
104   - label: '刷新时间(毫秒)',
105   - name: 'refreshTime',
106   - relactiveDom: 'dataType',
107   - relactiveDomValue: 'dynamicData',
108   - value: 600000
109   - },
110   - {
111   - type: 'el-button',
112   - label: '静态数据',
113   - name: 'staticData',
114   - required: false,
115   - placeholder: '',
116   - relactiveDom: 'dataType',
117   - relactiveDomValue: 'staticData',
118   - value: {title:'标题', name: '测试名字', address: '上海市普陀区金沙江路 1518 弄0001','dProductQty':100,'dProductRate':13},
119   - },
120   - {
121   - type: 'dycustComponents',
122   - label: '',
123   - name: 'dynamicData',
124   - required: false,
125   - placeholder: '',
126   - relactiveDom: 'dataType',
127   - relactiveDomValue: 'dynamicData',
128   - chartType: 'master-data',
129   - dictKey: 'MASTER_PROPERTIES',
130   - value: '',
131   - }
132   - ],
133   - position: [],
  78 + type: 'el-radio-group',
  79 + label: '数据类型',
  80 + name: 'dataType',
  81 + require: false,
  82 + placeholder: '',
  83 + selectValue: true,
  84 + selectOptions: [
  85 + {
  86 + code: 'staticData',
  87 + name: '静态数据',
  88 + },
  89 + {
  90 + code: 'dynamicData',
  91 + name: '动态数据',
  92 + },
  93 + ],
  94 + value: 'staticData',
  95 + },
  96 + {
  97 + type: 'el-input-number',
  98 + label: '刷新时间(毫秒)',
  99 + name: 'refreshTime',
  100 + relactiveDom: 'dataType',
  101 + relactiveDomValue: 'dynamicData',
  102 + value: 600000
  103 + },
  104 + {
  105 + type: 'el-button',
  106 + label: '静态数据',
  107 + name: 'staticData',
  108 + required: false,
  109 + placeholder: '',
  110 + relactiveDom: 'dataType',
  111 + relactiveDomValue: 'staticData',
  112 + value: {title:'标题', name: '测试名字', address: '上海市普陀区金沙江路 1518 弄0001','dProductQty':100,'dProductRate':13},
  113 + },
  114 + {
  115 + type: 'dycustComponents',
  116 + label: '',
  117 + name: 'dynamicData',
  118 + required: false,
  119 + placeholder: '',
  120 + relactiveDom: 'dataType',
  121 + relactiveDomValue: 'dynamicData',
  122 + chartType: 'master-data',
  123 + dictKey: 'MASTER_PROPERTIES',
  124 + value: '',
  125 + }],
  126 + position: [],
134 127 }
135 128 }
136 129  
... ... @@ -168,4 +161,4 @@ const getToolByCode = function (code) {
168 161 return item.code == code
169 162 })
170 163 }
171   -export { widgetTools, getToolByCode }
  164 +export { widgetTools, getToolByCode}
... ...
src/views/bigscreenDesigner/designer/tools/main.js
1   -/*
2   - * @Descripttion: json 入口文件
3   - * @version:
4   - * @Author: qianlishi
5   - * @Date: 2021-08-29 07:46:46
6   - * @LastEditors: qianlishi qianlishi@anji-plus.com
7   - * @LastEditTime: 2022-11-07 15:34:02
8   - */
9 1 // import { widgetDiv } from "./configure/div/widget-div"
10 2 import { widgetBorderBox } from "./configure/div/widget-border-box";
11 3 import { widgetDecoration } from "./configure/div/widget-decoration";
... ...
src/views/bigscreenDesigner/designer/widget/bubble/widgetBubblechart.vue 0 → 100644
  1 +<!--
  2 +气泡图
  3 + !-->
  4 +<template>
  5 + <div :class="styleObj" id="container"></div>
  6 +</template>
  7 +<script>
  8 +import { Chart } from '@antv/g2';
  9 +export default {
  10 + name: "WidgetBubblechart",
  11 + components: {},
  12 + props: {
  13 + value: Object,
  14 + ispreview: Boolean
  15 + },
  16 + data(){
  17 + return {
  18 + chart:null,//图表对象
  19 + showData:[//图表中将要显示的数据
  20 + {
  21 + "year": "1956 年",
  22 + "sales": 61,
  23 + "size": 21,
  24 + "group": "分组1"
  25 + },
  26 + {
  27 + "year": "1957 年",
  28 + "sales": 145,
  29 + "size": 45,
  30 + "group": "分组1"
  31 + },
  32 + {
  33 + "year": "1958 年",
  34 + "sales": 48,
  35 + "size": 68,
  36 + "group": "分组1"
  37 + },
  38 + {
  39 + "year": "1959 年",
  40 + "sales": 38,
  41 + "size": 78,
  42 + "group": "分组1"
  43 + },
  44 + {
  45 + "year": "1960 年",
  46 + "sales": 38,
  47 + "size": 18,
  48 + "group": "分组1"
  49 + },
  50 + {
  51 + "year": "1962 年",
  52 + "sales": 38,
  53 + "size": 18,
  54 + "group": "分组1"
  55 + },
  56 + {
  57 + "year": "1956 年",
  58 + "sales": 41,
  59 + "size": 61,
  60 + "group": "分组2"
  61 + },
  62 + {
  63 + "year": "1957 年",
  64 + "sales": 45,
  65 + "size": 25,
  66 + "group": "分组2"
  67 + },
  68 + {
  69 + "year": "1958 年",
  70 + "sales": 68,
  71 + "size": 28,
  72 + "group": "分组2"
  73 + },
  74 + {
  75 + "year": "1959 年",
  76 + "sales": 48,
  77 + "size": 28,
  78 + "group": "分组2"
  79 + },
  80 + {
  81 + "year": "1960 年",
  82 + "sales": 28,
  83 + "size": 78,
  84 + "group": "分组2"
  85 + },
  86 + {
  87 + "year": "1962 年",
  88 + "sales": 18,
  89 + "size": 38,
  90 + "group": "分组2"
  91 + }
  92 + ],
  93 + }
  94 + },
  95 + created(){
  96 +
  97 + },
  98 + computed: {
  99 + styleObj() {
  100 + return {
  101 + position: this.ispreview ? 'absolute' : 'static',
  102 + width: this.optionsStyle.width + 'px',
  103 + height: this.optionsStyle.height + 'px',
  104 + left: this.optionsStyle.left + 'px',
  105 + top: this.optionsStyle.top + 'px',
  106 + background: this.optionsSetup.background
  107 + };
  108 + }
  109 + },
  110 + mounted(){
  111 + this.init();
  112 + },
  113 + methods:{
  114 + // 初始化
  115 + init(){
  116 + this.createChart();//创建chart
  117 + this.setChartData();//设置字段和数据
  118 + this.setChartAxis();//设置坐标轴和度量
  119 + this.setChartTooltip();//设置提示信息
  120 + this.chart.interaction('element-active');//设置图表样式
  121 + this.setChartStyle();//设置图表柱子相关属性
  122 + // this.chart.legend(false);//设置为false,表示不显示图例
  123 + this.setChartLegend();//设置图例
  124 + this.setChartAnimate();//设置动画
  125 + //渲染图表
  126 + this.chart.render();
  127 + //添加点击事件
  128 + this.addClickEvent();
  129 +
  130 + },
  131 + //创建chart
  132 + createChart(){
  133 + this.chart = new Chart({
  134 + container: 'container',//chart容器id
  135 + autoFit: false,//图表是否自适应容器宽高,默认为 false
  136 + width: 800,//图标宽度
  137 + height: 400,//图表高度
  138 + padding: [40, 120, 80, 120],//图表内边距,依次为:上,右,下,左
  139 + // defaultInteractions:"ellipsis-text",//配置图表默认交互,仅支持字符串形式。G2 默认支持的交互有 'tooltip', 'legend-filter', 'legend-active', 'continuous-filter', 'ellipsis-text'
  140 + pixelRatio:window.devicePixelRatio,//设置设备像素比,默认取浏览器的值 window.devicePixelRatio
  141 + renderer:"canvas",//指定渲染引擎,默认使用 canvas。可选:'canvas' | 'svg'
  142 + theme:"dark",//配置主题,目前 g2 默认有 dark 主题模式,如需要自定义配置,可以先通过 registerTheme 注册主题,再设置主题 key。
  143 + visible:true,//chart 是否可见,默认为 true,设置为 false 则会隐藏。
  144 + });
  145 + },
  146 + //设置数据
  147 + setChartData(){
  148 + this.chart.data(this.showData);
  149 + },
  150 + //设置坐标轴
  151 + setChartAxis(){
  152 + var scale={};
  153 + scale["sales"]={
  154 + type: 'pow',
  155 + nice: true,
  156 + }
  157 + scale["size"]={
  158 + type: 'pow',
  159 + nice: true,
  160 + }
  161 + this.chart.scale(scale, {//Y轴 字段是 度量
  162 + nice: false,//是否自动调整 min、max 。默认为false
  163 + min: 10,//度量最小值,
  164 + max: 120,//度量最大值,如果不需要指定最大值可以设置max=null,或者不要填该参数
  165 + });
  166 + //设置Y轴
  167 + //this.chart.axis("sales",false);//不需要Y轴,可以设置false
  168 + this.chart.axis("sales", {//Y轴样式
  169 + grid:{
  170 + line:{
  171 + type:"line",
  172 + style:{
  173 + // fill:'#ff0000',
  174 + stroke:"#fff",//网格线颜色
  175 + opacity:0.3,//网格线透明度
  176 + lineDash:[1,3],//虚线
  177 + }
  178 + },
  179 + },
  180 + label:{
  181 + style:{
  182 + fill:"#fff",///Y轴文字颜色
  183 + fontFamily: "Microsoft YaHei",///Y轴文字字体
  184 + fontWeight: 400,///Y轴文字粗细
  185 + fontSize: 12,///Y轴文字大小
  186 + }
  187 + },
  188 + line:{
  189 + style:{
  190 + stroke:"#fff",//坐标轴颜色
  191 + }
  192 + },
  193 + tickLine: {
  194 + style:{
  195 + stroke:"#fff",//刻度线颜色
  196 + }
  197 + },
  198 + subTickLine:{
  199 + style:{
  200 + stroke:"#fff",//小刻度颜色
  201 + }
  202 + }
  203 + });
  204 +
  205 + //设置X轴
  206 + //this.chart.axis("year",false);//不需要Y轴,可以设置false
  207 + this.chart.axis("year", {//X轴样式
  208 +
  209 + label: {
  210 + formatter: (val) => {
  211 + return val;
  212 + // return +val * 100 + '%';
  213 + },
  214 + style:{
  215 + fill:"#fff",//文字颜色
  216 + fontFamily: "Microsoft YaHei",//文字字体
  217 + fontWeight: 400,//文字粗细
  218 + fontSize: 12,//文字大小
  219 + }
  220 + },
  221 + line:{
  222 + style:{
  223 + stroke:"#fff",//坐标轴颜色
  224 + }
  225 + },
  226 + tickLine: {
  227 + style:{
  228 + stroke:"#fff",//刻度线颜色
  229 + }
  230 + },
  231 + subTickLine:{
  232 + style:{
  233 + stroke:"#fff",//小刻度颜色
  234 + }
  235 + }
  236 + });
  237 + },
  238 + //设置提示框信息样式
  239 + setChartTooltip(){
  240 + this.chart.tooltip({
  241 + showMarkers: false,
  242 + showCrosshairs: false,
  243 + domStyles:{
  244 + 'g2-tooltip':{
  245 + background:"rgba(00, 00, 00,0.5)",//背景RGBA形式的值
  246 + color:"#ffffff",//文字颜色
  247 + boxShadow:"0px 0px 5px #000000",//阴影大小 阴影颜色
  248 + },
  249 + },
  250 + customItems: (items) => {//自定义显示的内容格式
  251 + // console.log("items")
  252 + // console.log(items)
  253 + // items[0].name="sales";
  254 + return items;
  255 + },
  256 + });
  257 + },
  258 + //设置图表气泡相关属性【气泡样式】
  259 + setChartStyle(){
  260 + var line=this.chart.point();
  261 +
  262 + line.size(6)//圆点大小
  263 + .style({
  264 + // strokeOpacity:1,
  265 + // fill: this.attrs.style.pointColor,
  266 + stroke:"#fff",//圆点边框颜色
  267 +
  268 + })
  269 + .state({
  270 + // selected:{
  271 + // style:{
  272 + // stroke:'red',
  273 + // }
  274 + // }
  275 + active:{
  276 + style:{
  277 + stroke:"#2681ff",//鼠标经过 边框颜色
  278 + }
  279 + }
  280 + })
  281 + .position("year"+"*"+"sales")//X轴 * Y轴
  282 + .size("size"+"",[1,40])//气泡半径范围 1-30
  283 + .color("group", ["#2681ff","#00ff44","#2611ff","#26aa99"])//参数1:group字段为分组字段,参数2:颜色数组,散点的颜色会循环的从颜色数组中取出来
  284 + .tooltip("year"+"*"+"sales"+"*"+"size"+"*"+"group")
  285 + .shape('circle');
  286 + //柱子上是否显示值标签
  287 + //line.label(false);//不需要显示,可以设置false
  288 + line.label("sales", {//标签值
  289 + content: (originData) => {
  290 + return originData["sales"]+"万";//设置值标签最终显示的内容
  291 + },
  292 + style: {
  293 + fill: "#fff",
  294 + fontFamily: "Microsoft YaHei",
  295 + fontWeight: 400,
  296 + fontSize: 16,
  297 + // fill: "#ffffff",
  298 + },
  299 + position:"top",//显示位置
  300 + })
  301 + },
  302 + //设置图例
  303 + setChartLegend(){
  304 +
  305 + // this.chart.legend(false);//设置为false,表示不显示图例
  306 +
  307 + this.chart.legend("group", {
  308 + position: "bottom",//图例位置:"top" | "top-left" | "top-right" | "right" | "right-top" | "right-bottom" | "left" | "left-top" | "left-bottom" | "bottom" | "bottom-left" | "bottom-right"
  309 + itemName:{
  310 + style:{
  311 + fill: "#fff",
  312 + fontFamily: "Microsoft YaHei",
  313 + fontWeight: 400,
  314 + fontSize: 16,
  315 + }
  316 + },
  317 + pageNavigator: {
  318 + marker: {//分页器指示箭头配置项
  319 + style: {
  320 + // 非激活,不可点击态时的填充色设置
  321 + inactiveFill: "#fff",//分页器:箭头颜色
  322 + inactiveOpacity: 1,//分页器:箭头透明度
  323 + // 默认填充色设置
  324 + fill: "#fff",//分页器:颜色
  325 + opacity: 1,//分页器:透明度
  326 + size: 12,//分页器:大小
  327 + },
  328 + },
  329 + text: {//分页器指示文本配置项
  330 + style: {
  331 + fill: "#fff",//分页器:文本颜色
  332 + fontSize: 12,//分页器:文本大小
  333 + },
  334 + },
  335 + },
  336 + });
  337 + },
  338 + //设置动画
  339 + setChartAnimate(){
  340 + // this.chart.animate(false);//设置为false,表示不使用动画效果
  341 + this.chart.animate({
  342 + // 初始化时的入场动画
  343 + appear: {
  344 + animation: 'fade-in', // 动画名称:'fade-in'|'fan-in'|'scale-inx'|'scale-iny'|'path-in'|'zoom-in'|'clip-in'
  345 + easing: 'easeQuadIn', // 动画缓动效果
  346 + delay: 100, // 动画延迟执行时间
  347 + duration: 600 // 动画执行时间
  348 + },
  349 + // 更新时的出现动画
  350 + enter: {
  351 + animation: 'fade-in', //动画名称:'fade-in'|'fan-in'|'scale-inx'|'scale-iny'|'path-in'|'zoom-in'|'clip-in'
  352 + easing: 'easeQuadIn', // 动画缓动效果
  353 + delay: 100, // 动画延迟执行时间
  354 + duration: 600 // 动画执行时间
  355 + },
  356 + // 更新时的动画
  357 + leave: {
  358 + animation: 'path-out', //动画名称:'fade-out'|'path-out'|'zoom-out'|'lineWidth-out'
  359 + easing: 'easeQuadIn', // 动画缓动效果
  360 + delay: 100, // 动画延迟执行时间
  361 + duration: 600 // 动画执行时间
  362 + },
  363 + // 更新时的变化动画
  364 + update: {
  365 + animation: 'fade-in', //动画名称:'fade-in'|'fan-in'
  366 + easing: 'easeQuadIn', // 动画缓动效果
  367 + delay: 100, // 动画延迟执行时间
  368 + duration: 600 // 动画执行时间
  369 + },
  370 + })
  371 + },
  372 + //添加点击事件
  373 + addClickEvent(){
  374 + this.chart.on('element:click', (ev) => {
  375 + var data=ev.data.data;
  376 + console.log(data);
  377 + alert(JSON.stringify(data));
  378 + });
  379 + }
  380 + },
  381 +}
  382 +</script>
  383 +
  384 +<style scoped lang="scss">
  385 +.echarts {
  386 + width: 100%;
  387 + height: 100%;
  388 + overflow: hidden;
  389 +}
  390 +.container{width:800px; height: 800px; margin: 100px auto; background: cadetblue;}
  391 +</style>
... ...
src/views/bigscreenDesigner/designer/widget/temp.vue
1   -<!--
2   - * @Author: lide1202@hotmail.com
3   - * @Date: 2021-3-13 11:04:24
4   - * @Last Modified by: lide1202@hotmail.com
5   - * @Last Modified time: 2021-3-13 11:04:24
6   - !-->
7 1 <template>
8 2 <div>
9 3 <component :is="type" :value="value" :ispreview="true"/>
... ...
src/views/bigscreenDesigner/designer/widget/text/widgetTable.vue
... ... @@ -69,7 +69,7 @@ export default {
69 69 },
70 70 computed: {
71 71 styleObj() {
72   - console.log(this.optionsSetUp);
  72 + //console.log(this.optionsSetUp);
73 73 const allStyle = this.optionsPosition;
74 74 return {
75 75 position: this.ispreview ? "absolute" : "static",
... ...
src/views/bigscreenDesigner/viewer/index.vue
... ... @@ -17,6 +17,7 @@
17 17 <script>
18 18 import widget from "../designer/widget/temp";
19 19 import { detailDashboard } from "@/api/bigscreen";
  20 +import { mapMutations } from 'vuex';
20 21 export default {
21 22 name: "Login",
22 23 components: {
... ... @@ -25,13 +26,15 @@ export default {
25 26 data() {
26 27 return {
27 28 bigScreenStyle: {},
28   - widgets: []
  29 + widgets: [],
  30 + masterData:{}
29 31 };
30 32 },
31 33 mounted() {
32 34 this.getData();
33 35 },
34 36 methods: {
  37 + ...mapMutations('dataSource', ['SET_STATIC_DATA']),
35 38 async getData() {
36 39 const reportCode = this.$route.query.reportCode;
37 40 const { code, data } = await detailDashboard(reportCode);
... ... @@ -52,9 +55,54 @@ export default {
52 55 transform: `scale(${ratioEquipment}, ${ratioEquipment})`,
53 56 "transform-origin": "0 0"
54 57 };
  58 + // 赋值到全局变量
  59 + this.setMasterData(data.dashboard);
  60 + //加载其余子组件
55 61 this.widgets = data.dashboard.widgets;
56   - }
57   - }
  62 + },
  63 + // 数据处理
  64 + setMasterData(screenData){
  65 + // 数据类型 静态 or 动态
  66 + const screenD = screenData.data;
  67 + const refreshTime = screenD["refreshTime"]||60000*30;
  68 + screenD.dataType == "staticData"
  69 + ? this.staticDataFn(screenD.staticData)
  70 + : this.dynamicDataFn(screenD.dynamicData, refreshTime);
  71 + },
  72 + staticDataFn(val) {
  73 + //获取静态数据
  74 + this.masterData=val;
  75 + this.SET_STATIC_DATA(this.masterData);
  76 + },
  77 + dynamicDataFn(val, refreshTime) {
  78 + if (!val) return;
  79 + //第一次赋值
  80 + this.getEchartData(val);
  81 + //定时赋值
  82 + this.flagInter = setInterval(() => {
  83 + this.getEchartData(val);
  84 + }, refreshTime);
  85 + },
  86 + getEchartData(val) {
  87 + const data = this.queryEchartsData(val);
  88 + data.then(res => {
  89 + this.renderingFn(res);
  90 + });
  91 + },
  92 + renderingFn(val) {
  93 + if(this.isNotBlankArray(val)){
  94 + for (let i = 0; i < val.length; i++) {
  95 + const one = val[i];
  96 + const sValue = (this.isBlankObject(one)|| this.isBlank(one['sValue']))?"":one['sValue'];
  97 + if(this.isNotBlankObj(one) && this.isNotBlank(one['sName'])){
  98 + const sName = one['sName'];
  99 + this.masterData[sName]=sValue;
  100 + }
  101 + }
  102 + }
  103 + this.SET_STATIC_DATA(this.masterData);
  104 + },
  105 + },
58 106 };
59 107 </script>
60 108  
... ...
src/views/reportManage/components/copyDialog.vue
1 1 <!--
2   - * @Descripttion:
3   - * @version:
4   - * @Author: qianlishi
5   - * @Date: 2022-05-17 16:55:05
6   - * @LastEditors: qianlishi
7   - * @LastEditTime: 2022-05-17 17:38:54
  2 + * @Descripttion: 报表管理--复制
8 3 -->
9 4 <template>
10 5 <el-dialog
... ...
src/views/reportManage/index.vue
1 1 <!--
2 2 * @Descripttion: 报表设计--报表管理
3   - * @version:
4   - * @Author: qianlishi
5   - * @Date: 2021-12-11 14:48:27
6   - * @LastEditors: qianlishi
7   - * @LastEditTime: 2022-05-17 17:38:44
8 3 -->
9 4 <template>
10 5 <anji-crud ref="listPage" :option="crudOption">
... ...
src/views/resultset/index.vue
1 1 <!--
2 2 * @Descripttion: 用户权限--数据集
3   - * @version:
4   - * @Author: qianlishi
5   - * @Date: 2021-12-11 14:48:27
6   - * @LastEditors: qianlishi
7   - * @LastEditTime: 2022-04-14 18:48:24
8 3 -->
9 4 <template>
10 5 <anji-crud ref="listPage" :option="crudOption">
... ...
src/views/screenDesigner/index备份.vue deleted
1   -<template>
2   - <div class="layout">
3   - <div class="layout-container">
4   - <!-- 图表 -->
5   - <el-tabs class="layout-left" type="border-card">
6   - <el-tab-pane>
7   - <span slot="label"><i class="el-icon-date icon"></i>工具栏</span>
8   - <div class="chart-type">
9   - <el-tabs class="type-left" tab-position="left">
10   - <el-tab-pane
11   - v-for="(item, index) in widgetTools"
12   - :key="index"
13   - :label="item.name"
14   - >
15   - <draggable
16   - v-for="(it, idx) in item.list"
17   - :key="idx"
18   - @end="evt => widgetOnDragged(evt, it.code)"
19   - >
20   - <div class="tools-item">
21   - <span class="tools-item-icon">
22   - <i class="iconfont" :class="it.icon"></i>
23   - </span>
24   - <span class="tools-item-text">{{ it.label }}</span>
25   - </div>
26   - </draggable>
27   - </el-tab-pane>
28   - </el-tabs>
29   - </div>
30   - </el-tab-pane>
31   - <el-tab-pane>
32   - <span slot="label" class="icon"
33   - ><i class="el-icon-date icon"></i>图层</span
34   - >
35   - <div
36   - v-for="(item, index) in layerWidget"
37   - :key="'item' + index"
38   - class="tools-item"
39   - :class="widgetIndex == index ? 'is-active' : ''"
40   - @click="layerClick(index)"
41   - >
42   - <span class="tools-item-icon">
43   - <i class="iconfont" :class="item.icon"></i>
44   - </span>
45   - <span class="tools-item-text">{{ item.label }}</span>
46   - </div>
47   - </el-tab-pane>
48   - </el-tabs>
49   -
50   - <div
51   - class="layout-middle"
52   - :style="{
53   - width: middleWidth + 'px',
54   - height: middleHeight + 'px'
55   - }"
56   - >
57   - <!-- 操作栏 -->
58   - <div class="layout-bar">
59   - <div class="bar-item" @click="saveData">
60   - <i class="iconfont iconsave"></i>保存
61   - </div>
62   - <div class="bar-item" @click="viewScreen">
63   - <i class="iconfont iconyulan"></i>预览
64   - </div>
65   - <div class="bar-item" @click="handleUndo">
66   - <i class="iconfont iconundo"></i>撤销
67   - </div>
68   - <div class="bar-item" @click="handleRedo">
69   - <i class="iconfont iconhuifubeifen"></i>恢复
70   - </div>
71   - <div class="bar-item">
72   - <el-upload
73   - class="el-upload"
74   - ref="upload"
75   - :action="uploadUrl"
76   - :headers="headers"
77   - accept=".zip"
78   - :on-success="handleUpload"
79   - :on-error="handleError"
80   - :show-file-list="false"
81   - :limit="1"
82   - >
83   - <i class="iconfont icondaoru"></i>
84   - </el-upload>
85   - 导入
86   - </div>
87   - <div class="bar-item">
88   - <i class="iconfont icondaochu"></i>
89   - <el-dropdown @command="exportDashboard">
90   - <span class="el-dropdown-link">
91   - 导出<i class="el-icon-arrow-down el-icon--right"></i>
92   - </span>
93   - <el-dropdown-menu slot="dropdown">
94   - <el-dropdown-item command="1"
95   - >导出(包含数据集)</el-dropdown-item
96   - >
97   - <el-dropdown-item command="0"
98   - >导出(不包含数据集)</el-dropdown-item
99   - >
100   - </el-dropdown-menu>
101   - </el-dropdown>
102   - </div>
103   - </div>
104   - <!-- 设计器 -->
105   - <div
106   - class="workbench-container"
107   - :style="{
108   - width: bigscreenWidthInWorkbench + 'px',
109   - height: bigscreenHeightInWorkbench + 'px'
110   - }"
111   - @mousedown="handleMouseDown"
112   - >
113   - <vue-ruler-tool
114   - v-model="dashboard.presetLine"
115   - class="vueRuler"
116   - :step-length="50"
117   - :parent="true"
118   - :position="'relative'"
119   - :is-scale-revise="true"
120   - :visible.sync="dashboard.presetLineVisible"
121   - >
122   - <div
123   - id="workbench"
124   - class="workbench"
125   - :style="{
126   - transform: workbenchTransform,
127   - width: bigscreenWidth + 'px',
128   - height: bigscreenHeight + 'px',
129   - 'background-color': dashboard.backgroundColor,
130   - 'background-image': 'url(' + dashboard.backgroundImage + ')',
131   - 'background-position': '0% 0%',
132   - 'background-size': '100% 100%',
133   - 'background-repeat': 'initial',
134   - 'background-attachment': 'initial',
135   - 'background-origin': 'initial',
136   - 'background-clip': 'initial'
137   - }"
138   - @click.self="setOptionsOnClickScreen"
139   - >
140   - <div v-if="grade" class="bg-grid"></div>
141   - <widget
142   - ref="widgets"
143   - v-for="(widget, index) in widgets"
144   - :key="index"
145   - v-model="widget.value"
146   - :index="index"
147   - :step="step"
148   - :type="widget.type"
149   - :bigscreen="{ bigscreenWidth, bigscreenHeight }"
150   - @onActivated="setOptionsOnClickWidget"
151   - @contextmenu.prevent.native="rightClick($event, index)"
152   - @mousedown.prevent.native="widgetsClick(index)"
153   - @mouseup.prevent.native="widgetsMouseup"
154   - />
155   - </div>
156   - </vue-ruler-tool>
157   - </div>
158   - </div>
159   -
160   - <!-- 设置 -->
161   - <div class="layout-right">
162   - <el-tabs v-model="activeName" type="border-card" :stretch="true">
163   - <el-tab-pane
164   - v-if="
165   - isNotNull(widgetOptions.setup) ||
166   - isNotNull(widgetOptions.collapse)
167   - "
168   - name="first"
169   - label="配置"
170   - >
171   - <dynamicForm
172   - ref="formData"
173   - :options="widgetOptions.setup"
174   - @onChanged="val => widgetValueChanged('setup', val)"
175   - />
176   - </el-tab-pane>
177   - <el-tab-pane
178   - v-if="isNotNull(widgetOptions.data)"
179   - name="second"
180   - label="数据"
181   - >
182   - <dynamicForm
183   - ref="formData"
184   - :options="widgetOptions.data"
185   - @onChanged="val => widgetValueChanged('data', val)"
186   - />
187   - </el-tab-pane>
188   - <el-tab-pane
189   - v-if="isNotNull(widgetOptions.position)"
190   - name="third"
191   - label="坐标"
192   - >
193   - <dynamicForm
194   - ref="formData"
195   - :options="widgetOptions.position"
196   - @onChanged="val => widgetValueChanged('position', val)"
197   - />
198   - </el-tab-pane>
199   - </el-tabs>
200   - </div>
201   - </div>
202   -
203   - <content-menu
204   - :visible.sync="visibleContentMenu"
205   - :style-obj="styleObj"
206   - @deletelayer="deletelayer"
207   - @copylayer="copylayer"
208   - @istopLayer="istopLayer"
209   - @setlowLayer="setlowLayer"
210   - @moveupLayer="moveupLayer"
211   - @movedownLayer="movedownLayer"
212   - />
213   - </div>
214   -</template>
215   -<script>
216   -import {
217   - insertDashboard,
218   - detailDashboard,
219   - importDashboard,
220   - exportDashboard
221   -} from "@/api/bigscreen";
222   -import {
223   - swapArr,
224   - setDefaultValue,
225   - handleDefaultValue,
226   - getPXUnderScale,
227   - handleInitEchartsData,
228   - handleBigScreen,
229   - handlerLayerWidget
230   -} from "./util/screen";
231   -import { screenConfig } from "./config/texts/screenConfig.js";
232   -import { widgetTools, getToolByCode } from "./config/index.js";
233   -import VueRulerTool from "vue-ruler-tool"; // 大屏设计页面的标尺插件
234   -import widget from "./widget/index.vue";
235   -import dynamicForm from "./components/dynamicForm.vue";
236   -import draggable from "vuedraggable";
237   -import contentMenu from "./components/contentMenu";
238   -import { getToken } from "@/utils/auth";
239   -import { Revoke } from "@/utils/revoke"; //处理历史记录 2022-02-22
240   -export default {
241   - components: {
242   - VueRulerTool,
243   - widget,
244   - dynamicForm,
245   - draggable,
246   - contentMenu
247   - },
248   - data() {
249   - return {
250   - uploadUrl:
251   - process.env.BASE_API +
252   - "/reportDashboard/import/" +
253   - this.$route.query.reportCode,
254   - grade: false,
255   - layerWidget: [],
256   - widgetTools: widgetTools, // 左侧工具栏的组件图标,将js变量加入到当前作用域
257   - widthLeftForTools: 200, // 左侧工具栏宽度
258   - widthLeftForToolsHideButton: 15, // 左侧工具栏折叠按钮宽度
259   - widthLeftForOptions: 300, // 右侧属性配置区
260   - widthPaddingTools: 18,
261   - toolIsShow: true, // 左侧工具栏是否显示
262   -
263   - bigscreenWidth: 1920, // 大屏设计的大小
264   - bigscreenHeight: 1080,
265   - revoke: null, //处理历史记录 2022-02-22
266   -
267   - // 工作台大屏画布,保存到表gaea_report_dashboard中
268   - dashboard: {
269   - id: null,
270   - title: "", // 大屏页面标题
271   - width: 1920, // 大屏设计宽度
272   - height: 1080, // 大屏设计高度
273   - backgroundColor: "", // 大屏背景色
274   - backgroundImage: "", // 大屏背景图片
275   - refreshSeconds: null, // 大屏刷新时间间隔
276   - presetLine: [], // 辅助线
277   - presetLineVisible: true // 辅助线是否显示
278   - },
279   - // 大屏的标记
280   - screenCode: "",
281   - // 大屏画布中的组件
282   - widgets: [
283   - {
284   - // type和value最终存到数据库中去,保存到gaea_report_dashboard_widget中
285   - type: "widget-text",
286   - value: {
287   - setup: {},
288   - data: {},
289   - position: {
290   - width: 100,
291   - height: 100,
292   - left: 0,
293   - top: 0,
294   - zIndex: 0
295   - }
296   - },
297   - // options属性是从工具栏中拿到的tools中拿到
298   - options: []
299   - }
300   - ], // 工作区中拖放的组件
301   -
302   - // 当前激活组件
303   - widgetIndex: 0,
304   - // 当前激活组件右侧配置属性
305   - widgetOptions: {
306   - setup: [], // 配置
307   - data: [], // 数据
308   - position: [] // 坐标
309   - },
310   - flagWidgetClickStopPropagation: false, // 点击组件时阻止事件冒泡传递到画布click事件上
311   - styleObj: {
312   - left: 0,
313   - top: 0
314   - },
315   - visibleContentMenu: false,
316   - rightClickIndex: -1,
317   - activeName: "first"
318   - };
319   - },
320   - computed: {
321   - step() {
322   - return Number(100 / (this.bigscreenScaleInWorkbench * 100));
323   - },
324   - headers() {
325   - return {
326   - Authorization: getToken() // 直接从本地获取token就行
327   - };
328   - },
329   - // 左侧折叠切换时,动态计算中间区的宽度
330   - middleWidth() {
331   - let widthLeftAndRight = 0;
332   - if (this.toolIsShow) {
333   - widthLeftAndRight += this.widthLeftForTools; // 左侧工具栏宽度
334   - }
335   - widthLeftAndRight += this.widthLeftForToolsHideButton; // 左侧工具栏折叠按钮宽度
336   - widthLeftAndRight += this.widthLeftForOptions; // 右侧配置栏宽度
337   -
338   - let middleWidth = this.bodyWidth - widthLeftAndRight;
339   - return middleWidth;
340   - },
341   - middleHeight() {
342   - return this.bodyHeight;
343   - },
344   - // 设计台按大屏的缩放比例
345   - bigscreenScaleInWorkbench() {
346   - let widthScale =
347   - (this.middleWidth - this.widthPaddingTools) / this.bigscreenWidth;
348   - let heightScale =
349   - (this.middleHeight - this.widthPaddingTools) / this.bigscreenHeight;
350   - return Math.min(widthScale, heightScale);
351   - },
352   - workbenchTransform() {
353   - return `scale(${this.bigscreenScaleInWorkbench}, ${
354   - this.bigscreenScaleInWorkbench
355   - })`;
356   - },
357   - // 大屏在设计模式的大小
358   - bigscreenWidthInWorkbench() {
359   - return (
360   - getPXUnderScale(this.bigscreenScaleInWorkbench, this.bigscreenWidth) +
361   - this.widthPaddingTools
362   - );
363   - },
364   - bigscreenHeightInWorkbench() {
365   - return (
366   - getPXUnderScale(this.bigscreenScaleInWorkbench, this.bigscreenHeight) +
367   - this.widthPaddingTools
368   - );
369   - }
370   - },
371   - watch: {
372   - widgets: {
373   - handler(val) {
374   - this.layerWidget = handlerLayerWidget(val, getToolByCode);
375   - //以下部分是记录历史
376   - this.$nextTick(() => {
377   - this.revoke.push(this.widgets);
378   - });
379   - },
380   - deep: true
381   - }
382   - },
383   - created() {
384   - /* 以下是记录历史的 */
385   - this.revoke = new Revoke();
386   - },
387   - mounted() {
388   - this.initScreen();
389   - // 如果是新的设计工作台
390   - // this.initEchartData();
391   - this.widgets = [];
392   - window.addEventListener("mouseup", () => {
393   - this.grade = false;
394   - });
395   - },
396   - methods: {
397   - // 初始化大屏
398   - initScreen() {
399   - this.widgetOptions = screenConfig["options"];
400   - },
401   - // 初始化 echrats
402   - async initEchartData() {
403   - const reportCode = this.$route.query.reportCode;
404   - const { code, data } = await detailDashboard(reportCode);
405   - if (code != 200) return;
406   - const processData = handleInitEchartsData(data, getToolByCode);
407   - const screenData = handleBigScreen(
408   - data.dashboard,
409   - getToolByCode,
410   - this.setOptionsOnClickScreen
411   - );
412   - this.widgets = processData;
413   - this.dashboard = screenData;
414   - this.bigscreenWidth = this.dashboard.width;
415   - this.bigscreenHeight = this.dashboard.height;
416   - },
417   -
418   - // 拖动一个组件放到工作区中去,在拖动结束时,放到工作区对应的坐标点上去
419   - widgetOnDragged(evt, widgetCode) {
420   - let widgetType = widgetCode;
421   -
422   - // 获取结束坐标和列名
423   - let eventX = evt.originalEvent.clientX; // 结束在屏幕的x坐标
424   - let eventY = evt.originalEvent.clientY; // 结束在屏幕的y坐标
425   -
426   - let workbenchPosition = this.getDomTopLeftById("workbench");
427   - let widgetTopInWorkbench = eventY - workbenchPosition.top;
428   - let widgetLeftInWorkbench = eventX - workbenchPosition.left;
429   -
430   - // 计算在缩放模式下的x y
431   - let x = widgetLeftInWorkbench / this.bigscreenScaleInWorkbench;
432   - let y = widgetTopInWorkbench / this.bigscreenScaleInWorkbench;
433   -
434   - // 复制一个组件
435   - let tool = getToolByCode(widgetType);
436   - let widgetJson = {
437   - type: widgetType,
438   - value: {
439   - setup: {},
440   - data: {},
441   - position: {
442   - width: 0,
443   - height: 0,
444   - left: 0,
445   - top: 0,
446   - zIndex: 0
447   - }
448   - },
449   - options: tool.options
450   - };
451   - // 处理默认值
452   - const widgetJsonValue = handleDefaultValue(widgetJson);
453   -
454   - //2022年02月22日 修复:可以拖拽放到鼠标的位置
455   - widgetJsonValue.value.position.left =
456   - x - widgetJsonValue.value.position.width / 2;
457   - widgetJsonValue.value.position.top =
458   - y - widgetJsonValue.value.position.height / 2;
459   -
460   - // 将选中的复制组件,放到工作区中去
461   - this.widgets.push(this.deepClone(widgetJsonValue));
462   - // 激活新组件的配置属性
463   - this.setOptionsOnClickWidget(this.widgets.length - 1);
464   - },
465   - // 如果是点击大屏设计器中的底层,加载大屏底层属性
466   - setOptionsOnClickScreen() {
467   - this.screenCode = "screen";
468   - // 选中不同的组件 右侧都显示第一栏
469   - this.activeName = "first";
470   - this.widgetOptions = screenConfig["options"];
471   - },
472   - layerClick(index) {
473   - this.widgetIndex = index;
474   - this.widgetsClick(index);
475   - },
476   - // 如果是点击某个组件,获取该组件的配置项
477   - setOptionsOnClickWidget(obj) {
478   - console.log(obj);
479   - this.screenCode = "";
480   - if (typeof obj == "number") {
481   - this.widgetOptions = this.deepClone(this.widgets[obj]["options"]);
482   - return;
483   - }
484   - if (obj.index < 0 || obj.index >= this.widgets.length) {
485   - return;
486   - }
487   - this.widgetIndex = obj.index;
488   - this.widgets[obj.index].value.position = obj;
489   - this.widgets[obj.index].options.position.forEach(el => {
490   - for (const key in obj) {
491   - if (el.name == key) {
492   - el.value = obj[key];
493   - }
494   - }
495   - });
496   - this.widgetOptions = this.deepClone(this.widgets[obj.index]["options"]);
497   - },
498   - widgetsClick(index) {
499   - const draggableArr = this.$refs.widgets;
500   - for (let i = 0; i < draggableArr.length; i++) {
501   - if (i == index) {
502   - this.$refs.widgets[i].$refs.draggable.setActive(true);
503   - } else {
504   - this.$refs.widgets[i].$refs.draggable.setActive(false);
505   - }
506   - }
507   - this.setOptionsOnClickWidget(index);
508   - this.grade = true;
509   - },
510   - widgetsMouseup(e) {
511   - this.grade = false;
512   - },
513   - handleMouseDown() {
514   - const draggableArr = this.$refs.widgets;
515   - for (let i = 0; i < draggableArr.length; i++) {
516   - this.$refs.widgets[i].$refs.draggable.setActive(false);
517   - }
518   - },
519   - // 将当前选中的组件,右侧属性值更新
520   - widgetValueChanged(key, val) {
521   - if (this.screenCode == "screen") {
522   - let newSetup = new Array();
523   - this.dashboard = this.deepClone(val);
524   - if (this.bigscreenWidth != this.dashboard.width) {
525   - this.bigscreenWidth = this.dashboard.width;
526   - }
527   - if (this.bigscreenHeight != this.dashboard.height) {
528   - this.bigscreenHeight = this.dashboard.height;
529   - }
530   - this.widgetOptions.setup.forEach(el => {
531   - if (el.name == "width") {
532   - el.value = this.bigscreenWidth;
533   - } else if (el.name == "height") {
534   - el.value = this.bigscreenHeight;
535   - }
536   - newSetup.push(el);
537   - });
538   - this.widgetOptions.setup = newSetup;
539   - } else {
540   - for (let i = 0; i < this.widgets.length; i++) {
541   - if (this.widgetIndex == i) {
542   - this.widgets[i].value[key] = this.deepClone(val);
543   - setDefaultValue(this.widgets[i].options[key], val);
544   - }
545   - }
546   - }
547   - },
548   - rightClick(event, index) {
549   - this.rightClickIndex = index;
550   - const left = event.clientX;
551   - const top = event.clientY;
552   - if (left || top) {
553   - this.styleObj = {
554   - left: left + "px",
555   - top: top + "px",
556   - display: "block"
557   - };
558   - }
559   - this.visibleContentMenu = true;
560   - return false;
561   - },
562   - datadragEnd(evt) {
563   - evt.preventDefault();
564   - this.widgets = swapArr(this.widgets, evt.oldIndex, evt.newIndex);
565   - },
566   - // 保存
567   - async saveData() {
568   - if (!this.widgets || this.widgets.length == 0) {
569   - this.$message.error("请添加组件");
570   - return;
571   - }
572   - const screenData = {
573   - reportCode: this.$route.query.reportCode,
574   - dashboard: {
575   - title: this.dashboard.title,
576   - width: this.dashboard.width,
577   - height: this.dashboard.height,
578   - backgroundColor: this.dashboard.backgroundColor,
579   - backgroundImage: this.dashboard.backgroundImage
580   - },
581   - widgets: this.widgets
582   - };
583   - const { code, data } = await insertDashboard(screenData);
584   - if (code == "200") {
585   - this.$message.success("保存成功!");
586   - }
587   - },
588   - // 预览
589   - viewScreen() {
590   - let routeUrl = this.$router.resolve({
591   - path: "/screen/preview",
592   - query: { reportCode: this.$route.query.reportCode }
593   - });
594   - window.open(routeUrl.href, "_blank");
595   - },
596   - // 撤销
597   - handleRedo() {
598   - const record = this.revoke.redo();
599   - if (!record) {
600   - return false;
601   - }
602   - this.widgets = record;
603   - },
604   - // 恢复
605   - handleUndo() {
606   - const record = this.revoke.undo();
607   - if (!record) {
608   - return false;
609   - }
610   - this.widgets = record;
611   - },
612   - // 导入 成功回调
613   - handleUpload(response, file, fileList) {
614   - //清除el-upload组件中的文件
615   - this.$refs.upload.clearFiles();
616   - //刷新大屏页面
617   - this.initEchartData();
618   - if (response.code == "200") {
619   - this.$message({
620   - message: "导入成功!",
621   - type: "success"
622   - });
623   - } else {
624   - this.$message({
625   - message: response.message,
626   - type: "error"
627   - });
628   - }
629   - },
630   - // 导入失败
631   - handleError(err) {
632   - this.$message({
633   - message: "上传失败!",
634   - type: "error"
635   - });
636   - },
637   - // 导出
638   - async exportDashboard(val) {
639   - console.log(val);
640   - const fileName = this.$route.query.reportCode + ".zip";
641   -
642   - const param = {
643   - reportCode: this.$route.query.reportCode,
644   - showDataSet: val
645   - };
646   - exportDashboard(param).then(res => {
647   - const that = this;
648   - const type = res.type;
649   - if (type == "application/json") {
650   - let reader = new FileReader();
651   - reader.readAsText(res, "utf-8");
652   - reader.onload = function() {
653   - const data = JSON.parse(reader.result);
654   - that.$message.error(data.message);
655   - };
656   - return;
657   - }
658   -
659   - const blob = new Blob([res], {
660   - type: "application/octet-stream"
661   - });
662   - if (window.navigator.msSaveOrOpenBlob) {
663   - //msSaveOrOpenBlob方法返回bool值
664   - navigator.msSaveBlob(blob, fileName); //本地保存
665   - } else {
666   - const link = document.createElement("a"); //a标签下载
667   - link.href = window.URL.createObjectURL(blob);
668   - link.download = fileName;
669   - link.click();
670   - window.URL.revokeObjectURL(link.href);
671   - }
672   - });
673   - },
674   - // 删除
675   - deletelayer() {
676   - this.widgets.splice(this.rightClickIndex, 1);
677   - },
678   - // 复制
679   - copylayer() {
680   - const obj = this.deepClone(this.widgets[this.rightClickIndex]);
681   - this.widgets.splice(this.widgets.length, 0, obj);
682   - },
683   - // 置顶
684   - istopLayer() {
685   - if (this.rightClickIndex + 1 < this.widgets.length) {
686   - const temp = this.widgets.splice(this.rightClickIndex, 1)[0];
687   - this.widgets.push(temp);
688   - }
689   - },
690   - // 置底
691   - setlowLayer() {
692   - if (this.rightClickIndex != 0) {
693   - this.widgets.unshift(this.widgets.splice(this.rightClickIndex, 1)[0]);
694   - }
695   - },
696   - // 上移一层
697   - moveupLayer() {
698   - if (this.rightClickIndex != 0) {
699   - this.widgets[this.rightClickIndex] = this.widgets.splice(
700   - this.rightClickIndex - 1,
701   - 1,
702   - this.widgets[this.rightClickIndex]
703   - )[0];
704   - } else {
705   - this.widgets.push(this.widgets.shift());
706   - }
707   - },
708   - // 下移一层
709   - movedownLayer() {
710   - if (this.rightClickIndex != this.widgets.length - 1) {
711   - this.widgets[this.rightClickIndex] = this.widgets.splice(
712   - this.rightClickIndex + 1,
713   - 1,
714   - this.widgets[this.rightClickIndex]
715   - )[0];
716   - } else {
717   - this.widgets.unshift(this.widgets.splice(this.rightClickIndex, 1)[0]);
718   - }
719   - }
720   - }
721   -};
722   -</script>
723   -<style scoped lang="scss">
724   -@import "../../assets/styles/screenDesigner.scss";
725   -</style>