@tplc/business 0.7.51 → 0.7.53
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/CHANGELOG.md +48 -0
- package/components/lcb-area/lcb-area.vue +9 -21
- package/components/lcb-block/lcb-block.vue +8 -18
- package/components/lcb-block/types.ts +1 -1
- package/components/lcb-button/lcb-button.vue +13 -20
- package/components/lcb-calendar-search/lcb-calendar-search.vue +8 -1
- package/components/lcb-calendar-search/types.ts +4 -0
- package/components/lcb-product-item/components/ItemValue.vue +0 -20
- package/components/lcb-product-item/lcb-product-item.vue +337 -66
- package/components/lcb-product-item/types.ts +2 -0
- package/components/lcb-wrapper-list/lcb-wrapper-list.vue +61 -5
- package/components/lcb-wrapper-list/types.ts +18 -0
- package/package.json +1 -1
- package/types/components/lcb-block/types.d.ts +1 -1
- package/types/components/lcb-calendar-search/types.d.ts +4 -0
- package/types/components/lcb-list/lcb-list.vue.d.ts +1 -1
- package/types/components/lcb-product-item/lcb-product-item.vue.d.ts +9 -0
- package/types/components/lcb-product-item/types.d.ts +1 -0
- package/types/components/lcb-wrapper-list/lcb-wrapper-list.vue.d.ts +7 -0
- package/types/components/lcb-wrapper-list/types.d.ts +18 -0
- package/types/utils/componentHelpers.d.ts +28 -0
- package/types/utils/request.d.ts +1 -0
- package/utils/componentHelpers.ts +50 -0
- package/utils/request.ts +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,54 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.7.53](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/compare/v0.7.51...v0.7.53) (2026-01-07)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### 🚀 Chore | 构建/工程依赖/工具
|
|
9
|
+
|
|
10
|
+
* **release:** 0.7.52 ([ee19331](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/ee193313d84f6116acdc38630ecc010fa29fcc37))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### ✨ Features | 新功能
|
|
14
|
+
|
|
15
|
+
* **lcb-wrapper-list:** implement pagination support with z-paging and enhance dynamic style handling in lcb-block ([f345e4e](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/f345e4e0d84231db8e72fd55fefebdf01eac3bd6))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### 🐛 Bug Fixes | Bug 修复
|
|
19
|
+
|
|
20
|
+
* **lcb-area:** set default value for compareValues function to prevent potential errors ([4e5e48a](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/4e5e48a373ba00e491c5cd002da5792e57006aec))
|
|
21
|
+
* **lcb-area:** use nullish coalescing for default flex value in itemStylesCache ([421d71c](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/421d71c428f4a2f3db37169e9d5dd6ccdc1d6d07))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### ♻️ Code Refactoring | 代码重构
|
|
25
|
+
|
|
26
|
+
* **lcb-area, lcb-button:** optimize actionProps computation and streamline data source selection ([117ce0d](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/117ce0df62ee17b25a341c4dd3b51b90a0f78bd8))
|
|
27
|
+
* **lcb-wrapper-list:** streamline pagination implementation and enhance style handling in lcb-block ([9bb70e5](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/9bb70e58d28cb5575760d6fad0da81dec229beab))
|
|
28
|
+
|
|
29
|
+
### [0.7.52](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/compare/v0.7.48...v0.7.52) (2026-01-07)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### ♻️ Code Refactoring | 代码重构
|
|
33
|
+
|
|
34
|
+
* **lcb-area:** update comparison logic to use compareType prop for improved clarity ([525e606](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/525e606ba08288fc1f048a68208575214cf8f274))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### ✨ Features | 新功能
|
|
38
|
+
|
|
39
|
+
* **lcb-block:** add styleKey to dynamic options and update style handling for improved flexibility ([014469d](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/014469da25766f682cff0d63a932b82504f41d7d))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### 🚀 Chore | 构建/工程依赖/工具
|
|
43
|
+
|
|
44
|
+
* **release:** 0.7.49 ([173d24d](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/173d24dc7bcdc7c3112db232ac14c3509232cd89))
|
|
45
|
+
* **release:** 0.7.50 ([c6f5712](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/c6f5712c7bf9558a6336a148f15a4ba225d11104))
|
|
46
|
+
* **release:** 0.7.51 ([4acced8](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/4acced89cd89f3105b4797644ad7feefab55aa09))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
### 🐛 Bug Fixes | Bug 修复
|
|
50
|
+
|
|
51
|
+
* **lcb-area:** set default value for compareValues function to prevent potential errors ([4e5e48a](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/4e5e48a373ba00e491c5cd002da5792e57006aec))
|
|
52
|
+
|
|
5
53
|
### [0.7.51](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/compare/v0.7.50...v0.7.51) (2026-01-06)
|
|
6
54
|
|
|
7
55
|
|
|
@@ -31,7 +31,7 @@ import { LcbAreaProps } from './types'
|
|
|
31
31
|
import { getFlexStyle, transformValueUnit } from '@tplc/business/utils/transform'
|
|
32
32
|
import { get } from 'lodash-es'
|
|
33
33
|
import { dynamicRequest } from '../../utils/request'
|
|
34
|
-
import {
|
|
34
|
+
import { resolveActionProps, selectDynamicSource } from '../../utils/componentHelpers'
|
|
35
35
|
import useDynamicData from '../../hooks/useDynamicData'
|
|
36
36
|
defineOptions({
|
|
37
37
|
name: 'LcbArea',
|
|
@@ -96,7 +96,7 @@ const itemStylesCache = computed(() => {
|
|
|
96
96
|
return {
|
|
97
97
|
...commonItemStyle.value,
|
|
98
98
|
gridColumn: colSpan && isGrid ? `span ${colSpan} / span ${colSpan}` : undefined,
|
|
99
|
-
flex: isFlex ? flex
|
|
99
|
+
flex: isFlex ? (flex ?? 'auto') : undefined,
|
|
100
100
|
flexShrink: isFlex ? flexShrink : undefined,
|
|
101
101
|
width: flex ? '100%' : 'auto',
|
|
102
102
|
}
|
|
@@ -121,24 +121,12 @@ const getData = async () => {
|
|
|
121
121
|
|
|
122
122
|
/** 处理跳转链接中的动态参数 */
|
|
123
123
|
const actionProps = computed(() => {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (props.dynamicActionKey) {
|
|
131
|
-
return get(innerDynamicData.value, props.dynamicActionKey)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// 优化: 只在 jumpUrl 存在时才调用 getDynamicData
|
|
135
|
-
|
|
136
|
-
return {
|
|
137
|
-
...props.action,
|
|
138
|
-
jumpUrl: getDynamicData(jumpUrl, {
|
|
139
|
-
store: innerDynamicData.value,
|
|
140
|
-
}),
|
|
141
|
-
}
|
|
124
|
+
return resolveActionProps({
|
|
125
|
+
dynamicActionKey: props.dynamicActionKey,
|
|
126
|
+
action: props.action as any,
|
|
127
|
+
innerDynamicData: innerDynamicData.value,
|
|
128
|
+
templateStore: innerDynamicData.value,
|
|
129
|
+
})
|
|
142
130
|
})
|
|
143
131
|
|
|
144
132
|
// 优化: 移除 deep: true,只监听引用变化
|
|
@@ -176,7 +164,7 @@ const compareValues = (value = '', compareValue: string, compareType: string) =>
|
|
|
176
164
|
|
|
177
165
|
// 优化: 缓存数据源
|
|
178
166
|
const dependDataSource = computed(() => {
|
|
179
|
-
return props.keyFromUser
|
|
167
|
+
return selectDynamicSource(props.keyFromUser, userStore?.userInfo, innerDynamicData.value)
|
|
180
168
|
})
|
|
181
169
|
|
|
182
170
|
const showArea = computed(() => {
|
|
@@ -48,24 +48,14 @@ const innerBackgroundColor = computed(() => {
|
|
|
48
48
|
})
|
|
49
49
|
|
|
50
50
|
const getInnerStyle = computed(() => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (data) {
|
|
60
|
-
acc[styleKey] = data
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return acc
|
|
65
|
-
},
|
|
66
|
-
{} as Record<string, string>,
|
|
67
|
-
)
|
|
68
|
-
return innerStyle
|
|
51
|
+
if (props.dynamicStyleOptions?.dynamicKey) {
|
|
52
|
+
const innerStyle = get(
|
|
53
|
+
props.dynamicStyleOptions?.keyFrom === 'user' ? userStore?.userInfo : innerDynamicData.value,
|
|
54
|
+
props.dynamicStyleOptions?.dynamicKey,
|
|
55
|
+
)
|
|
56
|
+
return innerStyle
|
|
57
|
+
}
|
|
58
|
+
return {}
|
|
69
59
|
})
|
|
70
60
|
|
|
71
61
|
// 缓存 padding 计算结果,减少 transformValueUnit 调用次数
|
|
@@ -11,7 +11,11 @@
|
|
|
11
11
|
@avatar="onAvatar"
|
|
12
12
|
@click="handleClick"
|
|
13
13
|
:customStyle="actionPaddingStyle"
|
|
14
|
-
:renderMode="
|
|
14
|
+
:renderMode="
|
|
15
|
+
!actionProps?.jumpType && (mode === 'image' ? !enablePreview : true)
|
|
16
|
+
? 'noClick'
|
|
17
|
+
: 'button'
|
|
18
|
+
"
|
|
15
19
|
>
|
|
16
20
|
<view class="!flex items-center justify-center" :style="iconGapStyle">
|
|
17
21
|
<wd-icon
|
|
@@ -63,6 +67,7 @@ import { computed } from 'vue'
|
|
|
63
67
|
import useDynamicData from '../../hooks/useDynamicData'
|
|
64
68
|
import { getFlexStyle, transformValueUnit } from '../../utils/transform'
|
|
65
69
|
import { getDynamicData } from '../../utils/utils'
|
|
70
|
+
import { resolveActionProps, selectDynamicSource } from '../../utils/componentHelpers'
|
|
66
71
|
import { LcbButtonProps } from './types'
|
|
67
72
|
defineOptions({
|
|
68
73
|
name: 'LcbButton',
|
|
@@ -85,7 +90,7 @@ const { userStore, innerDynamicData } = useDynamicData()
|
|
|
85
90
|
|
|
86
91
|
// 优化: 缓存 store 数据源
|
|
87
92
|
const store = computed(() => {
|
|
88
|
-
return props.keyFromUser
|
|
93
|
+
return selectDynamicSource(props.keyFromUser, userStore?.userInfo, innerDynamicData.value)
|
|
89
94
|
})
|
|
90
95
|
|
|
91
96
|
const dynamicValue = computed(() => {
|
|
@@ -122,25 +127,13 @@ const innerValue = computed(() => {
|
|
|
122
127
|
})
|
|
123
128
|
})
|
|
124
129
|
|
|
125
|
-
/** 处理跳转链接中的动态参数 */
|
|
126
130
|
const actionProps = computed(() => {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const jumpUrl = props.action?.jumpUrl
|
|
134
|
-
if (!jumpUrl) {
|
|
135
|
-
return props.action
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
...props.action,
|
|
140
|
-
jumpUrl: getDynamicData(jumpUrl, {
|
|
141
|
-
store: store.value,
|
|
142
|
-
}),
|
|
143
|
-
}
|
|
131
|
+
return resolveActionProps({
|
|
132
|
+
dynamicActionKey: props.dynamicActionKey,
|
|
133
|
+
action: props.action as any,
|
|
134
|
+
innerDynamicData: innerDynamicData.value,
|
|
135
|
+
templateStore: store.value,
|
|
136
|
+
})
|
|
144
137
|
})
|
|
145
138
|
|
|
146
139
|
const onAvatar = (headImgUrl) => {
|
|
@@ -44,7 +44,14 @@
|
|
|
44
44
|
v-bind="inputLink"
|
|
45
45
|
custom-class="!w-full !truncate !pr-2"
|
|
46
46
|
:customStyle="{
|
|
47
|
-
|
|
47
|
+
fontSize: placeholderFontSize ? `${placeholderFontSize}rpx` : undefined,
|
|
48
|
+
fontWeight: placeholderFontWeight,
|
|
49
|
+
fontFamily: placeholderFontFamily,
|
|
50
|
+
color: placeholderColor
|
|
51
|
+
? placeholderColor
|
|
52
|
+
: form.keywords
|
|
53
|
+
? 'var(--content-color)'
|
|
54
|
+
: '#969696',
|
|
48
55
|
}"
|
|
49
56
|
:url-params="urlParams"
|
|
50
57
|
>
|
|
@@ -8,4 +8,8 @@ export interface LcbCalendarSearchProps extends LcbBlockProps {
|
|
|
8
8
|
icon?: string
|
|
9
9
|
mode?: 'link' | 'search'
|
|
10
10
|
inputLink?: LcbActionViewProps
|
|
11
|
+
placeholderColor?: string
|
|
12
|
+
placeholderFontSize?: number
|
|
13
|
+
placeholderFontWeight?: number
|
|
14
|
+
placeholderFontFamily?: string
|
|
11
15
|
}
|
|
@@ -146,26 +146,6 @@ const coverImgWidth = computed(() => {
|
|
|
146
146
|
mode="heightFix"
|
|
147
147
|
/>
|
|
148
148
|
</view>
|
|
149
|
-
<!-- area -->
|
|
150
|
-
<!-- && itemProps.areaOnImg -->
|
|
151
|
-
<view
|
|
152
|
-
v-if="
|
|
153
|
-
itemProps.showArea &&
|
|
154
|
-
itemAttrs.cityArea &&
|
|
155
|
-
itemProps.areaOnImg &&
|
|
156
|
-
!itemProps.imgBottomIcon
|
|
157
|
-
"
|
|
158
|
-
class="flex absolute bottom-0 left-0 z-1 gap-1 p-1 w-full box-border text-white text-3.5 items-center text-shadow-xl"
|
|
159
|
-
:style="{
|
|
160
|
-
color: itemProps.areaColor,
|
|
161
|
-
fontSize: `${itemProps.areaFontSize}rpx`,
|
|
162
|
-
}"
|
|
163
|
-
>
|
|
164
|
-
<wd-icon name="location"></wd-icon>
|
|
165
|
-
<view class="line-clamp-1">
|
|
166
|
-
{{ itemAttrs.cityArea }}
|
|
167
|
-
</view>
|
|
168
|
-
</view>
|
|
169
149
|
<slot></slot>
|
|
170
150
|
</view>
|
|
171
151
|
</block>
|
|
@@ -63,6 +63,9 @@ const props = withDefaults(defineProps<LcbProductItemProps>(), {
|
|
|
63
63
|
itemContentPl: 0,
|
|
64
64
|
itemGap: 10,
|
|
65
65
|
titleOnImg: false,
|
|
66
|
+
areaOnImg: false,
|
|
67
|
+
addressOnImg: false,
|
|
68
|
+
priceOnImg: false,
|
|
66
69
|
})
|
|
67
70
|
const attrs = useAttrs() as Record<string, any>
|
|
68
71
|
provide('lcb-product-item-props', props)
|
|
@@ -147,6 +150,48 @@ const titleOnImgTextStyle = computed(() => {
|
|
|
147
150
|
...(props.productNameStyle || {}),
|
|
148
151
|
}
|
|
149
152
|
})
|
|
153
|
+
|
|
154
|
+
const blockedByImgBottomIcon = computed(() => !!(props.imgBottomIcon && props.imgBottomIconVisible))
|
|
155
|
+
|
|
156
|
+
const titleOnImgVisible = computed(() => {
|
|
157
|
+
return (
|
|
158
|
+
!!props.titleOnImg &&
|
|
159
|
+
!!props.productNameVisible &&
|
|
160
|
+
!!props.productName &&
|
|
161
|
+
!blockedByImgBottomIcon.value
|
|
162
|
+
)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
const areaOnImgVisible = computed(() => {
|
|
166
|
+
return !!(props.areaOnImg && props.showArea && attrs.cityArea && !blockedByImgBottomIcon.value)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
const addressOnImgVisible = computed(() => {
|
|
170
|
+
return !!(
|
|
171
|
+
props.addressOnImg &&
|
|
172
|
+
props.addressIntroVisible &&
|
|
173
|
+
!!props.addressIntro &&
|
|
174
|
+
!blockedByImgBottomIcon.value
|
|
175
|
+
)
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
const priceOnImgVisible = computed(() => {
|
|
179
|
+
if (!props.priceOnImg || blockedByImgBottomIcon.value) return false
|
|
180
|
+
|
|
181
|
+
const hasScribePrice = props.scribePriceVisible && isNumber(props.scribePrice)
|
|
182
|
+
const hasPrice = props.priceVisible && isNumber(props.price)
|
|
183
|
+
const hasPriceTips = props.priceTipsVisible && !!props.priceTips
|
|
184
|
+
return !!(hasScribePrice || hasPrice || hasPriceTips)
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
const imgOverlayVisible = computed(() => {
|
|
188
|
+
return (
|
|
189
|
+
titleOnImgVisible.value ||
|
|
190
|
+
areaOnImgVisible.value ||
|
|
191
|
+
addressOnImgVisible.value ||
|
|
192
|
+
priceOnImgVisible.value
|
|
193
|
+
)
|
|
194
|
+
})
|
|
150
195
|
</script>
|
|
151
196
|
|
|
152
197
|
<template>
|
|
@@ -169,28 +214,84 @@ const titleOnImgTextStyle = computed(() => {
|
|
|
169
214
|
<template #default>
|
|
170
215
|
<slot name="coverImgSection" />
|
|
171
216
|
<view
|
|
172
|
-
v-if="
|
|
173
|
-
titleOnImg &&
|
|
174
|
-
productNameVisible &&
|
|
175
|
-
!!productName &&
|
|
176
|
-
!(imgBottomIcon && imgBottomIconVisible)
|
|
177
|
-
"
|
|
217
|
+
v-if="imgOverlayVisible"
|
|
178
218
|
class="absolute left-0 w-full z-1 p-1 box-border text-white text-shadow-xl bottom-0"
|
|
179
219
|
:style="titleOnImgMaskStyle"
|
|
180
220
|
>
|
|
181
|
-
<
|
|
221
|
+
<view class="flex flex-col gap-1 items-start">
|
|
222
|
+
<view v-if="titleOnImgVisible" class="w-full">
|
|
223
|
+
<slot name="productName" :value="productName">
|
|
224
|
+
<view
|
|
225
|
+
:class="[
|
|
226
|
+
productNameClass,
|
|
227
|
+
'inline text-[32rpx] font-bold',
|
|
228
|
+
`line-clamp-${titleLineClamp}`,
|
|
229
|
+
'whitespace-pre-wrap',
|
|
230
|
+
]"
|
|
231
|
+
:style="titleOnImgTextStyle"
|
|
232
|
+
>
|
|
233
|
+
{{ productName }}
|
|
234
|
+
</view>
|
|
235
|
+
</slot>
|
|
236
|
+
</view>
|
|
237
|
+
|
|
182
238
|
<view
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
:style="titleOnImgTextStyle"
|
|
239
|
+
v-if="areaOnImgVisible || addressOnImgVisible"
|
|
240
|
+
class="flex gap-1 items-center w-full"
|
|
241
|
+
:style="{
|
|
242
|
+
color: areaColor,
|
|
243
|
+
fontSize: `${areaFontSize}rpx`,
|
|
244
|
+
}"
|
|
190
245
|
>
|
|
191
|
-
|
|
246
|
+
<wd-icon name="location"></wd-icon>
|
|
247
|
+
<view class="line-clamp-1">
|
|
248
|
+
{{ areaOnImgVisible ? attrs.cityArea : addressIntro }}
|
|
249
|
+
</view>
|
|
192
250
|
</view>
|
|
193
|
-
|
|
251
|
+
|
|
252
|
+
<view v-if="priceOnImgVisible" class="flex flex-col gap-1 items-start leading-none">
|
|
253
|
+
<view class="flex gap-1 justify-start w-full flex-wrap">
|
|
254
|
+
<view
|
|
255
|
+
class="flex gap-[2rpx] items-end line-through"
|
|
256
|
+
v-if="scribePriceVisible && isNumber(scribePrice)"
|
|
257
|
+
>
|
|
258
|
+
<template
|
|
259
|
+
v-for="propName in ['scribePriceUnit', 'scribePrice', 'scribePriceSuffix']"
|
|
260
|
+
:key="propName"
|
|
261
|
+
>
|
|
262
|
+
<ItemValue :prop="propName" v-if="!!$slots?.[propName]">
|
|
263
|
+
<template #scribePrice="{ value }">
|
|
264
|
+
<slot name="scribePrice" :value="value" />
|
|
265
|
+
</template>
|
|
266
|
+
<template #scribePriceUnit="{ value }">
|
|
267
|
+
<slot name="scribePriceUnit" :value="value" />
|
|
268
|
+
</template>
|
|
269
|
+
<template #scribePriceSuffix="{ value }">
|
|
270
|
+
<slot name="scribePriceSuffix" :value="value" />
|
|
271
|
+
</template>
|
|
272
|
+
</ItemValue>
|
|
273
|
+
<ItemValue :prop="propName" v-else />
|
|
274
|
+
</template>
|
|
275
|
+
</view>
|
|
276
|
+
|
|
277
|
+
<view
|
|
278
|
+
class="flex gap-[4rpx] items-end justify-start"
|
|
279
|
+
v-if="priceVisible && isNumber(price)"
|
|
280
|
+
>
|
|
281
|
+
<ItemValue prop="pricePrefix" />
|
|
282
|
+
<ItemValue prop="priceUnit" />
|
|
283
|
+
<ItemValue prop="price" />
|
|
284
|
+
<ItemValue prop="priceSuffix" />
|
|
285
|
+
</view>
|
|
286
|
+
</view>
|
|
287
|
+
<ItemValue prop="priceTips" v-if="!!$slots?.priceTips">
|
|
288
|
+
<template #priceTips="{ value }">
|
|
289
|
+
<slot name="priceTips" :value="value" />
|
|
290
|
+
</template>
|
|
291
|
+
</ItemValue>
|
|
292
|
+
<ItemValue prop="priceTips" v-else />
|
|
293
|
+
</view>
|
|
294
|
+
</view>
|
|
194
295
|
</view>
|
|
195
296
|
</template>
|
|
196
297
|
<template #coverImg="{ value }">
|
|
@@ -205,28 +306,84 @@ const titleOnImgTextStyle = computed(() => {
|
|
|
205
306
|
<template #default>
|
|
206
307
|
<slot name="coverImgSection" />
|
|
207
308
|
<view
|
|
208
|
-
v-if="
|
|
209
|
-
titleOnImg &&
|
|
210
|
-
productNameVisible &&
|
|
211
|
-
!!productName &&
|
|
212
|
-
!(imgBottomIcon && imgBottomIconVisible)
|
|
213
|
-
"
|
|
309
|
+
v-if="imgOverlayVisible"
|
|
214
310
|
class="absolute left-0 w-full z-1 p-1 box-border text-white text-shadow-xl bottom-0"
|
|
215
311
|
:style="titleOnImgMaskStyle"
|
|
216
312
|
>
|
|
217
|
-
<
|
|
313
|
+
<view class="flex flex-col gap-1 items-start">
|
|
314
|
+
<view v-if="titleOnImgVisible" class="w-full">
|
|
315
|
+
<slot name="productName" :value="productName">
|
|
316
|
+
<view
|
|
317
|
+
:class="[
|
|
318
|
+
productNameClass,
|
|
319
|
+
'inline text-[32rpx] font-bold',
|
|
320
|
+
`line-clamp-${titleLineClamp}`,
|
|
321
|
+
'whitespace-pre-wrap',
|
|
322
|
+
]"
|
|
323
|
+
:style="titleOnImgTextStyle"
|
|
324
|
+
>
|
|
325
|
+
{{ productName }}
|
|
326
|
+
</view>
|
|
327
|
+
</slot>
|
|
328
|
+
</view>
|
|
329
|
+
|
|
218
330
|
<view
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
:style="titleOnImgTextStyle"
|
|
331
|
+
v-if="areaOnImgVisible || addressOnImgVisible"
|
|
332
|
+
class="flex gap-1 items-center w-full"
|
|
333
|
+
:style="{
|
|
334
|
+
color: areaColor,
|
|
335
|
+
fontSize: `${areaFontSize}rpx`,
|
|
336
|
+
}"
|
|
226
337
|
>
|
|
227
|
-
|
|
338
|
+
<wd-icon name="location"></wd-icon>
|
|
339
|
+
<view class="line-clamp-1">
|
|
340
|
+
{{ areaOnImgVisible ? attrs.cityArea : addressIntro }}
|
|
341
|
+
</view>
|
|
228
342
|
</view>
|
|
229
|
-
|
|
343
|
+
|
|
344
|
+
<view v-if="priceOnImgVisible" class="flex flex-col gap-1 items-start leading-none">
|
|
345
|
+
<view class="flex gap-1 justify-start w-full flex-wrap">
|
|
346
|
+
<view
|
|
347
|
+
class="flex gap-[2rpx] items-end line-through"
|
|
348
|
+
v-if="scribePriceVisible && isNumber(scribePrice)"
|
|
349
|
+
>
|
|
350
|
+
<template
|
|
351
|
+
v-for="propName in ['scribePriceUnit', 'scribePrice', 'scribePriceSuffix']"
|
|
352
|
+
:key="propName"
|
|
353
|
+
>
|
|
354
|
+
<ItemValue :prop="propName" v-if="!!$slots?.[propName]">
|
|
355
|
+
<template #scribePrice="{ value }">
|
|
356
|
+
<slot name="scribePrice" :value="value" />
|
|
357
|
+
</template>
|
|
358
|
+
<template #scribePriceUnit="{ value }">
|
|
359
|
+
<slot name="scribePriceUnit" :value="value" />
|
|
360
|
+
</template>
|
|
361
|
+
<template #scribePriceSuffix="{ value }">
|
|
362
|
+
<slot name="scribePriceSuffix" :value="value" />
|
|
363
|
+
</template>
|
|
364
|
+
</ItemValue>
|
|
365
|
+
<ItemValue :prop="propName" v-else />
|
|
366
|
+
</template>
|
|
367
|
+
</view>
|
|
368
|
+
|
|
369
|
+
<view
|
|
370
|
+
class="flex gap-[4rpx] items-end justify-start"
|
|
371
|
+
v-if="priceVisible && isNumber(price)"
|
|
372
|
+
>
|
|
373
|
+
<ItemValue prop="pricePrefix" />
|
|
374
|
+
<ItemValue prop="priceUnit" />
|
|
375
|
+
<ItemValue prop="price" />
|
|
376
|
+
<ItemValue prop="priceSuffix" />
|
|
377
|
+
</view>
|
|
378
|
+
</view>
|
|
379
|
+
<ItemValue prop="priceTips" v-if="!!$slots?.priceTips">
|
|
380
|
+
<template #priceTips="{ value }">
|
|
381
|
+
<slot name="priceTips" :value="value" />
|
|
382
|
+
</template>
|
|
383
|
+
</ItemValue>
|
|
384
|
+
<ItemValue prop="priceTips" v-else />
|
|
385
|
+
</view>
|
|
386
|
+
</view>
|
|
230
387
|
</view>
|
|
231
388
|
</template>
|
|
232
389
|
</ItemValue>
|
|
@@ -274,7 +431,7 @@ const titleOnImgTextStyle = computed(() => {
|
|
|
274
431
|
</ItemValue>
|
|
275
432
|
</view>
|
|
276
433
|
|
|
277
|
-
<ItemValue prop="addressIntro" v-if="addressIntroVisible">
|
|
434
|
+
<ItemValue prop="addressIntro" v-if="addressIntroVisible && !addressOnImg">
|
|
278
435
|
<!-- <template #addressIntro="{ value }"> -->
|
|
279
436
|
<!-- <slot name="addressIntro" :value="value" /> -->
|
|
280
437
|
<!-- </template> -->
|
|
@@ -311,6 +468,7 @@ const titleOnImgTextStyle = computed(() => {
|
|
|
311
468
|
</view>
|
|
312
469
|
<view class="flex-1"></view>
|
|
313
470
|
<view
|
|
471
|
+
v-if="!priceOnImg"
|
|
314
472
|
class="flex flex-col gap-1 items-end leading-none"
|
|
315
473
|
:style="{
|
|
316
474
|
marginTop: transformValueUnit(itemGap),
|
|
@@ -399,28 +557,84 @@ const titleOnImgTextStyle = computed(() => {
|
|
|
399
557
|
<template #default>
|
|
400
558
|
<slot name="coverImgSection" />
|
|
401
559
|
<view
|
|
402
|
-
v-if="
|
|
403
|
-
titleOnImg &&
|
|
404
|
-
productNameVisible &&
|
|
405
|
-
!!productName &&
|
|
406
|
-
!(imgBottomIcon && imgBottomIconVisible)
|
|
407
|
-
"
|
|
560
|
+
v-if="imgOverlayVisible"
|
|
408
561
|
class="absolute left-0 w-full z-1 p-1 box-border text-white text-shadow-xl bottom-0"
|
|
409
562
|
:style="titleOnImgMaskStyle"
|
|
410
563
|
>
|
|
411
|
-
<
|
|
564
|
+
<view class="flex flex-col gap-1 items-start">
|
|
565
|
+
<view v-if="titleOnImgVisible" class="w-full">
|
|
566
|
+
<slot name="productName" :value="productName">
|
|
567
|
+
<view
|
|
568
|
+
:class="[
|
|
569
|
+
productNameClass,
|
|
570
|
+
'inline text-[32rpx] font-bold',
|
|
571
|
+
`line-clamp-${titleLineClamp}`,
|
|
572
|
+
'whitespace-pre-wrap',
|
|
573
|
+
]"
|
|
574
|
+
:style="titleOnImgTextStyle"
|
|
575
|
+
>
|
|
576
|
+
{{ productName }}
|
|
577
|
+
</view>
|
|
578
|
+
</slot>
|
|
579
|
+
</view>
|
|
580
|
+
|
|
412
581
|
<view
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
:style="titleOnImgTextStyle"
|
|
582
|
+
v-if="areaOnImgVisible || addressOnImgVisible"
|
|
583
|
+
class="flex gap-1 items-center w-full"
|
|
584
|
+
:style="{
|
|
585
|
+
color: areaColor,
|
|
586
|
+
fontSize: `${areaFontSize}rpx`,
|
|
587
|
+
}"
|
|
420
588
|
>
|
|
421
|
-
|
|
589
|
+
<wd-icon name="location"></wd-icon>
|
|
590
|
+
<view class="line-clamp-1">
|
|
591
|
+
{{ areaOnImgVisible ? attrs.cityArea : addressIntro }}
|
|
592
|
+
</view>
|
|
593
|
+
</view>
|
|
594
|
+
|
|
595
|
+
<view v-if="priceOnImgVisible" class="flex flex-col gap-1 items-start leading-none">
|
|
596
|
+
<view class="flex gap-1 justify-start w-full flex-wrap">
|
|
597
|
+
<view
|
|
598
|
+
class="flex gap-[2rpx] items-end line-through"
|
|
599
|
+
v-if="scribePriceVisible && isNumber(scribePrice)"
|
|
600
|
+
>
|
|
601
|
+
<template
|
|
602
|
+
v-for="propName in ['scribePriceUnit', 'scribePrice', 'scribePriceSuffix']"
|
|
603
|
+
:key="propName"
|
|
604
|
+
>
|
|
605
|
+
<ItemValue :prop="propName" v-if="!!$slots?.[propName]">
|
|
606
|
+
<template #scribePrice="{ value }">
|
|
607
|
+
<slot name="scribePrice" :value="value" />
|
|
608
|
+
</template>
|
|
609
|
+
<template #scribePriceUnit="{ value }">
|
|
610
|
+
<slot name="scribePriceUnit" :value="value" />
|
|
611
|
+
</template>
|
|
612
|
+
<template #scribePriceSuffix="{ value }">
|
|
613
|
+
<slot name="scribePriceSuffix" :value="value" />
|
|
614
|
+
</template>
|
|
615
|
+
</ItemValue>
|
|
616
|
+
<ItemValue :prop="propName" v-else />
|
|
617
|
+
</template>
|
|
618
|
+
</view>
|
|
619
|
+
|
|
620
|
+
<view
|
|
621
|
+
class="flex gap-[4rpx] items-end justify-start"
|
|
622
|
+
v-if="priceVisible && isNumber(price)"
|
|
623
|
+
>
|
|
624
|
+
<ItemValue prop="pricePrefix" />
|
|
625
|
+
<ItemValue prop="priceUnit" />
|
|
626
|
+
<ItemValue prop="price" />
|
|
627
|
+
<ItemValue prop="priceSuffix" />
|
|
628
|
+
</view>
|
|
629
|
+
</view>
|
|
630
|
+
<ItemValue prop="priceTips" v-if="!!$slots?.priceTips">
|
|
631
|
+
<template #priceTips="{ value }">
|
|
632
|
+
<slot name="priceTips" :value="value" />
|
|
633
|
+
</template>
|
|
634
|
+
</ItemValue>
|
|
635
|
+
<ItemValue prop="priceTips" v-else />
|
|
422
636
|
</view>
|
|
423
|
-
</
|
|
637
|
+
</view>
|
|
424
638
|
</view>
|
|
425
639
|
</template>
|
|
426
640
|
<template #coverImg="{ value }">
|
|
@@ -431,28 +645,84 @@ const titleOnImgTextStyle = computed(() => {
|
|
|
431
645
|
<template #default>
|
|
432
646
|
<slot name="coverImgSection" />
|
|
433
647
|
<view
|
|
434
|
-
v-if="
|
|
435
|
-
titleOnImg &&
|
|
436
|
-
productNameVisible &&
|
|
437
|
-
!!productName &&
|
|
438
|
-
!(imgBottomIcon && imgBottomIconVisible)
|
|
439
|
-
"
|
|
648
|
+
v-if="imgOverlayVisible"
|
|
440
649
|
class="absolute left-0 w-full z-1 p-1 box-border text-white text-shadow-xl bottom-0"
|
|
441
650
|
:style="titleOnImgMaskStyle"
|
|
442
651
|
>
|
|
443
|
-
<
|
|
652
|
+
<view class="flex flex-col gap-1 items-start">
|
|
653
|
+
<view v-if="titleOnImgVisible" class="w-full">
|
|
654
|
+
<slot name="productName" :value="productName">
|
|
655
|
+
<view
|
|
656
|
+
:class="[
|
|
657
|
+
productNameClass,
|
|
658
|
+
'inline text-[32rpx] font-bold',
|
|
659
|
+
`line-clamp-${titleLineClamp}`,
|
|
660
|
+
'whitespace-pre-wrap',
|
|
661
|
+
]"
|
|
662
|
+
:style="titleOnImgTextStyle"
|
|
663
|
+
>
|
|
664
|
+
{{ productName }}
|
|
665
|
+
</view>
|
|
666
|
+
</slot>
|
|
667
|
+
</view>
|
|
668
|
+
|
|
444
669
|
<view
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
:style="titleOnImgTextStyle"
|
|
670
|
+
v-if="areaOnImgVisible || addressOnImgVisible"
|
|
671
|
+
class="flex gap-1 items-center w-full"
|
|
672
|
+
:style="{
|
|
673
|
+
color: areaColor,
|
|
674
|
+
fontSize: `${areaFontSize}rpx`,
|
|
675
|
+
}"
|
|
452
676
|
>
|
|
453
|
-
|
|
677
|
+
<wd-icon name="location"></wd-icon>
|
|
678
|
+
<view class="line-clamp-1">
|
|
679
|
+
{{ areaOnImgVisible ? attrs.cityArea : addressIntro }}
|
|
680
|
+
</view>
|
|
454
681
|
</view>
|
|
455
|
-
|
|
682
|
+
|
|
683
|
+
<view v-if="priceOnImgVisible" class="flex flex-col gap-1 items-start leading-none">
|
|
684
|
+
<view class="flex gap-1 justify-start w-full flex-wrap">
|
|
685
|
+
<view
|
|
686
|
+
class="flex gap-[2rpx] items-end line-through"
|
|
687
|
+
v-if="scribePriceVisible && isNumber(scribePrice)"
|
|
688
|
+
>
|
|
689
|
+
<template
|
|
690
|
+
v-for="propName in ['scribePriceUnit', 'scribePrice', 'scribePriceSuffix']"
|
|
691
|
+
:key="propName"
|
|
692
|
+
>
|
|
693
|
+
<ItemValue :prop="propName" v-if="!!$slots?.[propName]">
|
|
694
|
+
<template #scribePrice="{ value }">
|
|
695
|
+
<slot name="scribePrice" :value="value" />
|
|
696
|
+
</template>
|
|
697
|
+
<template #scribePriceUnit="{ value }">
|
|
698
|
+
<slot name="scribePriceUnit" :value="value" />
|
|
699
|
+
</template>
|
|
700
|
+
<template #scribePriceSuffix="{ value }">
|
|
701
|
+
<slot name="scribePriceSuffix" :value="value" />
|
|
702
|
+
</template>
|
|
703
|
+
</ItemValue>
|
|
704
|
+
<ItemValue :prop="propName" v-else />
|
|
705
|
+
</template>
|
|
706
|
+
</view>
|
|
707
|
+
|
|
708
|
+
<view
|
|
709
|
+
class="flex gap-[4rpx] items-end justify-start"
|
|
710
|
+
v-if="priceVisible && isNumber(price)"
|
|
711
|
+
>
|
|
712
|
+
<ItemValue prop="pricePrefix" />
|
|
713
|
+
<ItemValue prop="priceUnit" />
|
|
714
|
+
<ItemValue prop="price" />
|
|
715
|
+
<ItemValue prop="priceSuffix" />
|
|
716
|
+
</view>
|
|
717
|
+
</view>
|
|
718
|
+
<ItemValue prop="priceTips" v-if="!!$slots?.priceTips">
|
|
719
|
+
<template #priceTips="{ value }">
|
|
720
|
+
<slot name="priceTips" :value="value" />
|
|
721
|
+
</template>
|
|
722
|
+
</ItemValue>
|
|
723
|
+
<ItemValue prop="priceTips" v-else />
|
|
724
|
+
</view>
|
|
725
|
+
</view>
|
|
456
726
|
</view>
|
|
457
727
|
</template>
|
|
458
728
|
</ItemValue>
|
|
@@ -494,7 +764,7 @@ const titleOnImgTextStyle = computed(() => {
|
|
|
494
764
|
</ItemValue>
|
|
495
765
|
</view>
|
|
496
766
|
|
|
497
|
-
<ItemValue prop="addressIntro" v-if="addressIntroVisible">
|
|
767
|
+
<ItemValue prop="addressIntro" v-if="addressIntroVisible && !addressOnImg">
|
|
498
768
|
<!-- <template #addressIntro="{ value }">
|
|
499
769
|
<slot name="addressIntro" :value="value" />
|
|
500
770
|
</template> -->
|
|
@@ -529,6 +799,7 @@ const titleOnImgTextStyle = computed(() => {
|
|
|
529
799
|
</view>
|
|
530
800
|
<view class="flex-1"></view>
|
|
531
801
|
<view
|
|
802
|
+
v-if="!priceOnImg"
|
|
532
803
|
class="flex flex-col gap-1 items-end leading-none"
|
|
533
804
|
:style="{
|
|
534
805
|
marginTop: transformValueUnit(itemGap),
|
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<z-paging
|
|
3
|
+
ref="paging"
|
|
4
|
+
:auto="true"
|
|
5
|
+
v-model="renderList"
|
|
6
|
+
@query="queryList"
|
|
7
|
+
:fixed="false"
|
|
8
|
+
:default-page-size="props.pageProps?.pageLimit"
|
|
9
|
+
:use-page-scroll="props.pageProps?.pagingUsePageScroll"
|
|
10
|
+
:height="props.pageProps?.pagingUsePageScroll ? undefined : props.pageProps?.pagingHeight"
|
|
11
|
+
v-if="props.pageProps?.pagingEnabled"
|
|
12
|
+
>
|
|
13
|
+
<lcb-block v-bind="$props" :custom-style="listStyle">
|
|
14
|
+
<view
|
|
15
|
+
v-for="(item, index) in renderList"
|
|
16
|
+
:key="getItemKey(item, index)"
|
|
17
|
+
class="flex-shrink-0"
|
|
18
|
+
:style="itemStyle"
|
|
19
|
+
>
|
|
20
|
+
<slot :data="item" :list="list" />
|
|
21
|
+
</view>
|
|
22
|
+
</lcb-block>
|
|
23
|
+
</z-paging>
|
|
24
|
+
<lcb-block v-bind="$props" :custom-style="listStyle" v-else>
|
|
3
25
|
<view
|
|
4
26
|
v-for="(item, index) in renderList"
|
|
5
27
|
:key="getItemKey(item, index)"
|
|
@@ -13,7 +35,8 @@
|
|
|
13
35
|
|
|
14
36
|
<script setup lang="ts">
|
|
15
37
|
import { transformValueUnit } from '@tplc/business/utils/transform'
|
|
16
|
-
import { computed, watch, shallowRef } from 'vue'
|
|
38
|
+
import { computed, watch, shallowRef, ref } from 'vue'
|
|
39
|
+
import useZPaging from 'z-paging/components/z-paging/js/hooks/useZPaging'
|
|
17
40
|
import useDynamicData from '../../hooks/useDynamicData'
|
|
18
41
|
import { dynamicRequest } from '../../utils/request'
|
|
19
42
|
import { LcbWrapperListProps } from './types'
|
|
@@ -28,10 +51,19 @@ defineOptions({
|
|
|
28
51
|
const props = withDefaults(defineProps<LcbWrapperListProps>(), {
|
|
29
52
|
display: 'flex',
|
|
30
53
|
flexDirection: 'column',
|
|
54
|
+
pagingEnabled: false,
|
|
55
|
+
pageLimit: 10,
|
|
56
|
+
pagingUsePageScroll: true,
|
|
31
57
|
})
|
|
32
58
|
const { userStore, innerDynamicData } = useDynamicData()
|
|
33
59
|
// 使用 shallowRef 优化大数组的响应式性能
|
|
34
60
|
const renderList = shallowRef<unknown[]>([])
|
|
61
|
+
const paging = ref()
|
|
62
|
+
useZPaging(paging)
|
|
63
|
+
const pageSearch = shallowRef<{ limit: number; page: number }>({
|
|
64
|
+
limit: props.pageLimit,
|
|
65
|
+
page: 1,
|
|
66
|
+
})
|
|
35
67
|
|
|
36
68
|
// 优化:检查是否需要转换,避免不必要的遍历
|
|
37
69
|
const transformStringArrayToObjectArray = (data: unknown[]): unknown[] => {
|
|
@@ -47,10 +79,33 @@ const transformStringArrayToObjectArray = (data: unknown[]): unknown[] => {
|
|
|
47
79
|
})
|
|
48
80
|
}
|
|
49
81
|
|
|
82
|
+
const queryList = async (page: number, limit: number) => {
|
|
83
|
+
pageSearch.value = { page, limit }
|
|
84
|
+
const data = await dynamicRequest(props.dataSource, innerDynamicData.value, userStore?.userInfo, {
|
|
85
|
+
pageSearch: pageSearch.value,
|
|
86
|
+
})
|
|
87
|
+
paging.value?.complete?.(data)
|
|
88
|
+
}
|
|
89
|
+
|
|
50
90
|
watch(
|
|
51
|
-
() =>
|
|
91
|
+
() =>
|
|
92
|
+
[
|
|
93
|
+
props.dataSource,
|
|
94
|
+
innerDynamicData.value,
|
|
95
|
+
userStore?.userInfo,
|
|
96
|
+
props.pageProps?.pagingEnabled,
|
|
97
|
+
props.pageProps?.pageLimit,
|
|
98
|
+
] as const,
|
|
52
99
|
|
|
53
|
-
async ([dataSource, dynamicData, userInfo]) => {
|
|
100
|
+
async ([dataSource, dynamicData, userInfo, pagingEnabled, pageLimit = 10]) => {
|
|
101
|
+
if (pagingEnabled) {
|
|
102
|
+
pageSearch.value = {
|
|
103
|
+
limit: pageLimit,
|
|
104
|
+
page: 1,
|
|
105
|
+
}
|
|
106
|
+
paging.value?.reload?.()
|
|
107
|
+
return
|
|
108
|
+
}
|
|
54
109
|
// 防止重复请求
|
|
55
110
|
let data: unknown[] = []
|
|
56
111
|
const result = await dynamicRequest(dataSource, dynamicData, userInfo)
|
|
@@ -81,11 +136,12 @@ const itemStyle = computed(() => {
|
|
|
81
136
|
|
|
82
137
|
// 优化:减少对象创建,使用固定的样式对象
|
|
83
138
|
const listStyle = computed(() => {
|
|
139
|
+
const gap = transformValueUnit(props.gap)
|
|
84
140
|
return {
|
|
85
141
|
width: '100%',
|
|
86
142
|
display: props.display,
|
|
87
143
|
'flex-direction': props.flexDirection,
|
|
88
|
-
gap
|
|
144
|
+
gap,
|
|
89
145
|
'align-items': 'stretch',
|
|
90
146
|
'grid-template-columns': `repeat(${props.gridColumns}, minmax(0, 1fr))`,
|
|
91
147
|
'overflow-x': props.scrollX ? 'auto' : 'hidden',
|
|
@@ -11,4 +11,22 @@ export interface LcbWrapperListProps extends LcbBlockProps {
|
|
|
11
11
|
scrollX?: boolean
|
|
12
12
|
list?: LcbAreaProps[]
|
|
13
13
|
childrenAutoWidth?: boolean
|
|
14
|
+
pageProps: {
|
|
15
|
+
/**
|
|
16
|
+
* 开启下拉刷新+上拉加载(基于 z-paging)
|
|
17
|
+
*/
|
|
18
|
+
pagingEnabled?: boolean
|
|
19
|
+
/**
|
|
20
|
+
* 分页大小,对应 pageSearch.limit,默认 10
|
|
21
|
+
*/
|
|
22
|
+
pageLimit?: number
|
|
23
|
+
/**
|
|
24
|
+
* z-paging 是否使用页面滚动模式,默认 true
|
|
25
|
+
*/
|
|
26
|
+
pagingUsePageScroll?: boolean
|
|
27
|
+
/**
|
|
28
|
+
* 非页面滚动模式下的高度(pagingUsePageScroll=false 时生效)
|
|
29
|
+
*/
|
|
30
|
+
pagingHeight?: string
|
|
31
|
+
}
|
|
14
32
|
}
|
package/package.json
CHANGED
|
@@ -54,7 +54,7 @@ export interface LcbBlockProps {
|
|
|
54
54
|
| 'bottom-left'
|
|
55
55
|
| 'bottom-center'
|
|
56
56
|
| 'bottom-right'
|
|
57
|
-
dynamicStyleOptions?: DynamicOptions
|
|
57
|
+
dynamicStyleOptions?: DynamicOptions
|
|
58
58
|
dynamicBgImage?: string
|
|
59
59
|
}
|
|
60
60
|
export interface LcbBlockInnerProps extends LcbBlockProps {
|
|
@@ -6,4 +6,8 @@ export interface LcbCalendarSearchProps extends LcbBlockProps {
|
|
|
6
6
|
icon?: string
|
|
7
7
|
mode?: 'link' | 'search'
|
|
8
8
|
inputLink?: LcbActionViewProps
|
|
9
|
+
placeholderColor?: string
|
|
10
|
+
placeholderFontSize?: number
|
|
11
|
+
placeholderFontWeight?: number
|
|
12
|
+
placeholderFontFamily?: string
|
|
9
13
|
}
|
|
@@ -66,7 +66,7 @@ declare const __VLS_component: import('vue').DefineComponent<
|
|
|
66
66
|
| 'bottom-left'
|
|
67
67
|
| 'bottom-center'
|
|
68
68
|
| 'bottom-right'
|
|
69
|
-
dynamicStyleOptions: import('../../action').DynamicOptions
|
|
69
|
+
dynamicStyleOptions: import('../../action').DynamicOptions
|
|
70
70
|
dynamicBgImage: string
|
|
71
71
|
gap: number
|
|
72
72
|
imageWidth: number
|
|
@@ -120,6 +120,9 @@ declare const __VLS_component: import('vue').DefineComponent<
|
|
|
120
120
|
itemContentPl: number
|
|
121
121
|
itemGap: number
|
|
122
122
|
titleOnImg: boolean
|
|
123
|
+
areaOnImg: boolean
|
|
124
|
+
addressOnImg: boolean
|
|
125
|
+
priceOnImg: boolean
|
|
123
126
|
}
|
|
124
127
|
>,
|
|
125
128
|
{},
|
|
@@ -184,6 +187,9 @@ declare const __VLS_component: import('vue').DefineComponent<
|
|
|
184
187
|
itemContentPl: number
|
|
185
188
|
itemGap: number
|
|
186
189
|
titleOnImg: boolean
|
|
190
|
+
areaOnImg: boolean
|
|
191
|
+
addressOnImg: boolean
|
|
192
|
+
priceOnImg: boolean
|
|
187
193
|
}
|
|
188
194
|
>
|
|
189
195
|
>
|
|
@@ -204,8 +210,11 @@ declare const __VLS_component: import('vue').DefineComponent<
|
|
|
204
210
|
itemContentPl: number
|
|
205
211
|
priceUnit: any
|
|
206
212
|
scribePriceUnit: any
|
|
213
|
+
areaOnImg: boolean
|
|
207
214
|
tagOverflowWrap: boolean
|
|
208
215
|
tagType: import('@tplc/wot/components/wd-tag/types').TagType
|
|
216
|
+
addressOnImg: boolean
|
|
217
|
+
priceOnImg: boolean
|
|
209
218
|
tagPlain: boolean
|
|
210
219
|
tagMark: boolean
|
|
211
220
|
tagRound: boolean
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LcbWrapperListProps } from './types'
|
|
2
2
|
declare function __VLS_template(): {
|
|
3
3
|
default?(_: { data: unknown; list: import('../lcb-area/types').LcbAreaProps[] | undefined }): any
|
|
4
|
+
default?(_: { data: unknown; list: import('../lcb-area/types').LcbAreaProps[] | undefined }): any
|
|
4
5
|
}
|
|
5
6
|
declare const __VLS_component: import('vue').DefineComponent<
|
|
6
7
|
__VLS_WithDefaults<
|
|
@@ -8,6 +9,9 @@ declare const __VLS_component: import('vue').DefineComponent<
|
|
|
8
9
|
{
|
|
9
10
|
display: string
|
|
10
11
|
flexDirection: string
|
|
12
|
+
pagingEnabled: boolean
|
|
13
|
+
pageLimit: number
|
|
14
|
+
pagingUsePageScroll: boolean
|
|
11
15
|
}
|
|
12
16
|
>,
|
|
13
17
|
{},
|
|
@@ -26,6 +30,9 @@ declare const __VLS_component: import('vue').DefineComponent<
|
|
|
26
30
|
{
|
|
27
31
|
display: string
|
|
28
32
|
flexDirection: string
|
|
33
|
+
pagingEnabled: boolean
|
|
34
|
+
pageLimit: number
|
|
35
|
+
pagingUsePageScroll: boolean
|
|
29
36
|
}
|
|
30
37
|
>
|
|
31
38
|
>
|
|
@@ -11,4 +11,22 @@ export interface LcbWrapperListProps extends LcbBlockProps {
|
|
|
11
11
|
scrollX?: boolean
|
|
12
12
|
list?: LcbAreaProps[]
|
|
13
13
|
childrenAutoWidth?: boolean
|
|
14
|
+
pageProps: {
|
|
15
|
+
/**
|
|
16
|
+
* 开启下拉刷新+上拉加载(基于 z-paging)
|
|
17
|
+
*/
|
|
18
|
+
pagingEnabled?: boolean
|
|
19
|
+
/**
|
|
20
|
+
* 分页大小,对应 pageSearch.limit,默认 10
|
|
21
|
+
*/
|
|
22
|
+
pageLimit?: number
|
|
23
|
+
/**
|
|
24
|
+
* z-paging 是否使用页面滚动模式,默认 true
|
|
25
|
+
*/
|
|
26
|
+
pagingUsePageScroll?: boolean
|
|
27
|
+
/**
|
|
28
|
+
* 非页面滚动模式下的高度(pagingUsePageScroll=false 时生效)
|
|
29
|
+
*/
|
|
30
|
+
pagingHeight?: string
|
|
31
|
+
}
|
|
14
32
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
type AnyRecord = Record<string, any>
|
|
2
|
+
/**
|
|
3
|
+
* 根据 keyFromUser 选择动态数据源
|
|
4
|
+
* - true: userStore.userInfo
|
|
5
|
+
* - false: innerDynamicData
|
|
6
|
+
*/
|
|
7
|
+
export declare function selectDynamicSource(
|
|
8
|
+
keyFromUser: boolean | undefined,
|
|
9
|
+
userInfo: AnyRecord | undefined,
|
|
10
|
+
innerDynamicData: AnyRecord | undefined,
|
|
11
|
+
): AnyRecord | undefined
|
|
12
|
+
/**
|
|
13
|
+
* 统一处理 actionProps:
|
|
14
|
+
* - dynamicActionKey 优先:从 innerDynamicData 取整段 action 配置
|
|
15
|
+
* - 否则对 action.jumpUrl 做动态参数替换(${xxx})
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveActionProps({
|
|
18
|
+
dynamicActionKey,
|
|
19
|
+
action,
|
|
20
|
+
innerDynamicData,
|
|
21
|
+
templateStore,
|
|
22
|
+
}: {
|
|
23
|
+
dynamicActionKey?: string
|
|
24
|
+
action?: AnyRecord
|
|
25
|
+
innerDynamicData?: AnyRecord
|
|
26
|
+
templateStore?: AnyRecord
|
|
27
|
+
}): any
|
|
28
|
+
export {}
|
package/types/utils/request.d.ts
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { get } from 'lodash-es'
|
|
2
|
+
import { getDynamicData } from './utils'
|
|
3
|
+
|
|
4
|
+
type AnyRecord = Record<string, any>
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 根据 keyFromUser 选择动态数据源
|
|
8
|
+
* - true: userStore.userInfo
|
|
9
|
+
* - false: innerDynamicData
|
|
10
|
+
*/
|
|
11
|
+
export function selectDynamicSource(
|
|
12
|
+
keyFromUser: boolean | undefined,
|
|
13
|
+
userInfo: AnyRecord | undefined,
|
|
14
|
+
innerDynamicData: AnyRecord | undefined,
|
|
15
|
+
) {
|
|
16
|
+
return (keyFromUser ? userInfo : innerDynamicData) as AnyRecord | undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 统一处理 actionProps:
|
|
21
|
+
* - dynamicActionKey 优先:从 innerDynamicData 取整段 action 配置
|
|
22
|
+
* - 否则对 action.jumpUrl 做动态参数替换(${xxx})
|
|
23
|
+
*/
|
|
24
|
+
export function resolveActionProps({
|
|
25
|
+
dynamicActionKey,
|
|
26
|
+
action,
|
|
27
|
+
innerDynamicData,
|
|
28
|
+
templateStore,
|
|
29
|
+
}: {
|
|
30
|
+
dynamicActionKey?: string
|
|
31
|
+
action?: AnyRecord
|
|
32
|
+
innerDynamicData?: AnyRecord
|
|
33
|
+
templateStore?: AnyRecord
|
|
34
|
+
}) {
|
|
35
|
+
if (dynamicActionKey) {
|
|
36
|
+
return get(innerDynamicData, dynamicActionKey)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const jumpUrl = action?.jumpUrl
|
|
40
|
+
if (!jumpUrl) {
|
|
41
|
+
return action
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
...action,
|
|
46
|
+
jumpUrl: getDynamicData(jumpUrl, {
|
|
47
|
+
store: templateStore,
|
|
48
|
+
}),
|
|
49
|
+
}
|
|
50
|
+
}
|
package/utils/request.ts
CHANGED
|
@@ -5,12 +5,17 @@ export const dynamicRequest = async (
|
|
|
5
5
|
dataSource?: DataSource,
|
|
6
6
|
pageInfo?: Record<string, any>,
|
|
7
7
|
userInfo?: Record<string, any>,
|
|
8
|
+
extraParams?: Record<string, any>,
|
|
8
9
|
) => {
|
|
9
10
|
if (dataSource?.source === 'remote') {
|
|
10
11
|
if (dataSource.requestInfo?.requestUrl) {
|
|
12
|
+
const baseParams = JSON.parse(dataSource.requestInfo.requestParams || '{}')
|
|
11
13
|
const response = await uni.$lcb.http.post(
|
|
12
14
|
dataSource.requestInfo.requestUrl,
|
|
13
|
-
|
|
15
|
+
{
|
|
16
|
+
...baseParams,
|
|
17
|
+
...(extraParams || {}),
|
|
18
|
+
},
|
|
14
19
|
)
|
|
15
20
|
/** 如果依赖key存在,则取依赖key的值 */
|
|
16
21
|
return response[dataSource?.dependKey || 'data'] as unknown
|