km-card-layout-component-miniprogram 0.1.18 → 0.1.20

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.
Files changed (62) hide show
  1. package/example/app.js +11 -1
  2. package/example/pages/home/index.js +324 -101
  3. package/example/pages/home/index.wxml +2 -1
  4. package/miniprogram_dist/components/card-layout/elements/custom-element/index.js +12 -6
  5. package/miniprogram_dist/components/card-layout/elements/custom-element/index.wxml +2 -2
  6. package/miniprogram_dist/components/card-layout/elements/custom-element/index.wxss +1 -1
  7. package/miniprogram_dist/components/card-layout/elements/icon-element/index.js +32 -15
  8. package/miniprogram_dist/components/card-layout/elements/icon-element/index.wxml +2 -4
  9. package/miniprogram_dist/components/card-layout/elements/icon-element/index.wxss +3 -17
  10. package/miniprogram_dist/components/card-layout/elements/icon-font.wxss +438 -0
  11. package/miniprogram_dist/components/card-layout/elements/image-element/index.js +18 -9
  12. package/miniprogram_dist/components/card-layout/elements/image-element/index.wxml +2 -2
  13. package/miniprogram_dist/components/card-layout/elements/image-element/index.wxss +1 -1
  14. package/miniprogram_dist/components/card-layout/elements/layout-panel-element/index.js +37 -0
  15. package/miniprogram_dist/components/card-layout/elements/layout-panel-element/index.json +3 -0
  16. package/miniprogram_dist/components/card-layout/elements/layout-panel-element/index.wxml +5 -0
  17. package/miniprogram_dist/components/card-layout/elements/layout-panel-element/index.wxss +10 -0
  18. package/miniprogram_dist/components/card-layout/elements/text-element/index.js +41 -17
  19. package/miniprogram_dist/components/card-layout/elements/text-element/index.wxml +8 -32
  20. package/miniprogram_dist/components/card-layout/elements/text-element/index.wxss +5 -22
  21. package/miniprogram_dist/components/card-layout/index.js +29 -38
  22. package/miniprogram_dist/components/card-layout/index.json +3 -1
  23. package/miniprogram_dist/components/card-layout/index.wxml +25 -29
  24. package/miniprogram_dist/components/card-layout/index.wxss +1 -455
  25. package/miniprogram_dist/vendor/wxml2canvas-2d/canvas.js +1116 -0
  26. package/miniprogram_dist/vendor/wxml2canvas-2d/constants.js +42 -0
  27. package/miniprogram_dist/vendor/wxml2canvas-2d/element.js +420 -0
  28. package/miniprogram_dist/vendor/wxml2canvas-2d/gradient.js +634 -0
  29. package/miniprogram_dist/vendor/wxml2canvas-2d/index.js +169 -0
  30. package/miniprogram_dist/vendor/wxml2canvas-2d/index.json +4 -0
  31. package/miniprogram_dist/vendor/wxml2canvas-2d/index.wxml +7 -0
  32. package/miniprogram_dist/vendor/wxml2canvas-2d/index.wxss +5 -0
  33. package/package.json +1 -1
  34. package/src/components/card-layout/elements/custom-element/index.ts +13 -7
  35. package/src/components/card-layout/elements/custom-element/index.wxml +2 -2
  36. package/src/components/card-layout/elements/custom-element/index.wxss +1 -1
  37. package/src/components/card-layout/elements/icon-element/index.ts +34 -16
  38. package/src/components/card-layout/elements/icon-element/index.wxml +2 -4
  39. package/src/components/card-layout/elements/icon-element/index.wxss +3 -17
  40. package/src/components/card-layout/elements/icon-font.wxss +438 -0
  41. package/src/components/card-layout/elements/image-element/index.ts +21 -11
  42. package/src/components/card-layout/elements/image-element/index.wxml +2 -2
  43. package/src/components/card-layout/elements/image-element/index.wxss +1 -1
  44. package/src/components/card-layout/elements/layout-panel-element/index.json +3 -0
  45. package/src/components/card-layout/elements/layout-panel-element/index.ts +40 -0
  46. package/src/components/card-layout/elements/layout-panel-element/index.wxml +5 -0
  47. package/src/components/card-layout/elements/layout-panel-element/index.wxss +10 -0
  48. package/src/components/card-layout/elements/text-element/index.ts +48 -19
  49. package/src/components/card-layout/elements/text-element/index.wxml +8 -32
  50. package/src/components/card-layout/elements/text-element/index.wxss +5 -22
  51. package/src/components/card-layout/index.json +3 -1
  52. package/src/components/card-layout/index.ts +34 -62
  53. package/src/components/card-layout/index.wxml +25 -29
  54. package/src/components/card-layout/index.wxss +1 -455
  55. package/src/vendor/wxml2canvas-2d/canvas.js +1116 -0
  56. package/src/vendor/wxml2canvas-2d/constants.js +42 -0
  57. package/src/vendor/wxml2canvas-2d/element.js +420 -0
  58. package/src/vendor/wxml2canvas-2d/gradient.js +634 -0
  59. package/src/vendor/wxml2canvas-2d/index.js +169 -0
  60. package/src/vendor/wxml2canvas-2d/index.json +4 -0
  61. package/src/vendor/wxml2canvas-2d/index.wxml +7 -0
  62. package/src/vendor/wxml2canvas-2d/index.wxss +5 -0
@@ -1,23 +1,34 @@
1
1
  import {
2
2
  buildTextContentStyle,
3
3
  buildTextIconMeta,
4
+ buildTextValueStyle,
4
5
  buildWrapperStyle,
5
6
  getTextValue,
6
7
  styleObjectToString,
7
8
  type TextElement,
8
- } from '../../../../vendor/km-card-layout-core/index';
9
- import { ICON_CODE_MAP } from '../../icon-map';
9
+ } from "../../../../vendor/km-card-layout-core/index";
10
+ import { ICON_CODE_MAP } from "../../icon-map";
10
11
 
11
- const mapIconGlyph = (name?: string, fallback?: string) => {
12
- if (!name) return fallback;
13
- const glyph = ICON_CODE_MAP[name];
14
- if (glyph) return String.fromCharCode(parseInt(glyph, 16));
15
- return fallback || name;
12
+ const normalizeIconName = (name?: string) => {
13
+ if (!name) return "";
14
+ return name.startsWith("icon-") ? name.slice(5) : name;
15
+ };
16
+
17
+ const buildIconClassName = (name?: string) => {
18
+ const normalized = normalizeIconName(name);
19
+ if (!normalized) return "";
20
+ return `icon-${normalized}`;
21
+ };
22
+
23
+ const buildIconCode = (name?: string) => {
24
+ const normalized = normalizeIconName(name);
25
+ if (!normalized) return "";
26
+ return ICON_CODE_MAP[normalized] || "";
16
27
  };
17
28
 
18
29
  Component({
19
30
  options: {
20
- styleIsolation: 'apply-shared',
31
+ styleIsolation: "apply-shared",
21
32
  },
22
33
  properties: {
23
34
  element: {
@@ -30,28 +41,46 @@ Component({
30
41
  },
31
42
  },
32
43
  data: {
33
- wrapperStyle: '',
34
- contentStyle: '',
35
- textValue: '',
44
+ wrapperStyle: "",
45
+ contentStyle: "",
46
+ textValue: "",
47
+ textStyle: "",
36
48
  iconMeta: null as any,
37
49
  },
38
50
  observers: {
39
- element(el: TextElement) {
51
+ element() {
52
+ this.rebuild();
53
+ },
54
+ rootData() {
55
+ this.rebuild();
56
+ },
57
+ },
58
+ methods: {
59
+ rebuild() {
60
+ const el = this.data.element as TextElement;
40
61
  if (!el) return;
41
- const data: Record<string, any> = this.data.rootData || {};
42
- const wrapperStyle = styleObjectToString(buildWrapperStyle(el, 'rpx'), 'rpx');
43
- const contentStyle = styleObjectToString(buildTextContentStyle(el, 'rpx'), 'rpx');
62
+ const data = this.data.rootData || {};
63
+ const wrapperStyle = styleObjectToString(buildWrapperStyle(el, "rpx"), "rpx");
64
+ const contentStyle = styleObjectToString(buildTextContentStyle(el, "rpx"), "rpx");
44
65
  const textValue = getTextValue(el, data);
45
- const iconRaw = buildTextIconMeta(el, 'rpx');
66
+ const textStyle = styleObjectToString(
67
+ {
68
+ ...buildTextContentStyle(el, "rpx"),
69
+ ...buildTextValueStyle(el, "rpx"),
70
+ },
71
+ "rpx"
72
+ );
73
+ const iconRaw = buildTextIconMeta(el, "rpx");
46
74
  const iconMeta =
47
75
  iconRaw && iconRaw.name
48
76
  ? {
49
77
  ...iconRaw,
50
- text: mapIconGlyph(iconRaw.name, iconRaw.name),
51
- wrapperStyle: styleObjectToString(iconRaw.wrapperStyle, 'rpx'),
78
+ className: buildIconClassName(iconRaw.name),
79
+ iconCode: buildIconCode(iconRaw.name),
80
+ wrapperStyle: styleObjectToString(iconRaw.wrapperStyle, "rpx"),
52
81
  }
53
82
  : iconRaw;
54
- this.setData({ wrapperStyle, contentStyle, textValue, iconMeta });
83
+ this.setData({ wrapperStyle, contentStyle, textValue, textStyle, iconMeta });
55
84
  },
56
85
  },
57
86
  });
@@ -1,42 +1,18 @@
1
- <view class="km-node km-node--text" style="{{wrapperStyle}}">
2
- <view class="km-node__text" style="{{contentStyle}}">
3
- <block wx:if="{{(iconMeta && (iconMeta.name || iconMeta.text)) && (element.icon && element.icon.style !== 'text')}}">
4
- <view class="km-node__text-content">
5
-
6
- <!-- icon 在右侧 -->
7
- <block wx:if="{{iconMeta && iconMeta.align === 'right'}}">
8
- <text class="km-node__text-value">{{(element.icon && element.icon.style === 'text' && element.icon.enable) ? (element.label + ':') : ''}}{{textValue || ''}}</text>
1
+ <view class="km-node km-node--text canvas-item" style="{{wrapperStyle}}">
2
+ <view class="km-node__text canvas-item" style="{{contentStyle}}">
3
+ <block wx:if="{{iconMeta && iconMeta.name && (element.icon && element.icon.style !== 'text')}}">
4
+ <view class="km-node__text-content canvas-item">
9
5
  <view
10
- class="km-node__text-icon--wrapper"
6
+ class="km-node__text-icon--wrapper canvas-item"
11
7
  style="{{iconMeta.wrapperStyle}}"
12
8
  >
13
- <text
14
- class="km-node__text-icon icon"
15
- style="font-size: {{iconMeta.size || '16px'}}; color: {{iconMeta.color || ''}}; margin-right: {{iconMeta.gap || ''}};"
16
- >{{iconMeta.text || iconMeta.name || ''}}</text>
9
+ <i class="km-node__text-icon icon {{iconMeta.className}} canvas-item" style="font-size: {{iconMeta.size || '16px'}}; color: {{iconMeta.color || ''}}; margin-right: {{iconMeta.gap || ''}};" data-icon="{{iconMeta.iconCode}}" ></i>
17
10
  </view>
18
- </block>
19
-
20
- <!-- icon 在左侧 -->
21
- <block wx:else>
22
- <view
23
- class="km-node__text-icon--wrapper"
24
- style="{{iconMeta.wrapperStyle}}"
25
- >
26
- <text
27
- class="km-node__text-icon icon"
28
- style="font-size: {{iconMeta.size || '16px'}}; color: {{iconMeta.color || ''}}; margin-right: {{iconMeta.gap || ''}};"
29
- >{{iconMeta.text || iconMeta.name || ''}}</text>
30
- </view>
31
- <text class="km-node__text-value">{{textValue || ''}}</text>
32
- </block>
33
-
11
+ <text class="km-node__text-value canvas-item" style="{{textStyle}}" data-text="{{textValue || ''}}">{{textValue || ''}}</text>
34
12
  </view>
35
13
  </block>
36
-
37
- <!-- 无 icon -->
38
14
  <block wx:else>
39
- <text class="km-node__text-value">{{(element.icon && element.icon.style === 'text' && element.icon.enable) ? (element.label + ':') : ''}}{{textValue || ''}}</text>
15
+ <text class="km-node__text-value canvas-item" style="{{textStyle}}" data-text="{{(element.icon && element.icon.style === 'text' && element.icon.enable) ? (element.label + ':') : ''}}{{textValue || ''}}">{{(element.icon && element.icon.style === 'text' && element.icon.enable) ? (element.label + ':') : ''}}{{textValue || ''}}</text>
40
16
  </block>
41
17
  </view>
42
18
  </view>
@@ -1,12 +1,10 @@
1
+ @import "../icon-font.wxss";
2
+
1
3
  .km-node {
2
4
  box-sizing: border-box;
3
5
  color: inherit;
4
6
  }
5
7
 
6
- .km-node--text {
7
- /* overflow hidden if needed */
8
- }
9
-
10
8
  .km-node--text text {
11
9
  display: inline;
12
10
  }
@@ -23,6 +21,7 @@
23
21
  display: inline-block;
24
22
  vertical-align: middle;
25
23
  height: 100%;
24
+ display: inline-flex;
26
25
  }
27
26
 
28
27
  .km-node__text-icon {
@@ -38,22 +37,6 @@
38
37
  vertical-align: middle;
39
38
  }
40
39
 
41
- @font-face {
42
- font-family: 'km-icon';
43
- src: url('data:font/woff;charset=utf-8;base64,d09GRgABAAAAAEl4AA0AAAAAcmgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAABJXAAAABoAAAAcrMtJV0dERUYAAEk8AAAAHgAAAB4AKQByT1MvMgAAAaQAAABGAAAAYDw3SVljbWFwAAAC7AAAAM8AAAIW8XL3K2dhc3AAAEk0AAAACAAAAAj//wADZ2x5ZgAABJgAAEBZAABkZPJymXJoZWFkAAABMAAAADEAAAA2MtZiFmhoZWEAAAFkAAAAIAAAACQNagmCaG10eAAAAewAAAD/AAABqqs3Ii9sb2NhAAADvAAAANoAAADaKv0P7G1heHAAAAGEAAAAHwAAACABmQHEbmFtZQAARPQAAAFGAAACgl6CAQJwb3N0AABGPAAAAvUAAATh1g15W3jaY2BkYGAA4lqffPd4fpuvDNwsDCDwVIyfA0b///i/gXMWcyeQy8HABBIFAAVdCfwAAAB42mNgZGBgbvjfwBDDOfP/x///OWcxAEVQQCYAuxgH/XjaY2BkYGDIYdzBoMwAAkxAzAWEDAz/wXwGACjlAl8AeNpjYGFRYJzAwMrAwNTJdIaBgaEfQjO+ZjBi5ACKMrAyM2AFAWmuKQwHnjE+y2Ju+N/AwMB8h6ERKMyIpESBgREAenQNCwAAeNo90cErBGEYx/Hf1LMH7MVxoigHtS600pzWnMjBlt2dFAeiNuWgXLgokgslbpyE/Aduyl38J3ty4aCs7/vOk6lPv+d5531n3nfGVF5JIZlUx9fAbawnEfIFq14/YhddFPjFmynZ9n4TbYzg2tcMW6Epr4NQT3jSJ2lcW9ec1fSEAheMnVume7KKBbQwiMye+5/kEpqYwQoOY59pn1xGw3Lt8NwHS7UY35frivqbet2fNYZp+4j76vj+GpUhjZJreLfxODecay/eTzVPzmIj9uX7VLnUmfdb/2fN4trcv0kYv8Oxe/V5Rzhg7inZ8wzjN5b0f6z8PV2d/AHivi0JAHja3dBFUoVRDITR88PD3d3d3d3d3d33zQqYwwVGbIGk8qV6kK7qIN7vlIsCRdlBRT865iPsWOig318/PwOjbwYd+7mKSZAoSbIUqdKky5ApS7YcufLkK1CoSLESpcqCZ4VKVarVqFWnXoNGTZq1aNWmXYdOXbr16NWn34BBQ4aNGDVm3IRJU6bNmDVn3oJFS5atWLVm3YZNW7bt2LVn34FDR46dOHXm3IVLV67duHXn3oNHT8Hv2YtXbyFaot9HfMeMC4jztyL/vr4AXx4eawAAAAAAAAAAAACwAPIDSgQ8BLIFUgWUBcIF/gY8BpIHCgdAB3wHoAgOCHAIxgk+CV4JzAnqCkQKrgtUC8QMEAxsDNQNFA1SDegONg6qDyQPgg/CEAIQxBEwEaQSHBLYE14T4hRcFPIVTBYMFkwWqBckGGAYxhmYGegaEBpeGuIbXhvwHPQd5B62Hygf6CBeILog9CFUIbgiBCJ0ItQjbCQSJGgkuCVsJcImKib0J44ocijOKSApUCo2KmQqtituK34sJixkLMgtdC3WLpgvPC+QMBww/DGCMagyMgAA') format('woff');
44
- font-weight: normal;
45
- font-style: normal;
46
- font-display: swap;
47
- }
48
-
49
- .icon {
50
- font-family: 'km-icon' !important;
51
- font-size: 16px;
52
- font-style: normal;
53
- -webkit-font-smoothing: antialiased;
54
- -moz-osx-font-smoothing: grayscale;
55
- }
56
-
57
- .km-node__text-icon--wrapper{
40
+ .km-node__text-icon--wrapper {
58
41
  display: inline-block;
59
- }
42
+ }
@@ -4,6 +4,8 @@
4
4
  "text-element": "./elements/text-element/index",
5
5
  "image-element": "./elements/image-element/index",
6
6
  "icon-element": "./elements/icon-element/index",
7
- "custom-element": "./elements/custom-element/index"
7
+ "custom-element": "./elements/custom-element/index",
8
+ "layout-panel-element": "./elements/layout-panel-element/index",
9
+ "wxml2canvas": "../../vendor/wxml2canvas-2d/index"
8
10
  }
9
11
  }
@@ -1,29 +1,23 @@
1
1
  import type {
2
2
  CardElement,
3
- CardLayoutInput,
4
3
  CardLayoutSchema,
5
- LayoutPanelElement,
6
- } from '../../vendor/km-card-layout-core/index';
4
+ } from "../../vendor/km-card-layout-core/index";
7
5
  import {
8
6
  buildBackgroundStyle,
9
7
  buildCardStyle,
10
- buildPanelContentStyle,
11
- buildWrapperStyle,
12
8
  normalizeLayout,
13
9
  processCardLayout,
14
10
  styleObjectToString,
15
- } from '../../vendor/km-card-layout-core/index';
11
+ } from "../../vendor/km-card-layout-core/index";
16
12
 
17
13
  type CompanyDuty = {
18
14
  company: string;
19
15
  duty: string;
20
16
  };
21
17
 
22
-
23
-
24
18
  const EMPTY_COMPANY_DUTY: CompanyDuty = {
25
- company: '',
26
- duty: '',
19
+ company: "",
20
+ duty: "",
27
21
  };
28
22
 
29
23
  /**
@@ -60,7 +54,6 @@ export function normalizeMoreCompany(data: AnyObject): AnyObject {
60
54
  };
61
55
  }
62
56
 
63
-
64
57
  const handleSpecialFields = (data: { user: Record<string, any> }) => {
65
58
  const user = data.user ?? {};
66
59
  return {
@@ -68,15 +61,13 @@ const handleSpecialFields = (data: { user: Record<string, any> }) => {
68
61
  user: {
69
62
  ...user,
70
63
  baseCompanyDuty:
71
- user.company && user.duty
72
- ? `${user.company} ${user.duty}`
73
- : user.baseCompanyDuty,
64
+ user.company && user.duty ? `${user.company} ${user.duty}` : user.baseCompanyDuty,
74
65
  moreCardInfo: user.moreCardInfo
75
66
  ? {
76
67
  ...user.moreCardInfo,
77
68
  company: Array.isArray(user.moreCardInfo.company)
78
69
  ? (user.moreCardInfo.company as CompanyDuty[]).map(
79
- item => `${item.company} ${item.duty}`
70
+ (item) => `${item.company} ${item.duty}`
80
71
  )
81
72
  : user.moreCardInfo.company,
82
73
  }
@@ -85,13 +76,7 @@ const handleSpecialFields = (data: { user: Record<string, any> }) => {
85
76
  };
86
77
  };
87
78
 
88
- type PanelElement = LayoutPanelElement & {
89
- wrapperStyle: string;
90
- contentStyle: string;
91
- children?: RenderElement[];
92
- };
93
-
94
- type RenderElement = CardElement | PanelElement;
79
+ type RenderElement = CardElement;
95
80
 
96
81
  type RenderCard = {
97
82
  id: string;
@@ -101,59 +86,33 @@ type RenderCard = {
101
86
  elements: RenderElement[];
102
87
  };
103
88
 
104
- const ensureArray = (input: CardLayoutInput | any): CardLayoutInput => {
105
- if (!input) return [];
106
- return Array.isArray(input) ? input : [input];
107
- };
108
-
109
89
  const pickCardId = (layout: any, idx: number) => {
110
90
  if (layout && (layout.name || layout.id)) return layout.name || layout.id;
111
91
  return `card-${idx}`;
112
92
  };
113
93
 
114
- const decorateElements = (children: CardElement[] = []): RenderElement[] =>
115
- (children || []).map(el => {
116
- if (el.type === 'layout-panel') {
117
- const panel = el as LayoutPanelElement;
118
- return {
119
- ...panel,
120
- wrapperStyle: styleObjectToString(buildWrapperStyle(panel, 'rpx'), 'rpx'),
121
- contentStyle: styleObjectToString(buildPanelContentStyle(panel, 'rpx'), 'rpx'),
122
- children: decorateElements(panel.children || []),
123
- };
124
- }
125
- return el;
126
- });
127
-
128
94
  const buildCards = (layouts: CardLayoutSchema[]) => {
129
95
  return layouts.map((layout, idx) => ({
130
96
  id: pickCardId(layouts[idx], idx),
131
- cardStyle: styleObjectToString(buildCardStyle(layout, 'rpx'), 'rpx'),
132
- backgroundImage: layout.backgroundImage || '',
133
- backgroundStyle: styleObjectToString(buildBackgroundStyle(layout, 'rpx'), 'rpx'),
134
- elements: decorateElements(layout.children || []),
97
+ cardStyle: styleObjectToString(buildCardStyle(layout, "rpx"), "rpx"),
98
+ backgroundImage: layout.backgroundImage || "",
99
+ backgroundStyle: styleObjectToString(buildBackgroundStyle(layout, "rpx"), "rpx"),
100
+ elements: layout.children || [],
135
101
  }));
136
102
  };
137
103
 
138
-
139
- export const hasCompanyDutyKey = (
140
- schemas: CardLayoutSchema[]
141
- ): boolean => {
142
- const TARGET_KEYS = new Set([
143
- 'company_duty_custom',
144
- 'company_duty_1',
145
- 'company_duty_2',
146
- ]);
104
+ export const hasCompanyDutyKey = (schemas: CardLayoutSchema[]): boolean => {
105
+ const TARGET_KEYS = new Set(["company_duty_custom", "company_duty_1", "company_duty_2"]);
147
106
 
148
107
  const traverse = (elements: CardElement[]): boolean => {
149
- return elements.some(el => {
108
+ return elements.some((el) => {
150
109
  // 命中 key
151
110
  if (el.key && TARGET_KEYS.has(el.key)) {
152
111
  return true;
153
112
  }
154
113
 
155
114
  // 递归 layout-panel
156
- if (el.type === 'layout-panel' && el.children?.length) {
115
+ if (el.type === "layout-panel" && el.children?.length) {
157
116
  return traverse(el.children);
158
117
  }
159
118
 
@@ -161,13 +120,12 @@ export const hasCompanyDutyKey = (
161
120
  });
162
121
  };
163
122
 
164
- return schemas.some(schema => traverse(schema.children));
123
+ return schemas.some((schema) => traverse(schema.children));
165
124
  };
166
125
 
167
-
168
126
  Component({
169
127
  options: {
170
- styleIsolation: 'apply-shared',
128
+ styleIsolation: "apply-shared",
171
129
  },
172
130
  properties: {
173
131
  layout: {
@@ -185,6 +143,7 @@ Component({
185
143
  data: {
186
144
  cards: [] as RenderCard[],
187
145
  rootData: {} as Record<string, any>,
146
+ firstCard: [] as RenderCard[],
188
147
  },
189
148
  observers: {
190
149
  layout() {
@@ -201,8 +160,10 @@ Component({
201
160
  },
202
161
  methods: {
203
162
  rebuild() {
204
- const data = normalizeMoreCompany(this.data.data)
205
- const layoutInput = hasCompanyDutyKey(this.data.layout)?processCardLayout(this.data.layout, data as any): this.data.layout;
163
+ const data = normalizeMoreCompany(this.data.data);
164
+ const layoutInput = hasCompanyDutyKey(this.data.layout)
165
+ ? processCardLayout(this.data.layout, data as any)
166
+ : this.data.layout;
206
167
  const rootData = handleSpecialFields(data as any);
207
168
  if (!layoutInput.length) {
208
169
  this.setData({ cards: [], rootData });
@@ -210,7 +171,18 @@ Component({
210
171
  }
211
172
  const normalizedLayouts = normalizeLayout(layoutInput);
212
173
  const cards = buildCards(normalizedLayouts);
213
- this.setData({ cards, rootData });
174
+ this.setData({ cards, rootData, firstCard: [cards[0]] });
175
+ },
176
+
177
+ async handleDrawCanvas() {
178
+ try {
179
+ const canvas = this.selectComponent(`#layout-canvas`);
180
+ await canvas.draw(this);
181
+ const filePath = await canvas.toTempFilePath();
182
+ return filePath;
183
+ } catch {
184
+ wx.showToast({ title: "保存失败", icon: "error" });
185
+ }
214
186
  },
215
187
  },
216
188
  });
@@ -1,42 +1,38 @@
1
- <view class="km-card-layout">
2
- <block wx:for="{{cards}}" wx:key="id">
3
- <view class="km-card-layout__item">
4
- <view class="km-card" style="{{item.cardStyle}}">
5
- <image
6
- wx:if="{{item.backgroundImage}}"
7
- class="km-card__bg"
8
- style="{{item.backgroundStyle}}"
9
- src="{{item.backgroundImage}}"
10
- mode="aspectFill"
11
- />
12
- <block wx:for="{{item.elements}}" wx:key="id">
13
- <template wx:if="{{item.visible !== false}}" is="render-element" data="{{el:item, rootData: rootData}}" />
14
- </block>
1
+ <template name="layout-template">
2
+ <view class="km-card-layout layout-container">
3
+ <block wx:for="{{renderCards}}" wx:key="id">
4
+ <view class="km-card-layout__item canvas-item">
5
+ <view class="km-card canvas-item" style="{{item.cardStyle}}">
6
+ <image wx:if="{{item.backgroundImage}}" class="km-card__bg canvas-item" style="{{item.backgroundStyle}}" src="{{item.backgroundImage}}" mode="aspectFill" />
7
+ <block wx:for="{{item.elements}}" wx:key="id">
8
+ <template wx:if="{{item.visible !== false}}" is="render-element" data="{{el:item, rootData: rootData}}" />
9
+ </block>
10
+ </view>
15
11
  </view>
16
- </view>
17
- </block>
18
- </view>
19
-
12
+ </block>
13
+ </view>
14
+ </template>
15
+ <template is="layout-template" data="{{ renderCards: cards, rootData: rootData }}"></template>
16
+ <!-- 暂时只绘制第一张卡片 -->
17
+ <wxml2canvas id="layout-canvas" container-class="layout-container" item-class="canvas-item"></wxml2canvas>
20
18
  <template name="render-element">
21
19
  <block wx:if="{{el.type === 'image'}}">
22
- <image-element element="{{el}}" rootData="{{rootData}}" />
20
+ <image-element id="node-{{el.id}}" class="canvas-item" data-component="{{true}}" element="{{el}}" rootData="{{rootData}}" />
23
21
  </block>
24
22
  <block wx:elif="{{el.type === 'icon'}}">
25
- <icon-element element="{{el}}" rootData="{{rootData}}" />
23
+ <icon-element id="node-{{el.id}}" class="canvas-item" data-component="{{true}}" element="{{el}}" rootData="{{rootData}}" />
26
24
  </block>
27
25
  <block wx:elif="{{el.type === 'layout-panel'}}">
28
- <view class="km-node" style="{{el.wrapperStyle}}">
29
- <view class="km-node__panel" style="{{el.contentStyle}}">
30
- <block wx:for="{{el.children}}" wx:key="id">
31
- <template is="render-element" data="{{el:item, rootData: rootData}}" />
32
- </block>
33
- </view>
34
- </view>
26
+ <layout-panel-element id="node-{{el.id}}" class="canvas-item" data-component="{{true}}" element="{{el}}" rootData="{{rootData}}">
27
+ <block wx:for="{{el.children}}" wx:key="id">
28
+ <template is="render-element" data="{{el:item, rootData: rootData}}" />
29
+ </block>
30
+ </layout-panel-element>
35
31
  </block>
36
32
  <block wx:elif="{{el.type === 'custom'}}">
37
- <custom-element element="{{el}}" rootData="{{rootData}}" />
33
+ <custom-element id="node-{{el.id}}" class="canvas-item" data-component="{{true}}" element="{{el}}" rootData="{{rootData}}" />
38
34
  </block>
39
35
  <block wx:else>
40
- <text-element element="{{el}}" rootData="{{rootData}}" />
36
+ <text-element id="node-{{el.id}}" class="canvas-item" data-component="{{true}}" element="{{el}}" rootData="{{rootData}}" />
41
37
  </block>
42
38
  </template>