kd-lane-container 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -121,7 +121,11 @@ config: {
121
121
  - **templates**:只需提供 `templateName` 属性
122
122
  - **lane**:不需要提供任何属性
123
123
  - **line**:需要提供以下属性:`paramId`, `min`, `lineSort`, `max`, `lineSize`, `lineColor`, `lineType`, `isUsed`
124
- 示例:`{ paramId: "51", min: 0.001, lineSort: 1, max: 100, lineSize: "2", lineColor: "#E5360B", lineType: "solid", isUsed: "1" }`
124
+ 可选属性:`themeConfig` - 线条级别主题颜色配置,支持为不同主题设置不同的线条颜色;`isGradient` - 是否为渐变线条。当设置为 true 时:
125
+ - lineType 必须为 "area"**避免歧义**
126
+ - lineColor 和 themeConfig 中的 lineColor 应使用 linear-gradient 格式
127
+ - LineEdit 组件中的颜色选择器和线型选择器将被禁用
128
+ 示例:`{ paramId: "52", min: 0.001, max: 100, lineSort: 1, lineSize: "2", lineColor: "linear-gradient(to bottom, blue, red)", lineType: "area", isUsed: "1", isGradient: true, themeConfig: { white: { lineColor: "linear-gradient(to bottom, black, red)" }, dark: { lineColor: "linear-gradient(to bottom, yellow, red)" }, gray: { lineColor: "linear-gradient(to bottom, #E5360B, red)" } } }`
125
129
  - **params**:需要提供以下属性:`paramId`, `paramName`, `paramUnit`
126
130
  示例:`{ paramId: "12", paramName: "钻头位置", paramUnit: "m" }`
127
131
 
@@ -135,13 +139,13 @@ config: {
135
139
  dataSource: {
136
140
  // 嵌套结构示例
137
141
  templates: [
138
- {
142
+ {
139
143
  templateName: "测试",
140
144
  lanes: [
141
145
  {
142
146
  lines: [
143
- { paramId: "51", min: 0.001, lineSort: 1, max: 100, lineSize: "2", lineColor: "#E5360B", lineType: "solid", isUsed: "1" },
144
- { paramId: "52", min: 0, lineSort: 2, max: 50, lineSize: "1", lineColor: "#1890FF", lineType: "dashed", isUsed: "1" }
147
+ { paramId: "51", min: 0.001, lineSort: 1, max: 100, lineSize: "2", lineColor: "#E5360B", lineType: "solid", isUsed: "1", isGradient: false, themeConfig: { white: { lineColor: "blue" }, dark: { lineColor: "black" }, gray: { lineColor: "yellow" } } },
148
+ { paramId: "52", min: 0.001, lineSort: 2, max: 100, lineSize: "2", lineColor: "linear-gradient(to bottom, blue, red)", lineType: "area", isUsed: "1", isGradient: true, themeConfig: { white: { lineColor: "linear-gradient(to bottom, black, red)" }, dark: { lineColor: "linear-gradient(to bottom, yellow, red)" }, gray: { lineColor: "linear-gradient(to bottom, #E5360B, red)" } } }
145
149
  ]
146
150
  }
147
151
  ]
@@ -172,7 +176,7 @@ config: {
172
176
  upsertLine(data) { /* 新增或更新线条 */ },
173
177
  delLine(data) { /* 删除线条 */ },
174
178
 
175
- // 可选方法:恢复默认设置
179
+ // 可选方法:恢复默认设置 【**在local模式下,可以通过this.$refs[xxx].restoreSetting()方法恢复默认设置**】
176
180
  restoreSetting() { /* 恢复默认设置 */ }
177
181
  }
178
182
  ```
@@ -278,13 +282,14 @@ handleCustomMenuClick(event) {
278
282
 
279
283
  ### 5.1 Props
280
284
 
281
- | 属性名 | 类型 | 默认值 | 说明 |
282
- | ---------------- | ------ | ------ | ---------------- |
283
- | config | Object | 必填 | 组件配置对象 |
284
- | headerPadding | Number | 4 | 泳道头部内边距 |
285
- | headerItemHeight | Number | 20 | 头部线条项高度 |
286
- | itemGap | Number | 2 | 线条项之间的间距 |
287
- | customMenuList | Array | [] | 自定义菜单列表 |
285
+ | 属性名 | 类型 | 默认值 | 说明 |
286
+ | ---------------- | ------ | ------- | ------------------ |
287
+ | config | Object | 必填 | 组件配置对象 |
288
+ | headerPadding | Number | 4 | 泳道头部内边距 |
289
+ | headerItemHeight | Number | 20 | 头部线条项高度 |
290
+ | itemGap | Number | 2 | 线条项之间的间距 |
291
+ | customMenuList | Array | [] | 自定义菜单列表 |
292
+ | themeName | String | "white" | 当前使用的主题名称 |
288
293
 
289
294
  ### 5.2 事件
290
295
 
@@ -399,20 +404,87 @@ handleCustomMenuClick(event) {
399
404
  </template>
400
405
  ```
401
406
 
402
- ## 7. 样式定制
407
+ ## 7. 主题颜色设置
403
408
 
404
- 可以通过 CSS 变量或直接覆盖样式来自定义组件外观:
409
+ ### 7.1 组件主题属性
405
410
 
406
- ```css
407
- .kd-lane-chart-container {
408
- --kd-lane-container-border-color: white;
409
- --kd-lane-container-context-background-color: darkgray;
410
- --kd-lane-container-context-hover-color: darkgray;
411
- --kd-lane-container-header-item-color: white;
412
- --app-background-color: gray;
411
+ 组件支持通过 `themeName` 属性设置当前主题,可选值包括 `white`、`dark` 和 `gray`。
412
+
413
+ ```vue
414
+ <KdLaneChartContainer
415
+ :themeName="themeName"
416
+ ...
417
+ >
418
+ ```
419
+
420
+ ### 7.2 线条级别主题配置
421
+
422
+ 每个线条对象可以通过 `themeConfig` 属性配置不同主题下的颜色,格式为:
423
+
424
+ ```javascript
425
+ themeConfig: {
426
+ [themeName]: { lineColor: "颜色值" },
427
+ ...
413
428
  }
414
429
  ```
415
430
 
431
+ 示例:
432
+
433
+ ```javascript
434
+ lines: [
435
+ {
436
+ paramId: "51",
437
+ lineColor: "#E5360B", // 默认颜色
438
+ themeConfig: {
439
+ white: { lineColor: "blue" }, // 白色主题颜色
440
+ dark: { lineColor: "black" }, // 暗黑主题颜色
441
+ gray: { lineColor: "yellow" }, // 灰色主题颜色
442
+ },
443
+ },
444
+ ];
445
+ ```
446
+
447
+ 当组件的 `themeName` 变化时,线条会自动应用对应主题的颜色。如果未配置 `themeConfig`,则使用默认的 `lineColor`。
448
+
449
+ ### 7.3 主题切换示例
450
+
451
+ ````vue
452
+ <template>
453
+ <div id="app">
454
+ <KdLaneChartContainer class="container" :config="config" :themeName="themeName" ...>
455
+ <!-- 插槽内容 -->
456
+ </KdLaneChartContainer>
457
+ <div style="display: flex">
458
+ <button @click="changeCheme('white')">white</button>
459
+ <button @click="changeCheme('dark')">dark</button>
460
+ <button @click="changeCheme('gray')">gray</button>
461
+ </div>
462
+ </div>
463
+ </template>
464
+
465
+ <script>
466
+ export default {
467
+ data() {
468
+ return {
469
+ themeName: "white", // 默认主题
470
+ // ...其他配置
471
+ };
472
+ },
473
+ methods: {
474
+ changeCheme(themeName) {
475
+ this.themeName = themeName;
476
+ // 可选:给body设置data-theme属性,用于全局样式切换
477
+ document.body.setAttribute("data-theme", themeName);
478
+ },
479
+ },
480
+ };
481
+ </script>
482
+
483
+ ## 8. 样式定制 可以通过 CSS 变量或直接覆盖样式来自定义组件外观: ```css .kd-lane-chart-container { --kd-lane-container-border-color: white;
484
+ --kd-lane-container-context-background-color: darkgray; --kd-lane-container-context-hover-color: darkgray;
485
+ --kd-lane-container-header-item-color: white; --app-background-color: gray; }
486
+ ````
487
+
416
488
  ## 8. 使用示例
417
489
 
418
490
  ```vue
package/dist/cjs/index.js CHANGED
@@ -2593,6 +2593,7 @@ var __vue_render__$3 = function () {
2593
2593
  },
2594
2594
  [
2595
2595
  _c("el-color-picker", {
2596
+ attrs: { disabled: _vm.formData.isGradient },
2596
2597
  model: {
2597
2598
  value: _vm.formData.lineColor,
2598
2599
  callback: function ($$v) {
@@ -2618,7 +2619,10 @@ var __vue_render__$3 = function () {
2618
2619
  _c(
2619
2620
  "el-select",
2620
2621
  {
2621
- attrs: { placeholder: "请选择" },
2622
+ attrs: {
2623
+ placeholder: "请选择",
2624
+ disabled: _vm.formData.isGradient,
2625
+ },
2622
2626
  model: {
2623
2627
  value: _vm.formData.lineType,
2624
2628
  callback: function ($$v) {
@@ -3314,6 +3318,7 @@ __vue_render__$2._withStripped = true;
3314
3318
  //
3315
3319
  //
3316
3320
  //
3321
+ //
3317
3322
 
3318
3323
  var script$1 = {
3319
3324
  props: {
@@ -3330,6 +3335,10 @@ var script$1 = {
3330
3335
  default: () => {},
3331
3336
  required: true,
3332
3337
  },
3338
+ themeName: {
3339
+ type: String,
3340
+ default: undefined,
3341
+ },
3333
3342
  },
3334
3343
  methods: {
3335
3344
  getParamName(line) {
@@ -3353,17 +3362,44 @@ var script$1 = {
3353
3362
  },
3354
3363
  },
3355
3364
  computed: {
3365
+ gradientDisplay() {
3366
+ let lineColor;
3367
+ if (this.themeName && this.line.themeConfig) {
3368
+ lineColor = this.line.themeConfig[this.themeName]?.lineColor;
3369
+ }
3370
+ let result;
3371
+ if (this.line.isGradient) {
3372
+ result = { background: `${lineColor || this.line.lineColor}` };
3373
+ } else {
3374
+ result = {};
3375
+ }
3376
+ return result;
3377
+ },
3356
3378
  textColor() {
3379
+ let lineColor;
3380
+ // 只有不是渐变色时,才从主题配置中获取文字颜色
3381
+ if (this.themeName && this.line.themeConfig && !this.line.isGradient) {
3382
+ lineColor = this.line.themeConfig[this.themeName]?.lineColor;
3383
+ }
3357
3384
  return {
3358
- color: this.line.lineColor,
3385
+ color: lineColor || this.line.lineColor,
3359
3386
  };
3360
3387
  },
3361
3388
  headerItemStyle() {
3389
+ let lineColor;
3390
+ if (this.themeName && this.line.themeConfig) {
3391
+ lineColor = this.line.themeConfig[this.themeName]?.lineColor;
3392
+ }
3393
+
3362
3394
  let lineType;
3363
3395
  if (this.line.lineType == "area") {
3364
- lineType = { "box-shadow": `inset 0 0 8px 0px ${this.line.lineColor}` };
3396
+ if (this.line.isGradient) {
3397
+ lineType = {};
3398
+ } else {
3399
+ lineType = { "box-shadow": `inset 0 0 8px 0px ${lineColor || this.line.lineColor}` };
3400
+ }
3365
3401
  } else {
3366
- lineType = { "border-bottom": `2px ${this.line.lineType} ${this.line.lineColor}` };
3402
+ lineType = { "border-bottom": `2px ${this.line.lineType} ${lineColor || this.line.lineColor}` };
3367
3403
  }
3368
3404
  return {
3369
3405
  height: `${this.itemHeight}px`,
@@ -3375,7 +3411,7 @@ var script$1 = {
3375
3411
  watch: {},
3376
3412
  };
3377
3413
 
3378
- var css_248z$1 = "@charset \"UTF-8\";\n.kd-lane-chart-container-header-item {\n color: var(--kd-lane-container-header-item-color, #333);\n border: unset;\n position: relative;\n cursor: pointer;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container {\n height: 100%;\n width: 100%;\n font-size: 10px;\n font-weight: bold;\n position: relative;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .left {\n position: absolute;\n left: 0;\n bottom: 2px;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .center {\n position: absolute;\n left: 50%;\n bottom: 2px;\n transform: translateX(-50%);\n /* 文字不换行,超出显示省略号 */\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .right {\n position: absolute;\n right: 0;\n bottom: 2px;\n}";
3414
+ var css_248z$1 = "@charset \"UTF-8\";\n.kd-lane-chart-container-header-item {\n color: var(--kd-lane-container-header-item-color, #333);\n border: unset;\n position: relative;\n cursor: pointer;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container {\n height: 100%;\n width: 100%;\n font-size: 10px;\n font-weight: bold;\n position: relative;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .left {\n position: absolute;\n left: 0;\n bottom: 2px;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .center {\n position: absolute;\n left: 50%;\n bottom: 2px;\n transform: translateX(-50%);\n /* 文字不换行,超出显示省略号 */\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .right {\n position: absolute;\n right: 0;\n bottom: 2px;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .gradient-display {\n position: absolute;\n height: 2px;\n left: 0;\n bottom: 0;\n right: 0;\n}";
3379
3415
  styleInject(css_248z$1);
3380
3416
 
3381
3417
  /* script */
@@ -3405,6 +3441,11 @@ var __vue_render__$1 = function () {
3405
3441
  _c("span", { staticClass: "right", style: _vm.textColor }, [
3406
3442
  _vm._v(_vm._s(_vm.line.max)),
3407
3443
  ]),
3444
+ _vm._v(" "),
3445
+ _c("div", {
3446
+ staticClass: "gradient-display",
3447
+ style: _vm.gradientDisplay,
3448
+ }),
3408
3449
  ]),
3409
3450
  ]
3410
3451
  )
@@ -3486,6 +3527,10 @@ var script = {
3486
3527
  return [];
3487
3528
  },
3488
3529
  },
3530
+ themeName: {
3531
+ type: String,
3532
+ default: undefined,
3533
+ },
3489
3534
  },
3490
3535
  data() {
3491
3536
  return {
@@ -3702,15 +3747,18 @@ var script = {
3702
3747
  if (option.key == "editTemplate") {
3703
3748
  this.curveConfigVisible = true;
3704
3749
  } else if (option.key == "restoreSetting") {
3705
- return this.strategy.restoreSetting().then(() => {
3706
- this.loadConfig();
3707
- });
3750
+ return this.restoreSetting();
3708
3751
  }
3709
3752
  } else {
3710
3753
  // 自定义菜单按钮
3711
3754
  this.$emit("onCustomMenuClicked", event);
3712
3755
  }
3713
3756
  },
3757
+ restoreSetting() {
3758
+ return this.strategy.restoreSetting().then(() => {
3759
+ this.loadConfig();
3760
+ });
3761
+ },
3714
3762
  loadConfig() {
3715
3763
  this.isLoading = true;
3716
3764
  this.strategy
@@ -3798,6 +3846,23 @@ var script = {
3798
3846
  }
3799
3847
  }
3800
3848
  },
3849
+ slotHeaderStyle() {
3850
+ // return { height: "30%", "min-height": "60px" };
3851
+ if (!this.currentTemplate) {
3852
+ return { height: "30%", "min-height": "60px" };
3853
+ } else {
3854
+ const { lanes = [] } = this.currentTemplate;
3855
+ if (!lanes || lanes.length == 0) {
3856
+ return { height: "30%", "min-height": "60px" };
3857
+ } else {
3858
+ const gapCount = Math.max(0, this.lineCount - 1);
3859
+ return {
3860
+ height: `${this.lineCount * this.headerItemHeight + this.headerPadding * 2 + gapCount * this.itemGap}px`,
3861
+ "min-height": "60px",
3862
+ };
3863
+ }
3864
+ }
3865
+ },
3801
3866
  darwAreaStyle() {
3802
3867
  const headerStyle = this.headerStyle;
3803
3868
  const height = headerStyle.height;
@@ -3806,7 +3871,7 @@ var script = {
3806
3871
  },
3807
3872
  };
3808
3873
 
3809
- var css_248z = ".kd-lane-chart-container {\n --border-color: var(--kd-lane-container-border-color, #333);\n --context-background-color: var(--kd-lane-container-context-background-color, #ecf0f1);\n --context-hover-color: var(--kd-lane-container-context-hover-color, #007aff);\n height: 100%;\n width: 100%;\n overflow: hidden;\n position: relative;\n border: 1px solid var(--border-color);\n display: flex;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-slot-container, .kd-lane-chart-container .kd-lane-chart-lane-container {\n height: 100%;\n min-width: 0;\n overflow: hidden;\n z-index: 1;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-slot-container .kd-lane-chart-lane-header, .kd-lane-chart-container .kd-lane-chart-lane-container .kd-lane-chart-lane-header {\n padding: 4px;\n max-height: 40%;\n border-bottom: 1px solid var(--border-color);\n overflow: hidden;\n z-index: 2;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-container {\n flex: 1;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-slot-container {\n width: auto;\n}\n.kd-lane-chart-container .border-left {\n border-left: 1px solid var(--border-color);\n}\n.kd-lane-chart-container .kd-lane-chart-container-draw-area {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n border: none;\n}\n.kd-lane-chart-container .vue-simple-context-menu {\n background-color: var(--context-background-color);\n position: fixed;\n}\n.kd-lane-chart-container .vue-simple-context-menu .vue-simple-context-menu__item:hover {\n background: var(--context-hover-color);\n}";
3874
+ var css_248z = ".kd-lane-chart-container {\n --border-color: var(--kd-lane-container-border-color, #333);\n --context-background-color: var(--kd-lane-container-context-background-color, #ecf0f1);\n --context-hover-color: var(--kd-lane-container-context-hover-color, #007aff);\n height: 100%;\n width: 100%;\n overflow: hidden;\n position: relative;\n border: 1px solid var(--border-color);\n display: flex;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-slot-container, .kd-lane-chart-container .kd-lane-chart-lane-container {\n height: 100%;\n min-width: 0;\n overflow: hidden;\n z-index: 1;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-slot-container .kd-lane-chart-lane-header, .kd-lane-chart-container .kd-lane-chart-lane-container .kd-lane-chart-lane-header {\n max-height: 40%;\n border-bottom: 1px solid var(--border-color);\n overflow: hidden;\n z-index: 2;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-container {\n flex: 1;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-slot-container {\n width: auto;\n}\n.kd-lane-chart-container .border-left {\n border-left: 1px solid var(--border-color);\n}\n.kd-lane-chart-container .kd-lane-chart-container-draw-area {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n border: none;\n}\n.kd-lane-chart-container .vue-simple-context-menu {\n background-color: var(--context-background-color);\n position: fixed;\n}\n.kd-lane-chart-container .vue-simple-context-menu .vue-simple-context-menu__item:hover {\n background: var(--context-hover-color);\n}";
3810
3875
  styleInject(css_248z);
3811
3876
 
3812
3877
  /* script */
@@ -3850,7 +3915,7 @@ var __vue_render__ = function () {
3850
3915
  "div",
3851
3916
  {
3852
3917
  staticClass: "kd-lane-chart-lane-header",
3853
- style: _vm.headerStyle,
3918
+ style: _vm.slotHeaderStyle,
3854
3919
  },
3855
3920
  [_vm._t("lane" + lane.laneId, null, { lane: lane })],
3856
3921
  2
@@ -3870,7 +3935,7 @@ var __vue_render__ = function () {
3870
3935
  "div",
3871
3936
  {
3872
3937
  staticClass: "kd-lane-chart-lane-header",
3873
- style: _vm.headerStyle,
3938
+ style: _vm.slotHeaderStyle,
3874
3939
  },
3875
3940
  [_vm._t("lane" + lane.laneId, null, { lane: lane })],
3876
3941
  2
@@ -3905,6 +3970,7 @@ var __vue_render__ = function () {
3905
3970
  itemHeight: _vm.headerItemHeight,
3906
3971
  line: line,
3907
3972
  paramsNameMap: _vm.paramsNameMap,
3973
+ themeName: _vm.themeName,
3908
3974
  },
3909
3975
  on: { updateLine: _vm.upsertLine },
3910
3976
  nativeOn: {
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("v-click-outside"),require("vue")):"function"==typeof define&&define.amd?define(["v-click-outside","vue"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).KdLaneChartContainer=t(e.vClickOutside,e.Vue)}(this,function(e,t){"use strict";function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var a=n(e),r=n(t);function s(e,t){void 0===t&&(t={});var n=t.insertAt;if(e&&"undefined"!=typeof document){var a=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css","top"===n&&a.firstChild?a.insertBefore(r,a.firstChild):a.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e))}}function i(e,t,n,a,r,s,i,o,l,d){"boolean"!=typeof i&&(l=o,o=i,i=!1);var c,m="function"==typeof n?n.options:n;if(e&&e.render&&(m.render=e.render,m.staticRenderFns=e.staticRenderFns,m._compiled=!0,r&&(m.functional=!0)),a&&(m._scopeId=a),s?(c=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),t&&t.call(this,l(e)),e&&e._registeredComponents&&e._registeredComponents.add(s)},m._ssrRegister=c):t&&(c=i?function(e){t.call(this,d(e,this.$root.$options.shadowRoot))}:function(e){t.call(this,o(e))}),c)if(m.functional){var p=m.render;m.render=function(e,t){return c.call(t),p(e,t)}}else{var h=m.beforeCreate;m.beforeCreate=h?[].concat(h,c):[c]}return n}s('.vue-simple-context-menu {\n top: 0;\n left: 0;\n margin: 0;\n padding: 0;\n display: none;\n list-style: none;\n position: absolute;\n z-index: 1000000;\n background-color: #ecf0f1;\n border-bottom-width: 0px;\n font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;\n box-shadow: 0 3px 6px 0 rgba(51, 51, 51, 0.2);\n border-radius: 4px;\n}\n.vue-simple-context-menu--active {\n display: block;\n}\n.vue-simple-context-menu__item {\n display: flex;\n color: #333;\n cursor: pointer;\n padding: 5px 15px;\n align-items: center;\n}\n.vue-simple-context-menu__item:hover {\n background-color: #007aff;\n color: #fff;\n}\n.vue-simple-context-menu__divider {\n box-sizing: content-box;\n height: 2px;\n background-color: #c0cdd1;\n padding: 4px 0;\n background-clip: content-box;\n pointer-events: none;\n}\n.vue-simple-context-menu li:first-of-type {\n margin-top: 4px;\n}\n.vue-simple-context-menu li:last-of-type {\n margin-bottom: 4px;\n}'),r.default.use(a.default);var o={name:"VueSimpleContextMenu",props:{elementId:{type:String,required:!0},options:{type:Array,required:!0}},data:function(){return{item:null,menuWidth:null,menuHeight:null}},methods:{showMenu:function(e,t){this.item=t;var n=document.getElementById(this.elementId);n&&(this.menuWidth&&this.menuHeight||(n.style.visibility="hidden",n.style.display="block",this.menuWidth=n.offsetWidth,this.menuHeight=n.offsetHeight,n.removeAttribute("style")),this.menuWidth+e.pageX>=window.innerWidth?n.style.left=e.pageX-this.menuWidth+2+"px":n.style.left=e.pageX-2+"px",this.menuHeight+e.pageY>=window.innerHeight?n.style.top=e.pageY-this.menuHeight+2+"px":n.style.top=e.pageY-2+"px",n.classList.add("vue-simple-context-menu--active"))},hideContextMenu:function(){var e=document.getElementById(this.elementId);e&&(e.classList.remove("vue-simple-context-menu--active"),this.$emit("menu-closed"))},onClickOutside:function(){this.hideContextMenu()},optionClicked:function(e){this.hideContextMenu(),this.$emit("option-clicked",{item:this.item,option:e})},onEscKeyRelease:function(e){27===e.keyCode&&this.hideContextMenu()}},mounted:function(){document.body.addEventListener("keyup",this.onEscKeyRelease)},beforeDestroy:function(){document.removeEventListener("keyup",this.onEscKeyRelease)}},l=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",[n("ul",{directives:[{name:"click-outside",rawName:"v-click-outside",value:e.onClickOutside,expression:"onClickOutside"}],staticClass:"vue-simple-context-menu",attrs:{id:e.elementId}},e._l(e.options,function(t,a){return n("li",{key:a,staticClass:"vue-simple-context-menu__item",class:[t.class,"divider"===t.type?"vue-simple-context-menu__divider":""],on:{click:function(n){return n.stopPropagation(),e.optionClicked(t)}}},[n("span",{domProps:{innerHTML:e._s(t.name)}})])}),0)])};l._withStripped=!0;var d=i({render:l,staticRenderFns:[]},undefined,o,undefined,false,undefined,!1,void 0,void 0,void 0);var c={install:function e(t){e.installed||(e.installed=!0,t.component("VueSimpleContextMenu",d))}},m=null;"undefined"!=typeof window?m=window.Vue:"undefined"!=typeof global&&(m=global.Vue),m&&m.use(c);class p{constructor(e){this.strategy=e}getUserTemplates(){return this.strategy.getUserTemplates()}upsertTemplate(e){return this.strategy.upsertTemplate(e)}delTemplate(e){return this.strategy.deleteTemplate(e)}upsertLane(e){return this.strategy.upsertLane(e)}delLane(e){return this.strategy.deleteLane(e)}upsertLine(e){return this.strategy.upsertLine(e)}delLine(e){return this.strategy.delLine(e)}restoreSetting(){return this.strategy.restoreSetting?this.strategy.restoreSetting():Promise.resolve()}}class h{static DB_NAME="KDLaneChartContainerConfigDB";static MAX_UNICODE_CHAR="￿";static DB_VERSION=2;static STORE_NAMES={TEMPLATES:"templates",LANES:"lanes",LINES:"lines",PARAMS:"params",CASE_VERSIONS:"case_versions"};_db=null;_openDB(){return new Promise((e,t)=>{if(this._db)return void e(this._db);const n=indexedDB.open(h.DB_NAME,h.DB_VERSION);n.onupgradeneeded=e=>{const t=e.target.result,{STORE_NAMES:n}=h;t.objectStoreNames.contains(n.CASE_VERSIONS)||t.createObjectStore(n.CASE_VERSIONS,{keyPath:"caseId"}),t.objectStoreNames.contains(n.TEMPLATES)||t.createObjectStore(n.TEMPLATES,{keyPath:["caseId","templateId"]}),t.objectStoreNames.contains(n.LANES)||t.createObjectStore(n.LANES,{keyPath:["caseId","laneId"]}),t.objectStoreNames.contains(n.LINES)||t.createObjectStore(n.LINES,{keyPath:["caseId","lineId"]}),t.objectStoreNames.contains(n.PARAMS)||t.createObjectStore(n.PARAMS,{keyPath:["caseId","paramId"]})},n.onsuccess=t=>{this._db=t.target.result,this._db.onclose=()=>{this._db=null},e(this._db)},n.onerror=e=>{t(new Error(`打开数据库失败:${e.target.error.message}`))},n.onblocked=()=>{t(new Error("数据库操作被阻塞,请关闭其他标签页后重试"))}})}closeDB(){return new Promise(e=>{this._db&&(this._db.close(),this._db=null),e()})}_compareVersion(e,t){const n=e=>String(e).split(".").map(Number),a=n(e),r=n(t),s=Math.max(a.length,r.length);for(let e=0;e<s;e++){const t=a[e]||0,n=r[e]||0;if(t>n)return 1;if(t<n)return-1}return 0}_clearSceneData(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([h.STORE_NAMES.CASE_VERSIONS,h.STORE_NAMES.TEMPLATES,h.STORE_NAMES.LANES,h.STORE_NAMES.LINES,h.STORE_NAMES.PARAMS],"readwrite"),s=r.objectStore(h.STORE_NAMES.TEMPLATES),i=r.objectStore(h.STORE_NAMES.LANES),o=r.objectStore(h.STORE_NAMES.LINES),l=r.objectStore(h.STORE_NAMES.CASE_VERSIONS),d=r.objectStore(h.STORE_NAMES.PARAMS),c=IDBKeyRange.bound([e],[e,h.MAX_UNICODE_CHAR]);s.delete(c),i.delete(c),o.delete(c),d.delete(c),l.delete(e),r.oncomplete=()=>n(),r.onerror=e=>a(new Error(`事务失败:${e.target.error.message}`))}))}_promisifyRequest(e){return new Promise((t,n)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>n(e.error)})}forceInitSceneConfig(e,t,n){return e&&t?this._clearSceneData(e).then(()=>{const a=this.setUpData(e,t,n);return this.batchAddConfig(a)}).catch(e=>{throw new Error(`强制初始化场景配置失败:${e.message}`)}):Promise.reject(new Error("caseId和versionCode为强制初始化的必传参数"))}setUpData(e,t,n){const a=n.templates.map(t=>({...t,caseId:e})),r=n.lanes.map(t=>({...t,caseId:e})),s=n.lines.map(t=>({...t,caseId:e})),i=n.params.map(t=>({...t,caseId:e}));return{caseVersion:{caseId:e,versionCode:t,updateTime:new Date},templates:a,lanes:r,lines:s,params:i}}checkConfigIntegrity(e,t){return this.getCaseVersionByCaseId(e).then(n=>!(!n||n.versionCode!==t)&&this.getTemplatesByCaseId(e).then(t=>{if(0===t.length)return!0;const n=t[0].templateId;return this.getLanesByTemplateId(e,n).then(t=>{if(0===t.length)return!0;const n=t[0].laneId;return this.getLinesByLaneId(e,n).then(e=>0===e.length)})}))}_initSceneConfig(e){const{caseVersion:t}=e,{caseId:n,versionCode:a}=t;return this.getCaseVersionByCaseId(n).then(t=>{if(!t)return this.batchAddConfig(e);const r=this._compareVersion(a,t.versionCode);if(r>0)return this._clearSceneData(n).then(()=>this.batchAddConfig(e));if(0===r)return console.log(`场景${n}已存在版本${a},无需重复创建`),Promise.resolve(t);throw new Error(`场景${n}当前版本${t.versionCode}高于待创建版本${a}。`)})}saveSceneConfig(e,t,n){if(!e||!t)return Promise.reject(new Error("caseId和versionCode为必传参数"));if(!Array.isArray(n.templates)||!Array.isArray(n.lanes)||!Array.isArray(n.lines))return Promise.reject(new Error("templates/lanes/lines必须为数组"));const a=this.setUpData(e,t,n);return this._initSceneConfig(a)}batchAddConfig(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([h.STORE_NAMES.CASE_VERSIONS,h.STORE_NAMES.TEMPLATES,h.STORE_NAMES.LANES,h.STORE_NAMES.LINES,h.STORE_NAMES.PARAMS],"readwrite");r.objectStore(h.STORE_NAMES.CASE_VERSIONS).put(e.caseVersion);const s=r.objectStore(h.STORE_NAMES.TEMPLATES);e.templates.forEach(e=>s.put(e));const i=r.objectStore(h.STORE_NAMES.LANES);e.lanes.forEach(e=>i.put(e));const o=r.objectStore(h.STORE_NAMES.LINES);e.lines.forEach(e=>o.put(e));const l=r.objectStore(h.STORE_NAMES.PARAMS);e.params.forEach(e=>l.put(e)),r.oncomplete=()=>n(e),r.onerror=e=>a(new Error(`批量添加配置失败:${e.target.error.message}`))}))}upsertCaseVersion(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([h.STORE_NAMES.CASE_VERSIONS],"readwrite").objectStore(h.STORE_NAMES.CASE_VERSIONS),s={updateTime:new Date,...e};this._promisifyRequest(r.put(s)).then(()=>n(s)).catch(e=>a(new Error(`更新场景版本失败:${e.message}`)))}))}getCaseVersionByCaseId(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([h.STORE_NAMES.CASE_VERSIONS],"readonly").objectStore(h.STORE_NAMES.CASE_VERSIONS);this._promisifyRequest(r.get(e)).then(e=>n(e||null)).catch(e=>a(new Error(`查询场景版本失败:${e.message}`)))}))}getConfigByCaseId(e){return e?Promise.all([this.getCaseVersionByCaseId(e),this.getTemplatesByCaseId(e),this.getParamsByCaseId(e)]).then(([t,n,a])=>{const r=n.map(t=>this.getLanesByTemplateId(e,t.templateId).then(n=>{const a=n.map(t=>this.getLinesByLaneId(e,t.laneId).then(e=>({...t,lines:e})));return Promise.all(a).then(e=>({...t,lanes:e}))}));return Promise.all(r).then(e=>({caseVersion:t,templates:e,params:a}))}).catch(e=>{throw new Error(`查询场景配置失败:${e.message}`)}):Promise.reject(new Error("caseId为必传参数"))}getConfigByTemplateId(e,t){if(!e||!t)return Promise.reject(new Error("caseId为必传参数"));const n={};return this.getLanesByTemplateId(e,t).then(t=>{const a=t.map(t=>this.getLinesByLaneId(e,t.laneId));return Promise.all(a).then(e=>{e.forEach((e,n)=>{t[n].lines=e}),n.lanes=t})}).then(()=>this.getTemplateById(e,t)).then(e=>(e.lanes=n.lanes,Promise.resolve(e)))}deleteCaseVersion(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([h.STORE_NAMES.CASE_VERSIONS],"readwrite").objectStore(h.STORE_NAMES.CASE_VERSIONS);this._promisifyRequest(r.delete(e)).then(()=>n()).catch(e=>a(new Error(`删除场景版本失败:${e.message}`)))}))}upsertTemplate(e){return this._openDB().then(t=>new Promise((n,a)=>{if(!e.caseId)return void a(new Error("模板数据必须包含caseId"));const r=t.transaction([h.STORE_NAMES.TEMPLATES],"readwrite").objectStore(h.STORE_NAMES.TEMPLATES),s={...e,createDate:e.createDate?new Date(e.createDate):new Date,updateDate:e.updateDate?new Date(e.updateDate):null};return delete s.lanes,this._promisifyRequest(r.put(s)).then(()=>n(s)).catch(e=>a(new Error(`更新模板失败:${e.message}`)))}))}getTemplateById(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([h.STORE_NAMES.TEMPLATES],"readonly").objectStore(h.STORE_NAMES.TEMPLATES);this._promisifyRequest(s.get([e,t])).then(e=>a(e||null)).catch(e=>r(new Error(`查询模板失败:${e.message}`)))}))}getTemplatesByCaseId(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([h.STORE_NAMES.TEMPLATES],"readonly").objectStore(h.STORE_NAMES.TEMPLATES),s=IDBKeyRange.bound([e],[e,h.MAX_UNICODE_CHAR]);this._promisifyRequest(r.getAll(s)).then(e=>{n(e||[])}).catch(e=>a(new Error(`查询场景下模板失败:${e.message}`)))}))}deleteTemplate(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([h.STORE_NAMES.TEMPLATES],"readwrite").objectStore(h.STORE_NAMES.TEMPLATES);this._promisifyRequest(s.delete([e,t])).then(()=>a()).catch(e=>r(new Error(`删除模板失败:${e.message}`)))}))}upsertLane(e,t){return this._openDB().then(n=>new Promise((a,r)=>{if(!e||!t.templateId)return void r(new Error("泳道数据必须包含caseId和templateId"));const s=n.transaction([h.STORE_NAMES.LANES],"readwrite").objectStore(h.STORE_NAMES.LANES),i={...t,caseId:e,updateDate:t.updateDate?new Date(t.updateDate):new Date};this._promisifyRequest(s.put(i)).then(()=>a(i)).catch(e=>r(new Error(`更新泳道失败:${e.message}`)))}))}getLaneById(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([h.STORE_NAMES.LANES],"readonly").objectStore(h.STORE_NAMES.LANES);this._promisifyRequest(s.get([e,t])).then(e=>a(e||null)).catch(e=>r(new Error(`查询泳道失败:${e.message}`)))}))}getLanesByTemplateId(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([h.STORE_NAMES.LANES],"readonly").objectStore(h.STORE_NAMES.LANES),i=IDBKeyRange.bound([e],[e,h.MAX_UNICODE_CHAR]);this._promisifyRequest(s.getAll(i)).then(e=>e.filter(e=>e.templateId===t)).then(e=>a(e||[])).catch(e=>r(new Error(`查询模板下泳道失败:${e.message}`)))}))}deleteLaneByLaneIds(e,t){return Array.isArray(t)&&0!==t.length?this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([h.STORE_NAMES.LANES],"readwrite"),i=s.objectStore(h.STORE_NAMES.LANES);t.map(t=>this._promisifyRequest(i.delete([e,t]))),s.oncomplete=()=>a(),s.onerror=e=>r(new Error(`删除泳道失败:${e.target.error.message}`))})):Promise.resolve()}upsertLine(e,t){return this._openDB().then(n=>new Promise((a,r)=>{if(!e||!t.laneId)return void r(new Error("线条数据必须包含caseId和laneId"));const s=n.transaction([h.STORE_NAMES.LINES],"readwrite").objectStore(h.STORE_NAMES.LINES),i={...t,caseId:e,updateDate:t.updateDate?new Date(t.updateDate):new Date};this._promisifyRequest(s.put(i)).then(()=>a(i)).catch(e=>r(new Error(`更新线条失败:${e.message}`)))}))}getLineById(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([h.STORE_NAMES.LINES],"readonly").objectStore(h.STORE_NAMES.LINES);this._promisifyRequest(s.get([e,t])).then(e=>a(e||null)).catch(e=>r(new Error(`查询线条失败:${e.message}`)))}))}getLinesByLaneId(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([h.STORE_NAMES.LINES],"readonly").objectStore(h.STORE_NAMES.LINES),i=IDBKeyRange.bound([e],[e,h.MAX_UNICODE_CHAR]);this._promisifyRequest(s.getAll(i)).then(e=>e.filter(e=>e.laneId===t)).then(e=>a(e||[])).catch(e=>r(new Error(`查询泳道下线条失败:${e.message}`)))}))}deleteLineByIds(e,t){return Array.isArray(t)&&0!==t.length?this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([h.STORE_NAMES.LINES],"readwrite"),i=s.objectStore(h.STORE_NAMES.LINES);t.map(t=>this._promisifyRequest(i.delete([e,t]))),s.oncomplete=()=>a(),s.onerror=e=>r(new Error(`批量删除线条失败:${e.target.error.message}`))})):Promise.resolve()}upsertParam(e){return this._openDB().then(t=>new Promise((n,a)=>{if(!e.caseId)return void a(new Error("参数数据必须包含caseId"));const r=t.transaction([h.STORE_NAMES.PARAMS],"readwrite").objectStore(h.STORE_NAMES.PARAMS),s={...e,updateDate:e.updateDate?new Date(e.updateDate):new Date};this._promisifyRequest(r.put(s)).then(()=>n(s)).catch(e=>a(new Error(`更新参数失败:${e.message}`)))}))}getParamById(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([h.STORE_NAMES.PARAMS],"readonly").objectStore(h.STORE_NAMES.PARAMS);this._promisifyRequest(s.get([e,t])).then(e=>a(e||null)).catch(e=>r(new Error(`查询参数失败:${e.message}`)))}))}getParamsByCaseId(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([h.STORE_NAMES.PARAMS],"readonly").objectStore(h.STORE_NAMES.PARAMS),s=IDBKeyRange.bound([e],[e,h.MAX_UNICODE_CHAR]);this._promisifyRequest(r.getAll(s)).then(e=>n(e||[])).catch(e=>a(new Error(`查询场景下参数失败:${e.message}`)))}))}deleteParamById(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([h.STORE_NAMES.PARAMS],"readwrite").objectStore(h.STORE_NAMES.PARAMS);this._promisifyRequest(s.delete([e,t])).then(()=>a()).catch(e=>r(new Error(`删除参数失败:${e.message}`)))}))}}const u=new h;function f(e){e&&Array.isArray(e.lines)&&e.lines.sort((e,t)=>(e.lineSort??0)-(t.lineSort??0))}function g(e){Array.isArray(e)&&(e.sort((e,t)=>(e.sort??0)-(t.sort??0)),e.forEach(e=>f(e)))}function S(e){return Array.isArray(e)&&0!==e.length?(e.sort((e,t)=>(e.sort??0)-(t.sort??0)),e.forEach(e=>g(e.lanes)),e):e}function y(e){return e?e.lineId&&e.laneId?"line":e.laneId&&e.templateId&&!e.lineId?"lane":e.templateId?"template":null:null}function v(e=!0){let t="";return t="undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}),e?t.replace(/-/g,""):t}class b{constructor(e,t,n,a=!0){this.caseId=e,this.versionCode=t,this.dataSource=n,this.flatData=a,this.ready=u.saveSceneConfig(e,t,n).catch(a=>(console.warn(`初始化数据库出错,直接重置:${a.message}`),u.forceInitSceneConfig(e,t,n)))}getUserTemplates(){return this.ready.then(()=>u.getConfigByCaseId(this.caseId))}upsertTemplate(e){let t;if(e.templateId)t=u.upsertTemplate(e);else{const n=v();if(e.templateId=n,e.baseTemplate){const a={};t=u.getLanesByTemplateId(this.caseId,e.baseTemplate).then(e=>{a.lanes=e;const t=e.map(e=>u.getLinesByLaneId(this.caseId,e.laneId));return Promise.all(t).then(e=>{const t=[];e.forEach((e,r)=>{const s=v();a.lanes[r].laneId=s,a.lanes[r].templateId=n,a.lanes[r].createUser=void 0,e.forEach(e=>{e.lineId=v(),e.laneId=s,e.createUser=void 0,t.push(e)})}),a.lines=t})}).then(()=>{a.templates=[e]}).then(()=>{a.params=[];const e=u.setUpData(this.caseId,this.versionCode,a);return u.batchAddConfig(e)}).then(()=>u.getTemplateById(this.caseId,n))}else t=u.upsertTemplate(e)}return"1"===e.isPublic?t.then(()=>u.getTemplatesByCaseId(this.caseId).then(t=>t.filter(t=>t.templateId!==e.templateId)).then(e=>{e.forEach(e=>{e.isPublic="0"});const t=e.map(e=>u.upsertTemplate(e));return Promise.all(t)}).then(()=>u.getConfigByTemplateId(this.caseId,e.templateId))):t}deleteTemplate(e){return u.getLanesByTemplateId(this.caseId,e.templateId).then(e=>{const t=e.map(e=>e.laneId);let n=t.map(e=>u.getLinesByLaneId(this.caseId,e));return Promise.all(n).then(e=>{const t=e.reduce((e,t)=>e.concat(t),[]).map(e=>e.lineId);return u.deleteLineByIds(this.caseId,t)}).then(()=>Promise.resolve(t))}).then(e=>u.deleteLaneByLaneIds(this.caseId,e)).then(()=>u.deleteTemplate(this.caseId,e.templateId)).then(()=>Promise.resolve(e))}upsertLane(e){return e.laneId||(e.laneId=v()),e.lines||(e.lines=[]),u.upsertLane(this.caseId,e)}delLane(e){const{lines:t,laneId:n}=e,a=t.map(e=>e.lineId);return u.deleteLineByIds(this.caseId,a).then(()=>u.deleteLaneByLaneIds(this.caseId,[n])).then(()=>Promise.resolve(e))}upsertLine(e){return e.lineId||(e.lineId=v()),e.laneId?u.upsertLine(this.caseId,e):Promise.reject(new Error("更新线条数据的时候,必须laneId不能为空!"))}delLine(e){return e.laneId?u.deleteLineByIds(this.caseId,[e.lineId]):Promise.reject(new Error("更新线条数据的时候,必须laneId不能为空!"))}restoreSetting(){return u.forceInitSceneConfig(this.caseId,this.versionCode,this.dataSource)}getType(){return"local-default"}}class E{static createStrategy(e){if("local"===e.type){let n;if((t=e.dataSource)&&Array.isArray(t.templates)&&Array.isArray(t.lanes)&&Array.isArray(t.lines)&&(0===t.templates.length||!t.templates[0].lanes))n={...e};else{if(!function(e){return Array.isArray(e)?0===e.length||!!e[0]&&Array.isArray(e[0].lanes):!!e&&Array.isArray(e.templates)&&(0===e.templates.length||Array.isArray(e.templates[0].lanes))}(e.dataSource))throw new Error("策略数据源格式不匹配");{const t=function(e){const t=[],n=[],a=[];for(const r of e){const{lanes:e,...s}=r;s.templateId||(s.templateId=v()),t.push(s);for(const t of e||[]){const{lines:e,...r}=t;r.templateId=s.templateId,r.laneId||(r.laneId=v()),n.push(r);for(const t of e||[])t.laneId=r.laneId,t.lineId||(t.lineId=v()),a.push(t)}}return{templates:t,lanes:n,lines:a}}(e.dataSource.templates);n={...e,dataSource:{...t,params:e.dataSource.params}}}}const{caseId:a,versionCode:r,dataSource:s}=n;return new b(a,r,s,!1)}return new p(e);var t}}var I={inject:["upsertTemplate","setTargetData","setExpanded"],props:{currentTemplate:{type:Object},formDisable:{type:Boolean},userTemplate:{type:Array},caseId:{type:String,default:""}},data(){return{formData:Object.assign({sort:void 0},this.currentTemplate),rules:{templateName:[{required:!0,message:"请输入模板名称",trigger:"blur"}]},saving:!1}},methods:{editable(){this.$emit("editable")},submitForm(e){this.$refs[e].validate(e=>{if(!e)return;if("function"!=typeof this.upsertTemplate)return void this.$message({type:"error",message:"没有配置模板管理方法"});this.saving=!0;const t={...this.formData};t.caseId||(t.caseId=this.caseId);const n=this.upsertTemplate(t);n instanceof Promise?n.then(e=>{this.setTargetData(e)}).then(()=>{this.$message({type:"success",message:"保存成功"})}).finally(()=>{this.saving=!1}):this.saving=!1})}},computed:{baseTemplate(){return this.userTemplate?[{name:"空白模板",value:""},...this.userTemplate.map(e=>({name:e.templateName,value:e.templateId}))]:[{name:"空白模板",value:""}]}},watch:{currentTemplate:{deep:!0,handler:function(e){this.formData=Object.assign({},e)}}}};function _(e,t,n,a,r,s,i,o,l,d){"boolean"!=typeof i&&(l=o,o=i,i=!1);const c="function"==typeof n?n.options:n;let m;if(e&&e.render&&(c.render=e.render,c.staticRenderFns=e.staticRenderFns,c._compiled=!0,r&&(c.functional=!0)),a&&(c._scopeId=a),s?(m=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),t&&t.call(this,l(e)),e&&e._registeredComponents&&e._registeredComponents.add(s)},c._ssrRegister=m):t&&(m=i?function(e){t.call(this,d(e,this.$root.$options.shadowRoot))}:function(e){t.call(this,o(e))}),m)if(c.functional){const e=c.render;c.render=function(t,n){return m.call(n),e(t,n)}}else{const e=c.beforeCreate;c.beforeCreate=e?[].concat(e,m):[m]}return n}s(".kd-lane-template-content {\n display: flex;\n flex-direction: column;\n align-content: center;\n}\n.kd-lane-template-content .template-buttons {\n text-align: center;\n}");const T=I;var x=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"kd-lane-template-content"},[n("el-form",{ref:"template",attrs:{rules:e.rules,model:e.formData,"label-width":"120px"}},[n("el-form-item",{attrs:{label:"模板名称",prop:"templateName"}},[n("el-input",{attrs:{disabled:"SYSTEM_USER"==e.currentTemplate.createUser||e.formDisable},model:{value:e.formData.templateName,callback:function(t){e.$set(e.formData,"templateName",t)},expression:"formData.templateName"}})],1),e._v(" "),n("el-form-item",{attrs:{label:"默认模板",prop:"isPublic"}},[n("el-radio-group",{attrs:{disabled:e.formDisable},model:{value:e.formData.isPublic,callback:function(t){e.$set(e.formData,"isPublic",t)},expression:"formData.isPublic"}},[n("el-radio",{attrs:{label:"1"}},[e._v("是")]),e._v(" "),n("el-radio",{attrs:{label:"0"}},[e._v("否")])],1)],1),e._v(" "),n("el-form-item",{attrs:{label:"曲线高度占比",prop:"col1"}},[n("el-select",{attrs:{disabled:e.formDisable},model:{value:e.formData.col1,callback:function(t){e.$set(e.formData,"col1",t)},expression:"formData.col1"}},[n("el-option",{attrs:{value:"0.5",label:"50%"}}),e._v(" "),n("el-option",{attrs:{value:"0.6",label:"60%"}}),e._v(" "),n("el-option",{attrs:{value:"0.7",label:"70%"}}),e._v(" "),n("el-option",{attrs:{value:"0.8",label:"80%"}}),e._v(" "),n("el-option",{attrs:{value:"0.9",label:"90%"}}),e._v(" "),n("el-option",{attrs:{value:"1",label:"全屏"}})],1)],1),e._v(" "),n("el-form-item",{directives:[{name:"show",rawName:"v-show",value:!e.currentTemplate.templateId,expression:"!currentTemplate.templateId"}],attrs:{label:"选择基础模板",prop:"lineType",disabled:e.formDisable}},[n("el-select",{attrs:{placeholder:"请选择"},model:{value:e.formData.baseTemplate,callback:function(t){e.$set(e.formData,"baseTemplate",t)},expression:"formData.baseTemplate"}},e._l(e.baseTemplate,function(e){return n("el-option",{key:e.value,attrs:{label:e.name,value:e.value}})}),1)],1),e._v(" "),n("el-form-item",{attrs:{label:"顺序",prop:"sort","label-width":"120px"}},[n("el-input",{attrs:{disabled:e.formDisable},model:{value:e.formData.sort,callback:function(t){e.$set(e.formData,"sort",e._n(t))},expression:"formData.sort"}})],1)],1),e._v(" "),n("div",{staticClass:"template-buttons"},[n("el-button",{on:{click:e.editable}},[e._v("编辑")]),e._v(" "),n("el-button",{attrs:{type:"primary",disabled:e.formDisable,loading:e.saving},on:{click:function(t){return e.submitForm("template")}}},[e._v("保存")])],1)],1)};x._withStripped=!0;const w=_({render:x,staticRenderFns:[]},undefined,T,undefined,false,undefined,!1,void 0,void 0,void 0);var C={inject:["upsertLane","setTargetData","setExpanded"],props:{laneInfo:{type:Object},caseId:{type:String,default:""},formDisable:{type:Boolean}},data(){return{formData:Object.assign(this.laneInfo),rules:{sort:[{required:!0,message:"请输入泳道顺序",trigger:"blur"}]},saving:!1}},methods:{editable(){this.$emit("editable")},submitForm(e){this.$refs[e].validate(e=>{if(!e)return;if("function"!=typeof this.upsertLane)return void this.$message({type:"error",message:"没有配置泳道管理方法"});this.saving=!0;const t={...this.formData};t.caseId||(t.caseId=this.caseId);const n=this.upsertLane(t);n instanceof Promise?n.then(e=>{this.setTargetData(e)}).then(()=>{this.$message({type:"success",message:"保存成功"})}).finally(()=>{this.saving=!1}):this.saving=!1})}},computed:{},watch:{laneInfo:{deep:!0,handler:function(e){this.formData=Object.assign({},e)}}}};s(".kd-lane-lane-content {\n display: flex;\n flex-direction: column;\n align-content: center;\n}\n.kd-lane-lane-content .template-buttons {\n text-align: center;\n}");const A=C;var D=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"kd-lane-lane-content"},[n("el-form",{ref:"template",attrs:{rules:e.rules,model:e.formData,"label-width":"120px"}},[n("el-form-item",{attrs:{label:"泳道顺序",prop:"sort"}},[n("el-input",{attrs:{disabled:e.formDisable},model:{value:e.formData.sort,callback:function(t){e.$set(e.formData,"sort",t)},expression:"formData.sort"}})],1)],1),e._v(" "),n("div",{staticClass:"template-buttons"},[n("el-button",{on:{click:e.editable}},[e._v("编辑")]),e._v(" "),n("el-button",{attrs:{type:"primary",disabled:e.formDisable,loading:e.saving},on:{click:function(t){return e.submitForm("template")}}},[e._v("保存")])],1)],1)};D._withStripped=!0;const N=_({render:D,staticRenderFns:[]},undefined,A,undefined,false,undefined,!1,void 0,void 0,void 0);var k={inject:["upsertLine","setTargetData","setExpanded"],props:{template:{type:Object},formDisable:{type:Boolean},params:{type:Array}},mounted(){},data(){const e=(e,t,n)=>{isNaN(t)?n(new Error("请输入数字值")):n()};return{formData:Object.assign({},this.template),lines:[{name:"直线",value:"solid"},{name:"虚线",value:"dashed"},{name:"点线",value:"dotted"},{name:"面积",value:"area"}],lineWidthSliderMarks:{1:"1",2:"2",3:"3",4:"4"},rules:{min:[{required:!0,message:"请输入最小值",trigger:"blur"},{validator:e,trigger:"blur"}],lineSort:[{required:!0,message:"请输入曲线顺序(1-10)",trigger:"blur"},{type:"number",message:"顺序必须为数字值"}],max:[{required:!0,message:"请输入最大值",trigger:"blur"},{validator:e,trigger:"blur"}],lineSize:[{required:!0,message:"请选择曲线粗细",trigger:"blur"}],lineColor:[{required:!0,message:"请选择曲线颜色",trigger:"blur"}],lineType:[{required:!0,message:"请选择线型",trigger:"blur"}],paramId:[{required:!0,message:"请选择参数名称",trigger:"blur"}]}}},methods:{editable(){this.$emit("editable")},submitForm(e){this.$refs[e].validate().then(()=>{if(!(this.upsertLine instanceof Function))return Promise.reject(new Error("未配置线条设置函数"));{const e=this.upsertLine(this.formData);e instanceof Promise?e.then(e=>{this.setTargetData(e)}).then(()=>{this.$message({type:"success",message:"保存成功"})}).finally(()=>{this.saving=!1}):this.saving=!1}}).catch(e=>{console.log(e)})}},watch:{template:{immediate:!1,deep:!0,handler(e){this.formData=Object.assign({},e)}}}};s(".kd-lane-line-content {\n width: 95%;\n display: flex;\n flex-direction: column;\n align-content: center;\n}\n.kd-lane-line-content .template-buttons {\n text-align: center;\n}");const L=k;var M=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"kd-lane-line-content"},[n("el-form",{ref:"template",attrs:{rules:e.rules,model:e.formData,disabled:e.formDisable}},[n("el-form-item",{attrs:{label:"参数名称",prop:"paramId","label-width":"120px"}},[n("el-select",{attrs:{filterable:"",placeholder:"请选择"},model:{value:e.formData.paramId,callback:function(t){e.$set(e.formData,"paramId",t)},expression:"formData.paramId"}},e._l(e.params,function(e){return n("el-option",{key:e.paramId,attrs:{label:e.paramName,value:e.paramId}})}),1)],1),e._v(" "),n("el-form-item",{attrs:{label:"最小值",prop:"min","label-width":"120px"}},[n("el-input",{model:{value:e.formData.min,callback:function(t){e.$set(e.formData,"min",t)},expression:"formData.min"}})],1),e._v(" "),n("el-form-item",{attrs:{label:"最大值",prop:"max","label-width":"120px"}},[n("el-input",{model:{value:e.formData.max,callback:function(t){e.$set(e.formData,"max",t)},expression:"formData.max"}})],1),e._v(" "),n("el-form-item",{attrs:{label:"曲线粗细",prop:"lineSize","label-width":"120px"}},[n("el-input",{attrs:{max:4,min:1,type:"number"},model:{value:e.formData.lineSize,callback:function(t){e.$set(e.formData,"lineSize",t)},expression:"formData.lineSize"}})],1),e._v(" "),n("el-form-item",{attrs:{label:"曲线颜色",prop:"lineColor","label-width":"120px"}},[n("el-color-picker",{model:{value:e.formData.lineColor,callback:function(t){e.$set(e.formData,"lineColor",t)},expression:"formData.lineColor"}})],1),e._v(" "),n("el-form-item",{attrs:{label:"线型",prop:"lineType","label-width":"120px"}},[n("el-select",{attrs:{placeholder:"请选择"},model:{value:e.formData.lineType,callback:function(t){e.$set(e.formData,"lineType",t)},expression:"formData.lineType"}},e._l(e.lines,function(e){return n("el-option",{key:e.value,attrs:{label:e.name,value:e.value}})}),1)],1),e._v(" "),n("el-form-item",{attrs:{label:"曲线顺序",prop:"lineSort","label-width":"120px"}},[n("el-input",{model:{value:e.formData.lineSort,callback:function(t){e.$set(e.formData,"lineSort",e._n(t))},expression:"formData.lineSort"}})],1),e._v(" "),e._e()],1),e._v(" "),n("div",{directives:[{name:"show",rawName:"v-show",value:"SYSTEM_USER"!=e.template.createUser,expression:"template.createUser != 'SYSTEM_USER'"}],staticClass:"template-buttons"},[n("el-button",{on:{click:e.editable}},[e._v("编辑")]),e._v(" "),n("el-button",{attrs:{type:"primary",disabled:e.formDisable},on:{click:function(t){return e.submitForm("template")}}},[e._v("保存")])],1)],1)};M._withStripped=!0;const R=_({render:M,staticRenderFns:[]},undefined,L,undefined,false,undefined,!1,void 0,void 0,void 0);var P={inject:["delTemplate","delLane","delLine"],provide(){return{setTargetData:this.setTargetData,setExpanded:this.setExpanded}},components:{LineEdit:R,TemplateEdit:w,LaneEdit:N},props:{contextItem:{type:Object,default:()=>{}},expended:{type:Object},caseId:{type:String,default:""},inputTempates:{type:Array,default:()=>[]},params:{type:Array,required:!0,default:()=>[]},paramsNameMap:{type:Object,default:()=>{},required:!0}},data:()=>({templateContentShow:!1,templateDisable:!1,laneContentShow:!1,lineContentShow:!1,templateInfo:{},laneInfo:{},lineInfo:{},dataType:"",curveConfigLoading:!1,expandedKeys:[],currentNodeKey:"",targetData:void 0,treeKey:""}),mounted(){},methods:{getLineDataLabel(e){if(!e)return"";const t=this.paramsNameMap[e.paramId];return t?t.paramName:e.paramId},setTargetData(e){this.targetData=e,this.setExpanded();switch(y(e)){case"template":this.templateContentShow=!0,this.laneContentShow=!1,this.lineContentShow=!1,this.templateDisable=!0,this.templateInfo=e;break;case"lane":this.templateContentShow=!1,this.laneContentShow=!0,this.lineContentShow=!1,this.templateDisable=!0,this.laneInfo=e;break;case"line":this.templateContentShow=!1,this.laneContentShow=!1,this.lineContentShow=!0,this.templateDisable=!0,this.lineInfo=e}},setExpanded(){const e=this.targetData;if(e){switch(y(e)){case"template":this.expandedKeys=[e.templateId],this.currentNodeKey=e.templateId;break;case"lane":this.expandedKeys=[e.laneId],this.currentNodeKey=e.laneId;break;case"line":this.expandedKeys=[e.lineId],this.currentNodeKey=e.lineId;break;default:this.expandedKeys=[],this.currentNodeKey=""}}else this.expandedKeys=[],this.currentNodeKey="";this.$refs.refTree&&this.$refs.refTree.setCurrentKey(this.currentNodeKey),this.treeKey=`treeKey${(new Date).getTime()}`},optionClicked(e){const{option:t={},item:n}=e;switch(t.key){case"delTemplate":this.askForDelTemplate(n);break;case"addLane":this.addLane(n);break;case"delLane":this.askForDelLane(n);break;case"addParam":this.addParam(n);break;case"delParam":this.delParam(n)}},hideContextMenu(){const e=this.$refs.vueSimpleContextMenu;e&&e.hideContextMenu()},showRightWindows(e,t,n){const a=this.judgeDataType(n);this.dataType=a,"SYSTEM_USER"!=t.createUser?this.$refs.vueSimpleContextMenu.showMenu(e,t):this.$message.warning("系统模板不能编辑")},clear(){this.expandedKeys=[],this.templateDisable=!0,this.templateContentShow=!1},editable(){this.templateDisable=!1},handleNodeClick(e){this.setTargetData(e)},judgeDataType(e){const{level:t,data:n={}}=e;return 1==t&&n.templateId?"template":2==t&&n.laneId&&n.templateId?"lane":3==t&&n.lineId?"line":null},addTemplate(){this.templateContentShow=!0,this.laneContentShow=!1,this.lineContentShow=!1,this.templateDisable=!1,this.templateInfo={isPublic:"0",baseTemplate:"",col1:"1"}},addLane(e){this.templateContentShow=!1,this.laneContentShow=!0,this.lineContentShow=!1,this.templateDisable=!1,this.laneInfo={templateId:e.templateId,isUsed:"1",sort:e.lanes.length+1}},addParam(e){this.templateContentShow=!1,this.laneContentShow=!1,this.lineContentShow=!0,this.templateDisable=!1,this.lineInfo={laneId:e.laneId,isUsed:"1",lineSize:2}},askForDelTemplate(e){this.$confirm("此操作将删除该模板, 是否继续?","提示",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then(()=>(e.bsflag="1",this.curveConfigLoading=!0,this.delTemplate instanceof Function?this.delTemplate(e):Promise.reject(new Error("未配置删除模板函数")))).catch(e=>{this.$message.error(e.message||"删除失败")}).finally(()=>{this.curveConfigLoading=!1})},askForDelLane(e){this.$confirm("此操作将删除该泳道, 是否继续?","提示",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then(()=>(e.bsflag="1",this.curveConfigLoading=!0,this.delLane instanceof Function?this.delLane(e):Promise.reject(new Error("未配置删除模板函数")))).catch(()=>{this.$message.error("删除失败")}).finally(()=>{this.curveConfigLoading=!1})},delParam(e){this.$confirm("此操作将删除该参数, 是否继续?","提示",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then(()=>(e.bsflag="1",this.delLine instanceof Function?this.delLine(e):Promise.reject(new Error("未配置删除线条函数")))).catch(e=>{this.$message.error(e.message||"删除失败")})}},computed:{contextMenuOptions(){switch(this.dataType){case"template":return[{name:"新增泳道",key:"addLane"},{name:"删除模板",key:"delTemplate"}];case"lane":return[{name:"新增参数",key:"addParam"},{name:"删除泳道",key:"delLane"}];case"line":return[{name:"删除参数",key:"delParam"}];default:return[]}},treeData(){if(this.inputTempates){const e=[];return this.inputTempates.forEach(t=>{const n={...t,id:t.templateId,label:t.templateName};n.children=[],t.lanes||(t.lanes=[]),t.lanes.forEach((e,t)=>{const a={...e,id:e.laneId,label:`泳道${t+1}`};n.children.push(a),a.lines||(a.lines=[]),a.children=[],e.lines.forEach(e=>{const t={...e,id:e.lineId,label:e.lineName||e.paramId};t.label=this.getLineDataLabel(e),a.children.push(t)})}),e.push(n)}),e}return[]},userTemplate(){return this.treeData?[...this.treeData]:[]}},watch:{contextItem:{immediate:!0,deep:!0,handler(e){this.setTargetData(Object.assign({},e))}}},beforeDestroy(){}};s(".kd-lane-el-container {\n height: 60vh;\n border: 1px solid var(--kd-lane-container-border-color, #333);\n width: 100%;\n}\n@media screen and (max-width: 1024px) {\n.kd-lane-el-container {\n height: 70vh;\n}\n}\n.kd-lane-el-container .rtd-config-side {\n border-right: 1px solid var(--kd-lane-container-border-color, #333);\n}\n.kd-lane-el-container .rtd-config-side-tree {\n height: 90%;\n overflow: auto;\n}\n.kd-lane-el-container .rtd-config-side-option {\n text-align: center;\n}\n.kd-lane-el-container .rtd-config-main {\n display: flex;\n align-content: center;\n justify-content: center;\n width: 100%;\n}");const $=P;var O=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-container",{directives:[{name:"loading",rawName:"v-loading",value:e.curveConfigLoading,expression:"curveConfigLoading"}],staticClass:"kd-lane-el-container"},[n("el-aside",{staticClass:"rtd-config-side",attrs:{width:"20%"}},[n("el-tree",{key:e.treeKey,ref:"refTree",staticClass:"rtd-config-side-tree",attrs:{data:e.treeData,"expand-on-click-node":!1,"current-node-key":e.currentNodeKey,"default-expanded-keys":e.expandedKeys,"node-key":"id","highlight-current":""},on:{"node-click":e.handleNodeClick,"node-expand":e.hideContextMenu,"node-collapse":e.hideContextMenu},scopedSlots:e._u([{key:"default",fn:function(t){var a=t.node,r=t.data;return n("span",{staticClass:"custom-tree-node",on:{contextmenu:function(t){return t.preventDefault(),e.showRightWindows(t,r,a)}}},[n("span",[e._v(e._s(a.label))]),e._v(" "),n("span",{directives:[{name:"show",rawName:"v-show",value:"1"==r.isPublic,expression:"data.isPublic == '1'"}],staticStyle:{"padding-left":"5px"}},[n("i",{staticClass:"el-icon-star-on"})])])}}])}),e._v(" "),n("div",{staticClass:"rtd-config-side-option"},[n("el-button",{on:{click:e.addTemplate}},[e._v("新增模板")])],1)],1),e._v(" "),n("el-main",{staticClass:"rtd-config-main"},[n("TemplateEdit",e._g({directives:[{name:"show",rawName:"v-show",value:e.templateContentShow,expression:"templateContentShow"}],attrs:{currentTemplate:e.templateInfo,"form-disable":e.templateDisable,userTemplate:e.userTemplate,caseId:e.caseId},on:{editable:e.editable}},e.$listeners)),e._v(" "),n("LaneEdit",e._g({directives:[{name:"show",rawName:"v-show",value:e.laneContentShow,expression:"laneContentShow"}],attrs:{laneInfo:e.laneInfo,"form-disable":e.templateDisable},on:{editable:e.editable}},e.$listeners)),e._v(" "),n("LineEdit",e._g({directives:[{name:"show",rawName:"v-show",value:e.lineContentShow,expression:"lineContentShow"}],attrs:{template:e.lineInfo,params:e.params,"form-disable":e.templateDisable},on:{editable:e.editable}},e.$listeners))],1),e._v(" "),n("VueSimpleContextMenu",{ref:"vueSimpleContextMenu",attrs:{"element-id":"kd-lane-chart-context-menu-2",options:e.contextMenuOptions},on:{"option-clicked":e.optionClicked}})],1)};O._withStripped=!0;const B=_({render:O,staticRenderFns:[]},undefined,$,undefined,false,undefined,!1,void 0,void 0,void 0);var j={props:{itemHeight:{type:Number,default:20},line:{type:Object,default:()=>{}},paramsNameMap:{type:Object,default:()=>{},required:!0}},methods:{getParamName(e){if(!e)return"";const t=this.paramsNameMap[e.paramId];return t?`${t.paramName}${t.paramUnit}`:""},toggleIsUsed(){const e={...this.line};"1"==e.isUsed||1==e.isUsed?e.isUsed="0":e.isUsed="1",this.$emit("updateLine",e)}},computed:{textColor(){return{color:this.line.lineColor}},headerItemStyle(){let e;return e="area"==this.line.lineType?{"box-shadow":`inset 0 0 8px 0px ${this.line.lineColor}`}:{"border-bottom":`2px ${this.line.lineType} ${this.line.lineColor}`},{height:`${this.itemHeight}px`,opacity:"1"==this.line.isUsed?1:.5,...e}}},watch:{}};s('@charset "UTF-8";\n.kd-lane-chart-container-header-item {\n color: var(--kd-lane-container-header-item-color, #333);\n border: unset;\n position: relative;\n cursor: pointer;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container {\n height: 100%;\n width: 100%;\n font-size: 10px;\n font-weight: bold;\n position: relative;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .left {\n position: absolute;\n left: 0;\n bottom: 2px;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .center {\n position: absolute;\n left: 50%;\n bottom: 2px;\n transform: translateX(-50%);\n /* 文字不换行,超出显示省略号 */\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .right {\n position: absolute;\n right: 0;\n bottom: 2px;\n}');const U=j;var V=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"kd-lane-chart-container-header-item",style:e.headerItemStyle,on:{click:e.toggleIsUsed}},[n("div",{staticClass:"kd-lane-chart-container-text-container"},[n("span",{staticClass:"left",style:e.textColor},[e._v(e._s(e.line.min))]),e._v(" "),n("span",{staticClass:"center"},[e._v(e._s(e.getParamName(e.line)))]),e._v(" "),n("span",{staticClass:"right",style:e.textColor},[e._v(e._s(e.line.max))])])])};V._withStripped=!0;const q=_({render:V,staticRenderFns:[]},undefined,U,undefined,false,undefined,!1,void 0,void 0,void 0);var K={name:"KdLaneChartContainer",provide(){return{upsertTemplate:this.upsertTemplate,delTemplate:this.delTemplate,upsertLane:this.upsertLane,delLane:this.delLane,upsertLine:this.upsertLine,delLine:this.delLine}},components:{HeaderItem:q,RealTimeCurveConfig:B},props:{config:{type:Object,required:!0,validator:function(e){if("object"!=typeof e||null===e)throw new Error("配置必须是一个对象");if(!("type"in e))throw new Error("配置必须包含 type 属性");if(!("caseId"in e)||!("versionCode"in e))throw new Error("配置必须包含 caseId, versionCode 属性");const{type:t}=e;if("local"===t){if(!("dataSource"in e)||null==e.dataSource)throw new Error("local 类型的配置必须包含 dataSource 属性");if(!("params"in e.dataSource))throw new Error("local 类型的配置 dataSource 必须包含 params 属性")}else{if("custom"!==t)throw new Error('type 必须是 "local" 或 "custom"');{const t=["getUserTemplates","upsertTemplate","delTemplate","upsertLane","delLane","upsertLine","delLine"];for(const n of t)if("function"!=typeof e[n])throw new Error(`${n} 必须是一个函数`)}}return!0}},headerPadding:{type:Number,default:4},headerItemHeight:{type:Number,default:20},itemGap:{type:Number,default:2},customMenuList:{type:Array,default:()=>[]}},data:()=>({treeTemplates:null,isLoading:!1,strategy:null,currentTemplate:{},curveConfigVisible:!1,params:[],contextItem:void 0}),created(){this.strategy=E.createStrategy(this.$props.config),this.loadConfig()},mounted(){},methods:{setExpanded(){this.$refs.curveConfig.setExpanded()},delLine(e){return this.strategy.delLine(e).then(()=>{const t=this.currentTemplate.lanes,n=t.findIndex(t=>t.laneId==e.laneId);if(n<0)for(const t of this.treeTemplates){const{lanes:n}=t;for(const t of n)if(t.laneId==e.laneId){const{lines:n}=t,a=n.findIndex(t=>t.lineId==e.lineId);a<0?console.warn("要删除的线条在当前泳道中不存在?"):n.splice(a,1);break}}else{const a=t[n].lines.findIndex(t=>t.lineId==e.lineId);a<0?console.warn("要删除的线条在当前泳道中不存在?"):t[n].lines.splice(a,1),this.onLineChange(e)}})},upsertLine(e){return this.strategy.upsertLine(e).then(e=>{const t=this.currentTemplate.lanes,n=t.findIndex(t=>t.laneId==e.laneId);if(!(n<0)){const a=t[n],r=a.lines,s=r.findIndex(t=>t.lineId==e.lineId);return s<0?r.push(e):this.$set(r,s,e),this.$set(t,n,a),f(a),this.onLineChange(e),e}for(const t of this.treeTemplates){const{lanes:n}=t;for(const t of n)if(t.laneId==e.laneId){const{lines:n}=t,a=n.findIndex(t=>t.lineId==e.lineId);a<0?n.push(e):this.$set(n,a,e),f(t);break}}})},delLane(e){return this.strategy.delLane(e).then(e=>{const{templateId:t}=e,n=this.treeTemplates.findIndex(e=>e.templateId==t);if(n<0)return void console.warn(`template_id not found: '${t}'`);const a=this.treeTemplates[n],r=a.lanes.findIndex(t=>t.laneId==e.laneId);a.lanes.splice(r,1),this.currentTemplate.templateId==t&&this.setDefaultAndNotify()})},upsertLane(e){return this.strategy.upsertLane(e).then(e=>{const t=this.treeTemplates.findIndex(t=>t.templateId==e.templateId);if(t<0)console.warn("template not found");else{const n=this.treeTemplates[t],a=n.lanes||[],r=a.findIndex(t=>t.laneId==e.laneId);r<0?a.push(e):this.$set(a,r,e),g(n.lanes),n.templateId===this.currentTemplate.templateId&&this.setDefaultAndNotify()}return e})},delTemplate(e){return this.strategy.deleteTemplate(e).then(()=>{const t=this.treeTemplates.findIndex(t=>t.templateId===e.templateId);this.treeTemplates.splice(t,1),e.templateId==this.currentTemplate.templateId&&this.setDefaultAndNotify()})},upsertTemplate(e){return this.strategy.upsertTemplate(e).then(e=>{"1"==e.isPublic&&this.treeTemplates.forEach(e=>{e.isPublic="0"});const t=this.treeTemplates.findIndex(t=>t.templateId===e.templateId);if(t>=0){const n=this.treeTemplates[t],a=Object.assign({},n,e);this.$set(this.treeTemplates,t,a)}else this.treeTemplates.push(e);return S(this.treeTemplates),this.setDefaultAndNotify(),e})},onParentContextMenu(e){const t=".kd-lane-chart-lane-header";if(!(e.target&&(e.target.classList.contains(t)||e.target.closest(t)))){e.preventDefault();const t=this.$refs.vueSimpleContextMenu;t&&t.hideContextMenu()}},showContextMenu(e,t){e.stopPropagation(),this.$refs.vueSimpleContextMenu.showMenu(e,t)},optionClicked(e){const{option:t,item:n}=e;this.contextItem=n;const a=this.customMenuList.findIndex(e=>e.key==t.key);if(a<0){if("editTemplate"==t.key)this.curveConfigVisible=!0;else if("restoreSetting"==t.key)return this.strategy.restoreSetting().then(()=>{this.loadConfig()})}else this.$emit("onCustomMenuClicked",e)},loadConfig(){this.isLoading=!0,this.strategy.getUserTemplates().then(e=>{const{templates:t=[],params:n=[]}=e;this.params=n,S(t),this.treeTemplates=t,this.setDefaultAndNotify()}).catch(e=>{console.error(`加载配置失败: ${this.$props.strategy.caseId},${this.$props.strategy.versionCode},${e.message}`)}).finally(()=>{this.isLoading=!1})},onLineChange(e){console.log("notify line change",e),this.$emit("line-change",e)},setDefaultAndNotify(){const e=this.treeTemplates.find(e=>"1"===e.isPublic);if(e)this.currentTemplate=e;else{const e=this.treeTemplates.find(e=>"SYSTEM_USER"==e.createUser);e?(e.isPublic="1",this.currentTemplate=e,this.strategy.upsertTemplate(e)):(this.treeTemplates[0].isPublic="1",this.currentTemplate=this.treeTemplates[0],this.strategy.upsertTemplate(this.currentTemplate))}this.$emit("template-change",this.currentTemplate)}},computed:{contextMenuOptions(){return"local"==this.config.type?[{name:"编辑模板",key:"editTemplate"},{name:"恢复默认",key:"restoreSetting"},...this.customMenuList]:[{name:"编辑模板",key:"template"},...this.customMenuList]},paramsNameMap(){const e={};for(const t of this.params)e[t.paramId]={paramName:t.paramName,paramUnit:t.paramUnit};return e},lineCount(){const{lanes:e=[]}=this.currentTemplate||{};return Math.max(...e.map(e=>e.lines?.length||0))},headerStyle(){const e={gap:`${this.itemGap}px`,padding:`${this.headerPadding}px`};if(this.currentTemplate){const{lanes:t=[]}=this.currentTemplate;if(t&&0!=t.length){const t=Math.max(0,this.lineCount-1);return{...e,height:this.lineCount*this.headerItemHeight+2*this.headerPadding+t*this.itemGap+"px","min-height":"60px"}}return{...e,height:"30%","min-height":"60px"}}return{...e,height:"30%","min-height":"60px"}},darwAreaStyle(){return{top:this.headerStyle.height}}}};s(".kd-lane-chart-container {\n --border-color: var(--kd-lane-container-border-color, #333);\n --context-background-color: var(--kd-lane-container-context-background-color, #ecf0f1);\n --context-hover-color: var(--kd-lane-container-context-hover-color, #007aff);\n height: 100%;\n width: 100%;\n overflow: hidden;\n position: relative;\n border: 1px solid var(--border-color);\n display: flex;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-slot-container, .kd-lane-chart-container .kd-lane-chart-lane-container {\n height: 100%;\n min-width: 0;\n overflow: hidden;\n z-index: 1;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-slot-container .kd-lane-chart-lane-header, .kd-lane-chart-container .kd-lane-chart-lane-container .kd-lane-chart-lane-header {\n padding: 4px;\n max-height: 40%;\n border-bottom: 1px solid var(--border-color);\n overflow: hidden;\n z-index: 2;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-container {\n flex: 1;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-slot-container {\n width: auto;\n}\n.kd-lane-chart-container .border-left {\n border-left: 1px solid var(--border-color);\n}\n.kd-lane-chart-container .kd-lane-chart-container-draw-area {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n border: none;\n}\n.kd-lane-chart-container .vue-simple-context-menu {\n background-color: var(--context-background-color);\n position: fixed;\n}\n.kd-lane-chart-container .vue-simple-context-menu .vue-simple-context-menu__item:hover {\n background: var(--context-hover-color);\n}");const F=K;var H=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"loading",rawName:"v-loading",value:e.isLoading,expression:"isLoading"}],staticClass:"kd-lane-chart-container",on:{contextmenu:e.onParentContextMenu}},[e.currentTemplate&&e.currentTemplate.lanes&&e.currentTemplate.lanes.length>0?[e._l(e.currentTemplate.lanes||[],function(t,a){return[e.$scopedSlots["lane"+t.laneId]?n("div",{key:t.laneId,staticClass:"kd-lane-chart-lane-slot-container",class:{"border-left":0!=a}},[n("div",{staticClass:"kd-lane-chart-lane-header",style:e.headerStyle},[e._t("lane"+t.laneId,null,{lane:t})],2)]):e.$slots["lane"+t.laneId]?n("div",{key:""+t.laneId,staticClass:"kd-lane-chart-lane-slot-container",class:{"border-left":0!=a}},[n("div",{staticClass:"kd-lane-chart-lane-header",style:e.headerStyle},[e._t("lane"+t.laneId,null,{lane:t})],2)]):[n("div",{key:t.laneId,staticClass:"kd-lane-chart-lane-container",class:{"border-left":0!=a}},[n("div",{staticClass:"kd-lane-chart-lane-header",style:e.headerStyle,on:{contextmenu:function(n){return n.preventDefault(),e.showContextMenu(n,t)}}},e._l(t.lines||[],function(t){return n("HeaderItem",{key:t.lineId,attrs:{itemHeight:e.headerItemHeight,line:t,paramsNameMap:e.paramsNameMap},on:{updateLine:e.upsertLine},nativeOn:{contextmenu:function(n){return n.preventDefault(),e.showContextMenu(n,t)}}})}),1)])]]})]:[n("div",{staticClass:"kd-lane-chart-lane-container"},[n("div",{staticClass:"kd-lane-chart-lane-header",style:e.headerStyle,on:{contextmenu:function(t){return t.preventDefault(),e.showContextMenu.apply(null,arguments)}}})])],e._v(" "),n("div",{staticClass:"kd-lane-chart-container-draw-area",style:e.darwAreaStyle},[e._t("draw-slot")],2),e._v(" "),n("VueSimpleContextMenu",{ref:"vueSimpleContextMenu",attrs:{"element-id":"kd-lane-chart-context-menu",options:e.contextMenuOptions},on:{"option-clicked":e.optionClicked}}),e._v(" "),n("el-dialog",{attrs:{title:"泳道模板设置",visible:e.curveConfigVisible},on:{"update:visible":function(t){e.curveConfigVisible=t},opened:e.setExpanded}},[n("RealTimeCurveConfig",e._g({ref:"curveConfig",attrs:{inputTempates:e.treeTemplates,caseId:e.strategy.caseId,params:e.params,paramsNameMap:e.paramsNameMap,contextItem:e.contextItem}},e.$listeners))],1)],2)};H._withStripped=!0;const X=_({render:H,staticRenderFns:[]},undefined,F,undefined,false,undefined,!1,void 0,void 0,void 0),z=e=>{e.use(a.default),e.component(d.name,d),e.component(X.name,X)};return"undefined"!=typeof window&&window.Vue&&window.Vue.use(z),{install:z}});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("v-click-outside"),require("vue")):"function"==typeof define&&define.amd?define(["v-click-outside","vue"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).KdLaneChartContainer=t(e.vClickOutside,e.Vue)}(this,function(e,t){"use strict";function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var a=n(e),r=n(t);function s(e,t){void 0===t&&(t={});var n=t.insertAt;if(e&&"undefined"!=typeof document){var a=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css","top"===n&&a.firstChild?a.insertBefore(r,a.firstChild):a.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e))}}function i(e,t,n,a,r,s,i,o,l,d){"boolean"!=typeof i&&(l=o,o=i,i=!1);var c,m="function"==typeof n?n.options:n;if(e&&e.render&&(m.render=e.render,m.staticRenderFns=e.staticRenderFns,m._compiled=!0,r&&(m.functional=!0)),a&&(m._scopeId=a),s?(c=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),t&&t.call(this,l(e)),e&&e._registeredComponents&&e._registeredComponents.add(s)},m._ssrRegister=c):t&&(c=i?function(e){t.call(this,d(e,this.$root.$options.shadowRoot))}:function(e){t.call(this,o(e))}),c)if(m.functional){var h=m.render;m.render=function(e,t){return c.call(t),h(e,t)}}else{var p=m.beforeCreate;m.beforeCreate=p?[].concat(p,c):[c]}return n}s('.vue-simple-context-menu {\n top: 0;\n left: 0;\n margin: 0;\n padding: 0;\n display: none;\n list-style: none;\n position: absolute;\n z-index: 1000000;\n background-color: #ecf0f1;\n border-bottom-width: 0px;\n font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;\n box-shadow: 0 3px 6px 0 rgba(51, 51, 51, 0.2);\n border-radius: 4px;\n}\n.vue-simple-context-menu--active {\n display: block;\n}\n.vue-simple-context-menu__item {\n display: flex;\n color: #333;\n cursor: pointer;\n padding: 5px 15px;\n align-items: center;\n}\n.vue-simple-context-menu__item:hover {\n background-color: #007aff;\n color: #fff;\n}\n.vue-simple-context-menu__divider {\n box-sizing: content-box;\n height: 2px;\n background-color: #c0cdd1;\n padding: 4px 0;\n background-clip: content-box;\n pointer-events: none;\n}\n.vue-simple-context-menu li:first-of-type {\n margin-top: 4px;\n}\n.vue-simple-context-menu li:last-of-type {\n margin-bottom: 4px;\n}'),r.default.use(a.default);var o={name:"VueSimpleContextMenu",props:{elementId:{type:String,required:!0},options:{type:Array,required:!0}},data:function(){return{item:null,menuWidth:null,menuHeight:null}},methods:{showMenu:function(e,t){this.item=t;var n=document.getElementById(this.elementId);n&&(this.menuWidth&&this.menuHeight||(n.style.visibility="hidden",n.style.display="block",this.menuWidth=n.offsetWidth,this.menuHeight=n.offsetHeight,n.removeAttribute("style")),this.menuWidth+e.pageX>=window.innerWidth?n.style.left=e.pageX-this.menuWidth+2+"px":n.style.left=e.pageX-2+"px",this.menuHeight+e.pageY>=window.innerHeight?n.style.top=e.pageY-this.menuHeight+2+"px":n.style.top=e.pageY-2+"px",n.classList.add("vue-simple-context-menu--active"))},hideContextMenu:function(){var e=document.getElementById(this.elementId);e&&(e.classList.remove("vue-simple-context-menu--active"),this.$emit("menu-closed"))},onClickOutside:function(){this.hideContextMenu()},optionClicked:function(e){this.hideContextMenu(),this.$emit("option-clicked",{item:this.item,option:e})},onEscKeyRelease:function(e){27===e.keyCode&&this.hideContextMenu()}},mounted:function(){document.body.addEventListener("keyup",this.onEscKeyRelease)},beforeDestroy:function(){document.removeEventListener("keyup",this.onEscKeyRelease)}},l=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",[n("ul",{directives:[{name:"click-outside",rawName:"v-click-outside",value:e.onClickOutside,expression:"onClickOutside"}],staticClass:"vue-simple-context-menu",attrs:{id:e.elementId}},e._l(e.options,function(t,a){return n("li",{key:a,staticClass:"vue-simple-context-menu__item",class:[t.class,"divider"===t.type?"vue-simple-context-menu__divider":""],on:{click:function(n){return n.stopPropagation(),e.optionClicked(t)}}},[n("span",{domProps:{innerHTML:e._s(t.name)}})])}),0)])};l._withStripped=!0;var d=i({render:l,staticRenderFns:[]},undefined,o,undefined,false,undefined,!1,void 0,void 0,void 0);var c={install:function e(t){e.installed||(e.installed=!0,t.component("VueSimpleContextMenu",d))}},m=null;"undefined"!=typeof window?m=window.Vue:"undefined"!=typeof global&&(m=global.Vue),m&&m.use(c);class h{constructor(e){this.strategy=e}getUserTemplates(){return this.strategy.getUserTemplates()}upsertTemplate(e){return this.strategy.upsertTemplate(e)}delTemplate(e){return this.strategy.deleteTemplate(e)}upsertLane(e){return this.strategy.upsertLane(e)}delLane(e){return this.strategy.deleteLane(e)}upsertLine(e){return this.strategy.upsertLine(e)}delLine(e){return this.strategy.delLine(e)}restoreSetting(){return this.strategy.restoreSetting?this.strategy.restoreSetting():Promise.resolve()}}class p{static DB_NAME="KDLaneChartContainerConfigDB";static MAX_UNICODE_CHAR="￿";static DB_VERSION=2;static STORE_NAMES={TEMPLATES:"templates",LANES:"lanes",LINES:"lines",PARAMS:"params",CASE_VERSIONS:"case_versions"};_db=null;_openDB(){return new Promise((e,t)=>{if(this._db)return void e(this._db);const n=indexedDB.open(p.DB_NAME,p.DB_VERSION);n.onupgradeneeded=e=>{const t=e.target.result,{STORE_NAMES:n}=p;t.objectStoreNames.contains(n.CASE_VERSIONS)||t.createObjectStore(n.CASE_VERSIONS,{keyPath:"caseId"}),t.objectStoreNames.contains(n.TEMPLATES)||t.createObjectStore(n.TEMPLATES,{keyPath:["caseId","templateId"]}),t.objectStoreNames.contains(n.LANES)||t.createObjectStore(n.LANES,{keyPath:["caseId","laneId"]}),t.objectStoreNames.contains(n.LINES)||t.createObjectStore(n.LINES,{keyPath:["caseId","lineId"]}),t.objectStoreNames.contains(n.PARAMS)||t.createObjectStore(n.PARAMS,{keyPath:["caseId","paramId"]})},n.onsuccess=t=>{this._db=t.target.result,this._db.onclose=()=>{this._db=null},e(this._db)},n.onerror=e=>{t(new Error(`打开数据库失败:${e.target.error.message}`))},n.onblocked=()=>{t(new Error("数据库操作被阻塞,请关闭其他标签页后重试"))}})}closeDB(){return new Promise(e=>{this._db&&(this._db.close(),this._db=null),e()})}_compareVersion(e,t){const n=e=>String(e).split(".").map(Number),a=n(e),r=n(t),s=Math.max(a.length,r.length);for(let e=0;e<s;e++){const t=a[e]||0,n=r[e]||0;if(t>n)return 1;if(t<n)return-1}return 0}_clearSceneData(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([p.STORE_NAMES.CASE_VERSIONS,p.STORE_NAMES.TEMPLATES,p.STORE_NAMES.LANES,p.STORE_NAMES.LINES,p.STORE_NAMES.PARAMS],"readwrite"),s=r.objectStore(p.STORE_NAMES.TEMPLATES),i=r.objectStore(p.STORE_NAMES.LANES),o=r.objectStore(p.STORE_NAMES.LINES),l=r.objectStore(p.STORE_NAMES.CASE_VERSIONS),d=r.objectStore(p.STORE_NAMES.PARAMS),c=IDBKeyRange.bound([e],[e,p.MAX_UNICODE_CHAR]);s.delete(c),i.delete(c),o.delete(c),d.delete(c),l.delete(e),r.oncomplete=()=>n(),r.onerror=e=>a(new Error(`事务失败:${e.target.error.message}`))}))}_promisifyRequest(e){return new Promise((t,n)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>n(e.error)})}forceInitSceneConfig(e,t,n){return e&&t?this._clearSceneData(e).then(()=>{const a=this.setUpData(e,t,n);return this.batchAddConfig(a)}).catch(e=>{throw new Error(`强制初始化场景配置失败:${e.message}`)}):Promise.reject(new Error("caseId和versionCode为强制初始化的必传参数"))}setUpData(e,t,n){const a=n.templates.map(t=>({...t,caseId:e})),r=n.lanes.map(t=>({...t,caseId:e})),s=n.lines.map(t=>({...t,caseId:e})),i=n.params.map(t=>({...t,caseId:e}));return{caseVersion:{caseId:e,versionCode:t,updateTime:new Date},templates:a,lanes:r,lines:s,params:i}}checkConfigIntegrity(e,t){return this.getCaseVersionByCaseId(e).then(n=>!(!n||n.versionCode!==t)&&this.getTemplatesByCaseId(e).then(t=>{if(0===t.length)return!0;const n=t[0].templateId;return this.getLanesByTemplateId(e,n).then(t=>{if(0===t.length)return!0;const n=t[0].laneId;return this.getLinesByLaneId(e,n).then(e=>0===e.length)})}))}_initSceneConfig(e){const{caseVersion:t}=e,{caseId:n,versionCode:a}=t;return this.getCaseVersionByCaseId(n).then(t=>{if(!t)return this.batchAddConfig(e);const r=this._compareVersion(a,t.versionCode);if(r>0)return this._clearSceneData(n).then(()=>this.batchAddConfig(e));if(0===r)return console.log(`场景${n}已存在版本${a},无需重复创建`),Promise.resolve(t);throw new Error(`场景${n}当前版本${t.versionCode}高于待创建版本${a}。`)})}saveSceneConfig(e,t,n){if(!e||!t)return Promise.reject(new Error("caseId和versionCode为必传参数"));if(!Array.isArray(n.templates)||!Array.isArray(n.lanes)||!Array.isArray(n.lines))return Promise.reject(new Error("templates/lanes/lines必须为数组"));const a=this.setUpData(e,t,n);return this._initSceneConfig(a)}batchAddConfig(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([p.STORE_NAMES.CASE_VERSIONS,p.STORE_NAMES.TEMPLATES,p.STORE_NAMES.LANES,p.STORE_NAMES.LINES,p.STORE_NAMES.PARAMS],"readwrite");r.objectStore(p.STORE_NAMES.CASE_VERSIONS).put(e.caseVersion);const s=r.objectStore(p.STORE_NAMES.TEMPLATES);e.templates.forEach(e=>s.put(e));const i=r.objectStore(p.STORE_NAMES.LANES);e.lanes.forEach(e=>i.put(e));const o=r.objectStore(p.STORE_NAMES.LINES);e.lines.forEach(e=>o.put(e));const l=r.objectStore(p.STORE_NAMES.PARAMS);e.params.forEach(e=>l.put(e)),r.oncomplete=()=>n(e),r.onerror=e=>a(new Error(`批量添加配置失败:${e.target.error.message}`))}))}upsertCaseVersion(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([p.STORE_NAMES.CASE_VERSIONS],"readwrite").objectStore(p.STORE_NAMES.CASE_VERSIONS),s={updateTime:new Date,...e};this._promisifyRequest(r.put(s)).then(()=>n(s)).catch(e=>a(new Error(`更新场景版本失败:${e.message}`)))}))}getCaseVersionByCaseId(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([p.STORE_NAMES.CASE_VERSIONS],"readonly").objectStore(p.STORE_NAMES.CASE_VERSIONS);this._promisifyRequest(r.get(e)).then(e=>n(e||null)).catch(e=>a(new Error(`查询场景版本失败:${e.message}`)))}))}getConfigByCaseId(e){return e?Promise.all([this.getCaseVersionByCaseId(e),this.getTemplatesByCaseId(e),this.getParamsByCaseId(e)]).then(([t,n,a])=>{const r=n.map(t=>this.getLanesByTemplateId(e,t.templateId).then(n=>{const a=n.map(t=>this.getLinesByLaneId(e,t.laneId).then(e=>({...t,lines:e})));return Promise.all(a).then(e=>({...t,lanes:e}))}));return Promise.all(r).then(e=>({caseVersion:t,templates:e,params:a}))}).catch(e=>{throw new Error(`查询场景配置失败:${e.message}`)}):Promise.reject(new Error("caseId为必传参数"))}getConfigByTemplateId(e,t){if(!e||!t)return Promise.reject(new Error("caseId为必传参数"));const n={};return this.getLanesByTemplateId(e,t).then(t=>{const a=t.map(t=>this.getLinesByLaneId(e,t.laneId));return Promise.all(a).then(e=>{e.forEach((e,n)=>{t[n].lines=e}),n.lanes=t})}).then(()=>this.getTemplateById(e,t)).then(e=>(e.lanes=n.lanes,Promise.resolve(e)))}deleteCaseVersion(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([p.STORE_NAMES.CASE_VERSIONS],"readwrite").objectStore(p.STORE_NAMES.CASE_VERSIONS);this._promisifyRequest(r.delete(e)).then(()=>n()).catch(e=>a(new Error(`删除场景版本失败:${e.message}`)))}))}upsertTemplate(e){return this._openDB().then(t=>new Promise((n,a)=>{if(!e.caseId)return void a(new Error("模板数据必须包含caseId"));const r=t.transaction([p.STORE_NAMES.TEMPLATES],"readwrite").objectStore(p.STORE_NAMES.TEMPLATES),s={...e,createDate:e.createDate?new Date(e.createDate):new Date,updateDate:e.updateDate?new Date(e.updateDate):null};return delete s.lanes,this._promisifyRequest(r.put(s)).then(()=>n(s)).catch(e=>a(new Error(`更新模板失败:${e.message}`)))}))}getTemplateById(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([p.STORE_NAMES.TEMPLATES],"readonly").objectStore(p.STORE_NAMES.TEMPLATES);this._promisifyRequest(s.get([e,t])).then(e=>a(e||null)).catch(e=>r(new Error(`查询模板失败:${e.message}`)))}))}getTemplatesByCaseId(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([p.STORE_NAMES.TEMPLATES],"readonly").objectStore(p.STORE_NAMES.TEMPLATES),s=IDBKeyRange.bound([e],[e,p.MAX_UNICODE_CHAR]);this._promisifyRequest(r.getAll(s)).then(e=>{n(e||[])}).catch(e=>a(new Error(`查询场景下模板失败:${e.message}`)))}))}deleteTemplate(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([p.STORE_NAMES.TEMPLATES],"readwrite").objectStore(p.STORE_NAMES.TEMPLATES);this._promisifyRequest(s.delete([e,t])).then(()=>a()).catch(e=>r(new Error(`删除模板失败:${e.message}`)))}))}upsertLane(e,t){return this._openDB().then(n=>new Promise((a,r)=>{if(!e||!t.templateId)return void r(new Error("泳道数据必须包含caseId和templateId"));const s=n.transaction([p.STORE_NAMES.LANES],"readwrite").objectStore(p.STORE_NAMES.LANES),i={...t,caseId:e,updateDate:t.updateDate?new Date(t.updateDate):new Date};this._promisifyRequest(s.put(i)).then(()=>a(i)).catch(e=>r(new Error(`更新泳道失败:${e.message}`)))}))}getLaneById(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([p.STORE_NAMES.LANES],"readonly").objectStore(p.STORE_NAMES.LANES);this._promisifyRequest(s.get([e,t])).then(e=>a(e||null)).catch(e=>r(new Error(`查询泳道失败:${e.message}`)))}))}getLanesByTemplateId(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([p.STORE_NAMES.LANES],"readonly").objectStore(p.STORE_NAMES.LANES),i=IDBKeyRange.bound([e],[e,p.MAX_UNICODE_CHAR]);this._promisifyRequest(s.getAll(i)).then(e=>e.filter(e=>e.templateId===t)).then(e=>a(e||[])).catch(e=>r(new Error(`查询模板下泳道失败:${e.message}`)))}))}deleteLaneByLaneIds(e,t){return Array.isArray(t)&&0!==t.length?this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([p.STORE_NAMES.LANES],"readwrite"),i=s.objectStore(p.STORE_NAMES.LANES);t.map(t=>this._promisifyRequest(i.delete([e,t]))),s.oncomplete=()=>a(),s.onerror=e=>r(new Error(`删除泳道失败:${e.target.error.message}`))})):Promise.resolve()}upsertLine(e,t){return this._openDB().then(n=>new Promise((a,r)=>{if(!e||!t.laneId)return void r(new Error("线条数据必须包含caseId和laneId"));const s=n.transaction([p.STORE_NAMES.LINES],"readwrite").objectStore(p.STORE_NAMES.LINES),i={...t,caseId:e,updateDate:t.updateDate?new Date(t.updateDate):new Date};this._promisifyRequest(s.put(i)).then(()=>a(i)).catch(e=>r(new Error(`更新线条失败:${e.message}`)))}))}getLineById(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([p.STORE_NAMES.LINES],"readonly").objectStore(p.STORE_NAMES.LINES);this._promisifyRequest(s.get([e,t])).then(e=>a(e||null)).catch(e=>r(new Error(`查询线条失败:${e.message}`)))}))}getLinesByLaneId(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([p.STORE_NAMES.LINES],"readonly").objectStore(p.STORE_NAMES.LINES),i=IDBKeyRange.bound([e],[e,p.MAX_UNICODE_CHAR]);this._promisifyRequest(s.getAll(i)).then(e=>e.filter(e=>e.laneId===t)).then(e=>a(e||[])).catch(e=>r(new Error(`查询泳道下线条失败:${e.message}`)))}))}deleteLineByIds(e,t){return Array.isArray(t)&&0!==t.length?this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([p.STORE_NAMES.LINES],"readwrite"),i=s.objectStore(p.STORE_NAMES.LINES);t.map(t=>this._promisifyRequest(i.delete([e,t]))),s.oncomplete=()=>a(),s.onerror=e=>r(new Error(`批量删除线条失败:${e.target.error.message}`))})):Promise.resolve()}upsertParam(e){return this._openDB().then(t=>new Promise((n,a)=>{if(!e.caseId)return void a(new Error("参数数据必须包含caseId"));const r=t.transaction([p.STORE_NAMES.PARAMS],"readwrite").objectStore(p.STORE_NAMES.PARAMS),s={...e,updateDate:e.updateDate?new Date(e.updateDate):new Date};this._promisifyRequest(r.put(s)).then(()=>n(s)).catch(e=>a(new Error(`更新参数失败:${e.message}`)))}))}getParamById(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([p.STORE_NAMES.PARAMS],"readonly").objectStore(p.STORE_NAMES.PARAMS);this._promisifyRequest(s.get([e,t])).then(e=>a(e||null)).catch(e=>r(new Error(`查询参数失败:${e.message}`)))}))}getParamsByCaseId(e){return this._openDB().then(t=>new Promise((n,a)=>{const r=t.transaction([p.STORE_NAMES.PARAMS],"readonly").objectStore(p.STORE_NAMES.PARAMS),s=IDBKeyRange.bound([e],[e,p.MAX_UNICODE_CHAR]);this._promisifyRequest(r.getAll(s)).then(e=>n(e||[])).catch(e=>a(new Error(`查询场景下参数失败:${e.message}`)))}))}deleteParamById(e,t){return this._openDB().then(n=>new Promise((a,r)=>{const s=n.transaction([p.STORE_NAMES.PARAMS],"readwrite").objectStore(p.STORE_NAMES.PARAMS);this._promisifyRequest(s.delete([e,t])).then(()=>a()).catch(e=>r(new Error(`删除参数失败:${e.message}`)))}))}}const u=new p;function f(e){e&&Array.isArray(e.lines)&&e.lines.sort((e,t)=>(e.lineSort??0)-(t.lineSort??0))}function g(e){Array.isArray(e)&&(e.sort((e,t)=>(e.sort??0)-(t.sort??0)),e.forEach(e=>f(e)))}function S(e){return Array.isArray(e)&&0!==e.length?(e.sort((e,t)=>(e.sort??0)-(t.sort??0)),e.forEach(e=>g(e.lanes)),e):e}function y(e){return e?e.lineId&&e.laneId?"line":e.laneId&&e.templateId&&!e.lineId?"lane":e.templateId?"template":null:null}function b(e=!0){let t="";return t="undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}),e?t.replace(/-/g,""):t}class v{constructor(e,t,n,a=!0){this.caseId=e,this.versionCode=t,this.dataSource=n,this.flatData=a,this.ready=u.saveSceneConfig(e,t,n).catch(a=>(console.warn(`初始化数据库出错,直接重置:${a.message}`),u.forceInitSceneConfig(e,t,n)))}getUserTemplates(){return this.ready.then(()=>u.getConfigByCaseId(this.caseId))}upsertTemplate(e){let t;if(e.templateId)t=u.upsertTemplate(e);else{const n=b();if(e.templateId=n,e.baseTemplate){const a={};t=u.getLanesByTemplateId(this.caseId,e.baseTemplate).then(e=>{a.lanes=e;const t=e.map(e=>u.getLinesByLaneId(this.caseId,e.laneId));return Promise.all(t).then(e=>{const t=[];e.forEach((e,r)=>{const s=b();a.lanes[r].laneId=s,a.lanes[r].templateId=n,a.lanes[r].createUser=void 0,e.forEach(e=>{e.lineId=b(),e.laneId=s,e.createUser=void 0,t.push(e)})}),a.lines=t})}).then(()=>{a.templates=[e]}).then(()=>{a.params=[];const e=u.setUpData(this.caseId,this.versionCode,a);return u.batchAddConfig(e)}).then(()=>u.getTemplateById(this.caseId,n))}else t=u.upsertTemplate(e)}return"1"===e.isPublic?t.then(()=>u.getTemplatesByCaseId(this.caseId).then(t=>t.filter(t=>t.templateId!==e.templateId)).then(e=>{e.forEach(e=>{e.isPublic="0"});const t=e.map(e=>u.upsertTemplate(e));return Promise.all(t)}).then(()=>u.getConfigByTemplateId(this.caseId,e.templateId))):t}deleteTemplate(e){return u.getLanesByTemplateId(this.caseId,e.templateId).then(e=>{const t=e.map(e=>e.laneId);let n=t.map(e=>u.getLinesByLaneId(this.caseId,e));return Promise.all(n).then(e=>{const t=e.reduce((e,t)=>e.concat(t),[]).map(e=>e.lineId);return u.deleteLineByIds(this.caseId,t)}).then(()=>Promise.resolve(t))}).then(e=>u.deleteLaneByLaneIds(this.caseId,e)).then(()=>u.deleteTemplate(this.caseId,e.templateId)).then(()=>Promise.resolve(e))}upsertLane(e){return e.laneId||(e.laneId=b()),e.lines||(e.lines=[]),u.upsertLane(this.caseId,e)}delLane(e){const{lines:t,laneId:n}=e,a=t.map(e=>e.lineId);return u.deleteLineByIds(this.caseId,a).then(()=>u.deleteLaneByLaneIds(this.caseId,[n])).then(()=>Promise.resolve(e))}upsertLine(e){return e.lineId||(e.lineId=b()),e.laneId?u.upsertLine(this.caseId,e):Promise.reject(new Error("更新线条数据的时候,必须laneId不能为空!"))}delLine(e){return e.laneId?u.deleteLineByIds(this.caseId,[e.lineId]):Promise.reject(new Error("更新线条数据的时候,必须laneId不能为空!"))}restoreSetting(){return u.forceInitSceneConfig(this.caseId,this.versionCode,this.dataSource)}getType(){return"local-default"}}class E{static createStrategy(e){if("local"===e.type){let n;if((t=e.dataSource)&&Array.isArray(t.templates)&&Array.isArray(t.lanes)&&Array.isArray(t.lines)&&(0===t.templates.length||!t.templates[0].lanes))n={...e};else{if(!function(e){return Array.isArray(e)?0===e.length||!!e[0]&&Array.isArray(e[0].lanes):!!e&&Array.isArray(e.templates)&&(0===e.templates.length||Array.isArray(e.templates[0].lanes))}(e.dataSource))throw new Error("策略数据源格式不匹配");{const t=function(e){const t=[],n=[],a=[];for(const r of e){const{lanes:e,...s}=r;s.templateId||(s.templateId=b()),t.push(s);for(const t of e||[]){const{lines:e,...r}=t;r.templateId=s.templateId,r.laneId||(r.laneId=b()),n.push(r);for(const t of e||[])t.laneId=r.laneId,t.lineId||(t.lineId=b()),a.push(t)}}return{templates:t,lanes:n,lines:a}}(e.dataSource.templates);n={...e,dataSource:{...t,params:e.dataSource.params}}}}const{caseId:a,versionCode:r,dataSource:s}=n;return new v(a,r,s,!1)}return new h(e);var t}}var I={inject:["upsertTemplate","setTargetData","setExpanded"],props:{currentTemplate:{type:Object},formDisable:{type:Boolean},userTemplate:{type:Array},caseId:{type:String,default:""}},data(){return{formData:Object.assign({sort:void 0},this.currentTemplate),rules:{templateName:[{required:!0,message:"请输入模板名称",trigger:"blur"}]},saving:!1}},methods:{editable(){this.$emit("editable")},submitForm(e){this.$refs[e].validate(e=>{if(!e)return;if("function"!=typeof this.upsertTemplate)return void this.$message({type:"error",message:"没有配置模板管理方法"});this.saving=!0;const t={...this.formData};t.caseId||(t.caseId=this.caseId);const n=this.upsertTemplate(t);n instanceof Promise?n.then(e=>{this.setTargetData(e)}).then(()=>{this.$message({type:"success",message:"保存成功"})}).finally(()=>{this.saving=!1}):this.saving=!1})}},computed:{baseTemplate(){return this.userTemplate?[{name:"空白模板",value:""},...this.userTemplate.map(e=>({name:e.templateName,value:e.templateId}))]:[{name:"空白模板",value:""}]}},watch:{currentTemplate:{deep:!0,handler:function(e){this.formData=Object.assign({},e)}}}};function _(e,t,n,a,r,s,i,o,l,d){"boolean"!=typeof i&&(l=o,o=i,i=!1);const c="function"==typeof n?n.options:n;let m;if(e&&e.render&&(c.render=e.render,c.staticRenderFns=e.staticRenderFns,c._compiled=!0,r&&(c.functional=!0)),a&&(c._scopeId=a),s?(m=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),t&&t.call(this,l(e)),e&&e._registeredComponents&&e._registeredComponents.add(s)},c._ssrRegister=m):t&&(m=i?function(e){t.call(this,d(e,this.$root.$options.shadowRoot))}:function(e){t.call(this,o(e))}),m)if(c.functional){const e=c.render;c.render=function(t,n){return m.call(n),e(t,n)}}else{const e=c.beforeCreate;c.beforeCreate=e?[].concat(e,m):[m]}return n}s(".kd-lane-template-content {\n display: flex;\n flex-direction: column;\n align-content: center;\n}\n.kd-lane-template-content .template-buttons {\n text-align: center;\n}");const T=I;var x=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"kd-lane-template-content"},[n("el-form",{ref:"template",attrs:{rules:e.rules,model:e.formData,"label-width":"120px"}},[n("el-form-item",{attrs:{label:"模板名称",prop:"templateName"}},[n("el-input",{attrs:{disabled:"SYSTEM_USER"==e.currentTemplate.createUser||e.formDisable},model:{value:e.formData.templateName,callback:function(t){e.$set(e.formData,"templateName",t)},expression:"formData.templateName"}})],1),e._v(" "),n("el-form-item",{attrs:{label:"默认模板",prop:"isPublic"}},[n("el-radio-group",{attrs:{disabled:e.formDisable},model:{value:e.formData.isPublic,callback:function(t){e.$set(e.formData,"isPublic",t)},expression:"formData.isPublic"}},[n("el-radio",{attrs:{label:"1"}},[e._v("是")]),e._v(" "),n("el-radio",{attrs:{label:"0"}},[e._v("否")])],1)],1),e._v(" "),n("el-form-item",{attrs:{label:"曲线高度占比",prop:"col1"}},[n("el-select",{attrs:{disabled:e.formDisable},model:{value:e.formData.col1,callback:function(t){e.$set(e.formData,"col1",t)},expression:"formData.col1"}},[n("el-option",{attrs:{value:"0.5",label:"50%"}}),e._v(" "),n("el-option",{attrs:{value:"0.6",label:"60%"}}),e._v(" "),n("el-option",{attrs:{value:"0.7",label:"70%"}}),e._v(" "),n("el-option",{attrs:{value:"0.8",label:"80%"}}),e._v(" "),n("el-option",{attrs:{value:"0.9",label:"90%"}}),e._v(" "),n("el-option",{attrs:{value:"1",label:"全屏"}})],1)],1),e._v(" "),n("el-form-item",{directives:[{name:"show",rawName:"v-show",value:!e.currentTemplate.templateId,expression:"!currentTemplate.templateId"}],attrs:{label:"选择基础模板",prop:"lineType",disabled:e.formDisable}},[n("el-select",{attrs:{placeholder:"请选择"},model:{value:e.formData.baseTemplate,callback:function(t){e.$set(e.formData,"baseTemplate",t)},expression:"formData.baseTemplate"}},e._l(e.baseTemplate,function(e){return n("el-option",{key:e.value,attrs:{label:e.name,value:e.value}})}),1)],1),e._v(" "),n("el-form-item",{attrs:{label:"顺序",prop:"sort","label-width":"120px"}},[n("el-input",{attrs:{disabled:e.formDisable},model:{value:e.formData.sort,callback:function(t){e.$set(e.formData,"sort",e._n(t))},expression:"formData.sort"}})],1)],1),e._v(" "),n("div",{staticClass:"template-buttons"},[n("el-button",{on:{click:e.editable}},[e._v("编辑")]),e._v(" "),n("el-button",{attrs:{type:"primary",disabled:e.formDisable,loading:e.saving},on:{click:function(t){return e.submitForm("template")}}},[e._v("保存")])],1)],1)};x._withStripped=!0;const C=_({render:x,staticRenderFns:[]},undefined,T,undefined,false,undefined,!1,void 0,void 0,void 0);var w={inject:["upsertLane","setTargetData","setExpanded"],props:{laneInfo:{type:Object},caseId:{type:String,default:""},formDisable:{type:Boolean}},data(){return{formData:Object.assign(this.laneInfo),rules:{sort:[{required:!0,message:"请输入泳道顺序",trigger:"blur"}]},saving:!1}},methods:{editable(){this.$emit("editable")},submitForm(e){this.$refs[e].validate(e=>{if(!e)return;if("function"!=typeof this.upsertLane)return void this.$message({type:"error",message:"没有配置泳道管理方法"});this.saving=!0;const t={...this.formData};t.caseId||(t.caseId=this.caseId);const n=this.upsertLane(t);n instanceof Promise?n.then(e=>{this.setTargetData(e)}).then(()=>{this.$message({type:"success",message:"保存成功"})}).finally(()=>{this.saving=!1}):this.saving=!1})}},computed:{},watch:{laneInfo:{deep:!0,handler:function(e){this.formData=Object.assign({},e)}}}};s(".kd-lane-lane-content {\n display: flex;\n flex-direction: column;\n align-content: center;\n}\n.kd-lane-lane-content .template-buttons {\n text-align: center;\n}");const A=w;var D=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"kd-lane-lane-content"},[n("el-form",{ref:"template",attrs:{rules:e.rules,model:e.formData,"label-width":"120px"}},[n("el-form-item",{attrs:{label:"泳道顺序",prop:"sort"}},[n("el-input",{attrs:{disabled:e.formDisable},model:{value:e.formData.sort,callback:function(t){e.$set(e.formData,"sort",t)},expression:"formData.sort"}})],1)],1),e._v(" "),n("div",{staticClass:"template-buttons"},[n("el-button",{on:{click:e.editable}},[e._v("编辑")]),e._v(" "),n("el-button",{attrs:{type:"primary",disabled:e.formDisable,loading:e.saving},on:{click:function(t){return e.submitForm("template")}}},[e._v("保存")])],1)],1)};D._withStripped=!0;const N=_({render:D,staticRenderFns:[]},undefined,A,undefined,false,undefined,!1,void 0,void 0,void 0);var k={inject:["upsertLine","setTargetData","setExpanded"],props:{template:{type:Object},formDisable:{type:Boolean},params:{type:Array}},mounted(){},data(){const e=(e,t,n)=>{isNaN(t)?n(new Error("请输入数字值")):n()};return{formData:Object.assign({},this.template),lines:[{name:"直线",value:"solid"},{name:"虚线",value:"dashed"},{name:"点线",value:"dotted"},{name:"面积",value:"area"}],lineWidthSliderMarks:{1:"1",2:"2",3:"3",4:"4"},rules:{min:[{required:!0,message:"请输入最小值",trigger:"blur"},{validator:e,trigger:"blur"}],lineSort:[{required:!0,message:"请输入曲线顺序(1-10)",trigger:"blur"},{type:"number",message:"顺序必须为数字值"}],max:[{required:!0,message:"请输入最大值",trigger:"blur"},{validator:e,trigger:"blur"}],lineSize:[{required:!0,message:"请选择曲线粗细",trigger:"blur"}],lineColor:[{required:!0,message:"请选择曲线颜色",trigger:"blur"}],lineType:[{required:!0,message:"请选择线型",trigger:"blur"}],paramId:[{required:!0,message:"请选择参数名称",trigger:"blur"}]}}},methods:{editable(){this.$emit("editable")},submitForm(e){this.$refs[e].validate().then(()=>{if(!(this.upsertLine instanceof Function))return Promise.reject(new Error("未配置线条设置函数"));{const e=this.upsertLine(this.formData);e instanceof Promise?e.then(e=>{this.setTargetData(e)}).then(()=>{this.$message({type:"success",message:"保存成功"})}).finally(()=>{this.saving=!1}):this.saving=!1}}).catch(e=>{console.log(e)})}},watch:{template:{immediate:!1,deep:!0,handler(e){this.formData=Object.assign({},e)}}}};s(".kd-lane-line-content {\n width: 95%;\n display: flex;\n flex-direction: column;\n align-content: center;\n}\n.kd-lane-line-content .template-buttons {\n text-align: center;\n}");const L=k;var M=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"kd-lane-line-content"},[n("el-form",{ref:"template",attrs:{rules:e.rules,model:e.formData,disabled:e.formDisable}},[n("el-form-item",{attrs:{label:"参数名称",prop:"paramId","label-width":"120px"}},[n("el-select",{attrs:{filterable:"",placeholder:"请选择"},model:{value:e.formData.paramId,callback:function(t){e.$set(e.formData,"paramId",t)},expression:"formData.paramId"}},e._l(e.params,function(e){return n("el-option",{key:e.paramId,attrs:{label:e.paramName,value:e.paramId}})}),1)],1),e._v(" "),n("el-form-item",{attrs:{label:"最小值",prop:"min","label-width":"120px"}},[n("el-input",{model:{value:e.formData.min,callback:function(t){e.$set(e.formData,"min",t)},expression:"formData.min"}})],1),e._v(" "),n("el-form-item",{attrs:{label:"最大值",prop:"max","label-width":"120px"}},[n("el-input",{model:{value:e.formData.max,callback:function(t){e.$set(e.formData,"max",t)},expression:"formData.max"}})],1),e._v(" "),n("el-form-item",{attrs:{label:"曲线粗细",prop:"lineSize","label-width":"120px"}},[n("el-input",{attrs:{max:4,min:1,type:"number"},model:{value:e.formData.lineSize,callback:function(t){e.$set(e.formData,"lineSize",t)},expression:"formData.lineSize"}})],1),e._v(" "),n("el-form-item",{attrs:{label:"曲线颜色",prop:"lineColor","label-width":"120px"}},[n("el-color-picker",{attrs:{disabled:e.formData.isGradient},model:{value:e.formData.lineColor,callback:function(t){e.$set(e.formData,"lineColor",t)},expression:"formData.lineColor"}})],1),e._v(" "),n("el-form-item",{attrs:{label:"线型",prop:"lineType","label-width":"120px"}},[n("el-select",{attrs:{placeholder:"请选择",disabled:e.formData.isGradient},model:{value:e.formData.lineType,callback:function(t){e.$set(e.formData,"lineType",t)},expression:"formData.lineType"}},e._l(e.lines,function(e){return n("el-option",{key:e.value,attrs:{label:e.name,value:e.value}})}),1)],1),e._v(" "),n("el-form-item",{attrs:{label:"曲线顺序",prop:"lineSort","label-width":"120px"}},[n("el-input",{model:{value:e.formData.lineSort,callback:function(t){e.$set(e.formData,"lineSort",e._n(t))},expression:"formData.lineSort"}})],1),e._v(" "),e._e()],1),e._v(" "),n("div",{directives:[{name:"show",rawName:"v-show",value:"SYSTEM_USER"!=e.template.createUser,expression:"template.createUser != 'SYSTEM_USER'"}],staticClass:"template-buttons"},[n("el-button",{on:{click:e.editable}},[e._v("编辑")]),e._v(" "),n("el-button",{attrs:{type:"primary",disabled:e.formDisable},on:{click:function(t){return e.submitForm("template")}}},[e._v("保存")])],1)],1)};M._withStripped=!0;const R=_({render:M,staticRenderFns:[]},undefined,L,undefined,false,undefined,!1,void 0,void 0,void 0);var P={inject:["delTemplate","delLane","delLine"],provide(){return{setTargetData:this.setTargetData,setExpanded:this.setExpanded}},components:{LineEdit:R,TemplateEdit:C,LaneEdit:N},props:{contextItem:{type:Object,default:()=>{}},expended:{type:Object},caseId:{type:String,default:""},inputTempates:{type:Array,default:()=>[]},params:{type:Array,required:!0,default:()=>[]},paramsNameMap:{type:Object,default:()=>{},required:!0}},data:()=>({templateContentShow:!1,templateDisable:!1,laneContentShow:!1,lineContentShow:!1,templateInfo:{},laneInfo:{},lineInfo:{},dataType:"",curveConfigLoading:!1,expandedKeys:[],currentNodeKey:"",targetData:void 0,treeKey:""}),mounted(){},methods:{getLineDataLabel(e){if(!e)return"";const t=this.paramsNameMap[e.paramId];return t?t.paramName:e.paramId},setTargetData(e){this.targetData=e,this.setExpanded();switch(y(e)){case"template":this.templateContentShow=!0,this.laneContentShow=!1,this.lineContentShow=!1,this.templateDisable=!0,this.templateInfo=e;break;case"lane":this.templateContentShow=!1,this.laneContentShow=!0,this.lineContentShow=!1,this.templateDisable=!0,this.laneInfo=e;break;case"line":this.templateContentShow=!1,this.laneContentShow=!1,this.lineContentShow=!0,this.templateDisable=!0,this.lineInfo=e}},setExpanded(){const e=this.targetData;if(e){switch(y(e)){case"template":this.expandedKeys=[e.templateId],this.currentNodeKey=e.templateId;break;case"lane":this.expandedKeys=[e.laneId],this.currentNodeKey=e.laneId;break;case"line":this.expandedKeys=[e.lineId],this.currentNodeKey=e.lineId;break;default:this.expandedKeys=[],this.currentNodeKey=""}}else this.expandedKeys=[],this.currentNodeKey="";this.$refs.refTree&&this.$refs.refTree.setCurrentKey(this.currentNodeKey),this.treeKey=`treeKey${(new Date).getTime()}`},optionClicked(e){const{option:t={},item:n}=e;switch(t.key){case"delTemplate":this.askForDelTemplate(n);break;case"addLane":this.addLane(n);break;case"delLane":this.askForDelLane(n);break;case"addParam":this.addParam(n);break;case"delParam":this.delParam(n)}},hideContextMenu(){const e=this.$refs.vueSimpleContextMenu;e&&e.hideContextMenu()},showRightWindows(e,t,n){const a=this.judgeDataType(n);this.dataType=a,"SYSTEM_USER"!=t.createUser?this.$refs.vueSimpleContextMenu.showMenu(e,t):this.$message.warning("系统模板不能编辑")},clear(){this.expandedKeys=[],this.templateDisable=!0,this.templateContentShow=!1},editable(){this.templateDisable=!1},handleNodeClick(e){this.setTargetData(e)},judgeDataType(e){const{level:t,data:n={}}=e;return 1==t&&n.templateId?"template":2==t&&n.laneId&&n.templateId?"lane":3==t&&n.lineId?"line":null},addTemplate(){this.templateContentShow=!0,this.laneContentShow=!1,this.lineContentShow=!1,this.templateDisable=!1,this.templateInfo={isPublic:"0",baseTemplate:"",col1:"1"}},addLane(e){this.templateContentShow=!1,this.laneContentShow=!0,this.lineContentShow=!1,this.templateDisable=!1,this.laneInfo={templateId:e.templateId,isUsed:"1",sort:e.lanes.length+1}},addParam(e){this.templateContentShow=!1,this.laneContentShow=!1,this.lineContentShow=!0,this.templateDisable=!1,this.lineInfo={laneId:e.laneId,isUsed:"1",lineSize:2}},askForDelTemplate(e){this.$confirm("此操作将删除该模板, 是否继续?","提示",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then(()=>(e.bsflag="1",this.curveConfigLoading=!0,this.delTemplate instanceof Function?this.delTemplate(e):Promise.reject(new Error("未配置删除模板函数")))).catch(e=>{this.$message.error(e.message||"删除失败")}).finally(()=>{this.curveConfigLoading=!1})},askForDelLane(e){this.$confirm("此操作将删除该泳道, 是否继续?","提示",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then(()=>(e.bsflag="1",this.curveConfigLoading=!0,this.delLane instanceof Function?this.delLane(e):Promise.reject(new Error("未配置删除模板函数")))).catch(()=>{this.$message.error("删除失败")}).finally(()=>{this.curveConfigLoading=!1})},delParam(e){this.$confirm("此操作将删除该参数, 是否继续?","提示",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then(()=>(e.bsflag="1",this.delLine instanceof Function?this.delLine(e):Promise.reject(new Error("未配置删除线条函数")))).catch(e=>{this.$message.error(e.message||"删除失败")})}},computed:{contextMenuOptions(){switch(this.dataType){case"template":return[{name:"新增泳道",key:"addLane"},{name:"删除模板",key:"delTemplate"}];case"lane":return[{name:"新增参数",key:"addParam"},{name:"删除泳道",key:"delLane"}];case"line":return[{name:"删除参数",key:"delParam"}];default:return[]}},treeData(){if(this.inputTempates){const e=[];return this.inputTempates.forEach(t=>{const n={...t,id:t.templateId,label:t.templateName};n.children=[],t.lanes||(t.lanes=[]),t.lanes.forEach((e,t)=>{const a={...e,id:e.laneId,label:`泳道${t+1}`};n.children.push(a),a.lines||(a.lines=[]),a.children=[],e.lines.forEach(e=>{const t={...e,id:e.lineId,label:e.lineName||e.paramId};t.label=this.getLineDataLabel(e),a.children.push(t)})}),e.push(n)}),e}return[]},userTemplate(){return this.treeData?[...this.treeData]:[]}},watch:{contextItem:{immediate:!0,deep:!0,handler(e){this.setTargetData(Object.assign({},e))}}},beforeDestroy(){}};s(".kd-lane-el-container {\n height: 60vh;\n border: 1px solid var(--kd-lane-container-border-color, #333);\n width: 100%;\n}\n@media screen and (max-width: 1024px) {\n.kd-lane-el-container {\n height: 70vh;\n}\n}\n.kd-lane-el-container .rtd-config-side {\n border-right: 1px solid var(--kd-lane-container-border-color, #333);\n}\n.kd-lane-el-container .rtd-config-side-tree {\n height: 90%;\n overflow: auto;\n}\n.kd-lane-el-container .rtd-config-side-option {\n text-align: center;\n}\n.kd-lane-el-container .rtd-config-main {\n display: flex;\n align-content: center;\n justify-content: center;\n width: 100%;\n}");const $=P;var O=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-container",{directives:[{name:"loading",rawName:"v-loading",value:e.curveConfigLoading,expression:"curveConfigLoading"}],staticClass:"kd-lane-el-container"},[n("el-aside",{staticClass:"rtd-config-side",attrs:{width:"20%"}},[n("el-tree",{key:e.treeKey,ref:"refTree",staticClass:"rtd-config-side-tree",attrs:{data:e.treeData,"expand-on-click-node":!1,"current-node-key":e.currentNodeKey,"default-expanded-keys":e.expandedKeys,"node-key":"id","highlight-current":""},on:{"node-click":e.handleNodeClick,"node-expand":e.hideContextMenu,"node-collapse":e.hideContextMenu},scopedSlots:e._u([{key:"default",fn:function(t){var a=t.node,r=t.data;return n("span",{staticClass:"custom-tree-node",on:{contextmenu:function(t){return t.preventDefault(),e.showRightWindows(t,r,a)}}},[n("span",[e._v(e._s(a.label))]),e._v(" "),n("span",{directives:[{name:"show",rawName:"v-show",value:"1"==r.isPublic,expression:"data.isPublic == '1'"}],staticStyle:{"padding-left":"5px"}},[n("i",{staticClass:"el-icon-star-on"})])])}}])}),e._v(" "),n("div",{staticClass:"rtd-config-side-option"},[n("el-button",{on:{click:e.addTemplate}},[e._v("新增模板")])],1)],1),e._v(" "),n("el-main",{staticClass:"rtd-config-main"},[n("TemplateEdit",e._g({directives:[{name:"show",rawName:"v-show",value:e.templateContentShow,expression:"templateContentShow"}],attrs:{currentTemplate:e.templateInfo,"form-disable":e.templateDisable,userTemplate:e.userTemplate,caseId:e.caseId},on:{editable:e.editable}},e.$listeners)),e._v(" "),n("LaneEdit",e._g({directives:[{name:"show",rawName:"v-show",value:e.laneContentShow,expression:"laneContentShow"}],attrs:{laneInfo:e.laneInfo,"form-disable":e.templateDisable},on:{editable:e.editable}},e.$listeners)),e._v(" "),n("LineEdit",e._g({directives:[{name:"show",rawName:"v-show",value:e.lineContentShow,expression:"lineContentShow"}],attrs:{template:e.lineInfo,params:e.params,"form-disable":e.templateDisable},on:{editable:e.editable}},e.$listeners))],1),e._v(" "),n("VueSimpleContextMenu",{ref:"vueSimpleContextMenu",attrs:{"element-id":"kd-lane-chart-context-menu-2",options:e.contextMenuOptions},on:{"option-clicked":e.optionClicked}})],1)};O._withStripped=!0;const B=_({render:O,staticRenderFns:[]},undefined,$,undefined,false,undefined,!1,void 0,void 0,void 0);var j={props:{itemHeight:{type:Number,default:20},line:{type:Object,default:()=>{}},paramsNameMap:{type:Object,default:()=>{},required:!0},themeName:{type:String,default:void 0}},methods:{getParamName(e){if(!e)return"";const t=this.paramsNameMap[e.paramId];return t?`${t.paramName}${t.paramUnit}`:""},toggleIsUsed(){const e={...this.line};"1"==e.isUsed||1==e.isUsed?e.isUsed="0":e.isUsed="1",this.$emit("updateLine",e)}},computed:{gradientDisplay(){let e,t;return this.themeName&&this.line.themeConfig&&(e=this.line.themeConfig[this.themeName]?.lineColor),t=this.line.isGradient?{background:`${e||this.line.lineColor}`}:{},t},textColor(){let e;return this.themeName&&this.line.themeConfig&&!this.line.isGradient&&(e=this.line.themeConfig[this.themeName]?.lineColor),{color:e||this.line.lineColor}},headerItemStyle(){let e,t;return this.themeName&&this.line.themeConfig&&(e=this.line.themeConfig[this.themeName]?.lineColor),t="area"==this.line.lineType?this.line.isGradient?{}:{"box-shadow":`inset 0 0 8px 0px ${e||this.line.lineColor}`}:{"border-bottom":`2px ${this.line.lineType} ${e||this.line.lineColor}`},{height:`${this.itemHeight}px`,opacity:"1"==this.line.isUsed?1:.5,...t}}},watch:{}};s('@charset "UTF-8";\n.kd-lane-chart-container-header-item {\n color: var(--kd-lane-container-header-item-color, #333);\n border: unset;\n position: relative;\n cursor: pointer;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container {\n height: 100%;\n width: 100%;\n font-size: 10px;\n font-weight: bold;\n position: relative;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .left {\n position: absolute;\n left: 0;\n bottom: 2px;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .center {\n position: absolute;\n left: 50%;\n bottom: 2px;\n transform: translateX(-50%);\n /* 文字不换行,超出显示省略号 */\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .right {\n position: absolute;\n right: 0;\n bottom: 2px;\n}\n.kd-lane-chart-container-header-item .kd-lane-chart-container-text-container .gradient-display {\n position: absolute;\n height: 2px;\n left: 0;\n bottom: 0;\n right: 0;\n}');const U=j;var V=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"kd-lane-chart-container-header-item",style:e.headerItemStyle,on:{click:e.toggleIsUsed}},[n("div",{staticClass:"kd-lane-chart-container-text-container"},[n("span",{staticClass:"left",style:e.textColor},[e._v(e._s(e.line.min))]),e._v(" "),n("span",{staticClass:"center"},[e._v(e._s(e.getParamName(e.line)))]),e._v(" "),n("span",{staticClass:"right",style:e.textColor},[e._v(e._s(e.line.max))]),e._v(" "),n("div",{staticClass:"gradient-display",style:e.gradientDisplay})])])};V._withStripped=!0;const q=_({render:V,staticRenderFns:[]},undefined,U,undefined,false,undefined,!1,void 0,void 0,void 0);var K={name:"KdLaneChartContainer",provide(){return{upsertTemplate:this.upsertTemplate,delTemplate:this.delTemplate,upsertLane:this.upsertLane,delLane:this.delLane,upsertLine:this.upsertLine,delLine:this.delLine}},components:{HeaderItem:q,RealTimeCurveConfig:B},props:{config:{type:Object,required:!0,validator:function(e){if("object"!=typeof e||null===e)throw new Error("配置必须是一个对象");if(!("type"in e))throw new Error("配置必须包含 type 属性");if(!("caseId"in e)||!("versionCode"in e))throw new Error("配置必须包含 caseId, versionCode 属性");const{type:t}=e;if("local"===t){if(!("dataSource"in e)||null==e.dataSource)throw new Error("local 类型的配置必须包含 dataSource 属性");if(!("params"in e.dataSource))throw new Error("local 类型的配置 dataSource 必须包含 params 属性")}else{if("custom"!==t)throw new Error('type 必须是 "local" 或 "custom"');{const t=["getUserTemplates","upsertTemplate","delTemplate","upsertLane","delLane","upsertLine","delLine"];for(const n of t)if("function"!=typeof e[n])throw new Error(`${n} 必须是一个函数`)}}return!0}},headerPadding:{type:Number,default:4},headerItemHeight:{type:Number,default:20},itemGap:{type:Number,default:2},customMenuList:{type:Array,default:()=>[]},themeName:{type:String,default:void 0}},data:()=>({treeTemplates:null,isLoading:!1,strategy:null,currentTemplate:{},curveConfigVisible:!1,params:[],contextItem:void 0}),created(){this.strategy=E.createStrategy(this.$props.config),this.loadConfig()},mounted(){},methods:{setExpanded(){this.$refs.curveConfig.setExpanded()},delLine(e){return this.strategy.delLine(e).then(()=>{const t=this.currentTemplate.lanes,n=t.findIndex(t=>t.laneId==e.laneId);if(n<0)for(const t of this.treeTemplates){const{lanes:n}=t;for(const t of n)if(t.laneId==e.laneId){const{lines:n}=t,a=n.findIndex(t=>t.lineId==e.lineId);a<0?console.warn("要删除的线条在当前泳道中不存在?"):n.splice(a,1);break}}else{const a=t[n].lines.findIndex(t=>t.lineId==e.lineId);a<0?console.warn("要删除的线条在当前泳道中不存在?"):t[n].lines.splice(a,1),this.onLineChange(e)}})},upsertLine(e){return this.strategy.upsertLine(e).then(e=>{const t=this.currentTemplate.lanes,n=t.findIndex(t=>t.laneId==e.laneId);if(!(n<0)){const a=t[n],r=a.lines,s=r.findIndex(t=>t.lineId==e.lineId);return s<0?r.push(e):this.$set(r,s,e),this.$set(t,n,a),f(a),this.onLineChange(e),e}for(const t of this.treeTemplates){const{lanes:n}=t;for(const t of n)if(t.laneId==e.laneId){const{lines:n}=t,a=n.findIndex(t=>t.lineId==e.lineId);a<0?n.push(e):this.$set(n,a,e),f(t);break}}})},delLane(e){return this.strategy.delLane(e).then(e=>{const{templateId:t}=e,n=this.treeTemplates.findIndex(e=>e.templateId==t);if(n<0)return void console.warn(`template_id not found: '${t}'`);const a=this.treeTemplates[n],r=a.lanes.findIndex(t=>t.laneId==e.laneId);a.lanes.splice(r,1),this.currentTemplate.templateId==t&&this.setDefaultAndNotify()})},upsertLane(e){return this.strategy.upsertLane(e).then(e=>{const t=this.treeTemplates.findIndex(t=>t.templateId==e.templateId);if(t<0)console.warn("template not found");else{const n=this.treeTemplates[t],a=n.lanes||[],r=a.findIndex(t=>t.laneId==e.laneId);r<0?a.push(e):this.$set(a,r,e),g(n.lanes),n.templateId===this.currentTemplate.templateId&&this.setDefaultAndNotify()}return e})},delTemplate(e){return this.strategy.deleteTemplate(e).then(()=>{const t=this.treeTemplates.findIndex(t=>t.templateId===e.templateId);this.treeTemplates.splice(t,1),e.templateId==this.currentTemplate.templateId&&this.setDefaultAndNotify()})},upsertTemplate(e){return this.strategy.upsertTemplate(e).then(e=>{"1"==e.isPublic&&this.treeTemplates.forEach(e=>{e.isPublic="0"});const t=this.treeTemplates.findIndex(t=>t.templateId===e.templateId);if(t>=0){const n=this.treeTemplates[t],a=Object.assign({},n,e);this.$set(this.treeTemplates,t,a)}else this.treeTemplates.push(e);return S(this.treeTemplates),this.setDefaultAndNotify(),e})},onParentContextMenu(e){const t=".kd-lane-chart-lane-header";if(!(e.target&&(e.target.classList.contains(t)||e.target.closest(t)))){e.preventDefault();const t=this.$refs.vueSimpleContextMenu;t&&t.hideContextMenu()}},showContextMenu(e,t){e.stopPropagation(),this.$refs.vueSimpleContextMenu.showMenu(e,t)},optionClicked(e){const{option:t,item:n}=e;this.contextItem=n;const a=this.customMenuList.findIndex(e=>e.key==t.key);if(a<0){if("editTemplate"==t.key)this.curveConfigVisible=!0;else if("restoreSetting"==t.key)return this.restoreSetting()}else this.$emit("onCustomMenuClicked",e)},restoreSetting(){return this.strategy.restoreSetting().then(()=>{this.loadConfig()})},loadConfig(){this.isLoading=!0,this.strategy.getUserTemplates().then(e=>{const{templates:t=[],params:n=[]}=e;this.params=n,S(t),this.treeTemplates=t,this.setDefaultAndNotify()}).catch(e=>{console.error(`加载配置失败: ${this.$props.strategy.caseId},${this.$props.strategy.versionCode},${e.message}`)}).finally(()=>{this.isLoading=!1})},onLineChange(e){console.log("notify line change",e),this.$emit("line-change",e)},setDefaultAndNotify(){const e=this.treeTemplates.find(e=>"1"===e.isPublic);if(e)this.currentTemplate=e;else{const e=this.treeTemplates.find(e=>"SYSTEM_USER"==e.createUser);e?(e.isPublic="1",this.currentTemplate=e,this.strategy.upsertTemplate(e)):(this.treeTemplates[0].isPublic="1",this.currentTemplate=this.treeTemplates[0],this.strategy.upsertTemplate(this.currentTemplate))}this.$emit("template-change",this.currentTemplate)}},computed:{contextMenuOptions(){return"local"==this.config.type?[{name:"编辑模板",key:"editTemplate"},{name:"恢复默认",key:"restoreSetting"},...this.customMenuList]:[{name:"编辑模板",key:"template"},...this.customMenuList]},paramsNameMap(){const e={};for(const t of this.params)e[t.paramId]={paramName:t.paramName,paramUnit:t.paramUnit};return e},lineCount(){const{lanes:e=[]}=this.currentTemplate||{};return Math.max(...e.map(e=>e.lines?.length||0))},headerStyle(){const e={gap:`${this.itemGap}px`,padding:`${this.headerPadding}px`};if(this.currentTemplate){const{lanes:t=[]}=this.currentTemplate;if(t&&0!=t.length){const t=Math.max(0,this.lineCount-1);return{...e,height:this.lineCount*this.headerItemHeight+2*this.headerPadding+t*this.itemGap+"px","min-height":"60px"}}return{...e,height:"30%","min-height":"60px"}}return{...e,height:"30%","min-height":"60px"}},slotHeaderStyle(){if(this.currentTemplate){const{lanes:e=[]}=this.currentTemplate;if(e&&0!=e.length){const e=Math.max(0,this.lineCount-1);return{height:this.lineCount*this.headerItemHeight+2*this.headerPadding+e*this.itemGap+"px","min-height":"60px"}}return{height:"30%","min-height":"60px"}}return{height:"30%","min-height":"60px"}},darwAreaStyle(){return{top:this.headerStyle.height}}}};s(".kd-lane-chart-container {\n --border-color: var(--kd-lane-container-border-color, #333);\n --context-background-color: var(--kd-lane-container-context-background-color, #ecf0f1);\n --context-hover-color: var(--kd-lane-container-context-hover-color, #007aff);\n height: 100%;\n width: 100%;\n overflow: hidden;\n position: relative;\n border: 1px solid var(--border-color);\n display: flex;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-slot-container, .kd-lane-chart-container .kd-lane-chart-lane-container {\n height: 100%;\n min-width: 0;\n overflow: hidden;\n z-index: 1;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-slot-container .kd-lane-chart-lane-header, .kd-lane-chart-container .kd-lane-chart-lane-container .kd-lane-chart-lane-header {\n max-height: 40%;\n border-bottom: 1px solid var(--border-color);\n overflow: hidden;\n z-index: 2;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-container {\n flex: 1;\n}\n.kd-lane-chart-container .kd-lane-chart-lane-slot-container {\n width: auto;\n}\n.kd-lane-chart-container .border-left {\n border-left: 1px solid var(--border-color);\n}\n.kd-lane-chart-container .kd-lane-chart-container-draw-area {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n border: none;\n}\n.kd-lane-chart-container .vue-simple-context-menu {\n background-color: var(--context-background-color);\n position: fixed;\n}\n.kd-lane-chart-container .vue-simple-context-menu .vue-simple-context-menu__item:hover {\n background: var(--context-hover-color);\n}");const F=K;var H=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"loading",rawName:"v-loading",value:e.isLoading,expression:"isLoading"}],staticClass:"kd-lane-chart-container",on:{contextmenu:e.onParentContextMenu}},[e.currentTemplate&&e.currentTemplate.lanes&&e.currentTemplate.lanes.length>0?[e._l(e.currentTemplate.lanes||[],function(t,a){return[e.$scopedSlots["lane"+t.laneId]?n("div",{key:t.laneId,staticClass:"kd-lane-chart-lane-slot-container",class:{"border-left":0!=a}},[n("div",{staticClass:"kd-lane-chart-lane-header",style:e.slotHeaderStyle},[e._t("lane"+t.laneId,null,{lane:t})],2)]):e.$slots["lane"+t.laneId]?n("div",{key:""+t.laneId,staticClass:"kd-lane-chart-lane-slot-container",class:{"border-left":0!=a}},[n("div",{staticClass:"kd-lane-chart-lane-header",style:e.slotHeaderStyle},[e._t("lane"+t.laneId,null,{lane:t})],2)]):[n("div",{key:t.laneId,staticClass:"kd-lane-chart-lane-container",class:{"border-left":0!=a}},[n("div",{staticClass:"kd-lane-chart-lane-header",style:e.headerStyle,on:{contextmenu:function(n){return n.preventDefault(),e.showContextMenu(n,t)}}},e._l(t.lines||[],function(t){return n("HeaderItem",{key:t.lineId,attrs:{itemHeight:e.headerItemHeight,line:t,paramsNameMap:e.paramsNameMap,themeName:e.themeName},on:{updateLine:e.upsertLine},nativeOn:{contextmenu:function(n){return n.preventDefault(),e.showContextMenu(n,t)}}})}),1)])]]})]:[n("div",{staticClass:"kd-lane-chart-lane-container"},[n("div",{staticClass:"kd-lane-chart-lane-header",style:e.headerStyle,on:{contextmenu:function(t){return t.preventDefault(),e.showContextMenu.apply(null,arguments)}}})])],e._v(" "),n("div",{staticClass:"kd-lane-chart-container-draw-area",style:e.darwAreaStyle},[e._t("draw-slot")],2),e._v(" "),n("VueSimpleContextMenu",{ref:"vueSimpleContextMenu",attrs:{"element-id":"kd-lane-chart-context-menu",options:e.contextMenuOptions},on:{"option-clicked":e.optionClicked}}),e._v(" "),n("el-dialog",{attrs:{title:"泳道模板设置",visible:e.curveConfigVisible},on:{"update:visible":function(t){e.curveConfigVisible=t},opened:e.setExpanded}},[n("RealTimeCurveConfig",e._g({ref:"curveConfig",attrs:{inputTempates:e.treeTemplates,caseId:e.strategy.caseId,params:e.params,paramsNameMap:e.paramsNameMap,contextItem:e.contextItem}},e.$listeners))],1)],2)};H._withStripped=!0;const X=_({render:H,staticRenderFns:[]},undefined,F,undefined,false,undefined,!1,void 0,void 0,void 0),z=e=>{e.use(a.default),e.component(d.name,d),e.component(X.name,X)};return"undefined"!=typeof window&&window.Vue&&window.Vue.use(z),{install:z}});
2
2
  //# sourceMappingURL=index.min.js.map
package/package.json CHANGED
@@ -1,43 +1,44 @@
1
- {
2
- "name": "kd-lane-container",
3
- "version": "0.0.3",
4
- "description": "kd-lane-chart-container",
5
- "main": "dist/cjs/index.js",
6
- "module": "dist/esm/index.js",
7
- "browser": "dist/umd/index.min.js",
8
- "scripts": {
9
- "build": "rollup -c && cp ../README.md ./",
10
- "link": "pnpm run build && pnpm link --global",
11
- "prepare": "pnpm run build"
12
- },
13
- "files": [
14
- "README.md"
15
- ],
16
- "keywords": [],
17
- "author": "Fozei",
18
- "license": "MIT",
19
- "dependencies": {
20
- "vue-simple-context-menu": "3.4.2"
21
- },
22
- "peerDependencies": {
23
- "element-ui": "^2.15.14",
24
- "vue": "^2.6.0",
25
- "v-click-outside": "^2.1.3"
26
- },
27
- "devDependencies": {
28
- "@rollup/plugin-babel": "^5.3.1",
29
- "@rollup/plugin-commonjs": "^22.0.0",
30
- "@rollup/plugin-node-resolve": "^13.3.0",
31
- "@rollup/plugin-terser": "^0.1.0",
32
- "rollup-plugin-peer-deps-external": "^2.2.4",
33
- "rollup-plugin-postcss": "^4.0.2",
34
- "rollup-plugin-visualizer": "^5.14.0",
35
- "rollup-plugin-vue": "^5.1.9",
36
- "sass": "^1.62.1",
37
- "vue-template-compiler": "^2.6.14"
38
- },
39
- "browserslist": [
40
- "> 1%",
41
- "not dead"
42
- ]
43
- }
1
+ {
2
+ "name": "kd-lane-container",
3
+ "version": "0.0.5",
4
+ "description": "kd-lane-chart-container",
5
+ "main": "dist/cjs/index.js",
6
+ "module": "dist/esm/index.js",
7
+ "browser": "dist/umd/index.min.js",
8
+ "scripts": {
9
+ "build": "rimraf dist && rollup -c && cp ../README.md ./",
10
+ "link": "pnpm run build && pnpm link --global",
11
+ "prepare": "pnpm run build"
12
+ },
13
+ "files": [
14
+ "README.md"
15
+ ],
16
+ "keywords": [],
17
+ "author": "Fozei",
18
+ "license": "MIT",
19
+ "dependencies": {
20
+ "vue-simple-context-menu": "3.4.2"
21
+ },
22
+ "peerDependencies": {
23
+ "element-ui": "^2.15.14",
24
+ "v-click-outside": "^2.1.3",
25
+ "vue": "^2.6.0"
26
+ },
27
+ "devDependencies": {
28
+ "@rollup/plugin-babel": "^5.3.1",
29
+ "@rollup/plugin-commonjs": "^22.0.0",
30
+ "@rollup/plugin-node-resolve": "^13.3.0",
31
+ "@rollup/plugin-terser": "^0.1.0",
32
+ "rimraf": "^6.1.2",
33
+ "rollup-plugin-peer-deps-external": "^2.2.4",
34
+ "rollup-plugin-postcss": "^4.0.2",
35
+ "rollup-plugin-visualizer": "^5.14.0",
36
+ "rollup-plugin-vue": "^5.1.9",
37
+ "sass": "^1.62.1",
38
+ "vue-template-compiler": "^2.6.14"
39
+ },
40
+ "browserslist": [
41
+ "> 1%",
42
+ "not dead"
43
+ ]
44
+ }
package/dist/README.md DELETED
@@ -1,406 +0,0 @@
1
- # KdLaneChartContainer 组件使用文档
2
-
3
- ## 1. 组件概述
4
-
5
- KdLaneChartContainer 是一个基于 Vue 开发的泳道图容器组件,用于展示和管理泳道模板、线条配置等。
6
-
7
- ### 1.1 设计思路
8
- - **逻辑分离**:将模板、泳道、参数的设置逻辑和绘制逻辑完全剥离,提高组件的可维护性和扩展性
9
- - **接口兼容**:提供了不依赖接口但是兼容接口实现的模板配置逻辑,既支持本地静态数据直接使用,也支持对接后端接口
10
- - **使用场景**:
11
- - 适合静态数据展示场景,无需后端接口即可运行
12
- - 适合合作单位使用,提供灵活的数据接入方式
13
- - **技术栈无关**:不限制绘制区技术栈,绘制逻辑完全由外部实现,只需要监听组件事件即可动态调整绘制内容
14
-
15
- ## 2. 组件功能
16
-
17
- ## 2. 组件功能
18
-
19
- - 加载和展示泳道模板
20
- - 支持自定义泳道头部
21
- - 提供上下文菜单操作
22
- - 支持自定义菜单扩展
23
- - 实时曲线配置功能
24
- - 模板和线条的增删改查操作
25
-
26
- ## 3. 组件引入
27
-
28
- ```javascript
29
- import KdLaneChartContainer from "./components/kd-lane/chart-container.vue";
30
-
31
- export default {
32
- components: {
33
- KdLaneChartContainer,
34
- },
35
- // ...
36
- };
37
- ```
38
-
39
- ## 4. 组件使用
40
-
41
- ### 4.1 基本使用
42
-
43
- ```vue
44
- <KdLaneChartContainer class="container" :config="config" :customMenuList="customMenuList" @onCustomMenuClicked="onCustomMenuClicked">
45
- <!-- 自定义插槽内容 -->
46
- </KdLaneChartContainer>
47
- ```
48
-
49
- ### 4.1 场景与版本控制
50
-
51
- #### 4.1.1 场景唯一标识规则
52
- - **caseId (场景ID)**:用于唯一标识不同的应用场景或业务模块。
53
- - 必须确保在同一应用中唯一,否则会导致数据混淆。
54
- - 建议使用业务模块名称或唯一的UUID。
55
- - 所有数据操作都将与该场景ID绑定,确保数据隔离。
56
-
57
- #### 4.1.2 版本号管理
58
- - **versionCode (版本号)**:用于管理不同版本的初始配置。
59
- - 当业务需求发生重大变更时,可以通过升级版本号来重置数据。
60
- - 版本号升级后,系统会自动清理旧版本数据并重新初始化。
61
- - 版本号必须为整数,建议从1开始递增。
62
-
63
- #### 4.1.3 数据初始化策略
64
- - 首次初始化:系统会将传入的`dataSource`保存为当前版本的初始配置。
65
- - 版本冲突:当检测到版本号变更时,系统会自动重置数据并使用新版本的配置。
66
- - 异常恢复:如果初始化过程中出现错误,系统会自动执行重置操作。
67
-
68
- ### 4.2 配置参数
69
-
70
- #### 4.2.1 本地数据源 (Local)
71
-
72
- ```javascript
73
- config: {
74
- type: "local", // 数据源类型,可选值: "local" | "custom"
75
- caseId: "demo", // 案例ID
76
- versionCode: 2, // 版本号
77
- dataSource: { // 数据源
78
- // 支持两种数据结构:
79
-
80
- // 1. 扁平结构 (推荐用于数据量大的场景)
81
- templates: [], // 模板数据
82
- lanes: [], // 泳道数据
83
- lines: [], // 线条数据
84
- params: [] // 参数数据
85
-
86
- // 2. 树形结构 (直观易读,不用关心数据ID,组件会自己补全和维护)
87
- // templates: [{
88
- // lanes: [{
89
- // lines: []
90
- // }]
91
- // }],
92
- // params: []
93
- }
94
- }
95
- ```
96
-
97
- #### 4.2.2 自定义数据源 (Custom)
98
-
99
- 当需要从服务器或自定义数据源获取和管理数据时,使用 `custom` 类型。需要实现以下CRUD方法:
100
-
101
- ```javascript
102
- config: {
103
- type: "custom", // 数据源类型,可选值: "local" | "custom"
104
- caseId: "demo", // 案例ID
105
- versionCode: 2, // 版本号
106
-
107
- // 自定义数据源必须实现的方法
108
- getUserTemplates() { /* 加载所有模板、泳道和线条数据 */ },
109
- upsertTemplate(data) { /* 新增或更新模板 */ },
110
- delTemplate(data) { /* 删除模板 */ },
111
- upsertLane(data) { /* 新增或更新泳道 */ },
112
- delLane(data) { /* 删除泳道 */ },
113
- upsertLine(data) { /* 新增或更新线条 */ },
114
- delLine(data) { /* 删除线条 */ },
115
-
116
- // 可选方法:恢复默认设置
117
- restoreSetting() { /* 恢复默认设置 */ }
118
- }
119
- ```
120
-
121
- 各方法参数和返回值说明:
122
-
123
- 1. `getUserTemplates()`
124
- - 返回值:`Promise<Object>` - 包含所有模板、泳道和线条数据的配置对象
125
- - 示例:
126
- ```json
127
- {
128
- "caseVersion": { "caseId": "case123", "versionCode": "v1.0" },
129
- "templates": [/* 模板数组 */],
130
- "params": []
131
- }
132
- ```
133
-
134
- 2. `upsertTemplate(data)`
135
- - 参数:`data` - 模板数据
136
- - 返回值:`Promise<Object>` - 插入或更新后的完整模板对象
137
-
138
- 3. `delTemplate(data)`
139
- - 参数:`data` - 模板数据(需包含`templateId`)
140
- - 返回值:`Promise<void>` - 操作成功或失败的Promise
141
-
142
- 4. `upsertLane(data)`
143
- - 参数:`data` - 泳道数据
144
- - 返回值:`Promise<Object>` - 插入或更新后的完整泳道对象
145
-
146
- 5. `delLane(lane)`
147
- - 参数:`lane` - 泳道数据(需包含`laneId`和`lines`数组)
148
- - 返回值:`Promise<void>` - 操作成功或失败的Promise
149
-
150
- 6. `upsertLine(data)`
151
- - 参数:`data` - 线条数据
152
- - 返回值:`Promise<Object>` - 插入或更新后的完整线条对象
153
-
154
- 7. `delLine(data)`
155
- - 参数:`data` - 线条数据(需包含`lineId`和`laneId`)
156
- - 返回值:`Promise<void>` - 操作成功或失败的Promise
157
-
158
- 8. `restoreSetting()` (可选)
159
- - 返回值:`Promise<void>` - 恢复默认设置的Promise
160
-
161
- ### 4.3 自定义菜单
162
-
163
- customMenuList用于在上下文菜单中添加自定义操作选项。当用户在泳道头部或线条上右键点击时,这些自定义选项会出现在上下文菜单中。
164
-
165
- #### 4.3.1 菜单结构
166
- ```javascript
167
- customMenuList: [
168
- {
169
- name: "单屏时长", // 菜单项显示名称
170
- key: "timeRange" // 菜单项唯一标识
171
- },
172
- {
173
- name: "导出数据",
174
- key: "exportData"
175
- }
176
- ];
177
- ```
178
-
179
- #### 4.3.2 点击事件
180
- 当用户点击自定义菜单项时,会触发 `onCustomMenuClicked` 事件,并传递以下参数:
181
- - `event`: 事件对象,包含 `option` 和 `item` 属性
182
- - `option`: 被点击的菜单项配置
183
- - `item`: 右键点击时的目标对象(可能是泳道或线条)
184
-
185
- #### 4.3.3 使用示例
186
- ```html
187
- <kd-lane-chart-container
188
- :customMenuList=\"[{ name: '单屏时长', key: 'timeRange' }]\"
189
- @onCustomMenuClicked=\"handleCustomMenuClick\">
190
- </kd-lane-chart-container>
191
- ```
192
-
193
- ```javascript
194
- handleCustomMenuClick(event) {
195
- const { option, item } = event;
196
- console.log('自定义菜单项被点击:', option.name);
197
- console.log('点击的目标对象:', item);
198
-
199
- if (option.key === 'timeRange') {
200
- // 处理单屏时长操作
201
- }
202
- }
203
- ```
204
-
205
- ## 5. 组件 API
206
-
207
- ### 5.1 Props
208
-
209
- | 属性名 | 类型 | 默认值 | 说明 |
210
- | ---------------- | ------ | ------ | ---------------- |
211
- | config | Object | 必填 | 组件配置对象 |
212
- | headerPadding | Number | 4 | 泳道头部内边距 |
213
- | headerItemHeight | Number | 20 | 头部线条项高度 |
214
- | itemGap | Number | 2 | 线条项之间的间距 |
215
- | customMenuList | Array | [] | 自定义菜单列表 |
216
-
217
- ### 5.2 事件
218
-
219
- | 事件名 | 参数 | 说明 |
220
- | ------------------- | -------- | ------------------ |
221
- | onCustomMenuClicked | event | 自定义菜单点击事件 |
222
- | line-change | line | 线条变化事件 |
223
- | template-change | template | 模板变化事件 |
224
-
225
- ### 5.3 方法
226
-
227
- 组件内部提供的方法主要用于模板和线条的管理:
228
-
229
- - upsertTemplate(data) - 新增或更新模板
230
- - 参数:`data` - 模板数据
231
- - 返回值:`Promise<Object>` - 插入或更新后的**完整**模板对象
232
-
233
- - delTemplate(data) - 删除模板
234
- - 参数:`data` - 模板数据(需包含`templateId`)
235
- - 返回值:`Promise<void>` - 操作成功或失败的Promise
236
-
237
- - upsertLane(data) - 新增或更新泳道
238
- - 参数:`data` - 泳道数据
239
- - 返回值:`Promise<Object>` - 插入或更新后的**完整**泳道对象
240
-
241
- - delLane(lane) - 删除泳道
242
- - 参数:`lane` - 泳道数据(需包含`laneId`和`lines`数组)
243
- - 返回值:`Promise<void>` - 操作成功或失败的Promise
244
-
245
- - upsertLine(data) - 新增或更新线条
246
- - 参数:`data` - 线条数据
247
- - 返回值:`Promise<Object>` - 插入或更新后的**完整线**条对象
248
-
249
- - delLine(data) - 删除线条
250
- - 参数:`data` - 线条数据(需包含`lineId`和`laneId`)
251
- - 返回值:`Promise<void>` - 操作成功或失败的Promise
252
-
253
- - restoreSetting() - 恢复默认设置
254
- - 功能:将当前场景的数据重置为初始配置状态
255
- - 实现逻辑:使用构造函数传入的初始dataSource重新初始化数据
256
- - 返回值:`Promise<void>` - 恢复默认设置的Promise
257
-
258
- ## 6. 自定义插槽
259
-
260
- 组件支持根据泳道 ID 动态生成的插槽,用于自定义泳道头部:
261
-
262
- ```vue
263
- <KdLaneChartContainer ...>
264
- <!-- 动态slot名称 -->
265
- <template v-if="slotName">
266
- <div :slot="slotName" class="demo-slot">
267
- {{ slotName }}
268
- </div>
269
- </template>
270
-
271
- <!-- 带参数的插槽 -->
272
- <template v-if="slotName2" :slot="slotName2" slot-scope="slotData">
273
- <div class="demo-slot">{{ typeof slotData }}</div>
274
- </template>
275
- </KdLaneChartContainer>
276
- ```
277
-
278
- 插槽名称格式为 `lane${laneId}`,例如:`lane1556bdbfd0f24c11948b14999947c556`。
279
-
280
- ### 6.2 draw-slot 画布插槽
281
-
282
- 组件提供 `draw-slot` 插槽用于自定义绘制内容,该插槽占据泳道下方的整个绘制区域:
283
-
284
- ```vue
285
- <KdLaneChartContainer ...>
286
- <template slot="draw-slot">
287
- <div style="height: 100%; width: 100%; padding: 10px">
288
- <!-- 自定义绘制内容 -->
289
- </div>
290
- </template>
291
- </KdLaneChartContainer>
292
- ```
293
-
294
- ### 6.3 插槽布局与尺寸注意事项
295
-
296
- 1. **布局方式**:
297
- - 自定义插槽与泳道区域采用 flex 布局
298
- - 自定义插槽会占据剩余位置后,与其他泳道进行平分
299
- - 确保自定义插槽内容的宽度和高度设置正确,以保证与泳道对齐
300
-
301
- 2. **尺寸单位**:
302
- - 组件内的自定义插槽使用 style 绑定形式
303
- - 宽度和高度单位必须使用 px,以确保精确对齐
304
- - 避免使用其他单位(如 %、rem、em 等),否则可能导致布局错位
305
-
306
- 3. **样式处理**:
307
- - 不要使用全局样式处理插件对自定义插槽的尺寸单位进行转换
308
- - 直接使用 px 单位编写插槽内容的尺寸样式
309
- - 确保插槽内容的 box-sizing 为 border-box,以避免 padding 和 border 影响实际尺寸
310
-
311
- ```vue
312
- <!-- 推荐的插槽内容样式 -->
313
- <template slot="draw-slot">
314
- <div style="height: 100%; width: 100%; box-sizing: border-box; padding: 10px">
315
- <!-- 自定义绘制内容 -->
316
- </div>
317
- </template>
318
- ```
319
-
320
- ## 7. 样式定制
321
-
322
- 可以通过 CSS 变量或直接覆盖样式来自定义组件外观:
323
-
324
- ```css
325
- .kd-lane-chart-container {
326
- --kd-lane-container-border-color: white;
327
- --kd-lane-container-context-background-color: darkgray;
328
- --kd-lane-container-context-hover-color: darkgray;
329
- --kd-lane-container-header-item-color: white;
330
- --app-background-color: gray;
331
- }
332
- ```
333
-
334
- ## 8. 使用示例
335
-
336
- ```vue
337
- <template>
338
- <div id="app">
339
- <KdLaneChartContainer class="container" :config="config" :customMenuList="customMenuList" @onCustomMenuClicked="onCustomMenuClicked">
340
- <template v-if="slotName">
341
- <div :slot="slotName" class="demo-slot">
342
- {{ slotName }}
343
- </div>
344
- </template>
345
- </KdLaneChartContainer>
346
- </div>
347
- </template>
348
-
349
- <script>
350
- import KdLaneChartContainer from "./components/kd-lane/chart-container.vue";
351
- import { data } from "./mock/mockData.js";
352
-
353
- export default {
354
- name: "App",
355
- components: {
356
- KdLaneChartContainer,
357
- },
358
- data() {
359
- return {
360
- config: {
361
- type: "local",
362
- caseId: "demo",
363
- versionCode: 2,
364
- dataSource: { templates: data.templates, lanes: data.lanes, lines: data.lines, params: data.params },
365
- },
366
- slotName: "",
367
- customMenuList: [{ name: "单屏时长", key: "timeRange" }],
368
- };
369
- },
370
- mounted() {
371
- setTimeout(() => {
372
- this.slotName = "lane1556bdbfd0f24c11948b14999947c556";
373
- }, 2000);
374
- },
375
- methods: {
376
- onCustomMenuClicked(event) {
377
- console.log(event);
378
- },
379
- },
380
- };
381
- </script>
382
-
383
- <style>
384
- #app {
385
- font-family: Avenir, Helvetica, Arial, sans-serif;
386
- -webkit-font-smoothing: antialiased;
387
- -moz-osx-font-smoothing: grayscale;
388
- text-align: center;
389
- color: #2c3e50;
390
- height: 100vh;
391
- position: relative;
392
- padding: 10px;
393
-
394
- .container {
395
- margin-left: 100px;
396
- margin-top: 50px;
397
- height: 600px;
398
- width: 800px;
399
- }
400
-
401
- .demo-slot {
402
- width: 80px;
403
- }
404
- }
405
- </style>
406
- ```