feat: refresh UI and add vite ci workflow
@@ -0,0 +1,19 @@
|
|||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["main", "master"]
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22
|
||||||
|
cache: npm
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run build:h5
|
||||||
|
- run: npm run build:mp-weixin
|
||||||
@@ -1 +1,4 @@
|
|||||||
unpackage/*
|
node_modules/
|
||||||
|
dist/
|
||||||
|
unpackage/
|
||||||
|
.hbuilderx/
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# 戒烟助手小程序(smt)
|
# 戒烟助手小程序(smt)
|
||||||
|
|
||||||
基于 `uni-app + Vue 3 + Pinia` 的戒烟辅助小程序前端,核心目标是帮助用户记录抽烟/忍住行为,并通过首页看板、统计分析和 AI 建议逐步降低吸烟频率。
|
基于 `uni-app + Vue 3 + Pinia + Vite` 的戒烟辅助小程序前端,核心目标是帮助用户记录抽烟/忍住行为,并通过首页看板、统计分析和 AI 建议逐步降低吸烟频率。
|
||||||
|
|
||||||
## 项目状态
|
## 项目状态
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
## 页面与路由
|
## 页面与路由
|
||||||
|
|
||||||
在 `pages.json` 中注册了以下页面:
|
在 `src/pages.json` 中注册了以下页面:
|
||||||
|
|
||||||
- `pages/index/index`:首页
|
- `pages/index/index`:首页
|
||||||
- `pages/stats/index`:统计
|
- `pages/stats/index`:统计
|
||||||
@@ -56,51 +56,79 @@
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
smt/
|
smt/
|
||||||
├── api/ # 接口封装
|
├── src/
|
||||||
├── components/ # 业务组件(含 smoke-record-dialog)
|
│ ├── api/ # 接口封装
|
||||||
├── config/ # 环境配置(BASE_URL 等)
|
│ ├── components/ # 业务组件(含 smoke-record-dialog)
|
||||||
|
│ ├── config/ # 环境配置(BASE_URL 等)
|
||||||
|
│ ├── hooks/ # 组合式逻辑(如 useLogin)
|
||||||
|
│ ├── pages/ # 页面
|
||||||
|
│ ├── stores/ # Pinia 状态管理
|
||||||
|
│ ├── utils/ # 工具函数与本地存储封装
|
||||||
|
│ ├── App.vue
|
||||||
|
│ ├── main.js
|
||||||
|
│ ├── manifest.json
|
||||||
|
│ └── pages.json
|
||||||
├── docs/ # PRD、API、算法与认证文档
|
├── docs/ # PRD、API、算法与认证文档
|
||||||
├── hooks/ # 组合式逻辑(如 useLogin)
|
├── index.html
|
||||||
├── pages/ # 页面
|
├── package.json
|
||||||
├── stores/ # Pinia 状态管理
|
└── vite.config.js
|
||||||
├── utils/ # 工具函数与本地存储封装
|
|
||||||
├── App.vue
|
|
||||||
├── main.js
|
|
||||||
├── manifest.json
|
|
||||||
└── pages.json
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 本地开发
|
## 本地开发
|
||||||
|
|
||||||
## 1. 环境准备
|
## 1. 环境准备
|
||||||
|
|
||||||
- 推荐使用 `HBuilderX` 打开项目目录
|
- Node.js 22
|
||||||
- 微信开发者工具(用于运行到微信小程序)
|
- npm
|
||||||
|
- 微信开发者工具(用于运行微信小程序)
|
||||||
> 说明:本仓库当前未包含 `package.json`,默认按 HBuilderX/uni-app 工程方式运行。
|
|
||||||
|
|
||||||
## 2. 配置后端地址
|
## 2. 配置后端地址
|
||||||
|
|
||||||
编辑 `config/index.js`:
|
编辑 `src/config/index.js`:
|
||||||
|
|
||||||
- `development.BASE_URL`:开发环境 API 地址
|
- `development.BASE_URL`:开发环境 API 地址
|
||||||
- `production.BASE_URL`:生产环境 API 地址
|
- `production.BASE_URL`:生产环境 API 地址
|
||||||
- `MINI_PROGRAM_ID`:后端登录接口使用的小程序 ID
|
- `MINI_PROGRAM_ID`:后端登录接口使用的小程序 ID
|
||||||
|
|
||||||
## 3. 小程序配置
|
## 3. 安装依赖
|
||||||
|
|
||||||
`manifest.json` 中包含:
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. 小程序配置
|
||||||
|
|
||||||
|
`src/manifest.json` 中包含:
|
||||||
|
|
||||||
- `mp-weixin.appid`
|
- `mp-weixin.appid`
|
||||||
- 微信端 `urlCheck` 等基础配置
|
- 微信端 `urlCheck` 等基础配置
|
||||||
|
|
||||||
## 4. 运行
|
## 5. 运行
|
||||||
|
|
||||||
在 HBuilderX 中:
|
微信小程序本地开发:
|
||||||
|
|
||||||
1. 导入项目目录
|
```bash
|
||||||
2. 运行到 `微信开发者工具`
|
npm run dev:mp-weixin
|
||||||
3. 确认接口可访问后开始联调
|
```
|
||||||
|
|
||||||
|
微信开发者工具导入目录:
|
||||||
|
|
||||||
|
```text
|
||||||
|
dist/dev/mp-weixin
|
||||||
|
```
|
||||||
|
|
||||||
|
H5 调试:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev:h5
|
||||||
|
```
|
||||||
|
|
||||||
|
构建:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build:h5
|
||||||
|
npm run build:mp-weixin
|
||||||
|
```
|
||||||
|
|
||||||
## 接口与文档
|
## 接口与文档
|
||||||
|
|
||||||
@@ -109,21 +137,22 @@ smt/
|
|||||||
- 抽烟记录 API:`docs/api.md`
|
- 抽烟记录 API:`docs/api.md`
|
||||||
- 登录认证:`docs/auth.md`
|
- 登录认证:`docs/auth.md`
|
||||||
- 算法说明:`docs/ALGORITHM.md`
|
- 算法说明:`docs/ALGORITHM.md`
|
||||||
- 组件文档:`components/smoke-record-dialog/README.md`
|
- 组件文档:`src/components/smoke-record-dialog/README.md`
|
||||||
|
|
||||||
## 关键实现说明
|
## 关键实现说明
|
||||||
|
|
||||||
- 全局启动时在 `App.vue` 发起静默登录
|
- 全局启动时在 `src/App.vue` 发起静默登录
|
||||||
- 业务页面通过 `useLogin().waitForLogin()` 确保登录完成后请求接口
|
- 业务页面通过 `useLogin().waitForLogin()` 确保登录完成后请求接口
|
||||||
- `api/request.js` 统一处理请求:
|
- `src/api/request.js` 统一处理请求:
|
||||||
- 自动注入 `Authorization: Bearer <session_key>`
|
- 自动注入 `Authorization: Bearer <session_key>`
|
||||||
- 401 自动登录并重试一次
|
- 401 自动登录并重试一次
|
||||||
|
|
||||||
## 注意事项
|
## 注意事项
|
||||||
|
|
||||||
- `config/index.js` 里默认开发地址是局域网 IP,跨设备调试需改成可访问地址
|
- `src/config/index.js` 里默认开发地址是局域网 IP,跨设备调试需改成可访问地址
|
||||||
- 历史记录与统计页依赖后端返回格式,联调时请以 `docs/api.md` 为准
|
- 历史记录与统计页依赖后端返回格式,联调时请以 `docs/api.md` 为准
|
||||||
- 仓库中 `docs/*` 可能存在进行中的改动,提交前建议按需选择暂存文件
|
- 仓库中 `docs/*` 可能存在进行中的改动,提交前建议按需选择暂存文件
|
||||||
|
- GitHub Actions CI 会在 `master` / `main` 推送和 PR 时执行 `npm ci`、`build:h5`、`build:mp-weixin`
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,6 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"><!--app-html--></div>
|
<div id="app"><!--app-html--></div>
|
||||||
<script type="module" src="/main.js"></script>
|
<script type="module" src="/src/main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "smt",
|
||||||
|
"type": "module",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev:h5": "uni -p h5",
|
||||||
|
"dev:mp-weixin": "uni -p mp-weixin",
|
||||||
|
"build:h5": "uni build -p h5",
|
||||||
|
"build:mp-weixin": "uni build -p mp-weixin",
|
||||||
|
"about": "uni --help"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@dcloudio/uni-app": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-app-harmony": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-app-plus": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-components": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-h5": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-mp-alipay": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-mp-baidu": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-mp-harmony": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-mp-jd": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-mp-kuaishou": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-mp-lark": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-mp-qq": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-mp-toutiao": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-mp-weixin": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-mp-xhs": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-quickapp-webview": "3.0.0-4080720251210001",
|
||||||
|
"pinia": "2.1.7",
|
||||||
|
"vue": "3.4.21"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@dcloudio/types": "3.4.19",
|
||||||
|
"@dcloudio/uni-cli-shared": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/vite-plugin-uni": "3.0.0-4080720251210001",
|
||||||
|
"@uni-helper/plugin-uni": "0.1.0",
|
||||||
|
"@uni-helper/unh": "^0.2.10",
|
||||||
|
"sass": "1.64.2",
|
||||||
|
"vite": "5.2.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,7 +48,10 @@ export default {
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
page {
|
page {
|
||||||
background: linear-gradient(to bottom, #D1FAE5 0%, #F0FDF4 45%, #FFFFFF 100%);
|
background:
|
||||||
|
radial-gradient(circle at top left, rgba(52, 200, 160, 0.14), transparent 28%),
|
||||||
|
radial-gradient(circle at top right, rgba(255, 255, 255, 0.78), transparent 24%),
|
||||||
|
linear-gradient(180deg, #eef3f8 0%, #f5f7fb 38%, #fbfdff 100%);
|
||||||
color: #111827;
|
color: #111827;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
@@ -62,28 +65,30 @@ page {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 24rpx;
|
border-radius: 28rpx;
|
||||||
padding: 32rpx;
|
padding: 32rpx;
|
||||||
margin-bottom: 24rpx;
|
margin-bottom: 24rpx;
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.64);
|
||||||
box-shadow: 0 8rpx 20rpx rgba(16, 185, 129, 0.08);
|
box-shadow: 0 10rpx 30rpx rgba(15, 23, 42, 0.06);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-light {
|
.card-light {
|
||||||
background-color: #F0FDF4;
|
background: rgba(255, 255, 255, 0.62);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-primary {
|
.text-primary {
|
||||||
color: #10B981;
|
color: #1AA37A;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-secondary {
|
.text-secondary {
|
||||||
color: #6B7280;
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-muted {
|
.text-muted {
|
||||||
color: #9CA3AF;
|
color: #98A2B3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-center {
|
.text-center {
|
||||||
@@ -160,26 +165,54 @@ page {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 96rpx;
|
height: 96rpx;
|
||||||
border-radius: 48rpx;
|
border-radius: 999rpx;
|
||||||
font-size: 32rpx;
|
font-size: 32rpx;
|
||||||
font-weight: 500;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
background-color: #10B981;
|
background: linear-gradient(180deg, #32c59d 0%, #1aa37a 100%);
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
|
box-shadow: 0 12rpx 28rpx rgba(26, 163, 122, 0.22);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-secondary {
|
.btn-secondary {
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
color: #111827;
|
color: #111827;
|
||||||
border: 2rpx solid #E5E7EB;
|
border: 2rpx solid rgba(15, 23, 42, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-outline {
|
.btn-outline {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: #10B981;
|
color: #1AA37A;
|
||||||
border: 2rpx solid #10B981;
|
border: 2rpx solid rgba(26, 163, 122, 0.32);
|
||||||
|
}
|
||||||
|
|
||||||
|
.glass-card {
|
||||||
|
background: rgba(255, 255, 255, 0.68);
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
|
box-shadow: 0 12rpx 32rpx rgba(15, 23, 42, 0.07);
|
||||||
|
backdrop-filter: blur(28rpx);
|
||||||
|
-webkit-backdrop-filter: blur(28rpx);
|
||||||
|
}
|
||||||
|
|
||||||
|
.surface-card {
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
border: 2rpx solid rgba(15, 23, 42, 0.06);
|
||||||
|
box-shadow: 0 10rpx 30rpx rgba(15, 23, 42, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pill-chip {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 12rpx 22rpx;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.72);
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.68);
|
||||||
|
color: #475467;
|
||||||
|
font-size: 22rpx;
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.safe-area-bottom {
|
.safe-area-bottom {
|
||||||
@@ -248,7 +248,7 @@ export default {
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background-color: rgba(0, 0, 0, 0.35);
|
background-color: rgba(15, 23, 42, 0.22);
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
@@ -257,12 +257,15 @@ export default {
|
|||||||
.dialog-container {
|
.dialog-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-height: 85vh;
|
max-height: 85vh;
|
||||||
background-color: #FFFFFF;
|
background: rgba(248, 250, 252, 0.9);
|
||||||
border-radius: 36rpx 36rpx 0 0;
|
border-radius: 36rpx 36rpx 0 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transform: translateY(100%);
|
transform: translateY(100%);
|
||||||
transition: transform 0.3s ease-out;
|
transition: transform 0.3s ease-out;
|
||||||
padding-bottom: 16rpx;
|
padding-bottom: 16rpx;
|
||||||
|
border-top: 2rpx solid rgba(255, 255, 255, 0.72);
|
||||||
|
backdrop-filter: blur(28rpx);
|
||||||
|
-webkit-backdrop-filter: blur(28rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-show {
|
.dialog-show {
|
||||||
@@ -272,7 +275,7 @@ export default {
|
|||||||
.dialog-handle {
|
.dialog-handle {
|
||||||
width: 80rpx;
|
width: 80rpx;
|
||||||
height: 8rpx;
|
height: 8rpx;
|
||||||
background-color: #E5E7EB;
|
background-color: rgba(152, 162, 179, 0.45);
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
margin: 16rpx auto 0;
|
margin: 16rpx auto 0;
|
||||||
}
|
}
|
||||||
@@ -297,9 +300,9 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 44rpx;
|
font-size: 44rpx;
|
||||||
color: #9CA3AF;
|
color: #98A2B3;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
background-color: #F3F4F6;
|
background-color: rgba(255, 255, 255, 0.78);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,10 +323,10 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.input-card {
|
.input-card {
|
||||||
background-color: #F9FAFB;
|
background-color: rgba(255, 255, 255, 0.78);
|
||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
padding: 20rpx 24rpx;
|
padding: 20rpx 24rpx;
|
||||||
border: 2rpx solid #F3F4F6;
|
border: 2rpx solid rgba(255, 255, 255, 0.72);
|
||||||
min-height: 120rpx;
|
min-height: 120rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -392,11 +395,11 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.section-card {
|
.section-card {
|
||||||
background-color: #FFFFFF;
|
background-color: rgba(255, 255, 255, 0.84);
|
||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
border: 2rpx solid #F3F4F6;
|
border: 2rpx solid rgba(255, 255, 255, 0.72);
|
||||||
box-shadow: 0 4rpx 12rpx rgba(15, 23, 42, 0.04);
|
box-shadow: 0 10rpx 24rpx rgba(15, 23, 42, 0.05);
|
||||||
margin-bottom: 24rpx;
|
margin-bottom: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,7 +451,7 @@ export default {
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 20rpx;
|
gap: 20rpx;
|
||||||
background-color: #F8FAFC;
|
background-color: rgba(247, 249, 252, 0.92);
|
||||||
padding: 12rpx 16rpx;
|
padding: 12rpx 16rpx;
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
border: 2rpx solid #F1F5F9;
|
border: 2rpx solid #F1F5F9;
|
||||||
@@ -461,12 +464,12 @@ export default {
|
|||||||
width: 56rpx;
|
width: 56rpx;
|
||||||
height: 56rpx;
|
height: 56rpx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: #E8FFF1;
|
background-color: rgba(255, 255, 255, 0.9);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 36rpx;
|
font-size: 36rpx;
|
||||||
color: #22C55E;
|
color: #1aa37a;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,8 +491,8 @@ export default {
|
|||||||
.level-badge {
|
.level-badge {
|
||||||
padding: 8rpx 18rpx;
|
padding: 8rpx 18rpx;
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
background-color: #DCFCE7;
|
background-color: rgba(52, 200, 160, 0.14);
|
||||||
color: #22C55E;
|
color: #1aa37a;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
@@ -515,16 +518,16 @@ export default {
|
|||||||
|
|
||||||
.remark-card {
|
.remark-card {
|
||||||
margin-top: 16rpx;
|
margin-top: 16rpx;
|
||||||
background-color: #F9FAFB;
|
background-color: rgba(255, 255, 255, 0.78);
|
||||||
border-radius: 20rpx;
|
border-radius: 20rpx;
|
||||||
padding: 8rpx;
|
padding: 8rpx;
|
||||||
border: 2rpx solid #F3F4F6;
|
border: 2rpx solid rgba(255, 255, 255, 0.72);
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-textarea {
|
.form-textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 180rpx;
|
min-height: 180rpx;
|
||||||
background-color: #F9FAFB;
|
background-color: rgba(255, 255, 255, 0);
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
padding: 24rpx 20rpx;
|
padding: 24rpx 20rpx;
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
@@ -540,19 +543,19 @@ export default {
|
|||||||
.dialog-btn-primary {
|
.dialog-btn-primary {
|
||||||
height: 96rpx;
|
height: 96rpx;
|
||||||
border-radius: 32rpx;
|
border-radius: 32rpx;
|
||||||
background-color: #22C55E;
|
background: linear-gradient(180deg, #32c59d 0%, #1aa37a 100%);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 16rpx;
|
gap: 16rpx;
|
||||||
box-shadow: 0 10rpx 24rpx rgba(34, 197, 94, 0.3);
|
box-shadow: 0 12rpx 28rpx rgba(26, 163, 122, 0.22);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-icon {
|
.btn-icon {
|
||||||
width: 44rpx;
|
width: 44rpx;
|
||||||
height: 44rpx;
|
height: 44rpx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: #0F172A;
|
background-color: rgba(255, 255, 255, 0.24);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,6 +574,6 @@ export default {
|
|||||||
.btn-text {
|
.btn-text {
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #0F172A;
|
color: #FFFFFF;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
{
|
{
|
||||||
"path": "pages/profile/index",
|
"path": "pages/profile/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "个人中心"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -70,15 +70,15 @@
|
|||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
"navigationBarTextStyle": "black",
|
"navigationBarTextStyle": "black",
|
||||||
"navigationBarTitleText": "戒烟助手",
|
"navigationBarTitleText": "戒烟助手",
|
||||||
"navigationBarBackgroundColor": "#F0FDF4",
|
"navigationBarBackgroundColor": "#F5F7FB",
|
||||||
"backgroundColor": "#F0FDF4",
|
"backgroundColor": "#F5F7FB",
|
||||||
"backgroundColorTop": "#D1FAE5",
|
"backgroundColorTop": "#EEF3F8",
|
||||||
"backgroundColorBottom": "#FFFFFF"
|
"backgroundColorBottom": "#FBFDFF"
|
||||||
},
|
},
|
||||||
"tabBar": {
|
"tabBar": {
|
||||||
"color": "#9CA3AF",
|
"color": "#98A2B3",
|
||||||
"selectedColor": "#10B981",
|
"selectedColor": "#1AA37A",
|
||||||
"backgroundColor": "#FFFFFF",
|
"backgroundColor": "#F9FBFD",
|
||||||
"borderStyle": "white",
|
"borderStyle": "white",
|
||||||
"list": [
|
"list": [
|
||||||
{
|
{
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page">
|
<view class="page">
|
||||||
|
<view class="page-glow page-glow-a"></view>
|
||||||
|
<view class="page-glow page-glow-b"></view>
|
||||||
<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
|
<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
|
||||||
<view class="container">
|
<view class="container">
|
||||||
<view class="hero-card">
|
<view class="hero-card">
|
||||||
@@ -20,7 +22,7 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-if="suggestedClock" class="suggested-pill">
|
<view v-if="suggestedClock" class="suggested-pill">
|
||||||
<text class="suggested-pill-label">✨ 下次建议</text>
|
<text class="suggested-pill-label">下次建议</text>
|
||||||
<text class="suggested-pill-value">{{ suggestedClock }}</text>
|
<text class="suggested-pill-value">{{ suggestedClock }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -211,25 +213,58 @@ onShow(async () => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.page {
|
.page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: linear-gradient(to bottom, #D1FAE5 0%, #F0FDF4 45%, #FFFFFF 100%);
|
position: relative;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at top left, rgba(52, 200, 160, 0.16), transparent 30%),
|
||||||
|
radial-gradient(circle at top right, rgba(255, 255, 255, 0.92), transparent 24%),
|
||||||
|
linear-gradient(180deg, #edf2f8 0%, #f5f7fb 38%, #fbfdff 100%);
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-bar {
|
.status-bar {
|
||||||
background: linear-gradient(to bottom, #D1FAE5, #E9FDF2);
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(24rpx);
|
||||||
|
opacity: 0.72;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow-a {
|
||||||
|
top: 80rpx;
|
||||||
|
left: -140rpx;
|
||||||
|
width: 360rpx;
|
||||||
|
height: 360rpx;
|
||||||
|
background: rgba(52, 200, 160, 0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow-b {
|
||||||
|
top: 320rpx;
|
||||||
|
right: -120rpx;
|
||||||
|
width: 320rpx;
|
||||||
|
height: 320rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
padding: 24rpx 32rpx 80rpx;
|
padding: 24rpx 32rpx 80rpx;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-card,
|
.hero-card,
|
||||||
.section-card,
|
.section-card,
|
||||||
.advice-card,
|
.advice-card,
|
||||||
.empty-card {
|
.empty-card {
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.8);
|
||||||
border-radius: 28rpx;
|
border-radius: 32rpx;
|
||||||
border: 2rpx solid #D9FBE7;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 10rpx 24rpx rgba(16, 185, 129, 0.08);
|
box-shadow: 0 16rpx 36rpx rgba(15, 23, 42, 0.06);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-card {
|
.hero-card {
|
||||||
@@ -239,7 +274,7 @@ onShow(async () => {
|
|||||||
|
|
||||||
.hero-label {
|
.hero-label {
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
color: #059669;
|
color: #1a7f61;
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 12rpx;
|
margin-bottom: 12rpx;
|
||||||
}
|
}
|
||||||
@@ -254,7 +289,7 @@ onShow(async () => {
|
|||||||
|
|
||||||
.hero-desc {
|
.hero-desc {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #6B7280;
|
color: #667085;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +314,7 @@ onShow(async () => {
|
|||||||
|
|
||||||
.section-subtitle {
|
.section-subtitle {
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
color: #6B7280;
|
color: #667085;
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 8rpx;
|
margin-top: 8rpx;
|
||||||
}
|
}
|
||||||
@@ -287,7 +322,8 @@ onShow(async () => {
|
|||||||
.primary-btn {
|
.primary-btn {
|
||||||
padding: 10rpx 24rpx;
|
padding: 10rpx 24rpx;
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
background: linear-gradient(135deg, #34D399, #10B981);
|
background: linear-gradient(180deg, #32c59d 0%, #1aa37a 100%);
|
||||||
|
box-shadow: 0 12rpx 28rpx rgba(26, 163, 122, 0.22);
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-btn-text {
|
.primary-btn-text {
|
||||||
@@ -302,14 +338,14 @@ onShow(async () => {
|
|||||||
gap: 12rpx;
|
gap: 12rpx;
|
||||||
padding: 14rpx 22rpx;
|
padding: 14rpx 22rpx;
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
background: #ECFDF5;
|
background: rgba(255, 255, 255, 0.88);
|
||||||
border: 2rpx solid #D1FAE5;
|
border: 2rpx solid rgba(255, 255, 255, 0.72);
|
||||||
margin-bottom: 24rpx;
|
margin-bottom: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.suggested-pill-label {
|
.suggested-pill-label {
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
color: #059669;
|
color: #1a7f61;
|
||||||
}
|
}
|
||||||
|
|
||||||
.suggested-pill-value {
|
.suggested-pill-value {
|
||||||
@@ -338,7 +374,7 @@ onShow(async () => {
|
|||||||
width: 20rpx;
|
width: 20rpx;
|
||||||
height: 20rpx;
|
height: 20rpx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: #D1FAE5;
|
background-color: rgba(152, 162, 179, 0.4);
|
||||||
margin-bottom: 8rpx;
|
margin-bottom: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,12 +384,12 @@ onShow(async () => {
|
|||||||
left: calc(50% + 18rpx);
|
left: calc(50% + 18rpx);
|
||||||
right: -50%;
|
right: -50%;
|
||||||
height: 2rpx;
|
height: 2rpx;
|
||||||
background-color: #D1FAE5;
|
background-color: rgba(152, 162, 179, 0.32);
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-time {
|
.timeline-time {
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
color: #9CA3AF;
|
color: #98A2B3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-node-past .timeline-dot {
|
.timeline-node-past .timeline-dot {
|
||||||
@@ -365,37 +401,37 @@ onShow(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.timeline-node-current .timeline-dot {
|
.timeline-node-current .timeline-dot {
|
||||||
background-color: #10B981;
|
background-color: #1aa37a;
|
||||||
width: 24rpx;
|
width: 24rpx;
|
||||||
height: 24rpx;
|
height: 24rpx;
|
||||||
box-shadow: 0 0 12rpx rgba(16, 185, 129, 0.5);
|
box-shadow: 0 0 12rpx rgba(16, 185, 129, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-node-current .timeline-time {
|
.timeline-node-current .timeline-time {
|
||||||
color: #059669;
|
color: #1a7f61;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-node-future .timeline-time {
|
.timeline-node-future .timeline-time {
|
||||||
color: #6B7280;
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.advice-card {
|
.advice-card {
|
||||||
padding: 22rpx;
|
padding: 22rpx;
|
||||||
background-color: #F0FDF4;
|
background-color: rgba(247, 249, 252, 0.92);
|
||||||
}
|
}
|
||||||
|
|
||||||
.advice-title {
|
.advice-title {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #059669;
|
color: #1a7f61;
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 8rpx;
|
margin-bottom: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.advice-text {
|
.advice-text {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #374151;
|
color: #344054;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,7 +449,7 @@ onShow(async () => {
|
|||||||
|
|
||||||
.empty-desc {
|
.empty-desc {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #6B7280;
|
color: #667085;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page">
|
<view class="page">
|
||||||
|
<view class="page-glow page-glow-a"></view>
|
||||||
|
<view class="page-glow page-glow-b"></view>
|
||||||
<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
|
<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
|
||||||
<view class="container">
|
<view class="container">
|
||||||
<view class="hero-card">
|
<view class="hero-card">
|
||||||
@@ -233,15 +235,46 @@ onShow(async () => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.page {
|
.page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: linear-gradient(to bottom, #D1FAE5 0%, #F0FDF4 45%, #FFFFFF 100%);
|
position: relative;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at top left, rgba(52, 200, 160, 0.16), transparent 30%),
|
||||||
|
radial-gradient(circle at top right, rgba(255, 255, 255, 0.92), transparent 24%),
|
||||||
|
linear-gradient(180deg, #edf2f8 0%, #f5f7fb 38%, #fbfdff 100%);
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-bar {
|
.status-bar {
|
||||||
background: linear-gradient(to bottom, #D1FAE5, #E9FDF2);
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(24rpx);
|
||||||
|
opacity: 0.72;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow-a {
|
||||||
|
top: 80rpx;
|
||||||
|
left: -140rpx;
|
||||||
|
width: 360rpx;
|
||||||
|
height: 360rpx;
|
||||||
|
background: rgba(52, 200, 160, 0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow-b {
|
||||||
|
top: 320rpx;
|
||||||
|
right: -120rpx;
|
||||||
|
width: 320rpx;
|
||||||
|
height: 320rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
padding: 24rpx 32rpx 80rpx;
|
padding: 24rpx 32rpx 80rpx;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-card,
|
.hero-card,
|
||||||
@@ -249,10 +282,12 @@ onShow(async () => {
|
|||||||
.summary-card,
|
.summary-card,
|
||||||
.highlights-card,
|
.highlights-card,
|
||||||
.suggestion-card {
|
.suggestion-card {
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.8);
|
||||||
border-radius: 28rpx;
|
border-radius: 32rpx;
|
||||||
border: 2rpx solid #D9FBE7;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 10rpx 24rpx rgba(16, 185, 129, 0.08);
|
box-shadow: 0 16rpx 36rpx rgba(15, 23, 42, 0.06);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-card {
|
.hero-card {
|
||||||
@@ -262,7 +297,7 @@ onShow(async () => {
|
|||||||
|
|
||||||
.hero-label {
|
.hero-label {
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
color: #059669;
|
color: #1a7f61;
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 12rpx;
|
margin-bottom: 12rpx;
|
||||||
}
|
}
|
||||||
@@ -277,7 +312,7 @@ onShow(async () => {
|
|||||||
|
|
||||||
.hero-desc {
|
.hero-desc {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #6B7280;
|
color: #667085;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,13 +328,13 @@ onShow(async () => {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 18rpx 22rpx;
|
padding: 18rpx 22rpx;
|
||||||
border-radius: 20rpx;
|
border-radius: 20rpx;
|
||||||
background: #F0FDF4;
|
background: rgba(247, 249, 252, 0.92);
|
||||||
border: 2rpx solid #D1FAE5;
|
border: 2rpx solid rgba(15, 23, 42, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
.date-picker-label {
|
.date-picker-label {
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
color: #6B7280;
|
color: #667085;
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 6rpx;
|
margin-bottom: 6rpx;
|
||||||
}
|
}
|
||||||
@@ -313,7 +348,8 @@ onShow(async () => {
|
|||||||
.primary-btn {
|
.primary-btn {
|
||||||
padding: 14rpx 24rpx;
|
padding: 14rpx 24rpx;
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
background: linear-gradient(135deg, #34D399, #10B981);
|
background: linear-gradient(180deg, #32c59d 0%, #1aa37a 100%);
|
||||||
|
box-shadow: 0 12rpx 28rpx rgba(26, 163, 122, 0.22);
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-btn-text {
|
.primary-btn-text {
|
||||||
@@ -333,12 +369,12 @@ onShow(async () => {
|
|||||||
|
|
||||||
.loading-text {
|
.loading-text {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #6B7280;
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-date {
|
.summary-date {
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
color: #059669;
|
color: #1a7f61;
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 12rpx;
|
margin-bottom: 12rpx;
|
||||||
}
|
}
|
||||||
@@ -354,13 +390,13 @@ onShow(async () => {
|
|||||||
.suggestion-card {
|
.suggestion-card {
|
||||||
margin-top: 20rpx;
|
margin-top: 20rpx;
|
||||||
padding: 22rpx;
|
padding: 22rpx;
|
||||||
background-color: #F9FFFB;
|
background-color: rgba(247, 249, 252, 0.92);
|
||||||
}
|
}
|
||||||
|
|
||||||
.block-title {
|
.block-title {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #059669;
|
color: #1a7f61;
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 10rpx;
|
||||||
}
|
}
|
||||||
@@ -378,7 +414,7 @@ onShow(async () => {
|
|||||||
|
|
||||||
.highlight-dot {
|
.highlight-dot {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: #10B981;
|
color: #1aa37a;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
@@ -387,7 +423,7 @@ onShow(async () => {
|
|||||||
.suggestion-text,
|
.suggestion-text,
|
||||||
.empty-desc {
|
.empty-desc {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #374151;
|
color: #344054;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page">
|
<view class="page">
|
||||||
|
<view class="page-glow page-glow-a"></view>
|
||||||
|
<view class="page-glow page-glow-b"></view>
|
||||||
<view class="nav-placeholder" :style="{ height: navBarHeight + 'px' }"></view>
|
<view class="nav-placeholder" :style="{ height: navBarHeight + 'px' }"></view>
|
||||||
|
|
||||||
<view v-if="loading" class="skeleton">
|
<view v-if="loading" class="skeleton">
|
||||||
@@ -14,21 +16,25 @@
|
|||||||
|
|
||||||
<view v-else class="dashboard">
|
<view v-else class="dashboard">
|
||||||
<view class="header-card">
|
<view class="header-card">
|
||||||
<view class="user-info">
|
<view class="header-copy">
|
||||||
<image class="avatar" :src="userAvatar" mode="aspectFill"></image>
|
<text class="header-eyebrow">SMT</text>
|
||||||
<view class="greeting">
|
<text class="greeting-text">{{ greetingTitle }}</text>
|
||||||
<text class="greeting-text">{{ greetingTitle }}</text>
|
<text class="greeting-sub">{{ greetingSubtitle }}</text>
|
||||||
<text class="greeting-sub">{{ greetingSubtitle }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="mode-chip" :class="isQuitMode ? 'mode-chip-quit' : 'mode-chip-record'">
|
<view class="header-side">
|
||||||
{{ isQuitMode ? '戒烟模式' : '记录模式' }}
|
<image class="avatar" :src="userAvatar" mode="aspectFill"></image>
|
||||||
|
<view class="mode-chip" :class="isQuitMode ? 'mode-chip-quit' : 'mode-chip-record'">
|
||||||
|
{{ isQuitMode ? '戒烟模式' : '记录模式' }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-if="isQuitMode">
|
<view v-if="isQuitMode">
|
||||||
<view class="hero-card hero-card-quit">
|
<view class="hero-card hero-card-quit">
|
||||||
<text class="hero-label">已坚持</text>
|
<view class="hero-meta-row">
|
||||||
|
<text class="hero-label">已坚持</text>
|
||||||
|
<text class="hero-inline-chip">{{ todayChecked ? '今日已打卡' : '今日待打卡' }}</text>
|
||||||
|
</view>
|
||||||
<view class="hero-value-row">
|
<view class="hero-value-row">
|
||||||
<text class="hero-value">{{ quitDays }}</text>
|
<text class="hero-value">{{ quitDays }}</text>
|
||||||
<text class="hero-unit">天</text>
|
<text class="hero-unit">天</text>
|
||||||
@@ -37,7 +43,7 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="primary-action" :class="{ 'primary-action-done': todayChecked }" @tap="handleQuitCheckin">
|
<view class="primary-action" :class="{ 'primary-action-done': todayChecked }" @tap="handleQuitCheckin">
|
||||||
<text class="primary-action-icon">{{ todayChecked ? '✓' : '🔥' }}</text>
|
<view class="primary-action-icon">{{ todayChecked ? '✓' : '打' }}</view>
|
||||||
<text class="primary-action-title">{{ todayChecked ? '今日已打卡' : '今天没抽,去打卡' }}</text>
|
<text class="primary-action-title">{{ todayChecked ? '今日已打卡' : '今天没抽,去打卡' }}</text>
|
||||||
<text class="primary-action-desc">{{ todayChecked ? `已于 ${todayCheckinTime} 记录` : '把今天记成无烟的一天' }}</text>
|
<text class="primary-action-desc">{{ todayChecked ? `已于 ${todayCheckinTime} 记录` : '把今天记成无烟的一天' }}</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -63,7 +69,10 @@
|
|||||||
|
|
||||||
<view v-else>
|
<view v-else>
|
||||||
<view class="hero-card hero-card-record">
|
<view class="hero-card hero-card-record">
|
||||||
<text class="hero-label">距上次抽烟</text>
|
<view class="hero-meta-row">
|
||||||
|
<text class="hero-label">距上次抽烟</text>
|
||||||
|
<text v-if="nextSmokeTimeText" class="hero-inline-chip">建议 {{ nextSmokeTimeText }}</text>
|
||||||
|
</view>
|
||||||
<text class="hero-value hero-value-time">{{ timerDisplay }}</text>
|
<text class="hero-value hero-value-time">{{ timerDisplay }}</text>
|
||||||
<text class="hero-sub">{{ nextSmokeTimeText ? `下次建议:${nextSmokeTimeText}` : '先把今天的抽烟情况记下来' }}</text>
|
<text class="hero-sub">{{ nextSmokeTimeText ? `下次建议:${nextSmokeTimeText}` : '先把今天的抽烟情况记下来' }}</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -83,12 +92,12 @@
|
|||||||
|
|
||||||
<view class="action-row">
|
<view class="action-row">
|
||||||
<view class="action-btn action-btn-record" @tap="openSmokeDialog">
|
<view class="action-btn action-btn-record" @tap="openSmokeDialog">
|
||||||
<text class="action-icon">🚬</text>
|
<view class="action-icon">记</view>
|
||||||
<text class="action-title">记录抽烟</text>
|
<text class="action-title">记录抽烟</text>
|
||||||
<text class="action-desc">补记这一根</text>
|
<text class="action-desc">补记这一根</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="action-btn action-btn-resist" @tap="openResistedDialog">
|
<view class="action-btn action-btn-resist" @tap="openResistedDialog">
|
||||||
<text class="action-icon">💪</text>
|
<view class="action-icon">忍</view>
|
||||||
<text class="action-title">想抽忍住了</text>
|
<text class="action-title">想抽忍住了</text>
|
||||||
<text class="action-desc">记一次成功抵抗</text>
|
<text class="action-desc">记一次成功抵抗</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -461,18 +470,48 @@ onShareAppMessage(() => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.page {
|
.page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
position: relative;
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle at top left, rgba(16, 185, 129, 0.16), transparent 36%),
|
radial-gradient(circle at top left, rgba(52, 200, 160, 0.18), transparent 34%),
|
||||||
linear-gradient(180deg, #ecfdf5 0%, #f0fdf4 42%, #ffffff 100%);
|
radial-gradient(circle at top right, rgba(255, 255, 255, 0.9), transparent 26%),
|
||||||
|
linear-gradient(180deg, #edf2f8 0%, #f5f7fb 38%, #fbfdff 100%);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-placeholder {
|
.page-glow {
|
||||||
background: transparent;
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(24rpx);
|
||||||
|
opacity: 0.7;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow-a {
|
||||||
|
top: 108rpx;
|
||||||
|
left: -140rpx;
|
||||||
|
width: 360rpx;
|
||||||
|
height: 360rpx;
|
||||||
|
background: rgba(52, 200, 160, 0.16);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow-b {
|
||||||
|
top: 280rpx;
|
||||||
|
right: -120rpx;
|
||||||
|
width: 320rpx;
|
||||||
|
height: 320rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.86);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-placeholder,
|
||||||
|
.dashboard,
|
||||||
|
.skeleton {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard {
|
.dashboard {
|
||||||
padding: 24rpx 24rpx 160rpx;
|
padding: 24rpx 24rpx 168rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-card,
|
.header-card,
|
||||||
@@ -482,37 +521,57 @@ onShareAppMessage(() => {
|
|||||||
.note-card,
|
.note-card,
|
||||||
.action-btn,
|
.action-btn,
|
||||||
.skeleton-card {
|
.skeleton-card {
|
||||||
background: rgba(255, 255, 255, 0.88);
|
background: rgba(255, 255, 255, 0.76);
|
||||||
border-radius: 28rpx;
|
border-radius: 32rpx;
|
||||||
border: 2rpx solid rgba(236, 253, 245, 0.9);
|
border: 2rpx solid rgba(255, 255, 255, 0.62);
|
||||||
box-shadow: 0 16rpx 42rpx rgba(15, 23, 42, 0.08);
|
box-shadow: 0 16rpx 42rpx rgba(15, 23, 42, 0.08);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-card {
|
.header-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: flex-start;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 28rpx;
|
padding: 30rpx;
|
||||||
margin-bottom: 24rpx;
|
margin-bottom: 28rpx;
|
||||||
}
|
|
||||||
|
|
||||||
.user-info {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 20rpx;
|
gap: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header-copy {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-side {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 14rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-eyebrow {
|
||||||
|
font-size: 20rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 4rpx;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #98a2b3;
|
||||||
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
width: 88rpx;
|
width: 92rpx;
|
||||||
height: 88rpx;
|
height: 92rpx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: 4rpx solid #a7f3d0;
|
border: 4rpx solid rgba(255, 255, 255, 0.82);
|
||||||
background: #ecfdf5;
|
background: rgba(255, 255, 255, 0.72);
|
||||||
}
|
}
|
||||||
|
|
||||||
.greeting-text {
|
.greeting-text {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 34rpx;
|
margin-top: 10rpx;
|
||||||
|
font-size: 42rpx;
|
||||||
|
line-height: 1.18;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #111827;
|
color: #111827;
|
||||||
}
|
}
|
||||||
@@ -522,7 +581,7 @@ onShareAppMessage(() => {
|
|||||||
margin-top: 8rpx;
|
margin-top: 8rpx;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
color: #6b7280;
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-chip {
|
.mode-chip {
|
||||||
@@ -530,38 +589,56 @@ onShareAppMessage(() => {
|
|||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.64);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-chip-quit {
|
.mode-chip-quit {
|
||||||
background: rgba(16, 185, 129, 0.12);
|
background: rgba(52, 200, 160, 0.14);
|
||||||
color: #047857;
|
color: #17795c;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-chip-record {
|
.mode-chip-record {
|
||||||
background: rgba(248, 113, 113, 0.12);
|
background: rgba(245, 158, 11, 0.12);
|
||||||
color: #b91c1c;
|
color: #b56b09;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-card {
|
.hero-card {
|
||||||
padding: 34rpx 30rpx;
|
padding: 36rpx 32rpx;
|
||||||
margin-bottom: 24rpx;
|
margin-bottom: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-card-quit {
|
.hero-card-quit {
|
||||||
background: linear-gradient(135deg, rgba(220, 252, 231, 0.92), rgba(255, 255, 255, 0.92));
|
background: linear-gradient(135deg, rgba(246, 255, 251, 0.88), rgba(255, 255, 255, 0.7));
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-card-record {
|
.hero-card-record {
|
||||||
background: linear-gradient(135deg, rgba(254, 242, 242, 0.92), rgba(255, 255, 255, 0.92));
|
background: linear-gradient(135deg, rgba(255, 250, 243, 0.88), rgba(255, 255, 255, 0.7));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-meta-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-label {
|
.hero-label {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #6b7280;
|
color: #667085;
|
||||||
letter-spacing: 2rpx;
|
letter-spacing: 2rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hero-inline-chip {
|
||||||
|
padding: 10rpx 18rpx;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.82);
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.7);
|
||||||
|
font-size: 22rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #475467;
|
||||||
|
}
|
||||||
|
|
||||||
.hero-value-row {
|
.hero-value-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
@@ -573,15 +650,15 @@ onShareAppMessage(() => {
|
|||||||
.hero-value-time {
|
.hero-value-time {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 18rpx;
|
margin-top: 18rpx;
|
||||||
font-size: 84rpx;
|
font-size: 82rpx;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
font-weight: 800;
|
font-weight: 700;
|
||||||
color: #111827;
|
color: #111827;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-unit {
|
.hero-unit {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: #4b5563;
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-sub {
|
.hero-sub {
|
||||||
@@ -589,40 +666,50 @@ onShareAppMessage(() => {
|
|||||||
margin-top: 18rpx;
|
margin-top: 18rpx;
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
color: #4b5563;
|
color: #475467;
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-action {
|
.primary-action {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: flex-start;
|
||||||
padding: 38rpx 30rpx;
|
padding: 36rpx 32rpx;
|
||||||
margin-bottom: 24rpx;
|
margin-bottom: 24rpx;
|
||||||
background: linear-gradient(135deg, #10b981 0%, #34d399 100%);
|
background: linear-gradient(180deg, #32c59d 0%, #1aa37a 100%);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
|
box-shadow: 0 16rpx 36rpx rgba(26, 163, 122, 0.24);
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-action-done {
|
.primary-action-done {
|
||||||
background: linear-gradient(135deg, #059669 0%, #10b981 100%);
|
background: linear-gradient(180deg, #1f9f7a 0%, #188564 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-action-icon {
|
.primary-action-icon {
|
||||||
font-size: 58rpx;
|
width: 68rpx;
|
||||||
|
height: 68rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: rgba(255, 255, 255, 0.18);
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.22);
|
||||||
|
font-size: 30rpx;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-action-title {
|
.primary-action-title {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 12rpx;
|
margin-top: 18rpx;
|
||||||
font-size: 34rpx;
|
font-size: 34rpx;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-action-desc {
|
.primary-action-desc {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 12rpx;
|
margin-top: 10rpx;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
opacity: 0.88;
|
line-height: 1.55;
|
||||||
|
opacity: 0.9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-grid {
|
.stats-grid {
|
||||||
@@ -633,28 +720,31 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.stat-card {
|
.stat-card {
|
||||||
padding: 28rpx 24rpx;
|
padding: 28rpx 24rpx 26rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.86);
|
||||||
|
border: 2rpx solid rgba(15, 23, 42, 0.05);
|
||||||
|
box-shadow: 0 10rpx 30rpx rgba(15, 23, 42, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-label {
|
.stat-label {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #6b7280;
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-value {
|
.stat-value {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 18rpx;
|
margin-top: 18rpx;
|
||||||
font-size: 48rpx;
|
font-size: 46rpx;
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
font-weight: 800;
|
font-weight: 700;
|
||||||
color: #111827;
|
color: #111827;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-unit {
|
.stat-unit {
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #6b7280;
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-desc {
|
.stat-desc {
|
||||||
@@ -662,18 +752,22 @@ onShareAppMessage(() => {
|
|||||||
margin-top: 16rpx;
|
margin-top: 16rpx;
|
||||||
font-size: 23rpx;
|
font-size: 23rpx;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
color: #6b7280;
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-card {
|
.note-card {
|
||||||
padding: 28rpx;
|
padding: 28rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.84);
|
||||||
|
border: 2rpx solid rgba(15, 23, 42, 0.05);
|
||||||
|
box-shadow: 0 10rpx 30rpx rgba(15, 23, 42, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-title {
|
.note-title {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #047857;
|
color: #1a7f61;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
letter-spacing: 1rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-text {
|
.note-text {
|
||||||
@@ -681,7 +775,7 @@ onShareAppMessage(() => {
|
|||||||
margin-top: 14rpx;
|
margin-top: 14rpx;
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
color: #374151;
|
color: #344054;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-row {
|
.action-row {
|
||||||
@@ -691,19 +785,32 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.action-btn {
|
.action-btn {
|
||||||
padding: 30rpx 24rpx;
|
padding: 30rpx 24rpx 28rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.86);
|
||||||
|
border: 2rpx solid rgba(15, 23, 42, 0.05);
|
||||||
|
box-shadow: 0 10rpx 30rpx rgba(15, 23, 42, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-btn-record {
|
.action-btn-record {
|
||||||
background: linear-gradient(135deg, rgba(254, 226, 226, 0.92), rgba(255, 255, 255, 0.92));
|
background: linear-gradient(135deg, rgba(255, 248, 239, 0.95), rgba(255, 255, 255, 0.88));
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-btn-resist {
|
.action-btn-resist {
|
||||||
background: linear-gradient(135deg, rgba(220, 252, 231, 0.92), rgba(255, 255, 255, 0.92));
|
background: linear-gradient(135deg, rgba(245, 255, 251, 0.95), rgba(255, 255, 255, 0.88));
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-icon {
|
.action-icon {
|
||||||
font-size: 40rpx;
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
border-radius: 18rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.76);
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #111827;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-title {
|
.action-title {
|
||||||
@@ -734,7 +841,7 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.skeleton-card {
|
.skeleton-card {
|
||||||
height: 180rpx;
|
height: 180rpx;
|
||||||
background: linear-gradient(90deg, #d1fae5 25%, #ecfdf5 50%, #d1fae5 75%);
|
background: linear-gradient(90deg, rgba(232, 238, 245, 0.92) 25%, rgba(255, 255, 255, 0.98) 50%, rgba(232, 238, 245, 0.92) 75%);
|
||||||
background-size: 200% 100%;
|
background-size: 200% 100%;
|
||||||
animation: shimmer 1.5s infinite;
|
animation: shimmer 1.5s infinite;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
@@ -1,5 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page">
|
<view class="page">
|
||||||
|
<view class="page-glow page-glow-a"></view>
|
||||||
|
<view class="page-glow page-glow-b"></view>
|
||||||
|
<view class="page-header">
|
||||||
|
<text class="page-eyebrow">History</text>
|
||||||
|
<text class="page-title">记录历史</text>
|
||||||
|
<text class="page-subtitle">按时间查看抽烟和忍住记录。</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 筛选标签 -->
|
<!-- 筛选标签 -->
|
||||||
<view class="filters">
|
<view class="filters">
|
||||||
<view class="tabs">
|
<view class="tabs">
|
||||||
@@ -48,8 +56,8 @@
|
|||||||
<view v-for="log in group" :key="log.id" class="log-card" :class="log.type === 'resisted' ? 'log-card-resisted' : 'log-card-smoke'">
|
<view v-for="log in group" :key="log.id" class="log-card" :class="log.type === 'resisted' ? 'log-card-resisted' : 'log-card-smoke'">
|
||||||
<view class="log-bar"></view>
|
<view class="log-bar"></view>
|
||||||
<view class="log-icon" :class="log.type === 'resisted' ? 'icon-resisted' : 'icon-smoke'">
|
<view class="log-icon" :class="log.type === 'resisted' ? 'icon-resisted' : 'icon-smoke'">
|
||||||
<text v-if="log.type === 'resisted'">🌿</text>
|
<text v-if="log.type === 'resisted'">忍</text>
|
||||||
<text v-else>🚬</text>
|
<text v-else>烟</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="log-main">
|
<view class="log-main">
|
||||||
<view class="log-top">
|
<view class="log-top">
|
||||||
@@ -91,7 +99,7 @@
|
|||||||
|
|
||||||
<!-- 空状态 -->
|
<!-- 空状态 -->
|
||||||
<view v-else class="empty-state">
|
<view v-else class="empty-state">
|
||||||
<text class="empty-icon">📝</text>
|
<text class="empty-icon">记</text>
|
||||||
<text class="empty-text">暂无记录</text>
|
<text class="empty-text">暂无记录</text>
|
||||||
<text class="empty-hint">点击右下角按钮开始记录</text>
|
<text class="empty-hint">点击右下角按钮开始记录</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -297,25 +305,94 @@ onShareAppMessage(() => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.page {
|
.page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: linear-gradient(to bottom, #D1FAE5 0%, #F3FFF8 45%, #FFFFFF 100%);
|
position: relative;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at top left, rgba(52, 200, 160, 0.16), transparent 30%),
|
||||||
|
radial-gradient(circle at top right, rgba(255, 255, 255, 0.92), transparent 24%),
|
||||||
|
linear-gradient(180deg, #edf2f8 0%, #f5f7fb 38%, #fbfdff 100%);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(24rpx);
|
||||||
|
opacity: 0.72;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow-a {
|
||||||
|
top: 60rpx;
|
||||||
|
left: -140rpx;
|
||||||
|
width: 360rpx;
|
||||||
|
height: 360rpx;
|
||||||
|
background: rgba(52, 200, 160, 0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow-b {
|
||||||
|
top: 360rpx;
|
||||||
|
right: -120rpx;
|
||||||
|
width: 320rpx;
|
||||||
|
height: 320rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header,
|
||||||
|
.filters,
|
||||||
|
.scroll-container,
|
||||||
|
.fab {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
padding: 32rpx 32rpx 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-eyebrow {
|
||||||
|
display: block;
|
||||||
|
font-size: 20rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 4rpx;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #98a2b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
display: block;
|
||||||
|
margin-top: 10rpx;
|
||||||
|
font-size: 42rpx;
|
||||||
|
line-height: 1.18;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #111827;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-subtitle {
|
||||||
|
display: block;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filters {
|
.filters {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16rpx;
|
gap: 16rpx;
|
||||||
padding: 24rpx 32rpx 8rpx;
|
padding: 16rpx 32rpx 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs {
|
.tabs {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.76);
|
||||||
border-radius: 20rpx;
|
border-radius: 24rpx;
|
||||||
padding: 6rpx;
|
padding: 6rpx;
|
||||||
box-shadow: 0 8rpx 20rpx rgba(16, 185, 129, 0.08);
|
box-shadow: 0 12rpx 28rpx rgba(15, 23, 42, 0.06);
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab {
|
.tab {
|
||||||
@@ -330,9 +407,9 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tab-active {
|
.tab-active {
|
||||||
background-color: #10B981;
|
background: rgba(255, 255, 255, 0.92);
|
||||||
color: #0B2F23;
|
color: #111827;
|
||||||
box-shadow: 0 6rpx 16rpx rgba(16, 185, 129, 0.25);
|
box-shadow: 0 8rpx 18rpx rgba(15, 23, 42, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-btn {
|
.filter-btn {
|
||||||
@@ -381,9 +458,10 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.skeleton-card {
|
.skeleton-card {
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 24rpx;
|
border-radius: 28rpx;
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
}
|
}
|
||||||
|
|
||||||
.skeleton-line {
|
.skeleton-line {
|
||||||
@@ -433,8 +511,8 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.group-count {
|
.group-count {
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
color: #64748B;
|
color: #667085;
|
||||||
background-color: #E8FFF1;
|
background-color: rgba(255, 255, 255, 0.76);
|
||||||
padding: 6rpx 16rpx;
|
padding: 6rpx 16rpx;
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
}
|
}
|
||||||
@@ -447,23 +525,25 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.log-card {
|
.log-card {
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 24rpx;
|
border-radius: 28rpx;
|
||||||
padding: 24rpx 24rpx 20rpx 24rpx;
|
padding: 24rpx 24rpx 20rpx 24rpx;
|
||||||
box-shadow: 0 8rpx 20rpx rgba(15, 23, 42, 0.06);
|
box-shadow: 0 14rpx 32rpx rgba(15, 23, 42, 0.06);
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 20rpx;
|
gap: 20rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-card-resisted {
|
.log-card-resisted {
|
||||||
background-color: #F6FFFA;
|
background: linear-gradient(135deg, rgba(245, 255, 251, 0.95), rgba(255, 255, 255, 0.88));
|
||||||
border: 2rpx solid #E8FFF1;
|
border: 2rpx solid rgba(255, 255, 255, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-card-smoke {
|
.log-card-smoke {
|
||||||
background-color: #FFF7F5;
|
background: linear-gradient(135deg, rgba(255, 248, 242, 0.95), rgba(255, 255, 255, 0.88));
|
||||||
border: 2rpx solid #FFE4E6;
|
border: 2rpx solid rgba(255, 255, 255, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-bar {
|
.log-bar {
|
||||||
@@ -486,7 +566,8 @@ onShareAppMessage(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 36rpx;
|
font-size: 26rpx;
|
||||||
|
font-weight: 700;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,7 +649,7 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.log-desc {
|
.log-desc {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #475569;
|
color: #475467;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 10rpx;
|
||||||
}
|
}
|
||||||
@@ -588,8 +669,8 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.log-interval {
|
.log-interval {
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
color: #64748B;
|
color: #667085;
|
||||||
background-color: #F1F5F9;
|
background-color: rgba(255, 255, 255, 0.72);
|
||||||
padding: 4rpx 12rpx;
|
padding: 4rpx 12rpx;
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
}
|
}
|
||||||
@@ -604,10 +685,10 @@ onShareAppMessage(() => {
|
|||||||
.action-btn {
|
.action-btn {
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
padding: 6rpx 14rpx;
|
padding: 6rpx 14rpx;
|
||||||
border-radius: 12rpx;
|
border-radius: 999rpx;
|
||||||
background-color: #FFFFFF;
|
background-color: rgba(255, 255, 255, 0.8);
|
||||||
border: 2rpx solid #E2E8F0;
|
border: 2rpx solid rgba(15, 23, 42, 0.08);
|
||||||
color: #64748B;
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-btn {
|
.edit-btn {
|
||||||
@@ -656,7 +737,17 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.empty-icon {
|
.empty-icon {
|
||||||
font-size: 120rpx;
|
width: 112rpx;
|
||||||
|
height: 112rpx;
|
||||||
|
border-radius: 36rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.82);
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.68);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 40rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #98a2b3;
|
||||||
margin-bottom: 24rpx;
|
margin-bottom: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -690,12 +781,12 @@ onShareAppMessage(() => {
|
|||||||
bottom: 140rpx;
|
bottom: 140rpx;
|
||||||
width: 96rpx;
|
width: 96rpx;
|
||||||
height: 96rpx;
|
height: 96rpx;
|
||||||
background-color: #10B981;
|
background: linear-gradient(180deg, #32c59d 0%, #1aa37a 100%);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
box-shadow: 0 12rpx 28rpx rgba(16, 185, 129, 0.35);
|
box-shadow: 0 16rpx 34rpx rgba(26, 163, 122, 0.24);
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
:class="{ 'mode-card-active': currentMode === 'quit' }"
|
:class="{ 'mode-card-active': currentMode === 'quit' }"
|
||||||
@tap="selectMode('quit')"
|
@tap="selectMode('quit')"
|
||||||
>
|
>
|
||||||
<view class="mode-icon mode-icon-quit">🔥</view>
|
<view class="mode-icon mode-icon-quit">戒</view>
|
||||||
<view class="mode-main">
|
<view class="mode-main">
|
||||||
<text class="mode-title">戒烟打卡</text>
|
<text class="mode-title">戒烟打卡</text>
|
||||||
<text class="mode-desc">按天记录“今天没抽”,用连续天数驱动坚持。</text>
|
<text class="mode-desc">按天记录“今天没抽”,用连续天数驱动坚持。</text>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
:class="{ 'mode-card-active': currentMode === 'record' }"
|
:class="{ 'mode-card-active': currentMode === 'record' }"
|
||||||
@tap="selectMode('record')"
|
@tap="selectMode('record')"
|
||||||
>
|
>
|
||||||
<view class="mode-icon mode-icon-record">🚬</view>
|
<view class="mode-icon mode-icon-record">记</view>
|
||||||
<view class="mode-main">
|
<view class="mode-main">
|
||||||
<text class="mode-title">记录抽烟</text>
|
<text class="mode-title">记录抽烟</text>
|
||||||
<text class="mode-desc">继续按支数记录,观察自己的频率和变化趋势。</text>
|
<text class="mode-desc">继续按支数记录,观察自己的频率和变化趋势。</text>
|
||||||
@@ -107,8 +107,9 @@ onMounted(async () => {
|
|||||||
.page {
|
.page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle at top left, rgba(16, 185, 129, 0.18), transparent 34%),
|
radial-gradient(circle at top left, rgba(52, 200, 160, 0.16), transparent 34%),
|
||||||
linear-gradient(180deg, #ecfdf5 0%, #f7fee7 42%, #ffffff 100%);
|
radial-gradient(circle at top right, rgba(255, 255, 255, 0.92), transparent 24%),
|
||||||
|
linear-gradient(180deg, #edf2f8 0%, #f5f7fb 38%, #fbfdff 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-placeholder {
|
.nav-placeholder {
|
||||||
@@ -127,8 +128,8 @@ onMounted(async () => {
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
padding: 8rpx 18rpx;
|
padding: 8rpx 18rpx;
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
background: rgba(16, 185, 129, 0.12);
|
background: rgba(255, 255, 255, 0.78);
|
||||||
color: #047857;
|
color: #667085;
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
}
|
}
|
||||||
@@ -146,7 +147,7 @@ onMounted(async () => {
|
|||||||
margin-top: 16rpx;
|
margin-top: 16rpx;
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
color: #4b5563;
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-card {
|
.mode-card {
|
||||||
@@ -156,14 +157,16 @@ onMounted(async () => {
|
|||||||
padding: 30rpx 28rpx;
|
padding: 30rpx 28rpx;
|
||||||
margin-bottom: 24rpx;
|
margin-bottom: 24rpx;
|
||||||
border-radius: 28rpx;
|
border-radius: 28rpx;
|
||||||
background: rgba(255, 255, 255, 0.82);
|
background: rgba(255, 255, 255, 0.8);
|
||||||
border: 2rpx solid rgba(255, 255, 255, 0.6);
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 16rpx 44rpx rgba(15, 23, 42, 0.08);
|
box-shadow: 0 16rpx 44rpx rgba(15, 23, 42, 0.08);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-card-active {
|
.mode-card-active {
|
||||||
border-color: rgba(16, 185, 129, 0.35);
|
border-color: rgba(255, 255, 255, 0.72);
|
||||||
box-shadow: 0 20rpx 52rpx rgba(16, 185, 129, 0.14);
|
box-shadow: 0 20rpx 52rpx rgba(26, 163, 122, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-icon {
|
.mode-icon {
|
||||||
@@ -173,16 +176,17 @@ onMounted(async () => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 42rpx;
|
font-size: 34rpx;
|
||||||
|
font-weight: 700;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-icon-quit {
|
.mode-icon-quit {
|
||||||
background: linear-gradient(135deg, #d1fae5 0%, #86efac 100%);
|
background: linear-gradient(135deg, rgba(245, 255, 251, 0.95), rgba(219, 252, 231, 0.9));
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-icon-record {
|
.mode-icon-record {
|
||||||
background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);
|
background: linear-gradient(135deg, rgba(255, 248, 242, 0.95), rgba(254, 231, 214, 0.9));
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-main {
|
.mode-main {
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
<view class="footer">
|
<view class="footer">
|
||||||
<view v-if="step > 1" class="btn-secondary" @tap="prevStep">上一步</view>
|
<view v-if="step > 1" class="btn-secondary" @tap="prevStep">上一步</view>
|
||||||
<view class="btn-primary" :class="{ 'btn-full': step === 1 }" @tap="nextStep">
|
<view class="btn-primary" :class="{ 'btn-full': step === 1 }" @tap="nextStep">
|
||||||
{{ step === 5 ? finishButtonText + ' 🚀' : '下一步' }}
|
{{ step === 5 ? finishButtonText : '下一步' }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -293,7 +293,10 @@ onShareAppMessage(() => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.page {
|
.page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: linear-gradient(to bottom, #D1FAE5 0%, #F0FDF4 45%, #FFFFFF 100%);
|
background:
|
||||||
|
radial-gradient(circle at top left, rgba(52, 200, 160, 0.16), transparent 30%),
|
||||||
|
radial-gradient(circle at top right, rgba(255, 255, 255, 0.92), transparent 22%),
|
||||||
|
linear-gradient(180deg, #edf2f8 0%, #f5f7fb 38%, #fbfdff 100%);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
@@ -301,7 +304,7 @@ onShareAppMessage(() => {
|
|||||||
.nav-area {
|
.nav-area {
|
||||||
padding-left: 32rpx;
|
padding-left: 32rpx;
|
||||||
padding-right: 32rpx;
|
padding-right: 32rpx;
|
||||||
background: linear-gradient(to bottom, #D1FAE5, #E9FDF2);
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-row {
|
.nav-row {
|
||||||
@@ -314,8 +317,8 @@ onShareAppMessage(() => {
|
|||||||
.step-indicator {
|
.step-indicator {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #059669;
|
color: #667085;
|
||||||
background-color: rgba(255, 255, 255, 0.7);
|
background-color: rgba(255, 255, 255, 0.76);
|
||||||
padding: 6rpx 24rpx;
|
padding: 6rpx 24rpx;
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
}
|
}
|
||||||
@@ -329,7 +332,7 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.progress-fill {
|
.progress-fill {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: linear-gradient(90deg, #10B981, #34D399);
|
background: linear-gradient(90deg, #32c59d, #1aa37a);
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
transition: width 0.3s ease;
|
transition: width 0.3s ease;
|
||||||
}
|
}
|
||||||
@@ -351,7 +354,7 @@ onShareAppMessage(() => {
|
|||||||
margin-bottom: 16rpx;
|
margin-bottom: 16rpx;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #047857;
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-switch {
|
.mode-switch {
|
||||||
@@ -362,15 +365,17 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.mode-switch-item {
|
.mode-switch-item {
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
border-radius: 20rpx;
|
border-radius: 24rpx;
|
||||||
background: rgba(255, 255, 255, 0.82);
|
background: rgba(255, 255, 255, 0.8);
|
||||||
border: 2rpx solid #d1fae5;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 8rpx 20rpx rgba(16, 185, 129, 0.08);
|
box-shadow: 0 12rpx 28rpx rgba(15, 23, 42, 0.06);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-switch-item-active {
|
.mode-switch-item-active {
|
||||||
background: #ecfdf5;
|
background: rgba(255, 255, 255, 0.92);
|
||||||
border-color: #10b981;
|
border-color: rgba(255, 255, 255, 0.78);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-switch-title {
|
.mode-switch-title {
|
||||||
@@ -436,14 +441,14 @@ onShareAppMessage(() => {
|
|||||||
width: 96rpx;
|
width: 96rpx;
|
||||||
height: 96rpx;
|
height: 96rpx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: #FFFFFF;
|
background-color: rgba(255, 255, 255, 0.86);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 48rpx;
|
font-size: 48rpx;
|
||||||
color: #10B981;
|
color: #1aa37a;
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.72);
|
||||||
box-shadow: 0 8rpx 20rpx rgba(16, 185, 129, 0.12);
|
box-shadow: 0 10rpx 24rpx rgba(15, 23, 42, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-value {
|
.input-value {
|
||||||
@@ -472,12 +477,12 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.option {
|
.option {
|
||||||
padding: 28rpx 36rpx;
|
padding: 28rpx 36rpx;
|
||||||
background-color: #FFFFFF;
|
background-color: rgba(255, 255, 255, 0.84);
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
color: #111827;
|
color: #111827;
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.72);
|
||||||
box-shadow: 0 4rpx 12rpx rgba(16, 185, 129, 0.06);
|
box-shadow: 0 8rpx 20rpx rgba(15, 23, 42, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.option-tag {
|
.option-tag {
|
||||||
@@ -486,9 +491,9 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.option-active {
|
.option-active {
|
||||||
background-color: #ECFDF5;
|
background-color: rgba(255, 255, 255, 0.96);
|
||||||
border-color: #10B981;
|
border-color: rgba(255, 255, 255, 0.82);
|
||||||
color: #059669;
|
color: #1a7f61;
|
||||||
}
|
}
|
||||||
|
|
||||||
.time-row {
|
.time-row {
|
||||||
@@ -506,25 +511,25 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.time-picker {
|
.time-picker {
|
||||||
background-color: #FFFFFF;
|
background-color: rgba(255, 255, 255, 0.86);
|
||||||
padding: 32rpx;
|
padding: 32rpx;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
font-size: 40rpx;
|
font-size: 40rpx;
|
||||||
color: #111827;
|
color: #111827;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.72);
|
||||||
box-shadow: 0 4rpx 12rpx rgba(16, 185, 129, 0.06);
|
box-shadow: 0 8rpx 20rpx rgba(15, 23, 42, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-input {
|
.price-input {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: #FFFFFF;
|
background-color: rgba(255, 255, 255, 0.86);
|
||||||
padding: 24rpx 32rpx;
|
padding: 24rpx 32rpx;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
gap: 8rpx;
|
gap: 8rpx;
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.72);
|
||||||
box-shadow: 0 4rpx 12rpx rgba(16, 185, 129, 0.06);
|
box-shadow: 0 8rpx 20rpx rgba(15, 23, 42, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-prefix {
|
.price-prefix {
|
||||||
@@ -550,15 +555,15 @@ onShareAppMessage(() => {
|
|||||||
.btn-primary {
|
.btn-primary {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 96rpx;
|
height: 96rpx;
|
||||||
background-color: #10B981;
|
background: linear-gradient(180deg, #32c59d 0%, #1aa37a 100%);
|
||||||
border-radius: 48rpx;
|
border-radius: 48rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 32rpx;
|
font-size: 32rpx;
|
||||||
font-weight: 500;
|
font-weight: 600;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
box-shadow: 0 12rpx 28rpx rgba(16, 185, 129, 0.25);
|
box-shadow: 0 12rpx 28rpx rgba(26, 163, 122, 0.22);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-full { flex: 1; }
|
.btn-full { flex: 1; }
|
||||||
@@ -566,13 +571,13 @@ onShareAppMessage(() => {
|
|||||||
.btn-secondary {
|
.btn-secondary {
|
||||||
height: 96rpx;
|
height: 96rpx;
|
||||||
padding: 0 48rpx;
|
padding: 0 48rpx;
|
||||||
background-color: #FFFFFF;
|
background-color: rgba(255, 255, 255, 0.86);
|
||||||
border-radius: 48rpx;
|
border-radius: 48rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 32rpx;
|
font-size: 32rpx;
|
||||||
color: #111827;
|
color: #111827;
|
||||||
border: 2rpx solid #E5E7EB;
|
border: 2rpx solid rgba(15, 23, 42, 0.08);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,14 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page">
|
<view class="page">
|
||||||
|
<view class="page-glow page-glow-a"></view>
|
||||||
|
<view class="page-glow page-glow-b"></view>
|
||||||
|
<view class="nav-placeholder" :style="{ height: navBarHeight + 'px' }"></view>
|
||||||
|
|
||||||
|
<view class="page-header">
|
||||||
|
<text class="header-eyebrow">Account</text>
|
||||||
|
<text class="header-title">个人中心</text>
|
||||||
|
<text class="header-subtitle">模式切换、分享与基础设置</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
<view class="user-section">
|
<view class="user-section">
|
||||||
<image class="avatar" :src="userAvatar" mode="aspectFill"></image>
|
<image class="avatar" :src="userAvatar" mode="aspectFill"></image>
|
||||||
<text class="user-name">{{ userName }}</text>
|
<view class="user-copy">
|
||||||
|
<text class="user-name">{{ userName }}</text>
|
||||||
|
<text class="user-desc">已连接戒烟记录与统计数据</text>
|
||||||
|
<view class="user-meta">
|
||||||
|
<text class="user-pill">{{ modeText }}</text>
|
||||||
|
<text class="user-pill user-pill-muted">{{ shareToken ? '分享已启用' : '分享未生成' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="section">
|
<view class="section">
|
||||||
<view class="mode-card">
|
<view class="mode-card">
|
||||||
<view class="mode-card-header">
|
<view class="mode-card-header">
|
||||||
<view class="menu-icon menu-icon-green">🧭</view>
|
<view class="menu-icon menu-icon-accent">
|
||||||
|
<text class="menu-glyph">模</text>
|
||||||
|
</view>
|
||||||
<view class="menu-content">
|
<view class="menu-content">
|
||||||
<text class="menu-label">打卡模式</text>
|
<text class="menu-label">打卡模式</text>
|
||||||
<text class="menu-desc">直接切换成“戒烟打卡”或“记录抽烟”</text>
|
<text class="menu-desc">直接切换成“戒烟打卡”或“记录抽烟”</text>
|
||||||
@@ -31,7 +50,9 @@
|
|||||||
|
|
||||||
<view class="menu-list">
|
<view class="menu-list">
|
||||||
<view class="menu-item">
|
<view class="menu-item">
|
||||||
<view class="menu-icon menu-icon-green">🔗</view>
|
<view class="menu-icon menu-icon-accent">
|
||||||
|
<text class="menu-glyph">享</text>
|
||||||
|
</view>
|
||||||
<view class="menu-content">
|
<view class="menu-content">
|
||||||
<text class="menu-label">分享戒烟记录</text>
|
<text class="menu-label">分享戒烟记录</text>
|
||||||
<text class="menu-desc">{{ shareDesc }}</text>
|
<text class="menu-desc">{{ shareDesc }}</text>
|
||||||
@@ -46,8 +67,12 @@
|
|||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<view class="menu-divider"></view>
|
||||||
|
|
||||||
<view class="menu-item" @tap="goOnboarding">
|
<view class="menu-item" @tap="goOnboarding">
|
||||||
<view class="menu-icon menu-icon-green">📋</view>
|
<view class="menu-icon menu-icon-accent">
|
||||||
|
<text class="menu-glyph">问</text>
|
||||||
|
</view>
|
||||||
<view class="menu-content">
|
<view class="menu-content">
|
||||||
<text class="menu-label">重新填写问卷</text>
|
<text class="menu-label">重新填写问卷</text>
|
||||||
<text class="menu-desc">修改吸烟基线与个人信息</text>
|
<text class="menu-desc">修改吸烟基线与个人信息</text>
|
||||||
@@ -60,16 +85,25 @@
|
|||||||
<view class="section">
|
<view class="section">
|
||||||
<view class="menu-list">
|
<view class="menu-list">
|
||||||
<view class="menu-item" @tap="clearCache">
|
<view class="menu-item" @tap="clearCache">
|
||||||
<view class="menu-icon menu-icon-gray">🗑️</view>
|
<view class="menu-icon menu-icon-muted">
|
||||||
|
<text class="menu-glyph">清</text>
|
||||||
|
</view>
|
||||||
<view class="menu-content">
|
<view class="menu-content">
|
||||||
<text class="menu-label">清除缓存</text>
|
<text class="menu-label">清除缓存</text>
|
||||||
|
<text class="menu-desc">仅清理本地缓存,不影响云端记录</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="menu-arrow">›</text>
|
<text class="menu-arrow">›</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<view class="menu-divider"></view>
|
||||||
|
|
||||||
<view class="menu-item" @tap="copyInfo">
|
<view class="menu-item" @tap="copyInfo">
|
||||||
<view class="menu-icon menu-icon-gray">💬</view>
|
<view class="menu-icon menu-icon-muted">
|
||||||
|
<text class="menu-glyph">邮</text>
|
||||||
|
</view>
|
||||||
<view class="menu-content">
|
<view class="menu-content">
|
||||||
<text class="menu-label">意见反馈</text>
|
<text class="menu-label">意见反馈</text>
|
||||||
|
<text class="menu-desc">复制反馈邮箱,发送使用建议或问题</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="menu-arrow">›</text>
|
<text class="menu-arrow">›</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -81,7 +115,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref, onMounted } from 'vue'
|
||||||
import { onShareAppMessage, onShow } from '@dcloudio/uni-app'
|
import { onShareAppMessage, onShow } from '@dcloudio/uni-app'
|
||||||
import * as api from '@/api'
|
import * as api from '@/api'
|
||||||
import { useProfileStore } from '@/stores/profile'
|
import { useProfileStore } from '@/stores/profile'
|
||||||
@@ -96,6 +130,7 @@ const shareToken = ref('')
|
|||||||
const shareExpireAt = ref('')
|
const shareExpireAt = ref('')
|
||||||
const shareLoading = ref(false)
|
const shareLoading = ref(false)
|
||||||
const modeSaving = ref(false)
|
const modeSaving = ref(false)
|
||||||
|
const navBarHeight = ref(0)
|
||||||
const modeOptions = [
|
const modeOptions = [
|
||||||
{ value: 'quit', label: '戒烟打卡', desc: '按天记录今天没抽' },
|
{ value: 'quit', label: '戒烟打卡', desc: '按天记录今天没抽' },
|
||||||
{ value: 'record', label: '记录抽烟', desc: '按支数记录变化' }
|
{ value: 'record', label: '记录抽烟', desc: '按支数记录变化' }
|
||||||
@@ -123,6 +158,17 @@ const sharePath = computed(() => {
|
|||||||
return `pages/share/index?share_token=${shareToken.value}`
|
return `pages/share/index?share_token=${shareToken.value}`
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function setupNavBar() {
|
||||||
|
const systemInfo = uni.getSystemInfoSync()
|
||||||
|
const statusBarH = systemInfo.statusBarHeight || 0
|
||||||
|
try {
|
||||||
|
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||||||
|
navBarHeight.value = menuBtn.bottom + (menuBtn.top - statusBarH)
|
||||||
|
} catch (e) {
|
||||||
|
navBarHeight.value = statusBarH + 44
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function formatExpire(value) {
|
function formatExpire(value) {
|
||||||
if (!value) return '--'
|
if (!value) return '--'
|
||||||
const d = new Date(value)
|
const d = new Date(value)
|
||||||
@@ -225,6 +271,10 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
setupNavBar()
|
||||||
|
})
|
||||||
|
|
||||||
onShow(async () => {
|
onShow(async () => {
|
||||||
await waitForLogin()
|
await waitForLogin()
|
||||||
await profileStore.fetchProfile()
|
await profileStore.fetchProfile()
|
||||||
@@ -235,44 +285,156 @@ onShow(async () => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.page {
|
.page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: linear-gradient(to bottom, #D1FAE5 0%, #F0FDF4 45%, #FFFFFF 100%);
|
position: relative;
|
||||||
padding: 32rpx;
|
background:
|
||||||
padding-bottom: 160rpx;
|
radial-gradient(circle at top left, rgba(52, 200, 160, 0.16), transparent 30%),
|
||||||
|
radial-gradient(circle at top right, rgba(255, 255, 255, 0.92), transparent 22%),
|
||||||
|
linear-gradient(180deg, #edf2f8 0%, #f5f7fb 38%, #fbfdff 100%);
|
||||||
|
padding: 0 24rpx 168rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(24rpx);
|
||||||
|
opacity: 0.72;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow-a {
|
||||||
|
top: 100rpx;
|
||||||
|
left: -140rpx;
|
||||||
|
width: 360rpx;
|
||||||
|
height: 360rpx;
|
||||||
|
background: rgba(52, 200, 160, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow-b {
|
||||||
|
top: 340rpx;
|
||||||
|
right: -120rpx;
|
||||||
|
width: 320rpx;
|
||||||
|
height: 320rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.86);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-placeholder,
|
||||||
|
.page-header,
|
||||||
|
.user-section,
|
||||||
|
.section,
|
||||||
|
.version {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
padding: 24rpx 6rpx 18rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-eyebrow {
|
||||||
|
display: block;
|
||||||
|
font-size: 20rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 4rpx;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #98a2b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title {
|
||||||
|
display: block;
|
||||||
|
margin-top: 10rpx;
|
||||||
|
font-size: 42rpx;
|
||||||
|
line-height: 1.18;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #111827;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-subtitle {
|
||||||
|
display: block;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-section {
|
.user-section {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 48rpx 0 40rpx;
|
gap: 24rpx;
|
||||||
|
padding: 12rpx 28rpx 32rpx;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.74);
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
|
border-radius: 32rpx;
|
||||||
|
box-shadow: 0 16rpx 42rpx rgba(15, 23, 42, 0.08);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
width: 140rpx;
|
width: 132rpx;
|
||||||
height: 140rpx;
|
height: 132rpx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: 4rpx solid #A7F3D0;
|
border: 4rpx solid rgba(255, 255, 255, 0.82);
|
||||||
background-color: #ECFDF5;
|
background-color: rgba(255, 255, 255, 0.7);
|
||||||
margin-bottom: 20rpx;
|
}
|
||||||
|
|
||||||
|
.user-copy {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-name {
|
.user-name {
|
||||||
font-size: 38rpx;
|
font-size: 40rpx;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #111827;
|
color: #111827;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-desc {
|
||||||
|
display: block;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #667085;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-meta {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 12rpx;
|
||||||
|
margin-top: 18rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-pill {
|
||||||
|
padding: 10rpx 20rpx;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
background: rgba(52, 200, 160, 0.12);
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.64);
|
||||||
|
font-size: 22rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #17795c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-pill-muted {
|
||||||
|
background: rgba(255, 255, 255, 0.78);
|
||||||
|
color: #667085;
|
||||||
|
}
|
||||||
|
|
||||||
.section {
|
.section {
|
||||||
margin-bottom: 24rpx;
|
margin-bottom: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-card {
|
.mode-card {
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.76);
|
||||||
border-radius: 24rpx;
|
border-radius: 32rpx;
|
||||||
padding: 28rpx 24rpx;
|
padding: 30rpx 24rpx;
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 8rpx 20rpx rgba(16, 185, 129, 0.08);
|
box-shadow: 0 16rpx 42rpx rgba(15, 23, 42, 0.08);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
margin-bottom: 16rpx;
|
margin-bottom: 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,36 +448,50 @@ onShow(async () => {
|
|||||||
.menu-list {
|
.menu-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 16rpx;
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
border-radius: 32rpx;
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
|
box-shadow: 0 16rpx 42rpx rgba(15, 23, 42, 0.08);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item {
|
.menu-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 24rpx;
|
gap: 24rpx;
|
||||||
background-color: #FFFFFF;
|
|
||||||
border-radius: 24rpx;
|
|
||||||
padding: 28rpx 24rpx;
|
padding: 28rpx 24rpx;
|
||||||
border: 2rpx solid #ECFDF3;
|
}
|
||||||
box-shadow: 0 8rpx 20rpx rgba(16, 185, 129, 0.08);
|
|
||||||
|
.menu-divider {
|
||||||
|
margin: 0 24rpx;
|
||||||
|
height: 2rpx;
|
||||||
|
background: rgba(15, 23, 42, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-icon {
|
.menu-icon {
|
||||||
width: 64rpx;
|
width: 64rpx;
|
||||||
height: 64rpx;
|
height: 64rpx;
|
||||||
border-radius: 16rpx;
|
border-radius: 20rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 32rpx;
|
border: 2rpx solid rgba(255, 255, 255, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-icon-green {
|
.menu-icon-accent {
|
||||||
background-color: #DCFCE7;
|
background: rgba(52, 200, 160, 0.14);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-icon-gray {
|
.menu-icon-muted {
|
||||||
background-color: #F3F4F6;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-glyph {
|
||||||
|
font-size: 24rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #111827;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-content {
|
.menu-content {
|
||||||
@@ -328,11 +504,13 @@ onShow(async () => {
|
|||||||
.menu-label {
|
.menu-label {
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
color: #111827;
|
color: #111827;
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-desc {
|
.menu-desc {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #6B7280;
|
line-height: 1.5;
|
||||||
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-actions {
|
.menu-actions {
|
||||||
@@ -342,44 +520,49 @@ onShow(async () => {
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 8rpx;
|
gap: 8rpx;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #10B981;
|
color: #1aa37a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-action {
|
.menu-action {
|
||||||
color: #10B981;
|
color: #1aa37a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-action-sep {
|
.menu-action-sep {
|
||||||
color: #9CA3AF;
|
color: #98a2b3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-arrow {
|
.menu-arrow {
|
||||||
font-size: 36rpx;
|
font-size: 36rpx;
|
||||||
color: #9CA3AF;
|
color: #98a2b3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-value {
|
.menu-value {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #10B981;
|
color: #1aa37a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-switch {
|
.mode-switch {
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
gap: 12rpx;
|
||||||
gap: 16rpx;
|
padding: 8rpx;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
background: rgba(247, 249, 252, 0.92);
|
||||||
|
border: 2rpx solid rgba(15, 23, 42, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-switch-item {
|
.mode-switch-item {
|
||||||
padding: 22rpx 20rpx;
|
flex: 1;
|
||||||
border-radius: 18rpx;
|
padding: 22rpx 18rpx;
|
||||||
background: #F9FAFB;
|
border-radius: 20rpx;
|
||||||
border: 2rpx solid #E5E7EB;
|
background: transparent;
|
||||||
|
border: 2rpx solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-switch-item-active {
|
.mode-switch-item-active {
|
||||||
background: #ECFDF5;
|
background: rgba(255, 255, 255, 0.94);
|
||||||
border-color: #10B981;
|
border-color: rgba(255, 255, 255, 0.76);
|
||||||
|
box-shadow: 0 8rpx 18rpx rgba(15, 23, 42, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-switch-title {
|
.mode-switch-title {
|
||||||
@@ -394,29 +577,30 @@ onShow(async () => {
|
|||||||
margin-top: 8rpx;
|
margin-top: 8rpx;
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
color: #6B7280;
|
color: #667085;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-hint {
|
.mode-hint {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 16rpx;
|
margin-top: 16rpx;
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
color: #10B981;
|
color: #1aa37a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.share-btn {
|
.share-btn {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 10rpx 20rpx;
|
padding: 12rpx 22rpx;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
background: #10B981;
|
background: linear-gradient(180deg, #32c59d 0%, #1aa37a 100%);
|
||||||
|
box-shadow: 0 12rpx 28rpx rgba(26, 163, 122, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.share-btn[disabled] {
|
.share-btn[disabled] {
|
||||||
background: #9CA3AF;
|
background: #98a2b3;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,7 +612,7 @@ onShow(async () => {
|
|||||||
display: block;
|
display: block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
color: #9CA3AF;
|
color: #98a2b3;
|
||||||
margin-top: 32rpx;
|
margin-top: 32rpx;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<view v-else>
|
<view v-else>
|
||||||
<!-- 无计划状态 -->
|
<!-- 无计划状态 -->
|
||||||
<view v-if="!planData" class="no-plan-card">
|
<view v-if="!planData" class="no-plan-card">
|
||||||
<view class="no-plan-icon">📋</view>
|
<view class="no-plan-icon">计</view>
|
||||||
<text class="no-plan-title">暂无戒烟计划</text>
|
<text class="no-plan-title">暂无戒烟计划</text>
|
||||||
<text class="no-plan-desc">生成专属30天戒烟计划,按阶段轻松戒烟</text>
|
<text class="no-plan-desc">生成专属30天戒烟计划,按阶段轻松戒烟</text>
|
||||||
<view class="generate-btn" @tap="handleGenerate">
|
<view class="generate-btn" @tap="handleGenerate">
|
||||||
@@ -356,12 +356,15 @@ onShareAppMessage(() => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.page {
|
.page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: linear-gradient(to bottom, #D1FAE5 0%, #F0FDF4 45%, #FFFFFF 100%);
|
background:
|
||||||
|
radial-gradient(circle at top left, rgba(52, 200, 160, 0.16), transparent 30%),
|
||||||
|
radial-gradient(circle at top right, rgba(255, 255, 255, 0.92), transparent 24%),
|
||||||
|
linear-gradient(180deg, #edf2f8 0%, #f5f7fb 38%, #fbfdff 100%);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-bar {
|
.status-bar {
|
||||||
background: linear-gradient(to bottom, #D1FAE5, #E9FDF2);
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
@@ -409,18 +412,29 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
/* 无计划状态 */
|
/* 无计划状态 */
|
||||||
.no-plan-card {
|
.no-plan-card {
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 28rpx;
|
border-radius: 32rpx;
|
||||||
padding: 60rpx 40rpx;
|
padding: 60rpx 40rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
box-shadow: 0 10rpx 28rpx rgba(16, 185, 129, 0.12);
|
box-shadow: 0 16rpx 36rpx rgba(15, 23, 42, 0.06);
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.no-plan-icon {
|
.no-plan-icon {
|
||||||
font-size: 80rpx;
|
width: 104rpx;
|
||||||
|
height: 104rpx;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
background: rgba(247, 249, 252, 0.92);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1a7f61;
|
||||||
margin-bottom: 24rpx;
|
margin-bottom: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,7 +454,7 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.generate-btn {
|
.generate-btn {
|
||||||
background: linear-gradient(135deg, #10B981, #059669);
|
background: linear-gradient(180deg, #32c59d 0%, #1aa37a 100%);
|
||||||
padding: 24rpx 60rpx;
|
padding: 24rpx 60rpx;
|
||||||
border-radius: 48rpx;
|
border-radius: 48rpx;
|
||||||
box-shadow: 0 8rpx 20rpx rgba(16, 185, 129, 0.3);
|
box-shadow: 0 8rpx 20rpx rgba(16, 185, 129, 0.3);
|
||||||
@@ -454,20 +468,22 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
/* 阶段卡片 */
|
/* 阶段卡片 */
|
||||||
.stage-card {
|
.stage-card {
|
||||||
background: #FFFFFF;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 28rpx;
|
border-radius: 32rpx;
|
||||||
padding: 32rpx;
|
padding: 32rpx;
|
||||||
margin-bottom: 32rpx;
|
margin-bottom: 32rpx;
|
||||||
position: relative;
|
position: relative;
|
||||||
box-shadow: 0 10rpx 28rpx rgba(16, 185, 129, 0.12);
|
box-shadow: 0 16rpx 36rpx rgba(15, 23, 42, 0.06);
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stage-badge {
|
.stage-badge {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 24rpx;
|
top: 24rpx;
|
||||||
right: 24rpx;
|
right: 24rpx;
|
||||||
background-color: #10B981;
|
background-color: #1aa37a;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
padding: 8rpx 20rpx;
|
padding: 8rpx 20rpx;
|
||||||
border-radius: 20rpx;
|
border-radius: 20rpx;
|
||||||
@@ -523,7 +539,7 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.stage-progress-fill {
|
.stage-progress-fill {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: linear-gradient(90deg, #10B981, #34D399);
|
background: linear-gradient(90deg, #32c59d, #1aa37a);
|
||||||
border-radius: 6rpx;
|
border-radius: 6rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,11 +570,13 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.stage-info-card {
|
.stage-info-card {
|
||||||
background-color: #FFFFFF;
|
background-color: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 24rpx;
|
border-radius: 28rpx;
|
||||||
padding: 28rpx;
|
padding: 28rpx;
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 8rpx 22rpx rgba(16, 185, 129, 0.08);
|
box-shadow: 0 14rpx 30rpx rgba(15, 23, 42, 0.05);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stage-item {
|
.stage-item {
|
||||||
@@ -618,11 +636,13 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
/* 每日目标 */
|
/* 每日目标 */
|
||||||
.daily-tips-card {
|
.daily-tips-card {
|
||||||
background-color: #FFFFFF;
|
background-color: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 24rpx;
|
border-radius: 28rpx;
|
||||||
padding: 28rpx;
|
padding: 28rpx;
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 8rpx 22rpx rgba(16, 185, 129, 0.08);
|
box-shadow: 0 14rpx 30rpx rgba(15, 23, 42, 0.05);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.daily-tips-title {
|
.daily-tips-title {
|
||||||
@@ -647,16 +667,18 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.day-item {
|
.day-item {
|
||||||
background-color: #FFFFFF;
|
background-color: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 20rpx;
|
border-radius: 24rpx;
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 6rpx 16rpx rgba(16, 185, 129, 0.08);
|
box-shadow: 0 12rpx 24rpx rgba(15, 23, 42, 0.05);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.day-item-today {
|
.day-item-today {
|
||||||
border-color: #10B981;
|
border-color: rgba(255, 255, 255, 0.82);
|
||||||
background: linear-gradient(135deg, #ECFDF5, #F0FDF4);
|
background: linear-gradient(135deg, rgba(245, 255, 251, 0.95), rgba(255, 255, 255, 0.88));
|
||||||
}
|
}
|
||||||
|
|
||||||
.day-item-past {
|
.day-item-past {
|
||||||
@@ -723,8 +745,8 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.days-loading,
|
.days-loading,
|
||||||
.days-empty {
|
.days-empty {
|
||||||
background-color: #FFFFFF;
|
background-color: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 24rpx;
|
border-radius: 28rpx;
|
||||||
padding: 40rpx;
|
padding: 40rpx;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
@@ -742,7 +764,7 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.reset-btn {
|
.reset-btn {
|
||||||
background-color: #FFFFFF;
|
background-color: rgba(255, 255, 255, 0.86);
|
||||||
border: 2rpx solid #EF4444;
|
border: 2rpx solid #EF4444;
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
@@ -761,7 +783,7 @@ onShareAppMessage(() => {
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
background-color: rgba(15, 23, 42, 0.26);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -769,11 +791,14 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.modal-content {
|
.modal-content {
|
||||||
background-color: #FFFFFF;
|
background-color: rgba(248, 250, 252, 0.92);
|
||||||
border-radius: 28rpx;
|
border-radius: 28rpx;
|
||||||
width: 600rpx;
|
width: 600rpx;
|
||||||
max-height: 70vh;
|
max-height: 70vh;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.72);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-header {
|
.modal-header {
|
||||||
@@ -323,7 +323,9 @@ onShareAppMessage(() => {
|
|||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background: #f5f7fa;
|
background:
|
||||||
|
radial-gradient(circle at top left, rgba(52, 200, 160, 0.14), transparent 28%),
|
||||||
|
linear-gradient(180deg, #edf2f8 0%, #f5f7fb 38%, #fbfdff 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.state-wrap {
|
.state-wrap {
|
||||||
@@ -339,7 +341,7 @@ onShareAppMessage(() => {
|
|||||||
.retry-btn {
|
.retry-btn {
|
||||||
margin-top: 24rpx;
|
margin-top: 24rpx;
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
background: #10b981;
|
background: linear-gradient(180deg, #32c59d 0%, #1aa37a 100%);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
@@ -350,8 +352,12 @@ onShareAppMessage(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 20rpx;
|
gap: 20rpx;
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
background: #ffffff;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 20rpx;
|
border-radius: 28rpx;
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.68);
|
||||||
|
box-shadow: 0 16rpx 36rpx rgba(15, 23, 42, 0.06);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
@@ -387,8 +393,10 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.overview-item {
|
.overview-item {
|
||||||
padding: 20rpx;
|
padding: 20rpx;
|
||||||
background: #fff;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 16rpx;
|
border-radius: 24rpx;
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.68);
|
||||||
|
box-shadow: 0 12rpx 28rpx rgba(15, 23, 42, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.overview-label {
|
.overview-label {
|
||||||
@@ -415,8 +423,12 @@ onShareAppMessage(() => {
|
|||||||
.section {
|
.section {
|
||||||
margin-top: 20rpx;
|
margin-top: 20rpx;
|
||||||
padding: 20rpx;
|
padding: 20rpx;
|
||||||
background: #fff;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 20rpx;
|
border-radius: 28rpx;
|
||||||
|
border: 2rpx solid rgba(255, 255, 255, 0.68);
|
||||||
|
box-shadow: 0 16rpx 36rpx rgba(15, 23, 42, 0.06);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-header {
|
.section-header {
|
||||||
@@ -446,8 +458,9 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.range-item.active {
|
.range-item.active {
|
||||||
background: #10b981;
|
background: rgba(255, 255, 255, 0.92);
|
||||||
color: #fff;
|
color: #111827;
|
||||||
|
box-shadow: 0 8rpx 18rpx rgba(15, 23, 42, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-row {
|
.stats-row {
|
||||||
@@ -459,8 +472,8 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.stats-block {
|
.stats-block {
|
||||||
padding: 14rpx;
|
padding: 14rpx;
|
||||||
border-radius: 14rpx;
|
border-radius: 18rpx;
|
||||||
background: #f8fafc;
|
background: rgba(247, 249, 252, 0.92);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-key {
|
.stats-key {
|
||||||
@@ -527,8 +540,8 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.log-item {
|
.log-item {
|
||||||
padding: 18rpx;
|
padding: 18rpx;
|
||||||
border-radius: 14rpx;
|
border-radius: 20rpx;
|
||||||
background: #f8fafc;
|
background: rgba(247, 249, 252, 0.92);
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-top {
|
.log-top {
|
||||||
@@ -578,7 +591,7 @@ onShareAppMessage(() => {
|
|||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
border-radius: 14rpx;
|
border-radius: 14rpx;
|
||||||
border: none;
|
border: none;
|
||||||
background: #ecfdf5;
|
background: rgba(255, 255, 255, 0.88);
|
||||||
color: #047857;
|
color: #1a7f61;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,7 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page">
|
<view class="page">
|
||||||
|
<view class="page-glow page-glow-a"></view>
|
||||||
|
<view class="page-glow page-glow-b"></view>
|
||||||
<view class="sticky-bar">
|
<view class="sticky-bar">
|
||||||
<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
|
<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
|
||||||
|
<view class="page-head">
|
||||||
|
<text class="page-eyebrow">Statistics</text>
|
||||||
|
<text class="page-title">数据统计</text>
|
||||||
|
<text class="page-subtitle">趋势、恢复和储蓄会在这里汇总。</text>
|
||||||
|
</view>
|
||||||
<view class="segment">
|
<view class="segment">
|
||||||
<view
|
<view
|
||||||
v-for="tab in tabs"
|
v-for="tab in tabs"
|
||||||
@@ -17,7 +24,7 @@
|
|||||||
|
|
||||||
<view class="insight-card">
|
<view class="insight-card">
|
||||||
<view class="insight-icon" :class="insightIconClass">
|
<view class="insight-icon" :class="insightIconClass">
|
||||||
<text class="insight-emoji">{{ insightEmoji }}</text>
|
<text class="insight-glyph">{{ insightEmoji }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="insight-content">
|
<view class="insight-content">
|
||||||
<text class="insight-title">每周洞察</text>
|
<text class="insight-title">每周洞察</text>
|
||||||
@@ -68,7 +75,7 @@
|
|||||||
<view class="savings-card">
|
<view class="savings-card">
|
||||||
<view class="savings-header">
|
<view class="savings-header">
|
||||||
<view class="savings-icon" :class="moneyIconClass">
|
<view class="savings-icon" :class="moneyIconClass">
|
||||||
<text class="icon-emoji">💰</text>
|
<text class="icon-glyph">省</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="savings-header-text">
|
<view class="savings-header-text">
|
||||||
<text class="savings-title">节省金额</text>
|
<text class="savings-title">节省金额</text>
|
||||||
@@ -102,7 +109,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="!moneyAvailable" class="card-empty">
|
<view v-if="!moneyAvailable" class="card-empty">
|
||||||
<text class="card-empty-icon">🔒</text>
|
<text class="card-empty-icon">待</text>
|
||||||
<text class="card-empty-text">完善基础信息后解锁节省金额</text>
|
<text class="card-empty-text">完善基础信息后解锁节省金额</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -111,15 +118,15 @@
|
|||||||
<view class="health-header">
|
<view class="health-header">
|
||||||
<view class="health-title-row">
|
<view class="health-title-row">
|
||||||
<view class="health-icon" :class="healthIconClass">
|
<view class="health-icon" :class="healthIconClass">
|
||||||
<text class="icon-emoji">❤️</text>
|
<text class="icon-glyph">肺</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="health-title">健康恢复里程碑</text>
|
<text class="health-title">健康恢复里程碑</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="health-badge" :class="{ 'health-badge-muted': !healthAvailable }">{{ healthStatusText }}</view>
|
<view class="health-badge" :class="{ 'health-badge-muted': !healthAvailable }">{{ healthStatusText }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="healthAvailable" class="health-overview">
|
<view v-if="healthAvailable" class="health-overview">
|
||||||
<view class="health-metric">
|
<view class="health-metric">
|
||||||
<view class="health-metric-icon">⏱️</view>
|
<view class="health-metric-icon">时</view>
|
||||||
<text class="health-metric-value">{{ smokeFreeText }}</text>
|
<text class="health-metric-value">{{ smokeFreeText }}</text>
|
||||||
<text class="health-metric-label">无烟时长</text>
|
<text class="health-metric-label">无烟时长</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -131,7 +138,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-else class="card-empty">
|
<view v-else class="card-empty">
|
||||||
<text class="card-empty-icon">🫁</text>
|
<text class="card-empty-icon">未</text>
|
||||||
<text class="card-empty-text">暂无健康数据,记录一次后解锁</text>
|
<text class="card-empty-text">暂无健康数据,记录一次后解锁</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="health-list">
|
<view class="health-list">
|
||||||
@@ -154,7 +161,7 @@
|
|||||||
<view class="stats-grid">
|
<view class="stats-grid">
|
||||||
<view class="mini-card">
|
<view class="mini-card">
|
||||||
<view class="mini-icon mini-icon-fire" :class="streakIconClass">
|
<view class="mini-icon mini-icon-fire" :class="streakIconClass">
|
||||||
<text class="icon-emoji">🔥</text>
|
<text class="icon-glyph">续</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="mini-label">连续记录</text>
|
<text class="mini-label">连续记录</text>
|
||||||
<view class="mini-value-row">
|
<view class="mini-value-row">
|
||||||
@@ -165,7 +172,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="mini-card">
|
<view class="mini-card">
|
||||||
<view class="mini-icon mini-icon-block" :class="resistedIconClass">
|
<view class="mini-icon mini-icon-block" :class="resistedIconClass">
|
||||||
<text class="icon-emoji">🛡️</text>
|
<text class="icon-glyph">忍</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="mini-label">已拒绝</text>
|
<text class="mini-label">已拒绝</text>
|
||||||
<view class="mini-value-row">
|
<view class="mini-value-row">
|
||||||
@@ -205,8 +212,8 @@ const changePercent = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const insightEmoji = computed(() => {
|
const insightEmoji = computed(() => {
|
||||||
if (changePercent.value === null) return '✨'
|
if (changePercent.value === null) return '新'
|
||||||
return changePercent.value <= 0 ? '🌿' : '⚠️'
|
return changePercent.value <= 0 ? '稳' : '警'
|
||||||
})
|
})
|
||||||
|
|
||||||
const insightIconClass = computed(() => {
|
const insightIconClass = computed(() => {
|
||||||
@@ -509,33 +516,94 @@ onShareAppMessage(() => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.page {
|
.page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: linear-gradient(to bottom, #D1FAE5 0%, #F0FDF4 45%, #FFFFFF 100%);
|
position: relative;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at top left, rgba(52, 200, 160, 0.16), transparent 30%),
|
||||||
|
radial-gradient(circle at top right, rgba(255, 255, 255, 0.92), transparent 24%),
|
||||||
|
linear-gradient(180deg, #edf2f8 0%, #f5f7fb 38%, #fbfdff 100%);
|
||||||
padding: 0 32rpx 200rpx;
|
padding: 0 32rpx 200rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-bar {
|
.status-bar {
|
||||||
background: linear-gradient(to bottom, #D1FAE5, #F0FDF4);
|
background: transparent;
|
||||||
height: 0;
|
height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page-glow {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(24rpx);
|
||||||
|
opacity: 0.72;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow-a {
|
||||||
|
top: 88rpx;
|
||||||
|
left: -140rpx;
|
||||||
|
width: 360rpx;
|
||||||
|
height: 360rpx;
|
||||||
|
background: rgba(52, 200, 160, 0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-glow-b {
|
||||||
|
top: 340rpx;
|
||||||
|
right: -120rpx;
|
||||||
|
width: 320rpx;
|
||||||
|
height: 320rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
.sticky-bar {
|
.sticky-bar {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
background: linear-gradient(to bottom, #D1FAE5 0%, #F0FDF4 70%, rgba(255, 255, 255, 0.95) 100%);
|
background: linear-gradient(180deg, rgba(237, 242, 248, 0.96) 0%, rgba(245, 247, 251, 0.92) 76%, rgba(251, 253, 255, 0) 100%);
|
||||||
padding-bottom: 8rpx;
|
padding-bottom: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page-head {
|
||||||
|
padding: 18rpx 0 18rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-eyebrow {
|
||||||
|
display: block;
|
||||||
|
font-size: 20rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 4rpx;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #98a2b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
display: block;
|
||||||
|
margin-top: 10rpx;
|
||||||
|
font-size: 42rpx;
|
||||||
|
line-height: 1.18;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #111827;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-subtitle {
|
||||||
|
display: block;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #667085;
|
||||||
|
}
|
||||||
|
|
||||||
.segment {
|
.segment {
|
||||||
display: flex;
|
display: flex;
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.76);
|
||||||
padding: 6rpx;
|
padding: 6rpx;
|
||||||
border-radius: 20rpx;
|
border-radius: 24rpx;
|
||||||
gap: 6rpx;
|
gap: 6rpx;
|
||||||
margin-bottom: 16rpx;
|
margin-bottom: 16rpx;
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 10rpx 22rpx rgba(16, 185, 129, 0.08);
|
box-shadow: 0 12rpx 28rpx rgba(15, 23, 42, 0.06);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.segment-item {
|
.segment-item {
|
||||||
@@ -550,21 +618,23 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.segment-active {
|
.segment-active {
|
||||||
background-color: #10B981;
|
background: rgba(255, 255, 255, 0.92);
|
||||||
color: #0B2F23;
|
color: #111827;
|
||||||
box-shadow: 0 6rpx 16rpx rgba(16, 185, 129, 0.25);
|
box-shadow: 0 8rpx 18rpx rgba(15, 23, 42, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
.insight-card {
|
.insight-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 20rpx;
|
gap: 20rpx;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
background-color: #ECFDF3;
|
background: rgba(255, 255, 255, 0.78);
|
||||||
border: 2rpx solid #D9FBE7;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
border-radius: 24rpx;
|
border-radius: 30rpx;
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
margin-bottom: 28rpx;
|
margin-bottom: 28rpx;
|
||||||
box-shadow: 0 10rpx 20rpx rgba(16, 185, 129, 0.1);
|
box-shadow: 0 14rpx 34rpx rgba(15, 23, 42, 0.06);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.insight-icon {
|
.insight-icon {
|
||||||
@@ -593,8 +663,11 @@ onShareAppMessage(() => {
|
|||||||
box-shadow: 0 10rpx 18rpx rgba(100, 116, 139, 0.12);
|
box-shadow: 0 10rpx 18rpx rgba(100, 116, 139, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.insight-emoji {
|
.insight-glyph,
|
||||||
font-size: 30rpx;
|
.icon-glyph {
|
||||||
|
font-size: 24rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.insight-title {
|
.insight-title {
|
||||||
@@ -696,11 +769,13 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.trend-card {
|
.trend-card {
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 28rpx;
|
border-radius: 32rpx;
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 12rpx 24rpx rgba(16, 185, 129, 0.1);
|
box-shadow: 0 16rpx 36rpx rgba(15, 23, 42, 0.06);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.trend-header {
|
.trend-header {
|
||||||
@@ -813,12 +888,14 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.savings-card {
|
.savings-card {
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 28rpx;
|
border-radius: 32rpx;
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
margin-top: 20rpx;
|
margin-top: 20rpx;
|
||||||
border: 2rpx solid #FEF3C7;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 12rpx 24rpx rgba(245, 158, 11, 0.08);
|
box-shadow: 0 16rpx 36rpx rgba(15, 23, 42, 0.06);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.savings-header {
|
.savings-header {
|
||||||
@@ -916,23 +993,6 @@ onShareAppMessage(() => {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-emoji {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.savings-icon .icon-emoji {
|
|
||||||
font-size: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.health-icon .icon-emoji {
|
|
||||||
font-size: 26rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mini-icon .icon-emoji {
|
|
||||||
font-size: 26rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.savings-metrics {
|
.savings-metrics {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -1011,6 +1071,7 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.card-empty-icon {
|
.card-empty-icon {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-empty-text {
|
.card-empty-text {
|
||||||
@@ -1019,12 +1080,14 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.health-card {
|
.health-card {
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 28rpx;
|
border-radius: 32rpx;
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
margin-top: 24rpx;
|
margin-top: 24rpx;
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 12rpx 24rpx rgba(16, 185, 129, 0.08);
|
box-shadow: 0 16rpx 36rpx rgba(15, 23, 42, 0.06);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.health-header {
|
.health-header {
|
||||||
@@ -1113,7 +1176,16 @@ onShareAppMessage(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.health-metric-icon {
|
.health-metric-icon {
|
||||||
font-size: 22rpx;
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
border-radius: 14rpx;
|
||||||
|
background: rgba(52, 200, 160, 0.14);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 20rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #17795c;
|
||||||
}
|
}
|
||||||
|
|
||||||
.health-metric-value {
|
.health-metric-value {
|
||||||
@@ -1208,11 +1280,13 @@ onShareAppMessage(() => {
|
|||||||
|
|
||||||
.mini-card {
|
.mini-card {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background-color: #FFFFFF;
|
background: rgba(255, 255, 255, 0.82);
|
||||||
border-radius: 24rpx;
|
border-radius: 28rpx;
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
border: 2rpx solid #ECFDF3;
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 12rpx 24rpx rgba(16, 185, 129, 0.06);
|
box-shadow: 0 14rpx 32rpx rgba(15, 23, 42, 0.05);
|
||||||
|
backdrop-filter: blur(24rpx);
|
||||||
|
-webkit-backdrop-filter: blur(24rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mini-icon {
|
.mini-icon {
|
||||||
@@ -1299,4 +1373,3 @@ onShareAppMessage(() => {
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 902 B After Width: | Height: | Size: 902 B |
|
Before Width: | Height: | Size: 912 B After Width: | Height: | Size: 912 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 464 B After Width: | Height: | Size: 464 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,13 @@
|
|||||||
|
import { fileURLToPath, URL } from 'node:url'
|
||||||
|
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import Uni from '@uni-helper/plugin-uni'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: [Uni()]
|
||||||
|
})
|
||||||