ow
This commit is contained in:
1 parent
8a2adb0a92
commit
bd678b0112
22 files changed
+1968
-81
No files matched your search
@@ -1,44 +1,360 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 底部导航「文件」测试页:先占位,后续接相册/文件功能。
|
||||
* 权限暂用 UserOperation(见 routes.ts 的 PAGE_PERMISSIONS);nav-guard 在 reLaunch 时做路由级校验,
|
||||
* 这里再挂一次 useAuthGuard 兜冷启动直达(地址栏 / file、分享链接不经过导航 API)。
|
||||
* 底部导航「文件」页:按截图拆解为独立组件(components/ 下各自一个 vue 文件),
|
||||
* 页面只持有状态与数据,经 props 单向下发、事件(emit)上报,组件之间不互相引用:
|
||||
* page-navbar 顶部导航(居中标题;仅子目录态显示返回箭头)
|
||||
* file-breadcrumb 目录面包屑(仅子目录态:左起排列,放不下折成 根+…+尾部段)
|
||||
* search-input 搜索框(v-model 即时过滤,确认键触发服务端搜索)
|
||||
* quick-entry 快捷功能入口(横向滚动图标组)
|
||||
* file-tab-filter 分类标签 + 排序 + 视图切换 + 多选开关
|
||||
* file-grid-list 文件网格/列表卡片
|
||||
* float-add-btn 右下角悬浮加号
|
||||
* 数据来自后端 DMS 接口(composables/useDmsFiles,调用链对齐旧 WebVue DmsFileEnquiry.vue);
|
||||
* 组件契约(data/custom/fileBrowser.ts)不关心数据源,演示数据到真实接口只动页面层。
|
||||
* 目录导航:点文件夹下钻;子目录态隐藏底部 tabbar,返回箭头/面包屑退层级。
|
||||
* 权限暂用 UserOperation(见 routes.ts 的 PAGE_PERMISSIONS);useAuthGuard 兜冷启动直达。
|
||||
*/
|
||||
import { useAuthGuard } from "@/composables";
|
||||
import type { FileCategory, FileItem, FileTabItem, QuickEntryItem } from "@/data/custom/fileBrowser";
|
||||
import { useLocale } from "uview-pro";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { useAuthGuard, useDmsFiles, useThemeGradient } from "@/composables";
|
||||
import { pageUrl } from "@/router/routes";
|
||||
|
||||
useAuthGuard();
|
||||
const { t } = useLocale();
|
||||
|
||||
// 页面底渐变跟随主题(派生逻辑在 composables/useThemeGradient,多页共用)
|
||||
const { themeBackground } = useThemeGradient();
|
||||
|
||||
const { files, loading, errorText, pathStack, atRoot, init, retry, openFolder, back, goTo, search } = useDmsFiles();
|
||||
|
||||
// 首次显示拉根目录,之后每次回到页面只刷新当前目录(重进 tab 不该丢位置重新拉全链)
|
||||
let started = false;
|
||||
useAuthGuard(() => {
|
||||
if (started) {
|
||||
retry();
|
||||
return;
|
||||
}
|
||||
started = true;
|
||||
init();
|
||||
});
|
||||
|
||||
// ===== 页面状态(全部单向下发,组件只上报意图) =====
|
||||
const keyword = ref("");
|
||||
const category = ref<FileCategory>("all");
|
||||
const viewMode = ref<"grid" | "list">("list");
|
||||
const selectMode = ref(false);
|
||||
const selectedIds = ref<number[]>([]);
|
||||
/** 排序模式:0 时间降序 / 1 时间升序 / 2 名称,点导航栏排序按钮循环 */
|
||||
const sortMode = ref(0);
|
||||
|
||||
/* 搜索框 / 快捷入口显隐:navbar 右侧两个图标手动切换;
|
||||
默认规则——进入子目录(有面包屑)时隐藏、回根目录恢复显示 */
|
||||
const showSearch = ref(true);
|
||||
const showQuick = ref(true);
|
||||
watch(atRoot, (root) => {
|
||||
showSearch.value = root;
|
||||
showQuick.value = root;
|
||||
});
|
||||
|
||||
/** 导航栏标题跟随当前目录:根为「我的云盘」,下钻后是文件夹名 */
|
||||
const navTitle = computed(() => pathStack.value[pathStack.value.length - 1]?.displayName || t("FilePage.title"));
|
||||
|
||||
const quickEntries = computed<QuickEntryItem[]>(() => [
|
||||
{ key: "recent", label: t("FilePage.recent"), icon: "clock", bgFrom: "#5ee7c1", bgTo: "#22c79f" },
|
||||
{ key: "favorite", label: t("FilePage.favorite"), icon: "star-fill", bgFrom: "#ff8a8a", bgTo: "#f0413e" },
|
||||
{ key: "downloaded", label: t("FilePage.downloaded"), icon: "arrow-down", bgFrom: "#a78bfa", bgTo: "#6d43e0" },
|
||||
{ key: "team", label: t("FilePage.team"), icon: "account", bgFrom: "#63b3ff", bgTo: "#1f7ae0" },
|
||||
{ key: "shared", label: t("FilePage.shared"), icon: "share-fill", bgFrom: "#5ec2ff", bgTo: "#2b8fff" },
|
||||
]);
|
||||
|
||||
const tabs = computed<FileTabItem[]>(() => [
|
||||
{ key: "all", label: t("FilePage.catAll") },
|
||||
{ key: "image", label: t("FilePage.catImage") },
|
||||
{ key: "audio", label: t("FilePage.catAudio") },
|
||||
{ key: "video", label: t("FilePage.catVideo") },
|
||||
{ key: "document", label: t("FilePage.catDocument") },
|
||||
]);
|
||||
|
||||
/**
|
||||
* 分类为本地过滤(后端按目录返回全量,切标签不该重新打接口);
|
||||
* 选中分类时目录一起被过滤掉,只有「全部」显示文件夹;
|
||||
* 关键字在确认键时走服务端 contain 过滤,输入过程中先本地收敛已加载数据。
|
||||
*/
|
||||
const visibleFiles = computed<FileItem[]>(() => {
|
||||
const kw = keyword.value.trim().toLowerCase();
|
||||
const list = files.value.filter(
|
||||
f => (category.value === "all" || f.kind === category.value)
|
||||
&& (!kw || f.name.toLowerCase().includes(kw)),
|
||||
);
|
||||
const bySort = (a: FileItem, b: FileItem) => {
|
||||
if (sortMode.value === 2) {
|
||||
return a.name.localeCompare(b.name, "zh-CN");
|
||||
}
|
||||
return sortMode.value === 1 ? a.sortTime - b.sortTime : b.sortTime - a.sortTime;
|
||||
};
|
||||
// 文件夹组恒置顶(对齐后端 IsDirectoryIndc desc 排序与截图样式),组内再按当前排序
|
||||
const folders = list.filter(f => f.kind === "folder").sort(bySort);
|
||||
const others = list.filter(f => f.kind !== "folder").sort(bySort);
|
||||
return [...folders, ...others];
|
||||
});
|
||||
|
||||
function toast(title: string): void {
|
||||
uni.showToast({ title, icon: "none" });
|
||||
}
|
||||
|
||||
/** 待接入真实功能时的统一占位提示 */
|
||||
function todoTip(): void {
|
||||
toast(t("FilePage.todoTip"));
|
||||
}
|
||||
|
||||
// ===== 导航栏 / 面包屑 =====
|
||||
function onToggleSearch(): void {
|
||||
showSearch.value = !showSearch.value;
|
||||
}
|
||||
|
||||
function onToggleQuick(): void {
|
||||
showQuick.value = !showQuick.value;
|
||||
}
|
||||
|
||||
async function onBack(): Promise<void> {
|
||||
// 返回箭头只在子目录态出现:退一层目录;根目录走页面退出兜底
|
||||
if (await back()) {
|
||||
keyword.value = "";
|
||||
selectedIds.value = [];
|
||||
return;
|
||||
}
|
||||
// tab 页 reLaunch 进来的没有返回栈,回不去就回首页
|
||||
if (getCurrentPages().length > 1) {
|
||||
uni.navigateBack();
|
||||
return;
|
||||
}
|
||||
uni.reLaunch({ url: pageUrl("dashboard") });
|
||||
}
|
||||
|
||||
/** 点面包屑某一段:截断到该层并重查(goTo 内部处理「已在该层」空点) */
|
||||
async function onCrumbNav(index: number): Promise<void> {
|
||||
if (index >= pathStack.value.length - 1) {
|
||||
return;
|
||||
}
|
||||
await goTo(index);
|
||||
keyword.value = "";
|
||||
selectedIds.value = [];
|
||||
}
|
||||
|
||||
const sortLabels = computed(() => [
|
||||
t("FilePage.sortTimeDesc"),
|
||||
t("FilePage.sortTimeAsc"),
|
||||
t("FilePage.sortName"),
|
||||
]);
|
||||
|
||||
function onSort(): void {
|
||||
sortMode.value = (sortMode.value + 1) % 3;
|
||||
toast(sortLabels.value[sortMode.value] ?? "");
|
||||
}
|
||||
|
||||
// ===== 搜索 / 快捷入口 =====
|
||||
function onSearch(value: string): void {
|
||||
search(value);
|
||||
}
|
||||
|
||||
function onQuickClick(key: string): void {
|
||||
const entry = quickEntries.value.find(e => e.key === key);
|
||||
toast(entry ? `${entry.label} · ${t("FilePage.todoTip")}` : t("FilePage.todoTip"));
|
||||
}
|
||||
|
||||
// ===== 分类 / 视图 / 多选 =====
|
||||
function onCategoryChange(key: FileCategory): void {
|
||||
category.value = key;
|
||||
selectedIds.value = [];
|
||||
}
|
||||
|
||||
function onToggleView(): void {
|
||||
viewMode.value = viewMode.value === "grid" ? "list" : "grid";
|
||||
}
|
||||
|
||||
function onToggleSelect(): void {
|
||||
selectMode.value = !selectMode.value;
|
||||
if (!selectMode.value) {
|
||||
selectedIds.value = [];
|
||||
}
|
||||
}
|
||||
|
||||
function onToggleSelectItem(id: number): void {
|
||||
const index = selectedIds.value.indexOf(id);
|
||||
if (index >= 0) {
|
||||
selectedIds.value.splice(index, 1);
|
||||
return;
|
||||
}
|
||||
selectedIds.value.push(id);
|
||||
}
|
||||
|
||||
// ===== 列表条目 / 悬浮按钮 =====
|
||||
async function onOpen(file: FileItem): Promise<void> {
|
||||
// 文件夹下钻走真实接口;打开文件(预览/播放)尚未实现,先占位
|
||||
if (await openFolder(file)) {
|
||||
keyword.value = "";
|
||||
selectedIds.value = [];
|
||||
return;
|
||||
}
|
||||
toast(`${file.name} · ${t("FilePage.todoTip")}`);
|
||||
}
|
||||
|
||||
function onItemMore(file: FileItem): void {
|
||||
toast(`${file.name} · ${t("FilePage.todoTip")}`);
|
||||
}
|
||||
|
||||
function onAdd(): void {
|
||||
todoTip();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<app-page nav-title="文件" :show-nav-back="false" :show-tabbar="true">
|
||||
<view class="tab-page">
|
||||
<text class="tab-page__title">
|
||||
文件
|
||||
</text>
|
||||
<text class="tab-page__hint">
|
||||
测试页,功能待接入
|
||||
</text>
|
||||
<app-page :hide-nav="true" :show-tabbar="atRoot">
|
||||
<view class="file-page" :style="{ background: themeBackground }">
|
||||
<!-- 上半屏整体固定,只有文件列表所在的 scroll-view 内部滚动(整页不滚) -->
|
||||
<view class="file-page__head">
|
||||
<page-navbar :title="navTitle" :show-back="!atRoot" :search-on="showSearch" :quick-on="showQuick" @back="onBack"
|
||||
@toggle-search="onToggleSearch" @toggle-quick="onToggleQuick" />
|
||||
<!-- 子目录态才有的路径条:白色衬底包住面包屑(外面不再是灰页面底),左起全量显示,溢出折叠 -->
|
||||
<view v-if="!atRoot" class="file-page__crumb">
|
||||
<file-breadcrumb :items="pathStack" @nav="onCrumbNav" />
|
||||
</view>
|
||||
<!-- 搜索框与快捷入口由 navbar 右侧图标切换显隐(进子目录默认隐藏);
|
||||
快捷入口外层包装负责卡片定位(scroll-view 自身不能带左右 margin) -->
|
||||
<search-input v-if="showSearch" v-model="keyword" :placeholder="t('FilePage.searchPlaceholder')"
|
||||
@search="onSearch" />
|
||||
<view v-if="showQuick" class="file-page__quick">
|
||||
<quick-entry :items="quickEntries" @click="onQuickClick" />
|
||||
</view>
|
||||
<file-tab-filter :tabs="tabs" :active="category" :view-mode="viewMode" :select-mode="selectMode"
|
||||
@change="onCategoryChange" @sort="onSort" @toggle-view="onToggleView" @toggle-select="onToggleSelect" />
|
||||
<view v-if="selectMode" class="file-page__selection">
|
||||
<text class="file-page__selection-text">
|
||||
{{ t("FilePage.selectedCount", { count: selectedIds.length }) }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 滚动窗口外层包装:margin/圆角/白底/裁剪放这层(scroll-view 根节点固定
|
||||
100% 宽,自带左右 margin 会右侧溢出被裁,与 quick-entry 同坑实测过) -->
|
||||
<view class="file-page__scroll-wrap">
|
||||
<scroll-view scroll-y class="file-page__scroll">
|
||||
<!-- 文件列表内容容器:卡片外观由 wrap 层负责 -->
|
||||
<view class="file-page__card">
|
||||
<view v-if="loading" class="file-page__state">
|
||||
<text class="file-page__state-text">
|
||||
{{ t("FilePage.loading") }}
|
||||
</text>
|
||||
</view>
|
||||
<view v-else-if="errorText" class="file-page__state">
|
||||
<text class="file-page__state-text file-page__state-text--error">
|
||||
{{ errorText }}
|
||||
</text>
|
||||
<text class="file-page__retry" @click="retry()">
|
||||
{{ t("FilePage.retryBut") }}
|
||||
</text>
|
||||
</view>
|
||||
<file-grid-list v-else :files="visibleFiles" :view-mode="viewMode" :select-mode="selectMode"
|
||||
:selected-ids="selectedIds" :empty-text="t('FilePage.emptyText')" @open="onOpen" @more="onItemMore"
|
||||
@toggle-select="onToggleSelectItem" />
|
||||
</view>
|
||||
<!-- 列表尾部让位悬浮 tabbar;子目录态 tabbar 隐藏,占位相应收小 -->
|
||||
<view class="file-page__tabbar-space" :class="{ 'file-page__tabbar-space--slim': !atRoot }" />
|
||||
</scroll-view>
|
||||
</view>
|
||||
<float-add-btn @click="onAdd" />
|
||||
</view>
|
||||
</app-page>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tab-page {
|
||||
.file-page {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
/* 渐变底由 script 的 pageBackground 按主题 primary 动态计算(内联 style 下发) */
|
||||
}
|
||||
|
||||
.file-page__head {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 面包屑分区:透明衬底露灰页面底,与其余卡片同节奏的间隔(面包屑自身就是白卡片) */
|
||||
.file-page__crumb {
|
||||
padding: 20rpx 24rpx 0;
|
||||
}
|
||||
|
||||
/* 快捷入口卡片定位(组件内 scroll-view 不能自带左右 margin,挪到这层) */
|
||||
.file-page__quick {
|
||||
margin: 20rpx 24rpx 0;
|
||||
}
|
||||
|
||||
/* 滚动窗口外层包装=卡片本体:margin/圆角/白底/裁剪在这层,
|
||||
左右 20rpx 间隔对称(scroll-view 自身带 margin 会右侧溢出被裁) */
|
||||
.file-page__scroll-wrap {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
margin: 20rpx 20rpx 0;
|
||||
border-radius: 32rpx 32rpx 0 0;
|
||||
background-color: #ffffff;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* scroll-view 只当纯滚动容器垫满 wrap,滚动内容被 wrap 的圆角窗口裁剪 */
|
||||
.file-page__scroll {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.file-grid-list--list[data-v-2dfb0235] {
|
||||
padding: 0.15rem 0.25rem 0.15rem !important;
|
||||
}
|
||||
|
||||
.file-page__tabbar-space {
|
||||
height: 140rpx;
|
||||
|
||||
&--slim {
|
||||
height: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.file-page__selection {
|
||||
margin: 20rpx 24rpx 0;
|
||||
padding: 16rpx 32rpx;
|
||||
border-radius: 24rpx;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.file-page__selection-text {
|
||||
font-size: 24rpx;
|
||||
color: #2b8fff;
|
||||
}
|
||||
|
||||
.file-page__state {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 120rpx 40rpx;
|
||||
justify-content: center;
|
||||
gap: 24rpx;
|
||||
padding: 64rpx 32rpx;
|
||||
}
|
||||
|
||||
.tab-page__title {
|
||||
font-size: 40rpx;
|
||||
font-weight: 600;
|
||||
color: $u-main-color;
|
||||
}
|
||||
|
||||
.tab-page__hint {
|
||||
margin-top: 16rpx;
|
||||
.file-page__state-text {
|
||||
font-size: 26rpx;
|
||||
color: $u-tips-color;
|
||||
color: #9aa0a6;
|
||||
}
|
||||
|
||||
.file-page__state-text--error {
|
||||
color: #f0413e;
|
||||
}
|
||||
|
||||
.file-page__retry {
|
||||
padding: 8rpx 28rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 26rpx;
|
||||
color: #2b8fff;
|
||||
background-color: #eaf4ff;
|
||||
}
|
||||
</style>
|
||||
@@ -1,43 +1,172 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 底部导航「我的」测试页:先占位,后续接个人资料/设置/关于入口。
|
||||
* 底部导航「我的」页:主题外观设置(uView Pro 主题系统)+ 后续个人资料入口占位。
|
||||
* 主题列表与默认值在 main.ts 注册(common/uview-pro.theme.ts 的四套配色);
|
||||
* useTheme 的 setTheme/setDarkMode 自带 Storage 持久化(uview-pro-theme 键),
|
||||
* 冷启动时由插件 initTheme 恢复,这里不需要再接 store。
|
||||
* 权限暂用 UserOperation(见 routes.ts 的 PAGE_PERMISSIONS);useAuthGuard 兜冷启动直达。
|
||||
*/
|
||||
import { useLocale, useTheme } from "uview-pro";
|
||||
import { useAuthGuard } from "@/composables";
|
||||
|
||||
/** 与 uview-pro 内部 DarkMode 联合对齐(顶层未导出该类型,本地声明同构字面量) */
|
||||
type DarkModeValue = "auto" | "light" | "dark";
|
||||
|
||||
const { t } = useLocale();
|
||||
|
||||
useAuthGuard();
|
||||
|
||||
// currentTheme/darkMode 是包级单例 ref:任意页切换,本页选中态实时跟随
|
||||
const { themes, currentTheme, setTheme, darkMode, setDarkMode } = useTheme();
|
||||
|
||||
const darkOptions: { value: DarkModeValue; label: string }[] = [
|
||||
{ value: "auto", label: t("MinePage.darkAuto") },
|
||||
{ value: "light", label: t("MinePage.darkLight") },
|
||||
{ value: "dark", label: t("MinePage.darkDark") },
|
||||
];
|
||||
|
||||
function onPickTheme(name: string): void {
|
||||
setTheme(name);
|
||||
}
|
||||
|
||||
function onPickDarkMode(mode: DarkModeValue): void {
|
||||
setDarkMode(mode);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<app-page nav-title="我的" :show-nav-back="false" :show-tabbar="true">
|
||||
<view class="tab-page">
|
||||
<text class="tab-page__title">
|
||||
我的
|
||||
</text>
|
||||
<text class="tab-page__hint">
|
||||
测试页,功能待接入
|
||||
</text>
|
||||
<app-page :nav-title="t('MinePage.title')" :show-nav-back="false" :show-tabbar="true">
|
||||
<view class="mine-page">
|
||||
<!-- 主题配色:色点取自各主题 primary,选中打勾 -->
|
||||
<view class="mine-card">
|
||||
<text class="mine-card__title">
|
||||
{{ t("MinePage.themeTitle") }}
|
||||
</text>
|
||||
<view class="mine-themes">
|
||||
<view v-for="theme in themes" :key="theme.name" class="mine-theme" @tap="onPickTheme(theme.name)">
|
||||
<view class="mine-theme__dot"
|
||||
:class="{ 'mine-theme__dot--active': theme.name === currentTheme?.name }"
|
||||
:style="{ backgroundColor: theme.color.primary }">
|
||||
<u-icon v-if="theme.name === currentTheme?.name" name="checkmark" size="30"
|
||||
color="#ffffff" />
|
||||
</view>
|
||||
<text class="mine-theme__label">
|
||||
{{ theme.label }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="mine-card__hint">
|
||||
{{ t("MinePage.themeHint") }}
|
||||
</text>
|
||||
</view>
|
||||
<!-- 深色模式:跟随系统 / 强制浅色 / 强制暗黑 三段 -->
|
||||
<view class="mine-card">
|
||||
<text class="mine-card__title">
|
||||
{{ t("MinePage.darkTitle") }}
|
||||
</text>
|
||||
<view class="mine-dark">
|
||||
<view v-for="opt in darkOptions" :key="opt.value" class="mine-dark__seg"
|
||||
:class="{ 'mine-dark__seg--active': opt.value === darkMode }" @tap="onPickDarkMode(opt.value)">
|
||||
<text class="mine-dark__text">
|
||||
{{ opt.label }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</app-page>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tab-page {
|
||||
.mine-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24rpx;
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
/* 白底圆角卡片:与文件页分区卡片同一风格语言 */
|
||||
.mine-card {
|
||||
padding: 32rpx;
|
||||
border-radius: 24rpx;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.mine-card__title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
.mine-card__hint {
|
||||
margin-top: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #9aa0a6;
|
||||
}
|
||||
|
||||
.mine-themes {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 40rpx;
|
||||
margin-top: 28rpx;
|
||||
}
|
||||
|
||||
.mine-theme {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 120rpx 40rpx;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.tab-page__title {
|
||||
font-size: 40rpx;
|
||||
font-weight: 600;
|
||||
color: $u-main-color;
|
||||
.mine-theme__dot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 8rpx 16rpx rgba(31, 35, 41, 0.12);
|
||||
|
||||
&--active {
|
||||
border: 6rpx solid #ffffff;
|
||||
outline: 4rpx solid #1f2329;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-page__hint {
|
||||
margin-top: 16rpx;
|
||||
.mine-theme__label {
|
||||
font-size: 24rpx;
|
||||
color: #5c626b;
|
||||
}
|
||||
|
||||
/* 三段胶囊:选中段深底白字(跟随 currentTheme primary 的中性替代) */
|
||||
.mine-dark {
|
||||
display: flex;
|
||||
gap: 8rpx;
|
||||
margin-top: 28rpx;
|
||||
padding: 8rpx;
|
||||
border-radius: 999rpx;
|
||||
background-color: #f2f3f5;
|
||||
}
|
||||
|
||||
.mine-dark__seg {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
height: 64rpx;
|
||||
border-radius: 999rpx;
|
||||
|
||||
&--active {
|
||||
background-color: #1f2329;
|
||||
}
|
||||
}
|
||||
|
||||
.mine-dark__text {
|
||||
font-size: 26rpx;
|
||||
color: $u-tips-color;
|
||||
color: #5c626b;
|
||||
|
||||
.mine-dark__seg--active & {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user