diff --git a/package-lock.json b/package-lock.json index ef6bdfa..a7012ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@wangeditor/editor": "^5.1.23", "@wangeditor/editor-for-vue": "^5.1.12", "axios": "^1.6.8", + "chart.js": "^4.4.6", "countup.js": "^2.8.0", "cropperjs": "^1.6.1", "echarts": "^5.5.0", @@ -23,6 +24,7 @@ "js-table2excel": "^1.1.2", "jsplumb": "^2.15.6", "mitt": "^3.0.1", + "mockjs": "^1.1.0", "nprogress": "^0.2.0", "pinia": "^2.1.7", "print-js": "^1.6.0", @@ -39,6 +41,8 @@ "vue-router": "^4.3.0" }, "devDependencies": { + "@types/chart.js": "^2.9.41", + "@types/mockjs": "^1.0.10", "@types/node": "^20.11.28", "@types/nprogress": "^0.2.3", "@types/sortablejs": "^1.15.8", @@ -412,6 +416,11 @@ "version": "1.4.15", "license": "MIT" }, + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmmirror.com/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -472,6 +481,15 @@ "version": "0.0.7", "license": "MIT" }, + "node_modules/@types/chart.js": { + "version": "2.9.41", + "resolved": "https://registry.npmmirror.com/@types/chart.js/-/chart.js-2.9.41.tgz", + "integrity": "sha512-3dvkDvueckY83UyUXtJMalYoH6faOLkWQoaTlJgB4Djde3oORmNP0Jw85HtzTuXyliUHcdp704s0mZFQKio/KQ==", + "dev": true, + "dependencies": { + "moment": "^2.10.2" + } + }, "node_modules/@types/estree": { "version": "1.0.5", "dev": true, @@ -497,6 +515,12 @@ "@types/lodash": "*" } }, + "node_modules/@types/mockjs": { + "version": "1.0.10", + "resolved": "https://registry.npmmirror.com/@types/mockjs/-/mockjs-1.0.10.tgz", + "integrity": "sha512-SXgrhajHG7boLv6oU93CcmdDm0HYRiceuz6b+7z+/2lCJPTWDv0V5YiwFHT2ejE4bQqgSXQiVPQYPWv7LGsK1g==", + "dev": true + }, "node_modules/@types/node": { "version": "20.11.28", "dev": true, @@ -1245,6 +1269,17 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chart.js": { + "version": "4.4.6", + "resolved": "https://registry.npmmirror.com/chart.js/-/chart.js-4.4.6.tgz", + "integrity": "sha512-8Y406zevUPbbIBA/HRk33khEmQPk5+cxeflWE/2rx1NJsjVWMPw/9mSP9rxHP5eqi6LNoPBVMfZHxbwLSgldYA==", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/chokidar": { "version": "3.5.3", "dev": true, @@ -1359,6 +1394,14 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmmirror.com/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "engines": { + "node": ">=18" + } + }, "node_modules/compute-scroll-into-view": { "version": "1.0.20", "license": "MIT" @@ -2538,6 +2581,26 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mockjs": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/mockjs/-/mockjs-1.1.0.tgz", + "integrity": "sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==", + "dependencies": { + "commander": "*" + }, + "bin": { + "random": "bin/random" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.2", "dev": true, diff --git a/package.json b/package.json index 554989b..69d9952 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@wangeditor/editor": "^5.1.23", "@wangeditor/editor-for-vue": "^5.1.12", "axios": "^1.6.8", + "chart.js": "^4.4.6", "countup.js": "^2.8.0", "cropperjs": "^1.6.1", "echarts": "^5.5.0", @@ -24,6 +25,7 @@ "js-table2excel": "^1.1.2", "jsplumb": "^2.15.6", "mitt": "^3.0.1", + "mockjs": "^1.1.0", "nprogress": "^0.2.0", "pinia": "^2.1.7", "print-js": "^1.6.0", @@ -40,6 +42,8 @@ "vue-router": "^4.3.0" }, "devDependencies": { + "@types/chart.js": "^2.9.41", + "@types/mockjs": "^1.0.10", "@types/node": "^20.11.28", "@types/nprogress": "^0.2.3", "@types/sortablejs": "^1.15.8", diff --git a/src/api/mock/index.ts b/src/api/mock/index.ts new file mode 100644 index 0000000..3209170 --- /dev/null +++ b/src/api/mock/index.ts @@ -0,0 +1,39 @@ +// src/api/mock/index.ts +import { Random } from 'mockjs'; + +interface StatisticsData { + todayVisits: number; + newUsers: number; + currentMonthSales: number; + currentMonthOrders: number; +} + +interface YearlySalesData { + monthlySales: number[]; +} + +// 模拟统计数据接口 +export const getStatisticsData = async (): Promise => { + return new Promise((resolve) => { + // 模拟 API 延迟 + setTimeout(() => { + resolve({ + todayVisits: Random.integer(500, 1500), + newUsers: Random.integer(20, 100), + currentMonthSales: Random.integer(3000, 15000), + currentMonthOrders: Random.integer(100, 500), + }); + }, 1000); + }); +}; + +// 模拟年度销售数据接口 +export const getYearlySalesData = async (): Promise => { + return new Promise((resolve) => { + // 模拟 API 延迟 + setTimeout(() => { + const monthlySales = Array.from({ length: 12 }, () => Random.integer(5000, 20000)); + resolve({ monthlySales }); + }, 1000); + }); +}; diff --git a/src/i18n/lang/en.ts b/src/i18n/lang/en.ts index 8aaf6c5..dd58fb4 100644 --- a/src/i18n/lang/en.ts +++ b/src/i18n/lang/en.ts @@ -13,6 +13,7 @@ export default { article: 'article', message: 'message', order: 'order', + statistics: 'statistics', articleDetail: 'articleDetail', addArticle: 'addArticle', editArticle: 'editArticle', diff --git a/src/i18n/lang/zh-cn.ts b/src/i18n/lang/zh-cn.ts index 0b603ba..1552702 100644 --- a/src/i18n/lang/zh-cn.ts +++ b/src/i18n/lang/zh-cn.ts @@ -13,6 +13,7 @@ export default { article: '文章管理', message: '留言管理', order: '订单管理', + statistics: '统计分析', articleDetail: '文章详情', addArticle: '新增文章', editArticle: '编辑文章', diff --git a/src/i18n/lang/zh-tw.ts b/src/i18n/lang/zh-tw.ts index eca98f1..31483d0 100644 --- a/src/i18n/lang/zh-tw.ts +++ b/src/i18n/lang/zh-tw.ts @@ -13,6 +13,7 @@ export default { article: '文章管理', message: '聯言管理', order: '訂單管理', + statistics: '統計分析', articleDetail: '文章詳情', addArticle: '文章新增', editArticle: '文章編輯', diff --git a/src/router/route.ts b/src/router/route.ts index 9555dfe..8e32e4c 100644 --- a/src/router/route.ts +++ b/src/router/route.ts @@ -117,7 +117,7 @@ export const dynamicRoutes: Array = [ isLink: '', isHide: false, isKeepAlive: true, - isAffix: false, + isAffix: false, isIframe: false, roles: ['admin'], icon: 'iconfont icon-icon-', @@ -295,6 +295,21 @@ export const dynamicRoutes: Array = [ icon: 'iconfont icon-shuju', }, }, + { + path: '/statistics', + name: 'statistics', + component: () => import('/@/views/statistics/index.vue'), + meta: { + title: 'message.router.statistics', + isLink: '', + isHide: false, + isKeepAlive: true, + isAffix: false, + isIframe: false, + roles: ['admin', 'common'], + icon: 'iconfont icon-ico_shuju', + }, + }, { path: '/video', name: 'video', diff --git a/src/types/chartjs.d.ts b/src/types/chartjs.d.ts new file mode 100644 index 0000000..7c60267 --- /dev/null +++ b/src/types/chartjs.d.ts @@ -0,0 +1 @@ +declare module 'chart.js'; diff --git a/src/views/statistics/index.vue b/src/views/statistics/index.vue new file mode 100644 index 0000000..12f435c --- /dev/null +++ b/src/views/statistics/index.vue @@ -0,0 +1,118 @@ + + + + +