feat: add mine page and secondary pages
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
# Mine Page Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 为小程序新增“我的”主页面和其二级页面骨架,完成页面注册、页面跳转和深色视觉落地。
|
||||
|
||||
**Architecture:** 保持当前项目的轻量结构,直接在 `src/pages/` 下新增页面目录,不引入状态管理或新 UI 框架。主页面使用本地 mock 数据渲染,二级页面复用统一的深色卡片布局和轻量占位文案,验证以 `npm run build:weapp` 为主。
|
||||
|
||||
**Tech Stack:** Taro 4、React 18、TypeScript、SCSS
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 注册页面与整理导航入口
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/app.config.ts`
|
||||
- Modify: `src/pages/index/index.tsx`
|
||||
|
||||
- [ ] 在 `src/app.config.ts` 中注册 `mine` 主页面及 `profile`、`settings`、`support`、`devices`、`repair`、`feedback`、`videos`、`follow-us` 二级页面
|
||||
- [ ] 将首页底部导航中的“我的”入口改为跳转到 `pages/mine/index`
|
||||
- [ ] 保留首页其余入口当前占位逻辑,不扩展其他 Tab 页面
|
||||
|
||||
### Task 2: 实现“我的”主页面
|
||||
|
||||
**Files:**
|
||||
- Create: `src/pages/mine/index.config.ts`
|
||||
- Create: `src/pages/mine/index.tsx`
|
||||
- Create: `src/pages/mine/index.scss`
|
||||
|
||||
- [ ] 新建“我的”主页面配置,设置页面标题
|
||||
- [ ] 在 `index.tsx` 中定义本地 mock 用户数据、功能列表数据和页面跳转逻辑
|
||||
- [ ] 实现顶部用户信息卡、右侧快捷入口、功能列表和版本检查提示
|
||||
- [ ] 保持代码对新手友好,复杂映射处仅补充必要注释
|
||||
|
||||
### Task 3: 实现二级页面骨架
|
||||
|
||||
**Files:**
|
||||
- Create: `src/pages/profile/index.config.ts`
|
||||
- Create: `src/pages/profile/index.tsx`
|
||||
- Create: `src/pages/profile/index.scss`
|
||||
- Create: `src/pages/settings/index.config.ts`
|
||||
- Create: `src/pages/settings/index.tsx`
|
||||
- Create: `src/pages/settings/index.scss`
|
||||
- Create: `src/pages/support/index.config.ts`
|
||||
- Create: `src/pages/support/index.tsx`
|
||||
- Create: `src/pages/support/index.scss`
|
||||
- Create: `src/pages/devices/index.config.ts`
|
||||
- Create: `src/pages/devices/index.tsx`
|
||||
- Create: `src/pages/devices/index.scss`
|
||||
- Create: `src/pages/repair/index.config.ts`
|
||||
- Create: `src/pages/repair/index.tsx`
|
||||
- Create: `src/pages/repair/index.scss`
|
||||
- Create: `src/pages/feedback/index.config.ts`
|
||||
- Create: `src/pages/feedback/index.tsx`
|
||||
- Create: `src/pages/feedback/index.scss`
|
||||
- Create: `src/pages/videos/index.config.ts`
|
||||
- Create: `src/pages/videos/index.tsx`
|
||||
- Create: `src/pages/videos/index.scss`
|
||||
- Create: `src/pages/follow-us/index.config.ts`
|
||||
- Create: `src/pages/follow-us/index.tsx`
|
||||
- Create: `src/pages/follow-us/index.scss`
|
||||
|
||||
- [ ] 为每个二级页面补齐标题、卡片布局和占位内容
|
||||
- [ ] 保持二级页面视觉与主页面一致,但布局更简洁
|
||||
- [ ] 确保所有从“我的”页发起的跳转都能进入对应页面
|
||||
|
||||
### Task 4: 样式收口与验证
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/app.scss`
|
||||
- Modify: `src/pages/index/index.tsx`
|
||||
- Modify: `src/pages/mine/index.scss`
|
||||
- Modify: `src/pages/profile/index.scss`
|
||||
- Modify: `src/pages/settings/index.scss`
|
||||
- Modify: `src/pages/support/index.scss`
|
||||
- Modify: `src/pages/devices/index.scss`
|
||||
- Modify: `src/pages/repair/index.scss`
|
||||
- Modify: `src/pages/feedback/index.scss`
|
||||
- Modify: `src/pages/videos/index.scss`
|
||||
- Modify: `src/pages/follow-us/index.scss`
|
||||
|
||||
- [ ] 如有必要,补充少量全局基础样式,避免和现有页面冲突
|
||||
- [ ] 运行 `npm run build:weapp`
|
||||
- [ ] 检查构建输出,确认页面注册、TS 代码和 SCSS 都能通过编译
|
||||
@@ -1,5 +1,17 @@
|
||||
export default defineAppConfig({
|
||||
pages: ["pages/index/index", "pages/message/index"],
|
||||
pages: [
|
||||
"pages/index/index",
|
||||
"pages/message/index",
|
||||
"pages/mine/index",
|
||||
"pages/profile/index",
|
||||
"pages/settings/index",
|
||||
"pages/support/index",
|
||||
"pages/devices/index",
|
||||
"pages/repair/index",
|
||||
"pages/feedback/index",
|
||||
"pages/videos/index",
|
||||
"pages/follow-us/index"
|
||||
],
|
||||
window: {
|
||||
navigationBarTitleText: "新手小程序",
|
||||
navigationBarBackgroundColor: "#1AAD19",
|
||||
|
||||
128
src/components/secondary-page/index.scss
Normal file
128
src/components/secondary-page/index.scss
Normal file
@@ -0,0 +1,128 @@
|
||||
.secondary-page {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
padding: 32rpx 24rpx 48rpx;
|
||||
box-sizing: border-box;
|
||||
background: linear-gradient(180deg, #1e2432 0%, #171d29 100%);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.secondary-page__halo {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.secondary-page__halo--large {
|
||||
top: -80rpx;
|
||||
right: -44rpx;
|
||||
width: 320rpx;
|
||||
height: 320rpx;
|
||||
background:
|
||||
radial-gradient(circle, rgba(54, 228, 170, 0.08) 0 24%, transparent 25% 44%, rgba(109, 121, 154, 0.16) 45% 62%, transparent 63%),
|
||||
radial-gradient(circle at center, rgba(255, 255, 255, 0.06), transparent 72%);
|
||||
}
|
||||
|
||||
.secondary-page__halo--small {
|
||||
top: 180rpx;
|
||||
right: 90rpx;
|
||||
width: 160rpx;
|
||||
height: 120rpx;
|
||||
background: radial-gradient(circle at center, rgba(255, 255, 255, 0.05), transparent 68%);
|
||||
}
|
||||
|
||||
.secondary-page__hero {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-bottom: 28rpx;
|
||||
padding: 32rpx 30rpx;
|
||||
border-radius: 28rpx;
|
||||
background: rgba(39, 46, 64, 0.95);
|
||||
box-shadow: inset 0 0 0 2rpx rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
.secondary-page__eyebrow {
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
color: #40deb4;
|
||||
font-size: 22rpx;
|
||||
letter-spacing: 4rpx;
|
||||
}
|
||||
|
||||
.secondary-page__title {
|
||||
display: block;
|
||||
color: #f6f8fb;
|
||||
font-size: 42rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.secondary-page__description {
|
||||
display: block;
|
||||
margin-top: 14rpx;
|
||||
color: #9aa5bb;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.secondary-page__content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.secondary-page__card {
|
||||
padding: 28rpx;
|
||||
border-radius: 24rpx;
|
||||
background: rgba(39, 46, 64, 0.94);
|
||||
box-shadow: inset 0 0 0 2rpx rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
.secondary-page__card-title {
|
||||
display: block;
|
||||
margin-bottom: 20rpx;
|
||||
color: #eef3fb;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.secondary-page__list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rpx;
|
||||
}
|
||||
|
||||
.secondary-page__list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
.secondary-page__list-item:last-child {
|
||||
padding-bottom: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.secondary-page__list-label {
|
||||
color: #edf1f7;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.secondary-page__list-value {
|
||||
color: #7c879d;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.secondary-page__footer-tip {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: block;
|
||||
margin-top: 22rpx;
|
||||
color: #7d88a1;
|
||||
font-size: 22rpx;
|
||||
line-height: 1.7;
|
||||
text-align: center;
|
||||
}
|
||||
56
src/components/secondary-page/index.tsx
Normal file
56
src/components/secondary-page/index.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { Text, View } from "@tarojs/components";
|
||||
import "./index.scss";
|
||||
|
||||
export type SecondaryPageItem = {
|
||||
label: string;
|
||||
value?: string;
|
||||
};
|
||||
|
||||
export type SecondaryPageSection = {
|
||||
title: string;
|
||||
items: SecondaryPageItem[];
|
||||
};
|
||||
|
||||
type SecondaryPageProps = {
|
||||
eyebrow: string;
|
||||
title: string;
|
||||
description: string;
|
||||
sections: SecondaryPageSection[];
|
||||
footerTip?: string;
|
||||
};
|
||||
|
||||
export default function SecondaryPage(props: SecondaryPageProps) {
|
||||
const { eyebrow, title, description, sections, footerTip } = props;
|
||||
|
||||
return (
|
||||
<View className="secondary-page">
|
||||
<View className="secondary-page__halo secondary-page__halo--large" />
|
||||
<View className="secondary-page__halo secondary-page__halo--small" />
|
||||
|
||||
<View className="secondary-page__hero">
|
||||
<Text className="secondary-page__eyebrow">{eyebrow}</Text>
|
||||
<Text className="secondary-page__title">{title}</Text>
|
||||
<Text className="secondary-page__description">{description}</Text>
|
||||
</View>
|
||||
|
||||
<View className="secondary-page__content">
|
||||
{sections.map((section) => (
|
||||
<View className="secondary-page__card" key={section.title}>
|
||||
<Text className="secondary-page__card-title">{section.title}</Text>
|
||||
|
||||
<View className="secondary-page__list">
|
||||
{section.items.map((item) => (
|
||||
<View className="secondary-page__list-item" key={`${section.title}-${item.label}`}>
|
||||
<Text className="secondary-page__list-label">{item.label}</Text>
|
||||
<Text className="secondary-page__list-value">{item.value || "待接入"}</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
|
||||
{footerTip ? <Text className="secondary-page__footer-tip">{footerTip}</Text> : null}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
3
src/pages/devices/index.config.ts
Normal file
3
src/pages/devices/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "我的设备"
|
||||
});
|
||||
3
src/pages/devices/index.scss
Normal file
3
src/pages/devices/index.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.devices-page {
|
||||
display: block;
|
||||
}
|
||||
29
src/pages/devices/index.tsx
Normal file
29
src/pages/devices/index.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import SecondaryPage, { type SecondaryPageSection } from "../../components/secondary-page";
|
||||
import "./index.scss";
|
||||
|
||||
const sections: SecondaryPageSection[] = [
|
||||
{
|
||||
title: "设备概览",
|
||||
items: [
|
||||
{ label: "已绑定设备", value: "0 台" },
|
||||
{ label: "设备共享管理", value: "待接入" },
|
||||
{ label: "添加设备", value: "可复用首页绑定能力" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "当前状态",
|
||||
items: [{ label: "设备列表", value: "暂无已绑定设备" }]
|
||||
}
|
||||
];
|
||||
|
||||
export default function DevicesPage() {
|
||||
return (
|
||||
<SecondaryPage
|
||||
eyebrow="DEVICES"
|
||||
title="我的设备"
|
||||
description="这里先保留设备管理骨架,后续可以接真实设备列表、设备状态和共享管理。"
|
||||
sections={sections}
|
||||
footerTip="如果后面要对接设备绑定,可以优先复用首页已经实现的扫码和蓝牙入口。"
|
||||
/>
|
||||
);
|
||||
}
|
||||
3
src/pages/feedback/index.config.ts
Normal file
3
src/pages/feedback/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "问题反馈"
|
||||
});
|
||||
3
src/pages/feedback/index.scss
Normal file
3
src/pages/feedback/index.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.feedback-page {
|
||||
display: block;
|
||||
}
|
||||
28
src/pages/feedback/index.tsx
Normal file
28
src/pages/feedback/index.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import SecondaryPage, { type SecondaryPageSection } from "../../components/secondary-page";
|
||||
import "./index.scss";
|
||||
|
||||
const sections: SecondaryPageSection[] = [
|
||||
{
|
||||
title: "反馈入口",
|
||||
items: [
|
||||
{ label: "提交问题" },
|
||||
{ label: "提交建议" },
|
||||
{ label: "上传截图", value: "待接入上传能力" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "记录查询",
|
||||
items: [{ label: "反馈记录", value: "后续展示处理进度" }]
|
||||
}
|
||||
];
|
||||
|
||||
export default function FeedbackPage() {
|
||||
return (
|
||||
<SecondaryPage
|
||||
eyebrow="FEEDBACK"
|
||||
title="问题反馈"
|
||||
description="这里先保留问题和建议入口,后续补充表单校验、截图上传和反馈历史即可继续扩展。"
|
||||
sections={sections}
|
||||
/>
|
||||
);
|
||||
}
|
||||
3
src/pages/follow-us/index.config.ts
Normal file
3
src/pages/follow-us/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "关注我们"
|
||||
});
|
||||
3
src/pages/follow-us/index.scss
Normal file
3
src/pages/follow-us/index.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.follow-us-page {
|
||||
display: block;
|
||||
}
|
||||
25
src/pages/follow-us/index.tsx
Normal file
25
src/pages/follow-us/index.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import SecondaryPage, { type SecondaryPageSection } from "../../components/secondary-page";
|
||||
import "./index.scss";
|
||||
|
||||
const sections: SecondaryPageSection[] = [
|
||||
{
|
||||
title: "官方入口",
|
||||
items: [
|
||||
{ label: "官方公众号", value: "待补充二维码" },
|
||||
{ label: "官方网站", value: "待补充地址" },
|
||||
{ label: "联系方式", value: "待补充电话或邮箱" },
|
||||
{ label: "社区入口", value: "待补充链接" }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export default function FollowUsPage() {
|
||||
return (
|
||||
<SecondaryPage
|
||||
eyebrow="FOLLOW"
|
||||
title="关注我们"
|
||||
description="这里先预留官方触点,后续可以继续接公众号二维码、官网跳转和社区活动入口。"
|
||||
sections={sections}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -28,6 +28,7 @@ const navItems: TabbarItem[] = [
|
||||
{ key: "message", label: "消息", active: false, badge: true },
|
||||
{ key: "mine", label: "我的", active: false }
|
||||
];
|
||||
|
||||
const mockBluetoothDevices: DeviceCandidate[] = [
|
||||
{ id: "mock-thermo-01", name: "体征监测设备 A1", source: "mock" },
|
||||
{ id: "mock-thermo-02", name: "体征监测设备 B2", source: "mock" }
|
||||
@@ -124,6 +125,11 @@ export default function Index() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.key === "mine") {
|
||||
Taro.navigateTo({ url: "/pages/mine/index" });
|
||||
return;
|
||||
}
|
||||
|
||||
showToast(`${item.label}功能待接入`);
|
||||
};
|
||||
|
||||
|
||||
4
src/pages/mine/index.config.ts
Normal file
4
src/pages/mine/index.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationStyle: "custom",
|
||||
navigationBarTitleText: "我的"
|
||||
});
|
||||
429
src/pages/mine/index.scss
Normal file
429
src/pages/mine/index.scss
Normal file
@@ -0,0 +1,429 @@
|
||||
.mine-page {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
padding: calc(var(--top-safe-height, 0px) + 34rpx) 24rpx 170rpx;
|
||||
box-sizing: border-box;
|
||||
background: linear-gradient(180deg, #1f2534 0%, #171d29 100%);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mine-page__halo {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mine-page__halo--large {
|
||||
top: -110rpx;
|
||||
right: -34rpx;
|
||||
width: 360rpx;
|
||||
height: 360rpx;
|
||||
background:
|
||||
radial-gradient(circle, rgba(54, 228, 170, 0.06) 0 24%, transparent 25% 42%, rgba(110, 121, 151, 0.14) 43% 62%, transparent 63%),
|
||||
radial-gradient(circle at center, rgba(255, 255, 255, 0.05), transparent 72%);
|
||||
}
|
||||
|
||||
.mine-page__halo--small {
|
||||
top: 90rpx;
|
||||
right: 88rpx;
|
||||
width: 150rpx;
|
||||
height: 110rpx;
|
||||
background: radial-gradient(circle at center, rgba(255, 255, 255, 0.04), transparent 70%);
|
||||
}
|
||||
|
||||
.mine-page__header-card {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 34rpx 28rpx 30rpx;
|
||||
margin-bottom: 22rpx;
|
||||
border-radius: 0 0 28rpx 28rpx;
|
||||
background: rgba(39, 46, 64, 0.96);
|
||||
box-shadow: inset 0 0 0 2rpx rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
.mine-page__header-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.mine-page__avatar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 104rpx;
|
||||
height: 104rpx;
|
||||
margin-right: 24rpx;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(180deg, rgba(170, 177, 192, 0.55) 0%, rgba(131, 141, 159, 0.75) 100%);
|
||||
}
|
||||
|
||||
.mine-page__avatar-placeholder {
|
||||
position: relative;
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
}
|
||||
|
||||
.mine-page__avatar-head,
|
||||
.mine-page__avatar-body {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
background: rgba(238, 240, 244, 0.72);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.mine-page__avatar-head {
|
||||
top: 0;
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.mine-page__avatar-body {
|
||||
bottom: 0;
|
||||
width: 48rpx;
|
||||
height: 26rpx;
|
||||
border-radius: 26rpx 26rpx 20rpx 20rpx;
|
||||
}
|
||||
|
||||
.mine-page__identity {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.mine-page__name {
|
||||
color: #f4f7fb;
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.mine-page__phone {
|
||||
margin-top: 10rpx;
|
||||
color: #c2cad9;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.mine-page__vip-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 12rpx;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.mine-page__vip-badge {
|
||||
color: #f4a55c;
|
||||
font-size: 22rpx;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.mine-page__vip-text,
|
||||
.mine-page__vip-count {
|
||||
color: #11d1ba;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
|
||||
.mine-page__header-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
padding-left: 18rpx;
|
||||
padding-right: calc(var(--menu-safe-width, 0px) + 6rpx);
|
||||
}
|
||||
|
||||
.mine-page__icon-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.mine-page__circle-action {
|
||||
position: relative;
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.mine-page__circle-action::before,
|
||||
.mine-page__circle-action::after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.mine-page__circle-action--support::before {
|
||||
inset: 7rpx 4rpx 10rpx;
|
||||
border: 2rpx solid rgba(255, 255, 255, 0.84);
|
||||
border-bottom: 0;
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
}
|
||||
|
||||
.mine-page__circle-action--support::after {
|
||||
left: 12rpx;
|
||||
right: 12rpx;
|
||||
bottom: 6rpx;
|
||||
height: 10rpx;
|
||||
border-left: 2rpx solid rgba(255, 255, 255, 0.84);
|
||||
border-right: 2rpx solid rgba(255, 255, 255, 0.84);
|
||||
border-radius: 0 0 10rpx 10rpx;
|
||||
}
|
||||
|
||||
.mine-page__circle-action--settings::before {
|
||||
inset: 8rpx;
|
||||
border: 2rpx solid rgba(255, 255, 255, 0.84);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.mine-page__circle-action--settings::after {
|
||||
inset: 3rpx;
|
||||
border: 2rpx dashed rgba(255, 255, 255, 0.56);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.mine-page__profile-link {
|
||||
margin-top: 56rpx;
|
||||
color: #1ac9c0;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.mine-page__menu-card {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border-radius: 24rpx;
|
||||
background: rgba(39, 46, 64, 0.96);
|
||||
box-shadow: inset 0 0 0 2rpx rgba(255, 255, 255, 0.03);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mine-page__menu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 96rpx;
|
||||
padding: 0 24rpx;
|
||||
border-top: 1rpx solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.mine-page__menu-item--first {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.mine-page__menu-icon {
|
||||
position: relative;
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
margin-right: 18rpx;
|
||||
}
|
||||
|
||||
.mine-page__menu-icon::before,
|
||||
.mine-page__menu-icon::after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
border-color: #19d3be;
|
||||
}
|
||||
|
||||
.mine-page__menu-icon--device::before {
|
||||
inset: 4rpx;
|
||||
border: 2rpx solid #19d3be;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
|
||||
.mine-page__menu-icon--device::after {
|
||||
left: 6rpx;
|
||||
right: 6rpx;
|
||||
top: 12rpx;
|
||||
height: 2rpx;
|
||||
background: #19d3be;
|
||||
}
|
||||
|
||||
.mine-page__menu-icon--repair::before {
|
||||
left: 4rpx;
|
||||
top: 12rpx;
|
||||
width: 20rpx;
|
||||
height: 2rpx;
|
||||
background: #19d3be;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.mine-page__menu-icon--repair::after {
|
||||
left: 10rpx;
|
||||
top: 6rpx;
|
||||
width: 10rpx;
|
||||
height: 14rpx;
|
||||
border: 2rpx solid #19d3be;
|
||||
border-left: 0;
|
||||
border-bottom: 0;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.mine-page__menu-icon--feedback::before {
|
||||
inset: 4rpx;
|
||||
border: 2rpx solid #19d3be;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.mine-page__menu-icon--feedback::after {
|
||||
left: 12rpx;
|
||||
top: 8rpx;
|
||||
width: 2rpx;
|
||||
height: 12rpx;
|
||||
background: #19d3be;
|
||||
box-shadow: 0 10rpx 0 #19d3be;
|
||||
}
|
||||
|
||||
.mine-page__menu-icon--video::before {
|
||||
inset: 5rpx 3rpx;
|
||||
border: 2rpx solid #19d3be;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
|
||||
.mine-page__menu-icon--video::after {
|
||||
top: 9rpx;
|
||||
right: 7rpx;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 5rpx solid transparent;
|
||||
border-bottom: 5rpx solid transparent;
|
||||
border-left: 8rpx solid #19d3be;
|
||||
}
|
||||
|
||||
.mine-page__menu-icon--follow::before {
|
||||
left: 4rpx;
|
||||
top: 8rpx;
|
||||
width: 10rpx;
|
||||
height: 16rpx;
|
||||
border: 2rpx solid #19d3be;
|
||||
border-right: 0;
|
||||
border-radius: 12rpx 0 0 12rpx;
|
||||
}
|
||||
|
||||
.mine-page__menu-icon--follow::after {
|
||||
right: 4rpx;
|
||||
top: 8rpx;
|
||||
width: 10rpx;
|
||||
height: 16rpx;
|
||||
border: 2rpx solid #19d3be;
|
||||
border-left: 0;
|
||||
border-radius: 0 12rpx 12rpx 0;
|
||||
}
|
||||
|
||||
.mine-page__menu-icon--version::before {
|
||||
inset: 4rpx;
|
||||
border: 2rpx solid #19d3be;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.mine-page__menu-icon--version::after {
|
||||
left: 12rpx;
|
||||
top: 8rpx;
|
||||
width: 2rpx;
|
||||
height: 8rpx;
|
||||
background: #19d3be;
|
||||
box-shadow: 0 12rpx 0 #19d3be;
|
||||
}
|
||||
|
||||
.mine-page__menu-label {
|
||||
flex: 1;
|
||||
color: #edf2f7;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.mine-page__menu-trailing {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.mine-page__menu-value {
|
||||
color: #707b92;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.mine-page__menu-arrow {
|
||||
color: #7d869d;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.mine-page__tabbar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 5;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 16rpx 24rpx calc(20rpx + env(safe-area-inset-bottom));
|
||||
background: rgba(30, 35, 48, 0.98);
|
||||
box-shadow: 0 -8rpx 24rpx rgba(4, 8, 20, 0.34);
|
||||
}
|
||||
|
||||
.mine-page__tabbar-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
min-width: 88rpx;
|
||||
}
|
||||
|
||||
.mine-page__tabbar-icon {
|
||||
position: relative;
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
margin-bottom: 8rpx;
|
||||
border-radius: 10rpx;
|
||||
border: 2rpx solid #8f97a9;
|
||||
opacity: 0.86;
|
||||
}
|
||||
|
||||
.mine-page__tabbar-icon::before,
|
||||
.mine-page__tabbar-icon::after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.mine-page__tabbar-icon::before {
|
||||
left: 8rpx;
|
||||
right: 8rpx;
|
||||
top: 10rpx;
|
||||
height: 2rpx;
|
||||
background: #8f97a9;
|
||||
}
|
||||
|
||||
.mine-page__tabbar-icon::after {
|
||||
left: 8rpx;
|
||||
right: 8rpx;
|
||||
bottom: 10rpx;
|
||||
height: 2rpx;
|
||||
background: #8f97a9;
|
||||
}
|
||||
|
||||
.mine-page__tabbar-icon--active {
|
||||
border-color: #36e4aa;
|
||||
background: rgba(54, 228, 170, 0.12);
|
||||
}
|
||||
|
||||
.mine-page__tabbar-icon--active::before,
|
||||
.mine-page__tabbar-icon--active::after {
|
||||
background: #36e4aa;
|
||||
}
|
||||
|
||||
.mine-page__tabbar-badge {
|
||||
position: absolute;
|
||||
top: -4rpx;
|
||||
right: -4rpx;
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
border-radius: 50%;
|
||||
background: #ff4d4f;
|
||||
box-shadow: 0 0 0 4rpx rgba(30, 35, 48, 0.98);
|
||||
}
|
||||
|
||||
.mine-page__tabbar-label {
|
||||
color: #b0b6c4;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
|
||||
.mine-page__tabbar-label--active {
|
||||
color: #36e4aa;
|
||||
}
|
||||
180
src/pages/mine/index.tsx
Normal file
180
src/pages/mine/index.tsx
Normal file
@@ -0,0 +1,180 @@
|
||||
import { Text, View } from "@tarojs/components";
|
||||
import Taro from "@tarojs/taro";
|
||||
import type { CSSProperties } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import "./index.scss";
|
||||
|
||||
type UserProfile = {
|
||||
userName: string;
|
||||
phone: string;
|
||||
vip: boolean;
|
||||
avatar: string;
|
||||
deviceCount: number;
|
||||
};
|
||||
|
||||
type FeatureItem = {
|
||||
key: string;
|
||||
label: string;
|
||||
value?: string;
|
||||
icon: string;
|
||||
url?: string;
|
||||
};
|
||||
|
||||
const userProfile: UserProfile = {
|
||||
userName: "张天爱",
|
||||
phone: "135****2598",
|
||||
vip: true,
|
||||
avatar: "",
|
||||
deviceCount: 0
|
||||
};
|
||||
|
||||
const featureItems: FeatureItem[] = [
|
||||
{ key: "devices", label: "我的设备", value: "已绑定 0 台", icon: "device", url: "/pages/devices/index" },
|
||||
{ key: "repair", label: "设备报修", icon: "repair", url: "/pages/repair/index" },
|
||||
{ key: "feedback", label: "问题反馈", icon: "feedback", url: "/pages/feedback/index" },
|
||||
{ key: "videos", label: "教学视频", icon: "video", url: "/pages/videos/index" },
|
||||
{ key: "follow-us", label: "关注我们", icon: "follow", url: "/pages/follow-us/index" },
|
||||
{ key: "version", label: "当前版本", value: "V1.0.2504.12", icon: "version" }
|
||||
];
|
||||
|
||||
const tabItems = [
|
||||
{ key: "home", label: "首页" },
|
||||
{ key: "report", label: "报告" },
|
||||
{ key: "assistant", label: "小e" },
|
||||
{ key: "message", label: "消息", badge: true },
|
||||
{ key: "mine", label: "我的", active: true }
|
||||
];
|
||||
|
||||
export default function MinePage() {
|
||||
const [topSafeHeight, setTopSafeHeight] = useState(0);
|
||||
const [menuSafeWidth, setMenuSafeWidth] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const windowInfo = typeof Taro.getWindowInfo === "function" ? Taro.getWindowInfo() : Taro.getSystemInfoSync();
|
||||
const menuButtonRect =
|
||||
typeof Taro.getMenuButtonBoundingClientRect === "function" ? Taro.getMenuButtonBoundingClientRect() : null;
|
||||
const safeTop = menuButtonRect?.bottom || windowInfo.statusBarHeight || 0;
|
||||
const safeRight = menuButtonRect ? windowInfo.windowWidth - menuButtonRect.left : 0;
|
||||
|
||||
setTopSafeHeight(safeTop);
|
||||
setMenuSafeWidth(safeRight);
|
||||
}, []);
|
||||
|
||||
const showToast = (title: string) => {
|
||||
Taro.showToast({
|
||||
title,
|
||||
icon: "none"
|
||||
});
|
||||
};
|
||||
|
||||
const openPage = (url: string) => {
|
||||
Taro.navigateTo({ url });
|
||||
};
|
||||
|
||||
const handleFeatureClick = (item: FeatureItem) => {
|
||||
if (item.url) {
|
||||
openPage(item.url);
|
||||
return;
|
||||
}
|
||||
|
||||
showToast("当前已是最新版本");
|
||||
};
|
||||
|
||||
const handleTabClick = (key: string, label: string) => {
|
||||
if (key === "mine") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (key === "home") {
|
||||
const pages = Taro.getCurrentPages();
|
||||
|
||||
if (pages.length > 1) {
|
||||
Taro.navigateBack();
|
||||
} else {
|
||||
Taro.redirectTo({ url: "/pages/index/index" });
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
showToast(`${label}功能待接入`);
|
||||
};
|
||||
|
||||
const pageStyle = {
|
||||
"--top-safe-height": `${topSafeHeight}px`,
|
||||
"--menu-safe-width": `${menuSafeWidth}px`
|
||||
} as CSSProperties;
|
||||
|
||||
return (
|
||||
<View className="mine-page" style={pageStyle}>
|
||||
<View className="mine-page__halo mine-page__halo--large" />
|
||||
<View className="mine-page__halo mine-page__halo--small" />
|
||||
|
||||
<View className="mine-page__header-card">
|
||||
<View className="mine-page__header-main">
|
||||
<View className="mine-page__avatar">
|
||||
{userProfile.avatar ? (
|
||||
<View className="mine-page__avatar-image" />
|
||||
) : (
|
||||
<View className="mine-page__avatar-placeholder">
|
||||
<View className="mine-page__avatar-head" />
|
||||
<View className="mine-page__avatar-body" />
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View className="mine-page__identity">
|
||||
<Text className="mine-page__name">{userProfile.userName}</Text>
|
||||
<Text className="mine-page__phone">账号: {userProfile.phone}</Text>
|
||||
<View className="mine-page__vip-row">
|
||||
<Text className="mine-page__vip-badge">VIP</Text>
|
||||
<Text className="mine-page__vip-text">{userProfile.vip ? "已开通VIP会员" : "暂未开通VIP会员"}</Text>
|
||||
<Text className="mine-page__vip-count">0</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className="mine-page__header-actions">
|
||||
<View className="mine-page__icon-actions">
|
||||
<View className="mine-page__circle-action mine-page__circle-action--support" onClick={() => openPage("/pages/support/index")} />
|
||||
<View className="mine-page__circle-action mine-page__circle-action--settings" onClick={() => openPage("/pages/settings/index")} />
|
||||
</View>
|
||||
|
||||
<Text className="mine-page__profile-link" onClick={() => openPage("/pages/profile/index")}>
|
||||
个人信息
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className="mine-page__menu-card">
|
||||
{featureItems.map((item, index) => (
|
||||
<View
|
||||
className={`mine-page__menu-item ${index === 0 ? "mine-page__menu-item--first" : ""}`}
|
||||
key={item.key}
|
||||
onClick={() => handleFeatureClick(item)}
|
||||
>
|
||||
<View className={`mine-page__menu-icon mine-page__menu-icon--${item.icon}`} />
|
||||
|
||||
<Text className="mine-page__menu-label">{item.label}</Text>
|
||||
|
||||
<View className="mine-page__menu-trailing">
|
||||
{item.value ? <Text className="mine-page__menu-value">{item.value}</Text> : null}
|
||||
<Text className="mine-page__menu-arrow">></Text>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<View className="mine-page__tabbar">
|
||||
{tabItems.map((item) => (
|
||||
<View className="mine-page__tabbar-item" key={item.key} onClick={() => handleTabClick(item.key, item.label)}>
|
||||
<View className={`mine-page__tabbar-icon ${item.active ? "mine-page__tabbar-icon--active" : ""}`}>
|
||||
{item.badge ? <View className="mine-page__tabbar-badge" /> : null}
|
||||
</View>
|
||||
<Text className={`mine-page__tabbar-label ${item.active ? "mine-page__tabbar-label--active" : ""}`}>{item.label}</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
3
src/pages/profile/index.config.ts
Normal file
3
src/pages/profile/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "个人信息"
|
||||
});
|
||||
3
src/pages/profile/index.scss
Normal file
3
src/pages/profile/index.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.profile-page {
|
||||
display: block;
|
||||
}
|
||||
26
src/pages/profile/index.tsx
Normal file
26
src/pages/profile/index.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import SecondaryPage, { type SecondaryPageSection } from "../../components/secondary-page";
|
||||
import "./index.scss";
|
||||
|
||||
const sections: SecondaryPageSection[] = [
|
||||
{
|
||||
title: "资料编辑",
|
||||
items: [
|
||||
{ label: "头像", value: "支持后续替换" },
|
||||
{ label: "昵称", value: "张天爱" },
|
||||
{ label: "手机号", value: "135****2598" },
|
||||
{ label: "修改密码", value: "待接入" }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export default function ProfilePage() {
|
||||
return (
|
||||
<SecondaryPage
|
||||
eyebrow="PROFILE"
|
||||
title="个人信息"
|
||||
description="这里先保留资料编辑骨架,后续接入真实账号体系时可以直接补上头像上传、昵称编辑和密码修改。"
|
||||
sections={sections}
|
||||
footerTip="当前页面以结构预留为主,暂不提交真实修改。"
|
||||
/>
|
||||
);
|
||||
}
|
||||
3
src/pages/repair/index.config.ts
Normal file
3
src/pages/repair/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "设备报修"
|
||||
});
|
||||
3
src/pages/repair/index.scss
Normal file
3
src/pages/repair/index.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.repair-page {
|
||||
display: block;
|
||||
}
|
||||
28
src/pages/repair/index.tsx
Normal file
28
src/pages/repair/index.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import SecondaryPage, { type SecondaryPageSection } from "../../components/secondary-page";
|
||||
import "./index.scss";
|
||||
|
||||
const sections: SecondaryPageSection[] = [
|
||||
{
|
||||
title: "报修申请",
|
||||
items: [
|
||||
{ label: "提交报修申请" },
|
||||
{ label: "上传故障图片", value: "待接入上传能力" },
|
||||
{ label: "填写设备问题", value: "待接入表单" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "售后进度",
|
||||
items: [{ label: "维修进度查询", value: "后续接接口" }]
|
||||
}
|
||||
];
|
||||
|
||||
export default function RepairPage() {
|
||||
return (
|
||||
<SecondaryPage
|
||||
eyebrow="REPAIR"
|
||||
title="设备报修"
|
||||
description="这个页面先把报修流程的主要节点放齐,后面接图片上传和工单接口时改动会比较小。"
|
||||
sections={sections}
|
||||
/>
|
||||
);
|
||||
}
|
||||
3
src/pages/settings/index.config.ts
Normal file
3
src/pages/settings/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "设置"
|
||||
});
|
||||
3
src/pages/settings/index.scss
Normal file
3
src/pages/settings/index.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.settings-page {
|
||||
display: block;
|
||||
}
|
||||
31
src/pages/settings/index.tsx
Normal file
31
src/pages/settings/index.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import SecondaryPage, { type SecondaryPageSection } from "../../components/secondary-page";
|
||||
import "./index.scss";
|
||||
|
||||
const sections: SecondaryPageSection[] = [
|
||||
{
|
||||
title: "通用设置",
|
||||
items: [
|
||||
{ label: "通知设置" },
|
||||
{ label: "权限管理" },
|
||||
{ label: "清理缓存" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "账号相关",
|
||||
items: [
|
||||
{ label: "关于我们" },
|
||||
{ label: "退出登录", value: "待二次确认" }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export default function SettingsPage() {
|
||||
return (
|
||||
<SecondaryPage
|
||||
eyebrow="SETTINGS"
|
||||
title="设置"
|
||||
description="这里先把常见设置入口排好,后续如果接入通知、缓存和权限管理,就可以在这个页面继续细化。"
|
||||
sections={sections}
|
||||
/>
|
||||
);
|
||||
}
|
||||
3
src/pages/support/index.config.ts
Normal file
3
src/pages/support/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "帮助与客服"
|
||||
});
|
||||
3
src/pages/support/index.scss
Normal file
3
src/pages/support/index.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.support-page {
|
||||
display: block;
|
||||
}
|
||||
24
src/pages/support/index.tsx
Normal file
24
src/pages/support/index.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import SecondaryPage, { type SecondaryPageSection } from "../../components/secondary-page";
|
||||
import "./index.scss";
|
||||
|
||||
const sections: SecondaryPageSection[] = [
|
||||
{
|
||||
title: "客服入口",
|
||||
items: [
|
||||
{ label: "在线客服", value: "工作日 9:00 - 18:00" },
|
||||
{ label: "联系售后", value: "支持提交工单" },
|
||||
{ label: "帮助中心", value: "常见问题待补充" }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export default function SupportPage() {
|
||||
return (
|
||||
<SecondaryPage
|
||||
eyebrow="SUPPORT"
|
||||
title="帮助与客服"
|
||||
description="耳机按钮先统一收口到这个页面,方便后面继续接客服系统、售后单据和帮助中心文章。"
|
||||
sections={sections}
|
||||
/>
|
||||
);
|
||||
}
|
||||
3
src/pages/videos/index.config.ts
Normal file
3
src/pages/videos/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "教学视频"
|
||||
});
|
||||
3
src/pages/videos/index.scss
Normal file
3
src/pages/videos/index.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.videos-page {
|
||||
display: block;
|
||||
}
|
||||
24
src/pages/videos/index.tsx
Normal file
24
src/pages/videos/index.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import SecondaryPage, { type SecondaryPageSection } from "../../components/secondary-page";
|
||||
import "./index.scss";
|
||||
|
||||
const sections: SecondaryPageSection[] = [
|
||||
{
|
||||
title: "视频分类",
|
||||
items: [
|
||||
{ label: "设备使用教程", value: "3 个占位视频" },
|
||||
{ label: "安装教程", value: "2 个占位视频" },
|
||||
{ label: "健康指导视频", value: "持续补充" }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export default function VideosPage() {
|
||||
return (
|
||||
<SecondaryPage
|
||||
eyebrow="VIDEOS"
|
||||
title="教学视频"
|
||||
description="当前先用列表骨架占位,后续接视频封面、时长和播放页后就可以扩展成真正的视频中心。"
|
||||
sections={sections}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user