@ruixinkeji/prism-ui 1.0.0 → 1.0.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.
Files changed (34) hide show
  1. package/README.md +1 -1
  2. package/components/PrismAIAssist/PrismAIAssist.vue +98 -98
  3. package/components/PrismAddressInput/PrismAddressInput.vue +597 -597
  4. package/components/PrismCityCascadeSelect/PrismCityCascadeSelect.vue +793 -793
  5. package/components/PrismCityPicker/PrismCityPicker.vue +1008 -1008
  6. package/components/PrismCitySelect/PrismCitySelect.vue +435 -435
  7. package/components/PrismCode/PrismCode.vue +749 -749
  8. package/components/PrismCodeInput/PrismCodeInput.vue +156 -156
  9. package/components/PrismDateTimePicker/PrismDateTimePicker.vue +953 -953
  10. package/components/PrismDropdown/PrismDropdown.vue +77 -77
  11. package/components/PrismGroupSticky/PrismGroupSticky.vue +352 -352
  12. package/components/PrismIdCardInput/PrismIdCardInput.vue +253 -253
  13. package/components/PrismImagePicker/PrismImagePicker.vue +457 -457
  14. package/components/PrismIndexBar/PrismIndexBar.vue +243 -243
  15. package/components/PrismLicensePlateInput/PrismLicensePlateInput.vue +1100 -1100
  16. package/components/PrismMusicPlayer/PrismMusicPlayer.vue +530 -530
  17. package/components/PrismNavBar/PrismNavBar.vue +199 -199
  18. package/components/PrismSecureInput/PrismSecureInput.vue +360 -360
  19. package/components/PrismSticky/PrismSticky.vue +173 -173
  20. package/components/PrismSwiper/PrismSwiper.vue +338 -338
  21. package/components/PrismSwitch/PrismSwitch.vue +202 -202
  22. package/components/PrismTabBar/PrismTabBar.vue +147 -147
  23. package/components/PrismTabs/PrismTabs.vue +49 -49
  24. package/components/PrismVoiceInput/PrismVoiceInput.vue +529 -529
  25. package/fonts/fa-brands-400.woff2 +0 -0
  26. package/fonts/fa-regular-400.woff2 +0 -0
  27. package/fonts/fa-solid-900.woff2 +0 -0
  28. package/fonts/fa-v4compatibility.woff2 +0 -0
  29. package/fonts/font-awesome.css +913 -0
  30. package/fonts/iconfont.woff2 +0 -0
  31. package/package.json +7 -1
  32. package/store/app.d.ts +21 -0
  33. package/store/app.js +68 -0
  34. package/styles/base.scss +2 -2
@@ -1,457 +1,457 @@
1
- <template>
2
- <view class="prism-image-picker" :class="{ 'dark-mode': appStore.isDarkMode }">
3
- <!-- 主图片区域 -->
4
- <view class="picker-main">
5
- <!-- 已选图片预览 -->
6
- <view class="image-preview" v-if="modelValue" @click="handleMainClick">
7
- <image class="preview-img" :src="modelValue" :mode="imageMode"></image>
8
- <view class="image-remove" @click.stop="removeImage" v-if="!disabled">
9
- <text class="fa fa-times"></text>
10
- </view>
11
- <view class="image-edit" v-if="!disabled">
12
- <text class="fa fa-camera"></text>
13
- </view>
14
- </view>
15
- <!-- 上传按钮 -->
16
- <view class="upload-btn" v-else @click="handleUpload" :class="{ 'disabled': disabled }">
17
- <text class="fa" :class="uploadIcon"></text>
18
- <text class="upload-text">{{ uploadText }}</text>
19
- </view>
20
- </view>
21
-
22
- <!-- 默认图片选择区域 -->
23
- <view class="default-images" v-if="defaultImages.length && showDefaults">
24
- <view class="default-title" v-if="defaultTitle">{{ defaultTitle }}</view>
25
- <scroll-view class="default-scroll" scroll-x>
26
- <view class="default-list">
27
- <view
28
- v-for="(img, index) in defaultImages"
29
- :key="index"
30
- class="default-item"
31
- :class="{ 'active': modelValue === img }"
32
- @click="selectDefault(img)"
33
- >
34
- <image :src="img" mode="aspectFill"></image>
35
- <view class="check-icon" v-if="modelValue === img">
36
- <text class="fa fa-check"></text>
37
- </view>
38
- </view>
39
- </view>
40
- </scroll-view>
41
- </view>
42
-
43
- <!-- 来源选择弹窗 -->
44
- <view class="source-popup" v-if="showSourcePopup" @click="showSourcePopup = false">
45
- <view class="source-content" @click.stop>
46
- <view class="source-title">选择图片</view>
47
- <view class="source-options">
48
- <view class="source-option" @click="chooseFromCamera">
49
- <view class="option-icon">
50
- <text class="fa fa-camera"></text>
51
- </view>
52
- <text>拍照</text>
53
- </view>
54
- <view class="source-option" @click="chooseFromAlbum">
55
- <view class="option-icon">
56
- <text class="fa fa-images"></text>
57
- </view>
58
- <text>相册</text>
59
- </view>
60
- </view>
61
- <view class="source-cancel" @click="showSourcePopup = false">取消</view>
62
- </view>
63
- </view>
64
- </view>
65
- </template>
66
-
67
- <script setup>
68
- import { ref } from 'vue';
69
- import { useAppStore } from '@/store/app';
70
-
71
- const props = defineProps({
72
- modelValue: {
73
- type: String,
74
- default: ''
75
- },
76
- // 默认图片列表
77
- defaultImages: {
78
- type: Array,
79
- default: () => []
80
- },
81
- // 是否显示默认图片
82
- showDefaults: {
83
- type: Boolean,
84
- default: true
85
- },
86
- // 默认图片区域标题
87
- defaultTitle: {
88
- type: String,
89
- default: ''
90
- },
91
- // 上传按钮图标
92
- uploadIcon: {
93
- type: String,
94
- default: 'fa-camera'
95
- },
96
- // 上传按钮文字
97
- uploadText: {
98
- type: String,
99
- default: '添加图片'
100
- },
101
- // 图片显示模式
102
- imageMode: {
103
- type: String,
104
- default: 'aspectFill'
105
- },
106
- // 是否显示来源选择弹窗
107
- showSourceSelect: {
108
- type: Boolean,
109
- default: false
110
- },
111
- // 图片来源:album/camera/both
112
- sourceType: {
113
- type: String,
114
- default: 'both',
115
- validator: (val) => ['album', 'camera', 'both'].includes(val)
116
- },
117
- // 是否压缩
118
- compressed: {
119
- type: Boolean,
120
- default: true
121
- },
122
- // 禁用状态
123
- disabled: {
124
- type: Boolean,
125
- default: false
126
- }
127
- });
128
-
129
- const emit = defineEmits(['update:modelValue', 'change', 'upload', 'remove']);
130
-
131
- const appStore = useAppStore();
132
- const showSourcePopup = ref(false);
133
-
134
- // 处理上传
135
- function handleUpload() {
136
- if (props.disabled) return;
137
-
138
- if (props.showSourceSelect && props.sourceType === 'both') {
139
- showSourcePopup.value = true;
140
- } else if (props.sourceType === 'camera') {
141
- chooseFromCamera();
142
- } else {
143
- chooseFromAlbum();
144
- }
145
- }
146
-
147
- // 点击主图片
148
- function handleMainClick() {
149
- if (props.disabled) return;
150
- handleUpload();
151
- }
152
-
153
- // 从相机选择
154
- function chooseFromCamera() {
155
- showSourcePopup.value = false;
156
- chooseImage(['camera']);
157
- }
158
-
159
- // 从相册选择
160
- function chooseFromAlbum() {
161
- showSourcePopup.value = false;
162
- chooseImage(['album']);
163
- }
164
-
165
- // 选择图片
166
- function chooseImage(sourceType) {
167
- uni.chooseImage({
168
- count: 1,
169
- sizeType: props.compressed ? ['compressed'] : ['original'],
170
- sourceType: sourceType,
171
- success: (res) => {
172
- const tempFilePath = res.tempFilePaths[0];
173
- emit('update:modelValue', tempFilePath);
174
- emit('change', tempFilePath);
175
- emit('upload', {
176
- tempFilePath,
177
- tempFile: res.tempFiles[0]
178
- });
179
- },
180
- fail: (err) => {
181
- console.log('选择图片失败', err);
182
- }
183
- });
184
- }
185
-
186
- // 选择默认图片
187
- function selectDefault(img) {
188
- if (props.disabled) return;
189
- emit('update:modelValue', img);
190
- emit('change', img);
191
- }
192
-
193
- // 移除图片
194
- function removeImage() {
195
- emit('update:modelValue', '');
196
- emit('change', '');
197
- emit('remove');
198
- }
199
- </script>
200
-
201
- <style lang="scss">
202
- .prism-image-picker {
203
- .picker-main {
204
- display: inline-block;
205
- }
206
-
207
- .image-preview {
208
- position: relative;
209
- width: 160rpx;
210
- height: 160rpx;
211
- border-radius: 16rpx;
212
- overflow: hidden;
213
- }
214
-
215
- .preview-img {
216
- width: 100%;
217
- height: 100%;
218
- }
219
-
220
- .image-remove {
221
- position: absolute;
222
- top: 8rpx;
223
- right: 8rpx;
224
- width: 40rpx;
225
- height: 40rpx;
226
- background: rgba(0, 0, 0, 0.5);
227
- border-radius: 50%;
228
- display: flex;
229
- align-items: center;
230
- justify-content: center;
231
-
232
- .fa {
233
- font-size: 20rpx;
234
- color: #FFFFFF;
235
- }
236
- }
237
-
238
- .image-edit {
239
- position: absolute;
240
- bottom: 0;
241
- left: 0;
242
- right: 0;
243
- height: 48rpx;
244
- background: rgba(0, 0, 0, 0.5);
245
- display: flex;
246
- align-items: center;
247
- justify-content: center;
248
-
249
- .fa {
250
- font-size: 24rpx;
251
- color: #FFFFFF;
252
- }
253
- }
254
-
255
- .upload-btn {
256
- width: 160rpx;
257
- height: 160rpx;
258
- background: var(--prism-bg-color-container, #F7F8FA);
259
- border: 2rpx dashed var(--prism-border-color-light, #E5E6EB);
260
- border-radius: 16rpx;
261
- display: flex;
262
- flex-direction: column;
263
- align-items: center;
264
- justify-content: center;
265
- gap: 12rpx;
266
- transition: all 0.2s;
267
-
268
- .fa {
269
- font-size: 48rpx;
270
- color: var(--prism-text-placeholder, #C9CDD4);
271
- }
272
-
273
- .upload-text {
274
- font-size: 24rpx;
275
- color: var(--prism-text-secondary, #86909C);
276
- }
277
-
278
- &:active {
279
- background: var(--prism-primary-light, rgba(52, 120, 246, 0.08));
280
- border-color: var(--prism-primary-color, #3478F6);
281
-
282
- .fa {
283
- color: var(--prism-primary-color, #3478F6);
284
- }
285
- }
286
-
287
- &.disabled {
288
- opacity: 0.5;
289
- pointer-events: none;
290
- }
291
- }
292
-
293
- // 默认图片区域
294
- .default-images {
295
- margin-top: 24rpx;
296
- }
297
-
298
- .default-title {
299
- font-size: 26rpx;
300
- color: var(--prism-text-secondary, #86909C);
301
- margin-bottom: 16rpx;
302
- }
303
-
304
- .default-scroll {
305
- white-space: nowrap;
306
-
307
- &::-webkit-scrollbar {
308
- display: none;
309
- }
310
- }
311
-
312
- .default-list {
313
- display: inline-flex;
314
- gap: 16rpx;
315
- }
316
-
317
- .default-item {
318
- position: relative;
319
- width: 96rpx;
320
- height: 96rpx;
321
- border-radius: 12rpx;
322
- overflow: hidden;
323
- border: 2rpx solid transparent;
324
- flex-shrink: 0;
325
- transition: all 0.2s;
326
-
327
- image {
328
- width: 100%;
329
- height: 100%;
330
- }
331
-
332
- &.active {
333
- border-color: var(--prism-primary-color, #3478F6);
334
- }
335
-
336
- .check-icon {
337
- position: absolute;
338
- bottom: 0;
339
- right: 0;
340
- width: 32rpx;
341
- height: 32rpx;
342
- background: var(--prism-primary-color, #3478F6);
343
- border-radius: 8rpx 0 0 0;
344
- display: flex;
345
- align-items: center;
346
- justify-content: center;
347
-
348
- .fa {
349
- font-size: 18rpx;
350
- color: #FFFFFF;
351
- }
352
- }
353
- }
354
-
355
- // 来源选择弹窗
356
- .source-popup {
357
- position: fixed;
358
- top: 0;
359
- left: 0;
360
- right: 0;
361
- bottom: 0;
362
- background: var(--prism-mask-bg, rgba(0, 0, 0, 0.5));
363
- display: flex;
364
- align-items: flex-end;
365
- justify-content: center;
366
- z-index: 9999;
367
- }
368
-
369
- .source-content {
370
- width: 100%;
371
- background: var(--prism-bg-color-card, #FFFFFF);
372
- border-radius: 24rpx 24rpx 0 0;
373
- padding: 32rpx;
374
- padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
375
- }
376
-
377
- .source-title {
378
- font-size: 32rpx;
379
- font-weight: 600;
380
- color: var(--prism-text-primary, #1D2129);
381
- text-align: center;
382
- margin-bottom: 32rpx;
383
- }
384
-
385
- .source-options {
386
- display: flex;
387
- gap: 24rpx;
388
- }
389
-
390
- .source-option {
391
- flex: 1;
392
- height: 160rpx;
393
- background: var(--prism-bg-color-container, #F7F8FA);
394
- border-radius: 16rpx;
395
- display: flex;
396
- flex-direction: column;
397
- align-items: center;
398
- justify-content: center;
399
- gap: 16rpx;
400
- transition: all 0.2s;
401
-
402
- .option-icon {
403
- width: 64rpx;
404
- height: 64rpx;
405
- background: var(--prism-primary-light, rgba(52, 120, 246, 0.1));
406
- border-radius: 50%;
407
- display: flex;
408
- align-items: center;
409
- justify-content: center;
410
-
411
- .fa {
412
- font-size: 32rpx;
413
- color: var(--prism-primary-color, #3478F6);
414
- }
415
- }
416
-
417
- text:last-child {
418
- font-size: 28rpx;
419
- color: var(--prism-text-primary, #1D2129);
420
- }
421
-
422
- &:active {
423
- background: var(--prism-primary-light, rgba(52, 120, 246, 0.1));
424
- }
425
- }
426
-
427
- .source-cancel {
428
- margin-top: 24rpx;
429
- height: 88rpx;
430
- display: flex;
431
- align-items: center;
432
- justify-content: center;
433
- font-size: 32rpx;
434
- color: var(--prism-text-secondary, #86909C);
435
- }
436
- }
437
-
438
- // 深色模式
439
- .dark-mode.prism-image-picker {
440
- .upload-btn {
441
- background: var(--prism-bg-color-container, #2A2A2A);
442
- border-color: rgba(255, 255, 255, 0.15);
443
- }
444
-
445
- .source-content {
446
- background: var(--prism-bg-color-card, #1A1A1A);
447
- }
448
-
449
- .source-option {
450
- background: var(--prism-bg-color-container, #2A2A2A);
451
-
452
- &:active {
453
- background: rgba(52, 120, 246, 0.15);
454
- }
455
- }
456
- }
457
- </style>
1
+ <template>
2
+ <view class="prism-image-picker" :class="{ 'dark-mode': appStore.isDarkMode }">
3
+ <!-- 主图片区域 -->
4
+ <view class="picker-main">
5
+ <!-- 已选图片预览 -->
6
+ <view class="image-preview" v-if="modelValue" @click="handleMainClick">
7
+ <image class="preview-img" :src="modelValue" :mode="imageMode"></image>
8
+ <view class="image-remove" @click.stop="removeImage" v-if="!disabled">
9
+ <text class="fa fa-times"></text>
10
+ </view>
11
+ <view class="image-edit" v-if="!disabled">
12
+ <text class="fa fa-camera"></text>
13
+ </view>
14
+ </view>
15
+ <!-- 上传按钮 -->
16
+ <view class="upload-btn" v-else @click="handleUpload" :class="{ 'disabled': disabled }">
17
+ <text class="fa" :class="uploadIcon"></text>
18
+ <text class="upload-text">{{ uploadText }}</text>
19
+ </view>
20
+ </view>
21
+
22
+ <!-- 默认图片选择区域 -->
23
+ <view class="default-images" v-if="defaultImages.length && showDefaults">
24
+ <view class="default-title" v-if="defaultTitle">{{ defaultTitle }}</view>
25
+ <scroll-view class="default-scroll" scroll-x>
26
+ <view class="default-list">
27
+ <view
28
+ v-for="(img, index) in defaultImages"
29
+ :key="index"
30
+ class="default-item"
31
+ :class="{ 'active': modelValue === img }"
32
+ @click="selectDefault(img)"
33
+ >
34
+ <image :src="img" mode="aspectFill"></image>
35
+ <view class="check-icon" v-if="modelValue === img">
36
+ <text class="fa fa-check"></text>
37
+ </view>
38
+ </view>
39
+ </view>
40
+ </scroll-view>
41
+ </view>
42
+
43
+ <!-- 来源选择弹窗 -->
44
+ <view class="source-popup" v-if="showSourcePopup" @click="showSourcePopup = false">
45
+ <view class="source-content" @click.stop>
46
+ <view class="source-title">选择图片</view>
47
+ <view class="source-options">
48
+ <view class="source-option" @click="chooseFromCamera">
49
+ <view class="option-icon">
50
+ <text class="fa fa-camera"></text>
51
+ </view>
52
+ <text>拍照</text>
53
+ </view>
54
+ <view class="source-option" @click="chooseFromAlbum">
55
+ <view class="option-icon">
56
+ <text class="fa fa-images"></text>
57
+ </view>
58
+ <text>相册</text>
59
+ </view>
60
+ </view>
61
+ <view class="source-cancel" @click="showSourcePopup = false">取消</view>
62
+ </view>
63
+ </view>
64
+ </view>
65
+ </template>
66
+
67
+ <script setup>
68
+ import { ref } from 'vue';
69
+ import { useAppStore } from '@/store/app';
70
+
71
+ const props = defineProps({
72
+ modelValue: {
73
+ type: String,
74
+ default: ''
75
+ },
76
+ // 默认图片列表
77
+ defaultImages: {
78
+ type: Array,
79
+ default: () => []
80
+ },
81
+ // 是否显示默认图片
82
+ showDefaults: {
83
+ type: Boolean,
84
+ default: true
85
+ },
86
+ // 默认图片区域标题
87
+ defaultTitle: {
88
+ type: String,
89
+ default: ''
90
+ },
91
+ // 上传按钮图标
92
+ uploadIcon: {
93
+ type: String,
94
+ default: 'fa-camera'
95
+ },
96
+ // 上传按钮文字
97
+ uploadText: {
98
+ type: String,
99
+ default: '添加图片'
100
+ },
101
+ // 图片显示模式
102
+ imageMode: {
103
+ type: String,
104
+ default: 'aspectFill'
105
+ },
106
+ // 是否显示来源选择弹窗
107
+ showSourceSelect: {
108
+ type: Boolean,
109
+ default: false
110
+ },
111
+ // 图片来源:album/camera/both
112
+ sourceType: {
113
+ type: String,
114
+ default: 'both',
115
+ validator: (val) => ['album', 'camera', 'both'].includes(val)
116
+ },
117
+ // 是否压缩
118
+ compressed: {
119
+ type: Boolean,
120
+ default: true
121
+ },
122
+ // 禁用状态
123
+ disabled: {
124
+ type: Boolean,
125
+ default: false
126
+ }
127
+ });
128
+
129
+ const emit = defineEmits(['update:modelValue', 'change', 'upload', 'remove']);
130
+
131
+ const appStore = useAppStore();
132
+ const showSourcePopup = ref(false);
133
+
134
+ // 处理上传
135
+ function handleUpload() {
136
+ if (props.disabled) return;
137
+
138
+ if (props.showSourceSelect && props.sourceType === 'both') {
139
+ showSourcePopup.value = true;
140
+ } else if (props.sourceType === 'camera') {
141
+ chooseFromCamera();
142
+ } else {
143
+ chooseFromAlbum();
144
+ }
145
+ }
146
+
147
+ // 点击主图片
148
+ function handleMainClick() {
149
+ if (props.disabled) return;
150
+ handleUpload();
151
+ }
152
+
153
+ // 从相机选择
154
+ function chooseFromCamera() {
155
+ showSourcePopup.value = false;
156
+ chooseImage(['camera']);
157
+ }
158
+
159
+ // 从相册选择
160
+ function chooseFromAlbum() {
161
+ showSourcePopup.value = false;
162
+ chooseImage(['album']);
163
+ }
164
+
165
+ // 选择图片
166
+ function chooseImage(sourceType) {
167
+ uni.chooseImage({
168
+ count: 1,
169
+ sizeType: props.compressed ? ['compressed'] : ['original'],
170
+ sourceType: sourceType,
171
+ success: (res) => {
172
+ const tempFilePath = res.tempFilePaths[0];
173
+ emit('update:modelValue', tempFilePath);
174
+ emit('change', tempFilePath);
175
+ emit('upload', {
176
+ tempFilePath,
177
+ tempFile: res.tempFiles[0]
178
+ });
179
+ },
180
+ fail: (err) => {
181
+ console.log('选择图片失败', err);
182
+ }
183
+ });
184
+ }
185
+
186
+ // 选择默认图片
187
+ function selectDefault(img) {
188
+ if (props.disabled) return;
189
+ emit('update:modelValue', img);
190
+ emit('change', img);
191
+ }
192
+
193
+ // 移除图片
194
+ function removeImage() {
195
+ emit('update:modelValue', '');
196
+ emit('change', '');
197
+ emit('remove');
198
+ }
199
+ </script>
200
+
201
+ <style lang="scss">
202
+ .prism-image-picker {
203
+ .picker-main {
204
+ display: inline-block;
205
+ }
206
+
207
+ .image-preview {
208
+ position: relative;
209
+ width: 160rpx;
210
+ height: 160rpx;
211
+ border-radius: 16rpx;
212
+ overflow: hidden;
213
+ }
214
+
215
+ .preview-img {
216
+ width: 100%;
217
+ height: 100%;
218
+ }
219
+
220
+ .image-remove {
221
+ position: absolute;
222
+ top: 8rpx;
223
+ right: 8rpx;
224
+ width: 40rpx;
225
+ height: 40rpx;
226
+ background: rgba(0, 0, 0, 0.5);
227
+ border-radius: 50%;
228
+ display: flex;
229
+ align-items: center;
230
+ justify-content: center;
231
+
232
+ .fa {
233
+ font-size: 20rpx;
234
+ color: #FFFFFF;
235
+ }
236
+ }
237
+
238
+ .image-edit {
239
+ position: absolute;
240
+ bottom: 0;
241
+ left: 0;
242
+ right: 0;
243
+ height: 48rpx;
244
+ background: rgba(0, 0, 0, 0.5);
245
+ display: flex;
246
+ align-items: center;
247
+ justify-content: center;
248
+
249
+ .fa {
250
+ font-size: 24rpx;
251
+ color: #FFFFFF;
252
+ }
253
+ }
254
+
255
+ .upload-btn {
256
+ width: 160rpx;
257
+ height: 160rpx;
258
+ background: var(--prism-bg-color-container, #F7F8FA);
259
+ border: 2rpx dashed var(--prism-border-color-light, #E5E6EB);
260
+ border-radius: 16rpx;
261
+ display: flex;
262
+ flex-direction: column;
263
+ align-items: center;
264
+ justify-content: center;
265
+ gap: 12rpx;
266
+ transition: all 0.2s;
267
+
268
+ .fa {
269
+ font-size: 48rpx;
270
+ color: var(--prism-text-placeholder, #C9CDD4);
271
+ }
272
+
273
+ .upload-text {
274
+ font-size: 24rpx;
275
+ color: var(--prism-text-secondary, #86909C);
276
+ }
277
+
278
+ &:active {
279
+ background: var(--prism-primary-light, rgba(52, 120, 246, 0.08));
280
+ border-color: var(--prism-primary-color, #3478F6);
281
+
282
+ .fa {
283
+ color: var(--prism-primary-color, #3478F6);
284
+ }
285
+ }
286
+
287
+ &.disabled {
288
+ opacity: 0.5;
289
+ pointer-events: none;
290
+ }
291
+ }
292
+
293
+ // 默认图片区域
294
+ .default-images {
295
+ margin-top: 24rpx;
296
+ }
297
+
298
+ .default-title {
299
+ font-size: 26rpx;
300
+ color: var(--prism-text-secondary, #86909C);
301
+ margin-bottom: 16rpx;
302
+ }
303
+
304
+ .default-scroll {
305
+ white-space: nowrap;
306
+
307
+ &::-webkit-scrollbar {
308
+ display: none;
309
+ }
310
+ }
311
+
312
+ .default-list {
313
+ display: inline-flex;
314
+ gap: 16rpx;
315
+ }
316
+
317
+ .default-item {
318
+ position: relative;
319
+ width: 96rpx;
320
+ height: 96rpx;
321
+ border-radius: 12rpx;
322
+ overflow: hidden;
323
+ border: 2rpx solid transparent;
324
+ flex-shrink: 0;
325
+ transition: all 0.2s;
326
+
327
+ image {
328
+ width: 100%;
329
+ height: 100%;
330
+ }
331
+
332
+ &.active {
333
+ border-color: var(--prism-primary-color, #3478F6);
334
+ }
335
+
336
+ .check-icon {
337
+ position: absolute;
338
+ bottom: 0;
339
+ right: 0;
340
+ width: 32rpx;
341
+ height: 32rpx;
342
+ background: var(--prism-primary-color, #3478F6);
343
+ border-radius: 8rpx 0 0 0;
344
+ display: flex;
345
+ align-items: center;
346
+ justify-content: center;
347
+
348
+ .fa {
349
+ font-size: 18rpx;
350
+ color: #FFFFFF;
351
+ }
352
+ }
353
+ }
354
+
355
+ // 来源选择弹窗
356
+ .source-popup {
357
+ position: fixed;
358
+ top: 0;
359
+ left: 0;
360
+ right: 0;
361
+ bottom: 0;
362
+ background: var(--prism-mask-bg, rgba(0, 0, 0, 0.5));
363
+ display: flex;
364
+ align-items: flex-end;
365
+ justify-content: center;
366
+ z-index: 9999;
367
+ }
368
+
369
+ .source-content {
370
+ width: 100%;
371
+ background: var(--prism-bg-color-card, #FFFFFF);
372
+ border-radius: 24rpx 24rpx 0 0;
373
+ padding: 32rpx;
374
+ padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
375
+ }
376
+
377
+ .source-title {
378
+ font-size: 32rpx;
379
+ font-weight: 600;
380
+ color: var(--prism-text-primary, #1D2129);
381
+ text-align: center;
382
+ margin-bottom: 32rpx;
383
+ }
384
+
385
+ .source-options {
386
+ display: flex;
387
+ gap: 24rpx;
388
+ }
389
+
390
+ .source-option {
391
+ flex: 1;
392
+ height: 160rpx;
393
+ background: var(--prism-bg-color-container, #F7F8FA);
394
+ border-radius: 16rpx;
395
+ display: flex;
396
+ flex-direction: column;
397
+ align-items: center;
398
+ justify-content: center;
399
+ gap: 16rpx;
400
+ transition: all 0.2s;
401
+
402
+ .option-icon {
403
+ width: 64rpx;
404
+ height: 64rpx;
405
+ background: var(--prism-primary-light, rgba(52, 120, 246, 0.1));
406
+ border-radius: 50%;
407
+ display: flex;
408
+ align-items: center;
409
+ justify-content: center;
410
+
411
+ .fa {
412
+ font-size: 32rpx;
413
+ color: var(--prism-primary-color, #3478F6);
414
+ }
415
+ }
416
+
417
+ text:last-child {
418
+ font-size: 28rpx;
419
+ color: var(--prism-text-primary, #1D2129);
420
+ }
421
+
422
+ &:active {
423
+ background: var(--prism-primary-light, rgba(52, 120, 246, 0.1));
424
+ }
425
+ }
426
+
427
+ .source-cancel {
428
+ margin-top: 24rpx;
429
+ height: 88rpx;
430
+ display: flex;
431
+ align-items: center;
432
+ justify-content: center;
433
+ font-size: 32rpx;
434
+ color: var(--prism-text-secondary, #86909C);
435
+ }
436
+ }
437
+
438
+ // 深色模式
439
+ .dark-mode.prism-image-picker {
440
+ .upload-btn {
441
+ background: var(--prism-bg-color-container, #2A2A2A);
442
+ border-color: rgba(255, 255, 255, 0.15);
443
+ }
444
+
445
+ .source-content {
446
+ background: var(--prism-bg-color-card, #1A1A1A);
447
+ }
448
+
449
+ .source-option {
450
+ background: var(--prism-bg-color-container, #2A2A2A);
451
+
452
+ &:active {
453
+ background: rgba(52, 120, 246, 0.15);
454
+ }
455
+ }
456
+ }
457
+ </style>