@jx3box/jx3box-ui 2.2.11 → 2.2.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jx3box/jx3box-ui",
3
- "version": "2.2.11",
3
+ "version": "2.2.13",
4
4
  "description": "JX3BOX Vue3 UI",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -33,7 +33,7 @@ import FooterResource from "./footer/resource.vue";
33
33
  import FooterCopyright from "./footer/copyright.vue";
34
34
  import i18nMixin from "../i18n/mixin";
35
35
  export default {
36
- name: "Footer",
36
+ name: "CommonFooter",
37
37
  mixins: [i18nMixin],
38
38
  components: {
39
39
  FooterOfficial,
@@ -53,7 +53,7 @@ body::after {
53
53
  bottom: 0;
54
54
  background: #111827;
55
55
  }
56
- .c-footer--v4{
56
+ .c-footer--v4 {
57
57
  box-sizing: border-box;
58
58
  padding: 3rem 1.5rem;
59
59
  background: #111827;
@@ -113,7 +113,7 @@ body::after {
113
113
  font-size: 1.5rem;
114
114
  line-height: 2rem;
115
115
  font-weight: 700;
116
- letter-spacing: -0.025em;
116
+ letter-spacing: 0;
117
117
  color: #fff;
118
118
  }
119
119
 
@@ -125,8 +125,8 @@ body::after {
125
125
  color: #9ca3af;
126
126
  }
127
127
 
128
- .u-logo{
129
- fill:#fff;
128
+ .u-logo {
129
+ fill: #fff;
130
130
  }
131
131
  }
132
132
  .c-footer--v4__popover {
@@ -4,7 +4,7 @@
4
4
  {{ $jx3boxT("jx3boxUi.commonFooter.downloadCenter", "下载中心") }}
5
5
  </h3>
6
6
  <div class="c-footer-resource__grid">
7
- <div v-for="item in downloadLinks" :key="item.name">
7
+ <div v-for="item in downloadLinks" :key="item.key">
8
8
  <el-popover v-if="item.qrcode" trigger="hover" placement="top" popper-class="c-footer--v4__popover">
9
9
  <div class="c-footer-resource__qrcode">
10
10
  <img
@@ -15,58 +15,26 @@
15
15
  <span class="c-footer-resource__qrcode-label">{{ getDownloadLabel(item) }}</span>
16
16
  </div>
17
17
  <template #reference>
18
- <a
19
- class="c-footer-resource__download"
20
- :href="item.href || '#'"
21
- :target="item.href ? '_blank' : null"
22
- :rel="item.href ? 'noopener noreferrer' : null"
23
- @click="handleLinkClick($event, item)"
24
- >
18
+ <button class="c-footer-resource__download" type="button">
25
19
  <span class="c-footer-resource__download-icon">
26
- <img :src="item.icon" :alt="getDownloadName(item)" />
20
+ <img :src="item.icon" alt="" aria-hidden="true" />
27
21
  </span>
28
22
  <span>{{ getDownloadName(item) }}</span>
29
- </a>
23
+ </button>
30
24
  </template>
31
25
  </el-popover>
32
- <el-popover
33
- v-else-if="item.placeholder"
34
- trigger="hover"
35
- placement="top"
36
- :show-after="150"
37
- popper-class="c-footer--v4__popover"
38
- >
39
- <div class="c-footer-resource__placeholder">
40
- {{ item.placeholder }}
41
- </div>
42
- <template #reference>
43
- <a
44
- class="c-footer-resource__download"
45
- :href="item.href || '#'"
46
- :target="item.href ? '_blank' : null"
47
- :rel="item.href ? 'noopener noreferrer' : null"
48
- @click="handleLinkClick($event, item)"
49
- >
50
- <span class="c-footer-resource__download-icon">
51
- <img :src="item.icon" :alt="getDownloadName(item)" />
52
- </span>
53
- <span>{{ getDownloadName(item) }}</span>
54
- </a>
55
- </template>
56
- </el-popover>
57
- <a
26
+ <button
58
27
  v-else
59
28
  class="c-footer-resource__download"
60
- :href="item.href || '#'"
61
- :target="item.href ? '_blank' : null"
62
- :rel="item.href ? 'noopener noreferrer' : null"
63
- @click="handleLinkClick($event, item)"
29
+ :class="{ 'is-active': activePlatform === item.key && downloadDialogVisible }"
30
+ type="button"
31
+ @click="openDownloadDialog(item)"
64
32
  >
65
33
  <span class="c-footer-resource__download-icon">
66
- <img :src="item.icon" :alt="getDownloadName(item)" />
34
+ <img :src="item.icon" alt="" aria-hidden="true" />
67
35
  </span>
68
36
  <span>{{ getDownloadName(item) }}</span>
69
- </a>
37
+ </button>
70
38
  </div>
71
39
  </div>
72
40
 
@@ -98,75 +66,290 @@
98
66
  {{ $jx3boxT("jx3boxUi.commonFooter.add", "添加") }}
99
67
  </a>
100
68
  </div>
69
+
70
+ <el-dialog
71
+ v-model="downloadDialogVisible"
72
+ :title="activeDialogTitle"
73
+ width="960px"
74
+ class="m-footer-app-dialog"
75
+ >
76
+ <div
77
+ v-loading="appConfigLoading"
78
+ class="m-footer-app-download"
79
+ >
80
+ <div class="u-app-header">
81
+ <img class="u-app-icon" :src="appLogo" :alt="appName" @error="handleLogoError" />
82
+ <div class="u-app-meta">
83
+ <div class="u-app-name">{{ appName }}</div>
84
+ <div class="u-app-version">{{ appVersion }}</div>
85
+ <div
86
+ v-if="appDescription"
87
+ class="u-app-desc-box"
88
+ :class="{
89
+ 'is-expanded': appDescExpanded,
90
+ 'is-foldable': hasDescFold(appDescription),
91
+ }"
92
+ @click="toggleAppDesc"
93
+ >
94
+ <el-icon v-if="hasDescFold(appDescription)" class="u-desc-toggle">
95
+ <ArrowUp v-if="appDescExpanded" />
96
+ <ArrowDown v-else />
97
+ </el-icon>
98
+ <div class="u-app-desc">
99
+ {{ getFoldedDesc(appDescription, appDescExpanded) }}
100
+ </div>
101
+ </div>
102
+ </div>
103
+ <div class="u-app-download-action">
104
+ <el-button
105
+ class="u-app-store-button"
106
+ type="primary"
107
+ :disabled="!activeDownloadUrl"
108
+ @click="openActiveDownload"
109
+ >
110
+ <el-icon class="u-button-icon"><Download /></el-icon>
111
+ <span>{{ activeDownloadText }}</span>
112
+ </el-button>
113
+ <div v-if="activePlatform === 'android'" class="u-app-download-tip">
114
+ 仅支持 Android 10 及以上系统
115
+ </div>
116
+ </div>
117
+ </div>
118
+
119
+ <div class="u-app-preview">
120
+ <div class="u-app-preview-tabs">
121
+ <button
122
+ v-for="device in previewDevices"
123
+ :key="device.key"
124
+ type="button"
125
+ class="u-preview-tab"
126
+ :class="{ 'is-active': activePreviewDevice === device.key }"
127
+ @click="activePreviewDevice = device.key"
128
+ >
129
+ {{ device.label }}
130
+ </button>
131
+ </div>
132
+
133
+ <div class="u-app-preview-list" :class="`is-${activePreviewDevice}`">
134
+ <div v-for="image in currentPreviewImages" :key="image" class="u-app-preview-card">
135
+ <el-image
136
+ class="u-app-preview-image"
137
+ :src="image"
138
+ :preview-src-list="currentPreviewImages"
139
+ :initial-index="currentPreviewImages.indexOf(image)"
140
+ fit="cover"
141
+ preview-teleported
142
+ />
143
+ </div>
144
+ </div>
145
+ </div>
146
+ </div>
147
+ </el-dialog>
101
148
  </section>
102
149
  </template>
103
150
 
104
151
  <script>
152
+ import { ArrowDown, ArrowUp, Download } from "@element-plus/icons-vue";
105
153
  import { copyText } from "../../utils";
106
154
  import i18nMixin from "../../i18n/mixin";
155
+ import { getConfig } from "../../service/cms";
156
+
157
+ const APP_LOGO_FALLBACK = "https://cdn.jx3box.com/design/app/logo/jx3box-icon-512.png";
158
+ const APP_CONFIG_KEYS = ["android_apk", "android_versions", "app_logo", "app_version_desc", "apple_url", "harmony_url"];
159
+
107
160
  export default {
108
161
  name: "FooterResource",
109
162
  mixins: [i18nMixin],
110
163
  props: [],
111
- components: {},
164
+ components: { ArrowDown, ArrowUp, Download },
112
165
  data: function () {
113
166
  return {
167
+ downloadDialogVisible: false,
168
+ activePlatform: "appStore",
169
+ activePreviewDevice: "phone",
170
+ appDescExpanded: false,
171
+ appConfig: {},
172
+ appConfigLoading: false,
173
+ appConfigLoaded: false,
174
+ previewDevices: [
175
+ { key: "phone", label: "Phone" },
176
+ { key: "pad", label: "Pad" },
177
+ ],
178
+ previewImages: {
179
+ phone: [
180
+ "https://cdn.jx3box.com/design/app/phone/phone1.jpg",
181
+ "https://cdn.jx3box.com/design/app/phone/phone2.jpg",
182
+ "https://cdn.jx3box.com/design/app/phone/phone3.jpg",
183
+ ],
184
+ pad: [
185
+ "https://cdn.jx3box.com/design/app/pad/pad1.jpg",
186
+ "https://cdn.jx3box.com/design/app/pad/pad2.jpg",
187
+ "https://cdn.jx3box.com/design/app/pad/pad3.jpg",
188
+ ],
189
+ },
114
190
  downloadLinks: [
115
191
  {
116
192
  key: "appStore",
117
193
  name: "App Store",
118
- href: "",
119
194
  icon: require("../../assets/img/common/ios.svg"),
120
- // qrcode: require("../../assets/img/common/ios.jpg"),
121
- placeholder: "即将上线",
122
195
  },
123
196
  {
124
197
  key: "android",
125
198
  name: "Android",
126
- href: "",
127
199
  icon: require("../../assets/img/common/android.svg"),
128
- // qrcode: require("../../assets/img/common/android.jpg"),
129
- placeholder: "即将上线",
130
200
  },
131
201
  {
132
202
  key: "harmonyNext",
133
203
  name: "鸿蒙 NEXT",
134
- href: "",
135
204
  icon: require("../../assets/img/common/harmony.svg"),
136
- // qrcode: require("../../assets/img/common/harmony.jpg"),
137
- placeholder: "即将上线",
138
205
  },
139
206
  {
140
207
  key: "miniProgram",
141
208
  name: "小程序",
142
209
  labelKey: "jx3boxHelper",
143
210
  label: "JX3BOX小助手",
144
- href: "",
145
211
  icon: require("../../assets/img/common/miniprogram.svg"),
146
212
  qrcode: require("../../assets/img/common/miniprogram.jpg"),
147
213
  },
148
214
  ],
149
215
  };
150
216
  },
151
- computed: {},
217
+ computed: {
218
+ activePlatformItem() {
219
+ return this.downloadLinks.find((item) => item.key === this.activePlatform) || this.downloadLinks[0];
220
+ },
221
+ activePlatformLabel() {
222
+ return this.getDownloadName(this.activePlatformItem);
223
+ },
224
+ activeDialogTitle() {
225
+ const map = {
226
+ appStore: "App Store",
227
+ android: "Android",
228
+ harmonyNext: "鸿蒙NEXT",
229
+ };
230
+ return map[this.activePlatform] || this.activePlatformLabel;
231
+ },
232
+ appLogo() {
233
+ return this.appConfig.app_logo || APP_LOGO_FALLBACK;
234
+ },
235
+ appName() {
236
+ return "剑网3魔盒";
237
+ },
238
+ appVersion() {
239
+ return this.appConfig.android_versions || "";
240
+ },
241
+ appDescription() {
242
+ return this.appConfig.app_version_desc || "";
243
+ },
244
+ androidDownloadUrl() {
245
+ return this.appConfig.android_apk || "";
246
+ },
247
+ appleDownloadUrl() {
248
+ return this.appConfig.apple_url || "";
249
+ },
250
+ harmonyDownloadUrl() {
251
+ return this.appConfig.harmony_url || "";
252
+ },
253
+ activeDownloadUrl() {
254
+ if (this.activePlatform === "android") return this.androidDownloadUrl;
255
+ if (this.activePlatform === "harmonyNext") return this.harmonyDownloadUrl;
256
+ return this.appleDownloadUrl;
257
+ },
258
+ activeDownloadText() {
259
+ const map = {
260
+ appStore: "前往苹果商店",
261
+ android: "下载 Android",
262
+ harmonyNext: "前往鸿蒙商店",
263
+ };
264
+ return map[this.activePlatform] || "立即下载";
265
+ },
266
+ currentPreviewImages() {
267
+ return this.previewImages[this.activePreviewDevice] || [];
268
+ },
269
+ },
152
270
  watch: {},
153
271
  methods: {
154
272
  copyText,
155
273
  getDownloadName(item) {
156
- if (item?.key) {
157
- const k = item.key === "harmonyNext" ? "harmonyNext" : item.key;
158
- const maybe = `jx3boxUi.commonFooter.${k}`;
159
- return this.$jx3boxT(maybe, item.name || k);
160
- }
161
- return item?.name || "";
274
+ if (!item?.key) return item?.name || "";
275
+ return this.$jx3boxT(`jx3boxUi.commonFooter.${item.key}`, item.name || item.key);
162
276
  },
163
277
  getDownloadLabel(item) {
164
- if (item?.labelKey)
278
+ if (item?.labelKey) {
165
279
  return this.$jx3boxT(`jx3boxUi.commonFooter.${item.labelKey}`, item.label || item.labelKey);
280
+ }
166
281
  return item?.label || "";
167
282
  },
168
- handleLinkClick(e, item) {
169
- if (!item?.href) e.preventDefault();
283
+ openDownloadDialog(item) {
284
+ this.activePlatform = item.key;
285
+ this.activePreviewDevice = "phone";
286
+ this.appDescExpanded = false;
287
+ this.downloadDialogVisible = true;
288
+ this.loadAppConfig();
289
+ },
290
+ openActiveDownload() {
291
+ if (!this.activeDownloadUrl) return;
292
+ window.open(this.activeDownloadUrl, "_blank", "noopener,noreferrer");
293
+ },
294
+ loadAppConfig() {
295
+ const storeConfig = this.getStoreAppConfig();
296
+ if (storeConfig) {
297
+ this.appConfig = {
298
+ ...this.appConfig,
299
+ ...storeConfig,
300
+ };
301
+ this.appConfigLoaded = true;
302
+ return Promise.resolve();
303
+ }
304
+ if (this.appConfigLoading || this.appConfigLoaded) return Promise.resolve();
305
+ this.appConfigLoading = true;
306
+ return getConfig({ subtype: "app" })
307
+ .then((items) => {
308
+ this.appConfig = this.getAppConfigFromItems(items);
309
+ this.appConfigLoaded = true;
310
+ })
311
+ .catch(() => {
312
+ this.appConfig = {};
313
+ })
314
+ .finally(() => {
315
+ this.appConfigLoading = false;
316
+ });
317
+ },
318
+ getStoreAppConfig() {
319
+ const config = this.$store?.state?.config || {};
320
+ const appConfig = APP_CONFIG_KEYS.reduce((result, key) => {
321
+ if (config[key]) result[key] = config[key];
322
+ return result;
323
+ }, {});
324
+ return Object.keys(appConfig).length ? appConfig : null;
325
+ },
326
+ getAppConfigFromItems(items) {
327
+ if (!Array.isArray(items)) return {};
328
+ return items.reduce((config, item) => {
329
+ if (!item?.key || !APP_CONFIG_KEYS.includes(item.key)) return config;
330
+ if (item.subtype && item.subtype !== "app") return config;
331
+ config[item.key] = item.val;
332
+ return config;
333
+ }, {});
334
+ },
335
+ getDescLines(description) {
336
+ return String(description || "")
337
+ .replace(/\\r\\n|\\n|\\r/g, "\n")
338
+ .split(/\r?\n/);
339
+ },
340
+ hasDescFold(description) {
341
+ return this.getDescLines(description).length > 1;
342
+ },
343
+ getFoldedDesc(description, expanded = false) {
344
+ const lines = this.getDescLines(description);
345
+ return expanded ? lines.join("\n") : lines[0] || "";
346
+ },
347
+ toggleAppDesc() {
348
+ if (!this.hasDescFold(this.appDescription)) return;
349
+ this.appDescExpanded = !this.appDescExpanded;
350
+ },
351
+ handleLogoError(e) {
352
+ e.target.src = APP_LOGO_FALLBACK;
170
353
  },
171
354
  gotoQQbot() {
172
355
  window.open("/qqbot", "_blank");
@@ -190,7 +373,7 @@ export default {
190
373
  font-size: 14px;
191
374
  font-weight: 600;
192
375
  line-height: 20px;
193
- letter-spacing: 0.025em;
376
+ letter-spacing: 0;
194
377
  }
195
378
 
196
379
  &__grid {
@@ -225,17 +408,10 @@ export default {
225
408
  line-height: 16px;
226
409
  }
227
410
 
228
- &__placeholder {
229
- padding: 12px;
230
- text-align: center;
231
- font-size: 12px;
232
- font-weight: 600;
233
- line-height: 16px;
234
- }
235
-
236
411
  &__download {
237
412
  display: flex;
238
413
  align-items: center;
414
+ width: 100%;
239
415
  height: 48px;
240
416
  padding: 0 16px;
241
417
  border: 1px solid #374151;
@@ -244,12 +420,16 @@ export default {
244
420
  color: #d1d5db;
245
421
  font-size: 12px;
246
422
  line-height: 16px;
423
+ text-align: left;
247
424
  text-decoration: none;
248
- transition: background-color 0.2s ease, border-color 0.2s ease;
425
+ cursor: pointer;
426
+ transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
249
427
 
250
- &:hover {
428
+ &:hover,
429
+ &.is-active {
251
430
  border-color: #3b82f6;
252
431
  background: #374151;
432
+ color: #fff;
253
433
  }
254
434
  }
255
435
 
@@ -260,6 +440,7 @@ export default {
260
440
  width: 16px;
261
441
  height: 16px;
262
442
  margin-right: 10px;
443
+ flex-shrink: 0;
263
444
 
264
445
  img {
265
446
  display: block;
@@ -317,7 +498,7 @@ export default {
317
498
  font-size: 10px;
318
499
  font-weight: 700;
319
500
  line-height: 14px;
320
- letter-spacing: 0.05em;
501
+ letter-spacing: 0;
321
502
  text-transform: uppercase;
322
503
  }
323
504
 
@@ -346,4 +527,271 @@ export default {
346
527
  }
347
528
  }
348
529
  }
530
+
531
+ .m-footer-app-dialog {
532
+ margin-top: 5vh !important;
533
+ width: min(960px, calc(100vw - 32px)) !important;
534
+
535
+ .el-dialog__header {
536
+ margin-right: 0;
537
+ padding: 20px 24px 12px;
538
+ border-bottom: 1px solid #e5eaf4;
539
+ }
540
+
541
+ .el-dialog__title {
542
+ color: #1f2937;
543
+ font-size: 18px;
544
+ font-weight: 700;
545
+ }
546
+
547
+ .el-dialog__body {
548
+ padding: 24px;
549
+ }
550
+
551
+ .m-footer-app-download {
552
+ min-height: 280px;
553
+ }
554
+
555
+ .u-app-header {
556
+ display: flex;
557
+ align-items: flex-start;
558
+ gap: 16px;
559
+ padding: 0 0 24px;
560
+ border-bottom: 1px solid #e5eaf4;
561
+ }
562
+
563
+ .u-app-icon {
564
+ width: 72px;
565
+ height: 72px;
566
+ border: 1px solid #e5eaf4;
567
+ border-radius: 18px;
568
+ object-fit: cover;
569
+ flex-shrink: 0;
570
+ box-shadow: 0 10px 24px rgba(79, 115, 201, 0.14);
571
+ }
572
+
573
+ .u-app-meta {
574
+ flex: 1;
575
+ min-width: 0;
576
+ }
577
+
578
+ .u-app-name {
579
+ color: #111827;
580
+ font-size: 22px;
581
+ font-weight: 700;
582
+ line-height: 1.3;
583
+ word-break: break-word;
584
+ }
585
+
586
+ .u-app-version {
587
+ margin-top: 6px;
588
+ color: #2d63ef;
589
+ font-size: 14px;
590
+ font-weight: 600;
591
+ line-height: 1.5;
592
+ }
593
+
594
+ .u-app-desc-box {
595
+ display: flex;
596
+ align-items: flex-start;
597
+ gap: 6px;
598
+ margin-top: 10px;
599
+ color: #4b5563;
600
+
601
+ &.is-foldable {
602
+ cursor: pointer;
603
+ }
604
+
605
+ &.is-expanded {
606
+ .u-app-desc {
607
+ display: block;
608
+ white-space: pre-wrap;
609
+ }
610
+ }
611
+ }
612
+
613
+ .u-desc-toggle {
614
+ margin-top: 6px;
615
+ color: #8a94a6;
616
+ flex-shrink: 0;
617
+ }
618
+
619
+ .u-app-desc {
620
+ display: -webkit-box;
621
+ overflow: hidden;
622
+ color: #4b5563;
623
+ font-size: 14px;
624
+ line-height: 1.8;
625
+ white-space: pre-wrap;
626
+ word-break: break-word;
627
+ -webkit-box-orient: vertical;
628
+ -webkit-line-clamp: 1;
629
+ }
630
+
631
+ .u-app-download-action {
632
+ margin-left: auto;
633
+ flex-shrink: 0;
634
+ display: flex;
635
+ flex-direction: column;
636
+ align-items: flex-end;
637
+ gap: 8px;
638
+ }
639
+
640
+ .u-app-store-button {
641
+ flex-shrink: 0;
642
+
643
+ .u-button-icon {
644
+ margin-right: 6px;
645
+ }
646
+ }
647
+
648
+ .u-app-download-tip {
649
+ color: #8a94a6;
650
+ font-size: 12px;
651
+ line-height: 18px;
652
+ white-space: nowrap;
653
+ }
654
+
655
+ .u-app-preview {
656
+ padding-top: 24px;
657
+ }
658
+
659
+ .u-app-preview-tabs {
660
+ display: flex;
661
+ justify-content: center;
662
+ gap: 12px;
663
+ margin-bottom: 20px;
664
+ }
665
+
666
+ .u-preview-tab {
667
+ min-width: 108px;
668
+ padding: 10px 18px;
669
+ border: 1px solid #d7e1f5;
670
+ border-radius: 999px;
671
+ background: #f7f9fe;
672
+ color: #5c6b84;
673
+ font-size: 14px;
674
+ font-weight: 600;
675
+ cursor: pointer;
676
+ transition: all 0.2s ease;
677
+
678
+ &:hover {
679
+ border-color: #9ab6ff;
680
+ color: #2d63ef;
681
+ }
682
+
683
+ &.is-active {
684
+ border-color: #4f73c9;
685
+ background: linear-gradient(135deg, #eff4ff 0%, #dfe9ff 100%);
686
+ color: #2349a6;
687
+ box-shadow: 0 10px 20px rgba(79, 115, 201, 0.16);
688
+ }
689
+ }
690
+
691
+ .u-app-preview-list {
692
+ display: grid;
693
+ grid-template-columns: repeat(3, minmax(0, 1fr));
694
+ gap: 16px;
695
+
696
+ &.is-phone {
697
+ .u-app-preview-card {
698
+ aspect-ratio: 9 / 16;
699
+ }
700
+ }
701
+
702
+ &.is-pad {
703
+ .u-app-preview-card {
704
+ aspect-ratio: 3 / 4;
705
+ }
706
+ }
707
+ }
708
+
709
+ .u-app-preview-card {
710
+ padding: 10px;
711
+ border: 1px solid #e0e8f7;
712
+ border-radius: 18px;
713
+ background: linear-gradient(180deg, #f9fbff 0%, #eef3ff 100%);
714
+ box-shadow: 0 10px 24px rgba(79, 115, 201, 0.08);
715
+ }
716
+
717
+ .u-app-preview-image {
718
+ display: block;
719
+ width: 100%;
720
+ height: 100%;
721
+ overflow: hidden;
722
+ border-radius: 12px;
723
+ background: #fff;
724
+ cursor: pointer;
725
+
726
+ .el-image__inner {
727
+ width: 100%;
728
+ height: 100%;
729
+ }
730
+ }
731
+ }
732
+
733
+ @media screen and (max-width: @phone) {
734
+ .m-footer-app-dialog {
735
+ width: calc(100vw - 24px) !important;
736
+
737
+ .el-dialog__header {
738
+ padding: 18px 16px 12px;
739
+ }
740
+
741
+ .el-dialog__body {
742
+ padding: 16px;
743
+ }
744
+
745
+ .u-app-header {
746
+ display: grid;
747
+ grid-template-columns: 64px minmax(0, 1fr);
748
+ gap: 14px;
749
+ padding-bottom: 18px;
750
+ }
751
+
752
+ .u-app-icon {
753
+ width: 64px;
754
+ height: 64px;
755
+ border-radius: 16px;
756
+ }
757
+
758
+ .u-app-name {
759
+ font-size: 20px;
760
+ }
761
+
762
+ .u-app-download-action {
763
+ grid-column: 1 / -1;
764
+ width: 100%;
765
+ margin-left: 0;
766
+ align-items: stretch;
767
+ }
768
+
769
+ .u-app-store-button {
770
+ width: 100%;
771
+ }
772
+
773
+ .u-app-download-tip {
774
+ text-align: center;
775
+ }
776
+
777
+ .u-app-preview {
778
+ padding-top: 18px;
779
+ }
780
+
781
+ .u-app-preview-tabs {
782
+ gap: 10px;
783
+ margin-bottom: 16px;
784
+ }
785
+
786
+ .u-preview-tab {
787
+ min-width: 0;
788
+ flex: 1;
789
+ padding: 10px 12px;
790
+ }
791
+
792
+ .u-app-preview-list {
793
+ grid-template-columns: 1fr;
794
+ }
795
+ }
796
+ }
349
797
  </style>