im-ui-mobile 0.1.0 → 0.1.2
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/components/im-avatar/im-avatar.vue +7 -7
- package/components/im-badge/im-badge.vue +326 -0
- package/components/im-button/im-button.vue +71 -34
- package/components/im-card/im-card.vue +563 -0
- package/components/im-chat-item/im-chat-item.vue +5 -4
- package/components/im-col/im-col.vue +191 -0
- package/components/im-dialog/im-dialog.vue +543 -0
- package/components/im-double-tap-view/im-double-tap-view.vue +93 -0
- package/components/im-emoji-picker/im-emoji-picker.vue +1143 -0
- package/components/im-friend-item/im-friend-item.vue +1 -1
- package/components/im-group-item/im-group-item.vue +1 -1
- package/components/im-group-member-selector/im-group-member-selector.vue +5 -5
- package/components/im-group-rtc-join/im-group-rtc-join.vue +8 -8
- package/components/im-icon/im-icon.vue +593 -0
- package/components/im-image-upload/im-image-upload.vue +0 -2
- package/components/im-link/im-link.vue +628 -0
- package/components/im-loading/im-loading.vue +13 -4
- package/components/im-mention-picker/im-mention-picker.vue +8 -7
- package/components/im-message-action/im-message-action.vue +678 -0
- package/components/im-message-item/im-message-item.vue +28 -26
- package/components/im-message-list/im-message-list.vue +1108 -0
- package/components/im-modal/im-modal.vue +373 -0
- package/components/im-nav-bar/im-nav-bar.vue +689 -75
- package/components/im-parse/im-parse.vue +1054 -0
- package/components/im-popup/im-popup.vue +467 -0
- package/components/im-read-receipt/im-read-receipt.vue +10 -10
- package/components/im-row/im-row.vue +189 -0
- package/components/im-search/im-search.vue +762 -0
- package/components/im-sku/im-sku.vue +720 -0
- package/components/im-sku/utils/helper.ts +182 -0
- package/components/im-stepper/im-stepper.vue +585 -0
- package/components/im-stepper/utils/helper.ts +167 -0
- package/components/im-tabs/im-tabs.vue +1022 -0
- package/components/im-tabs/tabs-navigation.vue +489 -0
- package/components/im-tabs/utils/helper.ts +181 -0
- package/components/im-tabs-tab-pane/im-tabs-tab-pane.vue +145 -0
- package/components/im-upload/im-upload.vue +1236 -0
- package/components/im-voice-input/im-voice-input.vue +1 -1
- package/index.js +3 -5
- package/index.scss +19 -0
- package/libs/emoji-data.ts +229 -0
- package/libs/index.ts +16 -16
- package/package.json +1 -2
- package/styles/button.scss +33 -33
- package/theme.scss +2 -2
- package/types/components/badge.d.ts +42 -0
- package/types/components/button.d.ts +2 -1
- package/types/components/card.d.ts +122 -0
- package/types/components/col.d.ts +37 -0
- package/types/components/dialog.d.ts +125 -0
- package/types/components/double-tap-view.d.ts +31 -0
- package/types/components/emoji-picker.d.ts +121 -0
- package/types/components/group-rtc-join.d.ts +1 -1
- package/types/components/icon.d.ts +77 -0
- package/types/components/link.d.ts +55 -0
- package/types/components/loading.d.ts +1 -0
- package/types/components/message-action.d.ts +96 -0
- package/types/components/message-item.d.ts +2 -2
- package/types/components/message-list.d.ts +136 -0
- package/types/components/modal.d.ts +106 -0
- package/types/components/nav-bar.d.ts +125 -0
- package/types/components/parse.d.ts +90 -0
- package/types/components/popup.d.ts +58 -0
- package/types/components/row.d.ts +31 -0
- package/types/components/search.d.ts +54 -0
- package/types/components/sku.d.ts +195 -0
- package/types/components/stepper.d.ts +99 -0
- package/types/components/tabs-tab-pane.d.ts +27 -0
- package/types/components/tabs.d.ts +117 -0
- package/types/components/upload.d.ts +137 -0
- package/types/components.d.ts +19 -1
- package/types/index.d.ts +38 -1
- package/types/libs/index.d.ts +10 -10
- package/types/utils/base64.d.ts +5 -0
- package/types/utils/dom.d.ts +3 -0
- package/types/utils/enums.d.ts +4 -5
- package/types/utils/validator.d.ts +74 -0
- package/utils/base64.js +18 -0
- package/utils/dom.js +353 -1
- package/utils/enums.js +4 -5
- package/utils/validator.js +230 -0
- package/components/im-file-upload/im-file-upload.vue +0 -309
- package/plugins/uview-plus.js +0 -29
- package/types/components/arrow-bar.d.ts +0 -14
- package/types/components/file-upload.d.ts +0 -58
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type { _SkuSpec, SkuItem } from '../../../types/components/sku'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 生成SKU树,用于规格选择和禁用状态管理
|
|
5
|
+
*/
|
|
6
|
+
export function generateSkuTree(specs: _SkuSpec[], skus: SkuItem[]) {
|
|
7
|
+
// 创建规格值映射
|
|
8
|
+
const specValueMap = new Map<string, Set<string>>()
|
|
9
|
+
|
|
10
|
+
specs.forEach(spec => {
|
|
11
|
+
specValueMap.set(spec.name, new Set())
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
// 收集所有有效的规格值
|
|
15
|
+
skus.forEach(sku => {
|
|
16
|
+
Object.entries(sku.specs).forEach(([specName, specValue]) => {
|
|
17
|
+
specValueMap.get(specName)?.add(specValue)
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
// 更新规格值的禁用状态
|
|
22
|
+
const updatedSpecs = specs.map(spec => {
|
|
23
|
+
const availableValues = specValueMap.get(spec.name) || new Set()
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
...spec,
|
|
27
|
+
values: spec.values.map(value => ({
|
|
28
|
+
...value,
|
|
29
|
+
disabled: !availableValues.has(value.name)
|
|
30
|
+
}))
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
return updatedSpecs
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 根据选中的规格计算可用的规格值
|
|
39
|
+
*/
|
|
40
|
+
export function getAvailableSpecValues(
|
|
41
|
+
selectedSpecs: Record<string, string>,
|
|
42
|
+
specs: _SkuSpec[],
|
|
43
|
+
skus: SkuItem[]
|
|
44
|
+
) {
|
|
45
|
+
const availableValues = new Map<string, Set<string>>()
|
|
46
|
+
|
|
47
|
+
// 初始化所有规格值
|
|
48
|
+
specs.forEach(spec => {
|
|
49
|
+
spec.values.forEach(value => {
|
|
50
|
+
if (!availableValues.has(spec.name)) {
|
|
51
|
+
availableValues.set(spec.name, new Set())
|
|
52
|
+
}
|
|
53
|
+
availableValues.get(spec.name)?.add(value.name)
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
// 过滤不可用的规格值
|
|
58
|
+
skus.forEach(sku => {
|
|
59
|
+
// 检查这个SKU是否与当前选中的规格匹配
|
|
60
|
+
const isMatch = Object.keys(selectedSpecs).every(specName => {
|
|
61
|
+
return sku.specs[specName] === selectedSpecs[specName]
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
if (isMatch && sku.stock > 0 && !sku.disabled) {
|
|
65
|
+
// 这个SKU可用,将其规格值标记为可用
|
|
66
|
+
Object.entries(sku.specs).forEach(([specName, specValue]) => {
|
|
67
|
+
if (!selectedSpecs[specName]) {
|
|
68
|
+
availableValues.get(specName)?.add(specValue)
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
// 更新规格的禁用状态
|
|
75
|
+
return specs.map(spec => {
|
|
76
|
+
const availableSet = availableValues.get(spec.name) || new Set()
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
...spec,
|
|
80
|
+
values: spec.values.map(value => ({
|
|
81
|
+
...value,
|
|
82
|
+
disabled: !availableSet.has(value.name)
|
|
83
|
+
}))
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* 验证SKU数据
|
|
90
|
+
*/
|
|
91
|
+
export function validateSkuData(specs: _SkuSpec[], skus: SkuItem[]) {
|
|
92
|
+
const errors: string[] = []
|
|
93
|
+
|
|
94
|
+
// 检查规格是否为空
|
|
95
|
+
if (!specs.length) {
|
|
96
|
+
errors.push('规格列表不能为空')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 检查SKU是否为空
|
|
100
|
+
if (!skus.length) {
|
|
101
|
+
errors.push('SKU列表不能为空')
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 检查规格名称是否重复
|
|
105
|
+
const specNames = specs.map(spec => spec.name)
|
|
106
|
+
const uniqueSpecNames = new Set(specNames)
|
|
107
|
+
if (uniqueSpecNames.size !== specNames.length) {
|
|
108
|
+
errors.push('规格名称不能重复')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// 检查每个规格的值是否重复
|
|
112
|
+
specs.forEach(spec => {
|
|
113
|
+
const valueNames = spec.values.map(value => value.name)
|
|
114
|
+
const uniqueValueNames = new Set(valueNames)
|
|
115
|
+
if (uniqueValueNames.size !== valueNames.length) {
|
|
116
|
+
errors.push(`规格"${spec.name}"的值不能重复`)
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
// 检查SKU规格组合是否完整
|
|
121
|
+
const expectedSpecCount = specs.length
|
|
122
|
+
skus.forEach((sku, index) => {
|
|
123
|
+
const specCount = Object.keys(sku.specs).length
|
|
124
|
+
if (specCount !== expectedSpecCount) {
|
|
125
|
+
errors.push(`SKU ${index + 1} 的规格数量不完整`)
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
// 检查SKU规格值是否有效
|
|
130
|
+
skus.forEach((sku, index) => {
|
|
131
|
+
Object.entries(sku.specs).forEach(([specName, specValue]) => {
|
|
132
|
+
const spec = specs.find(s => s.name === specName)
|
|
133
|
+
if (!spec) {
|
|
134
|
+
errors.push(`SKU ${index + 1} 包含不存在的规格"${specName}"`)
|
|
135
|
+
} else if (!spec.values.some(v => v.name === specValue)) {
|
|
136
|
+
errors.push(`SKU ${index + 1} 包含无效的规格值"${specValue}"`)
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
return errors
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* 根据规格值查找SKU
|
|
146
|
+
*/
|
|
147
|
+
export function findSkuBySpecs(
|
|
148
|
+
specs: Record<string, string>,
|
|
149
|
+
skus: SkuItem[]
|
|
150
|
+
): SkuItem | undefined {
|
|
151
|
+
return skus.find(sku => {
|
|
152
|
+
return Object.keys(specs).every(key => {
|
|
153
|
+
return sku.specs[key] === specs[key]
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 获取默认选中的规格
|
|
160
|
+
*/
|
|
161
|
+
export function getDefaultSelectedSpecs(skus: SkuItem[]) {
|
|
162
|
+
const selectedSpecs: Record<string, string> = {}
|
|
163
|
+
|
|
164
|
+
// 找到第一个有库存的SKU
|
|
165
|
+
const availableSku = skus.find(sku => sku.stock > 0 && !sku.disabled)
|
|
166
|
+
|
|
167
|
+
if (availableSku) {
|
|
168
|
+
return { ...availableSku.specs }
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return selectedSpecs
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* 检查规格组合是否完整
|
|
176
|
+
*/
|
|
177
|
+
export function isSpecsComplete(
|
|
178
|
+
selectedSpecs: Record<string, string>,
|
|
179
|
+
specs: _SkuSpec[]
|
|
180
|
+
) {
|
|
181
|
+
return specs.every(spec => selectedSpecs[spec.name])
|
|
182
|
+
}
|