Commit 4e53903bea915eafd42179a7c6875ccfed5bf498

Authored by qianbao
1 parent c5acd2c6

1、添加轮播大屏组件

2、添加边加放大缩小功能
3、分享码多个打开时候又问题修复
4、添加组件联动。各联动组件的参数配置 参数paramsKey的值具体封装时再改
package.json
... ... @@ -67,6 +67,7 @@
67 67 "file-loader": "1.1.11",
68 68 "friendly-errors-webpack-plugin": "1.7.0",
69 69 "html-webpack-plugin": "4.0.0-alpha",
  70 + "iframe-resizer": "^4.3.6",
70 71 "js-md5": "^0.7.3",
71 72 "mini-css-extract-plugin": "0.4.1",
72 73 "monaco-editor-webpack-plugin": "^4.1.1",
... ...
src/assets/styles/screen.scss 0 → 100644
  1 +.mr10 {
  2 + margin-right: 10px;
  3 +}
  4 +
  5 +.ml20 {
  6 + margin-left: 20px;
  7 +}
  8 +
  9 +.border-right {
  10 + border-right: 1px solid #273b4d;
  11 +}
  12 +
  13 +.border-left {
  14 + border-left: 1px solid #273b4d;
  15 +}
  16 +
  17 +.el-icon-arrow-down {
  18 + font-size: 10px;
  19 +}
  20 +
  21 +.is-active {
  22 + background: #31455d !important;
  23 + color: #bfcbd9 !important;
  24 +}
  25 +
  26 +.layout {
  27 + display: -webkit-box;
  28 + display: -ms-flexbox;
  29 + display: flex;
  30 + width: 100%;
  31 + height: 100%;
  32 + -webkit-box-sizing: border-box;
  33 + box-sizing: border-box;
  34 + overflow: hidden;
  35 +
  36 + .layout-left {
  37 + display: inline-block;
  38 + height: 100%;
  39 + box-sizing: border-box;
  40 + -webkit-box-sizing: border-box;
  41 + border: 0px;
  42 + background-color: #263445;
  43 +
  44 + //工具栏一个元素
  45 + .tools-item {
  46 + display: flex;
  47 + position: relative;
  48 + width: 100%;
  49 + height: 48px;
  50 + align-items: center;
  51 + -webkit-box-align: center;
  52 + padding: 0 6px;
  53 + cursor: pointer;
  54 + font-size: 12px;
  55 + margin-bottom: 1px;
  56 +
  57 + .tools-item-icon {
  58 + color: #409eff;
  59 + margin-right: 10px;
  60 + width: 53px;
  61 + height: 30px;
  62 + line-height: 30px;
  63 + text-align: center;
  64 + display: block;
  65 + border: 1px solid #3a4659;
  66 + background: #282a30;
  67 + }
  68 +
  69 + .tools-item-text {}
  70 + }
  71 + }
  72 +
  73 + .layout-left-fold {
  74 + display: -webkit-box;
  75 + display: -ms-flexbox;
  76 + display: flex;
  77 + height: 100%;
  78 +
  79 + font-size: 12px;
  80 + overflow: hidden;
  81 + background-color: #242a30;
  82 + cursor: pointer;
  83 + padding-top: 26%;
  84 +
  85 + i {
  86 + font-size: 18px;
  87 + width: 18px;
  88 + height: 23px;
  89 + margin-left: 0px;
  90 + color: #bfcbd9;
  91 + }
  92 + }
  93 +
  94 + .layout-middle {
  95 + // display: flex;
  96 + position: relative;
  97 + //width: calc(100% - 445px);
  98 + height: 100%;
  99 + background-color: rgb(36, 42, 48);
  100 + box-sizing: border-box;
  101 + -webkit-box-sizing: border-box;
  102 + border: 1px solid rgb(36, 42, 48);
  103 + align-items: center;
  104 + vertical-align: middle;
  105 + text-align: center;
  106 +
  107 + .top-button {
  108 + display: flex;
  109 + flex-direction: row;
  110 + height: 40px;
  111 + line-height: 40px;
  112 + margin-left: 9px;
  113 +
  114 + .btn {
  115 + color: #788994;
  116 + width: 55px;
  117 + text-align: center;
  118 + display: block;
  119 + cursor: pointer;
  120 +
  121 + .el-icon-arrow-down {
  122 + transform: rotate(0deg);
  123 + -ms-transform: rotate(0deg);
  124 + /* IE 9 */
  125 + -moz-transform: rotate(0deg);
  126 + /* Firefox */
  127 + -webkit-transform: rotate(0deg);
  128 + /* Safari 和 Chrome */
  129 + -o-transform: rotate(0deg);
  130 + /* Opera */
  131 + transition: all 0.4s ease-in-out;
  132 + }
  133 +
  134 + &:hover {
  135 + background: rgb(25, 29, 34);
  136 +
  137 + .el-icon-arrow-down {
  138 + transform: rotate(180deg);
  139 + -ms-transform: rotate(180deg);
  140 + /* IE 9 */
  141 + -moz-transform: rotate(180deg);
  142 + /* Firefox */
  143 + -webkit-transform: rotate(180deg);
  144 + /* Safari 和 Chrome */
  145 + -o-transform: rotate(180deg);
  146 + /* Opera */
  147 + transition: all 0.4s ease-in-out;
  148 + }
  149 + }
  150 + }
  151 +
  152 + .btn-disable {
  153 + opacity: 0.3;
  154 + cursor: no-drop;
  155 + }
  156 +
  157 + .scale-num {
  158 + color: #788994;
  159 + opacity: 1;
  160 + cursor: pointer;
  161 +
  162 + &.btn-disable {
  163 + cursor: no-drop;
  164 +
  165 + &:hover {
  166 + background: #20262c;
  167 + }
  168 + }
  169 + }
  170 + }
  171 +
  172 + .workbench-container {
  173 + position: relative;
  174 + -webkit-transform-origin: 0 0;
  175 + transform-origin: 0 0;
  176 + -webkit-box-sizing: border-box;
  177 + box-sizing: border-box;
  178 + margin: 0;
  179 + padding: 0;
  180 + overflow: auto;
  181 +
  182 + .vueRuler {
  183 + // width: 100%;
  184 + // padding: 18px 0px 0px 18px;
  185 + padding: 0;
  186 + }
  187 +
  188 + .workbench {
  189 + background-color: #1e1e1e;
  190 + position: relative;
  191 + -webkit-user-select: none;
  192 + -moz-user-select: none;
  193 + -ms-user-select: none;
  194 + user-select: none;
  195 + -webkit-transform-origin: 0 0;
  196 + transform-origin: 0 0;
  197 + margin: 0;
  198 + padding: 0;
  199 + }
  200 +
  201 + .bg-grid {
  202 + position: absolute;
  203 + top: 0;
  204 + left: 0;
  205 + width: 100%;
  206 + height: 100%;
  207 + background-size: 30px 30px, 30px 30px;
  208 + background-image: linear-gradient(hsla(0, 0%, 100%, 0.1) 1px,
  209 + transparent 0),
  210 + linear-gradient(90deg, hsla(0, 0%, 100%, 0.1) 1px, transparent 0);
  211 + // z-index: 2;
  212 + }
  213 + }
  214 +
  215 + .bottom-text {
  216 + width: 100%;
  217 + color: #a0a0a0;
  218 + font-size: 16px;
  219 + position: absolute;
  220 + bottom: 20px;
  221 + }
  222 + }
  223 +
  224 + .layout-right {
  225 + display: inline-block;
  226 + height: 100%;
  227 + }
  228 +
  229 + /deep/ .el-tabs--border-card {
  230 + border: 0;
  231 +
  232 + .el-tabs__header {
  233 + .el-tabs__nav {
  234 + .el-tabs__item {
  235 + background-color: #242f3b;
  236 + border: 0px;
  237 + }
  238 +
  239 + .el-tabs__item.is-active {
  240 + background-color: #31455d;
  241 + }
  242 + }
  243 + }
  244 +
  245 + .el-tabs__content {
  246 + background-color: #242a30;
  247 + height: calc(100vh - 39px);
  248 + overflow-x: hidden;
  249 + overflow-y: auto;
  250 +
  251 + .el-tab-pane {
  252 + color: #bfcbd9;
  253 + }
  254 +
  255 + &::-webkit-scrollbar {
  256 + width: 5px;
  257 + height: 14px;
  258 + }
  259 +
  260 + &::-webkit-scrollbar-track,
  261 + &::-webkit-scrollbar-thumb {
  262 + border-radius: 1px;
  263 + border: 0 solid transparent;
  264 + }
  265 +
  266 + &::-webkit-scrollbar-track-piece {
  267 + /*修改滚动条的背景和圆角*/
  268 + background: #29405c;
  269 + }
  270 +
  271 + &::-webkit-scrollbar-track {
  272 + box-shadow: 1px 1px 5px rgba(116, 148, 170, 0.5) inset;
  273 + }
  274 +
  275 + &::-webkit-scrollbar-thumb {
  276 + min-height: 20px;
  277 + background-clip: content-box;
  278 + box-shadow: 0 0 0 5px rgba(116, 148, 170, 0.5) inset;
  279 + }
  280 +
  281 + &::-webkit-scrollbar-corner {
  282 + background: transparent;
  283 + }
  284 +
  285 + /*修改垂直滚动条的样式*/
  286 + &::-webkit-scrollbar-thumb:vertical {
  287 + background-color: #00113a;
  288 + // -webkit-border-radius: 7px;
  289 + }
  290 +
  291 + /*修改水平滚动条的样式*/
  292 + &::-webkit-scrollbar-thumb:horizontal {
  293 + background-color: #00113a;
  294 + // -webkit-border-radius: 7px;
  295 + }
  296 + }
  297 + }
  298 +}
  299 +
  300 +ul,
  301 +li {
  302 + list-style: none;
  303 + margin: 0;
  304 + padding: 0;
  305 +}
  306 +
  307 +.nav {
  308 + width: 40px;
  309 + padding: 0;
  310 + list-style: none;
  311 + /* overflow: hidden; */
  312 +}
  313 +
  314 +.nav {
  315 + zoom: 1;
  316 +}
  317 +
  318 +.nav:before,
  319 +.nav:after {
  320 + content: "";
  321 + display: table;
  322 +}
  323 +
  324 +.nav:after {
  325 + clear: both;
  326 +}
  327 +
  328 +.nav>li {
  329 + width: 55px;
  330 + text-align: left;
  331 + position: relative;
  332 +}
  333 +
  334 +.nav>li a {
  335 + float: left;
  336 + padding: 12px 30px;
  337 + color: #999;
  338 + font: bold 12px;
  339 + text-decoration: none;
  340 +}
  341 +
  342 +.nav>li:hover {
  343 + color: #788994;
  344 +}
  345 +
  346 +.nav>li ul {
  347 + visibility: hidden;
  348 + position: absolute;
  349 + z-index: 1000;
  350 + list-style: none;
  351 + left: 0;
  352 + padding: 0;
  353 + background-color: rgb(36, 42, 48);
  354 + opacity: 0;
  355 + _margin: 0;
  356 + width: 120px;
  357 + transition: all 0.2s ease-in-out;
  358 +}
  359 +
  360 +.nav>li:hover>ul {
  361 + opacity: 1;
  362 + visibility: visible;
  363 + margin: 0;
  364 +
  365 + li:hover {
  366 + background-color: rgb(25, 29, 34);
  367 + }
  368 +}
  369 +
  370 +.nav ul li {
  371 + float: left;
  372 + display: block;
  373 + border: 0;
  374 + width: 100%;
  375 + font-size: 12px;
  376 +}
  377 +
  378 +.nav ul a {
  379 + padding: 10px;
  380 + width: 100%;
  381 + display: block;
  382 + float: none;
  383 + height: 120px;
  384 + border: 1px solid #30445c;
  385 + background-color: rgb(25, 29, 34);
  386 + transition: all 0.2s ease-in-out;
  387 +}
  388 +
  389 +.nav ul a:hover {
  390 + border: 1px solid #3c5e88;
  391 +}
  392 +
  393 +.nav ul li:first-child>a:hover:before {
  394 + border-bottom-color: #04acec;
  395 +}
  396 +
  397 +.nav ul ul {
  398 + top: 0;
  399 + left: 120px;
  400 + width: 400px;
  401 + height: 300px;
  402 + overflow: auto;
  403 + padding: 10px;
  404 + _margin: 0;
  405 +}
  406 +
  407 +.nav ul ul li {
  408 + width: 120px;
  409 + height: 120px;
  410 + margin-right: 3px;
  411 + display: block;
  412 + float: left;
  413 +}
  414 +
  415 +.nav .item {
  416 + padding: 5px;
  417 +}
  418 +
  419 +/deep/ .vue-ruler-h {
  420 + opacity: 0.3;
  421 +}
  422 +
  423 +/deep/ .vue-ruler-v {
  424 + opacity: 0.3;
  425 +}
  426 +
  427 +.layout-left {
  428 + width: 200px;
  429 + background: #242a30;
  430 + overflow-x: hidden;
  431 + overflow-y: auto;
  432 +
  433 + .chart-type {
  434 + display: flex;
  435 + flex-direction: row;
  436 + overflow: hidden;
  437 +
  438 + .type-left {
  439 + width: 100%;
  440 + height: calc(100vh - 80px);
  441 + text-align: center;
  442 +
  443 + /deep/.el-tabs__header {
  444 + width: 30%;
  445 + margin-right: 0;
  446 +
  447 + .el-tabs__nav-wrap {
  448 + &::after {
  449 + background: transparent;
  450 + }
  451 +
  452 + .el-tabs__item {
  453 + text-align: center;
  454 + width: 100% !important;
  455 + color: #fff;
  456 + padding: 0;
  457 + font-size: 12px !important;
  458 + }
  459 + }
  460 + }
  461 +
  462 + /deep/.el-tabs__content {
  463 + width: 70%;
  464 + }
  465 + }
  466 + }
  467 +
  468 + //工具栏一个元素
  469 + .tools-item {
  470 + display: flex;
  471 + position: relative;
  472 + width: 100%;
  473 + height: 48px;
  474 + align-items: center;
  475 + -webkit-box-align: center;
  476 + padding: 0 6px;
  477 + cursor: pointer;
  478 + font-size: 12px;
  479 + margin-bottom: 1px;
  480 +
  481 + .tools-item-icon {
  482 + color: #409eff;
  483 + margin-right: 10px;
  484 + width: 53px;
  485 + height: 30px;
  486 + line-height: 30px;
  487 + text-align: center;
  488 + display: block;
  489 + border: 1px solid #3a4659;
  490 + background: #282a30;
  491 + }
  492 +
  493 + .tools-item-text {
  494 + font-size: 12px !important;
  495 + }
  496 + }
  497 +
  498 + /deep/.el-tabs__content {
  499 + padding: 0;
  500 + }
  501 +}
  502 +
  503 +/* 设置滚动条的样式 */
  504 +
  505 +::-webkit-scrollbar {
  506 + width: 0;
  507 + height: 10px;
  508 +}
0 509 \ No newline at end of file
... ...
src/mixins/common.js
... ... @@ -308,6 +308,9 @@ export default {
308 308 }
309 309 return tmpData
310 310 },
  311 + isObjectFn(value) {
  312 + return Object.prototype.toString.call(value) === "[object Object]";
  313 + },
311 314 isArrayFn(value) {
312 315 if (typeof Array.isArray === "function") {
313 316 return Array.isArray(value);
... ...
src/mixins/queryform.js
... ... @@ -59,6 +59,7 @@ export default {
59 59 },
60 60 computed: {},
61 61 created() {
  62 +
62 63 },
63 64 mounted() {
64 65 },
... ... @@ -96,7 +97,7 @@ export default {
96 97 // 查询echarts 数据
97 98 queryEchartsData(params) {
98 99 return new Promise(async (resolve) => {
99   - const {code, data} = await getData(params);
  100 + const { code, data } = await getData(params);
100 101 if (code != 200) return
101 102 const analysisData = this.analysisChartsData(params, data);
102 103 resolve(analysisData)
... ... @@ -112,6 +113,7 @@ export default {
112 113 // widget-heatmap 热力图
113 114 // widget-mapline 中国地图-路线图
114 115 // widget-radar 雷达图
  116 + // widget-select 下拉框
115 117 const chartType = params.chartType
116 118 if (chartType == "widget-linechart" ||
117 119 chartType == "widget-barlinechart"
... ... @@ -134,6 +136,8 @@ export default {
134 136 return this.linemapChartFn(params.chartProperties, data)
135 137 } else if (chartType == "widget-radar") {
136 138 return this.radarChartFn(params.chartProperties, data)
  139 + } else if (chartType == "widget-select") {
  140 + return this.selectChartFn(params.chartProperties, data)
137 141 } else {
138 142 return data
139 143 }
... ... @@ -327,6 +331,7 @@ export default {
327 331 }
328 332 return ananysicData;
329 333 },
  334 + // 雷达图
330 335 radarChartFn(chartProperties, data) {
331 336 const ananysicData = {};
332 337 // 字段名
... ... @@ -346,6 +351,33 @@ export default {
346 351 ananysicData["value"] = data;
347 352 return ananysicData;
348 353 },
  354 + // 下拉框
  355 + selectChartFn(chartProperties, data){
  356 + let valueField;
  357 + let labelField;
  358 + for (const key in chartProperties) {
  359 + if (chartProperties[key] == "value") {
  360 + valueField = key;
  361 + }
  362 + if (chartProperties[key] == "label") {
  363 + labelField = key;
  364 + }
  365 + }
  366 + if (valueField == null && labelField != null) {
  367 + valueField = labelField;
  368 + }
  369 + if (labelField == null && valueField != null) {
  370 + labelField = valueField
  371 + }
  372 + const analysisData = [];
  373 + for (let i = 0; i < data.length; i++) {
  374 + const obj = {};
  375 + obj["value"] = data[i][valueField];
  376 + obj["label"] = data[i][labelField];
  377 + analysisData.push(obj);
  378 + }
  379 + return analysisData;
  380 + },
349 381 setUnique(arr) {
350 382 let newArr = [];
351 383 arr.forEach(item => {
... ...
src/utils/auth.js
... ... @@ -11,9 +11,13 @@ export function getShareToken() {
11 11 return getStorageItem(ShareTokenKey) == null ? '' : getStorageItem(ShareTokenKey);
12 12 }
13 13 export function setToken(token) {
14   - return setStorageItem(TokenKey, token)
  14 + return setStorageItem(TokenKey, token);
15 15 }
16 16 export function setShareToken(shareToken) {
  17 + const originalShareToken = getShareToken();
  18 + if ((originalShareToken != null || originalShareToken != '') && originalShareToken.indexOf(shareToken) == -1) {
  19 + shareToken = originalShareToken + ',' + shareToken
  20 + }
17 21 return setStorageItem(ShareTokenKey, shareToken)
18 22 }
19 23 export function delToken() {
... ...
src/utils/eventBus.js 0 → 100644
  1 +import Vue from 'vue'
  2 +
  3 +const eventBus = new Vue()
  4 +
  5 +export { eventBus }
0 6 \ No newline at end of file
... ...
src/utils/screen.js 0 → 100644
  1 +import { eventBus } from "@/utils/eventBus";
  2 +
  3 +export function setAssChartData(widgets, options) {
  4 + const selectOptions = options.filter(item => item.uuid).map(item => {
  5 + return {
  6 + code: item.uuid,
  7 + name: item.label
  8 + }
  9 + })
  10 + widgets.forEach(item => {
  11 + const setup = item['options']['setup']
  12 + console.log(setup)
  13 + setup.forEach(sItem => {
  14 + if (sItem.name == 'assChart') {
  15 + sItem['selectOptions'] = selectOptions
  16 + }
  17 + })
  18 + })
  19 +}
  20 +
  21 +export function eventBusParams(optionsSetup, optionsData, callback) {
  22 + eventBus.$on("eventParams", (formParams) => {
  23 + const uuid = optionsSetup.uuid;
  24 + if (formParams.assChart.includes(uuid)) {
  25 + const contextData = optionsData.dynamicData.contextData;
  26 + for (const key in contextData) {
  27 + if (formParams.hasOwnProperty(key)) {
  28 + contextData[key] = formParams[key];
  29 + }
  30 + }
  31 + callback(optionsData.dynamicData, optionsSetup)
  32 + }
  33 + });
  34 +}
... ...
src/views/bigscreenDesigner/designer/components/dynamicComponents.vue
... ... @@ -120,9 +120,11 @@ export default {
120 120 },
121 121 async selectDataSet() {
122 122 const { code, data } = await detailBysetId(this.dataSetValue);
  123 + if(data){
  124 + this.userNameList =data.dataSetParamDtoList?data.dataSetParamDtoList:this.userNameList;
  125 + this.setParamList =data.setParamList?data.setParamList:[];
  126 + }
123 127 // this.userNameList = this.isNotBlankArray(this.userNameList)?this.userNameList:data.dataSetParamDtoList;
124   - this.userNameList = data.dataSetParamDtoList;
125   - this.setParamList = data.setParamList;
126 128 if (code != "200") return;
127 129 },
128 130 async saveDataBtn() {
... ... @@ -138,6 +140,7 @@ export default {
138 140 contextData,
139 141 // userNameList:this.userNameList 去除userNameList对象,这样可以减少前台内存
140 142 };
  143 + // console.log("刷新",params)
141 144 this.$emit("input", params);
142 145 this.$emit("change", params);
143 146 },
... ... @@ -152,13 +155,13 @@ export default {
152 155 async echoDataSet(val) {
153 156 if (!val) return;
154 157 const setCode = val.setCode;
155   -
156 158 await this.loadDataSet();
157   -
158   - this.dataSetValue = this.dataSet.filter(
  159 + const dataSet = this.dataSet.
  160 + filter(
159 161 el => setCode == el.setCode
160   - )[0].id;
161   -
  162 + )[0];
  163 + if (!dataSet) return;
  164 + this.dataSetValue = dataSet.id;
162 165 await this.selectDataSet();
163 166 this.echoDynamicData(val);
164 167 },
... ... @@ -178,7 +181,7 @@ export default {
178 181 }
179 182 this.userNameList = sUserDataSet;
180 183 }
181   - if (this.setParamList.length > 0) {
  184 + if (this.setParamList && this.setParamList.length > 0) {
182 185 for (let i = 0; i < this.setParamList.length; i++) {
183 186 const item = this.setParamList[i];
184 187 if (chartProperties.hasOwnProperty(item)) {
... ...
src/views/bigscreenDesigner/designer/index.vue
... ... @@ -64,8 +64,9 @@
64 64 </div>
65 65 <!-- 是否显示左侧组件栏-->
66 66 <div class="layout-left-fold"
67   - :style="{ width: widthLeftForToolsHideButton + 'px' }"
68   - @click="toolIsShow = !toolIsShow">
  67 + :style="{ width: widthLeftForToolsHideButton + 'px' }"
  68 + @click="toolIsShow = !toolIsShow"
  69 + >
69 70 <i :class="[toolIsShow?' el-icon-arrow-left':'el-icon-arrow-right']"/>
70 71 </div>
71 72 <!-- 上面操作导入、导出-->
... ... @@ -74,46 +75,99 @@
74 75 :style="{ width: middleWidth + 'px', height: middleHeight + 'px' }"
75 76 >
76 77 <div class="top-button">
77   - <span class="btn">
  78 + <span class="btn" @click="saveData">
78 79 <el-tooltip
79 80 class="item"
80 81 effect="dark"
81 82 content="保存"
82 83 placement="bottom"
83 84 >
84   - <i class="iconfont iconsave" @click="saveData"></i>
  85 + <i class="iconfont iconsave"></i>
85 86 </el-tooltip>
86 87 </span>
87   - <span class="btn">
  88 + <span class="btn" @click="viewScreen">
88 89 <el-tooltip
89 90 class="item"
90 91 effect="dark"
91 92 content="预览"
92 93 placement="bottom"
93 94 >
94   - <i class="iconfont iconyulan" @click="viewScreen"></i>
  95 + <i class="iconfont iconyulan"></i>
95 96 </el-tooltip>
96 97 </span>
97 98  
98   - <span class="btn">
  99 + <span class="btn" @click="handleUndo">
99 100 <el-tooltip
100 101 class="item"
101 102 effect="dark"
102 103 content="撤销"
103 104 placement="bottom"
104 105 >
105   - <i class="iconfont iconundo" @click="handleUndo"></i>
  106 + <i class="iconfont iconundo"></i>
106 107 </el-tooltip>
107 108 </span>
108 109  
109   - <span class="btn">
  110 + <span class="btn" @click="handleRedo">
110 111 <el-tooltip
111 112 class="item"
112 113 effect="dark"
113 114 content="恢复"
114 115 placement="bottom"
115 116 >
116   - <i class="iconfont iconhuifubeifen" @click="handleRedo"></i>
  117 + <i class="iconfont iconhuifubeifen"></i>
  118 + </el-tooltip>
  119 + </span>
  120 +
  121 + <span
  122 + :class="{
  123 + btn: true,
  124 + 'btn-disable': currentSizeRangeIndex === 0,
  125 + }"
  126 + @click="setSize(0)"
  127 + >
  128 + <el-tooltip
  129 + class="item"
  130 + :disabled="currentSizeRangeIndex === 0"
  131 + effect="dark"
  132 + content="缩小"
  133 + placement="bottom"
  134 + >
  135 + <i class="el-icon-minus" style="font-size: 16px" />
  136 + </el-tooltip>
  137 + </span>
  138 + <span
  139 + :class="{
  140 + btn: true,
  141 + 'scale-num': true,
  142 + 'btn-disable': currentSizeRangeIndex === defaultSize.index,
  143 + }"
  144 + @click="setSize(2)"
  145 + >
  146 + <el-tooltip
  147 + class="item"
  148 + :disabled="currentSizeRangeIndex === defaultSize.index"
  149 + effect="dark"
  150 + content="默认比例"
  151 + placement="bottom"
  152 + >
  153 + <span> {{ parseInt(scaleNum) }}% </span>
  154 + </el-tooltip>
  155 + </span>
  156 + <span
  157 + :class="{
  158 + btn: true,
  159 + 'btn-disable': currentSizeRangeIndex === 8,
  160 + }"
  161 + @click="setSize(1)"
  162 + >
  163 + <el-tooltip
  164 + class="item"
  165 + :disabled="currentSizeRangeIndex === 8"
  166 + effect="dark"
  167 + content="放大"
  168 + placement="bottom"
  169 + >
  170 + <i class="el-icon-plus" style="font-size: 16px" />
117 171 </el-tooltip>
118 172 </span>
119 173  
... ... @@ -149,127 +203,96 @@
149 203 placement="right"
150 204 >
151 205 </el-tooltip>
152   -<!-- <ul class="nav">-->
153   -<!-- <li>-->
154   -<!-- <i class="iconfont icondaochu"></i-->
155   -<!-- ><i class="el-icon-arrow-down"></i>-->
156   -<!-- <ul>-->
157   -<!-- <li>-->
158   -<!-- <el-tooltip-->
159   -<!-- class="item"-->
160   -<!-- effect="dark"-->
161   -<!-- content="适合当前系统"-->
162   -<!-- placement="right"-->
163   -<!-- >-->
164   -<!-- <div @click="exportDashboard(1)">导出(包含数据集)</div>-->
165   -<!-- </el-tooltip>-->
166   -<!-- </li>-->
167   -<!-- <li>-->
168   -<!-- <el-tooltip-->
169   -<!-- class="item"-->
170   -<!-- effect="dark"-->
171   -<!-- content="适合跨系统"-->
172   -<!-- placement="right"-->
173   -<!-- >-->
174   -<!-- <div @click="exportDashboard(0)">导出(不包含数据集)</div>-->
175   -<!-- </el-tooltip>-->
176   -<!-- </li>-->
177   -<!-- </ul>-->
178   -<!-- </li>-->
179   -<!-- </ul>-->
180 206 </span>
181 207 </div>
182 208 <!-- 中间设计-->
183   - <div
184   - class="workbench-container"
185   - :style="{
186   - width: bigscreenWidthInWorkbench + 'px',
187   - height: bigscreenHeightInWorkbench + 'px',
188   - }"
189   - @mousedown="handleMouseDown"
190   - >
191   - <vue-ruler-tool
192   - v-model="dashboard.presetLine"
193   - class="vueRuler"
194   - :step-length="50"
195   - :parent="true"
196   - :position="'relative'"
197   - :is-scale-revise="true"
198   - :visible.sync="dashboard.presetLineVisible"
  209 + <div class="workbench-container" @mousedown="handleMouseDown">
  210 + <div
199 211 :style="{
200   - //如果想尺子不变化,单独定义遍历等于工作区域
201   - // width: bigscreenWidthRuler + 'px',
202   - // height: bigscreenHeightRuler + 'px',
203   - width: bigscreenWidthInWorkbench + 'px',
204   - //高度尺子不变换,想变化放出来
205   - height: bigscreenHeightInWorkbench + 'px',
  212 + width: (+bigscreenWidth + 18) * bigscreenScaleInWorkbench + 'px',
  213 + height: (+bigscreenHeight + 18) * bigscreenScaleInWorkbench + 'px',
206 214 }"
  215 + class="vue-ruler-tool-wrap"
207 216 >
208   - <div
209   - id="workbench"
210   - class="workbench"
  217 + <!-- 大屏设计页面的标尺插件 -->
  218 + <vue-ruler-tool
  219 + ref="vue-ruler-tool"
  220 + v-model="dashboard.presetLine"
  221 + class="vueRuler"
  222 + :step-length="50"
  223 + :parent="true"
  224 + :position="'relative'"
  225 + :is-scale-revise="true"
  226 + :visible.sync="dashboard.presetLineVisible"
211 227 :style="{
212   - transform: workbenchTransform,
213   - width: bigscreenWidth + 'px',
214   - height: bigscreenHeight + 'px',
215   - 'background-color': dashboard.backgroundColor,
216   - 'background-image': 'url(' + dashboard.backgroundImage + ')',
217   - 'background-position': '0% 0%',
218   - 'background-size': '100% 100%',
219   - 'background-repeat': 'initial',
220   - 'background-attachment': 'initial',
221   - 'background-origin': 'initial',
222   - 'background-clip': 'initial',
  228 + width: +bigscreenWidth + 18 + 'px',
  229 + height: +bigscreenHeight + 18 + 'px',
  230 + transform:
  231 + currentSizeRangeIndex === defaultSize.index
  232 + ? workbenchTransform
  233 + : `scale(${sizeRange[currentSizeRangeIndex] / 100})`,
  234 + transformOrigin: '0 0',
223 235 }"
224   - @click.self="setOptionsOnClickScreen"
225   - @drop="widgetOnDragged($event)"
226   - @dragover="dragOver($event)"
227 236 >
228   - <div v-if="grade" class="bg-grid"></div>
229   - <widget
230   - ref="widgets"
231   - v-for="(widget, index) in widgets"
232   - :key="index"
233   - v-model="widget.value"
234   - :index="index"
235   - :step="step"
236   - :type="widget.type"
237   - :bigscreen="{ bigscreenWidth, bigscreenHeight }"
238   - @onActivated="setOptionsOnClickWidget"
239   - @contextmenu.prevent.native="rightClick($event, index)"
240   - @mousedown.prevent.native="widgetsClick(index)"
241   - @mouseup.prevent.native="widgetsMouseup"
242   - @keyup.delete.native="entryDelete(index)"
243   - />
244   - </div>
245   - </vue-ruler-tool>
  237 + <div
  238 + id="workbench"
  239 + class="workbench"
  240 + :style="{
  241 + width: bigscreenWidth + 'px',
  242 + height: bigscreenHeight + 'px',
  243 + 'background-color': dashboard.backgroundColor,
  244 + 'background-image': 'url(' + dashboard.backgroundImage + ')',
  245 + 'background-position': '0% 0%',
  246 + 'background-size': '100% 100%',
  247 + 'background-repeat': 'initial',
  248 + 'background-attachment': 'initial',
  249 + 'background-origin': 'initial',
  250 + 'background-clip': 'initial',
  251 + }"
  252 + @click.self="setOptionsOnClickScreen"
  253 + @drop="widgetOnDragged($event)"
  254 + @dragover="dragOver($event)"
  255 + >
  256 + <div v-if="grade" class="bg-grid"></div>
  257 + <widget
  258 + ref="widgets"
  259 + v-for="(widget, index) in widgets"
  260 + :key="index"
  261 + v-model="widget.value"
  262 + :index="index"
  263 + :step="step"
  264 + :type="widget.type"
  265 + :bigscreen="{ bigscreenWidth, bigscreenHeight }"
  266 + @onActivated="setOptionsOnClickWidget"
  267 + @contextmenu.prevent.native="rightClick($event, index)"
  268 + @mousedown.prevent.native="widgetsClick(index)"
  269 + @mouseup.prevent.native="widgetsMouseup"
  270 + @keyup.delete.native="entryDelete(index)"
  271 + />
  272 + </div>
  273 + </vue-ruler-tool>
  274 + </div>
246 275 </div>
247 276 </div>
248   - <!-- 右侧是否显示-->
249   - <div
250   - class="layout-left-fold"
251   - :style="{ width: widthRightForToolsHideButton + 'px' }"
252   - @click="setupIsShow = !setupIsShow">
253   - <i :class="[setupIsShow?' el-icon-arrow-right':'el-icon-arrow-left']"/>
254   - </div>
255 277 <!-- 右侧配置-->
256   - <div class="layout-right" :style="{ width: widthLeftForOptions + 'px' }" v-if="setupIsShow">
  278 + <div class="layout-right" :style="{ width: widthLeftForOptions + 'px' }">
257 279 <el-tabs v-model="activeName" type="border-card" :stretch="true">
258 280 <el-tab-pane
259   - v-if="
260   - this.isNotNull(widgetOptions.setup) || this.isNotNull(widgetOptions.collapse)
261   - "
  281 + v-if="this.isNotNull(widgetOptions.setup) || this.isNotNull(widgetOptions.collapse)"
262 282 name="first"
263 283 label="配置"
264 284 >
265 285 <dynamicForm
266 286 ref="formData"
267 287 :options="widgetOptions.setup"
  288 + :layer-widget="layerWidget"
  289 + :widget-index="widgetIndex"
  290 + :widget-params-config="widgetParamsConfig"
268 291 @onChanged="(val) => widgetValueChanged('setup', val)"
269 292 />
270 293 </el-tab-pane>
271 294 <el-tab-pane
272   - v-if="this.isNotNull(widgetOptions.data)"
  295 + v-if="isNotNull(widgetOptions.data)"
273 296 name="second"
274 297 label="数据"
275 298 >
... ... @@ -280,7 +303,7 @@
280 303 />
281 304 </el-tab-pane>
282 305 <el-tab-pane
283   - v-if="this.isNotNull(widgetOptions.position)"
  306 + v-if="isNotNull(widgetOptions.position)"
284 307 name="third"
285 308 label="坐标"
286 309 >
... ... @@ -297,6 +320,8 @@
297 320 :visible.sync="visibleContentMenu"
298 321 :style-obj="styleObj"
299 322 @deletelayer="deletelayer"
  323 + @lockLayer="lockLayer"
  324 + @noLockLayer="noLockLayer"
300 325 @copylayer="copylayer"
301 326 @istopLayer="istopLayer"
302 327 @setlowLayer="setlowLayer"
... ... @@ -318,12 +343,10 @@ import dynamicForm from &quot;./components/dynamicForm.vue&quot;;
318 343 import draggable from "vuedraggable";
319 344 import VueRulerTool from "vue-ruler-tool"; // 大屏设计页面的标尺插件
320 345 import contentMenu from "./components/contentMenu";
321   -import { getToken } from "@/utils/auth";
322 346 import { Revoke } from "@/utils/revoke";
  347 +import { getToken } from "@/utils/auth";
323 348 import { mapMutations } from 'vuex';
324   -import process from "process";
325 349 import { debounce } from '@/utils/debounce'; // 引入防抖函数
326   -
327 350 import loadingViewerVue from 'loading-view-vue'
328 351 import Vue from "vue";
329 352 Vue.use(loadingViewerVue,{mode:"5"});
... ... @@ -344,13 +367,13 @@ export default {
344 367 widgetTools: widgetTools, // 左侧工具栏的组件图标,将js变量加入到当前作用域
345 368 widthLeftForTools: 200, // 左侧工具栏宽度
346 369 widthLeftForToolsHideButton: 15, // 左侧工具栏折叠按钮宽度
347   - widthRightForToolsHideButton: 15, // 右侧工具栏折叠按钮宽度
348 370 widthLeftForOptions: 300, // 右侧属性配置区
349   - widthPaddingTools: 18,//vueRuler
  371 + widthPaddingTools: 18,
350 372 toolIsShow: true, // 左侧工具栏是否显示
351   - setupIsShow: true, // 右侧配置是否显示
352 373 bigscreenWidth: 1920, // 大屏设计的大小
353 374 bigscreenHeight: 1080,
  375 + widthRightForToolsHideButton: 15, // 右侧工具栏折叠按钮宽度
  376 + setupIsShow: true, // 右侧配置是否显示
354 377 revoke: null,
355 378  
356 379 // 工作台大屏画布,保存到表gaea_report_dashboard中
... ... @@ -371,25 +394,7 @@ export default {
371 394 screenCode: "",
372 395 dragWidgetCode: "", //从工具栏拖拽的组件code
373 396 // 大屏画布中的组件
374   - widgets: [
375   - {
376   - // type和value最终存到数据库中去,保存到gaea_report_dashboard_widget中
377   - type: "widget-text",
378   - value: {
379   - setup: {},
380   - data: {},
381   - position: {
382   - width: 100,
383   - height: 100,
384   - left: 0,
385   - top: 0,
386   - zIndex: 0,
387   - },
388   - },
389   - // options属性是从工具栏中拿到的tools中拿到
390   - options: [],
391   - },
392   - ], // 工作区中拖放的组件
  397 + widgets: [], // 工作区中拖放的组件
393 398 // 当前激活组件
394 399 widgetIndex: 0,
395 400 // 当前激活组件右侧配置属性
... ... @@ -408,6 +413,11 @@ export default {
408 413 activeName: "first",
409 414 selectMore:[],//按住shift多选的图层
410 415 shiftEnt:false,//shift键盘是否按住
  416 + scaleNum: 0, // 当前缩放百分比的值
  417 + sizeRange: [20, 40, 60, 80, 100, 150, 200, 300, 400], // 缩放百分比
  418 + currentSizeRangeIndex: -1, // 当前是哪个缩放比分比,
  419 + currentWidgetTotal: 0,
  420 + widgetParamsConfig: [], // 各组件动态数据集的参数配置情况
411 421 };
412 422 },
413 423 computed: {
... ... @@ -421,10 +431,15 @@ export default {
421 431 },
422 432 // 左侧、右侧折叠切换时,动态计算中间区的宽度
423 433 middleWidth() {
424   - if(!this.setupIsShow && !this.toolIsShow){
425   - return document.documentElement.clientWidth - this.widthPaddingTools;
  434 + let widthLeftAndRight = 0;
  435 + if (this.toolIsShow) {
  436 + widthLeftAndRight += this.widthLeftForTools; // 左侧工具栏宽度
426 437 }
427   - return this.bodyWidth - this.widthLeftAndRight();
  438 + widthLeftAndRight += this.widthLeftForToolsHideButton; // 左侧工具栏折叠按钮宽度
  439 + widthLeftAndRight += this.widthLeftForOptions; // 右侧配置栏宽度
  440 +
  441 + let middleWidth = this.bodyWidth - widthLeftAndRight;
  442 + return middleWidth;
428 443 },
429 444 middleHeight() {
430 445 return this.bodyHeight;
... ... @@ -449,18 +464,41 @@ export default {
449 464 this.getPXUnderScale(this.bigscreenHeight) + this.widthPaddingTools
450 465 );
451 466 },
452   - // 尺子的宽度高度
453   - // bigscreenWidthRuler() {
454   - // return this.middleWidth;
455   - // },
456   - // bigscreenHeightRuler() {
457   - // return this.middleHeight;
458   - // },
  467 + // 初始的缩放百分比 和 下标
  468 + defaultSize() {
  469 + const obj = {
  470 + index: -1,
  471 + size: "50",
  472 + };
  473 + this.sizeRange.some((item, index) => {
  474 + console.log(item,index);
  475 + if (item <= 100 * this.bigscreenScaleInWorkbench) {
  476 + obj.index = index;
  477 + obj.size = 100 * this.bigscreenScaleInWorkbench;
  478 + }
  479 + });
  480 + if (obj.index === -1) {
  481 + obj.index = 0;
  482 + obj.size = this.sizeRange[0];
  483 + }
  484 + return obj;
  485 + },
459 486 },
460 487 watch: {
  488 + defaultSize: {
  489 + handler(val) {
  490 + if (val !== -1 && this.isObjectFn(val)) {
  491 + this.currentSizeRangeIndex = val.index;
  492 + this.scaleNum = val.size;
  493 + }
  494 + },
  495 + immediate: true,
  496 + },
461 497 widgets: {
462 498 handler(val) {
463 499 this.handlerLayerWidget(val);
  500 + // this.handlerdynamicDataParamsConfig(val);
  501 + // console.log("刷新")
464 502 //以下部分是记录历史
465 503 this.$nextTick(() => {
466 504 this.revoke.push(this.widgets);
... ... @@ -468,6 +506,12 @@ export default {
468 506 },
469 507 deep: true,
470 508 },
  509 + bigscreenWidth() {
  510 + this.initVueRulerTool();
  511 + },
  512 + bigscreenHeight() {
  513 + this.initVueRulerTool();
  514 + },
471 515 },
472 516 created() {
473 517 /* 以下是记录历史的 */
... ... @@ -475,14 +519,16 @@ export default {
475 519 },
476 520 mounted() {
477 521 // 如果是新的设计工作台
478   - this.initEchartData();
479 522 this.widgets = [];
480 523 window.addEventListener("mouseup", () => {
481 524 this.grade = false;
482 525 });
  526 + this.$nextTick(() => {
  527 + this.initVueRulerTool(); // 初始化 修正插件样式
  528 + });
  529 + this.initEchartData();
483 530 window.addEventListener('keydown', code => this.handleKeyDown(code)); // 监听键盘按下事件
484 531 window.addEventListener('keyup', code => this.handleKeyUp(code)); // 监听键盘松开事件
485   -
486 532 },
487 533 // 在beforeDestroy中
488 534 beforeDestroy() {
... ... @@ -493,6 +539,71 @@ export default {
493 539 methods: {
494 540 ...mapMutations('dataSource', ['SET_STATIC_DATA']),
495 541 /**
  542 + * @param num: 0缩小 1放大 2默认比例
  543 + * sizeRange: [20, 40, 60, 72, 100, 150, 200, 300, 400]
  544 + */
  545 + setSize(num) {
  546 + switch (num) {
  547 + case 0: this.currentSizeRangeIndex === 0 ? '' : this.currentSizeRangeIndex -= 1;
  548 + break;
  549 + case 1: this.currentSizeRangeIndex === 8 ? '' : this.currentSizeRangeIndex += 1;
  550 + break;
  551 + case 2: this.currentSizeRangeIndex = this.defaultSize.index;
  552 + }
  553 + // console.log(this.currentSizeRangeIndex,this.defaultSize.index,this.defaultSize.size,this.sizeRange[this.currentSizeRangeIndex])
  554 + this.scaleNum = this.currentSizeRangeIndex === this.defaultSize.index ? this.defaultSize.size : this.sizeRange[this.currentSizeRangeIndex];
  555 + },
  556 + // 初始化 修正插件样式
  557 + initVueRulerTool() {
  558 + const vueRulerToolDom = this.$refs["vue-ruler-tool"].$el; // 操作面板 第三方插件工具
  559 + const contentDom = vueRulerToolDom.querySelector(".vue-ruler-content");
  560 + const vueRulerX = vueRulerToolDom.querySelector(".vue-ruler-h"); // 横向标尺
  561 + const vueRulerY = vueRulerToolDom.querySelector(".vue-ruler-v"); // 纵向标尺
  562 + contentDom.style.width = "100%";
  563 + contentDom.style.height = "100%";
  564 +
  565 + let xHtmlContent = "";
  566 + let yHtmlContent = "";
  567 + let currentNum = 0;
  568 + while (currentNum < +this.bigscreenWidth) {
  569 + xHtmlContent += `<span class="n" style="left: ${currentNum + 2}px;">${currentNum}</span>`;
  570 + currentNum += 50;
  571 + }
  572 + currentNum = 0;
  573 + while (currentNum < +this.bigscreenHeight) {
  574 + yHtmlContent += `<span class="n" style="top: ${currentNum + 2}px;">${currentNum}</span>`;
  575 + currentNum += 50;
  576 + }
  577 + vueRulerX.innerHTML = xHtmlContent;
  578 + vueRulerY.innerHTML = yHtmlContent;
  579 + },
  580 + // 重写默认数据
  581 + setDefaultWidgetConfigValue(data, option) {
  582 + this.setConfigValue(data.setup, option.setup)
  583 + this.setConfigValue(data.position, option.position)
  584 + this.setConfigValue(data.data, option.data)
  585 + return option;
  586 + },
  587 + setConfigValue(objValue, setup) {
  588 + Object.keys(objValue).forEach(key => {
  589 + setup.forEach(item => {
  590 + if (this.isObjectFn(item) && key == item.name) {
  591 + item.value = objValue[key]
  592 + }
  593 + if (this.isArrayFn(item)) {
  594 + item.forEach(itemChild => {
  595 + itemChild.list.forEach(el => {
  596 + if (key == el.name) {
  597 + el.value = objValue[key]
  598 + }
  599 + })
  600 + })
  601 + }
  602 + })
  603 + })
  604 + },
  605 +
  606 + /**
496 607 * @description: 恢复
497 608 * @param {*}
498 609 * @return {*}
... ... @@ -515,8 +626,8 @@ export default {
515 626 code.keyCode === 39 ||
516 627 code.keyCode === 40
517 628 ) {
518   - //上下左右移动
519   - this.dragWidgetMoveByKey(code,this.widgetIndex);
  629 + //上下左右移动
  630 + this.dragWidgetMoveByKey(code,this.widgetIndex);
520 631 }
521 632 }, 10, true),
522 633 handleKeyUp: debounce(function(code) {
... ... @@ -573,6 +684,12 @@ export default {
573 684 this.setWidgetOptionsData(screenData.data);
574 685 }
575 686 },
  687 + // 返回每个组件的动态数据集参数配置情况
  688 + handlerdynamicDataParamsConfig(val) {
  689 + this.widgetParamsConfig = val.map((item) => {
  690 + return item.value.data;
  691 + });
  692 + },
576 693 // 数据处理
577 694 setMasterData(screenData){
578 695 // 数据类型 静态 or 动态
... ... @@ -605,17 +722,23 @@ export default {
605 722 });
606 723 },
607 724 renderingFn(val) {
  725 + let masterDataVal={};
608 726 if(this.isNotBlankArray(val)){
609 727 for (let i = 0; i < val.length; i++) {
610 728 const one = val[i];
611 729 const sValue = (this.isBlankObject(one)|| this.isBlank(one['sValue']))?"":one['sValue'];
612 730 if(this.isNotBlankObj(one) && this.isNotBlank(one['sName'])){
613 731 const sName = one['sName'];
614   - this.masterData[sName]=sValue;
  732 + masterDataVal[sName]=sValue;
615 733 }
616 734 }
  735 + }else{
  736 + masterDataVal={};
617 737 }
618   - this.SET_STATIC_DATA(this.masterData);
  738 + this.masterData = masterDataVal;
  739 + // console.log("masterData",masterDataVal);
  740 + this.SET_STATIC_DATA(masterDataVal);
  741 + // this.$forceUpdate();
619 742 },
620 743  
621 744 handleBigScreen(data) {
... ... @@ -630,7 +753,7 @@ export default {
630 753 }
631 754 this.setOptionsOnClickScreen();
632 755 return {
633   - backgroundColor: (data && data.backgroundColor) || "",
  756 + backgroundColor: (data && data.backgroundColor) || (!data ? "rgba(52, 80, 106, 1)" : ""),
634 757 backgroundImage: (data && data.backgroundImage) || "",
635 758 height: (data && data.height) || 1080,
636 759 title: (data && data.title) || "",
... ... @@ -718,7 +841,7 @@ export default {
718 841 // console.log(screenData);
719 842 //loading
720 843 this.$showLoading();
721   - const { code, data } = await insertDashboard(screenData);
  844 + const { code } = await insertDashboard(screenData);
722 845 this.$hideLoading();
723 846 if (code == "200") {
724 847 this.$message.success("保存成功!");
... ... @@ -796,29 +919,36 @@ export default {
796 919 type: "error",
797 920 });
798 921 },
799   - //中间区域减去的宽度
800   - widthLeftAndRight(){
801   - let widthLeftAndRight = 0;
802   - if (this.toolIsShow) {
803   - widthLeftAndRight += this.widthLeftForTools; // 左侧工具栏宽度
804   - widthLeftAndRight += this.widthLeftForToolsHideButton; // 左侧工具栏折叠按钮宽度
805   - }
806   - if (this.setupIsShow) {
807   - widthLeftAndRight += this.widthLeftForOptions; // 右侧配置栏宽度
808   - widthLeftAndRight += this.widthRightForToolsHideButton; // 右侧工具栏折叠按钮宽度
809   - }
810   - // console.log("中间区域增加的宽度",widthLeftAndRight,this.setupIsShow,this.toolIsShow)
811   - return widthLeftAndRight;
812   - },
813   - // 在缩放模式下的大小
  922 +// 在缩放模式下的大小
814 923 getPXUnderScale(px) {
815 924 return this.bigscreenScaleInWorkbench * px;
816 925 },
817 926 dragStart(widgetCode) {
818 927 this.dragWidgetCode = widgetCode;
  928 + this.currentWidgetTotal = this.widgets.length; // 当前操作面板上有多少各组件
819 929 },
820 930 dragEnd() {
821   - this.dragWidgetCode = "";
  931 + /**
  932 + * 40@remarks 新增组件到操作面板后,右边的配置有更新,但是当前选中的组件没更新,导致配置错乱的bug;
  933 + * 由于拖动组件拖到非操作面板上是不会添加组件,还需判断是否添加组件到操作面板上;
  934 + */
  935 + this.$nextTick(() => {
  936 + if (this.widgets.length === this.currentWidgetTotal + 1) {
  937 + // 确实新增了一个组件到操作面板上
  938 + // console.log(
  939 + // `新添加 '${
  940 + // this.widgets[this.currentWidgetTotal].value.setup.layerName
  941 + // }' 组件到操作面板`
  942 + // );
  943 + const uuid = Number(Math.random().toString().substr(2)).toString(36);
  944 + this.widgets[this.currentWidgetTotal].value.widgetId = uuid;
  945 + this.layerWidget[this.currentWidgetTotal].widgetId = uuid;
  946 + this.widgets[this.currentWidgetTotal].value.widgetCode = this.dragWidgetCode;
  947 + const index = this.widgets.length - 1;
  948 + this.layerClick(index); // 选中当前新增的组件
  949 + this.grade = false; // 去除网格线
  950 + }
  951 + });
822 952 },
823 953 dragOver(evt) {
824 954 evt.preventDefault();
... ... @@ -837,9 +967,12 @@ export default {
837 967 let widgetTopInWorkbench = eventY - workbenchPosition.top;
838 968 let widgetLeftInWorkbench = eventX - workbenchPosition.left;
839 969  
840   - // 计算在缩放模式下的x y
841   - let x = widgetLeftInWorkbench / this.bigscreenScaleInWorkbench;
842   - let y = widgetTopInWorkbench / this.bigscreenScaleInWorkbench;
  970 + const targetScale =
  971 + this.currentSizeRangeIndex === this.defaultSize.index
  972 + ? this.bigscreenScaleInWorkbench
  973 + : this.sizeRange[this.currentSizeRangeIndex] / 100;
  974 + const x = widgetLeftInWorkbench / targetScale;
  975 + const y = widgetTopInWorkbench / targetScale;
843 976  
844 977 // 复制一个组件
845 978 let tool = getToolByCode(widgetType);
... ... @@ -859,7 +992,7 @@ export default {
859 992 options: tool.options,
860 993 };
861 994 // 处理默认值
862   - const widgetJsonValue = this.handleDefaultValue(widgetJson);
  995 + const widgetJsonValue = this.getWidgetConfigValue(widgetJson);
863 996  
864 997 //可以拖拽放到鼠标的位置
865 998 widgetJsonValue.value.position.left =
... ... @@ -872,7 +1005,32 @@ export default {
872 1005 // 激活新组件的配置属性
873 1006 this.setOptionsOnClickWidget(this.widgets.length - 1);
874 1007 },
875   -
  1008 + getWidgetConfigValue(widgetJson) {
  1009 + this.setWidgetConfigValue(
  1010 + widgetJson.options.setup,
  1011 + widgetJson.value.setup
  1012 + );
  1013 + this.setWidgetConfigValue(
  1014 + widgetJson.options.position,
  1015 + widgetJson.value.position
  1016 + );
  1017 + this.setWidgetConfigValue(widgetJson.options.data, widgetJson.value.data);
  1018 + return widgetJson;
  1019 + },
  1020 + setWidgetConfigValue(config, configValue) {
  1021 + config.forEach((item) => {
  1022 + if (this.isObjectFn(item)) {
  1023 + configValue[item.name] = item.value;
  1024 + }
  1025 + if (this.isArrayFn(item)) {
  1026 + item.forEach((itemChild) => {
  1027 + itemChild.list.forEach((ev) => {
  1028 + configValue[ev.name] = ev.value;
  1029 + });
  1030 + });
  1031 + }
  1032 + });
  1033 + },
876 1034 // 对组件默认值处理
877 1035 handleDefaultValue(widgetJson) {
878 1036 for (const key in widgetJson) {
... ... @@ -1018,6 +1176,7 @@ export default {
1018 1176 widgetValueChanged(key, val) {
1019 1177 if (this.screenCode == "screen") {
1020 1178 if (key === 'setup') {
  1179 + // console.log("dddd",key,val,"this.screenCode",this.screenCode);
1021 1180 // 全局配置更改
1022 1181 let newSetup = new Array();
1023 1182 this.dashboard = this.deepClone(val);
... ... @@ -1051,7 +1210,11 @@ export default {
1051 1210 newData.push(el);
1052 1211 });
1053 1212 this.widgetOptions.data = newData;
1054   - this.setMasterData(this.dashboard);
  1213 + if(val
  1214 + && this.isNotBlankObj(val.dynamicData)
  1215 + && "master-data"===val.dynamicData.chartType){
  1216 + this.setMasterData(this.dashboard);
  1217 + }
1055 1218 }
1056 1219 } else {
1057 1220 for (let i = 0; i < this.widgets.length; i++) {
... ... @@ -1062,6 +1225,7 @@ export default {
1062 1225 }
1063 1226 }
1064 1227 },
  1228 + // 右键
1065 1229 rightClick(event, index) {
1066 1230 this.rightClickIndex = index;
1067 1231 const left = event.clientX;
... ... @@ -1175,9 +1339,9 @@ export default {
1175 1339 //输入删除键删除
1176 1340 entryDelete(index){
1177 1341 this.widgets.splice(index, 1);
1178   - //调用删除
1179   - // this.selectMore.push(index);
1180   - // this.deletelayerOne();
  1342 + //调用删除
  1343 + // this.selectMore.push(index);
  1344 + // this.deletelayerOne();
1181 1345 },
1182 1346 deletelayer() {
1183 1347 this.widgets.splice(this.rightClickIndex, 1);
... ... @@ -1191,13 +1355,23 @@ export default {
1191 1355 let widgetsCp = [];
1192 1356 if(this.isNotBlankArray(this.selectMore)){
1193 1357 for(let i = 0; i< this.widgets.length;i++){
1194   - if(this.selectMore.indexOf(i)<0){
1195   - widgetsCp.push(this.widgets[i]);
1196   - }
  1358 + if(this.selectMore.indexOf(i)<0){
  1359 + widgetsCp.push(this.widgets[i]);
  1360 + }
1197 1361 }
1198 1362 }
1199 1363 this.widgets = widgetsCp;
1200 1364 },
  1365 + // 锁定
  1366 + lockLayer() {
  1367 + const obj = this.widgets[this.rightClickIndex];
  1368 + this.$set(obj.value.position, "disabled", true);
  1369 + },
  1370 + // 解除锁定
  1371 + noLockLayer() {
  1372 + const obj = this.widgets[this.rightClickIndex];
  1373 + this.$set(obj.value.position, "disabled", false);
  1374 + },
1201 1375 //根据上下左右键移动(因为子组件直接切换焦点事件问题,这里弥补不点大屏直接切组件移动)
1202 1376 dragWidgetMoveByKey(code,widgetIndex){
1203 1377 const position = this.widgets[widgetIndex].value.position;
... ... @@ -1226,509 +1400,5 @@ export default {
1226 1400 </script>
1227 1401  
1228 1402 <style scoped lang="scss">
1229   -.mr10 {
1230   - margin-right: 10px;
1231   -}
1232   -
1233   -.ml20 {
1234   - margin-left: 20px;
1235   -}
1236   -
1237   -.border-right {
1238   - border-right: 1px solid #273b4d;
1239   -}
1240   -
1241   -.border-left {
1242   - border-left: 1px solid #273b4d;
1243   -}
1244   -
1245   -.el-icon-arrow-down {
1246   - font-size: 10px;
1247   -}
1248   -
1249   -.is-active {
1250   - background: #31455d !important;
1251   - color: #bfcbd9 !important;
1252   -}
1253   -
1254   -.layout {
1255   - display: -webkit-box;
1256   - display: -ms-flexbox;
1257   - display: flex;
1258   - width: 100%;
1259   - height: 100%;
1260   - -webkit-box-sizing: border-box;
1261   - box-sizing: border-box;
1262   - overflow: hidden;
1263   -
1264   - .layout-left {
1265   - display: inline-block;
1266   - height: 100%;
1267   - box-sizing: border-box;
1268   - -webkit-box-sizing: border-box;
1269   - border: 0px;
1270   - background-color: #263445;
1271   -
1272   - //工具栏一个元素
1273   - .tools-item {
1274   - display: flex;
1275   - position: relative;
1276   - width: 100%;
1277   - height: 48px;
1278   - align-items: center;
1279   - -webkit-box-align: center;
1280   - padding: 0 6px;
1281   - cursor: pointer;
1282   - font-size: 12px;
1283   - margin-bottom: 1px;
1284   -
1285   - .tools-item-icon {
1286   - color: #409eff;
1287   - margin-right: 10px;
1288   - width: 53px;
1289   - height: 30px;
1290   - line-height: 30px;
1291   - text-align: center;
1292   - display: block;
1293   - border: 1px solid #3a4659;
1294   - background: #282a30;
1295   - }
1296   - .tools-item-text {
1297   - }
1298   - }
1299   - }
1300   -
1301   - .layout-left-fold {
1302   - display: -webkit-box;
1303   - display: -ms-flexbox;
1304   - display: flex;
1305   - height: 100%;
1306   -
1307   - font-size: 12px;
1308   - overflow: hidden;
1309   - background-color: #242a30;
1310   - cursor: pointer;
1311   - padding-top: 26%;
1312   -
1313   - i {
1314   - font-size: 18px;
1315   - width: 18px;
1316   - height: 23px;
1317   - margin-left: 0px;
1318   - color: #bfcbd9;
1319   - }
1320   - }
1321   -
1322   - .layout-middle {
1323   - //display: flex;
1324   - position: relative;
1325   - //width: calc(100% - 445px);
1326   - height: 100%;
1327   - background-color: rgb(36, 42, 48);
1328   - box-sizing: border-box;
1329   - -webkit-box-sizing: border-box;
1330   - border: 1px solid rgb(36, 42, 48);
1331   - align-items: center;
1332   - vertical-align: middle;
1333   - text-align: center;
1334   -
1335   - .top-button {
1336   - display: flex;
1337   - flex-direction: row;
1338   - height: 40px;
1339   - line-height: 40px;
1340   - margin-left: 9px;
1341   -
1342   - .btn {
1343   - color: #788994;
1344   - width: 55px;
1345   - text-align: center;
1346   - display: block;
1347   - cursor: pointer;
1348   -
1349   - .el-icon-arrow-down {
1350   - transform: rotate(0deg);
1351   - -ms-transform: rotate(0deg); /* IE 9 */
1352   - -moz-transform: rotate(0deg); /* Firefox */
1353   - -webkit-transform: rotate(0deg); /* Safari 和 Chrome */
1354   - -o-transform: rotate(0deg); /* Opera */
1355   - transition: all 0.4s ease-in-out;
1356   - }
1357   -
1358   - &:hover {
1359   - background: rgb(25, 29, 34);
1360   -
1361   - .el-icon-arrow-down {
1362   - transform: rotate(180deg);
1363   - -ms-transform: rotate(180deg); /* IE 9 */
1364   - -moz-transform: rotate(180deg); /* Firefox */
1365   - -webkit-transform: rotate(180deg); /* Safari 和 Chrome */
1366   - -o-transform: rotate(180deg); /* Opera */
1367   - transition: all 0.4s ease-in-out;
1368   - }
1369   - }
1370   - }
1371   - }
1372   -
1373   - .workbench-container {
1374   - position: relative;
1375   - -webkit-transform-origin: 0 0;
1376   - transform-origin: 0 0;
1377   - -webkit-box-sizing: border-box;
1378   - box-sizing: border-box;
1379   - margin: 0;
1380   - padding: 0;
1381   -
1382   - .vueRuler {
1383   - width: 100%;
1384   - padding: 18px 0px 0px 18px;
1385   - }
1386   -
1387   - .workbench {
1388   - background-color: #1e1e1e;
1389   - position: relative;
1390   - -webkit-user-select: none;
1391   - -moz-user-select: none;
1392   - -ms-user-select: none;
1393   - user-select: none;
1394   - -webkit-transform-origin: 0 0;
1395   - transform-origin: 0 0;
1396   - margin: 0;
1397   - padding: 0;
1398   - }
1399   -
1400   - .bg-grid {
1401   - position: absolute;
1402   - top: 0;
1403   - left: 0;
1404   - width: 100%;
1405   - height: 100%;
1406   - background-size: 30px 30px, 30px 30px;
1407   - background-image: linear-gradient(
1408   - hsla(0, 0%, 100%, 0.1) 1px,
1409   - transparent 0
1410   - ),
1411   - linear-gradient(90deg, hsla(0, 0%, 100%, 0.1) 1px, transparent 0);
1412   - // z-index: 2;
1413   - }
1414   - }
1415   -
1416   - .bottom-text {
1417   - width: 100%;
1418   - color: #a0a0a0;
1419   - font-size: 16px;
1420   - position: absolute;
1421   - bottom: 20px;
1422   - }
1423   - }
1424   -
1425   - .layout-right {
1426   - display: inline-block;
1427   - height: 100%;
1428   - }
1429   -
1430   - /deep/ .el-tabs--border-card {
1431   - border: 0;
1432   -
1433   - .el-tabs__header {
1434   - .el-tabs__nav {
1435   - .el-tabs__item {
1436   - background-color: #242f3b;
1437   - border: 0px;
1438   - }
1439   -
1440   - .el-tabs__item.is-active {
1441   - background-color: #31455d;
1442   - }
1443   - }
1444   - }
1445   -
1446   - .el-tabs__content {
1447   - background-color: #242a30;
1448   - height: calc(100vh - 39px);
1449   - overflow-x: hidden;
1450   - overflow-y: auto;
1451   -
1452   - .el-tab-pane {
1453   - color: #bfcbd9;
1454   - }
1455   -
1456   - &::-webkit-scrollbar {
1457   - width: 5px;
1458   - height: 14px;
1459   - }
1460   -
1461   - &::-webkit-scrollbar-track,
1462   - &::-webkit-scrollbar-thumb {
1463   - border-radius: 1px;
1464   - border: 0 solid transparent;
1465   - }
1466   -
1467   - &::-webkit-scrollbar-track-piece {
1468   - /*修改滚动条的背景和圆角*/
1469   - background: #29405c;
1470   - -webkit-border-radius: 7px;
1471   - }
1472   -
1473   - &::-webkit-scrollbar-track {
1474   - box-shadow: 1px 1px 5px rgba(116, 148, 170, 0.5) inset;
1475   - }
1476   -
1477   - &::-webkit-scrollbar-thumb {
1478   - min-height: 20px;
1479   - background-clip: content-box;
1480   - box-shadow: 0 0 0 5px rgba(116, 148, 170, 0.5) inset;
1481   - }
1482   -
1483   - &::-webkit-scrollbar-corner {
1484   - background: transparent;
1485   - }
1486   -
1487   - /*修改垂直滚动条的样式*/
1488   - &::-webkit-scrollbar-thumb:vertical {
1489   - background-color: #00113a;
1490   - -webkit-border-radius: 7px;
1491   - }
1492   -
1493   - /*修改水平滚动条的样式*/
1494   - &::-webkit-scrollbar-thumb:horizontal {
1495   - background-color: #00113a;
1496   - -webkit-border-radius: 7px;
1497   - }
1498   - }
1499   - }
1500   -}
1501   -
1502   -ul,
1503   -li {
1504   - list-style: none;
1505   - margin: 0;
1506   - padding: 0;
1507   -}
1508   -
1509   -.nav {
1510   - width: 40px;
1511   - padding: 0;
1512   - list-style: none;
1513   - /* overflow: hidden; */
1514   -}
1515   -
1516   -.nav {
1517   - zoom: 1;
1518   -}
1519   -
1520   -.nav:before,
1521   -.nav:after {
1522   - content: "";
1523   - display: table;
1524   -}
1525   -
1526   -.nav:after {
1527   - clear: both;
1528   -}
1529   -
1530   -.nav > li {
1531   - width: 55px;
1532   - text-align: left;
1533   - position: relative;
1534   -}
1535   -
1536   -.nav > li a {
1537   - float: left;
1538   - padding: 12px 30px;
1539   - color: #999;
1540   - font-bold: 12px;
1541   - text-decoration: none;
1542   -}
1543   -
1544   -.nav > li:hover {
1545   - color: #788994;
1546   -}
1547   -
1548   -.nav > li ul {
1549   - visibility: hidden;
1550   - position: absolute;
1551   - z-index: 1000;
1552   - list-style: none;
1553   - left: 0;
1554   - padding: 0;
1555   - background-color: rgb(36, 42, 48);
1556   - opacity: 0;
1557   - _margin: 0;
1558   - width: 120px;
1559   - transition: all 0.2s ease-in-out;
1560   -}
1561   -
1562   -.nav > li:hover > ul {
1563   - opacity: 1;
1564   - visibility: visible;
1565   - margin: 0;
1566   -
1567   - li:hover {
1568   - background-color: rgb(25, 29, 34);
1569   - }
1570   -}
1571   -
1572   -.nav ul li {
1573   - float: left;
1574   - display: block;
1575   - border: 0;
1576   - width: 100%;
1577   - font-size: 12px;
1578   -}
1579   -
1580   -.nav ul a {
1581   - padding: 10px;
1582   - width: 100%;
1583   - display: block;
1584   - float: none;
1585   - height: 120px;
1586   - border: 1px solid #30445c;
1587   - background-color: rgb(25, 29, 34);
1588   - transition: all 0.2s ease-in-out;
1589   -}
1590   -
1591   -.nav ul a:hover {
1592   - border: 1px solid #3c5e88;
1593   -}
1594   -
1595   -.nav ul li:first-child > a:hover:before {
1596   - border-bottom-color: #04acec;
1597   -}
1598   -
1599   -.nav ul ul {
1600   - top: 0;
1601   - left: 120px;
1602   - width: 400px;
1603   - height: 300px;
1604   - overflow: auto;
1605   - padding: 10px;
1606   - _margin: 0;
1607   -}
1608   -
1609   -.nav ul ul li {
1610   - width: 120px;
1611   - height: 120px;
1612   - margin-right: 3px;
1613   - display: block;
1614   - float: left;
1615   -}
1616   -
1617   -.nav .item {
1618   - padding: 5px;
1619   -}
1620   -
1621   -/deep/ .vue-ruler-h {
1622   - opacity: 0.3;
1623   -}
1624   -
1625   -/deep/ .vue-ruler-v {
1626   - opacity: 0.3;
1627   -}
1628   -.layout-left {
1629   - width: 200px;
1630   - background: #242a30;
1631   - overflow-x: hidden;
1632   - overflow-y: auto;
1633   - .chart-type {
1634   - display: flex;
1635   - flex-direction: row;
1636   - overflow: hidden;
1637   - .type-left {
1638   - width: 100%;
1639   - height: calc(100vh - 80px);
1640   - text-align: center;
1641   - /deep/.el-tabs__header {
1642   - width: 30%;
1643   - margin-right: 0;
1644   - .el-tabs__nav-wrap {
1645   - &::after {
1646   - background: transparent;
1647   - }
1648   - .el-tabs__item {
1649   - text-align: center;
1650   - width: 100% !important;
1651   - color: #fff;
1652   - padding: 0;
1653   - font-size: 12px !important;
1654   - }
1655   - }
1656   - }
1657   - /deep/.el-tabs__content {
1658   - width: 70%;
1659   - }
1660   - }
1661   - }
1662   - //工具栏一个元素
1663   - .tools-item {
1664   - display: flex;
1665   - position: relative;
1666   - width: 100%;
1667   - height: 48px;
1668   - align-items: center;
1669   - -webkit-box-align: center;
1670   - padding: 0 6px;
1671   - cursor: pointer;
1672   - font-size: 12px;
1673   - margin-bottom: 1px;
1674   -
1675   - .tools-item-icon {
1676   - color: #409eff;
1677   - margin-right: 10px;
1678   - width: 53px;
1679   - height: 30px;
1680   - line-height: 30px;
1681   - text-align: center;
1682   - display: block;
1683   - border: 1px solid #3a4659;
1684   - background: #282a30;
1685   - }
1686   - .tools-item-text {
1687   - font-size: 12px !important;
1688   - }
1689   - }
1690   - /deep/.el-tabs__content {
1691   - padding: 0;
1692   - }
1693   -}
1694   -///* 设置滚动条的样式 */
1695   -//::-webkit-scrollbar {
1696   -// width: 0;
1697   -//}
1698   -//
1699   -///* 滚动槽 */
1700   -//::-webkit-scrollbar-track {
1701   -// -webkit-box-shadow: inset006pxrgba(0, 0, 0, 0.3);
1702   -//}
1703   -//
1704   -///* 滚动条滑块 */
1705   -//::-webkit-scrollbar-thumb {
1706   -// background: rgba(0, 0, 0, 0.1);
1707   -// -webkit-box-shadow: inset006pxrgba(0, 0, 0, 0.5);
1708   -//}
1709   -//
1710   -//::-webkit-scrollbar-thumb:window-inactive {
1711   -// background: rgba(255, 0, 0, 0.4);
1712   -//}
1713   -/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
1714   -::-webkit-scrollbar{
1715   - width: 0;
1716   - background-color: #242a30;
1717   -}
1718   -
1719   -/*定义滚动条轨道 内阴影+圆角*/
1720   -::-webkit-scrollbar-track {
1721   - box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
1722   - -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
1723   - border-radius: 10px;
1724   - background-color: #F5F5F5;
1725   -}
1726   -
1727   -/*定义滑块 内阴影+圆角*/
1728   -::-webkit-scrollbar-thumb{
1729   - border-radius: 10px;
1730   - box-shadow: inset 0 0 6px rgba(0, 0, 0, .1);
1731   - -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .1);
1732   - background-color: #c8c8c8;
1733   -}
  1403 +@import "@/assets/styles/screen.scss";
1734 1404 </style>
... ...
src/views/bigscreenDesigner/designer/index.vue.宽高都自适应 renamed to src/views/bigscreenDesigner/designer/index.vue.bak
... ... @@ -131,6 +131,7 @@
131 131 :headers="headers"
132 132 accept=".zip"
133 133 :on-success="handleUpload"
  134 + :before-upload="beforeUpload"
134 135 :on-error="handleError"
135 136 :show-file-list="false"
136 137 :limit="1"
... ... @@ -140,34 +141,42 @@
140 141 </el-tooltip>
141 142 </span>
142 143 <span class="btn border-left" v-permission="'bigScreenManage:import'">
143   - <ul class="nav">
144   - <li>
145   - <i class="iconfont icondaochu"></i
146   - ><i class="el-icon-arrow-down"></i>
147   - <ul>
148   - <li>
149   - <el-tooltip
150   - class="item"
151   - effect="dark"
152   - content="适合当前系统"
153   - placement="right"
154   - >
155   - <div @click="exportDashboard(1)">导出(包含数据集)</div>
156   - </el-tooltip>
157   - </li>
158   - <li>
159   - <el-tooltip
160   - class="item"
161   - effect="dark"
162   - content="适合跨系统"
163   - placement="right"
164   - >
165   - <div @click="exportDashboard(0)">导出(不包含数据集)</div>
166   - </el-tooltip>
167   - </li>
168   - </ul>
169   - </li>
170   - </ul>
  144 + <i class="iconfont icondaochu" @click="exportDashboard(1)"></i>
  145 + <el-tooltip
  146 + class="item"
  147 + effect="dark"
  148 + content="导出"
  149 + placement="right"
  150 + >
  151 + </el-tooltip>
  152 +<!-- <ul class="nav">-->
  153 +<!-- <li>-->
  154 +<!-- <i class="iconfont icondaochu"></i-->
  155 +<!-- ><i class="el-icon-arrow-down"></i>-->
  156 +<!-- <ul>-->
  157 +<!-- <li>-->
  158 +<!-- <el-tooltip-->
  159 +<!-- class="item"-->
  160 +<!-- effect="dark"-->
  161 +<!-- content="适合当前系统"-->
  162 +<!-- placement="right"-->
  163 +<!-- >-->
  164 +<!-- <div @click="exportDashboard(1)">导出(包含数据集)</div>-->
  165 +<!-- </el-tooltip>-->
  166 +<!-- </li>-->
  167 +<!-- <li>-->
  168 +<!-- <el-tooltip-->
  169 +<!-- class="item"-->
  170 +<!-- effect="dark"-->
  171 +<!-- content="适合跨系统"-->
  172 +<!-- placement="right"-->
  173 +<!-- >-->
  174 +<!-- <div @click="exportDashboard(0)">导出(不包含数据集)</div>-->
  175 +<!-- </el-tooltip>-->
  176 +<!-- </li>-->
  177 +<!-- </ul>-->
  178 +<!-- </li>-->
  179 +<!-- </ul>-->
171 180 </span>
172 181 </div>
173 182 <!-- 中间设计-->
... ... @@ -223,14 +232,14 @@
223 232 :key="index"
224 233 v-model="widget.value"
225 234 :index="index"
226   - :stepX="stepX"
227   - :stepY="stepY"
  235 + :step="step"
228 236 :type="widget.type"
229 237 :bigscreen="{ bigscreenWidth, bigscreenHeight }"
230 238 @onActivated="setOptionsOnClickWidget"
231 239 @contextmenu.prevent.native="rightClick($event, index)"
232 240 @mousedown.prevent.native="widgetsClick(index)"
233 241 @mouseup.prevent.native="widgetsMouseup"
  242 + @keyup.delete.native="entryDelete(index)"
234 243 />
235 244 </div>
236 245 </vue-ruler-tool>
... ... @@ -301,7 +310,6 @@
301 310 import {
302 311 insertDashboard,
303 312 detailDashboard,
304   - importDashboard,
305 313 exportDashboard,
306 314 } from "@/api/bigscreen";
307 315 import { widgetTools, getToolByCode } from "./tools/index";
... ... @@ -314,7 +322,11 @@ import { getToken } from &quot;@/utils/auth&quot;;
314 322 import { Revoke } from "@/utils/revoke";
315 323 import { mapMutations } from 'vuex';
316 324 import process from "process";
  325 +import { debounce } from '@/utils/debounce'; // 引入防抖函数
317 326  
  327 +import loadingViewerVue from 'loading-view-vue'
  328 +import Vue from "vue";
  329 +Vue.use(loadingViewerVue,{mode:"5"});
318 330 export default {
319 331 name: "Login",
320 332 components: {
... ... @@ -326,7 +338,7 @@ export default {
326 338 },
327 339 data() {
328 340 return {
329   - uploadUrl:process.env.BASE_API +"/reportDashboard/import/" +this.$route.query.reportCode,
  341 + uploadUrl :"http://"+window.location.host+"/xlyReport/reportDashboard/import/" +this.$route.query.reportCode,
330 342 grade: false,
331 343 layerWidget: [],
332 344 widgetTools: widgetTools, // 左侧工具栏的组件图标,将js变量加入到当前作用域
... ... @@ -378,7 +390,6 @@ export default {
378 390 options: [],
379 391 },
380 392 ], // 工作区中拖放的组件
381   -
382 393 // 当前激活组件
383 394 widgetIndex: 0,
384 395 // 当前激活组件右侧配置属性
... ... @@ -395,14 +406,13 @@ export default {
395 406 visibleContentMenu: false,
396 407 rightClickIndex: -1,
397 408 activeName: "first",
  409 + selectMore:[],//按住shift多选的图层
  410 + shiftEnt:false,//shift键盘是否按住
398 411 };
399 412 },
400 413 computed: {
401   - stepX() {
402   - return Number(100 / (this.bigscreenScaleInWorkbenchX * 100));
403   - },
404   - stepY() {
405   - return Number(100 / (this.bigscreenScaleInWorkbenchY * 100));
  414 + step() {
  415 + return Number(100 / (this.bigscreenScaleInWorkbench * 100));
406 416 },
407 417 headers() {
408 418 return {
... ... @@ -427,26 +437,16 @@ export default {
427 437 (this.middleHeight - this.widthPaddingTools) / this.bigscreenHeight;
428 438 return Math.min(widthScale, heightScale);
429 439 },
430   - bigscreenScaleInWorkbenchX() {
431   - let widthScale =
432   - (this.middleWidth - this.widthPaddingTools) / this.bigscreenWidth;
433   - return widthScale;
434   - },
435   - bigscreenScaleInWorkbenchY() {
436   - let heightScale =
437   - (this.middleHeight - this.widthPaddingTools) / this.bigscreenHeight;
438   - return heightScale;
439   - },
440 440 workbenchTransform() {
441   - return `scale(${this.bigscreenScaleInWorkbenchX}, ${this.bigscreenScaleInWorkbenchY})`;
  441 + return `scale(${this.bigscreenScaleInWorkbench}, ${this.bigscreenScaleInWorkbench})`;
442 442 },
443 443 // 大屏在设计模式的大小
444 444 bigscreenWidthInWorkbench() {
445   - return this.getPXUnderScaleX(this.bigscreenWidth) + this.widthPaddingTools;
  445 + return this.getPXUnderScale(this.bigscreenWidth) + this.widthPaddingTools;
446 446 },
447 447 bigscreenHeightInWorkbench() {
448 448 return (
449   - this.getPXUnderScaleY(this.bigscreenHeight) + this.widthPaddingTools
  449 + this.getPXUnderScale(this.bigscreenHeight) + this.widthPaddingTools
450 450 );
451 451 },
452 452 // 尺子的宽度高度
... ... @@ -480,6 +480,15 @@ export default {
480 480 window.addEventListener("mouseup", () => {
481 481 this.grade = false;
482 482 });
  483 + window.addEventListener('keydown', code => this.handleKeyDown(code)); // 监听键盘按下事件
  484 + window.addEventListener('keyup', code => this.handleKeyUp(code)); // 监听键盘松开事件
  485 +
  486 + },
  487 + // 在beforeDestroy中
  488 + beforeDestroy() {
  489 + // 销毁监听键盘事件
  490 + window.removeEventListener('keydown', code => this.handleKeyDown(code));
  491 + window.removeEventListener('keyup', code => this.handleKeyUp(code));
483 492 },
484 493 methods: {
485 494 ...mapMutations('dataSource', ['SET_STATIC_DATA']),
... ... @@ -495,6 +504,28 @@ export default {
495 504 }
496 505 this.widgets = record;
497 506 },
  507 + // 监听按下键盘事件
  508 + handleKeyDown: debounce(function(code) {
  509 + // 判断是否按住shift键,是就把pin赋值为true
  510 + if (code.keyCode === 16 && code.shiftKey) {
  511 + this.shiftEnt = true;
  512 + }else if (
  513 + code.keyCode === 37 ||
  514 + code.keyCode === 38 ||
  515 + code.keyCode === 39 ||
  516 + code.keyCode === 40
  517 + ) {
  518 + //上下左右移动
  519 + this.dragWidgetMoveByKey(code,this.widgetIndex);
  520 + }
  521 + }, 10, true),
  522 + handleKeyUp: debounce(function(code) {
  523 + // 判断是否松开shift键,是就把pin赋值为false
  524 + if (code.keyCode === 16) {
  525 + this.shiftEnt = false;
  526 + this.selectMore=[];
  527 + }
  528 + }, 500, true),
498 529 /**
499 530 * @description: 重做
500 531 * @param {*}
... ... @@ -523,8 +554,10 @@ export default {
523 554 this.layerWidget = layerWidgetArr;
524 555 },
525 556 async initEchartData() {
526   - const reportCode = this.$route.query.reportCode;
  557 + const reportCode = this.$route.query;
  558 + this.$showLoading();
527 559 const { code, data } = await detailDashboard(reportCode);
  560 + this.$hideLoading();
528 561 if (code != 200) return;
529 562 const processData = this.handleInitEchartsData(data);
530 563 const screenData = this.handleBigScreen(data.dashboard);
... ... @@ -683,7 +716,10 @@ export default {
683 716 widgets: this.widgets,
684 717 };
685 718 // console.log(screenData);
  719 + //loading
  720 + this.$showLoading();
686 721 const { code, data } = await insertDashboard(screenData);
  722 + this.$hideLoading();
687 723 if (code == "200") {
688 724 this.$message.success("保存成功!");
689 725 }
... ... @@ -699,14 +735,15 @@ export default {
699 735 // 导出
700 736 async exportDashboard(val) {
701 737 const fileName = this.$route.query.reportCode + ".zip";
702   -
703 738 const param = {
704 739 reportCode: this.$route.query.reportCode,
705 740 showDataSet: val,
706 741 };
  742 + this.$showLoading();
707 743 exportDashboard(param).then((res) => {
708 744 const that = this;
709 745 const type = res.type;
  746 + this.$hideLoading();
710 747 if (type == "application/json") {
711 748 let reader = new FileReader();
712 749 reader.readAsText(res, "utf-8");
... ... @@ -716,7 +753,6 @@ export default {
716 753 };
717 754 return;
718 755 }
719   -
720 756 const blob = new Blob([res], { type: "application/octet-stream" });
721 757 if (window.navigator.msSaveOrOpenBlob) {
722 758 //msSaveOrOpenBlob方法返回bool值
... ... @@ -730,12 +766,17 @@ export default {
730 766 }
731 767 });
732 768 },
  769 + //上传之前
  770 + beforeUpload(){
  771 + this.$showLoading();
  772 + },
733 773 // 上传成功的回调
734 774 handleUpload(response, file, fileList) {
735 775 //清除el-upload组件中的文件
736 776 this.$refs.upload.clearFiles();
737 777 //刷新大屏页面
738 778 this.initEchartData();
  779 + this.$hideLoading();
739 780 if (response.code == "200") {
740 781 this.$message({
741 782 message: "导入成功!",
... ... @@ -749,6 +790,7 @@ export default {
749 790 }
750 791 },
751 792 handleError(err) {
  793 + this.$hideLoading();
752 794 this.$message({
753 795 message: "上传失败!",
754 796 type: "error",
... ... @@ -769,11 +811,8 @@ export default {
769 811 return widthLeftAndRight;
770 812 },
771 813 // 在缩放模式下的大小
772   - getPXUnderScaleX(px) {
773   - return this.bigscreenScaleInWorkbenchX * px;
774   - },
775   - getPXUnderScaleY(px) {
776   - return this.bigscreenScaleInWorkbenchY * px;
  814 + getPXUnderScale(px) {
  815 + return this.bigscreenScaleInWorkbench * px;
777 816 },
778 817 dragStart(widgetCode) {
779 818 this.dragWidgetCode = widgetCode;
... ... @@ -873,6 +912,7 @@ export default {
873 912 }
874 913 }
875 914 }
  915 + // console.log("widgetJson",widgetJson);
876 916 return widgetJson;
877 917 },
878 918 layerClick(index) {
... ... @@ -881,10 +921,12 @@ export default {
881 921 },
882 922 // 如果是点击大屏设计器中的底层,加载大屏底层属性
883 923 setOptionsOnClickScreen() {
884   - this.screenCode = "screen";
885   - // 选中不同的组件 右侧都显示第一栏
886   - this.activeName = "first";
887   - this.widgetOptions = getToolByCode("screen")["options"];
  924 + if(!this.shiftEnt) {
  925 + this.screenCode = "screen";
  926 + // 选中不同的组件 右侧都显示第一栏
  927 + this.activeName = "first";
  928 + this.widgetOptions = getToolByCode("screen")["options"];
  929 + }
888 930 },
889 931 getScreenData(data){
890 932 const screenData = {};
... ... @@ -924,23 +966,41 @@ export default {
924 966 },
925 967 widgetsClick(index) {
926 968 const draggableArr = this.$refs.widgets;
927   - for (let i = 0; i < draggableArr.length; i++) {
928   - if (i == index) {
929   - this.$refs.widgets[i].$refs.draggable.setActive(true);
930   - } else {
931   - this.$refs.widgets[i].$refs.draggable.setActive(false);
  969 + //判断是否按住了shift键盘
  970 + if(this.shiftEnt){
  971 + for (let i = 0; i < draggableArr.length; i++) {
  972 + if (i == index) {
  973 + this.$refs.widgets[i].$refs.draggable.setActive(true);
  974 + this.selectMore.push(index);
  975 + }
  976 + }
  977 + }else{
  978 + //没有按住shift键标识编辑单个
  979 + let selectMore = [];
  980 + for (let i = 0; i < draggableArr.length; i++) {
  981 + if (i == index) {
  982 + this.$refs.widgets[i].$refs.draggable.setActive(true);
  983 + selectMore.push(index);
  984 + this.selectMore = selectMore;
  985 + } else {
  986 + this.$refs.widgets[i].$refs.draggable.setActive(false);
  987 + }
932 988 }
933 989 }
934 990 this.setOptionsOnClickWidget(index);
935 991 this.grade = true;
  992 + this.widgetIndex = index;
936 993 },
937 994 widgetsMouseup(e) {
938 995 this.grade = false;
939 996 },
940 997 handleMouseDown() {
941   - const draggableArr = this.$refs.widgets;
942   - for (let i = 0; i < draggableArr.length; i++) {
943   - this.$refs.widgets[i].$refs.draggable.setActive(false);
  998 + if(!this.shiftEnt){
  999 + const draggableArr = this.$refs.widgets;
  1000 + for (let i = 0; i < draggableArr.length; i++) {
  1001 + this.$refs.widgets[i].$refs.draggable.setActive(false);
  1002 + }
  1003 + this.selectMore = [];
944 1004 }
945 1005 },
946 1006 setWidgetOptionsData(val){
... ... @@ -1049,13 +1109,30 @@ export default {
1049 1109 arr[oldIndex] = arr.splice(newIndex, 1, arr[oldIndex])[0];
1050 1110 return arr;
1051 1111 },
1052   - // 删除
1053   - deletelayer() {
1054   - this.widgets.splice(this.rightClickIndex, 1);
  1112 + //去重
  1113 + setUnique(arr) {
  1114 + let newArr = [];
  1115 + arr.forEach(item => {
  1116 + return newArr.includes(item) ? '' : newArr.push(item);
  1117 + });
  1118 + return newArr;
1055 1119 },
1056   - // 复制
  1120 + // 多选复制
1057 1121 copylayer() {
1058   - const obj = this.deepClone(this.widgets[this.rightClickIndex]);
  1122 + //首先复制右选节点,再复制其他选择节点
  1123 + this.copylayerOne(this.rightClickIndex)
  1124 + // if(this.isNotBlankArray(this.selectMore)){
  1125 + // for(let i = 0; i< this.selectMore.length;i++){
  1126 + // const copyIndex = this.selectMore[i];
  1127 + // if(this.rightClickIndex != copyIndex){
  1128 + // this.copylayerOne(copyIndex);
  1129 + // }
  1130 + // }
  1131 + // }
  1132 + },
  1133 + // 复制
  1134 + copylayerOne(index) {
  1135 + const obj = this.deepClone(this.widgets[index]);
1059 1136 this.widgets.splice(this.widgets.length, 0, obj);
1060 1137 },
1061 1138 // 置顶
... ... @@ -1095,6 +1172,55 @@ export default {
1095 1172 this.widgets.unshift(this.widgets.splice(this.rightClickIndex, 1)[0]);
1096 1173 }
1097 1174 },
  1175 + //输入删除键删除
  1176 + entryDelete(index){
  1177 + this.widgets.splice(index, 1);
  1178 + //调用删除
  1179 + // this.selectMore.push(index);
  1180 + // this.deletelayerOne();
  1181 + },
  1182 + deletelayer() {
  1183 + this.widgets.splice(this.rightClickIndex, 1);
  1184 + // this.selectMore.push(this.rightClickIndex);
  1185 + // this.deletelayerOne();
  1186 + },
  1187 + // 删除
  1188 + deletelayerOne() {
  1189 + this.selectMore = this.setUnique(this.selectMore);
  1190 + //首先复制右选节点,再复制其他选择节点
  1191 + let widgetsCp = [];
  1192 + if(this.isNotBlankArray(this.selectMore)){
  1193 + for(let i = 0; i< this.widgets.length;i++){
  1194 + if(this.selectMore.indexOf(i)<0){
  1195 + widgetsCp.push(this.widgets[i]);
  1196 + }
  1197 + }
  1198 + }
  1199 + this.widgets = widgetsCp;
  1200 + },
  1201 + //根据上下左右键移动(因为子组件直接切换焦点事件问题,这里弥补不点大屏直接切组件移动)
  1202 + dragWidgetMoveByKey(code,widgetIndex){
  1203 + const position = this.widgets[widgetIndex].value.position;
  1204 + const temp=3;
  1205 + if(code.keyCode==40 || code.key=='ArrowDown'){
  1206 + position.top = position.top+temp;
  1207 + this.$refs.widgets[widgetIndex].$refs.draggable.setTop(position);
  1208 + }if(code.keyCode==38 || code.key=='ArrowUp'){
  1209 + position.top = position.top-temp;
  1210 + this.$refs.widgets[widgetIndex].$refs.draggable.setTop(position);
  1211 + }if(code.keyCode==37 || code.key=='ArrowLeft'){
  1212 + position.left = position.left-temp;
  1213 + this.$refs.widgets[widgetIndex].$refs.draggable.setLeft(position);
  1214 + }if(code.keyCode==39 || code.key=='ArrowRight'){
  1215 + position.left = position.left+temp;
  1216 + this.$refs.widgets[widgetIndex].$refs.draggable.setLeft(position);
  1217 + }
  1218 + },
  1219 + //输入ctrl+c
  1220 + entryCopy(index){
  1221 + const obj = this.deepClone(this.widgets[index]);
  1222 + this.widgets.splice(this.widgets.length, 0, obj);
  1223 + }
1098 1224 },
1099 1225 };
1100 1226 </script>
... ...
src/views/bigscreenDesigner/designer/linkageLogic.js 0 → 100644
  1 +/*
  2 + * @Description: 各联动组件的参数配置 参数paramsKey的值具体封装时再改
  3 + */
  4 +import { eventBus as bus } from "@/utils/eventBus";
  5 +export const lickageParamsConfig = [
  6 + // {
  7 + // name: '按钮组',
  8 + // code: 'widgetButtonGroup',
  9 + // paramsKey: [] // 40@remarks 动态:[...row, index]
  10 + // },
  11 + {
  12 + name: '下拉框',
  13 + code: 'widget-select',
  14 + paramsKey: ['label','value']
  15 + },
  16 + {
  17 + name: '时间筛选器',
  18 + code: 'widget-form-time',
  19 + paramsKey: ['startTime','endTime']
  20 + },
  21 + {
  22 + name: '柱图',
  23 + code: 'widget-barchart',
  24 + paramsKey: ['name', 'value']
  25 + },
  26 + {
  27 + name: '柱图-渐变色',
  28 + code: 'widget-gradient-color-barchart',
  29 + paramsKey: ['name', 'value']
  30 + },
  31 + // ……
  32 + {
  33 + name: '折线图',
  34 + code: 'widget-linechart',
  35 + paramsKey: ['name', 'value']
  36 + },
  37 + {
  38 + name: '百分比图',
  39 + code: 'widgetPiePercentageChart',
  40 + paramsKey: ['value']
  41 + },
  42 + {
  43 + name: '饼图',
  44 + code: 'widget-piechart',
  45 + paramsKey: ['name', 'value']
  46 + },
  47 + {
  48 + name: '南丁格尔玫瑰图',
  49 + code: 'WidgetPieNightingaleRoseArea',
  50 + paramsKey: ['name', 'value']
  51 + },
  52 +]
  53 +
  54 +export const getOneConfigByCode = function (code) {
  55 + return lickageParamsConfig.find(item => { return item.code === code })
  56 +}
  57 +
  58 +export const getOneConfigByName = function (name) {
  59 + return lickageParamsConfig.find(item => { return item.name === name })
  60 +}
  61 +
  62 +/**
  63 + * 源组件 - 初始化联动逻辑
  64 + * @param self 组件实例对象 this
  65 + * @param isActiveClick 主动触发(非echart类click事件触发)
  66 + * @param buttonConfig 按钮组组件的配置
  67 + * 40@remarks
  68 + * 1、v-chart 需添加 ref="myVChart" 以获取实例
  69 + * 2、 发消息发过去的对象 待封装配置动态兼容
  70 + */
  71 +export const originWidgetLinkageLogic = function (self, isActiveClick = false, buttonConfig = {}) {
  72 + // if (self.allComponentLinkage && self.allComponentLinkage.length && self.allComponentLinkage[self.widgetIndex].index !== -1 && self.allComponentLinkage[self.widgetIndex].linkageArr.length) {
  73 + if (self.optionsSetup.componentLinkage && self.optionsSetup.componentLinkage.length) {
  74 + if (isActiveClick) { // 主动触发
  75 + self.allComponentLinkage[self.widgetIndex].linkageArr.forEach(item => {
  76 + console.log(item)
  77 + console.log(`bus_${item.originId}_${item.targetId}`, ' -联动逻辑点击-发送消息', buttonConfig)
  78 + bus.$emit(`bus_${item.originId}_${item.targetId}`, buttonConfig.currentData)
  79 + })
  80 + } else { // chart 组件
  81 + self.$refs.myVChart.chart.on('click', function (params) {
  82 + self.allComponentLinkage[self.widgetIndex].linkageArr.forEach(item => {
  83 + console.log(`bus_${item.originId}_${item.targetId}`, ' -联动逻辑点击-发送消息', params)
  84 + console.log(self.value)
  85 + let message = {}
  86 + const widgetConfigTemp = getOneConfigByCode(self.value.widgetCode)
  87 + console.log('widgetConfigTemp', widgetConfigTemp)
  88 + if (widgetConfigTemp && widgetConfigTemp.paramsKey.length) { // 动态加载各组件的参数来封装
  89 + widgetConfigTemp.paramsKey.forEach(key => {
  90 + message[key] = params[key]
  91 + })
  92 + // 40@remarks 部分组件 传参需要特殊处理下
  93 + // ……
  94 + // 40@remarks 专用于测试联动发消息 手动改造消息内容
  95 + // if (self.value.widgetCode === 'widgetMap2d') {
  96 + // const nameTemp = ['苹果', '三星', '小米', '华为', 'OPPO', 'VIVO']
  97 + // // message = {
  98 + // // name: nameTemp[(params.dataIndex % 6)],
  99 + // // value: params.value,
  100 + // // dataIndex: params.dataIndex
  101 + // // }
  102 + // // message.name = nameTemp[(+params.value % 6)]
  103 + // message.name = nameTemp[(parseInt(Math.random() * 6) % 6)]
  104 + // }
  105 + // if (self.value.widgetCode === 'widget-piechart') {
  106 + // message.name = (parseInt(Math.random() * 2) % 2) === 0 ? '深圳市' : '盐田区'
  107 + // }
  108 + } else {
  109 + message = {
  110 + name: params.name,
  111 + value: params.value
  112 + }
  113 + }
  114 + bus.$emit(`bus_${item.originId}_${item.targetId}`, message)
  115 + })
  116 + })
  117 + }
  118 + }
  119 +}
  120 +
  121 +/**
  122 + * 目标组件 - 初始化联动逻辑
  123 + * @param self 组件实例对象 this
  124 + * @returns
  125 + */
  126 +export const targetWidgetLinkageLogic = function (self) {
  127 + const busEvents = []
  128 + // 有无有关联的组件
  129 + if (!self.allComponentLinkage || !self.allComponentLinkage.length) return
  130 + self.allComponentLinkage.some(item => {
  131 + if (item.index !== -1 && item.linkageArr.length) {
  132 + item.linkageArr.some(obj => {
  133 + if (obj.targetId === self.value.setup.widgetId) {
  134 + self.hasLinkage = true
  135 + busEvents.push({
  136 + eventName: `bus_${obj.originId}_${obj.targetId}`,
  137 + paramsConfig: obj.paramsConfig
  138 + })
  139 + return true
  140 + }
  141 + })
  142 + }
  143 + })
  144 + if (self.hasLinkage) {
  145 + busEvents.forEach(item => {
  146 + bus.$on(item.eventName, e => {
  147 + console.log(item.eventName, ' 接收消息e', e)
  148 + self.setOptionsData(e, item.paramsConfig)
  149 + })
  150 + })
  151 + }
  152 +}
... ...
src/views/bigscreenDesigner/designer/tools/configure/div/widget-html-slider.js 0 → 100644
  1 +/*
  2 + * @Descripttion: 轮播大屏
  3 + */
  4 +export const widgetHtmlSlider = {
  5 + code: 'widget-html-slider',
  6 + type: 'html',
  7 + tabName: '图层',
  8 + label: '轮播大屏',
  9 + icon: 'iconkuangjia',
  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: 'tabDirection',
  25 + required: false,
  26 + placeholder: '',
  27 + selectOptions: [
  28 + {code: 'horizontal', name: '横向'},
  29 + {code: 'vertical', name: '竖向'},
  30 + ],
  31 + value: 'horizontal'
  32 + },
  33 + {
  34 + type: 'el-select',
  35 + label: '类型',
  36 + name: 'tabType',
  37 + required: false,
  38 + placeholder: '',
  39 + selectOptions: [
  40 + {code: '', name: '普通'},
  41 + {code: 'card', name: '立体'},
  42 + ],
  43 + value: ''
  44 + },
  45 + {
  46 + type: 'el-input-number',
  47 + label: '轮播时间',
  48 + name: 'tabTime',
  49 + required: false,
  50 + placeholder: '',
  51 + value: 300000
  52 + },
  53 + [
  54 + {
  55 + name: '地址设置',
  56 + list: [
  57 + // {
  58 + // type: 'el-input-number',
  59 + // label: '',
  60 + // name: 'httpurl',
  61 + // required: false,
  62 + // value: '',
  63 + // },
  64 + ],
  65 + },
  66 + ],
  67 + ],
  68 + data:[],
  69 + // 坐标
  70 + position: [
  71 + {
  72 + type: 'el-input-number',
  73 + label: '左边距',
  74 + name: 'left',
  75 + required: false,
  76 + placeholder: '',
  77 + value: 0,
  78 + },
  79 + {
  80 + type: 'el-input-number',
  81 + label: '上边距',
  82 + name: 'top',
  83 + required: false,
  84 + placeholder: '',
  85 + value: 0,
  86 + },
  87 + {
  88 + type: 'el-input-number',
  89 + label: '宽度',
  90 + name: 'width',
  91 + required: false,
  92 + placeholder: '该容器在1920px大屏中的宽度',
  93 + value: 1920,
  94 + },
  95 + {
  96 + type: 'el-input-number',
  97 + label: '高度',
  98 + name: 'height',
  99 + required: false,
  100 + placeholder: '该容器在1080px大屏中的高度',
  101 + value: 1080
  102 + },
  103 + ],
  104 + }
  105 +}
... ...
src/views/bigscreenDesigner/designer/tools/main.js
... ... @@ -45,6 +45,7 @@ import {widgetBorderBoxFloat} from &quot;./configure/div/widget-border-box-float&quot;;
45 45 import {widgetDigitalFlopSingle} from "./configure/texts/widget-digital-flop-single";
46 46 import {widgetSvg} from "./configure/div/widget-svg";
47 47 import {widgetRotateRanking} from "./configure/table/widget-rotate-ranking";
  48 +import {widgetHtmlSlider} from "./configure/div/widget-html-slider";
48 49  
49 50  
50 51 export const widgetTool = [
... ... @@ -97,5 +98,6 @@ export const widgetTool = [
97 98 widgetDigitalFlopSingle,
98 99 widgetSvg,
99 100 widgetRotateRanking,
100   - widgetRadioPiechart
  101 + widgetRadioPiechart,
  102 + widgetHtmlSlider,
101 103 ]
... ...
src/views/bigscreenDesigner/designer/widget/barline/widgetBarLineStackChart.vue
... ... @@ -490,8 +490,10 @@ export default {
490 490 //颜色
491 491 const customColor = optionsSetup.customColor;
492 492 const arrColor = [];
493   - for (let i = 0; i < customColor.length; i++) {
494   - arrColor.push(customColor[i].color);
  493 + if(customColor){
  494 + for (let i = 0; i < customColor.length; i++) {
  495 + arrColor.push(customColor[i].color);
  496 + }
495 497 }
496 498 this.options.xAxis.data = val.xAxis;
497 499 this.options.yAxis.data = [];
... ...
src/views/bigscreenDesigner/designer/widget/div/widgetHtmlSlider.vue 0 → 100644
  1 +<template>
  2 + <div :style="style">
  3 + <el-carousel arrow="always" height="100%" class="carousel" :direction="carouselStyle.direction"
  4 + :indicator-position="carouselStyle.indicatorPosition" :interval="carouselStyle.interval"
  5 + :type="carouselStyle.type" :key="carouselKey">
  6 + <el-carousel-item v-for="(url, index) in carouselStyle.htmlurlList" :key="index">
  7 + <iframe class="carousel-img" :src="url" alt="" />
  8 + </el-carousel-item>
  9 + </el-carousel>
  10 + </div>
  11 +</template>
  12 +<script>
  13 +import Vue from 'vue'
  14 +import iframeResize from 'iframe-resizer/js/iframeResizer'
  15 +Vue.use(iframeResize)
  16 +export default {
  17 + name: 'WidgetHtmlSlider',
  18 + components: {},
  19 + props: {
  20 + value: Object,
  21 + ispreview: Boolean
  22 + },
  23 + data() {
  24 + return {
  25 + options: {},
  26 + carouselKey: 0, // 重新渲染组件用
  27 + };
  28 + },
  29 + mounted () {
  30 + // 内嵌iframe时
  31 + //iframeResize.iframeResizer({log: true,}, this.$refs.iframe);
  32 + this.changeFrameHeight();
  33 + },
  34 + computed: {
  35 + transStyle() {
  36 + return this.objToOne(this.options);
  37 + },
  38 + style() {
  39 + const autoLayer = this.transStyle.autoLayer;
  40 + //整屏显示
  41 + if(autoLayer){
  42 + return {
  43 + position: "absolute",
  44 + height: document.body.clientHeight+ "px",
  45 + width: document.body.clientWidth+ "px",
  46 + left: 0 + "px",
  47 + top: 0 + "px",
  48 + background:""
  49 + };
  50 + }else{
  51 + return {
  52 + position: this.ispreview ? "absolute" : "static",
  53 + background: background,
  54 + width: this.transStyle.width + "px",
  55 + height: this.transStyle.height + "px",
  56 + left: this.transStyle.left + "px",
  57 + top: this.transStyle.top + "px",
  58 + right: this.transStyle.right + "px",
  59 + };
  60 + }
  61 +
  62 + },
  63 + carouselStyle() {
  64 + // console.log(this.transStyle.imageAdress,"1111");
  65 + return {
  66 + //imageList: this.isBlank(this.transStyle.imageAdress)?[]:this.transStyle.imageAdress.split(","),
  67 + htmlurlList: ['http://localhost:8888/#/bigscreen/viewer?reportCode=BI_YS001_1680838448088_1684993969021'],
  68 + //htmlurlList: [],
  69 + //['http://localhost:8888/#/bigscreen/viewer?reportCode=dev_1_1680589693462','http://localhost:8888/#/bigscreen/viewer?reportCode=BI_YS001_1680838448088_1684993969021','http://localhost:8888/#/bigscreen/viewer?reportCode=BI_YS001_1680838448088'],
  70 + direction: !this.transStyle.tabType ? this.transStyle.tabDirection : 'horizontal',
  71 + indicatorPosition: this.transStyle.tabSelector,
  72 + interval: this.transStyle.tabTime,
  73 + type: this.transStyle.tabType
  74 + }
  75 + }
  76 + },
  77 + watch: {
  78 + value: {
  79 + handler(val) {
  80 + this.options = val;
  81 + },
  82 + deep: true
  83 + },
  84 + carouselStyle: {
  85 + handler(newValue, oldValue) {
  86 + if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) {
  87 + this.carouselKey++;
  88 + }
  89 + },
  90 + },
  91 + },
  92 + created() {
  93 + this.options = this.value;
  94 + },
  95 + methods: {
  96 + dianji() {
  97 + //设置后就是id==con_lf_top_div 的容器全屏
  98 + let case1 = document.getElementById("iframeId");
  99 + if (this.fullscreen) {
  100 + if (document.exitFullscreen) {
  101 + document.exitFullscreen();
  102 + } else if (document.webkitCancelFullScreen) {
  103 + document.webkitCancelFullScreen();
  104 + } else if (document.mozCancelFullScreen) {
  105 + document.mozCancelFullScreen();
  106 + } else if (document.msExitFullscreen) {
  107 + document.msExitFullscreen();
  108 + }
  109 + } else {
  110 + if (case1.requestFullscreen) {
  111 + case1.requestFullscreen();
  112 + } else if (case1.webkitRequestFullScreen) {
  113 + case1.webkitRequestFullScreen();
  114 + } else if (case1.mozRequestFullScreen) {
  115 + case1.mozRequestFullScreen();
  116 + } else if (case1.msRequestFullscreen) {
  117 + // IE11
  118 + case1.msRequestFullscreen();
  119 + }
  120 + }
  121 + },
  122 + },
  123 +}
  124 +</script>
  125 +
  126 +<style scoped lang="scss">
  127 +.carousel {
  128 + width: 100%;
  129 + height: 100%;
  130 +}
  131 +
  132 +.carousel-img {
  133 + width: 100%;
  134 + height: 100%;
  135 +}
  136 +</style>
  137 +
... ...
src/views/bigscreenDesigner/designer/widget/pie/widgetPiechart.vue
... ... @@ -236,18 +236,9 @@ export default {
236 236 },
237 237 getEchartData(val) {
238 238 const data = this.queryEchartsData(val);
239   - const arrColorData = [];
240   - for (let i = 0; i < data.length; i++) {
241   - const res = data[i];
  239 + data.then(res => {
242 240 this.renderingFn(res);
243   - if(this.isNotBlank(res.color)){
244   - arrColorData[i]=res.color;
245   - }
246   - }
247   - this.setOptionsColor(arrColorData)
248   - // data.then(res => {
249   - // this.renderingFn(res);
250   - // });
  241 + });
251 242 },
252 243 renderingFn(val) {
253 244 for (const key in this.options.series) {
... ... @@ -255,6 +246,14 @@ export default {
255 246 this.options.series[key].data = val;
256 247 }
257 248 }
  249 + const arrColorData = [];
  250 + for (let i = 0; i < val.length; i++) {
  251 + const res = val[i];
  252 + if(this.isNotBlank(res.color)){
  253 + arrColorData[i]=res.color;
  254 + }
  255 + }
  256 + this.setOptionsColor(arrColorData)
258 257 }
259 258 }
260 259 };
... ...
src/views/bigscreenDesigner/designer/widget/widget.vue
... ... @@ -3,15 +3,16 @@
3 3 :step="step"
4 4 :width="widgetsWidth"
5 5 :height="widgetsHeight"
  6 + :disabled="widgetDisabled"
6 7 :left="widgetsLeft"
7 8 :top="widgetsTop"
8 9 ref="draggable"
9 10 :index="index"
10   - :z-index="-1"
11 11 @focus="handleFocus"
12 12 @blur="handleBlur"
13 13 >
14   - <component :is="type" :value="value" />
  14 + <!-- :z-index="-1" -->
  15 + <component :is="type" :widget-index="index" :value="value" />
15 16 </avue-draggable>
16 17 </template>
17 18  
... ... @@ -115,19 +116,19 @@ export default {
115 116 },
116 117 model: {
117 118 prop: "value",
118   - event: "input"
  119 + event: "input",
119 120 },
120 121 props: {
121 122 /*
122 123 widget-text widget-marquee widget-href widget-time widget-image widget-slider widget-video widget-table widget-iframe widget-universal
123 124 widget-linechart widget-barlinechart widget-piechart widget-hollow-piechart widget-funnel widget-gauge widget-china-map
124 125 */
125   - // 当前组件,在工作区变量widgetInWorkbench中的索引
126   - index: Number,
  126 + index: Number, // 当前组件,在工作区变量widgetInWorkbench中的索引
127 127 type: String,
  128 + bigscreen: Object,
128 129 value: {
129 130 type: [Object],
130   - default: () => {}
  131 + default: () => {},
131 132 },
132 133 step: Number,
133 134 },
... ... @@ -157,7 +158,10 @@ export default {
157 158 },
158 159 widgetsZIndex() {
159 160 return this.value.position.zIndex || 1;
160   - }
  161 + },
  162 + widgetDisabled() {
  163 + return this.value.position.disabled || false;
  164 + },
161 165 },
162 166 mounted() {},
163 167 methods: {
... ...
src/views/bigscreenDesigner/viewer/index.vue
... ... @@ -8,6 +8,7 @@
8 8 v-for="(widget, index) in widgets"
9 9 :key="index"
10 10 v-model="widget.value"
  11 + :index="index"
11 12 :type="widget.type"
12 13 />
13 14 </div>
... ... @@ -62,7 +63,17 @@ export default {
62 63 };
63 64 // 赋值到全局变量
64 65 this.setMasterData(data.dashboard);
65   - //加载其余子组件
  66 + data.dashboard.widgets.forEach((item, index) => {
  67 + item.value.widgetId = item.value.setup.widgetId
  68 + item.value.widgetCode = item.value.setup.widgetCode
  69 + if (item.value.setup.componentLinkage && item.value.setup.componentLinkage.length) {
  70 + this.$store.commit('SET_ALL_COMPONENT_LINKAGE', {
  71 + index,
  72 + widgetId: item.value.widgetId,
  73 + linkageArr: item.value.setup.componentLinkage
  74 + })
  75 + }
  76 + })
66 77 this.widgets = data.dashboard.widgets;
67 78 },
68 79 // 数据处理
... ...