km-card-layout-component-miniprogram 0.1.19 → 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.
- package/example/app.js +11 -1
- package/example/pages/home/index.js +324 -101
- package/example/pages/home/index.wxml +2 -1
- package/miniprogram_dist/components/card-layout/elements/custom-element/index.js +12 -6
- package/miniprogram_dist/components/card-layout/elements/custom-element/index.wxml +4 -6
- package/miniprogram_dist/components/card-layout/elements/custom-element/index.wxss +1 -1
- package/miniprogram_dist/components/card-layout/elements/icon-element/index.js +32 -15
- package/miniprogram_dist/components/card-layout/elements/icon-element/index.wxml +3 -7
- package/miniprogram_dist/components/card-layout/elements/icon-element/index.wxss +3 -17
- package/miniprogram_dist/components/card-layout/elements/icon-font.wxss +438 -0
- package/miniprogram_dist/components/card-layout/elements/image-element/index.js +18 -9
- package/miniprogram_dist/components/card-layout/elements/image-element/index.wxml +8 -10
- package/miniprogram_dist/components/card-layout/elements/image-element/index.wxss +1 -1
- package/miniprogram_dist/components/card-layout/elements/layout-panel-element/index.js +37 -0
- package/miniprogram_dist/components/card-layout/elements/layout-panel-element/index.json +3 -0
- package/miniprogram_dist/components/card-layout/elements/layout-panel-element/index.wxml +5 -0
- package/miniprogram_dist/components/card-layout/elements/layout-panel-element/index.wxss +10 -0
- package/miniprogram_dist/components/card-layout/elements/text-element/index.js +41 -17
- package/miniprogram_dist/components/card-layout/elements/text-element/index.wxml +8 -34
- package/miniprogram_dist/components/card-layout/elements/text-element/index.wxss +5 -18
- package/miniprogram_dist/components/card-layout/index.js +31 -108
- package/miniprogram_dist/components/card-layout/index.json +9 -1
- package/miniprogram_dist/components/card-layout/index.wxml +25 -46
- package/miniprogram_dist/components/card-layout/index.wxss +1 -538
- package/package.json +1 -1
- package/src/components/card-layout/elements/custom-element/index.ts +13 -7
- package/src/components/card-layout/elements/custom-element/index.wxml +4 -6
- package/src/components/card-layout/elements/custom-element/index.wxss +1 -1
- package/src/components/card-layout/elements/icon-element/index.ts +34 -16
- package/src/components/card-layout/elements/icon-element/index.wxml +3 -7
- package/src/components/card-layout/elements/icon-element/index.wxss +3 -17
- package/src/components/card-layout/elements/icon-font.wxss +438 -0
- package/src/components/card-layout/elements/image-element/index.ts +21 -11
- package/src/components/card-layout/elements/image-element/index.wxml +8 -10
- package/src/components/card-layout/elements/image-element/index.wxss +1 -1
- package/src/components/card-layout/elements/layout-panel-element/index.json +3 -0
- package/src/components/card-layout/elements/layout-panel-element/index.ts +40 -0
- package/src/components/card-layout/elements/layout-panel-element/index.wxml +5 -0
- package/src/components/card-layout/elements/layout-panel-element/index.wxss +10 -0
- package/src/components/card-layout/elements/text-element/index.ts +48 -19
- package/src/components/card-layout/elements/text-element/index.wxml +8 -34
- package/src/components/card-layout/elements/text-element/index.wxss +5 -18
- package/src/components/card-layout/index.json +9 -1
- package/src/components/card-layout/index.ts +36 -156
- package/src/components/card-layout/index.wxml +25 -46
- package/src/components/card-layout/index.wxss +1 -538
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildPanelContentStyle,
|
|
3
|
+
buildWrapperStyle,
|
|
4
|
+
styleObjectToString,
|
|
5
|
+
type LayoutPanelElement,
|
|
6
|
+
} from "../../../../vendor/km-card-layout-core/index";
|
|
7
|
+
|
|
8
|
+
Component({
|
|
9
|
+
options: {
|
|
10
|
+
styleIsolation: "apply-shared",
|
|
11
|
+
},
|
|
12
|
+
properties: {
|
|
13
|
+
element: {
|
|
14
|
+
type: Object,
|
|
15
|
+
value: {},
|
|
16
|
+
},
|
|
17
|
+
rootData: {
|
|
18
|
+
type: Object,
|
|
19
|
+
value: {},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
data: {
|
|
23
|
+
wrapperStyle: "",
|
|
24
|
+
contentStyle: "",
|
|
25
|
+
},
|
|
26
|
+
observers: {
|
|
27
|
+
element() {
|
|
28
|
+
this.rebuild();
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
methods: {
|
|
32
|
+
rebuild() {
|
|
33
|
+
const el = this.data.element as LayoutPanelElement;
|
|
34
|
+
if (!el) return;
|
|
35
|
+
const wrapperStyle = styleObjectToString(buildWrapperStyle(el, "rpx"), "rpx");
|
|
36
|
+
const contentStyle = styleObjectToString(buildPanelContentStyle(el, "rpx"), "rpx");
|
|
37
|
+
this.setData({ wrapperStyle, contentStyle });
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
});
|
|
@@ -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
|
|
9
|
-
import { ICON_CODE_MAP } from
|
|
9
|
+
} from "../../../../vendor/km-card-layout-core/index";
|
|
10
|
+
import { ICON_CODE_MAP } from "../../icon-map";
|
|
10
11
|
|
|
11
|
-
const
|
|
12
|
-
if (!name) return
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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:
|
|
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(
|
|
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
|
|
42
|
-
const wrapperStyle = styleObjectToString(buildWrapperStyle(el,
|
|
43
|
-
const contentStyle = styleObjectToString(buildTextContentStyle(el,
|
|
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
|
|
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
|
-
|
|
51
|
-
|
|
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
|
-
<
|
|
2
|
-
<view class="km-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
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,23 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
CardElement,
|
|
3
|
-
CardLayoutInput,
|
|
4
3
|
CardLayoutSchema,
|
|
5
|
-
|
|
6
|
-
IconElement,
|
|
7
|
-
ImageElement,
|
|
8
|
-
LayoutPanelElement,
|
|
9
|
-
TextElement,
|
|
10
|
-
} from '../../vendor/km-card-layout-core/index';
|
|
4
|
+
} from "../../vendor/km-card-layout-core/index";
|
|
11
5
|
import {
|
|
12
6
|
buildBackgroundStyle,
|
|
13
|
-
buildBaseContentStyle,
|
|
14
7
|
buildCardStyle,
|
|
15
|
-
buildImageContentStyle,
|
|
16
|
-
buildPanelContentStyle,
|
|
17
|
-
buildTextContentStyle,
|
|
18
|
-
buildTextIconMeta,
|
|
19
|
-
buildWrapperStyle,
|
|
20
|
-
getIconName,
|
|
21
|
-
getImageSrc,
|
|
22
|
-
getTextValue,
|
|
23
8
|
normalizeLayout,
|
|
24
9
|
processCardLayout,
|
|
25
10
|
styleObjectToString,
|
|
26
|
-
} from
|
|
27
|
-
import { ICON_CODE_MAP } from './icon-map';
|
|
11
|
+
} from "../../vendor/km-card-layout-core/index";
|
|
28
12
|
|
|
29
13
|
type CompanyDuty = {
|
|
30
14
|
company: string;
|
|
31
15
|
duty: string;
|
|
32
16
|
};
|
|
33
17
|
|
|
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
18
|
const EMPTY_COMPANY_DUTY: CompanyDuty = {
|
|
44
|
-
company:
|
|
45
|
-
duty:
|
|
19
|
+
company: "",
|
|
20
|
+
duty: "",
|
|
46
21
|
};
|
|
47
22
|
|
|
48
23
|
/**
|
|
@@ -79,7 +54,6 @@ export function normalizeMoreCompany(data: AnyObject): AnyObject {
|
|
|
79
54
|
};
|
|
80
55
|
}
|
|
81
56
|
|
|
82
|
-
|
|
83
57
|
const handleSpecialFields = (data: { user: Record<string, any> }) => {
|
|
84
58
|
const user = data.user ?? {};
|
|
85
59
|
return {
|
|
@@ -87,15 +61,13 @@ const handleSpecialFields = (data: { user: Record<string, any> }) => {
|
|
|
87
61
|
user: {
|
|
88
62
|
...user,
|
|
89
63
|
baseCompanyDuty:
|
|
90
|
-
user.company && user.duty
|
|
91
|
-
? `${user.company} ${user.duty}`
|
|
92
|
-
: user.baseCompanyDuty,
|
|
64
|
+
user.company && user.duty ? `${user.company} ${user.duty}` : user.baseCompanyDuty,
|
|
93
65
|
moreCardInfo: user.moreCardInfo
|
|
94
66
|
? {
|
|
95
67
|
...user.moreCardInfo,
|
|
96
68
|
company: Array.isArray(user.moreCardInfo.company)
|
|
97
69
|
? (user.moreCardInfo.company as CompanyDuty[]).map(
|
|
98
|
-
item => `${item.company} ${item.duty}`
|
|
70
|
+
(item) => `${item.company} ${item.duty}`
|
|
99
71
|
)
|
|
100
72
|
: user.moreCardInfo.company,
|
|
101
73
|
}
|
|
@@ -104,22 +76,7 @@ const handleSpecialFields = (data: { user: Record<string, any> }) => {
|
|
|
104
76
|
};
|
|
105
77
|
};
|
|
106
78
|
|
|
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
|
-
};
|
|
79
|
+
type RenderElement = CardElement;
|
|
123
80
|
|
|
124
81
|
type RenderCard = {
|
|
125
82
|
id: string;
|
|
@@ -129,123 +86,33 @@ type RenderCard = {
|
|
|
129
86
|
elements: RenderElement[];
|
|
130
87
|
};
|
|
131
88
|
|
|
132
|
-
const ensureArray = (input: CardLayoutInput | any): CardLayoutInput => {
|
|
133
|
-
if (!input) return [];
|
|
134
|
-
return Array.isArray(input) ? input : [input];
|
|
135
|
-
};
|
|
136
|
-
|
|
137
89
|
const pickCardId = (layout: any, idx: number) => {
|
|
138
90
|
if (layout && (layout.name || layout.id)) return layout.name || layout.id;
|
|
139
91
|
return `card-${idx}`;
|
|
140
92
|
};
|
|
141
93
|
|
|
142
|
-
const
|
|
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>) => {
|
|
94
|
+
const buildCards = (layouts: CardLayoutSchema[]) => {
|
|
221
95
|
return layouts.map((layout, idx) => ({
|
|
222
96
|
id: pickCardId(layouts[idx], idx),
|
|
223
|
-
cardStyle: styleObjectToString(buildCardStyle(layout,
|
|
224
|
-
backgroundImage: layout.backgroundImage ||
|
|
225
|
-
backgroundStyle: styleObjectToString(buildBackgroundStyle(layout,
|
|
226
|
-
elements:
|
|
97
|
+
cardStyle: styleObjectToString(buildCardStyle(layout, "rpx"), "rpx"),
|
|
98
|
+
backgroundImage: layout.backgroundImage || "",
|
|
99
|
+
backgroundStyle: styleObjectToString(buildBackgroundStyle(layout, "rpx"), "rpx"),
|
|
100
|
+
elements: layout.children || [],
|
|
227
101
|
}));
|
|
228
102
|
};
|
|
229
103
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
schemas: CardLayoutSchema[]
|
|
233
|
-
): boolean => {
|
|
234
|
-
const TARGET_KEYS = new Set([
|
|
235
|
-
'company_duty_custom',
|
|
236
|
-
'company_duty_1',
|
|
237
|
-
'company_duty_2',
|
|
238
|
-
]);
|
|
104
|
+
export const hasCompanyDutyKey = (schemas: CardLayoutSchema[]): boolean => {
|
|
105
|
+
const TARGET_KEYS = new Set(["company_duty_custom", "company_duty_1", "company_duty_2"]);
|
|
239
106
|
|
|
240
107
|
const traverse = (elements: CardElement[]): boolean => {
|
|
241
|
-
return elements.some(el => {
|
|
108
|
+
return elements.some((el) => {
|
|
242
109
|
// 命中 key
|
|
243
110
|
if (el.key && TARGET_KEYS.has(el.key)) {
|
|
244
111
|
return true;
|
|
245
112
|
}
|
|
246
113
|
|
|
247
114
|
// 递归 layout-panel
|
|
248
|
-
if (el.type ===
|
|
115
|
+
if (el.type === "layout-panel" && el.children?.length) {
|
|
249
116
|
return traverse(el.children);
|
|
250
117
|
}
|
|
251
118
|
|
|
@@ -253,13 +120,12 @@ export const hasCompanyDutyKey = (
|
|
|
253
120
|
});
|
|
254
121
|
};
|
|
255
122
|
|
|
256
|
-
return schemas.some(schema => traverse(schema.children));
|
|
123
|
+
return schemas.some((schema) => traverse(schema.children));
|
|
257
124
|
};
|
|
258
125
|
|
|
259
|
-
|
|
260
126
|
Component({
|
|
261
127
|
options: {
|
|
262
|
-
styleIsolation:
|
|
128
|
+
styleIsolation: "apply-shared",
|
|
263
129
|
},
|
|
264
130
|
properties: {
|
|
265
131
|
layout: {
|
|
@@ -277,6 +143,7 @@ Component({
|
|
|
277
143
|
data: {
|
|
278
144
|
cards: [] as RenderCard[],
|
|
279
145
|
rootData: {} as Record<string, any>,
|
|
146
|
+
firstCard: [] as RenderCard[],
|
|
280
147
|
},
|
|
281
148
|
observers: {
|
|
282
149
|
layout() {
|
|
@@ -293,16 +160,29 @@ Component({
|
|
|
293
160
|
},
|
|
294
161
|
methods: {
|
|
295
162
|
rebuild() {
|
|
296
|
-
const data = normalizeMoreCompany(this.data.data)
|
|
297
|
-
const layoutInput = hasCompanyDutyKey(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;
|
|
298
167
|
const rootData = handleSpecialFields(data as any);
|
|
299
168
|
if (!layoutInput.length) {
|
|
300
169
|
this.setData({ cards: [], rootData });
|
|
301
170
|
return;
|
|
302
171
|
}
|
|
303
172
|
const normalizedLayouts = normalizeLayout(layoutInput);
|
|
304
|
-
const cards = buildCards(normalizedLayouts
|
|
305
|
-
this.setData({ cards, rootData });
|
|
173
|
+
const cards = buildCards(normalizedLayouts);
|
|
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
|
+
}
|
|
306
186
|
},
|
|
307
187
|
},
|
|
308
188
|
});
|
|
@@ -1,59 +1,38 @@
|
|
|
1
|
-
<
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
</
|
|
22
|
-
</
|
|
23
|
-
</
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
40
|
-
<
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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>
|