km-card-layout-component-miniprogram 0.1.6 → 0.1.7

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.
@@ -1,356 +1,6 @@
1
1
 
2
2
 
3
- const layouts = [
4
- {
5
- "name": "内置布局-左侧头像",
6
- "width": 343,
7
- "height": 210,
8
- "children": [
9
- {
10
- "id": "1",
11
- "key": "name",
12
- "type": "text",
13
- "style": {
14
- "color": "",
15
- "fontSize": 18,
16
- "textAlign": "left",
17
- "fontWeight": "bold",
18
- "lineHeight": 25
19
- },
20
- "layout": {
21
- "x": 107,
22
- "y": 23,
23
- "mode": "absolute",
24
- "width": 190,
25
- "height": 25,
26
- "zIndex": 1
27
- }
28
- },
29
- {
30
- "id": "2",
31
- "key": "company",
32
- "type": "text",
33
- "style": {
34
- "color": "",
35
- "fontSize": 13,
36
- "textAlign": "left",
37
- "fontWeight": "normal",
38
- "lineHeight": 18
39
- },
40
- "layout": {
41
- "x": 107,
42
- "y": 51,
43
- "mode": "absolute",
44
- "width": 190,
45
- "height": 18,
46
- "zIndex": 2
47
- },
48
- "visible": true
49
- },
50
- {
51
- "id": "3",
52
- "key": "mobile",
53
- "icon": {
54
- "size": 8,
55
- "style": "dot",
56
- "enable": true
57
- },
58
- "type": "text",
59
- "style": {
60
- "color": "",
61
- "fontSize": 13,
62
- "textAlign": "left",
63
- "fontWeight": "normal"
64
- },
65
- "layout": {
66
- "x": 18,
67
- "y": 131,
68
- "mode": "absolute",
69
- "width": 290,
70
- "height": 14,
71
- "zIndex": 8
72
- }
73
- },
74
- {
75
- "id": "4",
76
- "key": "duty",
77
- "type": "text",
78
- "style": {
79
- "color": "",
80
- "fontSize": 13,
81
- "textAlign": "left",
82
- "fontWeight": "normal",
83
- "lineHeight": 18
84
- },
85
- "layout": {
86
- "x": 107,
87
- "y": 72,
88
- "mode": "absolute",
89
- "width": 190,
90
- "height": 18,
91
- "zIndex": 3
92
- },
93
- "visible": true
94
- },
95
- {
96
- "id": "6",
97
- "key": "image",
98
- "url": "https://km-1257079185.cos.ap-chengdu.myqcloud.com/local/image/202505/3c6d8cc2b1df2cfad624376ae37d3b9e.png",
99
- "type": "image",
100
- "style": {
101
- "borderColor": "#f6f7fb",
102
- "borderStyle": "solid",
103
- "borderWidth": 1,
104
- "borderRadius": 100
105
- },
106
- "layout": {
107
- "x": 18,
108
- "y": 16,
109
- "mode": "absolute",
110
- "width": 80,
111
- "height": 80,
112
- "zIndex": 7
113
- }
114
- },
115
- {
116
- "id": "5",
117
- "key": "email",
118
- "icon": {
119
- "size": 8,
120
- "style": "dot",
121
- "enable": true
122
- },
123
- "type": "text",
124
- "style": {
125
- "color": "",
126
- "fontSize": 13,
127
- "textAlign": "left",
128
- "fontWeight": "normal"
129
- },
130
- "layout": {
131
- "x": 18,
132
- "y": 152,
133
- "mode": "absolute",
134
- "width": 290,
135
- "height": 14,
136
- "zIndex": 9
137
- }
138
- },
139
- {
140
- "id": "9",
141
- "key": "address",
142
- "icon": {
143
- "size": 8,
144
- "style": "dot",
145
- "enable": true
146
- },
147
- "type": "text",
148
- "style": {
149
- "color": "",
150
- "fontSize": 13,
151
- "textAlign": "left",
152
- "fontWeight": "normal"
153
- },
154
- "layout": {
155
- "x": 18,
156
- "y": 173,
157
- "mode": "absolute",
158
- "width": 290,
159
- "height": 34,
160
- "zIndex": 10
161
- }
162
- },
163
- {
164
- "id": "repeatable-1764640366125",
165
- "type": "repeatable-group",
166
- "items": [
167
- {
168
- "id": "item-1764640366125-d4ea",
169
- "data": {
170
- "duty": "CEO",
171
- "company": "合肥魅客网络有限公司"
172
- },
173
- "elements": [
174
- {
175
- "id": "company-duty-1764640366125-d4ea",
176
- "type": "text",
177
- "style": {
178
- "fontSize": 12,
179
- "textAlign": "left",
180
- "fontWeight": "normal",
181
- "lineHeight": 14
182
- },
183
- "layout": {
184
- "x": 107,
185
- "y": 52,
186
- "mode": "absolute",
187
- "width": 220,
188
- "height": 14,
189
- "zIndex": 2
190
- }
191
- }
192
- ]
193
- },
194
- {
195
- "id": "item-1764640369647-8b58",
196
- "data": {
197
- "duty": "副会长",
198
- "company": "人力资源协会"
199
- },
200
- "elements": [
201
- {
202
- "id": "company-duty-1764640369647-8b58",
203
- "type": "text",
204
- "style": {
205
- "fontSize": 12,
206
- "textAlign": "left",
207
- "fontWeight": "normal",
208
- "lineHeight": 14
209
- },
210
- "layout": {
211
- "x": 107,
212
- "y": 67,
213
- "mode": "absolute",
214
- "width": 220,
215
- "height": 14,
216
- "zIndex": 2
217
- }
218
- }
219
- ]
220
- },
221
- {
222
- "id": "item-1764640371911-e6ae",
223
- "data": {
224
- "duty": "高级顾问",
225
- "company": "北京博然思维咨询有限公司"
226
- },
227
- "elements": [
228
- {
229
- "id": "company-duty-1764640371911-e6ae",
230
- "type": "text",
231
- "style": {
232
- "fontSize": 12,
233
- "textAlign": "left",
234
- "fontWeight": "normal",
235
- "lineHeight": 14
236
- },
237
- "layout": {
238
- "x": 107,
239
- "y": 83,
240
- "mode": "absolute",
241
- "width": 220,
242
- "height": 14,
243
- "zIndex": 2
244
- }
245
- }
246
- ]
247
- }
248
- ],
249
- "layout": {
250
- "x": 0,
251
- "y": 0,
252
- "mode": "absolute",
253
- "width": 0,
254
- "height": 0,
255
- "zIndex": 1
256
- },
257
- "visible": false,
258
- "dataPath": "user.multiCompanyDuty",
259
- "maxItems": 3,
260
- "itemTemplate": [
261
- {
262
- "id": "company-duty",
263
- "type": "text",
264
- "style": {
265
- "fontSize": 13,
266
- "textAlign": "left",
267
- "fontWeight": "normal",
268
- "lineHeight": 18
269
- },
270
- "layout": {
271
- "x": 107,
272
- "y": 51,
273
- "mode": "absolute",
274
- "width": 190,
275
- "height": 18,
276
- "zIndex": 2
277
- }
278
- }
279
- ],
280
- "mutualExcludes": [
281
- "user.company",
282
- "user.duty"
283
- ]
284
- },
285
- {
286
- "id": "multiple-company-1",
287
- "type": "text",
288
- "style": {
289
- "color": "",
290
- "fontSize": 11,
291
- "textAlign": "left",
292
- "fontWeight": "normal",
293
- "lineHeight": 11
294
- },
295
- "layout": {
296
- "x": 107,
297
- "y": 51,
298
- "mode": "absolute",
299
- "width": 190,
300
- "height": 11,
301
- "zIndex": 2
302
- },
303
- "visible": false
304
- },
305
- {
306
- "id": "multiple-company-2",
307
- "type": "text",
308
- "style": {
309
- "color": "",
310
- "fontSize": 11,
311
- "textAlign": "left",
312
- "fontWeight": "normal",
313
- "lineHeight": 11
314
- },
315
- "layout": {
316
- "x": 107,
317
- "y": 65,
318
- "mode": "absolute",
319
- "width": 190,
320
- "height": 11,
321
- "zIndex": 2
322
- },
323
- "visible": false
324
- },
325
- {
326
- "id": "multiple-company-3",
327
- "type": "text",
328
- "style": {
329
- "color": "",
330
- "fontSize": 11,
331
- "textAlign": "left",
332
- "fontWeight": "normal",
333
- "lineHeight": 11
334
- },
335
- "layout": {
336
- "x": 107,
337
- "y": 79,
338
- "mode": "absolute",
339
- "width": 190,
340
- "height": 11,
341
- "zIndex": 2
342
- },
343
- "visible": false
344
- }
345
- ],
346
- "container": {
347
- "mode": "absolute"
348
- },
349
- "fontColor": "#ffffff",
350
- "backgroundImage": "https://km-1257079185.cos.ap-chengdu.myqcloud.com/local/image/202511/21dd21c0d693a1eb44e53bad64b9b94a.png",
351
- "backgroundZIndex": 0
352
- }
353
- ]
3
+ const layouts = [{"name":"内置布局-右侧logo","width":343,"height":210,"children":[{"id":"f2dd3515-2147-460a-b788-3f58dd5f858b","type":"custom","style":{"borderRadius":0,"backgroundColor":"currentColor"},"layout":{"x":20,"y":104,"mode":"absolute","width":12,"height":1,"zIndex":8}},{"id":"7fd4c8cd-6bea-42d0-9a80-b1ba27f4abd3","type":"custom","style":{"borderRadius":0,"backgroundColor":"currentColor"},"layout":{"x":37,"y":104,"mode":"absolute","width":105,"height":1,"zIndex":9}},{"id":"1","key":"name","type":"text","style":{"color":"","fontSize":16,"textAlign":"left","fontWeight":"bold","lineHeight":22},"layout":{"x":20,"y":45,"mode":"absolute","width":210,"height":22,"zIndex":1},"binding":"user.name","defaultValue":"名片君"},{"id":"2","key":"company","type":"text","style":{"color":"","fontSize":11,"textAlign":"left","fontWeight":"normal","lineHeight":15},"layout":{"x":20,"y":74,"mode":"absolute","width":210,"height":15,"zIndex":3},"binding":"user.company","defaultValue":"合肥魅客网络有限公司"},{"id":"4","key":"duty","type":"text","style":{"color":"","fontSize":10,"textAlign":"left","fontWeight":"normal","lineHeight":15},"layout":{"x":20,"y":21,"mode":"absolute","width":210,"height":15,"zIndex":2},"binding":"user.duty","defaultValue":"销售经理"},{"id":"3","key":"mobile","icon":{"style":"fill","enable":true},"type":"text","style":{"color":"","fontSize":10,"textAlign":"left","fontWeight":"normal","lineHeight":15},"layout":{"x":20,"y":123,"mode":"absolute","width":280,"height":15,"zIndex":5},"binding":"user.mobile","defaultValue":"18888888888"},{"id":"5","key":"email","icon":{"style":"fill","enable":true},"type":"text","style":{"color":"","fontSize":10,"textAlign":"left","fontWeight":"normal","lineHeight":15},"layout":{"x":20,"y":145,"mode":"absolute","width":280,"height":15,"zIndex":6},"binding":"user.email","defaultValue":"km@kuanmai.com"},{"id":"8","key":"logo","type":"image","style":{"color":"#000000","objectFit":"contain","borderRadius":0},"layout":{"x":263,"y":20,"mode":"absolute","width":60,"height":60,"zIndex":4},"binding":"user.logo","defaultValue":"https://km-1257079185.cos.ap-chengdu.myqcloud.com/local/image/202511/4c71811adfa51e1e3ab4181a88cebc87.png"},{"id":"9","key":"address","icon":{"style":"fill","enable":true},"type":"text","style":{"color":"","fontSize":10,"textAlign":"left","fontWeight":"normal","lineHeight":15},"layout":{"x":20,"y":167,"mode":"absolute","width":280,"height":33,"zIndex":7},"binding":"user.address","defaultValue":"安徽省合肥市包河区硅谷大厦"}],"container":{"mode":"absolute"},"fontColor":"#333333","backgroundImage":"https://km-1257079185.cos.ap-chengdu.myqcloud.com/local/image/202511/0a7331e2e1a9a4cbc828afe6c338aaae.png","backgroundZIndex":1}]
354
4
 
355
5
 
356
6
  const cardData = {
@@ -90,7 +90,7 @@ const mapIconGlyph = (name, fallback) => {
90
90
  return fallback || name;
91
91
  };
92
92
  const buildTextIcon = (el, unit) => {
93
- var _a, _b, _c, _d;
93
+ var _a, _b, _c, _d, _e;
94
94
  const icon = el.icon;
95
95
  if (!icon || icon.enable === false)
96
96
  return undefined;
@@ -116,6 +116,11 @@ const buildTextIcon = (el, unit) => {
116
116
  text,
117
117
  size: size !== undefined ? withUnit(size, unit) : undefined,
118
118
  gap: gap !== undefined ? withUnit(gap, unit) : undefined,
119
+ wrapperStyle: (0, index_1.styleObjectToString)({
120
+ display: 'inline-flex',
121
+ alignItems: 'center',
122
+ height: ((_e = el.style) === null || _e === void 0 ? void 0 : _e.lineHeight) || 'auto',
123
+ }, unit),
119
124
  color,
120
125
  align: icon.align || 'left',
121
126
  };
@@ -62,15 +62,23 @@
62
62
  <view class="km-node km-node--text" style="{{node.wrapperStyle}}">
63
63
  <view class="km-node__text" style="{{node.contentStyle}}">
64
64
  <block wx:if="{{node.icon && node.icon.name}}">
65
- <view
66
- class="km-node__text-content"
67
- style="flex-direction: {{node.icon.align === 'right' ? 'row-reverse' : 'row'}};">
68
- <text
69
- class="km-node__text-icon icon"
70
- style="font-size: {{node.icon.size || '16px'}}; color: {{node.icon.color || ''}}; margin-right: {{node.icon.align !== 'right' ? (node.icon.gap || '') : ''}}; margin-left: {{node.icon.align === 'right' ? (node.icon.gap || '') : ''}};">
71
- {{node.icon.text || node.icon.name || ''}}
72
- </text>
73
- <text class="km-node__text-value">{{node.text || ''}}</text>
65
+ <view class="km-node__text-content">
66
+ <block wx:if="{{node.icon.align === 'right'}}">
67
+ <text class="km-node__text-value">{{node.text || ''}}</text>
68
+ <view style="{{node.icon.wrapperStyle}}">
69
+ <text
70
+ class="km-node__text-icon icon"
71
+ style="font-size: {{node.icon.size || '16px'}}; color: {{node.icon.color || ''}}; margin-right: {{node.icon.gap || ''}};">{{node.icon.text || node.icon.name || ''}}</text>
72
+ </view>
73
+ </block>
74
+ <block wx:else>
75
+ <view style="{{node.icon.wrapperStyle}}">
76
+ <text
77
+ class="km-node__text-icon icon"
78
+ style="font-size: {{node.icon.size || '16px'}}; color: {{node.icon.color || ''}}; margin-right: {{node.icon.gap || ''}};">{{node.icon.text || node.icon.name || ''}}</text>
79
+ </view>
80
+ <text class="km-node__text-value">{{node.text || ''}}</text>
81
+ </block>
74
82
  </view>
75
83
  </block>
76
84
  <block wx:else>
@@ -78,25 +78,26 @@
78
78
  .km-node__text {
79
79
  width: 100%;
80
80
  height: 100%;
81
- display: flex;
82
- align-items: center;
81
+ display: block;
82
+ box-sizing: border-box;
83
+ text-align: inherit;
83
84
  }
84
85
 
85
86
  .km-node__text-content {
86
- display: inline-flex;
87
- align-items: center;
87
+ display: inline-block;
88
+ vertical-align: middle;
89
+ height: 100%;
88
90
  }
89
91
 
90
92
  .km-node__text-value {
91
93
  display: inline-block;
92
94
  white-space: pre-wrap;
93
95
  word-break: break-word;
96
+ vertical-align: middle;
94
97
  }
95
98
 
96
99
  .km-node--text text {
97
- display: block;
98
- white-space: pre-wrap;
99
- word-break: break-word;
100
+ display: inline;
100
101
  }
101
102
 
102
103
  /* ICON */
@@ -385,3 +385,4 @@ const buildRenderResult = (layoutInput, dataInput, unit = 'px') => {
385
385
  });
386
386
  };
387
387
  exports.buildRenderResult = buildRenderResult;
388
+ __exportStar(require("./utils"), exports);
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./elements"), exports);
18
18
  __exportStar(require("./layout"), exports);
19
19
  __exportStar(require("./render"), exports);
20
+ __exportStar(require("./data/payload"), exports);
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTemplateBackgrounds = exports.getTemplateItems = exports.applyItemCollectBindings = exports.stripLayoutBindings = exports.backgroundChange = void 0;
4
+ function backgroundChange(bg, layout) {
5
+ const toNameArray = (name) => {
6
+ if (Array.isArray(name))
7
+ return name.filter(Boolean);
8
+ if (!name)
9
+ return [];
10
+ return `${name}`
11
+ .split(',')
12
+ .map(n => n.trim())
13
+ .filter(Boolean);
14
+ };
15
+ const applySpecialColor = (el) => {
16
+ const extras = bg.fontColorExtra || [];
17
+ if (!extras.length)
18
+ return el;
19
+ const keys = [];
20
+ if (el.binding)
21
+ keys.push(String(el.binding));
22
+ if (el.id)
23
+ keys.push(String(el.id));
24
+ if (el.type === 'icon')
25
+ keys.push('icon');
26
+ if (el.type === 'custom')
27
+ keys.push('decor');
28
+ const matched = extras.find(sc => toNameArray(sc.name).some(n => keys.some(k => k === null || k === void 0 ? void 0 : k.startsWith(n))));
29
+ if (!matched)
30
+ return el;
31
+ const baseStyle = { ...(el.style || {}) };
32
+ if (el.type === 'custom') {
33
+ return { ...el, style: { ...baseStyle, backgroundColor: matched.color } };
34
+ }
35
+ return { ...el, style: { ...baseStyle, color: matched.color } };
36
+ };
37
+ const traverse = (children = []) => children.map(el => {
38
+ if (!el)
39
+ return el;
40
+ if (el.type === 'layout-panel') {
41
+ return {
42
+ ...el,
43
+ children: traverse(el.children || []),
44
+ };
45
+ }
46
+ return applySpecialColor(el);
47
+ });
48
+ return {
49
+ ...layout,
50
+ backgroundImage: bg.imgUrl,
51
+ fontColor: bg.fontColor || layout.fontColor,
52
+ children: traverse(layout.children || []),
53
+ };
54
+ }
55
+ exports.backgroundChange = backgroundChange;
56
+ function stripLayoutBindings(layouts = []) {
57
+ const targetLayouts = Array.isArray(layouts) ? layouts : [];
58
+ const stripElement = (el) => {
59
+ const { binding: _b, defaultValue: _d, ...rest } = el;
60
+ if (el.type === 'layout-panel') {
61
+ return {
62
+ ...rest,
63
+ children: (el.children || []).map(stripElement),
64
+ };
65
+ }
66
+ return rest;
67
+ };
68
+ return targetLayouts.map(layout => ({
69
+ ...layout,
70
+ children: (layout.children || []).map(stripElement),
71
+ }));
72
+ }
73
+ exports.stripLayoutBindings = stripLayoutBindings;
74
+ /**
75
+ * 应用元素数据绑定字段
76
+ * @param layouts 布局
77
+ * @param items 绑定元素数据
78
+ * @returns
79
+ */
80
+ function applyItemCollectBindings(layouts = [], items = []) {
81
+ const targetLayouts = Array.isArray(layouts) ? layouts : [];
82
+ const metaMap = new Map();
83
+ const metaList = Array.isArray(items) ? items : [];
84
+ metaList.forEach(item => {
85
+ if (item && item.id !== undefined && item.id !== null) {
86
+ metaMap.set(String(item.id), item);
87
+ }
88
+ });
89
+ const assignBinding = (el) => {
90
+ const meta = metaMap.get(String(el.id));
91
+ const binding = meta && meta.bind !== undefined && meta.bind !== null
92
+ ? meta.bind
93
+ : el.binding;
94
+ const defaultValue = meta && meta.default !== undefined ? meta.default : el.defaultValue;
95
+ const key = meta && meta.key !== undefined ? meta.key : el.key;
96
+ const base = { ...el };
97
+ if (binding !== undefined)
98
+ base.binding = binding;
99
+ else
100
+ delete base.binding;
101
+ if (defaultValue !== undefined)
102
+ base.defaultValue = defaultValue;
103
+ else
104
+ delete base.defaultValue;
105
+ if (key !== undefined)
106
+ base.key = key;
107
+ else
108
+ delete base.key;
109
+ if (el.type === 'layout-panel') {
110
+ return {
111
+ ...base,
112
+ children: (el.children || []).map(assignBinding),
113
+ };
114
+ }
115
+ return base;
116
+ };
117
+ return targetLayouts.map(layout => ({
118
+ ...layout,
119
+ children: (layout.children || []).map(assignBinding),
120
+ }));
121
+ }
122
+ exports.applyItemCollectBindings = applyItemCollectBindings;
123
+ function getTemplateItems(ids, items) {
124
+ const idArray = ids.split(',').map(id => id.trim());
125
+ return items.filter(item => idArray.includes(String(item.id)));
126
+ }
127
+ exports.getTemplateItems = getTemplateItems;
128
+ function getTemplateBackgrounds(ids, items) {
129
+ const idArray = ids.split(',').map(id => id.trim());
130
+ return items.filter(item => idArray.includes(String(item.id)));
131
+ }
132
+ exports.getTemplateBackgrounds = getTemplateBackgrounds;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "km-card-layout-component-miniprogram",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "",
5
5
  "main": "miniprogram_dist/index.js",
6
6
  "miniprogram": "miniprogram_dist",
@@ -5,7 +5,7 @@ const pkgRoot = path.resolve(__dirname, '..');
5
5
  const coreRoot = path.resolve(pkgRoot, '../km-card-layout-core');
6
6
  const targetDir = path.resolve(pkgRoot, 'src/vendor/km-card-layout-core');
7
7
 
8
- const filesToCopy = ['index.ts', 'types.d.ts'];
8
+ const filesToCopy = ['index.ts', 'types.d.ts', 'utils.ts'];
9
9
  const dirsToCopy = ['interface'];
10
10
 
11
11
  function ensureFileExists(filePath) {
@@ -26,6 +26,7 @@ interface RenderIcon {
26
26
  color?: string;
27
27
  gap?: string;
28
28
  align?: 'left' | 'right';
29
+ wrapperStyle: string;
29
30
  }
30
31
 
31
32
  interface RenderElement {
@@ -195,6 +196,14 @@ const buildTextIcon = (
195
196
  text,
196
197
  size: size !== undefined ? withUnit(size, unit) : undefined,
197
198
  gap: gap !== undefined ? withUnit(gap, unit) : undefined,
199
+ wrapperStyle: styleObjectToString(
200
+ {
201
+ display: 'inline-flex',
202
+ alignItems: 'center',
203
+ height: el.style?.lineHeight || 'auto',
204
+ },
205
+ unit,
206
+ ),
198
207
  color,
199
208
  align: icon.align || 'left',
200
209
  };
@@ -62,15 +62,23 @@
62
62
  <view class="km-node km-node--text" style="{{node.wrapperStyle}}">
63
63
  <view class="km-node__text" style="{{node.contentStyle}}">
64
64
  <block wx:if="{{node.icon && node.icon.name}}">
65
- <view
66
- class="km-node__text-content"
67
- style="flex-direction: {{node.icon.align === 'right' ? 'row-reverse' : 'row'}};">
68
- <text
69
- class="km-node__text-icon icon"
70
- style="font-size: {{node.icon.size || '16px'}}; color: {{node.icon.color || ''}}; margin-right: {{node.icon.align !== 'right' ? (node.icon.gap || '') : ''}}; margin-left: {{node.icon.align === 'right' ? (node.icon.gap || '') : ''}};">
71
- {{node.icon.text || node.icon.name || ''}}
72
- </text>
73
- <text class="km-node__text-value">{{node.text || ''}}</text>
65
+ <view class="km-node__text-content">
66
+ <block wx:if="{{node.icon.align === 'right'}}">
67
+ <text class="km-node__text-value">{{node.text || ''}}</text>
68
+ <view style="{{node.icon.wrapperStyle}}">
69
+ <text
70
+ class="km-node__text-icon icon"
71
+ style="font-size: {{node.icon.size || '16px'}}; color: {{node.icon.color || ''}}; margin-right: {{node.icon.gap || ''}};">{{node.icon.text || node.icon.name || ''}}</text>
72
+ </view>
73
+ </block>
74
+ <block wx:else>
75
+ <view style="{{node.icon.wrapperStyle}}">
76
+ <text
77
+ class="km-node__text-icon icon"
78
+ style="font-size: {{node.icon.size || '16px'}}; color: {{node.icon.color || ''}}; margin-right: {{node.icon.gap || ''}};">{{node.icon.text || node.icon.name || ''}}</text>
79
+ </view>
80
+ <text class="km-node__text-value">{{node.text || ''}}</text>
81
+ </block>
74
82
  </view>
75
83
  </block>
76
84
  <block wx:else>
@@ -78,25 +78,26 @@
78
78
  .km-node__text {
79
79
  width: 100%;
80
80
  height: 100%;
81
- display: flex;
82
- align-items: center;
81
+ display: block;
82
+ box-sizing: border-box;
83
+ text-align: inherit;
83
84
  }
84
85
 
85
86
  .km-node__text-content {
86
- display: inline-flex;
87
- align-items: center;
87
+ display: inline-block;
88
+ vertical-align: middle;
89
+ height: 100%;
88
90
  }
89
91
 
90
92
  .km-node__text-value {
91
93
  display: inline-block;
92
94
  white-space: pre-wrap;
93
95
  word-break: break-word;
96
+ vertical-align: middle;
94
97
  }
95
98
 
96
99
  .km-node--text text {
97
- display: block;
98
- white-space: pre-wrap;
99
- word-break: break-word;
100
+ display: inline;
100
101
  }
101
102
 
102
103
  /* ICON */
@@ -456,3 +456,5 @@ export const buildRenderResult = (
456
456
  };
457
457
  });
458
458
  };
459
+
460
+ export * from './utils';
@@ -1,3 +1,5 @@
1
+ import { CardLayoutSchema } from "../layout";
2
+
1
3
  /**
2
4
  * 背景项
3
5
  */
@@ -6,11 +8,10 @@ export interface TemplateBackground {
6
8
  name: string;
7
9
  fileId?: number;
8
10
  fontColor?: string;
9
- fontColorExtra?: { name: string | string[]; color: string }[]
11
+ fontColorExtra?: { name: string | string[]; color: string }[];
10
12
  imgUrl: string;
11
13
  }
12
14
 
13
-
14
15
  /**
15
16
  * 元素项
16
17
  */
@@ -25,3 +26,20 @@ export interface TemplateItem {
25
26
  cate: number;
26
27
  required?: 0 | 1;
27
28
  }
29
+
30
+ export interface TemplateLayoutInfo {
31
+ id: number | string;
32
+ name?: string;
33
+ previewImg?: string;
34
+ height?: number;
35
+ width?: number;
36
+ enableBgIds?: string | null;
37
+ enableItemIds?: string | null;
38
+ content?: CardLayoutSchema[];
39
+ isVip?: 0 | 1;
40
+ isDouble?: 0 | 1;
41
+ isMoreCompany?: 0 | 1;
42
+ isBgCustomize?: 0 | 1;
43
+ createAt?: string;
44
+ updateAt?: string;
45
+ }
@@ -1,3 +1,4 @@
1
1
  export * from './elements';
2
2
  export * from './layout';
3
3
  export * from './render';
4
+ export * from './data/payload';
@@ -14,13 +14,6 @@ import type {
14
14
  RenderResult,
15
15
  } from './interface';
16
16
 
17
- export type ItemCollectMeta = {
18
- id: string | number;
19
- bind?: string | null;
20
- default?: string | null;
21
- key?: string | null;
22
- };
23
-
24
17
  export function addUnit(
25
18
  value: string | number | undefined | null,
26
19
  unit: 'px' | 'rpx'
@@ -45,7 +38,7 @@ export function stripLayoutBindings(
45
38
 
46
39
  export function applyItemCollectBindings(
47
40
  layouts: CardLayoutSchema[],
48
- items?: ItemCollectMeta[]
41
+ items?: TemplateItem[]
49
42
  ): CardLayoutSchema[];
50
43
 
51
44
  export function buildRenderNodes(
@@ -60,3 +53,7 @@ export function buildRenderResult(
60
53
  data: Record<string, any>,
61
54
  unit?: 'px' | 'rpx'
62
55
  ): RenderResult;
56
+
57
+ export function getTemplateItems(ids: string, items: TemplateItem[]): TemplateItem[];
58
+
59
+ export function getTemplateBackgrounds(ids: string, items: TemplateBackground[]) : TemplateBackground[];
@@ -0,0 +1,141 @@
1
+ import type { CardElement, CardLayoutSchema, TemplateItem } from './interface';
2
+ import { TemplateBackground } from './interface/data/payload';
3
+
4
+
5
+ export function backgroundChange(
6
+ bg: TemplateBackground,
7
+ layout: CardLayoutSchema
8
+ ): CardLayoutSchema {
9
+ const toNameArray = (name?: string | string[]) => {
10
+ if (Array.isArray(name)) return name.filter(Boolean);
11
+ if (!name) return [];
12
+ return `${name}`
13
+ .split(',')
14
+ .map(n => n.trim())
15
+ .filter(Boolean);
16
+ };
17
+
18
+ const applySpecialColor = (el: CardElement): CardElement => {
19
+ const extras = bg.fontColorExtra || [];
20
+ if (!extras.length) return el;
21
+
22
+ const keys: string[] = [];
23
+ if (el.binding) keys.push(String(el.binding));
24
+ if (el.id) keys.push(String(el.id));
25
+ if (el.type === 'icon') keys.push('icon');
26
+ if (el.type === 'custom') keys.push('decor');
27
+
28
+ const matched = extras.find(sc =>
29
+ toNameArray(sc.name).some(n => keys.some(k => k?.startsWith(n)))
30
+ );
31
+ if (!matched) return el;
32
+
33
+ const baseStyle = { ...(el.style || {}) };
34
+ if (el.type === 'custom') {
35
+ return { ...el, style: { ...baseStyle, backgroundColor: matched.color } };
36
+ }
37
+ return { ...el, style: { ...baseStyle, color: matched.color } };
38
+ };
39
+
40
+ const traverse = (children: CardElement[] = []): CardElement[] =>
41
+ children.map(el => {
42
+ if (!el) return el;
43
+ if (el.type === 'layout-panel') {
44
+ return {
45
+ ...el,
46
+ children: traverse(el.children || []),
47
+ };
48
+ }
49
+ return applySpecialColor(el);
50
+ });
51
+
52
+ return {
53
+ ...layout,
54
+ backgroundImage: bg.imgUrl,
55
+ fontColor: bg.fontColor || layout.fontColor,
56
+ children: traverse(layout.children || []),
57
+ };
58
+ }
59
+
60
+ export function stripLayoutBindings(
61
+ layouts: CardLayoutSchema[] = []
62
+ ): CardLayoutSchema[] {
63
+ const targetLayouts = Array.isArray(layouts) ? layouts : [];
64
+ const stripElement = (el: CardElement): CardElement => {
65
+ const { binding: _b, defaultValue: _d, ...rest } = el as any;
66
+ if (el.type === 'layout-panel') {
67
+ return {
68
+ ...rest,
69
+ children: (el.children || []).map(stripElement),
70
+ } as CardElement;
71
+ }
72
+ return rest as CardElement;
73
+ };
74
+
75
+ return targetLayouts.map(layout => ({
76
+ ...layout,
77
+ children: (layout.children || []).map(stripElement),
78
+ }));
79
+ }
80
+
81
+ /**
82
+ * 应用元素数据绑定字段
83
+ * @param layouts 布局
84
+ * @param items 绑定元素数据
85
+ * @returns
86
+ */
87
+ export function applyItemCollectBindings(
88
+ layouts: CardLayoutSchema[] = [],
89
+ items: TemplateItem[] = []
90
+ ): CardLayoutSchema[] {
91
+ const targetLayouts = Array.isArray(layouts) ? layouts : [];
92
+ const metaMap = new Map<string, TemplateItem>();
93
+ const metaList = Array.isArray(items) ? items : [];
94
+ metaList.forEach(item => {
95
+ if (item && item.id !== undefined && item.id !== null) {
96
+ metaMap.set(String(item.id), item);
97
+ }
98
+ });
99
+
100
+ const assignBinding = (el: CardElement): CardElement => {
101
+ const meta = metaMap.get(String(el.id));
102
+ const binding =
103
+ meta && meta.bind !== undefined && meta.bind !== null
104
+ ? meta.bind
105
+ : el.binding;
106
+ const defaultValue =
107
+ meta && meta.default !== undefined ? meta.default : el.defaultValue;
108
+ const key = meta && meta.key !== undefined ? meta.key : el.key;
109
+ const base: any = { ...el };
110
+ if (binding !== undefined) base.binding = binding;
111
+ else delete base.binding;
112
+ if (defaultValue !== undefined) base.defaultValue = defaultValue;
113
+ else delete base.defaultValue;
114
+ if (key !== undefined) base.key = key;
115
+ else delete base.key;
116
+
117
+ if (el.type === 'layout-panel') {
118
+ return {
119
+ ...base,
120
+ children: (el.children || []).map(assignBinding),
121
+ } as CardElement;
122
+ }
123
+ return base as CardElement;
124
+ };
125
+
126
+ return targetLayouts.map(layout => ({
127
+ ...layout,
128
+ children: (layout.children || []).map(assignBinding),
129
+ }));
130
+ }
131
+
132
+ export function getTemplateItems(ids: string, items: TemplateItem[]) {
133
+ const idArray = ids.split(',').map(id => id.trim());
134
+ return items.filter(item => idArray.includes(String(item.id)));
135
+ }
136
+
137
+
138
+ export function getTemplateBackgrounds(ids: string, items: TemplateBackground[]){
139
+ const idArray = ids.split(',').map(id => id.trim());
140
+ return items.filter(item => idArray.includes(String(item.id)));
141
+ }