@tplc/business 0.7.80 → 0.7.82

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.
@@ -0,0 +1,152 @@
1
+ # Empty 状态功能实现总结
2
+
3
+ ## 修改的文件
4
+
5
+ ### 1. 类型定义文件
6
+
7
+ #### `/packages/business/components/lcb-product/types.ts`
8
+ - 新增 `EmptyProps` 接口,定义空状态配置项
9
+ - 在 `LcbProductProps` 中添加 `emptyProps?: EmptyProps` 属性
10
+
11
+ #### `/packages/business/components/lcb-list/types.ts`
12
+ - 导入 `EmptyProps` 类型
13
+ - 在 `LcbListProps` 中添加 `emptyProps?: EmptyProps` 属性
14
+
15
+ ### 2. 组件文件
16
+
17
+ #### `/packages/business/components/lcb-product/lcb-product.vue`
18
+ **修改内容:**
19
+ - 在 props 默认值中添加 `emptyProps` 的默认配置
20
+ - 新增 `showEmpty` 计算属性,判断是否显示空状态
21
+ - 新增 `mergedEmptyProps` 计算属性,合并默认配置和用户配置
22
+ - 在模板中添加空状态显示逻辑:
23
+ - 当 `showEmpty` 为 `true` 时显示空状态
24
+ - 空状态包含图片和文字
25
+ - 所有样式属性可配置
26
+
27
+ #### `/packages/business/components/lcb-list/lcb-list.vue`
28
+ **修改内容:**
29
+ - 将 `emptyProps` 透传给内部的 `lcb-product` 组件
30
+
31
+ ### 3. 静态资源
32
+
33
+ #### `/packages/engine/src/static/empty.png`
34
+ - 添加默认的空状态图片(从用户提供的图片复制)
35
+
36
+ ### 4. 文档文件
37
+
38
+ #### `/packages/business/components/lcb-product/EMPTY_USAGE.md`
39
+ - 创建详细的使用文档
40
+ - 包含配置项说明、默认值、使用示例等
41
+
42
+ #### `/packages/engine/src/pages/lcb-product/empty-demo.vue`
43
+ - 创建完整的示例页面
44
+ - 展示多种配置场景
45
+
46
+ ## EmptyProps 配置项
47
+
48
+ ```typescript
49
+ interface EmptyProps {
50
+ image?: string // 空状态图片地址
51
+ text?: string // 空状态文字
52
+ imageWidth?: number // 图片宽度(rpx)
53
+ imageHeight?: number // 图片高度(rpx)
54
+ textColor?: string // 文字颜色
55
+ textSize?: number // 文字大小(rpx)
56
+ textWeight?: string // 文字粗细
57
+ gap?: number // 图片与文字的间距(rpx)
58
+ }
59
+ ```
60
+
61
+ ## 默认配置
62
+
63
+ ```javascript
64
+ {
65
+ image: '',
66
+ text: '还没有点亮记录',
67
+ imageWidth: 400,
68
+ imageHeight: 400,
69
+ textColor: '#999999',
70
+ textSize: 28,
71
+ textWeight: 'normal',
72
+ gap: 24,
73
+ }
74
+ ```
75
+
76
+ ## 使用示例
77
+
78
+ ### lcb-product 组件
79
+
80
+ ```vue
81
+ <lcb-product
82
+ :items="[]"
83
+ :emptyProps="{
84
+ image: '/static/empty.png',
85
+ text: '还没有点亮记录',
86
+ imageWidth: 500,
87
+ imageHeight: 500,
88
+ textColor: '#666666',
89
+ textSize: 32,
90
+ textWeight: 'bold',
91
+ gap: 32,
92
+ }"
93
+ />
94
+ ```
95
+
96
+ ### lcb-list 组件
97
+
98
+ ```vue
99
+ <lcb-list
100
+ pageFilterType="product-filter"
101
+ :emptyProps="{
102
+ image: '/static/empty.png',
103
+ text: '还没有点亮记录',
104
+ imageWidth: 400,
105
+ imageHeight: 400,
106
+ textColor: '#999999',
107
+ textSize: 28,
108
+ textWeight: 'normal',
109
+ gap: 24,
110
+ }"
111
+ />
112
+ ```
113
+
114
+ ## 功能特点
115
+
116
+ 1. ✅ **完全可配置**:所有视觉属性都可以自定义
117
+ 2. ✅ **默认值友好**:即使不配置也有合理的默认显示
118
+ 3. ✅ **类型安全**:完整的 TypeScript 类型支持
119
+ 4. ✅ **响应式设计**:使用 rpx 单位,适配不同屏幕
120
+ 5. ✅ **独立配置**:通过 `emptyProps` 单独配置,不影响其他属性
121
+ 6. ✅ **兼容性好**:不影响现有功能,向下兼容
122
+
123
+ ## 显示逻辑
124
+
125
+ 空状态在以下条件同时满足时显示:
126
+ - 数据加载完成(`loading === false`)
127
+ - 数据列表为空(`renderList.length === 0`)
128
+
129
+ ## 样式特性
130
+
131
+ 1. **图片**:
132
+ - 支持自定义宽高
133
+ - 使用 `aspectFit` 模式保持比例
134
+ - 可选显示(如果不提供 image 则不显示图片)
135
+
136
+ 2. **文字**:
137
+ - 支持自定义颜色
138
+ - 支持自定义字号
139
+ - 支持自定义字重(normal、bold、100-900)
140
+ - 可选显示(如果不提供 text 则不显示文字)
141
+
142
+ 3. **布局**:
143
+ - 垂直居中对齐
144
+ - 图片在上,文字在下
145
+ - 可自定义间距
146
+
147
+ ## 注意事项
148
+
149
+ 1. 所有尺寸单位使用 `rpx`(响应式像素)
150
+ 2. 图片路径可以是相对路径或绝对 URL
151
+ 3. 空状态会继承父组件的内边距设置
152
+ 4. 最小高度为 `400rpx`,确保有足够的显示空间
@@ -0,0 +1,77 @@
1
+ # Empty 状态配置 - 快速参考
2
+
3
+ ## 🎯 快速开始
4
+
5
+ ```vue
6
+ <lcb-product
7
+ :items="productList"
8
+ :emptyProps="{
9
+ image: '/static/empty.png',
10
+ text: '还没有点亮记录'
11
+ }"
12
+ />
13
+ ```
14
+
15
+ ## 📋 所有配置项
16
+
17
+ | 属性 | 类型 | 默认值 | 说明 |
18
+ |------|------|--------|------|
19
+ | `image` | `string` | `''` | 空状态图片地址 |
20
+ | `text` | `string` | `'还没有点亮记录'` | 空状态文字 |
21
+ | `imageWidth` | `number` | `400` | 图片宽度(rpx) |
22
+ | `imageHeight` | `number` | `400` | 图片高度(rpx) |
23
+ | `textColor` | `string` | `'#999999'` | 文字颜色 |
24
+ | `textSize` | `number` | `28` | 文字大小(rpx) |
25
+ | `textWeight` | `string \| number` | `'normal'` | 文字粗细 |
26
+ | `gap` | `number` | `24` | 图片与文字间距(rpx) |
27
+
28
+ ## 🎨 常用配置示例
29
+
30
+ ### 小图片 + 浅色文字
31
+ ```javascript
32
+ {
33
+ image: '/static/empty.png',
34
+ text: '暂无数据',
35
+ imageWidth: 300,
36
+ imageHeight: 300,
37
+ textColor: '#CCCCCC',
38
+ textSize: 24,
39
+ }
40
+ ```
41
+
42
+ ### 大图片 + 粗体文字
43
+ ```javascript
44
+ {
45
+ image: '/static/empty.png',
46
+ text: '还没有点亮记录',
47
+ imageWidth: 600,
48
+ imageHeight: 600,
49
+ textColor: '#333333',
50
+ textSize: 36,
51
+ textWeight: 'bold',
52
+ }
53
+ ```
54
+
55
+ ### 紧凑布局
56
+ ```javascript
57
+ {
58
+ image: '/static/empty.png',
59
+ text: '暂无内容',
60
+ imageWidth: 250,
61
+ imageHeight: 250,
62
+ gap: 12,
63
+ textSize: 24,
64
+ }
65
+ ```
66
+
67
+ ## 🔧 适用组件
68
+
69
+ - ✅ `lcb-product`
70
+ - ✅ `lcb-list`
71
+
72
+ ## 💡 提示
73
+
74
+ 1. **图片优先级**:如果不提供 `image`,则只显示文字
75
+ 2. **文字优先级**:如果不提供 `text`,则只显示图片
76
+ 3. **响应式单位**:所有尺寸使用 `rpx`,自动适配不同屏幕
77
+ 4. **字重选项**:`'normal'` | `'bold'` | `100` | `200` | `300` | `400` | `500` | `600` | `700` | `800` | `900`
@@ -0,0 +1,147 @@
1
+ # Empty 状态配置说明
2
+
3
+ ## 功能概述
4
+
5
+ `lcb-product` 和 `lcb-list` 组件现在支持通过 `emptyProps` 配置空状态的展示,包括图片、文字以及样式定制。
6
+
7
+ ## 配置项说明
8
+
9
+ ### EmptyProps 接口
10
+
11
+ ```typescript
12
+ interface EmptyProps {
13
+ /** 空状态图片地址 */
14
+ image?: string
15
+ /** 空状态文字 */
16
+ text?: string
17
+ /** 图片宽度(rpx) */
18
+ imageWidth?: number
19
+ /** 图片高度(rpx) */
20
+ imageHeight?: number
21
+ /** 文字颜色 */
22
+ textColor?: string
23
+ /** 文字大小(rpx) */
24
+ textSize?: number
25
+ /** 文字粗细 */
26
+ textWeight?: 'normal' | 'bold' | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
27
+ /** 图片与文字的间距(rpx) */
28
+ gap?: number
29
+ }
30
+ ```
31
+
32
+ ## 默认配置
33
+
34
+ ```javascript
35
+ {
36
+ image: '',
37
+ text: '还没有点亮记录',
38
+ imageWidth: 400,
39
+ imageHeight: 400,
40
+ textColor: '#999999',
41
+ textSize: 28,
42
+ textWeight: 'normal',
43
+ gap: 24,
44
+ }
45
+ ```
46
+
47
+ ## 使用示例
48
+
49
+ ### 基础使用
50
+
51
+ ```vue
52
+ <template>
53
+ <lcb-product
54
+ :items="productList"
55
+ :emptyProps="{
56
+ image: '/static/empty.png',
57
+ text: '还没有点亮记录',
58
+ }"
59
+ />
60
+ </template>
61
+ ```
62
+
63
+ ### 完整配置
64
+
65
+ ```vue
66
+ <template>
67
+ <lcb-product
68
+ :items="productList"
69
+ :emptyProps="{
70
+ image: '/static/empty.png',
71
+ text: '还没有点亮记录',
72
+ imageWidth: 500,
73
+ imageHeight: 500,
74
+ textColor: '#666666',
75
+ textSize: 32,
76
+ textWeight: 'bold',
77
+ gap: 32,
78
+ }"
79
+ />
80
+ </template>
81
+ ```
82
+
83
+ ### 在 lcb-list 中使用
84
+
85
+ ```vue
86
+ <template>
87
+ <lcb-list
88
+ pageFilterType="product-filter"
89
+ :emptyProps="{
90
+ image: '/static/empty.png',
91
+ text: '还没有点亮记录',
92
+ imageWidth: 400,
93
+ imageHeight: 400,
94
+ textColor: '#999999',
95
+ textSize: 28,
96
+ textWeight: 'normal',
97
+ gap: 24,
98
+ }"
99
+ />
100
+ </template>
101
+ ```
102
+
103
+ ### 自定义不同的文字和样式
104
+
105
+ ```vue
106
+ <template>
107
+ <!-- 粗体大号文字 -->
108
+ <lcb-product
109
+ :items="[]"
110
+ :emptyProps="{
111
+ image: '/static/empty.png',
112
+ text: '暂无内容',
113
+ textSize: 36,
114
+ textWeight: 'bold',
115
+ textColor: '#333333',
116
+ }"
117
+ />
118
+
119
+ <!-- 浅色文字 -->
120
+ <lcb-product
121
+ :items="[]"
122
+ :emptyProps="{
123
+ image: '/static/empty.png',
124
+ text: '暂无数据',
125
+ textSize: 26,
126
+ textWeight: 300,
127
+ textColor: '#CCCCCC',
128
+ }"
129
+ />
130
+ </template>
131
+ ```
132
+
133
+ ## 注意事项
134
+
135
+ 1. **图片尺寸**:`imageWidth` 和 `imageHeight` 单位为 rpx(响应式像素)
136
+ 2. **文字大小**:`textSize` 单位为 rpx
137
+ 3. **间距**:`gap` 单位为 rpx,控制图片和文字之间的垂直间距
138
+ 4. **文字粗细**:`textWeight` 支持 CSS 标准的字重值
139
+ 5. **空状态显示时机**:当数据加载完成且列表为空时自动显示
140
+
141
+ ## 效果预览
142
+
143
+ 空状态展示效果:
144
+ - 居中显示图片
145
+ - 图片下方展示文字
146
+ - 可自定义所有视觉样式
147
+ - 响应式设计,适配不同屏幕尺寸
@@ -200,12 +200,32 @@ const horizontalRows = computed(() => {
200
200
 
201
201
  return rows
202
202
  })
203
+
204
+ // 计算是否显示空状态
205
+ const showEmpty = computed(() => {
206
+ return !loading.value && renderList.value.length === 0
207
+ })
208
+
209
+ // 合并默认空状态配置(添加内边距)
210
+ const mergedEmptyProps = computed(() => {
211
+ return {
212
+ ...props.emptyProps,
213
+ paddingTop: props.emptyProps?.paddingTop ?? props.paddingVertical ?? 0,
214
+ paddingRight: props.emptyProps?.paddingRight ?? props.paddingHorizontal ?? 0,
215
+ paddingBottom: props.emptyProps?.paddingBottom ?? props.paddingVertical ?? 0,
216
+ paddingLeft: props.emptyProps?.paddingLeft ?? props.paddingHorizontal ?? 0,
217
+ }
218
+ })
203
219
  </script>
204
220
 
205
221
  <template>
206
222
  <lcb-block v-bind="loading ? blockProps[0] : {}">
207
223
  <ProductSkeleton :loading="loading" v-bind="$props">
224
+ <!-- Empty 状态 -->
225
+ <lcb-empty v-if="showEmpty" v-bind="mergedEmptyProps" />
226
+
208
227
  <lcb-block
228
+ v-else
209
229
  v-bind="{
210
230
  ...$props,
211
231
  shadowColor: blockShadowColor,
@@ -1,4 +1,5 @@
1
1
  import { LcbBlockProps } from '../lcb-block/types'
2
+ import { LcbEmptyProps } from '../lcb-empty/types'
2
3
 
3
4
  export interface LcbProductProps extends LcbBlockProps {
4
5
  // Define the component's prop types here
@@ -47,4 +48,5 @@ export interface LcbProductProps extends LcbBlockProps {
47
48
  itemVerticalPadding?: number
48
49
  itemHorizontalPadding?: number
49
50
  rows?: number // horizontal 模式下的行数,默认为 1
51
+ emptyProps?: LcbEmptyProps // 空状态配置
50
52
  }
@@ -10,7 +10,10 @@
10
10
  :height="props.pageProps?.pagingUsePageScroll ? undefined : props.pageProps?.pagingHeight"
11
11
  v-if="props.pageProps?.pagingEnabled"
12
12
  >
13
- <lcb-block v-bind="$props" :custom-style="listStyle">
13
+ <!-- Empty 状态 -->
14
+ <lcb-empty v-if="showEmpty" v-bind="mergedEmptyProps" />
15
+
16
+ <lcb-block v-else v-bind="$props" :custom-style="listStyle">
14
17
  <view
15
18
  v-for="(item, index) in renderList"
16
19
  :key="getItemKey(item, index)"
@@ -21,16 +24,22 @@
21
24
  </view>
22
25
  </lcb-block>
23
26
  </z-paging>
24
- <lcb-block v-bind="$props" :custom-style="listStyle" v-else>
25
- <view
26
- v-for="(item, index) in renderList"
27
- :key="getItemKey(item, index)"
28
- class="flex-shrink-0"
29
- :style="itemStyle"
30
- >
31
- <slot :data="item" :list="list" />
32
- </view>
33
- </lcb-block>
27
+
28
+ <template v-else>
29
+ <!-- Empty 状态 -->
30
+ <lcb-empty v-if="showEmpty" v-bind="mergedEmptyProps" />
31
+
32
+ <lcb-block v-else v-bind="$props" :custom-style="listStyle">
33
+ <view
34
+ v-for="(item, index) in renderList"
35
+ :key="getItemKey(item, index)"
36
+ class="flex-shrink-0"
37
+ :style="itemStyle"
38
+ >
39
+ <slot :data="item" :list="list" />
40
+ </view>
41
+ </lcb-block>
42
+ </template>
34
43
  </template>
35
44
 
36
45
  <script setup lang="ts">
@@ -155,6 +164,22 @@ const listStyle = computed(() => {
155
164
  'white-space': props.scrollX ? 'nowrap' : 'normal',
156
165
  }
157
166
  })
167
+
168
+ // 计算是否显示空状态
169
+ const showEmpty = computed(() => {
170
+ return renderList.value.length === 0
171
+ })
172
+
173
+ // 合并默认空状态配置(添加内边距)
174
+ const mergedEmptyProps = computed(() => {
175
+ return {
176
+ ...props.emptyProps,
177
+ paddingTop: props.emptyProps?.paddingTop ?? props.paddingVertical ?? 0,
178
+ paddingRight: props.emptyProps?.paddingRight ?? props.paddingHorizontal ?? 0,
179
+ paddingBottom: props.emptyProps?.paddingBottom ?? props.paddingVertical ?? 0,
180
+ paddingLeft: props.emptyProps?.paddingLeft ?? props.paddingHorizontal ?? 0,
181
+ }
182
+ })
158
183
  </script>
159
184
 
160
185
  <style lang="scss" scoped></style>
@@ -1,6 +1,8 @@
1
1
  import { LcbAreaProps } from '../lcb-area/types'
2
2
  import { DataSource } from '../../action'
3
3
  import { LcbBlockProps } from '../lcb-block/types'
4
+ import { LcbEmptyProps } from '../lcb-empty/types'
5
+
4
6
  export interface LcbWrapperListProps extends LcbBlockProps {
5
7
  dataSource?: DataSource
6
8
  gap?: number
@@ -29,4 +31,5 @@ export interface LcbWrapperListProps extends LcbBlockProps {
29
31
  */
30
32
  pagingHeight?: string
31
33
  }
34
+ emptyProps?: LcbEmptyProps // 空状态配置
32
35
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tplc/business",
3
- "version": "0.7.80",
3
+ "version": "0.7.82",
4
4
  "keywords": [
5
5
  "业务组件"
6
6
  ],
@@ -0,0 +1,28 @@
1
+ export interface LcbEmptyProps {
2
+ /** 空状态图片地址 */
3
+ image?: string
4
+ /** 空状态文字 */
5
+ text?: string
6
+ /** 图片宽度(rpx) */
7
+ imageWidth?: number
8
+ /** 图片高度(rpx) */
9
+ imageHeight?: number
10
+ /** 文字颜色 */
11
+ textColor?: string
12
+ /** 文字大小(rpx) */
13
+ textSize?: number
14
+ /** 文字粗细 */
15
+ textWeight?: 'normal' | 'bold' | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
16
+ /** 图片与文字的间距(rpx) */
17
+ gap?: number
18
+ /** 最小高度(rpx) */
19
+ minHeight?: number
20
+ /** 内边距 - 上(rpx) */
21
+ paddingTop?: number
22
+ /** 内边距 - 右(rpx) */
23
+ paddingRight?: number
24
+ /** 内边距 - 下(rpx) */
25
+ paddingBottom?: number
26
+ /** 内边距 - 左(rpx) */
27
+ paddingLeft?: number
28
+ }
@@ -75,6 +75,7 @@ declare const _default: import('vue').DefineComponent<
75
75
  paddingHorizontal: number
76
76
  paddingVertical: number
77
77
  textColor: string
78
+ textSize: number
78
79
  pictureDistribution: 3 | 4 | 5
79
80
  iconRadius: number
80
81
  iconBorderColor: string
@@ -84,7 +85,6 @@ declare const _default: import('vue').DefineComponent<
84
85
  divider: boolean
85
86
  arrowColor: string
86
87
  arrowSize: number
87
- textSize: number
88
88
  urlKey: string
89
89
  titleKey: string
90
90
  titleBottom: number
@@ -108,6 +108,7 @@ declare const __VLS_component: import('vue').DefineComponent<
108
108
  mapTagMode: 'single' | 'multiple'
109
109
  mapConfigParams: string
110
110
  tagPosition: 'left' | 'right'
111
+ emptyProps: import('../lcb-empty/types').LcbEmptyProps
111
112
  },
112
113
  {}
113
114
  >
@@ -1,6 +1,7 @@
1
1
  import { PageListProps } from './components/FilterList/type'
2
2
  import { LcbProductProps } from '../lcb-product/types'
3
3
  import { LcbBlockProps } from '../lcb-block/types'
4
+ import { LcbEmptyProps } from '../lcb-empty/types'
4
5
  export interface LcbListProps extends LcbBlockProps {
5
6
  pageFilterType?: string
6
7
  pageListProps?: PageListProps
@@ -42,6 +43,7 @@ export interface LcbListProps extends LcbBlockProps {
42
43
  mapTagMode?: 'single' | 'multiple'
43
44
  mapConfigParams?: string
44
45
  tagPosition?: 'left' | 'right'
46
+ emptyProps?: LcbEmptyProps
45
47
  }
46
48
  export interface Option {
47
49
  label: string
@@ -1,4 +1,5 @@
1
1
  import { LcbBlockProps } from '../lcb-block/types'
2
+ import { LcbEmptyProps } from '../lcb-empty/types'
2
3
  export interface LcbProductProps extends LcbBlockProps {
3
4
  listType?: 'list' | 'horizontal' | 'grid' | 'waterfall'
4
5
  shadowColor?: string
@@ -43,4 +44,5 @@ export interface LcbProductProps extends LcbBlockProps {
43
44
  itemVerticalPadding?: number
44
45
  itemHorizontalPadding?: number
45
46
  rows?: number
47
+ emptyProps?: LcbEmptyProps
46
48
  }
@@ -107,9 +107,9 @@ declare const _default: import('vue').DefineComponent<
107
107
  paddingBottom: number
108
108
  paddingLeft: number
109
109
  paddingRight: number
110
- iconType: 0 | 1
111
110
  textColor: string
112
111
  textSize: number
112
+ iconType: 0 | 1
113
113
  photoRound: boolean
114
114
  photoSize: number
115
115
  titleMarginTop: number
@@ -1,6 +1,7 @@
1
1
  import { LcbAreaProps } from '../lcb-area/types'
2
2
  import { DataSource } from '../../action'
3
3
  import { LcbBlockProps } from '../lcb-block/types'
4
+ import { LcbEmptyProps } from '../lcb-empty/types'
4
5
  export interface LcbWrapperListProps extends LcbBlockProps {
5
6
  dataSource?: DataSource
6
7
  gap?: number
@@ -29,4 +30,5 @@ export interface LcbWrapperListProps extends LcbBlockProps {
29
30
  */
30
31
  pagingHeight?: string
31
32
  }
33
+ emptyProps?: LcbEmptyProps
32
34
  }