@ruixinkeji/prism-ui 1.0.0

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 (48) hide show
  1. package/README.md +141 -0
  2. package/components/PrismAIAssist/PrismAIAssist.vue +98 -0
  3. package/components/PrismAddressInput/PrismAddressInput.vue +597 -0
  4. package/components/PrismCityCascadeSelect/PrismCityCascadeSelect.vue +793 -0
  5. package/components/PrismCityPicker/PrismCityPicker.vue +1008 -0
  6. package/components/PrismCitySelect/PrismCitySelect.vue +435 -0
  7. package/components/PrismCode/PrismCode.vue +749 -0
  8. package/components/PrismCodeInput/PrismCodeInput.vue +156 -0
  9. package/components/PrismDateTimePicker/PrismDateTimePicker.vue +953 -0
  10. package/components/PrismDropdown/PrismDropdown.vue +77 -0
  11. package/components/PrismGroupSticky/PrismGroupSticky.vue +352 -0
  12. package/components/PrismIdCardInput/PrismIdCardInput.vue +253 -0
  13. package/components/PrismImagePicker/PrismImagePicker.vue +457 -0
  14. package/components/PrismIndexBar/PrismIndexBar.vue +243 -0
  15. package/components/PrismLicensePlateInput/PrismLicensePlateInput.vue +1100 -0
  16. package/components/PrismMusicPlayer/PrismMusicPlayer.vue +530 -0
  17. package/components/PrismNavBar/PrismNavBar.vue +199 -0
  18. package/components/PrismSecureInput/PrismSecureInput.vue +360 -0
  19. package/components/PrismSticky/PrismSticky.vue +173 -0
  20. package/components/PrismSwiper/PrismSwiper.vue +339 -0
  21. package/components/PrismSwitch/PrismSwitch.vue +202 -0
  22. package/components/PrismTabBar/PrismTabBar.vue +147 -0
  23. package/components/PrismTabs/PrismTabs.vue +49 -0
  24. package/components/PrismVoiceInput/PrismVoiceInput.vue +529 -0
  25. package/index.d.ts +24 -0
  26. package/index.esm.js +25 -0
  27. package/index.js +25 -0
  28. package/package.json +89 -0
  29. package/styles/base.scss +227 -0
  30. package/styles/button.scss +120 -0
  31. package/styles/card.scss +306 -0
  32. package/styles/colors.scss +877 -0
  33. package/styles/data.scss +1229 -0
  34. package/styles/effects.scss +407 -0
  35. package/styles/feedback.scss +698 -0
  36. package/styles/form.scss +1574 -0
  37. package/styles/index.scss +46 -0
  38. package/styles/list.scss +184 -0
  39. package/styles/navigation.scss +554 -0
  40. package/styles/overlay.scss +182 -0
  41. package/styles/utilities.scss +134 -0
  42. package/styles/variables.scss +138 -0
  43. package/theme/blue.scss +36 -0
  44. package/theme/cyan.scss +32 -0
  45. package/theme/green.scss +32 -0
  46. package/theme/orange.scss +32 -0
  47. package/theme/purple.scss +32 -0
  48. package/theme/red.scss +32 -0
@@ -0,0 +1,793 @@
1
+ <template>
2
+ <view class="prism-city-cascade-select" :class="{ 'dark-mode': appStore.isDarkMode }">
3
+ <!-- 触发器 -->
4
+ <view class="select-trigger" @click="openSelect">
5
+ <slot>
6
+ <view class="prism-select-box">
7
+ <text :class="{ 'placeholder': !displayValue, 'select-text': displayValue }">
8
+ {{ displayValue || placeholder }}
9
+ </text>
10
+ <text class="select-arrow fa fa-map-marker-alt"></text>
11
+ </view>
12
+ </slot>
13
+ </view>
14
+
15
+ <!-- 全屏选择页面 -->
16
+ <view class="select-page" v-if="showSelect">
17
+ <!-- 头部 -->
18
+ <view class="page-header">
19
+ <view class="header-back" @click="handleBack">
20
+ <text class="fa fa-arrow-left"></text>
21
+ </view>
22
+ <view class="header-title">{{ title }}</view>
23
+ <view class="header-right"></view>
24
+ </view>
25
+
26
+ <!-- 搜索框 -->
27
+ <view class="search-box" v-if="showSearch">
28
+ <view class="search-input-wrap">
29
+ <text class="fa fa-search"></text>
30
+ <input
31
+ class="search-input"
32
+ type="text"
33
+ v-model="searchKeyword"
34
+ :placeholder="searchPlaceholder"
35
+ @input="onSearch"
36
+ />
37
+ <text class="fa fa-times-circle" v-if="searchKeyword" @click="clearSearch"></text>
38
+ </view>
39
+ </view>
40
+
41
+ <!-- 内容区域 -->
42
+ <scroll-view class="page-content" scroll-y @touchmove.stop>
43
+ <!-- 搜索结果 -->
44
+ <view class="search-results" v-if="searchKeyword && searchResults.length">
45
+ <view
46
+ v-for="item in searchResults"
47
+ :key="item.code"
48
+ class="result-item"
49
+ @click="selectCity(item)"
50
+ >
51
+ <text class="item-name">{{ item.fullName || item.name }}</text>
52
+ </view>
53
+ </view>
54
+
55
+ <!-- 搜索无结果 -->
56
+ <view class="search-empty" v-else-if="searchKeyword && !searchResults.length">
57
+ <text class="fa fa-search"></text>
58
+ <text>未找到相关城市</text>
59
+ </view>
60
+
61
+ <!-- 正常列表 -->
62
+ <view v-else>
63
+ <!-- 热门城市 -->
64
+ <view class="hot-cities" v-if="showHotCities && currentLevel === 0">
65
+ <view class="section-title">
66
+ <text class="fa fa-fire"></text>
67
+ <text>热门城市</text>
68
+ </view>
69
+ <view class="hot-cities-grid">
70
+ <view
71
+ v-for="city in hotCities"
72
+ :key="city.code"
73
+ class="hot-city-item"
74
+ @click="selectCity(city)"
75
+ >
76
+ {{ city.name }}
77
+ </view>
78
+ </view>
79
+ </view>
80
+
81
+ <!-- 已选择的面包屑 -->
82
+ <view class="breadcrumb" v-if="tempSelected.length">
83
+ <view class="section-title">
84
+ <text>当前选择</text>
85
+ </view>
86
+ <view class="breadcrumb-content">
87
+ <view
88
+ v-for="(item, index) in tempSelected"
89
+ :key="index"
90
+ class="breadcrumb-item"
91
+ @click="backToLevel(index)"
92
+ >
93
+ <text>{{ item.name }}</text>
94
+ <text class="fa fa-chevron-right" v-if="index < tempSelected.length - 1"></text>
95
+ </view>
96
+ <view class="breadcrumb-clear" @click="clearSelection">
97
+ <text class="fa fa-times"></text>
98
+ </view>
99
+ </view>
100
+ </view>
101
+
102
+ <!-- 全部城市列表 -->
103
+ <view class="city-list">
104
+ <view class="section-title" v-if="currentLevel === 0">
105
+ <text>全部省份</text>
106
+ </view>
107
+ <view class="section-title" v-else>
108
+ <text>请选择{{ levelNames[currentLevel] }}</text>
109
+ </view>
110
+ <view
111
+ v-for="item in currentLevelList"
112
+ :key="item.code"
113
+ class="city-item"
114
+ :class="{ 'selected': isItemSelected(item) }"
115
+ @click="selectItem(item)"
116
+ >
117
+ <text class="item-name">{{ item.name }}</text>
118
+ <text class="fa fa-chevron-right item-arrow" v-if="hasChildren(item)"></text>
119
+ <text class="fa fa-check item-check" v-else-if="isItemSelected(item)"></text>
120
+ </view>
121
+ </view>
122
+ </view>
123
+ </scroll-view>
124
+ </view>
125
+ </view>
126
+ </template>
127
+
128
+ <script setup>
129
+ import { ref, computed, watch } from 'vue';
130
+ import { useAppStore } from '@/store/app';
131
+
132
+ const props = defineProps({
133
+ modelValue: {
134
+ type: Array,
135
+ default: () => []
136
+ },
137
+ // 城市数据
138
+ data: {
139
+ type: Array,
140
+ default: () => []
141
+ },
142
+ level: {
143
+ type: Number,
144
+ default: 2
145
+ },
146
+ placeholder: {
147
+ type: String,
148
+ default: '请选择城市'
149
+ },
150
+ title: {
151
+ type: String,
152
+ default: '选择城市'
153
+ },
154
+ separator: {
155
+ type: String,
156
+ default: '/'
157
+ },
158
+ showSearch: {
159
+ type: Boolean,
160
+ default: true
161
+ },
162
+ searchPlaceholder: {
163
+ type: String,
164
+ default: '搜索城市'
165
+ },
166
+ showHotCities: {
167
+ type: Boolean,
168
+ default: true
169
+ },
170
+ hotCities: {
171
+ type: Array,
172
+ default: () => [
173
+ { name: '北京', code: '110000' },
174
+ { name: '上海', code: '310000' },
175
+ { name: '广州', code: '440100' },
176
+ { name: '深圳', code: '440300' },
177
+ { name: '杭州', code: '330100' },
178
+ { name: '成都', code: '510100' },
179
+ { name: '武汉', code: '420100' },
180
+ { name: '南京', code: '320100' }
181
+ ]
182
+ },
183
+ disabled: {
184
+ type: Boolean,
185
+ default: false
186
+ }
187
+ });
188
+
189
+ const emit = defineEmits(['update:modelValue', 'change', 'confirm', 'cancel']);
190
+
191
+ const appStore = useAppStore();
192
+ const showSelect = ref(false);
193
+ const tempSelected = ref([]);
194
+ const currentLevel = ref(0);
195
+ const searchKeyword = ref('');
196
+ const searchResults = ref([]);
197
+
198
+ const levelNames = ['省份', '城市', '区县'];
199
+
200
+ // 默认地区数据
201
+ const defaultData = [
202
+ {
203
+ code: '110000',
204
+ name: '北京市',
205
+ children: [
206
+ {
207
+ code: '110100',
208
+ name: '北京市',
209
+ children: [
210
+ { code: '110101', name: '东城区' },
211
+ { code: '110102', name: '西城区' },
212
+ { code: '110105', name: '朝阳区' },
213
+ { code: '110106', name: '丰台区' },
214
+ { code: '110108', name: '海淀区' },
215
+ { code: '110112', name: '通州区' },
216
+ { code: '110114', name: '昌平区' },
217
+ { code: '110115', name: '大兴区' }
218
+ ]
219
+ }
220
+ ]
221
+ },
222
+ {
223
+ code: '120000',
224
+ name: '天津市',
225
+ children: [
226
+ {
227
+ code: '120100',
228
+ name: '天津市',
229
+ children: [
230
+ { code: '120101', name: '和平区' },
231
+ { code: '120102', name: '河东区' },
232
+ { code: '120103', name: '河西区' },
233
+ { code: '120104', name: '南开区' }
234
+ ]
235
+ }
236
+ ]
237
+ },
238
+ {
239
+ code: '310000',
240
+ name: '上海市',
241
+ children: [
242
+ {
243
+ code: '310100',
244
+ name: '上海市',
245
+ children: [
246
+ { code: '310101', name: '黄浦区' },
247
+ { code: '310104', name: '徐汇区' },
248
+ { code: '310106', name: '静安区' },
249
+ { code: '310110', name: '杨浦区' },
250
+ { code: '310112', name: '闵行区' },
251
+ { code: '310115', name: '浦东新区' }
252
+ ]
253
+ }
254
+ ]
255
+ },
256
+ {
257
+ code: '500000',
258
+ name: '重庆市',
259
+ children: [
260
+ {
261
+ code: '500100',
262
+ name: '重庆市',
263
+ children: [
264
+ { code: '500101', name: '万州区' },
265
+ { code: '500103', name: '渝中区' },
266
+ { code: '500104', name: '大渡口区' },
267
+ { code: '500105', name: '江北区' }
268
+ ]
269
+ }
270
+ ]
271
+ },
272
+ {
273
+ code: '440000',
274
+ name: '广东省',
275
+ children: [
276
+ {
277
+ code: '440100',
278
+ name: '广州市',
279
+ children: [
280
+ { code: '440104', name: '越秀区' },
281
+ { code: '440106', name: '天河区' },
282
+ { code: '440111', name: '白云区' },
283
+ { code: '440113', name: '番禺区' }
284
+ ]
285
+ },
286
+ {
287
+ code: '440300',
288
+ name: '深圳市',
289
+ children: [
290
+ { code: '440304', name: '福田区' },
291
+ { code: '440305', name: '南山区' },
292
+ { code: '440306', name: '宝安区' },
293
+ { code: '440307', name: '龙岗区' }
294
+ ]
295
+ }
296
+ ]
297
+ },
298
+ {
299
+ code: '330000',
300
+ name: '浙江省',
301
+ children: [
302
+ {
303
+ code: '330100',
304
+ name: '杭州市',
305
+ children: [
306
+ { code: '330102', name: '上城区' },
307
+ { code: '330106', name: '西湖区' },
308
+ { code: '330108', name: '滨江区' },
309
+ { code: '330109', name: '萧山区' }
310
+ ]
311
+ },
312
+ {
313
+ code: '330200',
314
+ name: '宁波市',
315
+ children: [
316
+ { code: '330203', name: '海曙区' },
317
+ { code: '330205', name: '江北区' }
318
+ ]
319
+ }
320
+ ]
321
+ },
322
+ {
323
+ code: '320000',
324
+ name: '江苏省',
325
+ children: [
326
+ {
327
+ code: '320100',
328
+ name: '南京市',
329
+ children: [
330
+ { code: '320102', name: '玄武区' },
331
+ { code: '320104', name: '秦淮区' },
332
+ { code: '320106', name: '鼓楼区' }
333
+ ]
334
+ },
335
+ {
336
+ code: '320500',
337
+ name: '苏州市',
338
+ children: [
339
+ { code: '320505', name: '虎丘区' },
340
+ { code: '320508', name: '姑苏区' }
341
+ ]
342
+ }
343
+ ]
344
+ },
345
+ {
346
+ code: '510000',
347
+ name: '四川省',
348
+ children: [
349
+ {
350
+ code: '510100',
351
+ name: '成都市',
352
+ children: [
353
+ { code: '510104', name: '锦江区' },
354
+ { code: '510105', name: '青羊区' },
355
+ { code: '510107', name: '武侯区' },
356
+ { code: '510108', name: '成华区' }
357
+ ]
358
+ }
359
+ ]
360
+ },
361
+ {
362
+ code: '420000',
363
+ name: '湖北省',
364
+ children: [
365
+ {
366
+ code: '420100',
367
+ name: '武汉市',
368
+ children: [
369
+ { code: '420102', name: '江岸区' },
370
+ { code: '420103', name: '江汉区' },
371
+ { code: '420104', name: '硚口区' },
372
+ { code: '420105', name: '汉阳区' }
373
+ ]
374
+ }
375
+ ]
376
+ }
377
+ ];
378
+
379
+ // 使用传入的数据或默认数据
380
+ const regionData = computed(() => {
381
+ return props.data && props.data.length ? props.data : defaultData;
382
+ });
383
+
384
+ // 显示值
385
+ const displayValue = computed(() => {
386
+ if (!props.modelValue || !props.modelValue.length) return '';
387
+ return props.modelValue.map(item => item.name).join(props.separator);
388
+ });
389
+
390
+ // 当前层级列表
391
+ const currentLevelList = computed(() => {
392
+ if (currentLevel.value === 0) {
393
+ return regionData.value;
394
+ }
395
+ const parent = tempSelected.value[currentLevel.value - 1];
396
+ return parent?.children || [];
397
+ });
398
+
399
+ // 打开选择页面
400
+ function openSelect() {
401
+ if (props.disabled) return;
402
+ showSelect.value = true;
403
+ tempSelected.value = [];
404
+ currentLevel.value = 0;
405
+ searchKeyword.value = '';
406
+ // 隐藏 tabBar
407
+ // #ifdef H5
408
+ try { uni.hideTabBar(); } catch (e) {}
409
+ // #endif
410
+ }
411
+
412
+ // 返回处理
413
+ function handleBack() {
414
+ if (currentLevel.value > 0) {
415
+ currentLevel.value--;
416
+ tempSelected.value = tempSelected.value.slice(0, currentLevel.value);
417
+ } else {
418
+ showSelect.value = false;
419
+ emit('cancel');
420
+ // 显示 tabBar
421
+ // #ifdef H5
422
+ try { uni.showTabBar(); } catch (e) {}
423
+ // #endif
424
+ }
425
+ }
426
+
427
+ // 选择项目
428
+ function selectItem(item) {
429
+ if (hasChildren(item) && currentLevel.value < props.level - 1) {
430
+ tempSelected.value = tempSelected.value.slice(0, currentLevel.value);
431
+ tempSelected.value.push({ code: item.code, name: item.name, children: item.children });
432
+ currentLevel.value++;
433
+ } else {
434
+ tempSelected.value = tempSelected.value.slice(0, currentLevel.value);
435
+ tempSelected.value.push({ code: item.code, name: item.name });
436
+ confirmSelect();
437
+ }
438
+ }
439
+
440
+ // 选择热门城市 - 查找完整路径
441
+ function selectCity(city) {
442
+ const path = findCityPath(city.code);
443
+ if (path.length) {
444
+ emit('update:modelValue', path);
445
+ emit('change', path);
446
+ emit('confirm', path);
447
+ } else {
448
+ // 找不到路径时直接使用城市信息
449
+ const result = [{ code: city.code, name: city.name }];
450
+ emit('update:modelValue', result);
451
+ emit('change', result);
452
+ emit('confirm', result);
453
+ }
454
+ showSelect.value = false;
455
+ // 显示 tabBar
456
+ // #ifdef H5
457
+ try { uni.showTabBar(); } catch (e) {}
458
+ // #endif
459
+ }
460
+
461
+ // 查找城市的完整路径(省-市-区)
462
+ function findCityPath(code) {
463
+ const path = [];
464
+
465
+ function search(list, currentPath) {
466
+ for (const item of list) {
467
+ const newPath = [...currentPath, { code: item.code, name: item.name }];
468
+ if (item.code === code) {
469
+ return newPath;
470
+ }
471
+ if (item.children) {
472
+ const result = search(item.children, newPath);
473
+ if (result) return result;
474
+ }
475
+ }
476
+ return null;
477
+ }
478
+
479
+ return search(regionData.value, []) || [];
480
+ }
481
+
482
+ // 确认选择
483
+ function confirmSelect() {
484
+ const result = tempSelected.value.map(item => ({
485
+ code: item.code,
486
+ name: item.name
487
+ }));
488
+ emit('update:modelValue', result);
489
+ emit('change', result);
490
+ emit('confirm', result);
491
+ showSelect.value = false;
492
+ // 显示 tabBar
493
+ // #ifdef H5
494
+ try { uni.showTabBar(); } catch (e) {}
495
+ // #endif
496
+ }
497
+
498
+ // 判断是否有子级
499
+ function hasChildren(item) {
500
+ return item.children && item.children.length > 0;
501
+ }
502
+
503
+ // 判断是否选中
504
+ function isItemSelected(item) {
505
+ const current = tempSelected.value[currentLevel.value];
506
+ return current && current.code === item.code;
507
+ }
508
+
509
+ // 返回到某一级
510
+ function backToLevel(index) {
511
+ currentLevel.value = index;
512
+ tempSelected.value = tempSelected.value.slice(0, index);
513
+ }
514
+
515
+ // 清空选择
516
+ function clearSelection() {
517
+ tempSelected.value = [];
518
+ currentLevel.value = 0;
519
+ }
520
+
521
+ // 搜索
522
+ function onSearch() {
523
+ if (!searchKeyword.value.trim()) {
524
+ searchResults.value = [];
525
+ return;
526
+ }
527
+ const keyword = searchKeyword.value.trim().toLowerCase();
528
+ const results = [];
529
+
530
+ // 递归搜索
531
+ function search(list, parentNames = []) {
532
+ for (const item of list) {
533
+ const fullName = [...parentNames, item.name].join(props.separator);
534
+ if (item.name.toLowerCase().includes(keyword)) {
535
+ results.push({ ...item, fullName });
536
+ }
537
+ if (item.children) {
538
+ search(item.children, [...parentNames, item.name]);
539
+ }
540
+ }
541
+ }
542
+
543
+ search(regionData.value);
544
+ searchResults.value = results.slice(0, 20);
545
+ }
546
+
547
+ // 清空搜索
548
+ function clearSearch() {
549
+ searchKeyword.value = '';
550
+ searchResults.value = [];
551
+ }
552
+ </script>
553
+
554
+ <style lang="scss">
555
+ .prism-city-cascade-select {
556
+ .prism-select-box {
557
+ display: flex;
558
+ align-items: center;
559
+ justify-content: space-between;
560
+ padding: 24rpx;
561
+ background: var(--prism-input-bg, #F7F8FA);
562
+ border-radius: 12rpx;
563
+
564
+ .placeholder {
565
+ color: var(--prism-text-placeholder, #C9CDD4);
566
+ font-size: 28rpx;
567
+ }
568
+
569
+ .select-text {
570
+ color: var(--prism-text-primary, #1D2129);
571
+ font-size: 28rpx;
572
+ }
573
+
574
+ .select-arrow {
575
+ color: var(--prism-text-secondary, #86909C);
576
+ font-size: 28rpx;
577
+ }
578
+ }
579
+
580
+ // 全屏页面
581
+ .select-page {
582
+ position: fixed;
583
+ top: 0;
584
+ left: 0;
585
+ right: 0;
586
+ bottom: -100rpx; // 向下延伸覆盖 tabBar
587
+ width: 100%;
588
+ padding-bottom: 100rpx; // 补偿底部延伸
589
+ background: var(--prism-bg-color-page, #F5F6F7);
590
+ z-index: 99999;
591
+ display: flex;
592
+ flex-direction: column;
593
+ overflow: hidden;
594
+ box-sizing: border-box;
595
+ }
596
+
597
+ // 头部
598
+ .page-header {
599
+ display: flex;
600
+ align-items: center;
601
+ justify-content: space-between;
602
+ padding: 24rpx 32rpx;
603
+ padding-top: calc(24rpx + env(safe-area-inset-top));
604
+ background: var(--prism-bg-color-card, #FFFFFF);
605
+ }
606
+
607
+ .header-back {
608
+ width: 60rpx;
609
+ .fa { font-size: 36rpx; color: var(--prism-text-primary, #1D2129); }
610
+ }
611
+
612
+ .header-title {
613
+ font-size: 34rpx;
614
+ font-weight: 600;
615
+ color: var(--prism-text-primary, #1D2129);
616
+ }
617
+
618
+ .header-right {
619
+ width: 60rpx;
620
+ }
621
+
622
+ // 搜索框
623
+ .search-box {
624
+ padding: 16rpx 32rpx;
625
+ background: var(--prism-bg-color-card, #FFFFFF);
626
+ }
627
+
628
+ .search-input-wrap {
629
+ display: flex;
630
+ align-items: center;
631
+ padding: 16rpx 24rpx;
632
+ background: var(--prism-bg-color-container, #F7F8FA);
633
+ border-radius: 8rpx;
634
+ gap: 16rpx;
635
+
636
+ .fa-search { color: var(--prism-text-placeholder, #C9CDD4); font-size: 28rpx; }
637
+ .fa-times-circle { color: var(--prism-text-secondary, #86909C); font-size: 28rpx; }
638
+ }
639
+
640
+ .search-input {
641
+ flex: 1;
642
+ font-size: 28rpx;
643
+ color: var(--prism-text-primary, #1D2129);
644
+ }
645
+
646
+ // 内容区域
647
+ .page-content {
648
+ flex: 1;
649
+ height: 0;
650
+ padding-bottom: env(safe-area-inset-bottom, 0px);
651
+ }
652
+
653
+ // 区块标题
654
+ .section-title {
655
+ display: flex;
656
+ align-items: center;
657
+ gap: 8rpx;
658
+ padding: 24rpx 32rpx 16rpx;
659
+ font-size: 26rpx;
660
+ color: var(--prism-text-secondary, #86909C);
661
+ .fa-fire { color: #FF6B00; }
662
+ }
663
+
664
+ // 热门城市
665
+ .hot-cities {
666
+ background: var(--prism-bg-color-card, #FFFFFF);
667
+ margin-bottom: 16rpx;
668
+ }
669
+
670
+ .hot-cities-grid {
671
+ display: flex;
672
+ flex-wrap: wrap;
673
+ padding: 0 32rpx 24rpx;
674
+ gap: 16rpx;
675
+ }
676
+
677
+ .hot-city-item {
678
+ padding: 20rpx 32rpx;
679
+ background: var(--prism-bg-color-container, #F7F8FA);
680
+ border-radius: 8rpx;
681
+ font-size: 28rpx;
682
+ color: var(--prism-text-primary, #1D2129);
683
+ &:active {
684
+ background: var(--prism-primary-light, rgba(52, 120, 246, 0.08));
685
+ color: var(--prism-primary-color, #3478F6);
686
+ }
687
+ }
688
+
689
+ // 面包屑
690
+ .breadcrumb {
691
+ background: var(--prism-bg-color-card, #FFFFFF);
692
+ margin-bottom: 16rpx;
693
+ }
694
+
695
+ .breadcrumb-content {
696
+ display: flex;
697
+ align-items: center;
698
+ padding: 0 32rpx 24rpx;
699
+ flex-wrap: wrap;
700
+ gap: 8rpx;
701
+ }
702
+
703
+ .breadcrumb-item {
704
+ display: flex;
705
+ align-items: center;
706
+ gap: 8rpx;
707
+ font-size: 28rpx;
708
+ color: var(--prism-primary-color, #3478F6);
709
+ .fa { font-size: 20rpx; color: var(--prism-text-placeholder, #C9CDD4); }
710
+ }
711
+
712
+ .breadcrumb-clear {
713
+ margin-left: auto;
714
+ .fa { font-size: 28rpx; color: var(--prism-text-secondary, #86909C); }
715
+ }
716
+
717
+ // 城市列表
718
+ .city-list {
719
+ background: var(--prism-bg-color-card, #FFFFFF);
720
+ }
721
+
722
+ .city-item {
723
+ display: flex;
724
+ align-items: center;
725
+ padding: 28rpx 32rpx;
726
+ border-bottom: 1rpx solid var(--prism-border-color-light, #E5E6EB);
727
+
728
+ .item-name {
729
+ flex: 1;
730
+ font-size: 30rpx;
731
+ color: var(--prism-text-primary, #1D2129);
732
+ }
733
+
734
+ .item-arrow {
735
+ font-size: 24rpx;
736
+ color: var(--prism-text-placeholder, #C9CDD4);
737
+ }
738
+
739
+ .item-check {
740
+ font-size: 28rpx;
741
+ color: var(--prism-primary-color, #3478F6);
742
+ }
743
+
744
+ &.selected .item-name {
745
+ color: var(--prism-primary-color, #3478F6);
746
+ font-weight: 500;
747
+ }
748
+ }
749
+
750
+ // 搜索结果
751
+ .search-results {
752
+ background: var(--prism-bg-color-card, #FFFFFF);
753
+ }
754
+
755
+ .result-item {
756
+ padding: 28rpx 32rpx;
757
+ border-bottom: 1rpx solid var(--prism-border-color-light, #E5E6EB);
758
+ font-size: 30rpx;
759
+ color: var(--prism-text-primary, #1D2129);
760
+ }
761
+
762
+ .search-empty {
763
+ display: flex;
764
+ flex-direction: column;
765
+ align-items: center;
766
+ padding: 120rpx 32rpx;
767
+ gap: 24rpx;
768
+ .fa { font-size: 80rpx; color: var(--prism-text-placeholder, #C9CDD4); }
769
+ text { font-size: 28rpx; color: var(--prism-text-secondary, #86909C); }
770
+ }
771
+ }
772
+
773
+ // 深色模式
774
+ .dark-mode.prism-city-cascade-select {
775
+ .select-page {
776
+ background: var(--prism-bg-color-page, #121212);
777
+ }
778
+
779
+ .page-header,
780
+ .search-box,
781
+ .hot-cities,
782
+ .breadcrumb,
783
+ .city-list,
784
+ .search-results {
785
+ background: var(--prism-bg-color-card, #1A1A1A);
786
+ }
787
+
788
+ .search-input-wrap,
789
+ .hot-city-item {
790
+ background: var(--prism-bg-color-container, #2A2A2A);
791
+ }
792
+ }
793
+ </style>