mirror of
https://github.com/chansee97/nova-admin.git
synced 2026-07-08 02:21:08 +08:00
Compare commits
2 Commits
1b4639d5d8
...
228ccaee5b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
228ccaee5b | ||
|
|
3144acbc39 |
42
package.json
42
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "nova-admin",
|
||||
"type": "module",
|
||||
"version": "0.9.17",
|
||||
"version": "0.9.18",
|
||||
"private": true,
|
||||
"description": "a clean and concise back-end management template based on Vue3, Vite5, Typescript, and Naive UI.",
|
||||
"author": {
|
||||
@ -50,43 +50,43 @@
|
||||
"sizecheck": "npx vite-bundle-visualizer"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vueuse/core": "^13.3.0",
|
||||
"alova": "^3.3.2",
|
||||
"@vueuse/core": "^13.6.0",
|
||||
"alova": "^3.3.4",
|
||||
"colord": "^2.9.3",
|
||||
"echarts": "^5.6.0",
|
||||
"md-editor-v3": "^5.6.1",
|
||||
"pinia": "^3.0.3",
|
||||
"pinia-plugin-persistedstate": "^4.3.0",
|
||||
"pinia-plugin-persistedstate": "^4.4.1",
|
||||
"pro-naive-ui": "^2.4.3",
|
||||
"quill": "^2.0.3",
|
||||
"radash": "^12.1.0",
|
||||
"vue": "^3.5.16",
|
||||
"radash": "^12.1.1",
|
||||
"vue": "^3.5.18",
|
||||
"vue-draggable-plus": "^0.6.0",
|
||||
"vue-i18n": "^11.1.5",
|
||||
"vue-i18n": "^11.1.11",
|
||||
"vue-router": "^4.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^4.14.1",
|
||||
"@antfu/eslint-config": "^5.0.0",
|
||||
"@iconify-json/icon-park-outline": "^1.2.2",
|
||||
"@iconify/vue": "^4.3.0",
|
||||
"@types/node": "^24.0.1",
|
||||
"@vitejs/plugin-vue": "^5.2.4",
|
||||
"@vitejs/plugin-vue-jsx": "^4.2.0",
|
||||
"@iconify/vue": "^5.0.0",
|
||||
"@types/node": "^24.1.0",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"@vitejs/plugin-vue-jsx": "^5.0.1",
|
||||
"eslint": "^9.29.0",
|
||||
"lint-staged": "^16.1.2",
|
||||
"naive-ui": "^2.41.1",
|
||||
"sass": "^1.86.3",
|
||||
"simple-git-hooks": "^2.13.0",
|
||||
"naive-ui": "^2.42.0",
|
||||
"sass": "^1.89.2",
|
||||
"simple-git-hooks": "^2.13.1",
|
||||
"typescript": "^5.8.3",
|
||||
"unocss": "^66.2.0",
|
||||
"unocss": "^66.3.3",
|
||||
"unplugin-auto-import": "^19.3.0",
|
||||
"unplugin-icons": "^22.1.0",
|
||||
"unplugin-vue-components": "^28.7.0",
|
||||
"vite": "^6.3.5",
|
||||
"unplugin-icons": "^22.2.0",
|
||||
"unplugin-vue-components": "^28.8.0",
|
||||
"vite": "^7.0.6",
|
||||
"vite-bundle-visualizer": "^1.2.1",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-vue-devtools": "7.7.6",
|
||||
"vue-tsc": "^2.2.10"
|
||||
"vite-plugin-vue-devtools": "8.0.0",
|
||||
"vue-tsc": "^3.0.5"
|
||||
},
|
||||
"simple-git-hooks": {
|
||||
"pre-commit": "pnpm lint-staged"
|
||||
|
||||
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">
|
||||
import { useBoolean } from '@/hooks'
|
||||
import { useRouteStore } from '@/store'
|
||||
import { useAppStore, useRouteStore } from '@/store'
|
||||
|
||||
const appStore = useAppStore()
|
||||
const routeStore = useRouteStore()
|
||||
|
||||
// 搜索值
|
||||
@ -143,13 +144,14 @@ function handleMouseEnter(index: number) {
|
||||
|
||||
<template>
|
||||
<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
|
||||
</n-tag>
|
||||
</CommonWrapper>
|
||||
<n-modal
|
||||
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"
|
||||
preset="card"
|
||||
:segmented="{
|
||||
|
||||
@ -2,6 +2,7 @@ import BackTop from './common/BackTop.vue'
|
||||
import Setting from './common/Setting.vue'
|
||||
import SettingDrawer from './common/SettingDrawer.vue'
|
||||
import Logo from './common/Logo.vue'
|
||||
import MobileDrawer from './common/MobileDrawer.vue'
|
||||
|
||||
import Breadcrumb from './header/Breadcrumb.vue'
|
||||
import CollapaseButton from './header/CollapaseButton.vue'
|
||||
@ -18,6 +19,7 @@ export {
|
||||
CollapaseButton,
|
||||
FullScreen,
|
||||
Logo,
|
||||
MobileDrawer,
|
||||
Notices,
|
||||
Search,
|
||||
Setting,
|
||||
|
||||
@ -20,7 +20,7 @@ function exitFullContent() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-tooltip placement="bottom" trigger="hover">
|
||||
<n-tooltip v-if="!appStore.isMobile" placement="bottom" trigger="hover">
|
||||
<template #trigger>
|
||||
<CommonWrapper @click="enterFullContent">
|
||||
<icon-park-outline-full-screen-one />
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
CollapaseButton,
|
||||
FullScreen,
|
||||
Logo,
|
||||
MobileDrawer,
|
||||
Notices,
|
||||
Search,
|
||||
Setting,
|
||||
@ -14,12 +15,12 @@ import {
|
||||
UserCenter,
|
||||
} from './components'
|
||||
import Content from './Content.vue'
|
||||
|
||||
import { ProLayout, useLayoutMenu } from 'pro-naive-ui'
|
||||
|
||||
const route = useRoute()
|
||||
const appStore = useAppStore()
|
||||
const routeStore = useRouteStore()
|
||||
|
||||
const { layoutMode } = storeToRefs(useAppStore())
|
||||
|
||||
const {
|
||||
@ -31,16 +32,19 @@ const {
|
||||
menus: routeStore.menus,
|
||||
})
|
||||
|
||||
watch(() => route.path, (value) => {
|
||||
watch(() => route.path, (value: string) => {
|
||||
activeKey.value = value
|
||||
}, { immediate: true })
|
||||
|
||||
// 移动端抽屉控制
|
||||
const showMobileDrawer = ref(false)
|
||||
|
||||
const sidebarWidth = ref(240)
|
||||
const sidebarCollapsedWidth = ref(64)
|
||||
|
||||
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>
|
||||
|
||||
<template>
|
||||
@ -48,7 +52,8 @@ const hidenCollapaseButton = computed(() => ['horizontal'].includes(layoutMode.v
|
||||
<ProLayout
|
||||
v-model:collapsed="appStore.collapsed"
|
||||
:mode="layoutMode"
|
||||
:show-logo="appStore.showLogo"
|
||||
:is-mobile="appStore.isMobile"
|
||||
:show-logo="appStore.showLogo && !appStore.isMobile"
|
||||
:show-footer="appStore.showFooter"
|
||||
:show-tabbar="appStore.showTabs"
|
||||
nav-fixed
|
||||
@ -79,13 +84,30 @@ const hidenCollapaseButton = computed(() => ['horizontal'].includes(layoutMode.v
|
||||
|
||||
<template #nav-right>
|
||||
<div class="h-full flex-y-center gap-1 p-x-xl">
|
||||
<Search />
|
||||
<Notices />
|
||||
<FullScreen />
|
||||
<DarkModeSwitch />
|
||||
<LangsSwitch />
|
||||
<Setting />
|
||||
<UserCenter />
|
||||
<!-- 移动端:只显示菜单按钮 -->
|
||||
<template v-if="appStore.isMobile">
|
||||
<n-button
|
||||
quaternary
|
||||
@click="showMobileDrawer = true"
|
||||
>
|
||||
<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>
|
||||
</template>
|
||||
|
||||
@ -111,5 +133,10 @@ const hidenCollapaseButton = computed(() => ['horizontal'].includes(layoutMode.v
|
||||
<Content />
|
||||
<BackTop />
|
||||
<SettingDrawer />
|
||||
|
||||
<!-- 移动端功能抽屉 -->
|
||||
<MobileDrawer v-model:show="showMobileDrawer">
|
||||
<n-menu v-bind="layout.verticalMenuProps" />
|
||||
</MobileDrawer>
|
||||
</ProLayout>
|
||||
</template>
|
||||
|
||||
@ -17,6 +17,8 @@ const { system, store } = useColorMode({
|
||||
emitAuto: true,
|
||||
})
|
||||
|
||||
const isMobile = useMediaQuery('(max-width: 700px)')
|
||||
|
||||
export const useAppStore = defineStore('app-store', {
|
||||
state: () => {
|
||||
return {
|
||||
@ -50,6 +52,9 @@ export const useAppStore = defineStore('app-store', {
|
||||
fullScreen() {
|
||||
return isFullscreen.value
|
||||
},
|
||||
isMobile() {
|
||||
return isMobile.value
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
// 重置所有设置
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { useAppStore } from '@/store'
|
||||
import Chart from './components/chart.vue'
|
||||
import Chart2 from './components/chart2.vue'
|
||||
import Chart3 from './components/chart3.vue'
|
||||
|
||||
const appStore = useAppStore()
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
id: 0,
|
||||
@ -32,218 +35,224 @@ const tableData = [
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<n-grid
|
||||
:x-gap="16"
|
||||
:y-gap="16"
|
||||
>
|
||||
<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="#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,
|
||||
}"
|
||||
<n-grid
|
||||
:x-gap="16"
|
||||
:y-gap="16"
|
||||
:cols="12"
|
||||
item-responsive
|
||||
responsive="screen"
|
||||
>
|
||||
<!-- 统计卡片 - 移动端每行2个,桌面端每行4个 -->
|
||||
<n-gi span="6 m:3">
|
||||
<n-card>
|
||||
<n-space
|
||||
justify="space-between"
|
||||
align="center"
|
||||
>
|
||||
<Chart3 />
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi :span="16">
|
||||
<n-card
|
||||
title="成交记录"
|
||||
:segmented="{
|
||||
content: true,
|
||||
}"
|
||||
>
|
||||
<template #header-extra>
|
||||
<n-button
|
||||
type="primary"
|
||||
quaternary
|
||||
>
|
||||
更多
|
||||
</n-button>
|
||||
</template>
|
||||
<n-table
|
||||
:bordered="false"
|
||||
:single-line="false"
|
||||
<n-statistic label="访问量">
|
||||
<n-number-animation
|
||||
:from="0"
|
||||
:to="12039"
|
||||
show-separator
|
||||
/>
|
||||
</n-statistic>
|
||||
<n-icon
|
||||
color="#de4307"
|
||||
size="42"
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
<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 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="#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 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
|
||||
:x-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
|
||||
vertical
|
||||
:size="16"
|
||||
>
|
||||
<!-- 图表区域 -->
|
||||
<n-card style="--n-padding-left: 0;">
|
||||
<Chart />
|
||||
</n-card>
|
||||
<n-card>
|
||||
<n-grid
|
||||
:x-gap="8"
|
||||
:y-gap="8"
|
||||
>
|
||||
<n-gi :span="6">
|
||||
<n-card>
|
||||
<n-thing>
|
||||
<template #avatar>
|
||||
<n-el>
|
||||
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
||||
<nova-icon :size="26" icon="icon-park-outline:user" />
|
||||
</n-icon-wrapper>
|
||||
</n-el>
|
||||
</template>
|
||||
<template #header>
|
||||
<n-statistic label="活跃用户">
|
||||
<n-number-animation show-separator :from="0" :to="12039" />
|
||||
</n-statistic>
|
||||
</template>
|
||||
</n-thing>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi :span="6">
|
||||
<n-card>
|
||||
<n-thing>
|
||||
<template #avatar>
|
||||
<n-el>
|
||||
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
||||
<nova-icon :size="26" icon="icon-park-outline:every-user" />
|
||||
</n-icon-wrapper>
|
||||
</n-el>
|
||||
</template>
|
||||
<template #header>
|
||||
<n-statistic label="用户">
|
||||
<n-number-animation show-separator :from="0" :to="44039" />
|
||||
</n-statistic>
|
||||
</template>
|
||||
</n-thing>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi :span="6">
|
||||
<n-card>
|
||||
<n-thing>
|
||||
<template #avatar>
|
||||
<n-el>
|
||||
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
||||
<nova-icon :size="26" icon="icon-park-outline:preview-open" />
|
||||
</n-icon-wrapper>
|
||||
</n-el>
|
||||
</template>
|
||||
<template #header>
|
||||
<n-statistic label="浏览量">
|
||||
<n-number-animation show-separator :from="0" :to="551039" />
|
||||
</n-statistic>
|
||||
</template>
|
||||
</n-thing>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi :span="6">
|
||||
<n-card>
|
||||
<n-thing>
|
||||
<template #avatar>
|
||||
<n-el>
|
||||
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
||||
<nova-icon :size="26" icon="icon-park-outline:star" />
|
||||
</n-icon-wrapper>
|
||||
</n-el>
|
||||
</template>
|
||||
<template #header>
|
||||
<n-statistic label="收藏数">
|
||||
<n-number-animation show-separator :from="0" :to="7739" />
|
||||
</n-statistic>
|
||||
</template>
|
||||
</n-thing>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
</n-card>
|
||||
|
||||
<!-- 统计卡片区域 -->
|
||||
<n-grid
|
||||
:x-gap="16"
|
||||
:y-gap="16"
|
||||
:cols="4"
|
||||
item-responsive
|
||||
responsive="screen"
|
||||
>
|
||||
<n-gi span="2 l:1">
|
||||
<n-card>
|
||||
<n-thing>
|
||||
<template #avatar>
|
||||
<n-el>
|
||||
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
||||
<nova-icon :size="26" icon="icon-park-outline:user" />
|
||||
</n-icon-wrapper>
|
||||
</n-el>
|
||||
</template>
|
||||
<template #header>
|
||||
<n-statistic label="活跃用户">
|
||||
<n-number-animation show-separator :from="0" :to="12039" />
|
||||
</n-statistic>
|
||||
</template>
|
||||
</n-thing>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi span="2 l:1">
|
||||
<n-card>
|
||||
<n-thing>
|
||||
<template #avatar>
|
||||
<n-el>
|
||||
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
||||
<nova-icon :size="26" icon="icon-park-outline:every-user" />
|
||||
</n-icon-wrapper>
|
||||
</n-el>
|
||||
</template>
|
||||
<template #header>
|
||||
<n-statistic label="用户">
|
||||
<n-number-animation show-separator :from="0" :to="44039" />
|
||||
</n-statistic>
|
||||
</template>
|
||||
</n-thing>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi span="2 l:1">
|
||||
<n-card>
|
||||
<n-thing>
|
||||
<template #avatar>
|
||||
<n-el>
|
||||
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
||||
<nova-icon :size="26" icon="icon-park-outline:preview-open" />
|
||||
</n-icon-wrapper>
|
||||
</n-el>
|
||||
</template>
|
||||
<template #header>
|
||||
<n-statistic label="浏览量">
|
||||
<n-number-animation show-separator :from="0" :to="551039" />
|
||||
</n-statistic>
|
||||
</template>
|
||||
</n-thing>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi span="2 l:1">
|
||||
<n-card>
|
||||
<n-thing>
|
||||
<template #avatar>
|
||||
<n-el>
|
||||
<n-icon-wrapper :size="46" color="var(--success-color)" :border-radius="999">
|
||||
<nova-icon :size="26" icon="icon-park-outline:star" />
|
||||
</n-icon-wrapper>
|
||||
</n-el>
|
||||
</template>
|
||||
<template #header>
|
||||
<n-statistic label="收藏数">
|
||||
<n-number-animation show-separator :from="0" :to="7739" />
|
||||
</n-statistic>
|
||||
</template>
|
||||
</n-thing>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
<n-card title="动态">
|
||||
<template #header-extra>
|
||||
<n-button
|
||||
@ -167,7 +175,9 @@ const { userInfo } = useAuthStore()
|
||||
</n-card>
|
||||
</n-space>
|
||||
</n-gi>
|
||||
<n-gi :span="8">
|
||||
|
||||
<!-- 右侧边栏 - 移动端全宽,桌面端1/3宽 -->
|
||||
<n-gi span="3 m:1">
|
||||
<n-space
|
||||
vertical
|
||||
:size="16"
|
||||
@ -226,11 +236,14 @@ const { userInfo } = useAuthStore()
|
||||
</n-list-item>
|
||||
</n-list>
|
||||
</n-card>
|
||||
<!-- 订单和待办统计 -->
|
||||
<n-grid
|
||||
:x-gap="8"
|
||||
:y-gap="8"
|
||||
:x-gap="16"
|
||||
:y-gap="16"
|
||||
:cols="2"
|
||||
>
|
||||
<n-gi :span="12">
|
||||
<!-- 移动端和桌面端都是每行2个 -->
|
||||
<n-gi :span="1">
|
||||
<n-card>
|
||||
<n-flex vertical align="center">
|
||||
<n-text depth="3">
|
||||
@ -245,7 +258,7 @@ const { userInfo } = useAuthStore()
|
||||
</n-flex>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi :span="12">
|
||||
<n-gi :span="1">
|
||||
<n-card>
|
||||
<n-flex vertical align="center">
|
||||
<n-text depth="3">
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { Login, Register, ResetPwd } from './components'
|
||||
|
||||
type IformType = 'login' | 'register' | 'resetPwd'
|
||||
type IformType = 'login' | 'register' | 'resetPwd'
|
||||
const formType: Ref<IformType> = ref('login')
|
||||
const formComponets = {
|
||||
login: Login,
|
||||
@ -18,7 +18,7 @@ const appName = import.meta.env.VITE_APP_NAME
|
||||
<DarkModeSwitch />
|
||||
<LangsSwitch />
|
||||
</div>
|
||||
<n-el
|
||||
<div
|
||||
class="p-4xl h-full w-full sm:w-450px sm:h-unset"
|
||||
style="background: var(--card-color);box-shadow: var(--box-shadow-1);"
|
||||
>
|
||||
@ -36,7 +36,7 @@ const appName = import.meta.env.VITE_APP_NAME
|
||||
/>
|
||||
</transition>
|
||||
</div>
|
||||
</n-el>
|
||||
</div>
|
||||
|
||||
<div />
|
||||
</n-el>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user