km-card-layout-component-miniprogram 0.1.19 → 0.1.21

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 (46) 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 +4 -6
  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 +3 -7
  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 +429 -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 +8 -10
  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 -34
  20. package/miniprogram_dist/components/card-layout/elements/text-element/index.wxss +5 -18
  21. package/miniprogram_dist/components/card-layout/index.js +39 -108
  22. package/miniprogram_dist/components/card-layout/index.json +9 -1
  23. package/miniprogram_dist/components/card-layout/index.wxml +25 -46
  24. package/miniprogram_dist/components/card-layout/index.wxss +1 -538
  25. package/package.json +1 -1
  26. package/src/components/card-layout/elements/custom-element/index.ts +13 -7
  27. package/src/components/card-layout/elements/custom-element/index.wxml +4 -6
  28. package/src/components/card-layout/elements/custom-element/index.wxss +1 -1
  29. package/src/components/card-layout/elements/icon-element/index.ts +34 -16
  30. package/src/components/card-layout/elements/icon-element/index.wxml +3 -7
  31. package/src/components/card-layout/elements/icon-element/index.wxss +3 -17
  32. package/src/components/card-layout/elements/icon-font.wxss +429 -0
  33. package/src/components/card-layout/elements/image-element/index.ts +21 -11
  34. package/src/components/card-layout/elements/image-element/index.wxml +8 -10
  35. package/src/components/card-layout/elements/image-element/index.wxss +1 -1
  36. package/src/components/card-layout/elements/layout-panel-element/index.json +3 -0
  37. package/src/components/card-layout/elements/layout-panel-element/index.ts +40 -0
  38. package/src/components/card-layout/elements/layout-panel-element/index.wxml +5 -0
  39. package/src/components/card-layout/elements/layout-panel-element/index.wxss +10 -0
  40. package/src/components/card-layout/elements/text-element/index.ts +48 -19
  41. package/src/components/card-layout/elements/text-element/index.wxml +8 -34
  42. package/src/components/card-layout/elements/text-element/index.wxss +5 -18
  43. package/src/components/card-layout/index.json +9 -1
  44. package/src/components/card-layout/index.ts +45 -159
  45. package/src/components/card-layout/index.wxml +25 -46
  46. package/src/components/card-layout/index.wxss +1 -538
@@ -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,44 +1,18 @@
1
- <template name="text-element">
2
- <view class="km-node km-node--text" style="{{wrapperStyle}}">
3
- <view class="km-node__text" style="{{contentStyle}}">
4
- <block wx:if="{{(iconMeta && (iconMeta.name || iconMeta.text)) && (element.icon && element.icon.style !== 'text')}}">
5
- <view class="km-node__text-content">
6
-
7
- <!-- icon 在右侧 -->
8
- <block wx:if="{{iconMeta && iconMeta.align === 'right'}}">
9
- <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">
10
5
  <view
11
- class="km-node__text-icon--wrapper"
6
+ class="km-node__text-icon--wrapper canvas-item"
12
7
  style="{{iconMeta.wrapperStyle}}"
13
8
  >
14
- <text
15
- class="km-node__text-icon icon"
16
- style="font-size: {{iconMeta.size || '16px'}}; color: {{iconMeta.color || ''}}; margin-right: {{iconMeta.gap || ''}};"
17
- >{{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>
18
10
  </view>
19
- </block>
20
-
21
- <!-- icon 在左侧 -->
22
- <block wx:else>
23
- <view
24
- class="km-node__text-icon--wrapper"
25
- style="{{iconMeta.wrapperStyle}}"
26
- >
27
- <text
28
- class="km-node__text-icon icon"
29
- style="font-size: {{iconMeta.size || '16px'}}; color: {{iconMeta.color || ''}}; margin-right: {{iconMeta.gap || ''}};"
30
- >{{iconMeta.text || iconMeta.name || ''}}</text>
31
- </view>
32
- <text class="km-node__text-value">{{textValue || ''}}</text>
33
- </block>
34
-
11
+ <text class="km-node__text-value canvas-item" style="{{textStyle}}" data-text="{{textValue || ''}}">{{textValue || ''}}</text>
35
12
  </view>
36
13
  </block>
37
-
38
- <!-- 无 icon -->
39
14
  <block wx:else>
40
- <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>
41
16
  </block>
42
17
  </view>
43
18
  </view>
44
- </template>
@@ -1,3 +1,5 @@
1
+ @import "../icon-font.wxss";
2
+
1
3
  .km-node {
2
4
  box-sizing: border-box;
3
5
  color: inherit;
@@ -19,6 +21,7 @@
19
21
  display: inline-block;
20
22
  vertical-align: middle;
21
23
  height: 100%;
24
+ display: inline-flex;
22
25
  }
23
26
 
24
27
  .km-node__text-icon {
@@ -34,22 +37,6 @@
34
37
  vertical-align: middle;
35
38
  }
36
39
 
37
- @font-face {
38
- font-family: 'km-icon';
39
- 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');
40
- font-weight: normal;
41
- font-style: normal;
42
- font-display: swap;
43
- }
44
-
45
- .icon {
46
- font-family: 'km-icon' !important;
47
- font-size: 16px;
48
- font-style: normal;
49
- -webkit-font-smoothing: antialiased;
50
- -moz-osx-font-smoothing: grayscale;
51
- }
52
-
53
- .km-node__text-icon--wrapper{
40
+ .km-node__text-icon--wrapper {
54
41
  display: inline-block;
55
- }
42
+ }
@@ -1,3 +1,11 @@
1
1
  {
2
- "component": true
2
+ "component": true,
3
+ "usingComponents": {
4
+ "text-element": "./elements/text-element/index",
5
+ "image-element": "./elements/image-element/index",
6
+ "icon-element": "./elements/icon-element/index",
7
+ "custom-element": "./elements/custom-element/index",
8
+ "layout-panel-element": "./elements/layout-panel-element/index",
9
+ "wxml2canvas": "../../vendor/wxml2canvas-2d/index"
10
+ }
3
11
  }
@@ -1,48 +1,20 @@
1
- import type {
2
- CardElement,
3
- CardLayoutInput,
4
- CardLayoutSchema,
5
- CustomElement,
6
- IconElement,
7
- ImageElement,
8
- LayoutPanelElement,
9
- TextElement,
10
- } from '../../vendor/km-card-layout-core/index';
1
+ import type { CardElement, CardLayoutSchema } from "../../vendor/km-card-layout-core/index";
11
2
  import {
12
3
  buildBackgroundStyle,
13
- buildBaseContentStyle,
14
4
  buildCardStyle,
15
- buildImageContentStyle,
16
- buildPanelContentStyle,
17
- buildTextContentStyle,
18
- buildTextIconMeta,
19
- buildWrapperStyle,
20
- getIconName,
21
- getImageSrc,
22
- getTextValue,
23
5
  normalizeLayout,
24
6
  processCardLayout,
25
7
  styleObjectToString,
26
- } from '../../vendor/km-card-layout-core/index';
27
- import { ICON_CODE_MAP } from './icon-map';
8
+ } from "../../vendor/km-card-layout-core/index";
28
9
 
29
10
  type CompanyDuty = {
30
11
  company: string;
31
12
  duty: string;
32
13
  };
33
14
 
34
- const mapIconGlyph = (name?: string, fallback?: string) => {
35
- if (!name) return fallback;
36
- const glyph = ICON_CODE_MAP[name];
37
- if (glyph) return String.fromCharCode(parseInt(glyph, 16));
38
- return fallback || name;
39
- };
40
-
41
-
42
-
43
15
  const EMPTY_COMPANY_DUTY: CompanyDuty = {
44
- company: '',
45
- duty: '',
16
+ company: "",
17
+ duty: "",
46
18
  };
47
19
 
48
20
  /**
@@ -79,7 +51,6 @@ export function normalizeMoreCompany(data: AnyObject): AnyObject {
79
51
  };
80
52
  }
81
53
 
82
-
83
54
  const handleSpecialFields = (data: { user: Record<string, any> }) => {
84
55
  const user = data.user ?? {};
85
56
  return {
@@ -87,15 +58,13 @@ const handleSpecialFields = (data: { user: Record<string, any> }) => {
87
58
  user: {
88
59
  ...user,
89
60
  baseCompanyDuty:
90
- user.company && user.duty
91
- ? `${user.company} ${user.duty}`
92
- : user.baseCompanyDuty,
61
+ user.company && user.duty ? `${user.company} ${user.duty}` : user.baseCompanyDuty,
93
62
  moreCardInfo: user.moreCardInfo
94
63
  ? {
95
64
  ...user.moreCardInfo,
96
65
  company: Array.isArray(user.moreCardInfo.company)
97
66
  ? (user.moreCardInfo.company as CompanyDuty[]).map(
98
- item => `${item.company} ${item.duty}`
67
+ (item) => `${item.company} ${item.duty}`
99
68
  )
100
69
  : user.moreCardInfo.company,
101
70
  }
@@ -104,22 +73,7 @@ const handleSpecialFields = (data: { user: Record<string, any> }) => {
104
73
  };
105
74
  };
106
75
 
107
- type RenderElement = CardElement & {
108
- wrapperStyle?: string;
109
- contentStyle?: string;
110
- imageSrc?: string;
111
- mode?: string;
112
- iconText?: string;
113
- textValue?: string;
114
- iconMeta?: any;
115
- children?: RenderElement[];
116
- };
117
-
118
- type PanelElement = LayoutPanelElement & {
119
- wrapperStyle: string;
120
- contentStyle: string;
121
- children?: RenderElement[];
122
- };
76
+ type RenderElement = CardElement;
123
77
 
124
78
  type RenderCard = {
125
79
  id: string;
@@ -129,123 +83,33 @@ type RenderCard = {
129
83
  elements: RenderElement[];
130
84
  };
131
85
 
132
- const ensureArray = (input: CardLayoutInput | any): CardLayoutInput => {
133
- if (!input) return [];
134
- return Array.isArray(input) ? input : [input];
135
- };
136
-
137
86
  const pickCardId = (layout: any, idx: number) => {
138
87
  if (layout && (layout.name || layout.id)) return layout.name || layout.id;
139
88
  return `card-${idx}`;
140
89
  };
141
90
 
142
- const decorateElements = (
143
- children: CardElement[] = [],
144
- rootData: Record<string, any>
145
- ): RenderElement[] => {
146
- const data = rootData || {};
147
-
148
- return (children || []).map(el => {
149
- const wrapperStyle = styleObjectToString(buildWrapperStyle(el, 'rpx'), 'rpx');
150
-
151
- switch (el.type) {
152
- case 'layout-panel': {
153
- const panel = el as LayoutPanelElement;
154
- return {
155
- ...panel,
156
- wrapperStyle,
157
- contentStyle: styleObjectToString(buildPanelContentStyle(panel, 'rpx'), 'rpx'),
158
- children: decorateElements(panel.children || [], rootData),
159
- } as PanelElement;
160
- }
161
- case 'image': {
162
- const imageEl = el as ImageElement;
163
- const contentStyle = styleObjectToString(buildImageContentStyle(imageEl), 'rpx');
164
- const imageSrc = getImageSrc(imageEl, data);
165
- const mode = imageEl.fit === 'contain' ? 'aspectFit' : 'aspectFill';
166
- return {
167
- ...imageEl,
168
- wrapperStyle,
169
- contentStyle,
170
- imageSrc,
171
- mode,
172
- };
173
- }
174
- case 'icon': {
175
- const iconEl = el as IconElement;
176
- const contentStyle = styleObjectToString(buildBaseContentStyle(iconEl), 'rpx');
177
- const name = getIconName(iconEl);
178
- const iconText = mapIconGlyph(name, name || '');
179
- return {
180
- ...iconEl,
181
- wrapperStyle,
182
- contentStyle,
183
- iconText,
184
- };
185
- }
186
- case 'custom': {
187
- const customEl = el as CustomElement;
188
- const contentStyle = styleObjectToString(buildBaseContentStyle(customEl), 'rpx');
189
- return {
190
- ...customEl,
191
- wrapperStyle,
192
- contentStyle,
193
- };
194
- }
195
- default: {
196
- const textEl = el as TextElement;
197
- const contentStyle = styleObjectToString(buildTextContentStyle(textEl, 'rpx'), 'rpx');
198
- const textValue = getTextValue(textEl, data);
199
- const iconRaw = buildTextIconMeta(textEl, 'rpx');
200
- const iconMeta =
201
- iconRaw && iconRaw.name
202
- ? {
203
- ...iconRaw,
204
- text: mapIconGlyph(iconRaw.name, iconRaw.name),
205
- wrapperStyle: styleObjectToString(iconRaw.wrapperStyle, 'rpx'),
206
- }
207
- : iconRaw;
208
- return {
209
- ...textEl,
210
- wrapperStyle,
211
- contentStyle,
212
- textValue,
213
- iconMeta,
214
- };
215
- }
216
- }
217
- });
218
- };
219
-
220
- const buildCards = (layouts: CardLayoutSchema[], rootData: Record<string, any>) => {
91
+ const buildCards = (layouts: CardLayoutSchema[]) => {
221
92
  return layouts.map((layout, idx) => ({
222
93
  id: pickCardId(layouts[idx], idx),
223
- cardStyle: styleObjectToString(buildCardStyle(layout, 'rpx'), 'rpx'),
224
- backgroundImage: layout.backgroundImage || '',
225
- backgroundStyle: styleObjectToString(buildBackgroundStyle(layout, 'rpx'), 'rpx'),
226
- elements: decorateElements(layout.children || [], rootData),
94
+ cardStyle: styleObjectToString(buildCardStyle(layout, "rpx"), "rpx"),
95
+ backgroundImage: layout.backgroundImage || "",
96
+ backgroundStyle: styleObjectToString(buildBackgroundStyle(layout, "rpx"), "rpx"),
97
+ elements: layout.children || [],
227
98
  }));
228
99
  };
229
100
 
230
-
231
- export const hasCompanyDutyKey = (
232
- schemas: CardLayoutSchema[]
233
- ): boolean => {
234
- const TARGET_KEYS = new Set([
235
- 'company_duty_custom',
236
- 'company_duty_1',
237
- 'company_duty_2',
238
- ]);
101
+ export const hasCompanyDutyKey = (schemas: CardLayoutSchema[]): boolean => {
102
+ const TARGET_KEYS = new Set(["company_duty_custom", "company_duty_1", "company_duty_2"]);
239
103
 
240
104
  const traverse = (elements: CardElement[]): boolean => {
241
- return elements.some(el => {
105
+ return elements.some((el) => {
242
106
  // 命中 key
243
107
  if (el.key && TARGET_KEYS.has(el.key)) {
244
108
  return true;
245
109
  }
246
110
 
247
111
  // 递归 layout-panel
248
- if (el.type === 'layout-panel' && el.children?.length) {
112
+ if (el.type === "layout-panel" && el.children?.length) {
249
113
  return traverse(el.children);
250
114
  }
251
115
 
@@ -253,13 +117,12 @@ export const hasCompanyDutyKey = (
253
117
  });
254
118
  };
255
119
 
256
- return schemas.some(schema => traverse(schema.children));
120
+ return schemas.some((schema) => traverse(schema.children));
257
121
  };
258
122
 
259
-
260
123
  Component({
261
124
  options: {
262
- styleIsolation: 'apply-shared',
125
+ styleIsolation: "apply-shared",
263
126
  },
264
127
  properties: {
265
128
  layout: {
@@ -277,6 +140,7 @@ Component({
277
140
  data: {
278
141
  cards: [] as RenderCard[],
279
142
  rootData: {} as Record<string, any>,
143
+ firstCard: [] as RenderCard[],
280
144
  },
281
145
  observers: {
282
146
  layout() {
@@ -288,21 +152,43 @@ Component({
288
152
  },
289
153
  lifetimes: {
290
154
  attached() {
155
+ this.loadFont();
291
156
  this.rebuild();
292
157
  },
293
158
  },
294
159
  methods: {
295
160
  rebuild() {
296
- const data = normalizeMoreCompany(this.data.data)
297
- const layoutInput = hasCompanyDutyKey(this.data.layout)?processCardLayout(this.data.layout, data as any): this.data.layout;
161
+ const data = normalizeMoreCompany(this.data.data);
162
+ const layoutInput = hasCompanyDutyKey(this.data.layout)
163
+ ? processCardLayout(this.data.layout, data as any)
164
+ : this.data.layout;
298
165
  const rootData = handleSpecialFields(data as any);
299
166
  if (!layoutInput.length) {
300
167
  this.setData({ cards: [], rootData });
301
168
  return;
302
169
  }
303
170
  const normalizedLayouts = normalizeLayout(layoutInput);
304
- const cards = buildCards(normalizedLayouts, rootData);
305
- this.setData({ cards, rootData });
171
+ const cards = buildCards(normalizedLayouts);
172
+ this.setData({ cards, rootData, firstCard: [cards[0]] });
173
+ },
174
+
175
+ async handleDrawCanvas() {
176
+ try {
177
+ const canvas = this.selectComponent(`#layout-canvas`);
178
+ await canvas.draw(this);
179
+ const filePath = await canvas.toTempFilePath();
180
+ return filePath;
181
+ } catch {
182
+ wx.showToast({ title: "保存失败", icon: "error" });
183
+ }
184
+ },
185
+
186
+ async loadFont() {
187
+ await wx.loadFontFace({
188
+ family: "km-icon",
189
+ // 可以为 https 链接或者 Data URL
190
+ source: "data:font/woff;charset=utf-8;base64,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",
191
+ });
306
192
  },
307
193
  },
308
194
  });
@@ -1,59 +1,38 @@
1
- <import src="./elements/custom-element/index.wxml" />
2
- <import src="./elements/icon-element/index.wxml" />
3
- <import src="./elements/image-element/index.wxml" />
4
- <import src="./elements/text-element/index.wxml" />
5
-
6
- <view class="km-card-layout">
7
- <block wx:for="{{cards}}" wx:key="id">
8
- <view class="km-card-layout__item">
9
- <view class="km-card" style="{{item.cardStyle}}">
10
- <image
11
- wx:if="{{item.backgroundImage}}"
12
- class="km-card__bg"
13
- style="{{item.backgroundStyle}}"
14
- src="{{item.backgroundImage}}"
15
- mode="aspectFill"
16
- />
17
- <block wx:for="{{item.elements}}" wx:key="id">
18
- <template wx:if="{{item.visible !== false}}" is="render-element" data="{{el:item, rootData: rootData}}" />
19
- </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>
20
11
  </view>
21
- </view>
22
- </block>
23
- </view>
24
-
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>
25
18
  <template name="render-element">
26
19
  <block wx:if="{{el.type === 'image'}}">
27
- <template
28
- is="image-element"
29
- data="{{wrapperStyle: el.wrapperStyle, contentStyle: el.contentStyle, imageSrc: el.imageSrc, mode: el.mode}}"
30
- />
20
+ <image-element id="node-{{el.id}}" class="canvas-item" data-component="{{true}}" element="{{el}}" rootData="{{rootData}}" />
31
21
  </block>
32
22
  <block wx:elif="{{el.type === 'icon'}}">
33
- <template
34
- is="icon-element"
35
- data="{{wrapperStyle: el.wrapperStyle, contentStyle: el.contentStyle, iconText: el.iconText}}"
36
- />
23
+ <icon-element id="node-{{el.id}}" class="canvas-item" data-component="{{true}}" element="{{el}}" rootData="{{rootData}}" />
37
24
  </block>
38
25
  <block wx:elif="{{el.type === 'layout-panel'}}">
39
- <view class="km-node" style="{{el.wrapperStyle}}">
40
- <view class="km-node__panel" style="{{el.contentStyle}}">
41
- <block wx:for="{{el.children}}" wx:key="id">
42
- <template is="render-element" data="{{el:item, rootData: rootData}}" />
43
- </block>
44
- </view>
45
- </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>
46
31
  </block>
47
32
  <block wx:elif="{{el.type === 'custom'}}">
48
- <template
49
- is="custom-element"
50
- data="{{wrapperStyle: el.wrapperStyle, contentStyle: el.contentStyle, element: el}}"
51
- />
33
+ <custom-element id="node-{{el.id}}" class="canvas-item" data-component="{{true}}" element="{{el}}" rootData="{{rootData}}" />
52
34
  </block>
53
35
  <block wx:else>
54
- <template
55
- is="text-element"
56
- data="{{wrapperStyle: el.wrapperStyle, contentStyle: el.contentStyle, textValue: el.textValue, iconMeta: el.iconMeta, element: el}}"
57
- />
36
+ <text-element id="node-{{el.id}}" class="canvas-item" data-component="{{true}}" element="{{el}}" rootData="{{rootData}}" />
58
37
  </block>
59
38
  </template>