创建uniapp基础形态
This commit is contained in:
+19
-6
@@ -1,18 +1,31 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
onLaunch: function() {
|
onLaunch() {
|
||||||
console.log('App Launch')
|
console.log('App Launch')
|
||||||
},
|
},
|
||||||
onShow: function() {
|
onShow() {
|
||||||
console.log('App Show')
|
console.log('App Show')
|
||||||
},
|
},
|
||||||
onHide: function() {
|
onHide() {
|
||||||
console.log('App Hide')
|
console.log('App Hide')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style lang="scss">
|
||||||
/*每个页面公共css */
|
@import 'uview-plus/index.scss';
|
||||||
@import './src/uni.scss';
|
@import './src/styles/theme.scss';
|
||||||
|
@import './src/styles/fontawesome.scss';
|
||||||
|
|
||||||
|
page {
|
||||||
|
height: 100%;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
|
||||||
|
background-color: #f8fafc;
|
||||||
|
color: #1e293b;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
view, text {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -0,0 +1,179 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view class="app-tabbar">
|
||||||
|
|
||||||
|
<view class="tabbar-pill">
|
||||||
|
|
||||||
|
<view
|
||||||
|
|
||||||
|
v-for="tab in tabs"
|
||||||
|
|
||||||
|
:key="tab.name"
|
||||||
|
|
||||||
|
class="tab-item"
|
||||||
|
|
||||||
|
:class="{ active: current === tab.name }"
|
||||||
|
|
||||||
|
@tap="onChange(tab.name)"
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
<FaIcon
|
||||||
|
|
||||||
|
:name="tab.icon"
|
||||||
|
|
||||||
|
:color="current === tab.name ? '#3c9cff' : '#9acafc'"
|
||||||
|
|
||||||
|
:size="20"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<text class="tab-text">{{ tab.text }}</text>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="safe-area" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
|
||||||
|
current: {
|
||||||
|
|
||||||
|
type: String,
|
||||||
|
|
||||||
|
default: 'dashboard'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const tabs = [
|
||||||
|
|
||||||
|
{ name: 'dashboard', text: '仪表盘', icon: 'table-cells' },
|
||||||
|
|
||||||
|
{ name: 'features', text: '功能', icon: 'grip' },
|
||||||
|
|
||||||
|
{ name: 'profile', text: '我的', icon: 'user' }
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const routes = {
|
||||||
|
|
||||||
|
dashboard: '/pages/dashboard/dashboard',
|
||||||
|
|
||||||
|
features: '/pages/features/features',
|
||||||
|
|
||||||
|
profile: '/pages/profile/profile'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function onChange(name) {
|
||||||
|
|
||||||
|
if (name === props.current) return
|
||||||
|
|
||||||
|
uni.redirectTo({ url: routes[name] })
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.app-tabbar {
|
||||||
|
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
padding: 16rpx 32rpx 0;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.tabbar-pill {
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
justify-content: space-around;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
|
||||||
|
border-radius: 999rpx;
|
||||||
|
|
||||||
|
padding: 16rpx 12rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
gap: 6rpx;
|
||||||
|
|
||||||
|
padding: 8rpx 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.tab-text {
|
||||||
|
|
||||||
|
font-size: 22rpx;
|
||||||
|
|
||||||
|
color: #9acafc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.tab-item.active .tab-text {
|
||||||
|
|
||||||
|
color: #3c9cff;
|
||||||
|
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.safe-area {
|
||||||
|
|
||||||
|
height: constant(safe-area-inset-bottom);
|
||||||
|
|
||||||
|
height: env(safe-area-inset-bottom);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<template>
|
||||||
|
<text class="fa-icon" :class="fontClass" :style="iconStyle">{{ iconChar }}</text>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { FA_ICONS } from '@/utils/fa-icons.js'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'solid'
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: 'inherit'
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 16
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const iconChar = computed(() => FA_ICONS[props.name] || '')
|
||||||
|
|
||||||
|
const fontClass = computed(() =>
|
||||||
|
props.type === 'brands' ? 'fa-font-brands' : 'fa-font-solid'
|
||||||
|
)
|
||||||
|
|
||||||
|
const iconStyle = computed(() => ({
|
||||||
|
color: props.color,
|
||||||
|
fontSize: typeof props.size === 'number' ? `${props.size}px` : props.size,
|
||||||
|
lineHeight: 1
|
||||||
|
}))
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.fa-icon {
|
||||||
|
display: inline-block;
|
||||||
|
font-style: normal;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.fa-font-solid {
|
||||||
|
font-family: 'Font Awesome 7 Free';
|
||||||
|
font-weight: 900;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-font-brands {
|
||||||
|
font-family: 'Font Awesome 7 Brands';
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import App from './App'
|
import App from './App'
|
||||||
import uviewPlus from 'uview-plus'
|
import uviewPlus from 'uview-plus'
|
||||||
|
import FaIcon from '@/components/FaIcon.vue'
|
||||||
|
|
||||||
// #ifndef VUE3
|
// #ifndef VUE3
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
@@ -19,6 +20,7 @@ import {
|
|||||||
export function createApp() {
|
export function createApp() {
|
||||||
const app = createSSRApp(App)
|
const app = createSSRApp(App)
|
||||||
app.use(uviewPlus)
|
app.use(uviewPlus)
|
||||||
|
app.component('FaIcon', FaIcon)
|
||||||
return {
|
return {
|
||||||
app
|
app
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+413
-1
@@ -5,15 +5,26 @@
|
|||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fortawesome/fontawesome-free": "^7.3.0",
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
"dayjs": "^1.11.21",
|
"dayjs": "^1.11.21",
|
||||||
"uview-plus": "^3.8.55"
|
"uview-plus": "^3.8.55"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"rollup-plugin-visualizer": "^7.0.1",
|
||||||
"sass": "^1.63.2",
|
"sass": "^1.63.2",
|
||||||
"sass-loader": "^10.4.1"
|
"sass-loader": "^10.4.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@fortawesome/fontawesome-free": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@fortawesome/fontawesome-free/-/fontawesome-free-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-Yw4Qa43P6e4Xwh0TwEUkHQNRJInWaqIBo73VJmns3j2AIlZPAvUcR4yGIxCPqPRCgyJ5KIVIalF/I1GxhZ/Kgw==",
|
||||||
|
"license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@jridgewell/gen-mapping": {
|
"node_modules/@jridgewell/gen-mapping": {
|
||||||
"version": "0.3.13",
|
"version": "0.3.13",
|
||||||
"resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
"resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||||
@@ -387,6 +398,32 @@
|
|||||||
"ajv": "^6.9.1"
|
"ajv": "^6.9.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ansi-regex": {
|
||||||
|
"version": "6.2.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.2.tgz",
|
||||||
|
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ansi-styles": {
|
||||||
|
"version": "6.2.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.3.tgz",
|
||||||
|
"integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/anymatch": {
|
"node_modules/anymatch": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
|
"resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
|
||||||
@@ -494,6 +531,22 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/bundle-name": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"run-applescript": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001805",
|
"version": "1.0.30001805",
|
||||||
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001805.tgz",
|
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001805.tgz",
|
||||||
@@ -563,6 +616,21 @@
|
|||||||
"tiny-emitter": "^2.0.0"
|
"tiny-emitter": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cliui": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"string-width": "^7.2.0",
|
||||||
|
"strip-ansi": "^7.1.0",
|
||||||
|
"wrap-ansi": "^9.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/commander": {
|
"node_modules/commander": {
|
||||||
"version": "2.20.3",
|
"version": "2.20.3",
|
||||||
"resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
|
"resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
|
||||||
@@ -577,6 +645,49 @@
|
|||||||
"integrity": "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==",
|
"integrity": "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/default-browser": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/default-browser/-/default-browser-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bundle-name": "^4.1.0",
|
||||||
|
"default-browser-id": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/default-browser-id": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/default-browser-id/-/default-browser-id-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/define-lazy-prop": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/delegate": {
|
"node_modules/delegate": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz",
|
"resolved": "https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz",
|
||||||
@@ -591,6 +702,13 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/emoji-regex": {
|
||||||
|
"version": "10.6.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-10.6.0.tgz",
|
||||||
|
"integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/emojis-list": {
|
"node_modules/emojis-list": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/emojis-list/-/emojis-list-3.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/emojis-list/-/emojis-list-3.0.0.tgz",
|
||||||
@@ -630,7 +748,6 @@
|
|||||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
@@ -757,6 +874,29 @@
|
|||||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/get-caller-file": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": "6.* || 8.* || >= 10.*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-east-asian-width": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/glob-parent": {
|
"node_modules/glob-parent": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz",
|
"resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||||
@@ -818,6 +958,22 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-docker": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"is-docker": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-extglob": {
|
"node_modules/is-extglob": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
|
"resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
@@ -841,6 +997,38 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-in-ssh": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/is-in-ssh/-/is-in-ssh-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-inside-container": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/is-inside-container/-/is-inside-container-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-docker": "^3.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"is-inside-container": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-number": {
|
"node_modules/is-number": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
|
||||||
@@ -851,6 +1039,22 @@
|
|||||||
"node": ">=0.12.0"
|
"node": ">=0.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-wsl": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-inside-container": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/jest-worker": {
|
"node_modules/jest-worker": {
|
||||||
"version": "27.5.1",
|
"version": "27.5.1",
|
||||||
"resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz",
|
"resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz",
|
||||||
@@ -1097,6 +1301,27 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/open": {
|
||||||
|
"version": "11.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/open/-/open-11.0.0.tgz",
|
||||||
|
"integrity": "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"default-browser": "^5.4.0",
|
||||||
|
"define-lazy-prop": "^3.0.0",
|
||||||
|
"is-in-ssh": "^1.0.0",
|
||||||
|
"is-inside-container": "^1.0.0",
|
||||||
|
"powershell-utils": "^0.1.0",
|
||||||
|
"wsl-utils": "^0.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
|
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
@@ -1118,6 +1343,19 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/powershell-utils": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/powershell-utils/-/powershell-utils-0.1.0.tgz",
|
||||||
|
"integrity": "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/punycode": {
|
"node_modules/punycode": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
|
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
|
||||||
@@ -1152,6 +1390,73 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/rollup-plugin-visualizer": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/rollup-plugin-visualizer/-/rollup-plugin-visualizer-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-UJUT4+1Ho4OcWmPYU3sYXgUqI8B8Ayfe06MX7y0qCJ1K8aGoKtR/NDd/2nZqM7ADkrzny+I99Ul7GgyoiVNAgg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"open": "^11.0.0",
|
||||||
|
"picomatch": "^4.0.2",
|
||||||
|
"source-map": "^0.7.4",
|
||||||
|
"yargs": "^18.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"rollup-plugin-visualizer": "dist/bin/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=22"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"rolldown": "1.x || ^1.0.0-beta || ^1.0.0-rc",
|
||||||
|
"rollup": "2.x || 3.x || 4.x"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"rolldown": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"rollup": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/rollup-plugin-visualizer/node_modules/picomatch": {
|
||||||
|
"version": "4.0.5",
|
||||||
|
"resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.5.tgz",
|
||||||
|
"integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/rollup-plugin-visualizer/node_modules/source-map": {
|
||||||
|
"version": "0.7.6",
|
||||||
|
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.7.6.tgz",
|
||||||
|
"integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/run-applescript": {
|
||||||
|
"version": "7.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/run-applescript/-/run-applescript-7.1.0.tgz",
|
||||||
|
"integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/sass": {
|
"node_modules/sass": {
|
||||||
"version": "1.63.2",
|
"version": "1.63.2",
|
||||||
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.63.2.tgz",
|
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.63.2.tgz",
|
||||||
@@ -1279,6 +1584,40 @@
|
|||||||
"source-map": "^0.6.0"
|
"source-map": "^0.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/string-width": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"emoji-regex": "^10.3.0",
|
||||||
|
"get-east-asian-width": "^1.0.0",
|
||||||
|
"strip-ansi": "^7.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/strip-ansi": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": "^6.2.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/supports-color": {
|
"node_modules/supports-color": {
|
||||||
"version": "8.1.1",
|
"version": "8.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz",
|
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz",
|
||||||
@@ -1542,6 +1881,79 @@
|
|||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/webpack"
|
"url": "https://opencollective.com/webpack"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wrap-ansi": {
|
||||||
|
"version": "9.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
|
||||||
|
"integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^6.2.1",
|
||||||
|
"string-width": "^7.0.0",
|
||||||
|
"strip-ansi": "^7.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wsl-utils": {
|
||||||
|
"version": "0.3.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/wsl-utils/-/wsl-utils-0.3.1.tgz",
|
||||||
|
"integrity": "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-wsl": "^3.1.0",
|
||||||
|
"powershell-utils": "^0.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/y18n": {
|
||||||
|
"version": "5.0.8",
|
||||||
|
"resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz",
|
||||||
|
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yargs": {
|
||||||
|
"version": "18.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/yargs/-/yargs-18.0.0.tgz",
|
||||||
|
"integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"cliui": "^9.0.1",
|
||||||
|
"escalade": "^3.1.1",
|
||||||
|
"get-caller-file": "^2.0.5",
|
||||||
|
"string-width": "^7.2.0",
|
||||||
|
"y18n": "^5.0.5",
|
||||||
|
"yargs-parser": "^22.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || ^22.12.0 || >=23"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yargs-parser": {
|
||||||
|
"version": "22.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-22.0.0.tgz",
|
||||||
|
"integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || ^22.12.0 || >=23"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fortawesome/fontawesome-free": "^7.3.0",
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
"dayjs": "^1.11.21",
|
"dayjs": "^1.11.21",
|
||||||
"uview-plus": "^3.8.55"
|
"uview-plus": "^3.8.55"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"rollup-plugin-visualizer": "^7.0.1",
|
||||||
"sass": "^1.63.2",
|
"sass": "^1.63.2",
|
||||||
"sass-loader": "^10.4.1"
|
"sass-loader": "^10.4.1"
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-7
@@ -1,26 +1,48 @@
|
|||||||
{
|
{
|
||||||
"easycom": {
|
"easycom": {
|
||||||
"autoscan": true,
|
"autoscan": true,
|
||||||
// 注意一定要放在custom里,否则无效,https://ask.dcloud.net.cn/question/131175
|
|
||||||
"custom": {
|
"custom": {
|
||||||
|
"^FaIcon$": "@/components/FaIcon.vue",
|
||||||
"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
||||||
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
||||||
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue"
|
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
"pages": [
|
||||||
{
|
{
|
||||||
"path": "pages/index/index",
|
"path": "pages/login/login",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "uni-app"
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "登录"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/dashboard/dashboard",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "仪表盘"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/features/features",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "功能"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/profile/profile",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "我的"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
"navigationBarTextStyle": "black",
|
"navigationBarTextStyle": "black",
|
||||||
"navigationBarTitleText": "uni-app",
|
"navigationBarTitleText": "云泽",
|
||||||
"navigationBarBackgroundColor": "#F8F8F8",
|
"navigationBarBackgroundColor": "#F8FAFC",
|
||||||
"backgroundColor": "#F8F8F8"
|
"backgroundColor": "#F8FAFC"
|
||||||
},
|
},
|
||||||
"uniIdRouter": {}
|
"uniIdRouter": {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,342 @@
|
|||||||
|
<template>
|
||||||
|
<view class="page">
|
||||||
|
<view class="header">
|
||||||
|
<view class="header-row">
|
||||||
|
<view class="user-info">
|
||||||
|
<text class="greeting">{{ greeting }}</text>
|
||||||
|
<text class="username">{{ user?.nickname || '云泽用户' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="avatar">
|
||||||
|
<text class="avatar-text">{{ avatarText }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="search-bar">
|
||||||
|
<FaIcon name="magnifying-glass" color="#9acafc" :size="18" />
|
||||||
|
<text class="search-text">搜索功能、数据...</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="main-scroll">
|
||||||
|
<view class="stats-grid">
|
||||||
|
<view class="stat-card" v-for="item in stats" :key="item.label">
|
||||||
|
<text class="stat-value">{{ item.value }}</text>
|
||||||
|
<text class="stat-label">{{ item.label }}</text>
|
||||||
|
<text class="stat-trend" :class="item.up ? 'up' : 'down'">
|
||||||
|
{{ item.up ? '↑' : '↓' }} {{ item.trend }}
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="section">
|
||||||
|
<text class="section-title">快捷入口</text>
|
||||||
|
<view class="quick-grid">
|
||||||
|
<view
|
||||||
|
class="quick-item"
|
||||||
|
v-for="item in quickActions"
|
||||||
|
:key="item.name"
|
||||||
|
@tap="onQuickTap(item)"
|
||||||
|
>
|
||||||
|
<view class="quick-icon">
|
||||||
|
<FaIcon :name="item.icon" color="#3c9cff" :size="22" />
|
||||||
|
</view>
|
||||||
|
<text class="quick-name">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-header">
|
||||||
|
<text class="section-title">最近动态</text>
|
||||||
|
<text class="section-more">查看全部</text>
|
||||||
|
</view>
|
||||||
|
<view class="activity-card">
|
||||||
|
<view class="activity-item" v-for="(item, index) in activities" :key="index">
|
||||||
|
<view class="activity-dot" />
|
||||||
|
<view class="activity-body">
|
||||||
|
<text class="activity-title">{{ item.title }}</text>
|
||||||
|
<text class="activity-time">{{ item.time }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="bottom-space" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<AppTabbar current="dashboard" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed, onMounted } from 'vue'
|
||||||
|
import { getUser, isLoggedIn } from '@/utils/auth.js'
|
||||||
|
import AppTabbar from '@/components/AppTabbar.vue'
|
||||||
|
|
||||||
|
const user = ref(null)
|
||||||
|
|
||||||
|
const greeting = computed(() => {
|
||||||
|
const hour = new Date().getHours()
|
||||||
|
if (hour < 12) return '早上好'
|
||||||
|
if (hour < 18) return '下午好'
|
||||||
|
return '晚上好'
|
||||||
|
})
|
||||||
|
|
||||||
|
const avatarText = computed(() => {
|
||||||
|
const name = user.value?.nickname || '云'
|
||||||
|
return name.charAt(0).toUpperCase()
|
||||||
|
})
|
||||||
|
|
||||||
|
const stats = ref([
|
||||||
|
{ label: '今日访问', value: '2,847', trend: '12%', up: true },
|
||||||
|
{ label: '活跃用户', value: '1,256', trend: '8%', up: true },
|
||||||
|
{ label: '转化率', value: '68.5%', trend: '3%', up: false },
|
||||||
|
{ label: '总收入', value: '¥8.2k', trend: '15%', up: true }
|
||||||
|
])
|
||||||
|
|
||||||
|
const quickActions = ref([
|
||||||
|
{ name: '数据分析', icon: 'chart-line' },
|
||||||
|
{ name: '消息中心', icon: 'bell' },
|
||||||
|
{ name: '订单管理', icon: 'clipboard-list' },
|
||||||
|
{ name: '设置', icon: 'gear' }
|
||||||
|
])
|
||||||
|
|
||||||
|
const activities = ref([
|
||||||
|
{ title: '新用户注册 +128', time: '5 分钟前' },
|
||||||
|
{ title: '系统更新完成 v2.1', time: '1 小时前' },
|
||||||
|
{ title: '订单 #8821 已发货', time: '2 小时前' },
|
||||||
|
{ title: '数据备份成功', time: '昨天 23:00' }
|
||||||
|
])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
uni.reLaunch({ url: '/pages/login/login' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user.value = getUser()
|
||||||
|
})
|
||||||
|
|
||||||
|
function onQuickTap(item) {
|
||||||
|
uni.showToast({ title: item.name, icon: 'none' })
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page {
|
||||||
|
height: 100vh;
|
||||||
|
background: #ffffff;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: calc(var(--status-bar-height, 44px) + 24rpx) 40rpx 32rpx;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.greeting {
|
||||||
|
display: block;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
display: block;
|
||||||
|
font-size: 40rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: $u-primary;
|
||||||
|
margin-top: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-text {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: $u-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16rpx;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 22rpx 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-scroll {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow-y: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
padding: 8rpx 40rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 20rpx;
|
||||||
|
margin-bottom: 48rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
background: #ffffff;
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
display: block;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: $u-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
display: block;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
margin-top: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-trend {
|
||||||
|
display: block;
|
||||||
|
margin-top: 12rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
|
||||||
|
&.up {
|
||||||
|
color: $u-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.down {
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-bottom: 48rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: $u-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-more {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-icon {
|
||||||
|
width: 96rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
border-color: $u-primary-disabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-name {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-card {
|
||||||
|
background: #ffffff;
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 28rpx;
|
||||||
|
gap: 20rpx;
|
||||||
|
|
||||||
|
& + & {
|
||||||
|
border-top: 2rpx solid #f0f6fb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-dot {
|
||||||
|
width: 12rpx;
|
||||||
|
height: 12rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: $u-primary;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-body {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-title {
|
||||||
|
display: block;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: $u-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-time {
|
||||||
|
display: block;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
margin-top: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-space {
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,451 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view class="page">
|
||||||
|
|
||||||
|
<view class="page-header">
|
||||||
|
|
||||||
|
<text class="page-title">功能中心</text>
|
||||||
|
|
||||||
|
<text class="page-desc">探索更多精彩功能</text>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<view class="main-scroll">
|
||||||
|
|
||||||
|
<view class="feature-banner" @tap="onBannerTap">
|
||||||
|
|
||||||
|
<view class="banner-content">
|
||||||
|
|
||||||
|
<text class="banner-title">新功能上线</text>
|
||||||
|
|
||||||
|
<text class="banner-desc">AI 智能助手,效率翻倍</text>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="banner-btn">立即体验</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<view class="category" v-for="cat in categories" :key="cat.title">
|
||||||
|
|
||||||
|
<text class="category-title">{{ cat.title }}</text>
|
||||||
|
|
||||||
|
<view class="feature-grid">
|
||||||
|
|
||||||
|
<view
|
||||||
|
|
||||||
|
class="feature-card"
|
||||||
|
|
||||||
|
v-for="item in cat.items"
|
||||||
|
|
||||||
|
:key="item.name"
|
||||||
|
|
||||||
|
@tap="onFeatureTap(item)"
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
<view class="feature-icon">
|
||||||
|
|
||||||
|
<FaIcon :name="item.icon" color="#3c9cff" :size="22" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<text class="feature-name">{{ item.name }}</text>
|
||||||
|
|
||||||
|
<text class="feature-desc">{{ item.desc }}</text>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<view class="bottom-space" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<AppTabbar current="features" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
|
||||||
|
import { isLoggedIn } from '@/utils/auth.js'
|
||||||
|
|
||||||
|
import AppTabbar from '@/components/AppTabbar.vue'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const categories = ref([
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
title: '常用工具',
|
||||||
|
|
||||||
|
items: [
|
||||||
|
|
||||||
|
{ name: '扫一扫', desc: '快速识别', icon: 'qrcode' },
|
||||||
|
|
||||||
|
{ name: '收付款', desc: '便捷支付', icon: 'coins' },
|
||||||
|
|
||||||
|
{ name: '卡包', desc: '优惠券', icon: 'ticket' },
|
||||||
|
|
||||||
|
{ name: '出行', desc: '交通服务', icon: 'car' }
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
title: '生活服务',
|
||||||
|
|
||||||
|
items: [
|
||||||
|
|
||||||
|
{ name: '外卖', desc: '美食到家', icon: 'bag-shopping' },
|
||||||
|
|
||||||
|
{ name: '电影', desc: '在线购票', icon: 'film' },
|
||||||
|
|
||||||
|
{ name: '酒店', desc: '预订住宿', icon: 'hotel' },
|
||||||
|
|
||||||
|
{ name: '更多', desc: '发现更多', icon: 'ellipsis' }
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
title: '办公效率',
|
||||||
|
|
||||||
|
items: [
|
||||||
|
|
||||||
|
{ name: '文档', desc: '在线协作', icon: 'file-lines' },
|
||||||
|
|
||||||
|
{ name: '日历', desc: '日程管理', icon: 'calendar-days' },
|
||||||
|
|
||||||
|
{ name: '云盘', desc: '文件存储', icon: 'folder' },
|
||||||
|
|
||||||
|
{ name: '会议', desc: '视频会议', icon: 'video' }
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
|
||||||
|
uni.reLaunch({ url: '/pages/login/login' })
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function onBannerTap() {
|
||||||
|
|
||||||
|
uni.showToast({ title: 'AI 智能助手', icon: 'none' })
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function onFeatureTap(item) {
|
||||||
|
|
||||||
|
uni.showToast({ title: item.name, icon: 'none' })
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
.page {
|
||||||
|
|
||||||
|
height: 100vh;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
padding: calc(var(--status-bar-height, 44px) + 24rpx) 40rpx 24rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
font-size: 40rpx;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
color: $u-primary;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.page-desc {
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
font-size: 26rpx;
|
||||||
|
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
|
||||||
|
margin-top: 6rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.main-scroll {
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
|
||||||
|
padding: 0 40rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.feature-banner {
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
|
||||||
|
border-radius: 16rpx;
|
||||||
|
|
||||||
|
padding: 32rpx 28rpx;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
margin-bottom: 48rpx;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
|
||||||
|
border-color: $u-primary-disabled;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.banner-title {
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
font-size: 30rpx;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
color: $u-primary;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.banner-desc {
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
font-size: 24rpx;
|
||||||
|
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
|
||||||
|
margin-top: 8rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.banner-btn {
|
||||||
|
|
||||||
|
padding: 14rpx 28rpx;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
|
||||||
|
border-radius: 16rpx;
|
||||||
|
|
||||||
|
font-size: 24rpx;
|
||||||
|
|
||||||
|
color: $u-primary;
|
||||||
|
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.category {
|
||||||
|
|
||||||
|
margin-bottom: 48rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.category-title {
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
font-size: 30rpx;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
color: $u-primary;
|
||||||
|
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.feature-grid {
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
|
||||||
|
gap: 20rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.feature-card {
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
|
||||||
|
border-radius: 16rpx;
|
||||||
|
|
||||||
|
padding: 28rpx;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
|
||||||
|
border-color: $u-primary-disabled;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.feature-icon {
|
||||||
|
|
||||||
|
width: 80rpx;
|
||||||
|
|
||||||
|
height: 80rpx;
|
||||||
|
|
||||||
|
border-radius: 20rpx;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.feature-name {
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
font-size: 28rpx;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
color: $u-primary;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.feature-desc {
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
font-size: 22rpx;
|
||||||
|
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
|
||||||
|
margin-top: 4rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.bottom-space {
|
||||||
|
|
||||||
|
height: 40rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,446 @@
|
|||||||
|
<template>
|
||||||
|
<view class="login-page">
|
||||||
|
<view class="page-inner">
|
||||||
|
<!-- 品牌区 -->
|
||||||
|
<view class="header">
|
||||||
|
<text class="title">欢迎回来</text>
|
||||||
|
<text class="subtitle">登录云泽,开启你的旅程</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 登录方式切换 -->
|
||||||
|
<view class="tabs">
|
||||||
|
<view
|
||||||
|
class="tab"
|
||||||
|
:class="{ active: loginType === 'phone' }"
|
||||||
|
@tap="loginType = 'phone'"
|
||||||
|
>手机登录</view>
|
||||||
|
<view
|
||||||
|
class="tab"
|
||||||
|
:class="{ active: loginType === 'account' }"
|
||||||
|
@tap="loginType = 'account'"
|
||||||
|
>账号登录</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 表单 -->
|
||||||
|
<view class="form">
|
||||||
|
<template v-if="loginType === 'phone'">
|
||||||
|
<view class="field">
|
||||||
|
<u-input
|
||||||
|
v-model="phone"
|
||||||
|
placeholder="请输入手机号"
|
||||||
|
type="number"
|
||||||
|
maxlength="11"
|
||||||
|
border="none"
|
||||||
|
color="#3c9cff"
|
||||||
|
:customStyle="inputStyle"
|
||||||
|
:placeholderStyle="placeholderStyle"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<text class="prefix">+86</text>
|
||||||
|
</template>
|
||||||
|
</u-input>
|
||||||
|
</view>
|
||||||
|
<view class="field field-row">
|
||||||
|
<u-input
|
||||||
|
v-model="code"
|
||||||
|
placeholder="请输入验证码"
|
||||||
|
type="number"
|
||||||
|
maxlength="6"
|
||||||
|
border="none"
|
||||||
|
color="#3c9cff"
|
||||||
|
:customStyle="inputStyle"
|
||||||
|
:placeholderStyle="placeholderStyle"
|
||||||
|
/>
|
||||||
|
<text
|
||||||
|
class="code-link"
|
||||||
|
:class="{ disabled: countdown > 0 }"
|
||||||
|
@tap="sendCode"
|
||||||
|
>{{ countdown > 0 ? `${countdown}s 后重发` : '获取验证码' }}</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
<view class="field">
|
||||||
|
<u-input
|
||||||
|
v-model="username"
|
||||||
|
placeholder="请输入账号"
|
||||||
|
border="none"
|
||||||
|
color="#3c9cff"
|
||||||
|
:customStyle="inputStyle"
|
||||||
|
:placeholderStyle="placeholderStyle"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="field">
|
||||||
|
<u-input
|
||||||
|
v-model="password"
|
||||||
|
placeholder="请输入密码"
|
||||||
|
type="password"
|
||||||
|
border="none"
|
||||||
|
color="#3c9cff"
|
||||||
|
:customStyle="inputStyle"
|
||||||
|
:placeholderStyle="placeholderStyle"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<view class="btn-primary" @tap="handleLogin">登 录</view>
|
||||||
|
<view class="btn-ghost" @tap="handleTestLogin">测试登录</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 协议 -->
|
||||||
|
<view class="agreement" @tap="agreed = !agreed">
|
||||||
|
<view class="agree-dot" :class="{ on: agreed }">
|
||||||
|
<text v-if="agreed" class="agree-check">✓</text>
|
||||||
|
</view>
|
||||||
|
<text class="agree-text">
|
||||||
|
登录即表示同意
|
||||||
|
<text class="agree-link">《用户协议》</text>
|
||||||
|
和
|
||||||
|
<text class="agree-link">《隐私政策》</text>
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 第三方 -->
|
||||||
|
<view class="oauth">
|
||||||
|
<text class="oauth-label">其他方式</text>
|
||||||
|
<view class="oauth-icons">
|
||||||
|
<view class="oauth-btn" @tap="socialLogin('wechat')">
|
||||||
|
<FaIcon name="weixin" type="brands" color="#3c9cff" :size="22" />
|
||||||
|
</view>
|
||||||
|
<view class="oauth-btn" @tap="socialLogin('qq')">
|
||||||
|
<FaIcon name="qq" type="brands" color="#3c9cff" :size="22" />
|
||||||
|
</view>
|
||||||
|
<view class="oauth-btn" @tap="socialLogin('alipay')">
|
||||||
|
<FaIcon name="alipay" type="brands" color="#3c9cff" :size="22" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { loginSuccess, isLoggedIn } from '@/utils/auth.js'
|
||||||
|
|
||||||
|
const loginType = ref('phone')
|
||||||
|
const phone = ref('')
|
||||||
|
const code = ref('')
|
||||||
|
const username = ref('')
|
||||||
|
const password = ref('')
|
||||||
|
const agreed = ref(true)
|
||||||
|
const countdown = ref(0)
|
||||||
|
let timer = null
|
||||||
|
|
||||||
|
const inputStyle = {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
padding: '0 8rpx',
|
||||||
|
height: '96rpx',
|
||||||
|
fontSize: '28rpx'
|
||||||
|
}
|
||||||
|
|
||||||
|
const placeholderStyle = 'color: #9acafc; font-size: 28rpx'
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (isLoggedIn()) {
|
||||||
|
uni.reLaunch({ url: '/pages/dashboard/dashboard' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function sendCode() {
|
||||||
|
if (countdown.value > 0) return
|
||||||
|
if (!/^1\d{10}$/.test(phone.value)) {
|
||||||
|
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
countdown.value = 60
|
||||||
|
timer = setInterval(() => {
|
||||||
|
countdown.value--
|
||||||
|
if (countdown.value <= 0) clearInterval(timer)
|
||||||
|
}, 1000)
|
||||||
|
uni.showToast({ title: '验证码已发送', icon: 'success' })
|
||||||
|
}
|
||||||
|
|
||||||
|
function navigateAfterLogin() {
|
||||||
|
uni.showToast({ title: '登录成功', icon: 'success' })
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.reLaunch({ url: '/pages/dashboard/dashboard' })
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTestLogin() {
|
||||||
|
loginSuccess({ nickname: '测试用户', phone: '13800000000' })
|
||||||
|
navigateAfterLogin()
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleLogin() {
|
||||||
|
if (!agreed.value) {
|
||||||
|
uni.showToast({ title: '请先同意用户协议', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (loginType.value === 'phone') {
|
||||||
|
if (!/^1\d{10}$/.test(phone.value)) {
|
||||||
|
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!code.value || code.value.length < 4) {
|
||||||
|
uni.showToast({ title: '请输入验证码', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
loginSuccess({ phone: phone.value, nickname: '用户' + phone.value.slice(-4) })
|
||||||
|
} else {
|
||||||
|
if (!username.value.trim()) {
|
||||||
|
uni.showToast({ title: '请输入账号', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!password.value.trim()) {
|
||||||
|
uni.showToast({ title: '请输入密码', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
loginSuccess({ nickname: username.value })
|
||||||
|
}
|
||||||
|
navigateAfterLogin()
|
||||||
|
}
|
||||||
|
|
||||||
|
function socialLogin(type) {
|
||||||
|
if (!agreed.value) {
|
||||||
|
uni.showToast({ title: '请先同意用户协议', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const names = { wechat: '微信', qq: 'QQ', alipay: '支付宝' }
|
||||||
|
loginSuccess({ nickname: names[type] + '用户' })
|
||||||
|
uni.showToast({ title: `${names[type]}登录成功`, icon: 'success' })
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.reLaunch({ url: '/pages/dashboard/dashboard' })
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.login-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-inner {
|
||||||
|
padding: 0 56rpx;
|
||||||
|
padding-top: calc(var(--status-bar-height, 44px) + 80rpx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- 品牌 ---- */
|
||||||
|
.header {
|
||||||
|
margin-bottom: 72rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 88rpx;
|
||||||
|
height: 88rpx;
|
||||||
|
border-radius: 22rpx;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-char {
|
||||||
|
font-size: 44rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: $u-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
display: block;
|
||||||
|
font-size: 52rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: $u-primary;
|
||||||
|
letter-spacing: 2rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
display: block;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
margin-top: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Tab ---- */
|
||||||
|
.tabs {
|
||||||
|
display: flex;
|
||||||
|
gap: 48rpx;
|
||||||
|
margin-bottom: 48rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
padding-bottom: 12rpx;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: $u-primary;
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
height: 4rpx;
|
||||||
|
background: $u-primary;
|
||||||
|
border-radius: 2rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- 表单 ---- */
|
||||||
|
.form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field {
|
||||||
|
background: #ffffff;
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 0 28rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prefix {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: $u-primary;
|
||||||
|
padding-right: 20rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
border-right: 1rpx solid $u-primary-disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-link {
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: $u-primary;
|
||||||
|
padding-left: 16rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
height: 96rpx;
|
||||||
|
background: $u-primary;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: 6rpx;
|
||||||
|
margin-top: 16rpx;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background: $u-primary-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-ghost {
|
||||||
|
height: 96rpx;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 2rpx solid $u-primary;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: $u-primary;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background: #f8fbff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- 协议 ---- */
|
||||||
|
.agreement {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12rpx;
|
||||||
|
margin-top: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agree-dot {
|
||||||
|
width: 30rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 2rpx solid $u-primary-disabled;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: 2rpx;
|
||||||
|
|
||||||
|
&.on {
|
||||||
|
background: $u-primary;
|
||||||
|
border-color: $u-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.agree-check {
|
||||||
|
font-size: 18rpx;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agree-text {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agree-link {
|
||||||
|
color: $u-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- 第三方 ---- */
|
||||||
|
.oauth {
|
||||||
|
margin-top: 80rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 28rpx;
|
||||||
|
padding-bottom: 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oauth-label {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oauth-icons {
|
||||||
|
display: flex;
|
||||||
|
gap: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oauth-btn {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
border-color: $u-primary-disabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,649 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view class="page">
|
||||||
|
|
||||||
|
<view class="profile-header">
|
||||||
|
|
||||||
|
<view class="profile-info">
|
||||||
|
|
||||||
|
<view class="profile-avatar">
|
||||||
|
|
||||||
|
<text class="avatar-text">{{ avatarText }}</text>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="profile-detail">
|
||||||
|
|
||||||
|
<text class="profile-name">{{ user?.nickname || '云泽用户' }}</text>
|
||||||
|
|
||||||
|
<text class="profile-id">ID: {{ userId }}</text>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="profile-edit" @tap="onEdit">
|
||||||
|
|
||||||
|
<FaIcon name="pen-to-square" color="#3c9cff" :size="18" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<view class="profile-stats">
|
||||||
|
|
||||||
|
<view class="profile-stat" v-for="item in profileStats" :key="item.label">
|
||||||
|
|
||||||
|
<text class="stat-num">{{ item.value }}</text>
|
||||||
|
|
||||||
|
<text class="stat-label">{{ item.label }}</text>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<view class="main-scroll">
|
||||||
|
|
||||||
|
<view class="menu-group" v-for="(group, gIndex) in menuGroups" :key="gIndex">
|
||||||
|
|
||||||
|
<view
|
||||||
|
|
||||||
|
class="menu-item"
|
||||||
|
|
||||||
|
v-for="item in group"
|
||||||
|
|
||||||
|
:key="item.title"
|
||||||
|
|
||||||
|
@tap="onMenuTap(item)"
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
<view class="menu-left">
|
||||||
|
|
||||||
|
<view class="menu-icon">
|
||||||
|
|
||||||
|
<FaIcon :name="item.icon" color="#3c9cff" :size="18" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<text class="menu-title">{{ item.title }}</text>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="menu-right">
|
||||||
|
|
||||||
|
<text v-if="item.badge" class="menu-badge">{{ item.badge }}</text>
|
||||||
|
|
||||||
|
<FaIcon name="chevron-right" color="#9acafc" :size="14" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<view class="logout-btn" @tap="handleLogout">
|
||||||
|
|
||||||
|
<text class="logout-text">退出登录</text>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<view class="bottom-space" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<AppTabbar current="profile" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
import { ref, computed, onMounted } from 'vue'
|
||||||
|
|
||||||
|
import { getUser, logout, isLoggedIn } from '@/utils/auth.js'
|
||||||
|
|
||||||
|
import AppTabbar from '@/components/AppTabbar.vue'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const user = ref(null)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const avatarText = computed(() => {
|
||||||
|
|
||||||
|
const name = user.value?.nickname || '云'
|
||||||
|
|
||||||
|
return name.charAt(0).toUpperCase()
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const userId = computed(() => {
|
||||||
|
|
||||||
|
return user.value?.phone
|
||||||
|
|
||||||
|
? user.value.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
|
||||||
|
|
||||||
|
: '10086'
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const profileStats = ref([
|
||||||
|
|
||||||
|
{ label: '关注', value: '128' },
|
||||||
|
|
||||||
|
{ label: '粉丝', value: '256' },
|
||||||
|
|
||||||
|
{ label: '获赞', value: '1.2k' }
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const menuGroups = ref([
|
||||||
|
|
||||||
|
[
|
||||||
|
|
||||||
|
{ title: '我的订单', icon: 'clipboard-list' },
|
||||||
|
|
||||||
|
{ title: '我的收藏', icon: 'star' },
|
||||||
|
|
||||||
|
{ title: '浏览历史', icon: 'clock-rotate-left' }
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
|
||||||
|
{ title: '消息通知', icon: 'bell', badge: '3' },
|
||||||
|
|
||||||
|
{ title: '账号安全', icon: 'lock' },
|
||||||
|
|
||||||
|
{ title: '隐私设置', icon: 'eye' }
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
|
||||||
|
{ title: '帮助中心', icon: 'circle-question' },
|
||||||
|
|
||||||
|
{ title: '关于我们', icon: 'circle-info' },
|
||||||
|
|
||||||
|
{ title: '设置', icon: 'gear' }
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
|
||||||
|
uni.reLaunch({ url: '/pages/login/login' })
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
user.value = getUser()
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function onEdit() {
|
||||||
|
|
||||||
|
uni.showToast({ title: '编辑资料', icon: 'none' })
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function onMenuTap(item) {
|
||||||
|
|
||||||
|
uni.showToast({ title: item.title, icon: 'none' })
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function handleLogout() {
|
||||||
|
|
||||||
|
uni.showModal({
|
||||||
|
|
||||||
|
title: '提示',
|
||||||
|
|
||||||
|
content: '确定要退出登录吗?',
|
||||||
|
|
||||||
|
success(res) {
|
||||||
|
|
||||||
|
if (res.confirm) {
|
||||||
|
|
||||||
|
logout()
|
||||||
|
|
||||||
|
uni.reLaunch({ url: '/pages/login/login' })
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
.page {
|
||||||
|
|
||||||
|
height: 100vh;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.profile-header {
|
||||||
|
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
padding: calc(var(--status-bar-height, 44px) + 24rpx) 40rpx 32rpx;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.profile-info {
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
gap: 24rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.profile-avatar {
|
||||||
|
|
||||||
|
width: 100rpx;
|
||||||
|
|
||||||
|
height: 100rpx;
|
||||||
|
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.avatar-text {
|
||||||
|
|
||||||
|
font-size: 40rpx;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
color: $u-primary;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.profile-detail {
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.profile-name {
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
font-size: 36rpx;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
color: $u-primary;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.profile-id {
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
font-size: 24rpx;
|
||||||
|
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
|
||||||
|
margin-top: 6rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.profile-edit {
|
||||||
|
|
||||||
|
width: 64rpx;
|
||||||
|
|
||||||
|
height: 64rpx;
|
||||||
|
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
|
||||||
|
border-color: $u-primary-disabled;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.profile-stats {
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
justify-content: space-around;
|
||||||
|
|
||||||
|
margin-top: 32rpx;
|
||||||
|
|
||||||
|
padding: 28rpx 0;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
|
||||||
|
border-radius: 16rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.profile-stat {
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.stat-num {
|
||||||
|
|
||||||
|
font-size: 32rpx;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
color: $u-primary;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
|
||||||
|
font-size: 22rpx;
|
||||||
|
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
|
||||||
|
margin-top: 4rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.main-scroll {
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
|
||||||
|
padding: 8rpx 40rpx 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.menu-group {
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
|
||||||
|
border-radius: 16rpx;
|
||||||
|
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
padding: 28rpx;
|
||||||
|
|
||||||
|
border-bottom: 2rpx solid #f0f6fb;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
|
||||||
|
border-bottom: none;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
|
||||||
|
background: #f8fafc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.menu-left {
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
gap: 20rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.menu-icon {
|
||||||
|
|
||||||
|
width: 64rpx;
|
||||||
|
|
||||||
|
height: 64rpx;
|
||||||
|
|
||||||
|
border-radius: 16rpx;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.menu-title {
|
||||||
|
|
||||||
|
font-size: 28rpx;
|
||||||
|
|
||||||
|
color: $u-primary;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.menu-right {
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
gap: 12rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.menu-badge {
|
||||||
|
|
||||||
|
font-size: 20rpx;
|
||||||
|
|
||||||
|
color: #ffffff;
|
||||||
|
|
||||||
|
background: $u-primary;
|
||||||
|
|
||||||
|
padding: 2rpx 12rpx;
|
||||||
|
|
||||||
|
border-radius: 999rpx;
|
||||||
|
|
||||||
|
min-width: 32rpx;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.logout-btn {
|
||||||
|
|
||||||
|
margin-top: 8rpx;
|
||||||
|
|
||||||
|
height: 96rpx;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
border: 2rpx solid #e8f0f8;
|
||||||
|
|
||||||
|
border-radius: 16rpx;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
|
||||||
|
border-color: $u-primary-disabled;
|
||||||
|
|
||||||
|
background: #f8fafc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.logout-text {
|
||||||
|
|
||||||
|
font-size: 30rpx;
|
||||||
|
|
||||||
|
color: $u-primary-disabled;
|
||||||
|
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.bottom-space {
|
||||||
|
|
||||||
|
height: 40rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* 从 Font Awesome SCSS 变量生成图标 Unicode 映射表。
|
||||||
|
* 升级 @fortawesome/fontawesome-free 后执行: node scripts/gen-fa-icons.js
|
||||||
|
*/
|
||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
const scssPath = path.join(
|
||||||
|
__dirname,
|
||||||
|
'../node_modules/@fortawesome/fontawesome-free/scss/_variables.scss'
|
||||||
|
)
|
||||||
|
const outputPath = path.join(__dirname, '../utils/fa-icons.js')
|
||||||
|
|
||||||
|
const source = fs.readFileSync(scssPath, 'utf8')
|
||||||
|
const icons = {}
|
||||||
|
|
||||||
|
for (const match of source.matchAll(/\$var-([a-z0-9-]+):\s*\\([a-f0-9]+);/gi)) {
|
||||||
|
const [, name, hex] = match
|
||||||
|
icons[name] = String.fromCharCode(parseInt(hex, 16))
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = `export const FA_ICONS = ${JSON.stringify(icons, null, 2)}\n`
|
||||||
|
fs.writeFileSync(outputPath, content, 'utf8')
|
||||||
|
console.log(`Generated ${Object.keys(icons).length} icons -> utils/fa-icons.js`)
|
||||||
Vendored
+15
@@ -0,0 +1,15 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Font Awesome 7 Free';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: block;
|
||||||
|
src: url('/static/webfonts/fa-solid-900.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Font Awesome 7 Brands';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: block;
|
||||||
|
src: url('/static/webfonts/fa-brands-400.woff2') format('woff2');
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// 简约潮流主题变量
|
||||||
|
$color-primary: #6366f1;
|
||||||
|
$color-primary-light: #818cf8;
|
||||||
|
$color-primary-dark: #4f46e5;
|
||||||
|
$color-accent: #ec4899;
|
||||||
|
$color-bg: #f8fafc;
|
||||||
|
$color-card: #ffffff;
|
||||||
|
$color-text: #1e293b;
|
||||||
|
$color-text-secondary: #64748b;
|
||||||
|
$color-text-muted: #94a3b8;
|
||||||
|
$color-border: #e2e8f0;
|
||||||
|
$gradient-primary: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #ec4899 100%);
|
||||||
|
$gradient-soft: linear-gradient(160deg, #eef2ff 0%, #faf5ff 50%, #fdf2f8 100%);
|
||||||
|
$shadow-sm: 0 2rpx 12rpx rgba(99, 102, 241, 0.08);
|
||||||
|
$shadow-md: 0 8rpx 32rpx rgba(99, 102, 241, 0.12);
|
||||||
|
$radius-sm: 16rpx;
|
||||||
|
$radius-md: 24rpx;
|
||||||
|
$radius-lg: 32rpx;
|
||||||
|
$radius-full: 999rpx;
|
||||||
+2
-1
@@ -1 +1,2 @@
|
|||||||
@import 'uview-plus/theme.scss';
|
// 已迁移至项目根目录 uni.scss,此文件保留兼容引用
|
||||||
|
@import '../uni.scss';
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -3,7 +3,7 @@
|
|||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"]
|
"@/*": ["./*"]
|
||||||
},
|
},
|
||||||
"lib": ["esnext", "dom"],
|
"lib": ["esnext", "dom"],
|
||||||
"types": [
|
"types": [
|
||||||
|
|||||||
@@ -74,3 +74,6 @@ $uni-color-subtitle: #555555; // 二级标题颜色
|
|||||||
$uni-font-size-subtitle:26px;
|
$uni-font-size-subtitle:26px;
|
||||||
$uni-color-paragraph: #3F536E; // 文章段落颜色
|
$uni-color-paragraph: #3F536E; // 文章段落颜色
|
||||||
$uni-font-size-paragraph:15px;
|
$uni-font-size-paragraph:15px;
|
||||||
|
|
||||||
|
/* uview-plus 主题变量与 mixin,需放在根目录 uni.scss 以便全局注入 */
|
||||||
|
@import 'uview-plus/theme.scss';
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
const TOKEN_KEY = 'app_token'
|
||||||
|
const USER_KEY = 'app_user'
|
||||||
|
|
||||||
|
export function setToken(token) {
|
||||||
|
uni.setStorageSync(TOKEN_KEY, token)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getToken() {
|
||||||
|
return uni.getStorageSync(TOKEN_KEY) || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setUser(user) {
|
||||||
|
uni.setStorageSync(USER_KEY, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getUser() {
|
||||||
|
return uni.getStorageSync(USER_KEY) || null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isLoggedIn() {
|
||||||
|
return !!getToken()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function logout() {
|
||||||
|
uni.removeStorageSync(TOKEN_KEY)
|
||||||
|
uni.removeStorageSync(USER_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loginSuccess(user = {}) {
|
||||||
|
setToken('demo_token_' + Date.now())
|
||||||
|
setUser({
|
||||||
|
nickname: user.nickname || '云泽用户',
|
||||||
|
avatar: user.avatar || '',
|
||||||
|
phone: user.phone || '',
|
||||||
|
...user
|
||||||
|
})
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
+8
-20
@@ -1,28 +1,16 @@
|
|||||||
import { defineConfig } from "vite";
|
import { defineConfig } from 'vite'
|
||||||
import uni from "@dcloudio/vite-plugin-uni";
|
import uni from '@dcloudio/vite-plugin-uni'
|
||||||
import { visualizer } from "rollup-plugin-visualizer";
|
|
||||||
import { uviewPlus } from "uview-plus/vite-plugin";
|
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
export default defineConfig({
|
||||||
export default defineConfig({
|
|
||||||
plugins: [
|
plugins: [
|
||||||
uni(),
|
uni()
|
||||||
uviewPlus({ appFontLocal: true }),
|
|
||||||
visualizer()
|
|
||||||
],
|
],
|
||||||
css: {
|
css: {
|
||||||
preprocessorOptions: {
|
preprocessorOptions: {
|
||||||
scss: {
|
scss: {
|
||||||
// 取消sass废弃API的报警
|
// 关闭废弃 API 警告
|
||||||
silenceDeprecations: ['legacy-js-api', 'color-functions', 'import'],
|
silenceDeprecations: ['legacy-js-api', 'color-functions', 'import'],
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
server: {
|
|
||||||
port: 5100,
|
|
||||||
fs: {
|
|
||||||
// Allow serving files from one level up to the project root
|
|
||||||
allow: ['..']
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
}
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user