@tplc/business 0.7.71 → 0.7.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/components/lcb-action-view/components/MemberRolePopup/api.ts +22 -0
  3. package/components/lcb-action-view/components/MemberRolePopup/index.vue +174 -0
  4. package/components/lcb-action-view/components/PayPopup/index.vue +1 -1
  5. package/components/lcb-action-view/lcb-action-view.vue +19 -1
  6. package/components/lcb-action-view/types.ts +4 -1
  7. package/components/lcb-calendar-filter/components/CalendarItem/index.vue +8 -10
  8. package/components/lcb-calendar-filter/lcb-calendar-filter.vue +2 -3
  9. package/components/lcb-list/types.ts +1 -0
  10. package/components/lcb-map/lcb-map.vue +6 -2
  11. package/components/lcb-product/lcb-product.vue +76 -38
  12. package/components/lcb-product/types.ts +2 -0
  13. package/components/lcb-product-item/components/ItemValue.vue +6 -6
  14. package/components/lcb-product-item/types.ts +1 -0
  15. package/hooks/usePay.ts +8 -5
  16. package/package.json +1 -1
  17. package/types/components/lcb-action-view/components/MemberRolePopup/api.d.ts +22 -0
  18. package/types/components/lcb-action-view/components/MemberRolePopup/index.vue.d.ts +34 -0
  19. package/types/components/lcb-action-view/types.d.ts +4 -0
  20. package/types/components/lcb-calendar-filter/components/CalendarItem/index.vue.d.ts +1 -1
  21. package/types/components/lcb-list/lcb-list.vue.d.ts +1 -0
  22. package/types/components/lcb-list/types.d.ts +1 -0
  23. package/types/components/lcb-map/lcb-map.vue.d.ts +3 -0
  24. package/types/components/lcb-product/lcb-product.vue.d.ts +3 -0
  25. package/types/components/lcb-product/types.d.ts +2 -0
  26. package/types/components/lcb-product-item/types.d.ts +1 -0
  27. package/types/components/lcb-search/lcb-search.vue.d.ts +2 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,46 @@
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.73](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/compare/v0.7.72...v0.7.73) (2026-01-17)
6
+
7
+
8
+ ### 🐛 Bug Fixes | Bug 修复
9
+
10
+ * **lcb-action-view:** rename memberRole to userLevelRole in jumpTypeMap for clarity ([9d52eaf](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/9d52eaf956d8a7e9d931d1f6ceb256ed0cf3ce4e))
11
+
12
+
13
+ ### ✨ Features | 新功能
14
+
15
+ * **lcb-action-view:** add MemberRolePopup component and update jump type handling for member role ([82e094a](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/82e094a20e121ce7b960d94a46a80e2a77722df7))
16
+ * **lcb-product:** add support for configurable row count in horizontal layout and implement row-based rendering ([d6d773d](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/d6d773da60a5a65d2dba4e47aed5969e6b22399b))
17
+
18
+
19
+ ### ♻️ Code Refactoring | 代码重构
20
+
21
+ * **lcb-calendar-filter:** simplify CalendarItem component and update styles for better consistency ([b63b489](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/b63b4893313cba648c1f2b62618e2ccb06e567af))
22
+
23
+ ### [0.7.72](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/compare/v0.7.69...v0.7.72) (2026-01-17)
24
+
25
+
26
+ ### ♻️ Code Refactoring | 代码重构
27
+
28
+ * **lcb-order-payment:** simplify openInsteadPopup function and improve item handling ([5fdd2b6](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/5fdd2b6d6339e9c5fa5cd4affa06eb9ed1908443))
29
+ * **types:** remove unused type definitions and clean up component type files for better maintainability ([923135e](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/923135ebed7bcbee56deb891cdbc42206cb40b2a))
30
+
31
+
32
+ ### 🚀 Chore | 构建/工程依赖/工具
33
+
34
+ * **release:** 0.7.70 ([993f445](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/993f4459a619742ee76b4774d7a565934fc2153f))
35
+ * **release:** 0.7.71 ([5b32edb](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/5b32edbe244e09f8de16e6d8ea40d1b174e1f442))
36
+ * Remove numerous TypeScript declaration files and update the `lcb-order-payment` component. ([c4860c8](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/c4860c866b272f26b5da30e0b5688bb7fae9dd57))
37
+
38
+
39
+ ### ✨ Features | 新功能
40
+
41
+ * Add multiple new LCB component demo pages, update routing and types, and enhance the LCB search demo with new attributes. ([dae3560](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/dae3560de985f84e888e5ac18ba0960941e1aa7c))
42
+ * **lcb-action-view:** add language selection feature to action view component ([42402c4](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/42402c41de1bba1b26e37155cf462f27bc4a0528))
43
+ * Update PayPopup z-index, enhance LcbListProps with tagPosition, and improve lcb-map layout and loading handling ([6b04414](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/6b044148a01f929804259298c3206849121dfa71))
44
+
5
45
  ### [0.7.71](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/compare/v0.7.70...v0.7.71) (2026-01-15)
6
46
 
7
47
 
@@ -0,0 +1,22 @@
1
+ /** 会员角色 */
2
+ export interface UserVipRole {
3
+ userLevelRoleId: string
4
+ levelRoleName: string
5
+ levelRoleNameEn: string
6
+ levelRoleImg: string
7
+ content: string
8
+ addition?: string
9
+ additionConfig?: string
10
+ subTitle?: string
11
+ title?: string
12
+ levelRoleType?: number
13
+ levelRoleTypeName?: string
14
+ }
15
+
16
+ /** 获取会员角色列表 */
17
+ export const getUserVipRole = () =>
18
+ uni.$lcb.http.post<UserVipRole[]>('/userLevelRole/list', {}, true)
19
+
20
+ /** 选择会员角色 */
21
+ export const userPointChooseRole = (params: { userLevelRoleId: string }) =>
22
+ uni.$lcb.http.post('/userLevelRole/chooseRole', params, true)
@@ -0,0 +1,174 @@
1
+ <template>
2
+ <wd-popup
3
+ v-model="show"
4
+ position="center"
5
+ :close-on-click-modal="false"
6
+ custom-style="background: transparent;"
7
+ >
8
+ <view class="member-role-box text-white text-center w-full relative">
9
+ <!-- 关闭按钮 -->
10
+ <view class="absolute top-20rpx right-20rpx z-10 w-60rpx h-60rpx" @click="close">
11
+ <wd-icon name="close" size="40rpx" color="#fff" />
12
+ </view>
13
+
14
+ <!-- 标题 -->
15
+ <view class="text-40rpx font-bold mb-12rpx">选择角色</view>
16
+ <view class="text-24rpx mb-50rpx">左右滑动选择角色</view>
17
+
18
+ <!-- 角色轮播 -->
19
+ <view class="swiper-box relative h-500rpx mb-80rpx">
20
+ <swiper
21
+ :current="currentIdx"
22
+ class="h-full"
23
+ @change="onChange"
24
+ :previous-margin="`200rpx`"
25
+ :next-margin="`200rpx`"
26
+ >
27
+ <swiper-item v-for="(item, idx) in roleList" :key="item.userLevelRoleId" class="w-300rpx">
28
+ <view class="relative h-full flex items-end justify-center w-full">
29
+ <wd-img
30
+ :src="item.levelRoleImg"
31
+ width="500rpx"
32
+ height="500rpx"
33
+ mode="aspectFit"
34
+ :customClass="`transition-all ${idx === currentIdx ? 'opacity-100 scale-100' : 'opacity-40 scale-70'}`"
35
+ />
36
+ </view>
37
+ </swiper-item>
38
+ </swiper>
39
+ </view>
40
+
41
+ <!-- 角色信息 -->
42
+ <view v-if="currentRole" class="px-40rpx">
43
+ <view class="text-40rpx font-bold mb-20rpx">{{ currentRole.levelRoleName }}</view>
44
+ <view
45
+ class="pager flex items-center justify-center rounded-full mx-auto mb-16rpx w-100rpx h-40rpx bg-white bg-opacity-20"
46
+ >
47
+ <text class="text-24rpx">{{ currentIdx + 1 }}/{{ roleList.length }}</text>
48
+ </view>
49
+ <view class="text-24rpx mb-20rpx">{{ currentRole.levelRoleNameEn }}</view>
50
+ <text class="text-24rpx text-center leading-24rpx whitespace-pre-line">
51
+ {{ currentRole.content }}
52
+ </text>
53
+
54
+ <!-- 确定按钮 -->
55
+ <wd-button
56
+ @click="showConfirm = true"
57
+ custom-class="!block !w-45 mt-4 !mx-auto"
58
+ type="info"
59
+ >
60
+ 确定选择该角色
61
+ </wd-button>
62
+ </view>
63
+ </view>
64
+
65
+ <!-- 确认弹窗 -->
66
+ <wd-popup
67
+ v-model="showConfirm"
68
+ position="center"
69
+ :close-on-click-modal="false"
70
+ custom-class="!bg-transparent"
71
+ >
72
+ <view class="confirm-popup bg-white rounded-24rpx pb-30rpx w-550rpx">
73
+ <view class="pt-4 text-center text-36rpx font-bold mb-4">会员确认</view>
74
+ <view class="text-3.5 text-#333 px-60rpx text-center mb-4">
75
+ 是否确认选择该会员角色?一旦确认,无法更改。
76
+ </view>
77
+ <view class="flex px-2 gap-3 box-border justify-center">
78
+ <wd-button @click="showConfirm = false" type="info">再看看</wd-button>
79
+ <wd-button @click="confirmRole" type="primary">确认</wd-button>
80
+ </view>
81
+ </view>
82
+ </wd-popup>
83
+ </wd-popup>
84
+ </template>
85
+
86
+ <script lang="ts" setup>
87
+ import { getUserVipRole, userPointChooseRole, type UserVipRole } from './api'
88
+ import { ref, computed, watch } from 'vue'
89
+
90
+ defineOptions({
91
+ name: 'MemberRolePopup',
92
+ })
93
+
94
+ const show = defineModel<boolean>('show', { required: true })
95
+
96
+ const currentIdx = ref(0)
97
+ const showConfirm = ref(false)
98
+ const roleList = ref<UserVipRole[]>([])
99
+ const loading = ref(false)
100
+
101
+ // 当前选中的角色
102
+ const currentRole = computed(() => roleList.value[currentIdx.value])
103
+
104
+ // 获取角色列表
105
+ const fetchRoleList = async () => {
106
+ try {
107
+ loading.value = true
108
+ const { data } = await getUserVipRole()
109
+ roleList.value = data || []
110
+ } catch (error) {
111
+ console.error('获取角色列表失败:', error)
112
+ uni.showToast({
113
+ title: '获取角色列表失败',
114
+ icon: 'none',
115
+ })
116
+ } finally {
117
+ loading.value = false
118
+ }
119
+ }
120
+
121
+ // Swiper 改变
122
+ const onChange = (e: any) => {
123
+ currentIdx.value = e.detail.current
124
+ }
125
+
126
+ // 确认选择角色
127
+ const confirmRole = async () => {
128
+ if (!currentRole.value) return
129
+
130
+ try {
131
+ loading.value = true
132
+ await userPointChooseRole({ userLevelRoleId: currentRole.value.userLevelRoleId })
133
+ uni.showToast({
134
+ title: '选择成功',
135
+ icon: 'success',
136
+ })
137
+ showConfirm.value = false
138
+ show.value = false
139
+ } catch (error) {
140
+ console.error('选择角色失败:', error)
141
+ uni.showToast({
142
+ title: '选择角色失败',
143
+ icon: 'none',
144
+ })
145
+ } finally {
146
+ loading.value = false
147
+ }
148
+ }
149
+
150
+ // 关闭弹窗
151
+ const close = () => {
152
+ show.value = false
153
+ }
154
+
155
+ // 监听弹窗打开,获取角色列表
156
+ watch(show, (newVal) => {
157
+ if (newVal && roleList.value.length === 0) {
158
+ fetchRoleList()
159
+ }
160
+ })
161
+ </script>
162
+
163
+ <style lang="scss" scoped>
164
+ .member-role-box {
165
+ width: 100vw;
166
+ min-height: 80vh;
167
+ }
168
+
169
+ .swiper-box {
170
+ :deep(.swiper) {
171
+ height: 100%;
172
+ }
173
+ }
174
+ </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <wd-popup v-model="show" :z-index="1000" custom-class="!rounded-20rpx" closable root-portal>
2
+ <wd-popup v-model="show" :z-index="2" custom-class="!rounded-20rpx" closable root-portal>
3
3
  <view
4
4
  class="popup-view"
5
5
  :style="{
@@ -78,6 +78,7 @@
78
78
  v-if="['145'].includes(getJumpType(jumpType)) && showCustomPopup"
79
79
  :jumpUrl="jumpUrl"
80
80
  />
81
+ <MemberRolePopup v-model:show="showMemberRole" v-if="showMemberRole" />
81
82
  </view>
82
83
  </template>
83
84
 
@@ -88,10 +89,11 @@ import { uploadFile } from '../../hooks/useUpload'
88
89
  import { getFinalUrl, onPageScrollSelector, getExposed, getCurrentPage } from '../../utils/utils'
89
90
  import SharePopup from '../../components/lcb-nav/SharePopup/index.vue'
90
91
  import CustomPopup from './components/CustomPopup/index.vue'
91
- import { useTranslate } from '@tplc/wot'
92
+ import { Locale, useTranslate } from '@tplc/wot'
92
93
  import { PAGE_PROVIDE_KEY, USER_BASIC_INFO } from '../../constants'
93
94
  import { getTemplateMessageList, TemplateMessage } from '../../api/user'
94
95
  import PayPopup from './components/PayPopup/index.vue'
96
+ import MemberRolePopup from './components/MemberRolePopup/index.vue'
95
97
  const { translate } = useTranslate()
96
98
  defineOptions({
97
99
  name: 'LcbActionView',
@@ -107,6 +109,7 @@ const basicInfo = inject(USER_BASIC_INFO, {}) as unknown as Ref<Record<string, a
107
109
  const pageInfo = inject(PAGE_PROVIDE_KEY) as unknown as Ref<Record<string, any>>
108
110
  const showPoster = ref(false)
109
111
  const showPay = ref(false)
112
+ const showMemberRole = ref(false)
110
113
  const emits = defineEmits<{
111
114
  (e: 'phone', value: { detail: { errMsg: string; encryptedData: string; iv: string } }): void
112
115
  (e: 'avatar', value: string): void
@@ -356,6 +359,21 @@ const onActionClick = async () => {
356
359
  fail: () => uni.navigateBack({}),
357
360
  })
358
361
  break
362
+ case '147':
363
+ uni.showActionSheet({
364
+ itemList: ['中文', '英文'],
365
+ success: (res) => {
366
+ if (res.tapIndex === 0) {
367
+ Locale.use('zh-CN')
368
+ } else {
369
+ Locale.use('en-US')
370
+ }
371
+ },
372
+ })
373
+ break
374
+ case '148':
375
+ showMemberRole.value = true
376
+ break
359
377
  default:
360
378
  emits('click', props)
361
379
  break
@@ -61,7 +61,8 @@ export type LcbActionViewProps = {
61
61
  | 104
62
62
  | 241
63
63
  | 143
64
-
64
+ | 147
65
+ | 148
65
66
  /** 小程序appid */
66
67
  jumpAppid?: string
67
68
 
@@ -140,4 +141,6 @@ export const jumpTypeMap = {
140
141
  'mixture-pay': 144,
141
142
  customPopup: 145,
142
143
  arScan: 146,
144
+ translate: 147,
145
+ userLevelRole: 148,
143
146
  }
@@ -1,19 +1,18 @@
1
1
  <template>
2
2
  <view
3
- class="gap-0.25 flex flex-col p-2 justify-center border-solid border-1 border-#eeeeee rounded-1 relative"
3
+ class="gap-0.25 flex flex-col p-2 justify-center border-solid border-1 border-[var(--wot-color-theme)] rounded-1 relative"
4
4
  @click="date?.status !== 0 ? (currentDate = date?.date) : undefined"
5
5
  :class="{
6
- 'bg-[var(--theme-bg-color)] text-primary !border-[var(--wot-color-theme)]':
7
- currentDate === date?.date,
6
+ 'bg-[var(--wot-color-theme)] text-white': currentDate === date?.date,
8
7
  'opacity-50': date?.status === 0,
9
- [customClass]: true,
8
+ [customClass ?? '']: true,
10
9
  }"
11
10
  >
12
11
  <template v-if="date">
13
- <text class="whitespace-nowrap">
14
- {{ date.topTextOutside }} {{ dayjs(date.date).format('MM-DD') }}
15
- </text>
16
- <view class="text-[var(--font1-color)]">{{ date.buttomText }}</view>
12
+ <view class="whitespace-nowrap">
13
+ {{ date.topTextOutside }}
14
+ </view>
15
+ <view class="text-[var(--font1-color)]" v-if="date.buttomText">{{ date.buttomText }}</view>
17
16
  <view v-if="date.floorText" class="text-[var(--font2-color)]">
18
17
  {{ date.floorText }}
19
18
  </view>
@@ -30,13 +29,12 @@
30
29
  </view>
31
30
  </template>
32
31
  <script setup lang="ts">
33
- import dayjs from 'dayjs/esm'
34
32
  import { HolidayInfo } from '../../types'
35
33
 
36
34
  defineProps<{
37
35
  date?: HolidayInfo
38
36
  showAll?: boolean
39
- customClass: string
37
+ customClass?: string
40
38
  }>()
41
39
 
42
40
  const currentDate = defineModel<string | undefined>()
@@ -2,7 +2,7 @@
2
2
  <lcb-block v-bind="$props">
3
3
  <view class="relative flex">
4
4
  <!-- 左侧固定的"全部"选项 -->
5
- <CalendarItem showAll v-model="currentDate" custom-class="mt-3" />
5
+ <CalendarItem showAll v-model="currentDate" />
6
6
 
7
7
  <scroll-view
8
8
  scroll-x
@@ -17,13 +17,12 @@
17
17
  :key="date.date"
18
18
  :id="`id_${date.date}`"
19
19
  :date="date"
20
- custom-class="mt-3 !justify-start"
21
20
  v-model="currentDate"
22
21
  />
23
22
  </view>
24
23
  </scroll-view>
25
24
  <view
26
- class="flex flex-col justify-center items-center px-2 py-1 w-8 text-primary mt-3"
25
+ class="rounded-1 flex flex-col justify-center items-center ml-2 px-1 py-1 w-8 text-primary !border-[var(--wot-color-theme)] border-solid border-1"
27
26
  @click="onMore"
28
27
  v-if="showMore"
29
28
  >
@@ -44,6 +44,7 @@ export interface LcbListProps extends LcbBlockProps {
44
44
  }[]
45
45
  mapTagMode?: 'single' | 'multiple'
46
46
  mapConfigParams?: string
47
+ tagPosition?: 'left' | 'right'
47
48
  }
48
49
  export interface Option {
49
50
  label: string
@@ -20,7 +20,10 @@
20
20
  class="w-36rpx h-66rpx absolute left-0 top-0 m-auto bottom-0 right-0"
21
21
  />
22
22
  <!-- 重新定位到当前位置 -->
23
- <view class="absolute top-3 right-2 flex flex-col gap-2">
23
+ <view
24
+ class="absolute top-3 flex flex-col gap-2"
25
+ :class="tagPosition === 'left' ? 'left-2 ' : 'right-2'"
26
+ >
24
27
  <view
25
28
  v-for="item in mapTags"
26
29
  :key="item.value"
@@ -122,6 +125,7 @@ const { userLatLon, getLocation } = useLocation()
122
125
  const isLoading = ref(false)
123
126
  const props = withDefaults(defineProps<LcbListProps & LcbListInfo>(), {
124
127
  mapTagMode: 'multiple',
128
+ tagPosition: 'right',
125
129
  })
126
130
  const themeColor = inject('theme-color', '#3875FF')
127
131
  const callout: MapMarker['callout'] = {
@@ -204,7 +208,7 @@ const fetchMapData = async (regionInfo: {
204
208
  mapScale: currentScale.value,
205
209
  mapCornerLongitude: regionInfo.southwest?.longitude,
206
210
  mapCornerLatitude: regionInfo.southwest?.latitude,
207
- productTypeList: selectedTag.value.length ? selectedTag.value : undefined,
211
+ mapSearchParamList: selectedTag.value.length ? selectedTag.value : undefined,
208
212
  },
209
213
  true,
210
214
  )) as {
@@ -31,6 +31,7 @@ const props = withDefaults(defineProps<LcbProductProps>(), {
31
31
  paddingVertical: 24,
32
32
  sourceMode: 1,
33
33
  gap: 16,
34
+ rows: 1,
34
35
  })
35
36
  const { form } = useSyncForm({ dynamicScope: props.dynamicScope })
36
37
  const loading = ref(false)
@@ -178,6 +179,27 @@ const blockProps = computed(() => {
178
179
  reset,
179
180
  ]
180
181
  })
182
+
183
+ // 计算 horizontal 模式下的分行数据
184
+ const horizontalRows = computed(() => {
185
+ if (props.listType !== 'horizontal' || !renderList.value.length) {
186
+ return []
187
+ }
188
+
189
+ const rows: any[][] = []
190
+ const totalItems = renderList.value.length
191
+ const itemsPerRow = Math.ceil(totalItems / props.rows)
192
+
193
+ for (let i = 0; i < props.rows; i++) {
194
+ const start = i * itemsPerRow
195
+ const end = Math.min(start + itemsPerRow, totalItems)
196
+ if (start < totalItems) {
197
+ rows.push(renderList.value.slice(start, end))
198
+ }
199
+ }
200
+
201
+ return rows
202
+ })
181
203
  </script>
182
204
 
183
205
  <template>
@@ -190,7 +212,7 @@ const blockProps = computed(() => {
190
212
  shadowSize: blockShadowSize,
191
213
  blurSize: blockBlurSize,
192
214
  }"
193
- :custom-class="`${listType == 'horizontal' ? '!gap-0 h-fit overflow-x-auto whitespace-nowrap flex items-stretch w-full' : ''}`"
215
+ :custom-class="`${listType == 'horizontal' ? '!gap-0 h-fit w-full' : ''}`"
194
216
  >
195
217
  <!-- 单列 -->
196
218
  <view
@@ -391,46 +413,62 @@ const blockProps = computed(() => {
391
413
  </view>
392
414
  <!-- 单列滚动 -->
393
415
  <template v-else-if="listType == 'horizontal'">
394
- <lcb-action-view
395
- v-for="(item, index) in renderList"
396
- :key="`${item?.productId}:${index}`"
397
- custom-class="flex-shrink-0 w-fit !h-auto"
398
- v-bind="item.link"
399
- render-mode="view"
400
- >
416
+ <view class="overflow-x-auto w-full" style="padding: 12rpx 0">
401
417
  <view
402
- :style="{
403
- width: `${itemWidth}rpx`,
404
- marginLeft: index === 0 ? 0 : `${gap}rpx`,
405
- height: '100%',
406
- }"
418
+ class="flex flex-col"
419
+ :style="{ gap: rows > 1 ? `${gap}rpx` : undefined, margin: '0 -12rpx' }"
407
420
  >
408
- <slot name="item" :item="item">
409
- <lcb-absolute-config-layout
410
- v-if="renderItemAbsoluteConfigLayout"
411
- :blocks="renderItemAbsoluteConfigLayout?.blocks"
412
- :canvas="renderItemAbsoluteConfigLayout?.canvas"
413
- :dataset="{
414
- ...(renderItemAbsoluteConfigLayout?.dataset ?? {}),
415
- ...item,
416
- }"
417
- />
418
- <lcb-product-item
419
- v-else
420
- className="h-full box-border"
421
- v-bind="{ ...item, ...$props, ...attrs }"
422
- :coverImgStyle="{
423
- width: layoutType === 'vertical' ? '100%' : transformValueUnit(imageWidth),
424
- height: layoutType === 'vertical' ? transformValueUnit(imageHeight) : undefined,
425
- minHeight:
426
- layoutType !== 'vertical' ? transformValueUnit(imageHeight) : undefined,
427
- borderRadius: imageRadius ? transformValueUnit(imageRadius) : undefined,
428
- ...(attrs?.coverImgStyle ?? {}),
429
- }"
430
- ></lcb-product-item>
431
- </slot>
421
+ <view
422
+ v-for="(row, rowIndex) in horizontalRows"
423
+ :key="`row-${rowIndex}`"
424
+ class="flex whitespace-nowrap"
425
+ style="padding: 0 12rpx"
426
+ >
427
+ <lcb-action-view
428
+ v-for="(item, index) in row"
429
+ :key="`${item?.productId}:${index}`"
430
+ custom-class="flex-shrink-0 w-fit !h-auto"
431
+ v-bind="item.link"
432
+ render-mode="view"
433
+ >
434
+ <view
435
+ :style="{
436
+ width: `${itemWidth}rpx`,
437
+ marginLeft: index === 0 ? 0 : `${gap}rpx`,
438
+ height: '100%',
439
+ }"
440
+ >
441
+ <slot name="item" :item="item">
442
+ <lcb-absolute-config-layout
443
+ v-if="renderItemAbsoluteConfigLayout"
444
+ :blocks="renderItemAbsoluteConfigLayout?.blocks"
445
+ :canvas="renderItemAbsoluteConfigLayout?.canvas"
446
+ :dataset="{
447
+ ...(renderItemAbsoluteConfigLayout?.dataset ?? {}),
448
+ ...item,
449
+ }"
450
+ />
451
+ <lcb-product-item
452
+ v-else
453
+ className="h-full box-border"
454
+ v-bind="{ ...item, ...$props, ...attrs }"
455
+ :coverImgStyle="{
456
+ width:
457
+ layoutType === 'vertical' ? '100%' : transformValueUnit(imageWidth),
458
+ height:
459
+ layoutType === 'vertical' ? transformValueUnit(imageHeight) : undefined,
460
+ minHeight:
461
+ layoutType !== 'vertical' ? transformValueUnit(imageHeight) : undefined,
462
+ borderRadius: imageRadius ? transformValueUnit(imageRadius) : undefined,
463
+ ...(attrs?.coverImgStyle ?? {}),
464
+ }"
465
+ ></lcb-product-item>
466
+ </slot>
467
+ </view>
468
+ </lcb-action-view>
469
+ </view>
432
470
  </view>
433
- </lcb-action-view>
471
+ </view>
434
472
  </template>
435
473
  </lcb-block>
436
474
  </ProductSkeleton>
@@ -27,6 +27,7 @@ export interface LcbProductProps extends LcbBlockProps {
27
27
  layoutType?: 'vertical' | 'horizontal' // 布局方式
28
28
  titleLineClamp?: number
29
29
  coverImgStyle?: Record<string, any>
30
+ headImgStyle?: Record<string, any>
30
31
  filterList?: boolean
31
32
  renderItemAbsoluteConfigLayout?: {
32
33
  dataset?: Record<string, any>
@@ -45,4 +46,5 @@ export interface LcbProductProps extends LcbBlockProps {
45
46
  borderMode?: 'full' | 'content'
46
47
  itemVerticalPadding?: number
47
48
  itemHorizontalPadding?: number
49
+ rows?: number // horizontal 模式下的行数,默认为 1
48
50
  }
@@ -62,7 +62,6 @@ const style = computed(() => {
62
62
  const fontSize = itemAttrs?.[`${props?.prop}FontSize`]
63
63
  const fontWeight = itemAttrs?.[`${props?.prop}Bold`] === true ? 'bold' : 'normal'
64
64
  const color = itemAttrs?.[`${props?.prop}Color`]
65
-
66
65
  return {
67
66
  fontSize: fontSize ? `${fontSize}rpx` : '',
68
67
  fontWeight,
@@ -374,11 +373,12 @@ const coverImgWidth = computed(() => {
374
373
  </slot>
375
374
 
376
375
  <slot :value="value" v-else-if="prop === 'headImg'" name="headImg">
377
- <img
378
- :src="value + `?x-oss-process=image/resize,m_mfit,w_${64}&imageView2/2/w/${64}`"
379
- class="block w-4 h-4 rounded-full"
380
- :class="className"
381
- :style="style"
376
+ <wd-img
377
+ :src="value"
378
+ :width="style.width || 16"
379
+ :height="style.height || 16"
380
+ custom-class="block rounded-full"
381
+ :radius="style.borderRadius || 1000"
382
382
  mode="aspectFill"
383
383
  />
384
384
  </slot>
@@ -132,6 +132,7 @@ export interface LcbProductItemProps {
132
132
  blurSize?: number
133
133
  shadowColor?: string
134
134
  shadowSize?: number
135
+ headImgStyle?: CSSProperties
135
136
 
136
137
  borderWidth?: number
137
138
  borderColor?: string
package/hooks/usePay.ts CHANGED
@@ -50,18 +50,21 @@ const usePay = (
50
50
  runAsync(orderNo)
51
51
  return
52
52
  }
53
+ uni.showLoading({
54
+ title: 'loading...',
55
+ mask: true,
56
+ })
53
57
  successFun.value = options?.onSuccess
54
58
  uni.requestPayment({
55
59
  provider: 'wxpay',
56
60
  ...paymentParams,
57
61
  success: () => {
58
- uni.showLoading({
59
- title: 'loading...',
60
- mask: true,
61
- })
62
62
  runAsync(orderNo)
63
63
  },
64
- fail: options?.onError,
64
+ fail: () => {
65
+ options?.onError?.()
66
+ uni.hideLoading()
67
+ },
65
68
  })
66
69
  }
67
70
  onPageHide(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tplc/business",
3
- "version": "0.7.71",
3
+ "version": "0.7.73",
4
4
  "keywords": [
5
5
  "业务组件"
6
6
  ],
@@ -0,0 +1,22 @@
1
+ /** 会员角色 */
2
+ export interface UserVipRole {
3
+ userLevelRoleId: string
4
+ levelRoleName: string
5
+ levelRoleNameEn: string
6
+ levelRoleImg: string
7
+ content: string
8
+ addition?: string
9
+ additionConfig?: string
10
+ subTitle?: string
11
+ title?: string
12
+ levelRoleType?: number
13
+ levelRoleTypeName?: string
14
+ }
15
+ /** 获取会员角色列表 */
16
+ export declare const getUserVipRole: () => Promise<
17
+ import('../../../../action').IResData<UserVipRole[]>
18
+ >
19
+ /** 选择会员角色 */
20
+ export declare const userPointChooseRole: (params: {
21
+ userLevelRoleId: string
22
+ }) => Promise<import('../../../../action').IResData<unknown>>
@@ -0,0 +1,34 @@
1
+ type __VLS_PublicProps = {
2
+ show: boolean
3
+ }
4
+ declare const _default: import('vue').DefineComponent<
5
+ __VLS_TypePropsToOption<__VLS_PublicProps>,
6
+ {},
7
+ unknown,
8
+ {},
9
+ {},
10
+ import('vue').ComponentOptionsMixin,
11
+ import('vue').ComponentOptionsMixin,
12
+ {
13
+ 'update:show': (show: boolean) => void
14
+ },
15
+ string,
16
+ import('vue').PublicProps,
17
+ Readonly<import('vue').ExtractPropTypes<__VLS_TypePropsToOption<__VLS_PublicProps>>> & {
18
+ 'onUpdate:show'?: ((show: boolean) => any) | undefined
19
+ },
20
+ {},
21
+ {}
22
+ >
23
+ export default _default
24
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T
25
+ type __VLS_TypePropsToOption<T> = {
26
+ [K in keyof T]-?: {} extends Pick<T, K>
27
+ ? {
28
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>
29
+ }
30
+ : {
31
+ type: import('vue').PropType<T[K]>
32
+ required: true
33
+ }
34
+ }
@@ -59,6 +59,8 @@ export type LcbActionViewProps = {
59
59
  | 104
60
60
  | 241
61
61
  | 143
62
+ | 147
63
+ | 148
62
64
  /** 小程序appid */
63
65
  jumpAppid?: string
64
66
  }
@@ -133,4 +135,6 @@ export declare const jumpTypeMap: {
133
135
  'mixture-pay': number
134
136
  customPopup: number
135
137
  arScan: number
138
+ translate: number
139
+ userLevelRole: number
136
140
  }
@@ -2,7 +2,7 @@ import { HolidayInfo } from '../../types'
2
2
  declare let __VLS_typeProps: {
3
3
  date?: HolidayInfo
4
4
  showAll?: boolean
5
- customClass: string
5
+ customClass?: string
6
6
  }
7
7
  type __VLS_PublicProps = {
8
8
  modelValue?: string | undefined
@@ -101,6 +101,7 @@ declare const __VLS_component: import('vue').DefineComponent<
101
101
  }[]
102
102
  mapTagMode: 'single' | 'multiple'
103
103
  mapConfigParams: string
104
+ tagPosition: 'left' | 'right'
104
105
  },
105
106
  {}
106
107
  >
@@ -41,6 +41,7 @@ export interface LcbListProps extends LcbBlockProps {
41
41
  }[]
42
42
  mapTagMode?: 'single' | 'multiple'
43
43
  mapConfigParams?: string
44
+ tagPosition?: 'left' | 'right'
44
45
  }
45
46
  export interface Option {
46
47
  label: string
@@ -5,6 +5,7 @@ declare const _default: import('vue').DefineComponent<
5
5
  __VLS_TypePropsToOption<LcbListProps & LcbListInfo>,
6
6
  {
7
7
  mapTagMode: string
8
+ tagPosition: string
8
9
  }
9
10
  >,
10
11
  {},
@@ -22,12 +23,14 @@ declare const _default: import('vue').DefineComponent<
22
23
  __VLS_TypePropsToOption<LcbListProps & LcbListInfo>,
23
24
  {
24
25
  mapTagMode: string
26
+ tagPosition: string
25
27
  }
26
28
  >
27
29
  >
28
30
  >,
29
31
  {
30
32
  mapTagMode: 'single' | 'multiple'
33
+ tagPosition: 'left' | 'right'
31
34
  },
32
35
  {}
33
36
  >
@@ -17,6 +17,7 @@ declare const __VLS_component: import('vue').DefineComponent<
17
17
  paddingVertical: number
18
18
  sourceMode: number
19
19
  gap: number
20
+ rows: number
20
21
  }
21
22
  >,
22
23
  {
@@ -44,6 +45,7 @@ declare const __VLS_component: import('vue').DefineComponent<
44
45
  paddingVertical: number
45
46
  sourceMode: number
46
47
  gap: number
48
+ rows: number
47
49
  }
48
50
  >
49
51
  >
@@ -58,6 +60,7 @@ declare const __VLS_component: import('vue').DefineComponent<
58
60
  listType: 'list' | 'horizontal' | 'grid' | 'waterfall'
59
61
  titleLineClamp: number
60
62
  sourceMode: 1 | 2
63
+ rows: number
61
64
  },
62
65
  {}
63
66
  >
@@ -24,6 +24,7 @@ export interface LcbProductProps extends LcbBlockProps {
24
24
  layoutType?: 'vertical' | 'horizontal'
25
25
  titleLineClamp?: number
26
26
  coverImgStyle?: Record<string, any>
27
+ headImgStyle?: Record<string, any>
27
28
  filterList?: boolean
28
29
  renderItemAbsoluteConfigLayout?: {
29
30
  dataset?: Record<string, any>
@@ -41,4 +42,5 @@ export interface LcbProductProps extends LcbBlockProps {
41
42
  borderMode?: 'full' | 'content'
42
43
  itemVerticalPadding?: number
43
44
  itemHorizontalPadding?: number
45
+ rows?: number
44
46
  }
@@ -125,6 +125,7 @@ export interface LcbProductItemProps {
125
125
  blurSize?: number
126
126
  shadowColor?: string
127
127
  shadowSize?: number
128
+ headImgStyle?: CSSProperties
128
129
  borderWidth?: number
129
130
  borderColor?: string
130
131
  borderMode?: 'full' | 'content'
@@ -113,6 +113,8 @@ declare const _default: import('vue').DefineComponent<
113
113
  | 104
114
114
  | 241
115
115
  | 143
116
+ | 147
117
+ | 148
116
118
  jumpAppid?: string
117
119
  } & import('../lcb-block/types').LcbBlockProps
118
120
  >,