diff --git a/index.html b/index.html
index 11603f8..0c18c48 100644
--- a/index.html
+++ b/index.html
@@ -1,5 +1,5 @@
-
+
diff --git a/package.json b/package.json
index 008d81d..5b12744 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
"dependencies": {
"axios": "^0.22.0",
"element-plus": "^1.1.0-beta.19",
+ "moment": "^2.29.1",
"unplugin-element-plus": "^0.1.0",
"vue": "^3.2.16",
"vue-axios": "^3.3.7",
diff --git a/src/App.vue b/src/App.vue
index 3e6b30b..4263498 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,16 +1,22 @@
-
+
+
+
diff --git a/src/config/menu.ts b/src/config/menu.ts
index b42d87e..89df1f4 100644
--- a/src/config/menu.ts
+++ b/src/config/menu.ts
@@ -4,29 +4,29 @@ export default [
title: '系统管理',
icon: 'el-icon-s-operation',
child: [
- { title: '系统配置', path: '/system/config', icon: 'md-settings' },
- { title: '用户管理', path: '/system/user', icon: 'md-contact' },
- { title: '角色管理', path: '/system/role', icon: 'md-contacts' },
- { title: '博客文章', path: '/system/article', icon: 'md-paper' },
- { title: '分析统计', path: '/system/statistics', icon: 'md-pie' }
+ { title: '系统配置', path: '/system/config' },
+ { title: '用户管理', path: '/system/user' },
+ { title: '角色管理', path: '/system/role' },
+ { title: '博客文章', path: '/system/article' },
+ { title: '分析统计', path: '/system/statistics' }
]
},{
name: 'api',
title: 'API数据',
icon: 'el-icon-s-data',
child: [
- { title: '一言', path: '/api/hitokoto', icon: 'md-chatbubbles' },
- { title: '照片墙', path: '/api/photoWall', icon: 'md-images' },
- { title: '图片资源库', path: '/api/sourceImage', icon: 'md-image' },
- { title: '中国行政区划', path: '/api/chinaProvince', icon: 'md-map' },
- { title: '歌曲库', path: '/api/music', icon: 'md-musical-note' }
+ { title: '一言', path: '/api/hitokoto' },
+ { title: '照片墙', path: '/api/photoWall' },
+ { title: '图片资源库', path: '/api/sourceImage' },
+ { title: '中国行政区划', path: '/api/chinaProvince' },
+ { title: '歌曲库', path: '/api/music' }
]
},{
name: 'tool',
title: '工具',
icon: 'el-icon-s-tools',
child: [
- { title: 'SQL占位符替换', path: '/tool/sqlReplace', icon: 'md-copy' }
+ { title: 'SQL占位符替换', path: '/tool/sqlReplace' }
]
}
]
\ No newline at end of file
diff --git a/src/env.d.ts b/src/env.d.ts
index eb4b22b..d27eb5a 100644
--- a/src/env.d.ts
+++ b/src/env.d.ts
@@ -1,7 +1,7 @@
///
declare module '*.vue' {
- import { DefineComponent, ComponentCustomProperties } from 'vue'
+ import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
diff --git a/src/main.ts b/src/main.ts
index 2126736..b6b3e3d 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -10,14 +10,15 @@ const service = axios.create({
timeout: 10000
})
-import { ElMessage } from 'element-plus'
+import { ElMessage, ElLoading } from 'element-plus'
// 添加请求拦截器
service.interceptors.request.use(config => {
// 在发送请求之前添加token到请求头
- // if (localStorage.getItem('login_token')) {
- // config.headers.token = localStorage.getItem('login_token')
- // }
+ const token = localStorage.getItem('login_token')
+ if (token !== null && config.headers) {
+ config.headers.token = token
+ }
return config
}, err => {
// 请求错误的处理
@@ -45,7 +46,7 @@ service.interceptors.response.use(res=> {
})
// 全局路由导航前置守卫
-router.beforeEach(function (to, from, next: Function) {
+router.beforeEach(function (to, from, next) {
app.$store.commit('setBreadcrumb', routePathes[to.path] || [])
if(filterExclude.indexOf(to.path) !== -1 || localStorage.getItem('login_token')) {
next()
@@ -58,4 +59,5 @@ const app = createApp(App)
.use(router)
.use(store)
.use(VueAxios, service)
+ .directive('loading', ElLoading.directive)
.mount('#app')
diff --git a/src/model/api/hitokoto.ts b/src/model/api/hitokoto.ts
new file mode 100644
index 0000000..225828d
--- /dev/null
+++ b/src/model/api/hitokoto.ts
@@ -0,0 +1,9 @@
+export default interface HitokotoModel {
+ _id: string
+ hitokoto: string
+ type: string
+ from: string
+ creator: string
+ created_at: Date
+ number: number
+}
\ No newline at end of file
diff --git a/src/model/api/music.ts b/src/model/api/music.ts
new file mode 100644
index 0000000..6b225a0
--- /dev/null
+++ b/src/model/api/music.ts
@@ -0,0 +1,35 @@
+export interface MusicModel {
+ _id: string
+ name: string // 文件名
+ ext: string // 扩展名
+ md5?: string // md5哈希值
+ size: number // 文件大小
+ title?: string // 标题
+ album?: string // 唱片集
+ artist?: string // 艺术家
+ lib_id: string // 歌单ID
+ lyric_id: string // 歌词ID
+}
+
+export interface MusicLibModel {
+ _id: string
+ name: string // 歌单名称
+ path: string // 歌单文件路径
+}
+
+export interface MusicLyricModel {
+ _id?: string
+ cloud_id?: number
+ name?: string
+ lyric?: string
+}
+
+export interface MusicPlayerItem {
+ id: number
+ name: string
+ artist: string
+ album: string
+ url: string
+ cover: string
+ lrc: string | undefined
+}
\ No newline at end of file
diff --git a/src/model/api/photowall.ts b/src/model/api/photowall.ts
new file mode 100644
index 0000000..6b6ce86
--- /dev/null
+++ b/src/model/api/photowall.ts
@@ -0,0 +1,9 @@
+export default interface PhotoWallModel {
+ _id: string
+ name: string // 图片文件名
+ md5: string // 文件md5哈希值
+ thumbnail: string // 缩略图名称
+ width: number // 宽度
+ height: number // 高度
+ index: number // 序号
+}
\ No newline at end of file
diff --git a/src/model/api/source-image.ts b/src/model/api/source-image.ts
new file mode 100644
index 0000000..aea6477
--- /dev/null
+++ b/src/model/api/source-image.ts
@@ -0,0 +1,17 @@
+export interface SourceImageModel {
+ _id: string
+ mime: string // MIME类型
+ hash: string // 图片md5值
+ size: number // 图片大小
+ label: string[] // 图片标签
+ img: ArrayBuffer // 图片二进制数据
+ created_at: Date
+}
+
+/**
+ * 图片标签
+ */
+export interface ImageLabel {
+ name: string // 标签名称
+ color: string // 标签颜色
+}
\ No newline at end of file
diff --git a/src/model/baselist.ts b/src/model/baselist.ts
new file mode 100644
index 0000000..7b5fd3d
--- /dev/null
+++ b/src/model/baselist.ts
@@ -0,0 +1,65 @@
+import { Vue } from 'vue-class-component'
+import { Page } from './common.dto'
+import moment from 'moment'
+
+export default abstract class BaseList extends Vue {
+ /**
+ * 表格数据加载中
+ */
+ protected loading: boolean = false
+ /**
+ * 表单提交中
+ */
+ protected modalLoading: boolean = true
+ /**
+ * 数据总数
+ */
+ protected total: number = 0
+ protected abstract search: T
+ /**
+ * 加载数据的实现
+ */
+ abstract loadData(): Promise
+ /**
+ * 加载数据
+ * @param resetPage 是否重置页码
+ */
+ loadDataBase(resetPage: boolean = false): void {
+ if(resetPage) {
+ this.search.pageNum = 1
+ }
+ this.loadData()
+ }
+ /**
+ * 重置搜索项
+ */
+ reset() {
+ this.search.reset()
+ this.loadData()
+ }
+ /**
+ * 页码变更
+ * @param pageNum 页码
+ */
+ pageChange(pageNum: number) {
+ this.search.pageNum = pageNum
+ this.loadData()
+ }
+
+ /**
+ * 每页数据条数变更
+ * @param pageSize 每页数据条数
+ */
+ pageSizeChange(pageSize: number) {
+ this.search.limit = pageSize
+ this.loadData()
+ }
+
+ /**
+ * 日期时间格式化
+ * @param dateStr 日期时间
+ */
+ datetimeFormat(dateStr: string) {
+ return moment(dateStr).format('YYYY-MM-DD HH:mm:ss')
+ }
+}
\ No newline at end of file
diff --git a/src/model/common.dto.ts b/src/model/common.dto.ts
new file mode 100644
index 0000000..9581242
--- /dev/null
+++ b/src/model/common.dto.ts
@@ -0,0 +1,21 @@
+export interface MsgResult {
+ status: boolean
+ message: string
+}
+
+/**
+ * 分页查询基础类
+ */
+export class Page {
+ // 页码
+ pageNum: number = 1
+ // 每页数据条数
+ limit: number = 10
+ /**
+ * 重置分页
+ */
+ public reset() {
+ this.pageNum = 1
+ this.limit = 10
+ }
+}
\ No newline at end of file
diff --git a/src/model/system/article.ts b/src/model/system/article.ts
new file mode 100644
index 0000000..8d781c8
--- /dev/null
+++ b/src/model/system/article.ts
@@ -0,0 +1,34 @@
+// import { CreateElement, VNode } from 'vue'
+
+export interface ArticleModel {
+ _id: string
+ path: string[] // 访问路径
+ categories: string[] //分类
+ tags: string[] // 标签
+ title: string // 标题
+ create_date: Date // 文章发布日期
+ content_len: number // 正文长度
+ is_splited: boolean // 是否分词
+}
+
+export interface TreeNodeBase {
+ name: string | null // 节点名称(ID)
+ deep: number // 节点深度(根节点为0)
+}
+
+export interface TreeNode extends TreeNodeBase {
+ expand: boolean // 是否展开
+ id?: string // 文章ID
+ title: string //显示的文字
+ children?: TreeNode[] // 子节点
+ loading?: boolean // 是否显示加载中
+ nodeKey?: number // 树节点唯一标识
+ isDirectory: boolean // 该节点是否为目录
+ // render?: (h: CreateElement, {data}: {data: TreeNode}) => Array
+}
+
+export interface TreeNodeSource {
+ _id: string
+ cnt: number
+ article_id: string | null
+}
\ No newline at end of file
diff --git a/src/model/system/system-config.ts b/src/model/system/system-config.ts
new file mode 100644
index 0000000..fbde539
--- /dev/null
+++ b/src/model/system/system-config.ts
@@ -0,0 +1,9 @@
+export interface SystemConfigModel {
+ _id?: string
+ name: string // 配置项名称
+ value: object | string // 配置项内容
+ description: string // 描述
+ is_public: boolean // 是否公开
+ created_at?: Date // 创建时间
+ updated_at?: Date // 更新时间
+}
\ No newline at end of file
diff --git a/src/model/system/system-role.ts b/src/model/system/system-role.ts
new file mode 100644
index 0000000..39a9a54
--- /dev/null
+++ b/src/model/system/system-role.ts
@@ -0,0 +1,10 @@
+export interface SystemRoleModel {
+ _id: string | null
+ name: string | null // 角色名称
+ description: string | null // 描述
+ methods: string[] // 允许的请求类型(优先级3)
+ include_uri: string[] // 包含的URI(优先级2)
+ exclude_uri: string[] // 排除的URI(优先级1)
+ created_at?: Date // 创建时间
+ updated_at?: Date // 更新时间
+}
\ No newline at end of file
diff --git a/src/model/system/system-user.ts b/src/model/system/system-user.ts
new file mode 100644
index 0000000..d2cebfc
--- /dev/null
+++ b/src/model/system/system-user.ts
@@ -0,0 +1,9 @@
+export interface SystemUserModel {
+ _id: string | null
+ username: string | null
+ password: string | null
+ realname: string | null
+ role_ids: string[]
+ created_at?: Date
+ updated_at?: Date
+}
\ No newline at end of file
diff --git a/src/router.ts b/src/router.ts
index 1ed98a2..7ab0021 100644
--- a/src/router.ts
+++ b/src/router.ts
@@ -2,11 +2,16 @@ import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import Login from './views/Login.vue'
import Home from './views/Home.vue'
-// import Welcome from '@/views/Welcome.vue'
-
+import Welcome from './views/Welcome.vue'
+import SystemUser from './views/system/SystemUser.vue'
+import SystemRole from './views/system/SystemRole.vue'
const routes: Array = [
{ path: '/login', name: 'Login', component: Login },
- { path: '/', name: 'Home', component: Home, children: []}
+ { path: '/', name: 'Home', component: Home, children: [
+ { path: '/', name: 'Welcome', component: Welcome },
+ { path: '/system/user', name: 'SystemUser', component: SystemUser },
+ { path: '/system/role', name: 'SystemRole', component: SystemRole },
+ ]}
]
export const router = createRouter({
diff --git a/src/static/common.less b/src/static/common.less
index bb0aaef..9e5364e 100644
--- a/src/static/common.less
+++ b/src/static/common.less
@@ -41,16 +41,11 @@ html,body,#app,.layout {
color: #9ea7b4;
}
}
-.search-title {
- line-height: 32px;
- text-align: right;
- padding-right: 5px;
-}
.table-container {
position: relative;
}
.btn-container {
- padding: 10px 0;
+ margin-bottom: 10px;
button {
margin-right: 3px;
}
diff --git a/src/types.ts b/src/types.ts
deleted file mode 100644
index 76cc4e6..0000000
--- a/src/types.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export type VForm = Vue & {
- validate: (callback: (valid: boolean) => void) => void
- resetValidation: () => boolean
- reset: () => void
-}
\ No newline at end of file
diff --git a/src/views/Home.vue b/src/views/Home.vue
index 2df7b33..79516b4 100644
--- a/src/views/Home.vue
+++ b/src/views/Home.vue
@@ -51,6 +51,7 @@
\ No newline at end of file
diff --git a/src/views/system/SystemRole.vue b/src/views/system/SystemRole.vue
new file mode 100644
index 0000000..0d6e216
--- /dev/null
+++ b/src/views/system/SystemRole.vue
@@ -0,0 +1,212 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{method}}
+
+
+
+
+ {{ datetimeFormat(scope.row.created_at) }}
+
+
+
+
+ {{ datetimeFormat(scope.row.updated_at) }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GET
+ POST
+ PUT
+ DELETE
+
+
+
+
+
+
+
+
+ {{uri}}
+
+
+
+
+
+
+
+ {{uri}}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/system/SystemUser.vue b/src/views/system/SystemUser.vue
new file mode 100644
index 0000000..e69de29
diff --git a/src/vuex.d.ts b/src/vuex.d.ts
new file mode 100644
index 0000000..b7528a4
--- /dev/null
+++ b/src/vuex.d.ts
@@ -0,0 +1,10 @@
+import { ComponentCustomProperties } from 'vue'
+import { Store } from 'vuex'
+import { StateType } from './store/types'
+
+declare module '@vue/runtime-core' {
+ // provide typings for `this.$store`
+ interface ComponentCustomProperties {
+ $store: Store
+ }
+}
\ No newline at end of file
diff --git a/vite.config.ts b/vite.config.ts
index 524a6ba..bb0fa03 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -21,6 +21,6 @@ export default defineConfig({
build: {
outDir: 'dist',
assetsDir: 'assets', // 静态资源的存放路径, 相对于outDir
- cssCodeSplit: true
+ cssCodeSplit: true // 是否拆分css
}
})
diff --git a/yarn.lock b/yarn.lock
index fd3ebb7..19c6adb 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -663,6 +663,11 @@ mime@^1.4.1:
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
+moment@^2.29.1:
+ version "2.29.1"
+ resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
+ integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
+
ms@^2.1.1:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
@@ -1068,9 +1073,9 @@ vscode-uri@^3.0.2:
integrity sha512-jkjy6pjU1fxUvI51P+gCsxg1u2n8LSt0W6KrCNQceaziKzff74GoWmjVG46KieVzybO1sttPQmYfrwSHey7GUA==
vscode-vue-languageservice@^0.27.0:
- version "0.27.27"
- resolved "https://registry.yarnpkg.com/vscode-vue-languageservice/-/vscode-vue-languageservice-0.27.27.tgz#abaf6190768d30e317d24220c76e96c0c7d31751"
- integrity sha512-q5vaaTxQpsqr4O2h2A5zXQtK17ZHKdrcjv6gZaItTBcI4rxw6GIHoblYsNXMo+dhBZEmFmyI18iPn+a7RajFEQ==
+ version "0.27.28"
+ resolved "https://registry.yarnpkg.com/vscode-vue-languageservice/-/vscode-vue-languageservice-0.27.28.tgz#97f537cf8d9be80f835b440de49a6a3d492d5b3d"
+ integrity sha512-dkYufKL/kchAxIxz2mYJDwsQuc7wnjTY+vc+sVz/DkFWfPEK0VaOStuKc85UME6VJ2IJzGEN1LHERGM65u8deQ==
dependencies:
"@volar/code-gen" "^0.27.24"
"@volar/html2pug" "^0.27.13"