Spaces:
Sleeping
Sleeping
Trae Assistant commited on
Commit ·
e3bbdaf
0
Parent(s):
initial commit
Browse files- .gitignore +21 -0
- Dockerfile +32 -0
- README.md +84 -0
- index.html +20 -0
- nginx.conf +18 -0
- package.json +73 -0
- pnpm-lock.yaml +0 -0
- shims-uni.d.ts +10 -0
- src/App.vue +47 -0
- src/env.d.ts +8 -0
- src/main.ts +8 -0
- src/manifest.json +111 -0
- src/pages.json +56 -0
- src/pages/function/function.vue +171 -0
- src/pages/index/index.vue +166 -0
- src/pages/login/login.vue +230 -0
- src/pages/profile/profile.vue +198 -0
- src/shime-uni.d.ts +6 -0
- src/static/logo.png +0 -0
- src/uni.scss +76 -0
- tsconfig.json +13 -0
- vite.config.ts +7 -0
.gitignore
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Logs
|
| 2 |
+
logs
|
| 3 |
+
*.log
|
| 4 |
+
npm-debug.log*
|
| 5 |
+
yarn-debug.log*
|
| 6 |
+
yarn-error.log*
|
| 7 |
+
pnpm-debug.log*
|
| 8 |
+
lerna-debug.log*
|
| 9 |
+
|
| 10 |
+
node_modules
|
| 11 |
+
.DS_Store
|
| 12 |
+
dist
|
| 13 |
+
*.local
|
| 14 |
+
|
| 15 |
+
# Editor directories and files
|
| 16 |
+
.idea
|
| 17 |
+
*.suo
|
| 18 |
+
*.ntvs*
|
| 19 |
+
*.njsproj
|
| 20 |
+
*.sln
|
| 21 |
+
*.sw?
|
Dockerfile
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 使用Node.js作为基础镜像进行构建
|
| 2 |
+
FROM node:18-alpine AS build-stage
|
| 3 |
+
|
| 4 |
+
# 设置工作目录
|
| 5 |
+
WORKDIR /app
|
| 6 |
+
|
| 7 |
+
# 安装pnpm
|
| 8 |
+
RUN npm install -g pnpm
|
| 9 |
+
|
| 10 |
+
# 复制依赖文件并安装
|
| 11 |
+
COPY package.json pnpm-lock.yaml ./
|
| 12 |
+
RUN pnpm install
|
| 13 |
+
|
| 14 |
+
# 复制源代码并构建 H5 版本
|
| 15 |
+
COPY . .
|
| 16 |
+
RUN pnpm run build:h5
|
| 17 |
+
|
| 18 |
+
# 使用Nginx作为基础镜像进行部署
|
| 19 |
+
FROM nginx:stable-alpine AS production-stage
|
| 20 |
+
|
| 21 |
+
# 复制构建好的静态文件到Nginx目录
|
| 22 |
+
# UniApp H5 默认构建目录是 dist/build/h5
|
| 23 |
+
COPY --from=build-stage /app/dist/build/h5 /usr/share/nginx/html
|
| 24 |
+
|
| 25 |
+
# 复制自定义Nginx配置
|
| 26 |
+
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
| 27 |
+
|
| 28 |
+
# 暴露80端口
|
| 29 |
+
EXPOSE 80
|
| 30 |
+
|
| 31 |
+
# 启动Nginx
|
| 32 |
+
CMD ["nginx", "-g", "daemon off;"]
|
README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: UniApp多平台小程序演示
|
| 3 |
+
emoji: 🚀
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: green
|
| 6 |
+
sdk: docker
|
| 7 |
+
app_port: 80
|
| 8 |
+
short_description: UniApp多平台小程序,一套代码运行在微信、支付宝、百度、抖音等平台。
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
# UniApp 多平台小程序
|
| 12 |
+
|
| 13 |
+
## 项目简介
|
| 14 |
+
基于 UniApp 框架开发的多平台小程序应用,支持微信、支付宝、百度、抖音等主流小程序平台。项目采用中文界面和代码注释,提供完整的用户交互体验和现代化的 UI 设计。
|
| 15 |
+
|
| 16 |
+
## 功能特性
|
| 17 |
+
- 🚀 **一套代码,多端运行**:支持微信、支付宝、百度、抖音、QQ、H5 等平台。
|
| 18 |
+
- 🎨 **现代化 UI 设计**:采用卡片式布局,界面美观大方。
|
| 19 |
+
- 🌐 **全中文支持**:包括界面文字、提示信息、代码注释等。
|
| 20 |
+
- 📦 **Docker 部署**:支持一键 Docker 构建和部署,适配 Hugging Face Spaces。
|
| 21 |
+
|
| 22 |
+
## 页面展示
|
| 23 |
+
1. **首页**:轮播图、功能入口、热门推荐。
|
| 24 |
+
2. **功能演示**:表单交互、条件编译、反馈提示。
|
| 25 |
+
3. **个人中心**:用户信息、统计数据、功能菜单。
|
| 26 |
+
4. **登录页面**:手机号登录、微信一键登录。
|
| 27 |
+
|
| 28 |
+
## 开发指南
|
| 29 |
+
|
| 30 |
+
### 环境要求
|
| 31 |
+
- Node.js >= 16.0.0
|
| 32 |
+
- pnpm >= 8.0.0
|
| 33 |
+
|
| 34 |
+
### 安装依赖
|
| 35 |
+
```bash
|
| 36 |
+
pnpm install
|
| 37 |
+
```
|
| 38 |
+
|
| 39 |
+
### 开发环境运行
|
| 40 |
+
```bash
|
| 41 |
+
# 运行到微信小程序
|
| 42 |
+
pnpm run dev:mp-weixin
|
| 43 |
+
|
| 44 |
+
# 运行到 H5
|
| 45 |
+
pnpm run dev:h5
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
### 生产环境构建
|
| 49 |
+
```bash
|
| 50 |
+
# 构建微信小程序
|
| 51 |
+
pnpm run build:mp-weixin
|
| 52 |
+
|
| 53 |
+
# 构建 H5
|
| 54 |
+
pnpm run build:h5
|
| 55 |
+
```
|
| 56 |
+
|
| 57 |
+
## 部署说明
|
| 58 |
+
|
| 59 |
+
### Docker 部署
|
| 60 |
+
```bash
|
| 61 |
+
# 构建镜像
|
| 62 |
+
docker build -t uniapp-app .
|
| 63 |
+
|
| 64 |
+
# 运行容器
|
| 65 |
+
docker run -d -p 80:80 uniapp-app
|
| 66 |
+
```
|
| 67 |
+
|
| 68 |
+
## 项目结构
|
| 69 |
+
```text
|
| 70 |
+
uniapp-miniprogram/
|
| 71 |
+
├── src/
|
| 72 |
+
│ ├── pages/ # 页面目录
|
| 73 |
+
│ ├── static/ # 静态资源
|
| 74 |
+
│ ├── App.vue # 应用主入口
|
| 75 |
+
│ ├── manifest.json # 应用配置
|
| 76 |
+
│ ├── pages.json # 路由配置
|
| 77 |
+
│ └── uni.scss # 全局样式
|
| 78 |
+
├── Dockerfile # Docker 配置文件
|
| 79 |
+
├── nginx.conf # Nginx 配置文件
|
| 80 |
+
└── package.json # 项目依赖
|
| 81 |
+
```
|
| 82 |
+
|
| 83 |
+
## 许可证
|
| 84 |
+
MIT License
|
index.html
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html>
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8" />
|
| 5 |
+
<script>
|
| 6 |
+
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
| 7 |
+
CSS.supports('top: constant(a)'))
|
| 8 |
+
document.write(
|
| 9 |
+
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
| 10 |
+
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
| 11 |
+
</script>
|
| 12 |
+
<title></title>
|
| 13 |
+
<!--preload-links-->
|
| 14 |
+
<!--app-context-->
|
| 15 |
+
</head>
|
| 16 |
+
<body>
|
| 17 |
+
<div id="app"><!--app-html--></div>
|
| 18 |
+
<script type="module" src="/src/main.ts"></script>
|
| 19 |
+
</body>
|
| 20 |
+
</html>
|
nginx.conf
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
server {
|
| 2 |
+
listen 80;
|
| 3 |
+
server_name localhost;
|
| 4 |
+
|
| 5 |
+
# 静态资源目录
|
| 6 |
+
location / {
|
| 7 |
+
root /usr/share/nginx/html;
|
| 8 |
+
index index.html index.htm;
|
| 9 |
+
# 支持单页应用路由
|
| 10 |
+
try_files $uri $uri/ /index.html;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
# 错误页面处理
|
| 14 |
+
error_page 500 502 503 504 /50x.html;
|
| 15 |
+
location = /50x.html {
|
| 16 |
+
root /usr/share/nginx/html;
|
| 17 |
+
}
|
| 18 |
+
}
|
package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "uni-preset-vue",
|
| 3 |
+
"version": "0.0.0",
|
| 4 |
+
"scripts": {
|
| 5 |
+
"dev:custom": "uni -p",
|
| 6 |
+
"dev:h5": "uni",
|
| 7 |
+
"dev:h5:ssr": "uni --ssr",
|
| 8 |
+
"dev:mp-alipay": "uni -p mp-alipay",
|
| 9 |
+
"dev:mp-baidu": "uni -p mp-baidu",
|
| 10 |
+
"dev:mp-jd": "uni -p mp-jd",
|
| 11 |
+
"dev:mp-kuaishou": "uni -p mp-kuaishou",
|
| 12 |
+
"dev:mp-lark": "uni -p mp-lark",
|
| 13 |
+
"dev:mp-qq": "uni -p mp-qq",
|
| 14 |
+
"dev:mp-toutiao": "uni -p mp-toutiao",
|
| 15 |
+
"dev:mp-harmony": "uni -p mp-harmony",
|
| 16 |
+
"dev:mp-weixin": "uni -p mp-weixin",
|
| 17 |
+
"dev:mp-xhs": "uni -p mp-xhs",
|
| 18 |
+
"dev:quickapp-webview": "uni -p quickapp-webview",
|
| 19 |
+
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
|
| 20 |
+
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
|
| 21 |
+
"build:custom": "uni build -p",
|
| 22 |
+
"build:h5": "uni build",
|
| 23 |
+
"build:h5:ssr": "uni build --ssr",
|
| 24 |
+
"build:mp-alipay": "uni build -p mp-alipay",
|
| 25 |
+
"build:mp-baidu": "uni build -p mp-baidu",
|
| 26 |
+
"build:mp-jd": "uni build -p mp-jd",
|
| 27 |
+
"build:mp-kuaishou": "uni build -p mp-kuaishou",
|
| 28 |
+
"build:mp-lark": "uni build -p mp-lark",
|
| 29 |
+
"build:mp-qq": "uni build -p mp-qq",
|
| 30 |
+
"build:mp-toutiao": "uni build -p mp-toutiao",
|
| 31 |
+
"build:mp-harmony": "uni build -p mp-harmony",
|
| 32 |
+
"build:mp-weixin": "uni build -p mp-weixin",
|
| 33 |
+
"build:mp-xhs": "uni build -p mp-xhs",
|
| 34 |
+
"build:quickapp-webview": "uni build -p quickapp-webview",
|
| 35 |
+
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
|
| 36 |
+
"build:quickapp-webview-union": "uni build -p quickapp-webview-union",
|
| 37 |
+
"type-check": "vue-tsc --noEmit"
|
| 38 |
+
},
|
| 39 |
+
"dependencies": {
|
| 40 |
+
"@dcloudio/uni-app": "3.0.0-4080720251210001",
|
| 41 |
+
"@dcloudio/uni-app-harmony": "3.0.0-4080720251210001",
|
| 42 |
+
"@dcloudio/uni-app-plus": "3.0.0-4080720251210001",
|
| 43 |
+
"@dcloudio/uni-components": "3.0.0-4080720251210001",
|
| 44 |
+
"@dcloudio/uni-h5": "3.0.0-4080720251210001",
|
| 45 |
+
"@dcloudio/uni-mp-alipay": "3.0.0-4080720251210001",
|
| 46 |
+
"@dcloudio/uni-mp-baidu": "3.0.0-4080720251210001",
|
| 47 |
+
"@dcloudio/uni-mp-harmony": "3.0.0-4080720251210001",
|
| 48 |
+
"@dcloudio/uni-mp-jd": "3.0.0-4080720251210001",
|
| 49 |
+
"@dcloudio/uni-mp-kuaishou": "3.0.0-4080720251210001",
|
| 50 |
+
"@dcloudio/uni-mp-lark": "3.0.0-4080720251210001",
|
| 51 |
+
"@dcloudio/uni-mp-qq": "3.0.0-4080720251210001",
|
| 52 |
+
"@dcloudio/uni-mp-toutiao": "3.0.0-4080720251210001",
|
| 53 |
+
"@dcloudio/uni-mp-weixin": "3.0.0-4080720251210001",
|
| 54 |
+
"@dcloudio/uni-mp-xhs": "3.0.0-4080720251210001",
|
| 55 |
+
"@dcloudio/uni-quickapp-webview": "3.0.0-4080720251210001",
|
| 56 |
+
"vue": "^3.4.21",
|
| 57 |
+
"vue-i18n": "^9.1.9"
|
| 58 |
+
},
|
| 59 |
+
"devDependencies": {
|
| 60 |
+
"@dcloudio/types": "^3.4.8",
|
| 61 |
+
"@dcloudio/uni-automator": "3.0.0-4080720251210001",
|
| 62 |
+
"@dcloudio/uni-cli-shared": "3.0.0-4080720251210001",
|
| 63 |
+
"@dcloudio/uni-stacktracey": "3.0.0-4080720251210001",
|
| 64 |
+
"@dcloudio/vite-plugin-uni": "3.0.0-4080720251210001",
|
| 65 |
+
"@vue/runtime-core": "^3.4.21",
|
| 66 |
+
"@vue/tsconfig": "^0.1.3",
|
| 67 |
+
"sass": "^1.97.3",
|
| 68 |
+
"sass-loader": "^16.0.7",
|
| 69 |
+
"typescript": "^4.9.4",
|
| 70 |
+
"vite": "5.2.8",
|
| 71 |
+
"vue-tsc": "^1.0.24"
|
| 72 |
+
}
|
| 73 |
+
}
|
pnpm-lock.yaml
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
shims-uni.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/// <reference types='@dcloudio/types' />
|
| 2 |
+
import 'vue'
|
| 3 |
+
|
| 4 |
+
declare module '@vue/runtime-core' {
|
| 5 |
+
type Hooks = App.AppInstance & Page.PageInstance;
|
| 6 |
+
|
| 7 |
+
interface ComponentCustomOptions extends Hooks {
|
| 8 |
+
|
| 9 |
+
}
|
| 10 |
+
}
|
src/App.vue
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script setup lang="ts">
|
| 2 |
+
import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
|
| 3 |
+
onLaunch(() => {
|
| 4 |
+
console.log("App Launch");
|
| 5 |
+
});
|
| 6 |
+
onShow(() => {
|
| 7 |
+
console.log("App Show");
|
| 8 |
+
});
|
| 9 |
+
onHide(() => {
|
| 10 |
+
console.log("App Hide");
|
| 11 |
+
});
|
| 12 |
+
</script>
|
| 13 |
+
<style lang="scss">
|
| 14 |
+
/* H5 网页限制最大宽度并居中 */
|
| 15 |
+
/* #ifdef H5 */
|
| 16 |
+
uni-page-body,
|
| 17 |
+
body {
|
| 18 |
+
display: flex;
|
| 19 |
+
justify-content: center;
|
| 20 |
+
background-color: #f0f0f0 !important; /* 背景灰色,突出手机显示区域 */
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
uni-page-wrapper {
|
| 24 |
+
max-width: 500px !important; /* 限制宽度 */
|
| 25 |
+
margin: 0 auto !important;
|
| 26 |
+
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
|
| 27 |
+
background-color: #fff;
|
| 28 |
+
min-height: 100vh;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
/* 适配顶部导航栏 */
|
| 32 |
+
uni-page-head {
|
| 33 |
+
max-width: 500px !important;
|
| 34 |
+
margin: 0 auto !important;
|
| 35 |
+
left: 0 !important;
|
| 36 |
+
right: 0 !important;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
/* 适配底部 TabBar */
|
| 40 |
+
uni-tabbar {
|
| 41 |
+
max-width: 500px !important;
|
| 42 |
+
margin: 0 auto !important;
|
| 43 |
+
left: 0 !important;
|
| 44 |
+
right: 0 !important;
|
| 45 |
+
}
|
| 46 |
+
/* #endif */
|
| 47 |
+
</style>
|
src/env.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/// <reference types="vite/client" />
|
| 2 |
+
|
| 3 |
+
declare module '*.vue' {
|
| 4 |
+
import { DefineComponent } from 'vue'
|
| 5 |
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
| 6 |
+
const component: DefineComponent<{}, {}, any>
|
| 7 |
+
export default component
|
| 8 |
+
}
|
src/main.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { createSSRApp } from "vue";
|
| 2 |
+
import App from "./App.vue";
|
| 3 |
+
export function createApp() {
|
| 4 |
+
const app = createSSRApp(App);
|
| 5 |
+
return {
|
| 6 |
+
app,
|
| 7 |
+
};
|
| 8 |
+
}
|
src/manifest.json
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "UniApp多平台小程序",
|
| 3 |
+
"appid": "__UNI__XXXXXX",
|
| 4 |
+
"description": "基于UniApp的多平台小程序,支持微信、支付宝、百度、抖音等主流小程序平台。",
|
| 5 |
+
"versionName": "1.0.0",
|
| 6 |
+
"versionCode": "100",
|
| 7 |
+
"transformPx": false,
|
| 8 |
+
"app-plus": {
|
| 9 |
+
"usingComponents": true,
|
| 10 |
+
"nvueStyleCompiler": "uni-app",
|
| 11 |
+
"compilerVersion": 3,
|
| 12 |
+
"splashscreen": {
|
| 13 |
+
"alwaysShowBeforeRender": true,
|
| 14 |
+
"waiting": true,
|
| 15 |
+
"autoclose": true,
|
| 16 |
+
"delay": 0
|
| 17 |
+
},
|
| 18 |
+
"modules": {},
|
| 19 |
+
"distribute": {
|
| 20 |
+
"android": {
|
| 21 |
+
"permissions": [
|
| 22 |
+
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\" />",
|
| 23 |
+
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\" />",
|
| 24 |
+
"<uses-permission android:name=\"android.permission.VIBRATE\" />",
|
| 25 |
+
"<uses-permission android:name=\"android.permission.READ_LOGS\" />",
|
| 26 |
+
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" />",
|
| 27 |
+
"<uses-feature android:name=\"android.hardware.camera.autofocus\" />",
|
| 28 |
+
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />",
|
| 29 |
+
"<uses-permission android:name=\"android.permission.CAMERA\" />",
|
| 30 |
+
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\" />",
|
| 31 |
+
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\" />",
|
| 32 |
+
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\" />",
|
| 33 |
+
"<uses-permission android:name=\"android.permission.WAKE_LOCK\" />",
|
| 34 |
+
"<uses-permission android:name=\"android.permission.FLASHLIGHT\" />",
|
| 35 |
+
"<uses-permission android:name=\"android.hardware.camera\" />",
|
| 36 |
+
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\" />"
|
| 37 |
+
]
|
| 38 |
+
},
|
| 39 |
+
"ios": {},
|
| 40 |
+
"sdkConfigs": {}
|
| 41 |
+
}
|
| 42 |
+
},
|
| 43 |
+
"quickapp": {},
|
| 44 |
+
"mp-weixin": {
|
| 45 |
+
"appid": "",
|
| 46 |
+
"setting": {
|
| 47 |
+
"urlCheck": false,
|
| 48 |
+
"es6": true,
|
| 49 |
+
"enhance": true,
|
| 50 |
+
"postcss": true,
|
| 51 |
+
"preloadBackgroundData": false,
|
| 52 |
+
"minified": true,
|
| 53 |
+
"newFeature": false,
|
| 54 |
+
"coverView": true,
|
| 55 |
+
"nodeModules": false,
|
| 56 |
+
"autoAudits": false,
|
| 57 |
+
"showShadowRootInWxmlPanel": true,
|
| 58 |
+
"scopeDataCheck": false,
|
| 59 |
+
"uglifyFileName": false,
|
| 60 |
+
"checkInvalidKey": true,
|
| 61 |
+
"checkSiteMap": true,
|
| 62 |
+
"uploadWithSourceMap": true,
|
| 63 |
+
"compileHotReLoad": false,
|
| 64 |
+
"lazyloadPlaceholderEnable": false,
|
| 65 |
+
"useMultiFrameRuntime": true,
|
| 66 |
+
"useApiHook": true,
|
| 67 |
+
"useApiHostProcess": true,
|
| 68 |
+
"babelSetting": {
|
| 69 |
+
"ignore": [],
|
| 70 |
+
"disablePlugins": [],
|
| 71 |
+
"outputPath": ""
|
| 72 |
+
},
|
| 73 |
+
"enableEngineNative": false,
|
| 74 |
+
"useIsolateContext": true,
|
| 75 |
+
"userConfirmedBundleSwitch": false,
|
| 76 |
+
"packNpmManually": false,
|
| 77 |
+
"packNpmRelationList": [],
|
| 78 |
+
"minifyWXSS": true,
|
| 79 |
+
"disableUseStrict": false,
|
| 80 |
+
"minifyWXML": true,
|
| 81 |
+
"showES6CompileOption": false,
|
| 82 |
+
"useCompilerPlugins": false
|
| 83 |
+
},
|
| 84 |
+
"usingComponents": true,
|
| 85 |
+
"permission": {
|
| 86 |
+
"scope.userLocation": {
|
| 87 |
+
"desc": "获取位置信息用于小程序位置接口的效果展示"
|
| 88 |
+
}
|
| 89 |
+
},
|
| 90 |
+
"optimization": {
|
| 91 |
+
"subPackages": true
|
| 92 |
+
},
|
| 93 |
+
"uniStatistics": {
|
| 94 |
+
"enable": false
|
| 95 |
+
}
|
| 96 |
+
},
|
| 97 |
+
"mp-alipay": {
|
| 98 |
+
"usingComponents": true,
|
| 99 |
+
"component2": true
|
| 100 |
+
},
|
| 101 |
+
"mp-baidu": {
|
| 102 |
+
"usingComponents": true
|
| 103 |
+
},
|
| 104 |
+
"mp-toutiao": {
|
| 105 |
+
"usingComponents": true
|
| 106 |
+
},
|
| 107 |
+
"uniStatistics": {
|
| 108 |
+
"enable": false
|
| 109 |
+
},
|
| 110 |
+
"vueVersion": "3"
|
| 111 |
+
}
|
src/pages.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"pages": [
|
| 3 |
+
{
|
| 4 |
+
"path": "pages/index/index",
|
| 5 |
+
"style": {
|
| 6 |
+
"navigationBarTitleText": "首页",
|
| 7 |
+
"enablePullDownRefresh": true
|
| 8 |
+
}
|
| 9 |
+
},
|
| 10 |
+
{
|
| 11 |
+
"path": "pages/profile/profile",
|
| 12 |
+
"style": {
|
| 13 |
+
"navigationBarTitleText": "个人中心"
|
| 14 |
+
}
|
| 15 |
+
},
|
| 16 |
+
{
|
| 17 |
+
"path": "pages/function/function",
|
| 18 |
+
"style": {
|
| 19 |
+
"navigationBarTitleText": "功能"
|
| 20 |
+
}
|
| 21 |
+
},
|
| 22 |
+
{
|
| 23 |
+
"path": "pages/login/login",
|
| 24 |
+
"style": {
|
| 25 |
+
"navigationBarTitleText": "登录"
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
],
|
| 29 |
+
"globalStyle": {
|
| 30 |
+
"navigationBarTextStyle": "black",
|
| 31 |
+
"navigationBarTitleText": "UniApp小程序",
|
| 32 |
+
"navigationBarBackgroundColor": "#F8F8F8",
|
| 33 |
+
"backgroundColor": "#F8F8F8"
|
| 34 |
+
},
|
| 35 |
+
"uniIdRouter": {},
|
| 36 |
+
"tabBar": {
|
| 37 |
+
"color": "#7A7E83",
|
| 38 |
+
"selectedColor": "#1890ff",
|
| 39 |
+
"borderStyle": "black",
|
| 40 |
+
"backgroundColor": "#ffffff",
|
| 41 |
+
"list": [
|
| 42 |
+
{
|
| 43 |
+
"pagePath": "pages/index/index",
|
| 44 |
+
"text": "首页"
|
| 45 |
+
},
|
| 46 |
+
{
|
| 47 |
+
"pagePath": "pages/function/function",
|
| 48 |
+
"text": "功能"
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
"pagePath": "pages/profile/profile",
|
| 52 |
+
"text": "我的"
|
| 53 |
+
}
|
| 54 |
+
]
|
| 55 |
+
}
|
| 56 |
+
}
|
src/pages/function/function.vue
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<template>
|
| 2 |
+
<view class="container">
|
| 3 |
+
<view class="card">
|
| 4 |
+
<view class="card-title">表单交互演示</view>
|
| 5 |
+
<view class="form-item">
|
| 6 |
+
<text class="label">输入内容:</text>
|
| 7 |
+
<input class="input" v-model="inputValue" placeholder="请输入内容" />
|
| 8 |
+
</view>
|
| 9 |
+
<view class="form-item">
|
| 10 |
+
<text class="label">当前输入:</text>
|
| 11 |
+
<text class="value">{{ inputValue || '暂无内容' }}</text>
|
| 12 |
+
</view>
|
| 13 |
+
<button class="primary-btn" @tap="handleSubmit">提交数据</button>
|
| 14 |
+
</view>
|
| 15 |
+
|
| 16 |
+
<view class="card">
|
| 17 |
+
<view class="card-title">条件编译演示</view>
|
| 18 |
+
<view class="platform-box">
|
| 19 |
+
<!-- #ifdef MP-WEIXIN -->
|
| 20 |
+
<view class="platform-tag weixin">当前处于:微信小程序</view>
|
| 21 |
+
<!-- #endif -->
|
| 22 |
+
<!-- #ifdef MP-ALIPAY -->
|
| 23 |
+
<view class="platform-tag alipay">当前处于:支付宝小程序</view>
|
| 24 |
+
<!-- #endif -->
|
| 25 |
+
<!-- #ifdef H5 -->
|
| 26 |
+
<view class="platform-tag h5">当前处于:H5 网页</view>
|
| 27 |
+
<!-- #endif -->
|
| 28 |
+
<view class="desc">这里使用了 UniApp 的条件编译功能,不同平台会显示不同的内容。</view>
|
| 29 |
+
</view>
|
| 30 |
+
</view>
|
| 31 |
+
|
| 32 |
+
<view class="card">
|
| 33 |
+
<view class="card-title">交互反馈演示</view>
|
| 34 |
+
<view class="btn-group">
|
| 35 |
+
<button class="btn" @tap="showToast">显示提示</button>
|
| 36 |
+
<button class="btn" @tap="showLoading">显示加载</button>
|
| 37 |
+
<button class="btn" @tap="showModal">显示弹窗</button>
|
| 38 |
+
</view>
|
| 39 |
+
</view>
|
| 40 |
+
</view>
|
| 41 |
+
</template>
|
| 42 |
+
|
| 43 |
+
<script setup lang="ts">
|
| 44 |
+
import { ref } from 'vue'
|
| 45 |
+
|
| 46 |
+
const inputValue = ref('')
|
| 47 |
+
|
| 48 |
+
const handleSubmit = () => {
|
| 49 |
+
if (!inputValue.value) {
|
| 50 |
+
uni.showToast({ title: '请输入内容', icon: 'none' })
|
| 51 |
+
return
|
| 52 |
+
}
|
| 53 |
+
uni.showToast({ title: '提交成功', icon: 'success' })
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
const showToast = () => {
|
| 57 |
+
uni.showToast({ title: '这是一个提示信息' })
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
const showLoading = () => {
|
| 61 |
+
uni.showLoading({ title: '加载中...' })
|
| 62 |
+
setTimeout(() => {
|
| 63 |
+
uni.hideLoading()
|
| 64 |
+
}, 2000)
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
const showModal = () => {
|
| 68 |
+
uni.showModal({
|
| 69 |
+
title: '温馨提示',
|
| 70 |
+
content: '这是一个自定义弹窗内容,用于确认用户操作。',
|
| 71 |
+
confirmText: '确定',
|
| 72 |
+
cancelText: '取消'
|
| 73 |
+
})
|
| 74 |
+
}
|
| 75 |
+
</script>
|
| 76 |
+
|
| 77 |
+
<style lang="scss">
|
| 78 |
+
.container {
|
| 79 |
+
padding: 30rpx;
|
| 80 |
+
background-color: #f8f8f8;
|
| 81 |
+
min-height: 100vh;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
.card {
|
| 85 |
+
background-color: #fff;
|
| 86 |
+
border-radius: 16rpx;
|
| 87 |
+
padding: 30rpx;
|
| 88 |
+
margin-bottom: 30rpx;
|
| 89 |
+
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.05);
|
| 90 |
+
|
| 91 |
+
.card-title {
|
| 92 |
+
font-size: 32rpx;
|
| 93 |
+
font-weight: bold;
|
| 94 |
+
color: #333;
|
| 95 |
+
margin-bottom: 30rpx;
|
| 96 |
+
padding-left: 20rpx;
|
| 97 |
+
border-left: 8rpx solid #1890ff;
|
| 98 |
+
}
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
.form-item {
|
| 102 |
+
display: flex;
|
| 103 |
+
align-items: center;
|
| 104 |
+
margin-bottom: 30rpx;
|
| 105 |
+
|
| 106 |
+
.label {
|
| 107 |
+
font-size: 28rpx;
|
| 108 |
+
color: #666;
|
| 109 |
+
width: 160rpx;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
.input {
|
| 113 |
+
flex: 1;
|
| 114 |
+
height: 80rpx;
|
| 115 |
+
border: 1rpx solid #ddd;
|
| 116 |
+
border-radius: 8rpx;
|
| 117 |
+
padding: 0 20rpx;
|
| 118 |
+
font-size: 28rpx;
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
.value {
|
| 122 |
+
font-size: 28rpx;
|
| 123 |
+
color: #1890ff;
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
.primary-btn {
|
| 128 |
+
background-color: #1890ff;
|
| 129 |
+
color: #fff;
|
| 130 |
+
font-size: 30rpx;
|
| 131 |
+
border-radius: 8rpx;
|
| 132 |
+
height: 80rpx;
|
| 133 |
+
line-height: 80rpx;
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
.platform-box {
|
| 137 |
+
.platform-tag {
|
| 138 |
+
padding: 20rpx;
|
| 139 |
+
border-radius: 8rpx;
|
| 140 |
+
color: #fff;
|
| 141 |
+
font-size: 28rpx;
|
| 142 |
+
text-align: center;
|
| 143 |
+
margin-bottom: 20rpx;
|
| 144 |
+
|
| 145 |
+
&.weixin { background-color: #07c160; }
|
| 146 |
+
&.alipay { background-color: #1677ff; }
|
| 147 |
+
&.h5 { background-color: #ff4d4f; }
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
.desc {
|
| 151 |
+
font-size: 24rpx;
|
| 152 |
+
color: #999;
|
| 153 |
+
line-height: 1.6;
|
| 154 |
+
}
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
.btn-group {
|
| 158 |
+
display: flex;
|
| 159 |
+
flex-direction: column;
|
| 160 |
+
gap: 20rpx;
|
| 161 |
+
|
| 162 |
+
.btn {
|
| 163 |
+
font-size: 28rpx;
|
| 164 |
+
background-color: #f5f5f5;
|
| 165 |
+
color: #333;
|
| 166 |
+
border: none;
|
| 167 |
+
|
| 168 |
+
&::after { border: none; }
|
| 169 |
+
}
|
| 170 |
+
}
|
| 171 |
+
</style>
|
src/pages/index/index.vue
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<template>
|
| 2 |
+
<view class="container">
|
| 3 |
+
<!-- 轮播图模块 -->
|
| 4 |
+
<swiper class="banner" circular autoplay indicator-dots indicator-color="rgba(255,255,255,0.6)" indicator-active-color="#fff">
|
| 5 |
+
<swiper-item v-for="(item, index) in banners" :key="index">
|
| 6 |
+
<image :src="item.image" mode="aspectFill" class="banner-image"></image>
|
| 7 |
+
</swiper-item>
|
| 8 |
+
</swiper>
|
| 9 |
+
|
| 10 |
+
<!-- 功能入口网格 -->
|
| 11 |
+
<view class="grid">
|
| 12 |
+
<view class="grid-item" v-for="(item, index) in gridItems" :key="index" @tap="navigateTo(item.path)">
|
| 13 |
+
<view class="grid-icon-box" :style="{ backgroundColor: item.color }">
|
| 14 |
+
<uni-icons :type="item.icon" size="24" color="#fff"></uni-icons>
|
| 15 |
+
</view>
|
| 16 |
+
<text class="grid-text">{{ item.text }}</text>
|
| 17 |
+
</view>
|
| 18 |
+
</view>
|
| 19 |
+
|
| 20 |
+
<!-- 推荐内容列表 -->
|
| 21 |
+
<view class="section">
|
| 22 |
+
<view class="section-title">热门推荐</view>
|
| 23 |
+
<view class="list">
|
| 24 |
+
<view class="list-item" v-for="(item, index) in recommendations" :key="index">
|
| 25 |
+
<image :src="item.image" mode="aspectFill" class="list-image"></image>
|
| 26 |
+
<view class="list-content">
|
| 27 |
+
<view class="list-title">{{ item.title }}</view>
|
| 28 |
+
<view class="list-desc">{{ item.desc }}</view>
|
| 29 |
+
</view>
|
| 30 |
+
</view>
|
| 31 |
+
</view>
|
| 32 |
+
</view>
|
| 33 |
+
</view>
|
| 34 |
+
</template>
|
| 35 |
+
|
| 36 |
+
<script setup lang="ts">
|
| 37 |
+
import { ref } from 'vue'
|
| 38 |
+
|
| 39 |
+
// 轮播图数据
|
| 40 |
+
const banners = ref([
|
| 41 |
+
{ image: 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=modern+tech+banner+blue&image_size=landscape_16_9' },
|
| 42 |
+
{ image: 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=abstract+digital+background+vibrant&image_size=landscape_16_9' },
|
| 43 |
+
{ image: 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=futuristic+interface+design&image_size=landscape_16_9' }
|
| 44 |
+
])
|
| 45 |
+
|
| 46 |
+
// 功能网格数据
|
| 47 |
+
const gridItems = ref([
|
| 48 |
+
{ text: '功能演示', icon: 'star', color: '#1890ff', path: '/pages/function/function' },
|
| 49 |
+
{ text: '个人中心', icon: 'person', color: '#52c41a', path: '/pages/profile/profile' },
|
| 50 |
+
{ text: '联系我们', icon: 'chat', color: '#faad14', path: '/pages/index/index' },
|
| 51 |
+
{ text: '设置', icon: 'gear', color: '#f5222d', path: '/pages/index/index' }
|
| 52 |
+
])
|
| 53 |
+
|
| 54 |
+
// 推荐列表数据
|
| 55 |
+
const recommendations = ref([
|
| 56 |
+
{ title: 'UniApp 跨平台开发指南', desc: '一套代码,多端运行,极大地提高开发效率。', image: 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=coding+laptop+desk&image_size=square' },
|
| 57 |
+
{ title: '小程序生态概览', desc: '深度解析微信、支付宝等主流小程序平台的差异与优势。', image: 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=mobile+apps+network&image_size=square' },
|
| 58 |
+
{ title: 'Vue3 + TypeScript 实战', desc: '利用现代前端技术栈构建健壮的小程序应用。', image: 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=vuejs+typescript+logo&image_size=square' }
|
| 59 |
+
])
|
| 60 |
+
|
| 61 |
+
// 页面跳转
|
| 62 |
+
const navigateTo = (path: string) => {
|
| 63 |
+
uni.switchTab({ url: path }).catch(() => {
|
| 64 |
+
uni.navigateTo({ url: path })
|
| 65 |
+
})
|
| 66 |
+
}
|
| 67 |
+
</script>
|
| 68 |
+
|
| 69 |
+
<style lang="scss">
|
| 70 |
+
.container {
|
| 71 |
+
background-color: #f8f8f8;
|
| 72 |
+
min-height: 100vh;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
.banner {
|
| 76 |
+
height: 360rpx;
|
| 77 |
+
.banner-image {
|
| 78 |
+
width: 100%;
|
| 79 |
+
height: 100%;
|
| 80 |
+
}
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
.grid {
|
| 84 |
+
display: flex;
|
| 85 |
+
flex-wrap: wrap;
|
| 86 |
+
padding: 20rpx;
|
| 87 |
+
background-color: #fff;
|
| 88 |
+
margin-bottom: 20rpx;
|
| 89 |
+
|
| 90 |
+
.grid-item {
|
| 91 |
+
width: 25%;
|
| 92 |
+
display: flex;
|
| 93 |
+
flex-direction: column;
|
| 94 |
+
align-items: center;
|
| 95 |
+
padding: 20rpx 0;
|
| 96 |
+
|
| 97 |
+
.grid-icon-box {
|
| 98 |
+
width: 90rpx;
|
| 99 |
+
height: 90rpx;
|
| 100 |
+
border-radius: 20rpx;
|
| 101 |
+
display: flex;
|
| 102 |
+
justify-content: center;
|
| 103 |
+
align-items: center;
|
| 104 |
+
margin-bottom: 12rpx;
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
.grid-text {
|
| 108 |
+
font-size: 24rpx;
|
| 109 |
+
color: #333;
|
| 110 |
+
}
|
| 111 |
+
}
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.section {
|
| 115 |
+
padding: 20rpx;
|
| 116 |
+
background-color: #fff;
|
| 117 |
+
|
| 118 |
+
.section-title {
|
| 119 |
+
font-size: 32rpx;
|
| 120 |
+
font-weight: bold;
|
| 121 |
+
margin-bottom: 20rpx;
|
| 122 |
+
color: #333;
|
| 123 |
+
padding-left: 10rpx;
|
| 124 |
+
border-left: 8rpx solid #1890ff;
|
| 125 |
+
}
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
.list {
|
| 129 |
+
.list-item {
|
| 130 |
+
display: flex;
|
| 131 |
+
padding: 20rpx 0;
|
| 132 |
+
border-bottom: 1rpx solid #eee;
|
| 133 |
+
|
| 134 |
+
&:last-child {
|
| 135 |
+
border-bottom: none;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
.list-image {
|
| 139 |
+
width: 160rpx;
|
| 140 |
+
height: 160rpx;
|
| 141 |
+
border-radius: 12rpx;
|
| 142 |
+
margin-right: 20rpx;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
.list-content {
|
| 146 |
+
flex: 1;
|
| 147 |
+
display: flex;
|
| 148 |
+
flex-direction: column;
|
| 149 |
+
justify-content: center;
|
| 150 |
+
|
| 151 |
+
.list-title {
|
| 152 |
+
font-size: 28rpx;
|
| 153 |
+
font-weight: bold;
|
| 154 |
+
color: #333;
|
| 155 |
+
margin-bottom: 10rpx;
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
.list-desc {
|
| 159 |
+
font-size: 24rpx;
|
| 160 |
+
color: #666;
|
| 161 |
+
line-height: 1.4;
|
| 162 |
+
}
|
| 163 |
+
}
|
| 164 |
+
}
|
| 165 |
+
}
|
| 166 |
+
</style>
|
src/pages/login/login.vue
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<template>
|
| 2 |
+
<view class="container">
|
| 3 |
+
<view class="login-box">
|
| 4 |
+
<image class="logo" src="https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=app+logo+minimalist+blue&image_size=square" mode="aspectFit"></image>
|
| 5 |
+
<view class="title">欢迎使用</view>
|
| 6 |
+
<view class="subtitle">UniApp 多平台小程序演示</view>
|
| 7 |
+
|
| 8 |
+
<view class="input-group">
|
| 9 |
+
<view class="input-item">
|
| 10 |
+
<uni-icons type="phone" size="20" color="#999"></uni-icons>
|
| 11 |
+
<input class="input" type="number" v-model="phone" placeholder="请输入手机号" maxlength="11" />
|
| 12 |
+
</view>
|
| 13 |
+
<view class="input-item">
|
| 14 |
+
<uni-icons type="mail" size="20" color="#999"></uni-icons>
|
| 15 |
+
<input class="input" type="number" v-model="code" placeholder="请输入验证码" maxlength="6" />
|
| 16 |
+
<text class="get-code" :class="{ disabled: countdown > 0 }" @tap="getCode">
|
| 17 |
+
{{ countdown > 0 ? `${countdown}s` : '获取验证码' }}
|
| 18 |
+
</text>
|
| 19 |
+
</view>
|
| 20 |
+
</view>
|
| 21 |
+
|
| 22 |
+
<button class="login-btn" @tap="handleLogin">登录</button>
|
| 23 |
+
|
| 24 |
+
<view class="other-login">
|
| 25 |
+
<view class="line"></view>
|
| 26 |
+
<view class="text">其他登录方式</view>
|
| 27 |
+
<view class="line"></view>
|
| 28 |
+
</view>
|
| 29 |
+
|
| 30 |
+
<view class="quick-login">
|
| 31 |
+
<!-- #ifdef MP-WEIXIN -->
|
| 32 |
+
<button class="icon-btn weixin" open-type="getPhoneNumber" @getphonenumber="handleWxLogin">
|
| 33 |
+
<uni-icons type="weixin" size="30" color="#fff"></uni-icons>
|
| 34 |
+
</button>
|
| 35 |
+
<!-- #endif -->
|
| 36 |
+
<button class="icon-btn" @tap="handleQuickLogin">
|
| 37 |
+
<uni-icons type="qq" size="30" color="#fff"></uni-icons>
|
| 38 |
+
</button>
|
| 39 |
+
</view>
|
| 40 |
+
|
| 41 |
+
<view class="agreement">
|
| 42 |
+
登录即代表您已同意 <text class="link">《用户协议》</text> 和 <text class="link">《隐私政策》</text>
|
| 43 |
+
</view>
|
| 44 |
+
</view>
|
| 45 |
+
</view>
|
| 46 |
+
</template>
|
| 47 |
+
|
| 48 |
+
<script setup lang="ts">
|
| 49 |
+
import { ref } from 'vue'
|
| 50 |
+
|
| 51 |
+
const phone = ref('')
|
| 52 |
+
const code = ref('')
|
| 53 |
+
const countdown = ref(0)
|
| 54 |
+
|
| 55 |
+
const getCode = () => {
|
| 56 |
+
if (countdown.value > 0) return
|
| 57 |
+
if (!/^1[3-9]\d{9}$/.test(phone.value)) {
|
| 58 |
+
uni.showToast({ title: '请输入正确的手机号', icon: 'none' })
|
| 59 |
+
return
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
uni.showToast({ title: '验证码已发送', icon: 'success' })
|
| 63 |
+
countdown.value = 60
|
| 64 |
+
const timer = setInterval(() => {
|
| 65 |
+
countdown.value--
|
| 66 |
+
if (countdown.value <= 0) {
|
| 67 |
+
clearInterval(timer)
|
| 68 |
+
}
|
| 69 |
+
}, 1000)
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
const handleLogin = () => {
|
| 73 |
+
if (!phone.value || !code.value) {
|
| 74 |
+
uni.showToast({ title: '请填写完整信息', icon: 'none' })
|
| 75 |
+
return
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
uni.showLoading({ title: '登录中...' })
|
| 79 |
+
setTimeout(() => {
|
| 80 |
+
uni.hideLoading()
|
| 81 |
+
uni.showToast({ title: '登录成功', icon: 'success' })
|
| 82 |
+
setTimeout(() => {
|
| 83 |
+
uni.switchTab({ url: '/pages/index/index' })
|
| 84 |
+
}, 1500)
|
| 85 |
+
}, 1000)
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
const handleWxLogin = (e: any) => {
|
| 89 |
+
console.log('微信登录详情:', e)
|
| 90 |
+
uni.showToast({ title: '微信授权成功', icon: 'success' })
|
| 91 |
+
setTimeout(() => {
|
| 92 |
+
uni.switchTab({ url: '/pages/index/index' })
|
| 93 |
+
}, 1500)
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
const handleQuickLogin = () => {
|
| 97 |
+
uni.showToast({ title: '第三方登录成功', icon: 'success' })
|
| 98 |
+
setTimeout(() => {
|
| 99 |
+
uni.switchTab({ url: '/pages/index/index' })
|
| 100 |
+
}, 1500)
|
| 101 |
+
}
|
| 102 |
+
</script>
|
| 103 |
+
|
| 104 |
+
<style lang="scss">
|
| 105 |
+
.container {
|
| 106 |
+
height: 100vh;
|
| 107 |
+
display: flex;
|
| 108 |
+
justify-content: center;
|
| 109 |
+
align-items: center;
|
| 110 |
+
background-color: #fff;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
.login-box {
|
| 114 |
+
width: 80%;
|
| 115 |
+
display: flex;
|
| 116 |
+
flex-direction: column;
|
| 117 |
+
align-items: center;
|
| 118 |
+
|
| 119 |
+
.logo {
|
| 120 |
+
width: 160rpx;
|
| 121 |
+
height: 160rpx;
|
| 122 |
+
margin-bottom: 30rpx;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
.title {
|
| 126 |
+
font-size: 40rpx;
|
| 127 |
+
font-weight: bold;
|
| 128 |
+
color: #333;
|
| 129 |
+
margin-bottom: 10rpx;
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
.subtitle {
|
| 133 |
+
font-size: 26rpx;
|
| 134 |
+
color: #999;
|
| 135 |
+
margin-bottom: 60rpx;
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
.input-group {
|
| 140 |
+
width: 100%;
|
| 141 |
+
margin-bottom: 40rpx;
|
| 142 |
+
|
| 143 |
+
.input-item {
|
| 144 |
+
display: flex;
|
| 145 |
+
align-items: center;
|
| 146 |
+
border-bottom: 1rpx solid #eee;
|
| 147 |
+
height: 100rpx;
|
| 148 |
+
margin-bottom: 20rpx;
|
| 149 |
+
|
| 150 |
+
.input {
|
| 151 |
+
flex: 1;
|
| 152 |
+
margin-left: 20rpx;
|
| 153 |
+
font-size: 28rpx;
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
.get-code {
|
| 157 |
+
font-size: 26rpx;
|
| 158 |
+
color: #1890ff;
|
| 159 |
+
padding: 10rpx 20rpx;
|
| 160 |
+
|
| 161 |
+
&.disabled {
|
| 162 |
+
color: #999;
|
| 163 |
+
}
|
| 164 |
+
}
|
| 165 |
+
}
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
.login-btn {
|
| 169 |
+
width: 100%;
|
| 170 |
+
height: 90rpx;
|
| 171 |
+
line-height: 90rpx;
|
| 172 |
+
background-color: #1890ff;
|
| 173 |
+
color: #fff;
|
| 174 |
+
border-radius: 45rpx;
|
| 175 |
+
font-size: 32rpx;
|
| 176 |
+
margin-bottom: 60rpx;
|
| 177 |
+
|
| 178 |
+
&::after { border: none; }
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
.other-login {
|
| 182 |
+
display: flex;
|
| 183 |
+
align-items: center;
|
| 184 |
+
width: 100%;
|
| 185 |
+
margin-bottom: 40rpx;
|
| 186 |
+
|
| 187 |
+
.line {
|
| 188 |
+
flex: 1;
|
| 189 |
+
height: 1rpx;
|
| 190 |
+
background-color: #eee;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
.text {
|
| 194 |
+
font-size: 24rpx;
|
| 195 |
+
color: #999;
|
| 196 |
+
margin: 0 20rpx;
|
| 197 |
+
}
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
.quick-login {
|
| 201 |
+
display: flex;
|
| 202 |
+
gap: 40rpx;
|
| 203 |
+
margin-bottom: 60rpx;
|
| 204 |
+
|
| 205 |
+
.icon-btn {
|
| 206 |
+
width: 100rpx;
|
| 207 |
+
height: 100rpx;
|
| 208 |
+
border-radius: 50%;
|
| 209 |
+
background-color: #1890ff;
|
| 210 |
+
display: flex;
|
| 211 |
+
justify-content: center;
|
| 212 |
+
align-items: center;
|
| 213 |
+
padding: 0;
|
| 214 |
+
|
| 215 |
+
&.weixin { background-color: #07c160; }
|
| 216 |
+
|
| 217 |
+
&::after { border: none; }
|
| 218 |
+
}
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
.agreement {
|
| 222 |
+
font-size: 24rpx;
|
| 223 |
+
color: #999;
|
| 224 |
+
text-align: center;
|
| 225 |
+
|
| 226 |
+
.link {
|
| 227 |
+
color: #1890ff;
|
| 228 |
+
}
|
| 229 |
+
}
|
| 230 |
+
</style>
|
src/pages/profile/profile.vue
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<template>
|
| 2 |
+
<view class="container">
|
| 3 |
+
<!-- 用户信息头部 -->
|
| 4 |
+
<view class="user-header">
|
| 5 |
+
<view class="user-info">
|
| 6 |
+
<image class="avatar" src="https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=friendly+human+avatar+minimalist&image_size=square" mode="aspectFill"></image>
|
| 7 |
+
<view class="info-right">
|
| 8 |
+
<text class="nickname">微信用户</text>
|
| 9 |
+
<text class="phone">138****8888</text>
|
| 10 |
+
</view>
|
| 11 |
+
</view>
|
| 12 |
+
</view>
|
| 13 |
+
|
| 14 |
+
<!-- 数据统计栏 -->
|
| 15 |
+
<view class="stats-bar">
|
| 16 |
+
<view class="stats-item" v-for="(item, index) in stats" :key="index">
|
| 17 |
+
<text class="stats-num">{{ item.num }}</text>
|
| 18 |
+
<text class="stats-label">{{ item.label }}</text>
|
| 19 |
+
</view>
|
| 20 |
+
</view>
|
| 21 |
+
|
| 22 |
+
<!-- 功能列表 -->
|
| 23 |
+
<view class="menu-list">
|
| 24 |
+
<view class="menu-item" v-for="(item, index) in menuItems" :key="index" @tap="handleMenuClick(item)">
|
| 25 |
+
<view class="menu-left">
|
| 26 |
+
<uni-icons :type="item.icon" size="20" :color="item.color"></uni-icons>
|
| 27 |
+
<text class="menu-text">{{ item.text }}</text>
|
| 28 |
+
</view>
|
| 29 |
+
<uni-icons type="right" size="16" color="#ccc"></uni-icons>
|
| 30 |
+
</view>
|
| 31 |
+
</view>
|
| 32 |
+
|
| 33 |
+
<!-- 退出登录按钮 -->
|
| 34 |
+
<button class="logout-btn" @tap="handleLogout">退出登录</button>
|
| 35 |
+
</view>
|
| 36 |
+
</template>
|
| 37 |
+
|
| 38 |
+
<script setup lang="ts">
|
| 39 |
+
import { ref } from 'vue'
|
| 40 |
+
|
| 41 |
+
// 统计数据
|
| 42 |
+
const stats = ref([
|
| 43 |
+
{ num: '12', label: '收藏' },
|
| 44 |
+
{ num: '8', label: '足迹' },
|
| 45 |
+
{ num: '3', label: '优惠券' },
|
| 46 |
+
{ num: '100', label: '积分' }
|
| 47 |
+
])
|
| 48 |
+
|
| 49 |
+
// 菜单项
|
| 50 |
+
const menuItems = ref([
|
| 51 |
+
{ text: '我的订单', icon: 'list', color: '#1890ff' },
|
| 52 |
+
{ text: '收货地址', icon: 'location', color: '#52c41a' },
|
| 53 |
+
{ text: '我的收藏', icon: 'heart', color: '#f5222d' },
|
| 54 |
+
{ text: '意见反馈', icon: 'email', color: '#faad14' },
|
| 55 |
+
{ text: '关于我们', icon: 'info', color: '#722ed1' }
|
| 56 |
+
])
|
| 57 |
+
|
| 58 |
+
// 菜单点击
|
| 59 |
+
const handleMenuClick = (item: any) => {
|
| 60 |
+
uni.showToast({
|
| 61 |
+
title: `点击了${item.text}`,
|
| 62 |
+
icon: 'none'
|
| 63 |
+
})
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
// 退出登录
|
| 67 |
+
const handleLogout = () => {
|
| 68 |
+
uni.showModal({
|
| 69 |
+
title: '提示',
|
| 70 |
+
content: '确定要退出登录吗?',
|
| 71 |
+
success: (res) => {
|
| 72 |
+
if (res.confirm) {
|
| 73 |
+
uni.reLaunch({ url: '/pages/login/login' })
|
| 74 |
+
}
|
| 75 |
+
}
|
| 76 |
+
})
|
| 77 |
+
}
|
| 78 |
+
</script>
|
| 79 |
+
|
| 80 |
+
<style lang="scss">
|
| 81 |
+
.container {
|
| 82 |
+
background-color: #f8f8f8;
|
| 83 |
+
min-height: 100vh;
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
.user-header {
|
| 87 |
+
background: linear-gradient(to bottom, #1890ff, #40a9ff);
|
| 88 |
+
padding: 60rpx 40rpx 100rpx;
|
| 89 |
+
|
| 90 |
+
.user-info {
|
| 91 |
+
display: flex;
|
| 92 |
+
align-items: center;
|
| 93 |
+
|
| 94 |
+
.avatar {
|
| 95 |
+
width: 120rpx;
|
| 96 |
+
height: 120rpx;
|
| 97 |
+
border-radius: 50%;
|
| 98 |
+
border: 4rpx solid rgba(255,255,255,0.8);
|
| 99 |
+
margin-right: 30rpx;
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
.info-right {
|
| 103 |
+
display: flex;
|
| 104 |
+
flex-direction: column;
|
| 105 |
+
|
| 106 |
+
.nickname {
|
| 107 |
+
font-size: 36rpx;
|
| 108 |
+
font-weight: bold;
|
| 109 |
+
color: #fff;
|
| 110 |
+
margin-bottom: 10rpx;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
.phone {
|
| 114 |
+
font-size: 24rpx;
|
| 115 |
+
color: rgba(255,255,255,0.8);
|
| 116 |
+
}
|
| 117 |
+
}
|
| 118 |
+
}
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
.stats-bar {
|
| 122 |
+
display: flex;
|
| 123 |
+
background-color: #fff;
|
| 124 |
+
margin: -40rpx 30rpx 20rpx;
|
| 125 |
+
border-radius: 16rpx;
|
| 126 |
+
padding: 30rpx 0;
|
| 127 |
+
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.05);
|
| 128 |
+
|
| 129 |
+
.stats-item {
|
| 130 |
+
flex: 1;
|
| 131 |
+
display: flex;
|
| 132 |
+
flex-direction: column;
|
| 133 |
+
align-items: center;
|
| 134 |
+
border-right: 1rpx solid #f0f0f0;
|
| 135 |
+
|
| 136 |
+
&:last-child {
|
| 137 |
+
border-right: none;
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
.stats-num {
|
| 141 |
+
font-size: 32rpx;
|
| 142 |
+
font-weight: bold;
|
| 143 |
+
color: #333;
|
| 144 |
+
margin-bottom: 8rpx;
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
.stats-label {
|
| 148 |
+
font-size: 24rpx;
|
| 149 |
+
color: #999;
|
| 150 |
+
}
|
| 151 |
+
}
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
.menu-list {
|
| 155 |
+
background-color: #fff;
|
| 156 |
+
margin: 0 30rpx 40rpx;
|
| 157 |
+
border-radius: 16rpx;
|
| 158 |
+
padding: 0 30rpx;
|
| 159 |
+
|
| 160 |
+
.menu-item {
|
| 161 |
+
display: flex;
|
| 162 |
+
justify-content: space-between;
|
| 163 |
+
align-items: center;
|
| 164 |
+
height: 100rpx;
|
| 165 |
+
border-bottom: 1rpx solid #f5f5f5;
|
| 166 |
+
|
| 167 |
+
&:last-child {
|
| 168 |
+
border-bottom: none;
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
.menu-left {
|
| 172 |
+
display: flex;
|
| 173 |
+
align-items: center;
|
| 174 |
+
|
| 175 |
+
.menu-text {
|
| 176 |
+
font-size: 28rpx;
|
| 177 |
+
color: #333;
|
| 178 |
+
margin-left: 20rpx;
|
| 179 |
+
}
|
| 180 |
+
}
|
| 181 |
+
}
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
.logout-btn {
|
| 185 |
+
margin: 0 30rpx;
|
| 186 |
+
background-color: #fff;
|
| 187 |
+
color: #f5222d;
|
| 188 |
+
font-size: 30rpx;
|
| 189 |
+
border-radius: 16rpx;
|
| 190 |
+
height: 90rpx;
|
| 191 |
+
line-height: 90rpx;
|
| 192 |
+
border: none;
|
| 193 |
+
|
| 194 |
+
&::after {
|
| 195 |
+
border: none;
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
</style>
|
src/shime-uni.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export {}
|
| 2 |
+
|
| 3 |
+
declare module "vue" {
|
| 4 |
+
type Hooks = App.AppInstance & Page.PageInstance;
|
| 5 |
+
interface ComponentCustomOptions extends Hooks {}
|
| 6 |
+
}
|
src/static/logo.png
ADDED
|
src/uni.scss
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* 这里是uni-app内置的常用样式变量
|
| 3 |
+
*
|
| 4 |
+
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
|
| 5 |
+
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
|
| 6 |
+
*
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
|
| 11 |
+
*
|
| 12 |
+
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
|
| 13 |
+
*/
|
| 14 |
+
|
| 15 |
+
/* 颜色变量 */
|
| 16 |
+
|
| 17 |
+
/* 行为相关颜色 */
|
| 18 |
+
$uni-color-primary: #007aff;
|
| 19 |
+
$uni-color-success: #4cd964;
|
| 20 |
+
$uni-color-warning: #f0ad4e;
|
| 21 |
+
$uni-color-error: #dd524d;
|
| 22 |
+
|
| 23 |
+
/* 文字基本颜色 */
|
| 24 |
+
$uni-text-color: #333; // 基本色
|
| 25 |
+
$uni-text-color-inverse: #fff; // 反色
|
| 26 |
+
$uni-text-color-grey: #999; // 辅助灰色,如加载更多的提示信息
|
| 27 |
+
$uni-text-color-placeholder: #808080;
|
| 28 |
+
$uni-text-color-disable: #c0c0c0;
|
| 29 |
+
|
| 30 |
+
/* 背景颜色 */
|
| 31 |
+
$uni-bg-color: #fff;
|
| 32 |
+
$uni-bg-color-grey: #f8f8f8;
|
| 33 |
+
$uni-bg-color-hover: #f1f1f1; // 点击状态颜色
|
| 34 |
+
$uni-bg-color-mask: rgba(0, 0, 0, 0.4); // 遮罩颜色
|
| 35 |
+
|
| 36 |
+
/* 边框颜色 */
|
| 37 |
+
$uni-border-color: #c8c7cc;
|
| 38 |
+
|
| 39 |
+
/* 尺寸变量 */
|
| 40 |
+
|
| 41 |
+
/* 文字尺寸 */
|
| 42 |
+
$uni-font-size-sm: 12px;
|
| 43 |
+
$uni-font-size-base: 14px;
|
| 44 |
+
$uni-font-size-lg: 16;
|
| 45 |
+
|
| 46 |
+
/* 图片尺寸 */
|
| 47 |
+
$uni-img-size-sm: 20px;
|
| 48 |
+
$uni-img-size-base: 26px;
|
| 49 |
+
$uni-img-size-lg: 40px;
|
| 50 |
+
|
| 51 |
+
/* Border Radius */
|
| 52 |
+
$uni-border-radius-sm: 2px;
|
| 53 |
+
$uni-border-radius-base: 3px;
|
| 54 |
+
$uni-border-radius-lg: 6px;
|
| 55 |
+
$uni-border-radius-circle: 50%;
|
| 56 |
+
|
| 57 |
+
/* 水平间距 */
|
| 58 |
+
$uni-spacing-row-sm: 5px;
|
| 59 |
+
$uni-spacing-row-base: 10px;
|
| 60 |
+
$uni-spacing-row-lg: 15px;
|
| 61 |
+
|
| 62 |
+
/* 垂直间距 */
|
| 63 |
+
$uni-spacing-col-sm: 4px;
|
| 64 |
+
$uni-spacing-col-base: 8px;
|
| 65 |
+
$uni-spacing-col-lg: 12px;
|
| 66 |
+
|
| 67 |
+
/* 透明度 */
|
| 68 |
+
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
|
| 69 |
+
|
| 70 |
+
/* 文章场景相关 */
|
| 71 |
+
$uni-color-title: #2c405a; // 文章标题颜色
|
| 72 |
+
$uni-font-size-title: 20px;
|
| 73 |
+
$uni-color-subtitle: #555; // 二级标题颜色
|
| 74 |
+
$uni-font-size-subtitle: 18px;
|
| 75 |
+
$uni-color-paragraph: #3f536e; // 文章段落颜色
|
| 76 |
+
$uni-font-size-paragraph: 15px;
|
tsconfig.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"extends": "@vue/tsconfig/tsconfig.json",
|
| 3 |
+
"compilerOptions": {
|
| 4 |
+
"sourceMap": true,
|
| 5 |
+
"baseUrl": ".",
|
| 6 |
+
"paths": {
|
| 7 |
+
"@/*": ["./src/*"]
|
| 8 |
+
},
|
| 9 |
+
"lib": ["esnext", "dom"],
|
| 10 |
+
"types": ["@dcloudio/types"]
|
| 11 |
+
},
|
| 12 |
+
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
|
| 13 |
+
}
|
vite.config.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { defineConfig } from "vite";
|
| 2 |
+
import uni from "@dcloudio/vite-plugin-uni";
|
| 3 |
+
|
| 4 |
+
// https://vitejs.dev/config/
|
| 5 |
+
export default defineConfig({
|
| 6 |
+
plugins: [uni()],
|
| 7 |
+
});
|