mirror of
https://github.com/chansee97/nova-admin.git
synced 2025-09-03 05:05:44 +08:00
feat: adapted mobile screen
This commit is contained in:
parent
1b4639d5d8
commit
3144acbc39
6
pnpm-workspace.yaml
Normal file
6
pnpm-workspace.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
ignoredBuiltDependencies:
|
||||||
|
- '@parcel/watcher'
|
||||||
|
- esbuild
|
||||||
|
- simple-git-hooks
|
||||||
|
- vue-demi
|
||||||
|
- unrs-resolver
|
38
src/layouts/components/common/MobileDrawer.vue
Normal file
38
src/layouts/components/common/MobileDrawer.vue
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import Search from '../header/Search.vue'
|
||||||
|
import Notices from '../header/Notices.vue'
|
||||||
|
import UserCenter from '../header/UserCenter.vue'
|
||||||
|
import Setting from './Setting.vue'
|
||||||
|
|
||||||
|
const showDrawer = defineModel<boolean>('show', { default: false })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<n-drawer
|
||||||
|
v-model:show="showDrawer"
|
||||||
|
:width="280"
|
||||||
|
placement="right"
|
||||||
|
:mask-closable="true"
|
||||||
|
:close-on-esc="true"
|
||||||
|
>
|
||||||
|
<n-drawer-content :native-scrollbar="false" :body-content-style="{ padding: '0' }">
|
||||||
|
<template #header>
|
||||||
|
<div class="flex">
|
||||||
|
<UserCenter />
|
||||||
|
<div class="ml-auto" />
|
||||||
|
<Search />
|
||||||
|
<Notices />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<slot />
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<DarkModeSwitch />
|
||||||
|
<LangsSwitch />
|
||||||
|
<div class="ml-auto" />
|
||||||
|
<Setting />
|
||||||
|
</template>
|
||||||
|
</n-drawer-content>
|
||||||
|
</n-drawer>
|
||||||
|
</template>
|
@ -1,7 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useBoolean } from '@/hooks'
|
import { useBoolean } from '@/hooks'
|
||||||
import { useRouteStore } from '@/store'
|
import { useAppStore, useRouteStore } from '@/store'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
const routeStore = useRouteStore()
|
const routeStore = useRouteStore()
|
||||||
|
|
||||||
// 搜索值
|
// 搜索值
|
||||||
@ -143,13 +144,14 @@ function handleMouseEnter(index: number) {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<CommonWrapper @click="openModal">
|
<CommonWrapper @click="openModal">
|
||||||
<icon-park-outline-search /><n-tag round size="small" class="font-mono cursor-pointer">
|
<icon-park-outline-search />
|
||||||
|
<n-tag v-if="!appStore.isMobile" round size="small" class="font-mono cursor-pointer">
|
||||||
CtrlK
|
CtrlK
|
||||||
</n-tag>
|
</n-tag>
|
||||||
</CommonWrapper>
|
</CommonWrapper>
|
||||||
<n-modal
|
<n-modal
|
||||||
v-model:show="showModal"
|
v-model:show="showModal"
|
||||||
class="w-560px fixed top-60px inset-x-0"
|
class="w-560px fixed top-60px inset-x-0 max-w-full"
|
||||||
size="small"
|
size="small"
|
||||||
preset="card"
|
preset="card"
|
||||||
:segmented="{
|
:segmented="{
|
||||||
|
@ -2,6 +2,7 @@ import BackTop from './common/BackTop.vue'
|
|||||||
import Setting from './common/Setting.vue'
|
import Setting from './common/Setting.vue'
|
||||||
import SettingDrawer from './common/SettingDrawer.vue'
|
import SettingDrawer from './common/SettingDrawer.vue'
|
||||||
import Logo from './common/Logo.vue'
|
import Logo from './common/Logo.vue'
|
||||||
|
import MobileDrawer from './common/MobileDrawer.vue'
|
||||||
|
|
||||||
import Breadcrumb from './header/Breadcrumb.vue'
|
import Breadcrumb from './header/Breadcrumb.vue'
|
||||||
import CollapaseButton from './header/CollapaseButton.vue'
|
import CollapaseButton from './header/CollapaseButton.vue'
|
||||||
@ -18,6 +19,7 @@ export {
|
|||||||
CollapaseButton,
|
CollapaseButton,
|
||||||
FullScreen,
|
FullScreen,
|
||||||
Logo,
|
Logo,
|
||||||
|
MobileDrawer,
|
||||||
Notices,
|
Notices,
|
||||||
Search,
|
Search,
|
||||||
Setting,
|
Setting,
|
||||||
|
@ -20,7 +20,7 @@ function exitFullContent() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<n-tooltip placement="bottom" trigger="hover">
|
<n-tooltip v-if="!appStore.isMobile" placement="bottom" trigger="hover">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<CommonWrapper @click="enterFullContent">
|
<CommonWrapper @click="enterFullContent">
|
||||||
<icon-park-outline-full-screen-one />
|
<icon-park-outline-full-screen-one />
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
CollapaseButton,
|
CollapaseButton,
|
||||||
FullScreen,
|
FullScreen,
|
||||||
Logo,
|
Logo,
|
||||||
|
MobileDrawer,
|
||||||
Notices,
|
Notices,
|
||||||
Search,
|
Search,
|
||||||
Setting,
|
Setting,
|
||||||
@ -14,12 +15,12 @@ import {
|
|||||||
UserCenter,
|
UserCenter,
|
||||||
} from './components'
|
} from './components'
|
||||||
import Content from './Content.vue'
|
import Content from './Content.vue'
|
||||||
|
|
||||||
import { ProLayout, useLayoutMenu } from 'pro-naive-ui'
|
import { ProLayout, useLayoutMenu } from 'pro-naive-ui'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
const routeStore = useRouteStore()
|
const routeStore = useRouteStore()
|
||||||
|
|
||||||
const { layoutMode } = storeToRefs(useAppStore())
|
const { layoutMode } = storeToRefs(useAppStore())
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -31,16 +32,19 @@ const {
|
|||||||
menus: routeStore.menus,
|
menus: routeStore.menus,
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => route.path, (value) => {
|
watch(() => route.path, (value: string) => {
|
||||||
activeKey.value = value
|
activeKey.value = value
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
|
// 移动端抽屉控制
|
||||||
|
const showMobileDrawer = ref(false)
|
||||||
|
|
||||||
const sidebarWidth = ref(240)
|
const sidebarWidth = ref(240)
|
||||||
const sidebarCollapsedWidth = ref(64)
|
const sidebarCollapsedWidth = ref(64)
|
||||||
|
|
||||||
const hasHorizontalMenu = computed(() => ['horizontal', 'mixed-two-column', 'mixed-sidebar'].includes(layoutMode.value))
|
const hasHorizontalMenu = computed(() => ['horizontal', 'mixed-two-column', 'mixed-sidebar'].includes(layoutMode.value))
|
||||||
|
|
||||||
const hidenCollapaseButton = computed(() => ['horizontal'].includes(layoutMode.value))
|
const hidenCollapaseButton = computed(() => ['horizontal'].includes(layoutMode.value) || appStore.isMobile)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -48,7 +52,8 @@ const hidenCollapaseButton = computed(() => ['horizontal'].includes(layoutMode.v
|
|||||||
<ProLayout
|
<ProLayout
|
||||||
v-model:collapsed="appStore.collapsed"
|
v-model:collapsed="appStore.collapsed"
|
||||||
:mode="layoutMode"
|
:mode="layoutMode"
|
||||||
:show-logo="appStore.showLogo"
|
:is-mobile="appStore.isMobile"
|
||||||
|
:show-logo="appStore.showLogo && !appStore.isMobile"
|
||||||
:show-footer="appStore.showFooter"
|
:show-footer="appStore.showFooter"
|
||||||
:show-tabbar="appStore.showTabs"
|
:show-tabbar="appStore.showTabs"
|
||||||
nav-fixed
|
nav-fixed
|
||||||
@ -79,13 +84,30 @@ const hidenCollapaseButton = computed(() => ['horizontal'].includes(layoutMode.v
|
|||||||
|
|
||||||
<template #nav-right>
|
<template #nav-right>
|
||||||
<div class="h-full flex-y-center gap-1 p-x-xl">
|
<div class="h-full flex-y-center gap-1 p-x-xl">
|
||||||
<Search />
|
<!-- 移动端:只显示菜单按钮 -->
|
||||||
<Notices />
|
<template v-if="appStore.isMobile">
|
||||||
<FullScreen />
|
<n-button
|
||||||
<DarkModeSwitch />
|
quaternary
|
||||||
<LangsSwitch />
|
@click="showMobileDrawer = true"
|
||||||
<Setting />
|
>
|
||||||
<UserCenter />
|
<template #icon>
|
||||||
|
<n-icon size="18">
|
||||||
|
<icon-park-outline-hamburger-button />
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 桌面端:显示完整功能组件 -->
|
||||||
|
<template v-else>
|
||||||
|
<Search />
|
||||||
|
<Notices />
|
||||||
|
<FullScreen />
|
||||||
|
<DarkModeSwitch />
|
||||||
|
<LangsSwitch />
|
||||||
|
<Setting />
|
||||||
|
<UserCenter />
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -111,5 +133,10 @@ const hidenCollapaseButton = computed(() => ['horizontal'].includes(layoutMode.v
|
|||||||
<Content />
|
<Content />
|
||||||
<BackTop />
|
<BackTop />
|
||||||
<SettingDrawer />
|
<SettingDrawer />
|
||||||
|
|
||||||
|
<!-- 移动端功能抽屉 -->
|
||||||
|
<MobileDrawer v-model:show="showMobileDrawer">
|
||||||
|
<n-menu v-bind="layout.verticalMenuProps" />
|
||||||
|
</MobileDrawer>
|
||||||
</ProLayout>
|
</ProLayout>
|
||||||
</template>
|
</template>
|
||||||
|
@ -17,6 +17,8 @@ const { system, store } = useColorMode({
|
|||||||
emitAuto: true,
|
emitAuto: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const isMobile = useMediaQuery('(max-width: 700px)')
|
||||||
|
|
||||||
export const useAppStore = defineStore('app-store', {
|
export const useAppStore = defineStore('app-store', {
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
@ -50,6 +52,9 @@ export const useAppStore = defineStore('app-store', {
|
|||||||
fullScreen() {
|
fullScreen() {
|
||||||
return isFullscreen.value
|
return isFullscreen.value
|
||||||
},
|
},
|
||||||
|
isMobile() {
|
||||||
|
return isMobile.value
|
||||||
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
// 重置所有设置
|
// 重置所有设置
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useAppStore } from '@/store'
|
||||||
import Chart from './components/chart.vue'
|
import Chart from './components/chart.vue'
|
||||||
import Chart2 from './components/chart2.vue'
|
import Chart2 from './components/chart2.vue'
|
||||||
import Chart3 from './components/chart3.vue'
|
import Chart3 from './components/chart3.vue'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
const tableData = [
|
const tableData = [
|
||||||
{
|
{
|
||||||
id: 0,
|
id: 0,
|
||||||
@ -32,218 +35,224 @@ const tableData = [
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<n-grid
|
||||||
<n-grid
|
:x-gap="16"
|
||||||
:x-gap="16"
|
:y-gap="16"
|
||||||
:y-gap="16"
|
:cols="12"
|
||||||
>
|
item-responsive
|
||||||
<n-gi :span="6">
|
responsive="screen"
|
||||||
<n-card>
|
>
|
||||||
<n-space
|
<!-- 统计卡片 - 移动端每行2个,桌面端每行4个 -->
|
||||||
justify="space-between"
|
<n-gi span="6 m:3">
|
||||||
align="center"
|
<n-card>
|
||||||
>
|
<n-space
|
||||||
<n-statistic label="访问量">
|
justify="space-between"
|
||||||
<n-number-animation
|
align="center"
|
||||||
:from="0"
|
|
||||||
:to="12039"
|
|
||||||
show-separator
|
|
||||||
/>
|
|
||||||
</n-statistic>
|
|
||||||
<n-icon
|
|
||||||
color="#de4307"
|
|
||||||
size="42"
|
|
||||||
>
|
|
||||||
<icon-park-outline-chart-histogram />
|
|
||||||
</n-icon>
|
|
||||||
</n-space>
|
|
||||||
<template #footer>
|
|
||||||
<n-space justify="space-between">
|
|
||||||
<span>累计访问数</span>
|
|
||||||
<span><n-number-animation
|
|
||||||
:from="0"
|
|
||||||
:to="322039"
|
|
||||||
show-separator
|
|
||||||
/></span>
|
|
||||||
</n-space>
|
|
||||||
</template>
|
|
||||||
</n-card>
|
|
||||||
</n-gi>
|
|
||||||
<n-gi :span="6">
|
|
||||||
<n-card>
|
|
||||||
<n-space
|
|
||||||
justify="space-between"
|
|
||||||
align="center"
|
|
||||||
>
|
|
||||||
<n-statistic label="下载量">
|
|
||||||
<n-number-animation
|
|
||||||
:from="0"
|
|
||||||
:to="12039"
|
|
||||||
show-separator
|
|
||||||
/>
|
|
||||||
</n-statistic>
|
|
||||||
<n-icon
|
|
||||||
color="#ffb549"
|
|
||||||
size="42"
|
|
||||||
>
|
|
||||||
<icon-park-outline-chart-graph />
|
|
||||||
</n-icon>
|
|
||||||
</n-space>
|
|
||||||
<template #footer>
|
|
||||||
<n-space justify="space-between">
|
|
||||||
<span>累计下载量</span>
|
|
||||||
<span><n-number-animation
|
|
||||||
:from="0"
|
|
||||||
:to="322039"
|
|
||||||
show-separator
|
|
||||||
/></span>
|
|
||||||
</n-space>
|
|
||||||
</template>
|
|
||||||
</n-card>
|
|
||||||
</n-gi>
|
|
||||||
<n-gi :span="6">
|
|
||||||
<n-card>
|
|
||||||
<n-space
|
|
||||||
justify="space-between"
|
|
||||||
align="center"
|
|
||||||
>
|
|
||||||
<n-statistic label="浏览量">
|
|
||||||
<n-number-animation
|
|
||||||
:from="0"
|
|
||||||
:to="12039"
|
|
||||||
show-separator
|
|
||||||
/>
|
|
||||||
</n-statistic>
|
|
||||||
<n-icon
|
|
||||||
color="#1687a7"
|
|
||||||
size="42"
|
|
||||||
>
|
|
||||||
<icon-park-outline-average />
|
|
||||||
</n-icon>
|
|
||||||
</n-space>
|
|
||||||
<template #footer>
|
|
||||||
<n-space justify="space-between">
|
|
||||||
<span>累计浏览量</span>
|
|
||||||
<span><n-number-animation
|
|
||||||
:from="0"
|
|
||||||
:to="322039"
|
|
||||||
show-separator
|
|
||||||
/></span>
|
|
||||||
</n-space>
|
|
||||||
</template>
|
|
||||||
</n-card>
|
|
||||||
</n-gi>
|
|
||||||
<n-gi :span="6">
|
|
||||||
<n-card>
|
|
||||||
<n-space
|
|
||||||
justify="space-between"
|
|
||||||
align="center"
|
|
||||||
>
|
|
||||||
<n-statistic label="注册量">
|
|
||||||
<n-number-animation
|
|
||||||
:from="0"
|
|
||||||
:to="12039"
|
|
||||||
show-separator
|
|
||||||
/>
|
|
||||||
</n-statistic>
|
|
||||||
<n-icon
|
|
||||||
color="#42218E"
|
|
||||||
size="42"
|
|
||||||
>
|
|
||||||
<icon-park-outline-chart-pie />
|
|
||||||
</n-icon>
|
|
||||||
</n-space>
|
|
||||||
<template #footer>
|
|
||||||
<n-space justify="space-between">
|
|
||||||
<span>累计注册量</span>
|
|
||||||
<span><n-number-animation
|
|
||||||
:from="0"
|
|
||||||
:to="322039"
|
|
||||||
show-separator
|
|
||||||
/></span>
|
|
||||||
</n-space>
|
|
||||||
</template>
|
|
||||||
</n-card>
|
|
||||||
</n-gi>
|
|
||||||
<n-gi :span="24">
|
|
||||||
<n-card content-style="padding: 0;">
|
|
||||||
<n-tabs
|
|
||||||
type="line"
|
|
||||||
size="large"
|
|
||||||
:tabs-padding="20"
|
|
||||||
pane-style="padding: 20px;"
|
|
||||||
>
|
|
||||||
<n-tab-pane name="流量趋势">
|
|
||||||
<Chart />
|
|
||||||
</n-tab-pane>
|
|
||||||
<n-tab-pane name="访问量趋势">
|
|
||||||
<Chart2 />
|
|
||||||
</n-tab-pane>
|
|
||||||
</n-tabs>
|
|
||||||
</n-card>
|
|
||||||
</n-gi>
|
|
||||||
<n-gi :span="8">
|
|
||||||
<n-card
|
|
||||||
title="访问来源"
|
|
||||||
:segmented="{
|
|
||||||
content: true,
|
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<Chart3 />
|
<n-statistic label="访问量">
|
||||||
</n-card>
|
<n-number-animation
|
||||||
</n-gi>
|
:from="0"
|
||||||
<n-gi :span="16">
|
:to="12039"
|
||||||
<n-card
|
show-separator
|
||||||
title="成交记录"
|
/>
|
||||||
:segmented="{
|
</n-statistic>
|
||||||
content: true,
|
<n-icon
|
||||||
}"
|
color="#de4307"
|
||||||
>
|
size="42"
|
||||||
<template #header-extra>
|
|
||||||
<n-button
|
|
||||||
type="primary"
|
|
||||||
quaternary
|
|
||||||
>
|
|
||||||
更多
|
|
||||||
</n-button>
|
|
||||||
</template>
|
|
||||||
<n-table
|
|
||||||
:bordered="false"
|
|
||||||
:single-line="false"
|
|
||||||
>
|
>
|
||||||
<thead>
|
<icon-park-outline-chart-histogram />
|
||||||
<tr>
|
</n-icon>
|
||||||
<th>交易名称</th>
|
</n-space>
|
||||||
<th>开始时间</th>
|
<template #footer>
|
||||||
<th>结束时间</th>
|
<n-space justify="space-between">
|
||||||
<th>进度</th>
|
<span>累计访问数</span>
|
||||||
<th>状态</th>
|
<span><n-number-animation
|
||||||
</tr>
|
:from="0"
|
||||||
</thead>
|
:to="322039"
|
||||||
<tbody>
|
show-separator
|
||||||
<tr
|
/></span>
|
||||||
v-for="item in tableData"
|
</n-space>
|
||||||
:key="item.id"
|
</template>
|
||||||
>
|
</n-card>
|
||||||
<td>{{ item.name }}</td>
|
</n-gi>
|
||||||
<td>{{ item.start }}</td>
|
<n-gi span="6 m:3">
|
||||||
<td>{{ item.end }}</td>
|
<n-card>
|
||||||
<td>{{ item.prograss }}%</td>
|
<n-space
|
||||||
<td>
|
justify="space-between"
|
||||||
<n-tag
|
align="center"
|
||||||
:bordered="false"
|
>
|
||||||
type="info"
|
<n-statistic label="下载量">
|
||||||
>
|
<n-number-animation
|
||||||
{{ item.status }}
|
:from="0"
|
||||||
</n-tag>
|
:to="12039"
|
||||||
</td>
|
show-separator
|
||||||
</tr>
|
/>
|
||||||
</tbody>
|
</n-statistic>
|
||||||
</n-table>
|
<n-icon
|
||||||
</n-card>
|
color="#ffb549"
|
||||||
</n-gi>
|
size="42"
|
||||||
</n-grid>
|
>
|
||||||
</div>
|
<icon-park-outline-chart-graph />
|
||||||
</template>
|
</n-icon>
|
||||||
|
</n-space>
|
||||||
|
<template #footer>
|
||||||
|
<n-space justify="space-between">
|
||||||
|
<span>累计下载量</span>
|
||||||
|
<span><n-number-animation
|
||||||
|
:from="0"
|
||||||
|
:to="322039"
|
||||||
|
show-separator
|
||||||
|
/></span>
|
||||||
|
</n-space>
|
||||||
|
</template>
|
||||||
|
</n-card>
|
||||||
|
</n-gi>
|
||||||
|
<n-gi span="6 m:3">
|
||||||
|
<n-card>
|
||||||
|
<n-space
|
||||||
|
justify="space-between"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<n-statistic label="浏览量">
|
||||||
|
<n-number-animation
|
||||||
|
:from="0"
|
||||||
|
:to="12039"
|
||||||
|
show-separator
|
||||||
|
/>
|
||||||
|
</n-statistic>
|
||||||
|
<n-icon
|
||||||
|
color="#1687a7"
|
||||||
|
size="42"
|
||||||
|
>
|
||||||
|
<icon-park-outline-average />
|
||||||
|
</n-icon>
|
||||||
|
</n-space>
|
||||||
|
<template #footer>
|
||||||
|
<n-space justify="space-between">
|
||||||
|
<span>累计浏览量</span>
|
||||||
|
<span><n-number-animation
|
||||||
|
:from="0"
|
||||||
|
:to="322039"
|
||||||
|
show-separator
|
||||||
|
/></span>
|
||||||
|
</n-space>
|
||||||
|
</template>
|
||||||
|
</n-card>
|
||||||
|
</n-gi>
|
||||||
|
<n-gi span="6 m:3">
|
||||||
|
<n-card>
|
||||||
|
<n-space
|
||||||
|
justify="space-between"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<n-statistic label="注册量">
|
||||||
|
<n-number-animation
|
||||||
|
:from="0"
|
||||||
|
:to="12039"
|
||||||
|
show-separator
|
||||||
|
/>
|
||||||
|
</n-statistic>
|
||||||
|
<n-icon
|
||||||
|
color="#42218E"
|
||||||
|
size="42"
|
||||||
|
>
|
||||||
|
<icon-park-outline-chart-pie />
|
||||||
|
</n-icon>
|
||||||
|
</n-space>
|
||||||
|
<template #footer>
|
||||||
|
<n-space justify="space-between">
|
||||||
|
<span>累计注册量</span>
|
||||||
|
<span><n-number-animation
|
||||||
|
:from="0"
|
||||||
|
:to="322039"
|
||||||
|
show-separator
|
||||||
|
/></span>
|
||||||
|
</n-space>
|
||||||
|
</template>
|
||||||
|
</n-card>
|
||||||
|
</n-gi>
|
||||||
|
<!-- 图表区域 - 全宽显示 -->
|
||||||
|
<n-gi :span="12">
|
||||||
|
<n-card content-style="padding: 0;">
|
||||||
|
<n-tabs
|
||||||
|
type="line"
|
||||||
|
size="large"
|
||||||
|
:tabs-padding="20"
|
||||||
|
pane-style="padding: 20px;"
|
||||||
|
>
|
||||||
|
<n-tab-pane name="流量趋势">
|
||||||
|
<Chart />
|
||||||
|
</n-tab-pane>
|
||||||
|
<n-tab-pane name="访问量趋势">
|
||||||
|
<Chart2 />
|
||||||
|
</n-tab-pane>
|
||||||
|
</n-tabs>
|
||||||
|
</n-card>
|
||||||
|
</n-gi>
|
||||||
|
|
||||||
<style scoped></style>
|
<!-- 访问来源 - 移动端全宽,桌面端1/3宽 -->
|
||||||
|
<n-gi span="12 m:4">
|
||||||
|
<n-card
|
||||||
|
title="访问来源"
|
||||||
|
:segmented="{
|
||||||
|
content: true,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<Chart3 />
|
||||||
|
</n-card>
|
||||||
|
</n-gi>
|
||||||
|
|
||||||
|
<!-- 成交记录 - 移动端全宽,桌面端2/3宽 -->
|
||||||
|
<n-gi span="12 m:8">
|
||||||
|
<n-card
|
||||||
|
title="成交记录"
|
||||||
|
:segmented="{
|
||||||
|
content: true,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #header-extra>
|
||||||
|
<n-button
|
||||||
|
type="primary"
|
||||||
|
quaternary
|
||||||
|
>
|
||||||
|
更多
|
||||||
|
</n-button>
|
||||||
|
</template>
|
||||||
|
<n-table
|
||||||
|
:bordered="false"
|
||||||
|
:single-line="false"
|
||||||
|
:scroll-x="appStore.isMobile ? 600 : undefined"
|
||||||
|
>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>交易名称</th>
|
||||||
|
<th>开始时间</th>
|
||||||
|
<th>结束时间</th>
|
||||||
|
<th>进度</th>
|
||||||
|
<th>状态</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr
|
||||||
|
v-for="item in tableData"
|
||||||
|
:key="item.id"
|
||||||
|
>
|
||||||
|
<td>{{ item.name }}</td>
|
||||||
|
<td>{{ item.start }}</td>
|
||||||
|
<td>{{ item.end }}</td>
|
||||||
|
<td>{{ item.prograss }}%</td>
|
||||||
|
<td>
|
||||||
|
<n-tag
|
||||||
|
:bordered="false"
|
||||||
|
type="info"
|
||||||
|
>
|
||||||
|
{{ item.status }}
|
||||||
|
</n-tag>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</n-table>
|
||||||
|
</n-card>
|
||||||
|
</n-gi>
|
||||||
|
</n-grid>
|
||||||
|
</template>
|
||||||
|
@ -9,94 +9,102 @@ const { userInfo } = useAuthStore()
|
|||||||
<n-grid
|
<n-grid
|
||||||
:x-gap="16"
|
:x-gap="16"
|
||||||
:y-gap="16"
|
:y-gap="16"
|
||||||
|
:cols="3"
|
||||||
|
item-responsive
|
||||||
|
responsive="screen"
|
||||||
>
|
>
|
||||||
<n-gi :span="16">
|
<!-- 左侧主要内容区 - 移动端全宽,桌面端2/3宽 -->
|
||||||
|
<n-gi span="3 m:2">
|
||||||
<n-space
|
<n-space
|
||||||
vertical
|
vertical
|
||||||
:size="16"
|
:size="16"
|
||||||
>
|
>
|
||||||
|
<!-- 图表区域 -->
|
||||||
<n-card style="--n-padding-left: 0;">
|
<n-card style="--n-padding-left: 0;">
|
||||||
<Chart />
|
<Chart />
|
||||||
</n-card>
|
</n-card>
|
||||||
<n-card>
|
|
||||||
<n-grid
|
<!-- 统计卡片区域 -->
|
||||||
:x-gap="8"
|
<n-grid
|
||||||
:y-gap="8"
|
:x-gap="16"
|
||||||
>
|
:y-gap="16"
|
||||||
<n-gi :span="6">
|
:cols="4"
|
||||||
<n-card>
|
item-responsive
|
||||||
<n-thing>
|
responsive="screen"
|
||||||
<template #avatar>
|
>
|
||||||
<n-el>
|
<n-gi span="2 l:1">
|
||||||
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
<n-card>
|
||||||
<nova-icon :size="26" icon="icon-park-outline:user" />
|
<n-thing>
|
||||||
</n-icon-wrapper>
|
<template #avatar>
|
||||||
</n-el>
|
<n-el>
|
||||||
</template>
|
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
||||||
<template #header>
|
<nova-icon :size="26" icon="icon-park-outline:user" />
|
||||||
<n-statistic label="活跃用户">
|
</n-icon-wrapper>
|
||||||
<n-number-animation show-separator :from="0" :to="12039" />
|
</n-el>
|
||||||
</n-statistic>
|
</template>
|
||||||
</template>
|
<template #header>
|
||||||
</n-thing>
|
<n-statistic label="活跃用户">
|
||||||
</n-card>
|
<n-number-animation show-separator :from="0" :to="12039" />
|
||||||
</n-gi>
|
</n-statistic>
|
||||||
<n-gi :span="6">
|
</template>
|
||||||
<n-card>
|
</n-thing>
|
||||||
<n-thing>
|
</n-card>
|
||||||
<template #avatar>
|
</n-gi>
|
||||||
<n-el>
|
<n-gi span="2 l:1">
|
||||||
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
<n-card>
|
||||||
<nova-icon :size="26" icon="icon-park-outline:every-user" />
|
<n-thing>
|
||||||
</n-icon-wrapper>
|
<template #avatar>
|
||||||
</n-el>
|
<n-el>
|
||||||
</template>
|
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
||||||
<template #header>
|
<nova-icon :size="26" icon="icon-park-outline:every-user" />
|
||||||
<n-statistic label="用户">
|
</n-icon-wrapper>
|
||||||
<n-number-animation show-separator :from="0" :to="44039" />
|
</n-el>
|
||||||
</n-statistic>
|
</template>
|
||||||
</template>
|
<template #header>
|
||||||
</n-thing>
|
<n-statistic label="用户">
|
||||||
</n-card>
|
<n-number-animation show-separator :from="0" :to="44039" />
|
||||||
</n-gi>
|
</n-statistic>
|
||||||
<n-gi :span="6">
|
</template>
|
||||||
<n-card>
|
</n-thing>
|
||||||
<n-thing>
|
</n-card>
|
||||||
<template #avatar>
|
</n-gi>
|
||||||
<n-el>
|
<n-gi span="2 l:1">
|
||||||
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
<n-card>
|
||||||
<nova-icon :size="26" icon="icon-park-outline:preview-open" />
|
<n-thing>
|
||||||
</n-icon-wrapper>
|
<template #avatar>
|
||||||
</n-el>
|
<n-el>
|
||||||
</template>
|
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
||||||
<template #header>
|
<nova-icon :size="26" icon="icon-park-outline:preview-open" />
|
||||||
<n-statistic label="浏览量">
|
</n-icon-wrapper>
|
||||||
<n-number-animation show-separator :from="0" :to="551039" />
|
</n-el>
|
||||||
</n-statistic>
|
</template>
|
||||||
</template>
|
<template #header>
|
||||||
</n-thing>
|
<n-statistic label="浏览量">
|
||||||
</n-card>
|
<n-number-animation show-separator :from="0" :to="551039" />
|
||||||
</n-gi>
|
</n-statistic>
|
||||||
<n-gi :span="6">
|
</template>
|
||||||
<n-card>
|
</n-thing>
|
||||||
<n-thing>
|
</n-card>
|
||||||
<template #avatar>
|
</n-gi>
|
||||||
<n-el>
|
<n-gi span="2 l:1">
|
||||||
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
<n-card>
|
||||||
<nova-icon :size="26" icon="icon-park-outline:star" />
|
<n-thing>
|
||||||
</n-icon-wrapper>
|
<template #avatar>
|
||||||
</n-el>
|
<n-el>
|
||||||
</template>
|
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
||||||
<template #header>
|
<nova-icon :size="26" icon="icon-park-outline:star" />
|
||||||
<n-statistic label="收藏数">
|
</n-icon-wrapper>
|
||||||
<n-number-animation show-separator :from="0" :to="7739" />
|
</n-el>
|
||||||
</n-statistic>
|
</template>
|
||||||
</template>
|
<template #header>
|
||||||
</n-thing>
|
<n-statistic label="收藏数">
|
||||||
</n-card>
|
<n-number-animation show-separator :from="0" :to="7739" />
|
||||||
</n-gi>
|
</n-statistic>
|
||||||
</n-grid>
|
</template>
|
||||||
</n-card>
|
</n-thing>
|
||||||
|
</n-card>
|
||||||
|
</n-gi>
|
||||||
|
</n-grid>
|
||||||
<n-card title="动态">
|
<n-card title="动态">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-button
|
<n-button
|
||||||
@ -167,7 +175,9 @@ const { userInfo } = useAuthStore()
|
|||||||
</n-card>
|
</n-card>
|
||||||
</n-space>
|
</n-space>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
<n-gi :span="8">
|
|
||||||
|
<!-- 右侧边栏 - 移动端全宽,桌面端1/3宽 -->
|
||||||
|
<n-gi span="3 m:1">
|
||||||
<n-space
|
<n-space
|
||||||
vertical
|
vertical
|
||||||
:size="16"
|
:size="16"
|
||||||
@ -226,11 +236,14 @@ const { userInfo } = useAuthStore()
|
|||||||
</n-list-item>
|
</n-list-item>
|
||||||
</n-list>
|
</n-list>
|
||||||
</n-card>
|
</n-card>
|
||||||
|
<!-- 订单和待办统计 -->
|
||||||
<n-grid
|
<n-grid
|
||||||
:x-gap="8"
|
:x-gap="16"
|
||||||
:y-gap="8"
|
:y-gap="16"
|
||||||
|
:cols="2"
|
||||||
>
|
>
|
||||||
<n-gi :span="12">
|
<!-- 移动端和桌面端都是每行2个 -->
|
||||||
|
<n-gi :span="1">
|
||||||
<n-card>
|
<n-card>
|
||||||
<n-flex vertical align="center">
|
<n-flex vertical align="center">
|
||||||
<n-text depth="3">
|
<n-text depth="3">
|
||||||
@ -245,7 +258,7 @@ const { userInfo } = useAuthStore()
|
|||||||
</n-flex>
|
</n-flex>
|
||||||
</n-card>
|
</n-card>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
<n-gi :span="12">
|
<n-gi :span="1">
|
||||||
<n-card>
|
<n-card>
|
||||||
<n-flex vertical align="center">
|
<n-flex vertical align="center">
|
||||||
<n-text depth="3">
|
<n-text depth="3">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Login, Register, ResetPwd } from './components'
|
import { Login, Register, ResetPwd } from './components'
|
||||||
|
|
||||||
type IformType = 'login' | 'register' | 'resetPwd'
|
type IformType = 'login' | 'register' | 'resetPwd'
|
||||||
const formType: Ref<IformType> = ref('login')
|
const formType: Ref<IformType> = ref('login')
|
||||||
const formComponets = {
|
const formComponets = {
|
||||||
login: Login,
|
login: Login,
|
||||||
@ -18,7 +18,7 @@ const appName = import.meta.env.VITE_APP_NAME
|
|||||||
<DarkModeSwitch />
|
<DarkModeSwitch />
|
||||||
<LangsSwitch />
|
<LangsSwitch />
|
||||||
</div>
|
</div>
|
||||||
<n-el
|
<div
|
||||||
class="p-4xl h-full w-full sm:w-450px sm:h-unset"
|
class="p-4xl h-full w-full sm:w-450px sm:h-unset"
|
||||||
style="background: var(--card-color);box-shadow: var(--box-shadow-1);"
|
style="background: var(--card-color);box-shadow: var(--box-shadow-1);"
|
||||||
>
|
>
|
||||||
@ -36,7 +36,7 @@ const appName = import.meta.env.VITE_APP_NAME
|
|||||||
/>
|
/>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</n-el>
|
</div>
|
||||||
|
|
||||||
<div />
|
<div />
|
||||||
</n-el>
|
</n-el>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user