Compare commits

..

No commits in common. "a0e49ceda6bcd42d1b754ea172babd2a2e82d96e" and "9131148bc187f4f0e62601af332d01dac3b2f91d" have entirely different histories.

21 changed files with 123 additions and 123 deletions

View File

@ -4,6 +4,6 @@ export default interface HitokotoModel {
type: string type: string
from: string from: string
creator: string creator: string
createdAt: Date created_at: Date
number: number number: number
} }

View File

@ -7,8 +7,8 @@ export interface MusicModel {
title?: string // 标题 title?: string // 标题
album?: string // 唱片集 album?: string // 唱片集
artist?: string // 艺术家 artist?: string // 艺术家
libId: string // 歌单ID lib_id: string // 歌单ID
lyricId: string // 歌词ID lyric_id: string // 歌词ID
isEditing?: boolean // 是否正在编辑当前行 isEditing?: boolean // 是否正在编辑当前行
} }
@ -20,7 +20,7 @@ export interface MusicLibModel {
export interface MusicLyricModel { export interface MusicLyricModel {
_id?: string _id?: string
cloudId?: number cloud_id?: number
name?: string name?: string
lyric?: string lyric?: string
} }

View File

@ -5,5 +5,5 @@ export interface SourceImageModel {
size: number // 图片大小 size: number // 图片大小
label: string[] // 图片标签 label: string[] // 图片标签
img: ArrayBuffer // 图片二进制数据 img: ArrayBuffer // 图片二进制数据
createdAt: Date created_at: Date
} }

View File

@ -6,9 +6,9 @@ export interface ArticleModel {
categories: string[] //分类 categories: string[] //分类
tags: string[] // 标签 tags: string[] // 标签
title: string // 标题 title: string // 标题
createDate: Date // 文章发布日期 create_date: Date // 文章发布日期
contentLen: number // 正文长度 content_len: number // 正文长度
isSplited: boolean // 是否分词 is_splited: boolean // 是否分词
} }
export interface TreeNodeData { export interface TreeNodeData {
@ -22,5 +22,5 @@ export interface TreeNodeData {
export interface TreeNodeSource { export interface TreeNodeSource {
_id: string _id: string
cnt: number cnt: number
articleId: string | null article_id: string | null
} }

View File

@ -3,7 +3,7 @@ export interface SystemConfigModel {
name: string // 配置项名称 name: string // 配置项名称
value: object | string // 配置项内容 value: object | string // 配置项内容
description: string // 描述 description: string // 描述
isPublic: boolean // 是否公开 is_public: boolean // 是否公开
createdAt?: Date // 创建时间 created_at?: Date // 创建时间
updatedAt?: Date // 更新时间 updated_at?: Date // 更新时间
} }

View File

@ -3,8 +3,8 @@ export interface SystemRoleModel {
name: string | null // 角色名称 name: string | null // 角色名称
description: string | null // 描述 description: string | null // 描述
methods: string[] // 允许的请求类型(优先级3) methods: string[] // 允许的请求类型(优先级3)
includeUri: string[] // 包含的URI(优先级2) include_uri: string[] // 包含的URI(优先级2)
excludeUri: string[] // 排除的URI(优先级1) exclude_uri: string[] // 排除的URI(优先级1)
createdAt?: Date // 创建时间 created_at?: Date // 创建时间
updatedAt?: Date // 更新时间 updated_at?: Date // 更新时间
} }

View File

@ -3,7 +3,7 @@ export interface SystemUserModel {
username: string | null username: string | null
password: string | null password: string | null
realname: string | null realname: string | null
roleIds: string[] role_ids: string[]
createdAt?: Date created_at?: Date
updatedAt?: Date updated_at?: Date
} }

View File

@ -164,7 +164,7 @@ html, body, #app, .layout {
} }
/* ===== 表单弹窗 ===== */ /* ===== 表单弹窗 ===== */
body .el-dialog { .el-dialog {
// CSS 变量覆盖:圆角、清除 element-plus 2.x 新增的根元素 padding // CSS 变量覆盖:圆角、清除 element-plus 2.x 新增的根元素 padding
--el-dialog-border-radius: 12px; --el-dialog-border-radius: 12px;
--el-dialog-padding-primary: 0; --el-dialog-padding-primary: 0;

View File

@ -2,7 +2,7 @@ export interface UserInfo {
_id: string _id: string
username: string // 用户名 username: string // 用户名
realname: string // 昵称 realname: string // 昵称
roleIds: string[] // 角色ID role_ids: string[] // 角色ID
} }
export interface TabItem { export interface TabItem {

View File

@ -90,7 +90,7 @@ if (defaultActiveMenuKey.value) {
if (!store.state.loginInfo.token) { if (!store.state.loginInfo.token) {
router.push('/login') router.push('/login')
} else { } else {
http.post<{token: string}, any>('/api/v2/common/verifyToken', {token: store.state.loginInfo.token}).then(data => { http.post<{token: string}, any>('/api/v1/common/verifyToken', {token: store.state.loginInfo.token}).then(data => {
if (data.status) { if (data.status) {
store.commit('login', {token: data.newToken || store.state.loginInfo.token, userInfo: data.userInfo}) store.commit('login', {token: data.newToken || store.state.loginInfo.token, userInfo: data.userInfo})
} else { } else {

View File

@ -81,7 +81,7 @@ async function login() {
loginForm.value?.validate(async (valid: boolean) => { loginForm.value?.validate(async (valid: boolean) => {
if (!valid) return if (!valid) return
loading.value = true loading.value = true
const data = await http.post<UserInfo, any>('/api/v2/common/login', userInfo).finally(() => { const data = await http.post<UserInfo, any>('/api/v1/common/login', userInfo).finally(() => {
loading.value = false loading.value = false
}) })
if (data.token) { if (data.token) {

View File

@ -38,9 +38,9 @@
<el-table-column prop="from" label="来自" width="180"/> <el-table-column prop="from" label="来自" width="180"/>
<el-table-column prop="creator" label="作者" width="180"/> <el-table-column prop="creator" label="作者" width="180"/>
<el-table-column prop="number" label="编号" width="70"/> <el-table-column prop="number" label="编号" width="70"/>
<el-table-column prop="createdAt" label="创建时间" width="180"> <el-table-column prop="created_at" label="创建时间" width="180">
<template #default="scope"> <template #default="scope">
{{ datetimeFormat(scope.row.createdAt) }} {{ datetimeFormat(scope.row.created_at) }}
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -101,7 +101,7 @@ let selectedData: string[] = []
async function loadData() { async function loadData() {
loading.value = true loading.value = true
const data = await http.get<HitokotoPage, any>('/api/v2/hitokoto/list', {params: search}) const data = await http.get<HitokotoPage, any>('/api/v1/hitokoto/list', {params: search})
selectedData = [] selectedData = []
loading.value = false loading.value = false
total.value = data.total total.value = data.total
@ -113,7 +113,7 @@ async function save() {
addForm.value?.hitokotoForm?.validate(async (valid: boolean) => { addForm.value?.hitokotoForm?.validate(async (valid: boolean) => {
if (!valid) return if (!valid) return
modalLoading.value = true modalLoading.value = true
const data = await http.post<any, any>('/api/v2/hitokoto/save', formData) const data = await http.post<any, any>('/api/v1/hitokoto/save', formData)
modalLoading.value = false modalLoading.value = false
addModal.value = false addModal.value = false
ElMessage.success(data.message) ElMessage.success(data.message)
@ -127,7 +127,7 @@ function deleteAll() {
return return
} }
ElMessageBox.confirm(`是否确认删除选中的${selectedData.length}条数据?`, '确认删除', {type: 'warning'}).then(async () => { ElMessageBox.confirm(`是否确认删除选中的${selectedData.length}条数据?`, '确认删除', {type: 'warning'}).then(async () => {
const data = await http.delete<any, any>('/api/v2/hitokoto/delete', {params: {_ids: selectedData}}) const data = await http.delete<any, any>('/api/v1/hitokoto/delete', {params: {_ids: selectedData}})
ElMessage.success(data.message) ElMessage.success(data.message)
loadData() loadData()
}).catch(() => {}) }).catch(() => {})
@ -142,7 +142,7 @@ function findTypeText(value: string): string | null {
// created // created
loadData() loadData()
http.get<never, any>('/api/v2/common/config/hitokoto_type').then(data => { http.get<never, any>('/api/v1/common/config/hitokoto_type').then(data => {
typeList.value = data typeList.value = data
}) })
</script> </script>

View File

@ -5,7 +5,7 @@
<el-input v-model="search.name" /> <el-input v-model="search.name" />
</el-form-item> </el-form-item>
<el-form-item label="所属歌单"> <el-form-item label="所属歌单">
<el-select v-model="search.libId" multiple collapse-tags> <el-select v-model="search.lib_id" multiple collapse-tags>
<el-option v-for="musicLib in musicLibs" :key="musicLib._id" :value="musicLib._id" :label="musicLib.name" /> <el-option v-for="musicLib in musicLibs" :key="musicLib._id" :value="musicLib._id" :label="musicLib.name" />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -45,25 +45,25 @@
<el-table-column prop="title" label="标题" show-overflow-tooltip /> <el-table-column prop="title" label="标题" show-overflow-tooltip />
<el-table-column prop="album" label="唱片集" /> <el-table-column prop="album" label="唱片集" />
<el-table-column prop="artist" label="艺术家" /> <el-table-column prop="artist" label="艺术家" />
<el-table-column prop="libId" label="所属歌单" > <el-table-column prop="lib_id" label="所属歌单" >
<template #default="scope"> <template #default="scope">
<template v-if="scope.row.isEditing && currentRow"> <template v-if="scope.row.isEditing && currentRow">
<el-select v-model="currentRow.libId"> <el-select v-model="currentRow.lib_id">
<el-option v-for="musicLib in musicLibs" :key="musicLib._id" :value="musicLib._id" :label="musicLib.name" /> <el-option v-for="musicLib in musicLibs" :key="musicLib._id" :value="musicLib._id" :label="musicLib.name" />
</el-select> </el-select>
<el-button link icon="Check" type="primary" @click="saveMusicLib(scope.row)"></el-button> <el-button link icon="Check" type="primary" @click="saveMusicLib(scope.row)"></el-button>
<el-button link icon="Close" type="primary" @click="scope.row.isEditing = false"></el-button> <el-button link icon="Close" type="primary" @click="scope.row.isEditing = false"></el-button>
</template> </template>
<template v-else> <template v-else>
{{ findMusicLib(scope.row.libId) }} {{ findMusicLib(scope.row.lib_id) }}
<el-button link icon="Edit" type="primary" @click="updateLib(scope.row)"></el-button> <el-button link icon="Edit" type="primary" @click="updateLib(scope.row)"></el-button>
</template> </template>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="lyricId" label="歌词" width="120" > <el-table-column prop="lyric_id" label="歌词" width="120" >
<template #default="scope"> <template #default="scope">
<div style="width: 18px"> <div style="width: 18px">
<Check v-if="scope.row.lyricId" /> <Check v-if="scope.row.lyric_id" />
<Close v-else/> <Close v-else/>
</div> </div>
</template> </template>
@ -89,8 +89,8 @@
</div> </div>
<el-dialog v-model="modifyLyricModal" title="编辑歌词" :width="600" > <el-dialog v-model="modifyLyricModal" title="编辑歌词" :width="600" >
<el-form ref="lyricForm" :model="lyricFormData" :rules="lyricRuleValidate" :label-width="120"> <el-form ref="lyricForm" :model="lyricFormData" :rules="lyricRuleValidate" :label-width="120">
<el-form-item label="网易云ID" prop="cloudId"> <el-form-item label="网易云ID" prop="cloud_id">
<el-input v-model="lyricFormData.cloudId" /> <el-input v-model="lyricFormData.cloud_id" />
</el-form-item> </el-form-item>
<el-form-item label="名称" prop="name"> <el-form-item label="名称" prop="name">
<el-input v-model="lyricFormData.name" /> <el-input v-model="lyricFormData.name" />
@ -166,7 +166,7 @@ class MusicPage extends Page {
title?: string title?: string
album?: string album?: string
artist?: string artist?: string
libId?: string[] = [] lib_id?: string[] = []
reset() { reset() {
super.reset() super.reset()
this.name = undefined this.name = undefined
@ -174,7 +174,7 @@ class MusicPage extends Page {
this.title = undefined this.title = undefined
this.album = undefined this.album = undefined
this.artist = undefined this.artist = undefined
this.libId = [] this.lib_id = []
} }
} }
@ -197,7 +197,7 @@ const musicUpload = ref<UploadInstance>()
const player = ref<any>() const player = ref<any>()
const lyricRuleValidate = { const lyricRuleValidate = {
cloudId: [ cloud_id: [
{ required: true, message: '请输入网易云ID', trigger: 'blur' } { required: true, message: '请输入网易云ID', trigger: 'blur' }
], ],
name: [ name: [
@ -212,7 +212,7 @@ let selectedIds: string[] = []
async function loadData() { async function loadData() {
loading.value = true loading.value = true
const data = await http.get<MusicPage, any>('/api/v2/music/list', {params: search}) const data = await http.get<MusicPage, any>('/api/v1/music/list', {params: search})
selectedIds = [] selectedIds = []
loading.value = false loading.value = false
total.value = data.total total.value = data.total
@ -229,7 +229,7 @@ function findMusicLib(value: string): string | null {
} }
async function playMusic() { async function playMusic() {
try { try {
const data = await http.get<any, any>('/api/v2/music/list/all', {params: selectedIds.length ? {ids: selectedIds} : search}) const data = await http.get<any, any>('/api/v1/music/list/all', {params: selectedIds.length ? {ids: selectedIds} : search})
musicList.value = data.map((item: MusicModel, index: number) => { musicList.value = data.map((item: MusicModel, index: number) => {
const musicItem: MusicPlayerItem = { const musicItem: MusicPlayerItem = {
id: index, id: index,
@ -239,8 +239,8 @@ async function playMusic() {
src: `/api/v2/common/music/load/${item._id}`, src: `/api/v2/common/music/load/${item._id}`,
pic: `/api/v2/common/music/album/${item._id}`, pic: `/api/v2/common/music/album/${item._id}`,
} }
if (item.lyricId) { if (item.lyric_id) {
musicItem.lrc = `${location.origin}/api/v2/common/music/lyric/${item.lyricId}` musicItem.lrc = `${location.origin}/api/v2/common/music/lyric/${item.lyric_id}`
} }
return musicItem return musicItem
}) })
@ -272,9 +272,9 @@ function remove(row: MusicModel) {
async function updateLyric(row: MusicModel) { async function updateLyric(row: MusicModel) {
currentRow.value = { ...row } currentRow.value = { ...row }
modifyLyricModal.value = true modifyLyricModal.value = true
if (row.lyricId) { if (row.lyric_id) {
const data = (await http.get<any, any>('/api/v2/music/lyric/get', {params: {lyricId: row.lyricId}})) const data = (await http.get<any, any>('/api/v1/music/lyric/get', {params: {lyricId: row.lyric_id}}))
data.cloudId = data.cloudId ? data.cloudId.toString() : null data.cloud_id = data.cloud_id ? data.cloud_id.toString() : null
lyricFormData.value = data lyricFormData.value = data
} else { } else {
lyricFormData.value = {} lyricFormData.value = {}
@ -284,7 +284,7 @@ async function saveLyric() {
lyricForm.value?.validate(async (valid: boolean) => { lyricForm.value?.validate(async (valid: boolean) => {
if (!valid) return if (!valid) return
modalLoading.value = true modalLoading.value = true
const data = await http.post<MusicLyricModel, any>(`/api/v2/music/lyric/save?musicId=${currentRow.value ? currentRow.value._id : ''}`, lyricFormData.value) const data = await http.post<MusicLyricModel, any>(`/api/v1/music/lyric/save?musicId=${currentRow.value ? currentRow.value._id : ''}`, lyricFormData.value)
modalLoading.value = false modalLoading.value = false
modifyLyricModal.value = false modifyLyricModal.value = false
ElMessage.success(data.message) ElMessage.success(data.message)
@ -294,9 +294,9 @@ async function saveLyric() {
} }
async function saveMusicLib(row: MusicModel) { async function saveMusicLib(row: MusicModel) {
if (!currentRow.value) return if (!currentRow.value) return
const data = await http.post<{id: string, libId: string}, any>('/api/v2/music/updateLib', {id: currentRow.value._id, libId: currentRow.value.libId}) const data = await http.post<{id: string, libId: string}, any>('/api/v2/music/updateLib', {id: currentRow.value._id, libId: currentRow.value.lib_id})
ElMessage.success(data.message) ElMessage.success(data.message)
row.libId = currentRow.value.libId row.lib_id = currentRow.value.lib_id
row.isEditing = false row.isEditing = false
} }
function openUploadModal() { function openUploadModal() {
@ -356,11 +356,11 @@ function musicPlay() {
} }
// created // created
http.get<never, any>('/api/v2/music/listLibs').then(data => { http.get<never, any>('/api/v1/music/listLibs').then(data => {
musicLibs.value = data musicLibs.value = data
loadData() loadData()
}) })
http.get<never, any>('/api/v2/music/listExts').then(data => { http.get<never, any>('/api/v1/music/listExts').then(data => {
exts.value = data exts.value = data
}) })
</script> </script>

View File

@ -113,7 +113,7 @@ let selectedData: string[] = []
async function loadData() { async function loadData() {
loading.value = true loading.value = true
const data = await http.get<PhotoWallPage, any>('/api/v2/photoWall/list', {params: search}) const data = await http.get<PhotoWallPage, any>('/api/v1/photowall/list', {params: search})
selectedData = [] selectedData = []
loading.value = false loading.value = false
total.value = data.total total.value = data.total
@ -127,7 +127,7 @@ function deleteAll() {
return return
} }
ElMessageBox.confirm(`是否确认删除选中的${selectedData.length}条数据?`, '确认删除', {type: 'warning'}).then(async () => { ElMessageBox.confirm(`是否确认删除选中的${selectedData.length}条数据?`, '确认删除', {type: 'warning'}).then(async () => {
await http.delete('/api/v2/photoWall/delete', {params: {_ids: selectedData}}) await http.delete('/api/v1/photowall/delete', {params: {_ids: selectedData}})
ElMessage.success('删除成功') ElMessage.success('删除成功')
loadData() loadData()
}).catch(() => {}) }).catch(() => {})
@ -158,7 +158,7 @@ function uploadError(error: Error) {
} }
async function preview(row: PhotoWallModel) { async function preview(row: PhotoWallModel) {
const previewHeight = Math.floor(row.height * (500 / row.width)) const previewHeight = Math.floor(row.height * (500 / row.width))
const pictureCdn = await http.get('/api/v2/common/config/picture_cdn') const pictureCdn = await http.get('/api/v1/common/config/picture_cdn')
ElMessageBox({ ElMessageBox({
title: '图片预览', title: '图片预览',
message: h('img', { style: `width:500px;height:${previewHeight}px;`, src: `${pictureCdn}/${row.name}` }, ''), message: h('img', { style: `width:500px;height:${previewHeight}px;`, src: `${pictureCdn}/${row.name}` }, ''),

View File

@ -35,9 +35,9 @@
<el-tag v-for="label in scope.row.label" :key="label" effect="plain">{{label}}</el-tag> <el-tag v-for="label in scope.row.label" :key="label" effect="plain">{{label}}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createdAt" label="上传时间" > <el-table-column prop="created_at" label="上传时间" >
<template #default="scope"> <template #default="scope">
{{ datetimeFormat(scope.row.createdAt) }} {{ datetimeFormat(scope.row.created_at) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" > <el-table-column label="操作" >
@ -108,7 +108,7 @@ let selectedData: string[] = []
async function loadData(): Promise<void> { async function loadData(): Promise<void> {
loading.value = true loading.value = true
const data = await http.get<Page, any>('/api/v2/source-image/list', {params: search}) const data = await http.get<Page, any>('/api/v1/source-image/list', {params: search})
selectedData = [] selectedData = []
loading.value = false loading.value = false
total.value = data.total total.value = data.total
@ -122,7 +122,7 @@ function deleteAll(): void {
return return
} }
ElMessageBox.confirm(`是否确认删除选中的${selectedData.length}条数据?`, '确认删除', {type: 'warning'}).then(async () => { ElMessageBox.confirm(`是否确认删除选中的${selectedData.length}条数据?`, '确认删除', {type: 'warning'}).then(async () => {
await http.delete('/api/v2/source-image/delete', {params: {_ids: selectedData}}) await http.delete('/api/v1/source-image/delete', {params: {_ids: selectedData}})
ElMessage.success('删除成功') ElMessage.success('删除成功')
loadData() loadData()
}).catch(() => {}) }).catch(() => {})
@ -154,7 +154,7 @@ function uploadError(error: Error): void {
function preview(row: SourceImageModel): void { function preview(row: SourceImageModel): void {
ElMessageBox({ ElMessageBox({
title: '图片预览', title: '图片预览',
message: h('img', { style: `width:500px`, src: `/api/v2/common/randomBg?id=${row._id}` }, ''), message: h('img', { style: `width:500px`, src: `/api/v1/common/randomBg?id=${row._id}` }, ''),
showCancelButton: false, showCancelButton: false,
confirmButtonText: '关闭', confirmButtonText: '关闭',
customStyle: {width: '530px', maxWidth: 'unset'} customStyle: {width: '530px', maxWidth: 'unset'}
@ -169,11 +169,11 @@ function modifyTags(item: SourceImageModel): void {
modifyModal.value = true modifyModal.value = true
} }
async function tarnsferChange(newTargetKeys: string[], direction: 'right' | 'left', moveKeys: string[]) { async function tarnsferChange(newTargetKeys: string[], direction: 'right' | 'left', moveKeys: string[]) {
await http.post('/api/v2/source-image/updateLabel', {id: curId.value, labels: newTargetKeys}) await http.post('/api/v1/source-image/updateLabel', {id: curId.value, labels: newTargetKeys})
} }
// created // created
http.get<never, any>('/api/v2/common/config/image_label').then(data => { http.get<never, any>('/api/v1/common/config/image_label').then(data => {
labelList.value.push(...data) labelList.value.push(...data)
loadData() loadData()
}) })

View File

@ -76,16 +76,16 @@
{{ typeof scope.row.tags === 'string' ? scope.row.tags : scope.row.tags?.join('') }} {{ typeof scope.row.tags === 'string' ? scope.row.tags : scope.row.tags?.join('') }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="contentLen" label="正文长度" width="100" /> <el-table-column prop="content_len" label="正文长度" width="100" />
<el-table-column prop="createDate" label="创建时间" width="180" > <el-table-column prop="create_date" label="创建时间" width="180" >
<template #default="scope"> <template #default="scope">
{{ datetimeFormat(scope.row.createDate) }} {{ datetimeFormat(scope.row.create_date) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="tags" label="是否已分词" width="120" > <el-table-column prop="tags" label="是否已分词" width="120" >
<template #default="scope"> <template #default="scope">
<div style="width: 18px"> <div style="width: 18px">
<Check v-if="scope.row.isSplited" /> <Check v-if="scope.row.is_splited" />
<Close v-else/> <Close v-else/>
</div> </div>
</template> </template>
@ -161,7 +161,7 @@ let selectedData: string[] = []
async function loadData() { async function loadData() {
loading.value = true loading.value = true
const data = await http.get<ArticlePage, any>('/api/v2/article/list', {params: search}) const data = await http.get<ArticlePage, any>('/api/v1/article/list', {params: search})
selectedData = [] selectedData = []
loading.value = false loading.value = false
total.value = data.total total.value = data.total
@ -175,7 +175,7 @@ function splitWord() {
return return
} }
ElMessageBox.confirm(`是否确认对选中的${selectedData.length}篇文章执行分词处理?`, '操作确认', {type: 'info'}).then(async () => { ElMessageBox.confirm(`是否确认对选中的${selectedData.length}篇文章执行分词处理?`, '操作确认', {type: 'info'}).then(async () => {
const data = await http.put<{_ids: string[]}, any>('/api/v2/article/splitWord', {_ids: selectedData}) const data = await http.put<{_ids: string[]}, any>('/api/v1/article/splitWord', {_ids: selectedData})
if (data.status) { if (data.status) {
ElMessage.success(data.message) ElMessage.success(data.message)
} else { } else {
@ -185,7 +185,7 @@ function splitWord() {
} }
function pullArticles() { function pullArticles() {
ElMessageBox.confirm('确认拉取全部文章?', '操作确认', {type: 'info'}).then(async () => { ElMessageBox.confirm('确认拉取全部文章?', '操作确认', {type: 'info'}).then(async () => {
const data = await http.put<never, any>('/api/v2/article/pull') const data = await http.put<never, any>('/api/v1/article/pull')
if (data.status) { if (data.status) {
ElMessage.success(data.message) ElMessage.success(data.message)
loadData() loadData()
@ -220,20 +220,20 @@ const treeProps = {
isLeaf: 'isLeaf', isLeaf: 'isLeaf',
} }
async function loadTreeData(node: Node, resolve: Function) { async function loadTreeData(node: Node, resolve: Function) {
const childItems: TreeNodeSource[] = await http.get('/api/v2/article/tree', {params: {deep: node.level, parent: node.data.name}}) const childItems: TreeNodeSource[] = await http.get('/api/v1/article/tree', {params: {deep: node.level, parent: node.data.name}})
resolve(childItems.map((childItem): TreeNodeData => { resolve(childItems.map((childItem): TreeNodeData => {
const treeNode: TreeNodeData = { const treeNode: TreeNodeData = {
name: childItem._id, name: childItem._id,
title: childItem.articleId ? childItem._id : `${childItem._id}(${childItem.cnt})`, title: childItem.article_id ? childItem._id : `${childItem._id}(${childItem.cnt})`,
id: childItem.articleId || childItem._id, id: childItem.article_id || childItem._id,
isLeaf: !!childItem.articleId isLeaf: !!childItem.article_id
} }
return treeNode return treeNode
})) }))
} }
async function articlePreview(node: TreeNodeData) { async function articlePreview(node: TreeNodeData) {
if (!node.isLeaf) return if (!node.isLeaf) return
const mdText = await http.get<never, any>('/api/v2/article/markdown', {params: {id: node.id}}) const mdText = await http.get<never, any>('/api/v1/article/markdown', {params: {id: node.id}})
markdownPreview.show = true markdownPreview.show = true
const markdownHtml = new hyperdown().makeHtml(mdText) const markdownHtml = new hyperdown().makeHtml(mdText)
markdownPreview.content = markdownHtml.replace(/(?<=<pre><code[^>]*?>)[\s\S]*?(?=<\/code><\/pre>)/gi, (content: string) => { markdownPreview.content = markdownHtml.replace(/(?<=<pre><code[^>]*?>)[\s\S]*?(?=<\/code><\/pre>)/gi, (content: string) => {
@ -244,10 +244,10 @@ async function articlePreview(node: TreeNodeData) {
// created // created
loadData() loadData()
http.get<never, any>('/api/v2/article/listCategories').then(data => { http.get<never, any>('/api/v1/article/listCategories').then(data => {
categories.value = data categories.value = data
}) })
http.get<never, any>('/api/v2/article/listTags').then(data => { http.get<never, any>('/api/v1/article/listTags').then(data => {
tags.value = data tags.value = data
}) })
</script> </script>

View File

@ -370,7 +370,7 @@ onMounted(async () => {
timelineWordsChartLoading.value = true timelineWordsChartLoading.value = true
// //
const articleData = await http.get<{params:{type:string}}, any>('/api/v2/article/statistics', {params: {type: 'normal'}}) const articleData = await http.get<{params:{type:string}}, any>('/api/v1/article/statistics', {params: {type: 'normal'}})
// //
totalArticles.value = articleData.categories.reduce((sum: number, item: any) => sum + item.cnt, 0) totalArticles.value = articleData.categories.reduce((sum: number, item: any) => sum + item.cnt, 0)
@ -397,7 +397,7 @@ onMounted(async () => {
publishDatesChartLoading.value = false publishDatesChartLoading.value = false
// //
const timelineData = await http.get<{params:{type:string}}, any>('/api/v2/article/statistics', {params: {type: 'timelineWords'}}) const timelineData = await http.get<{params:{type:string}}, any>('/api/v1/article/statistics', {params: {type: 'timelineWords'}})
if (timelineData.timelineWords.length > 0 && timelineData.timelineWords[0].keys.length > 0) { if (timelineData.timelineWords.length > 0 && timelineData.timelineWords[0].keys.length > 0) {
topKeyword.value = timelineData.timelineWords[0].keys[0].key topKeyword.value = timelineData.timelineWords[0].keys[0].key

View File

@ -21,19 +21,19 @@
</el-table-column> </el-table-column>
<el-table-column prop="name" label="配置项名称" /> <el-table-column prop="name" label="配置项名称" />
<el-table-column prop="description" label="配置项描述" /> <el-table-column prop="description" label="配置项描述" />
<el-table-column prop="isPublic" label="是否公开" > <el-table-column prop="is_public" label="是否公开" >
<template #default="scope"> <template #default="scope">
{{ scope.row.isPublic ? '是' : '否' }} {{ scope.row.is_public ? '是' : '否' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createdAt" label="创建时间" > <el-table-column prop="created_at" label="创建时间" >
<template #default="scope"> <template #default="scope">
{{ datetimeFormat(scope.row.createdAt) }} {{ datetimeFormat(scope.row.created_at) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="updatedAt" label="更新时间" > <el-table-column prop="updated_at" label="更新时间" >
<template #default="scope"> <template #default="scope">
{{ datetimeFormat(scope.row.updatedAt) }} {{ datetimeFormat(scope.row.updated_at) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" > <el-table-column label="操作" >
@ -73,7 +73,7 @@ const formData = ref<SystemConfigModel>({
name: '', name: '',
value: '', value: '',
description: '', description: '',
isPublic: false is_public: false
}) })
const addForm = ref<InstanceType<typeof SystemConfigAdd>>() const addForm = ref<InstanceType<typeof SystemConfigAdd>>()
@ -85,7 +85,7 @@ function reset() {
async function loadData() { async function loadData() {
loading.value = true loading.value = true
systemConfigData.value = await http.get('/api/v2/system/config/list', {params: search.value}) systemConfigData.value = await http.get('/api/v1/system/config/list', {params: search.value})
loading.value = false loading.value = false
} }
@ -94,7 +94,7 @@ function add() {
name: '', name: '',
value: '', value: '',
description: '', description: '',
isPublic: false is_public: false
} }
modalTitle.value = '新增配置项' modalTitle.value = '新增配置项'
addModal.value = true addModal.value = true
@ -112,7 +112,7 @@ async function save() {
addForm.value?.configForm?.validate(async (valid: boolean) => { addForm.value?.configForm?.validate(async (valid: boolean) => {
if (!valid) return if (!valid) return
modalLoading.value = true modalLoading.value = true
const data = await http.post<SystemConfigModel, any>('/api/v2/system/config/save', formData.value) const data = await http.post<SystemConfigModel, any>('/api/v1/system/config/save', formData.value)
modalLoading.value = false modalLoading.value = false
addModal.value = false addModal.value = false
ElMessage.success(data.message) ElMessage.success(data.message)
@ -122,7 +122,7 @@ async function save() {
function remove(row: SystemConfigModel) { function remove(row: SystemConfigModel) {
ElMessageBox.confirm(`是否确认删除 ${row.name} 配置项?`, '确认删除', {type: 'warning'}).then(async () => { ElMessageBox.confirm(`是否确认删除 ${row.name} 配置项?`, '确认删除', {type: 'warning'}).then(async () => {
const data = await http.delete<{params: {id: string}}, any>('/api/v2/system/config/delete', {params: {id: row._id}}) const data = await http.delete<{params: {id: string}}, any>('/api/v1/system/config/delete', {params: {id: row._id}})
if(data.status) { if(data.status) {
ElMessage.success(data.message) ElMessage.success(data.message)
loadData() loadData()

View File

@ -12,7 +12,7 @@
</el-form-item> </el-form-item>
<el-form-item label="公开"> <el-form-item label="公开">
<el-switch <el-switch
v-model="formData.isPublic" v-model="formData.is_public"
active-text="是" active-text="是"
inactive-text="否" /> inactive-text="否" />
</el-form-item> </el-form-item>
@ -35,7 +35,7 @@ const ruleValidate = computed(() => ({
name: [ name: [
{ required: true, message: '请输入配置项名称', trigger: 'blur' }, { required: true, message: '请输入配置项名称', trigger: 'blur' },
{ validator: (rule: object, value: string, callback: Function) => { { validator: (rule: object, value: string, callback: Function) => {
http.get<any, any>('/api/v2/system/config/exists', {params: {name: value, id: props.formData._id}}).then(data => { http.get<any, any>('/api/v1/system/config/exists', {params: {name: value, id: props.formData._id}}).then(data => {
if(data.data.exists) { if(data.data.exists) {
callback(new Error('配置项名称已存在')) callback(new Error('配置项名称已存在'))
} else { } else {

View File

@ -20,14 +20,14 @@
<el-tag type="info" v-for="method in scope.row.methods" :key="method">{{method}}</el-tag> <el-tag type="info" v-for="method in scope.row.methods" :key="method">{{method}}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createdAt" label="创建时间" > <el-table-column prop="created_at" label="创建时间" >
<template #default="scope"> <template #default="scope">
{{ datetimeFormat(scope.row.createdAt) }} {{ datetimeFormat(scope.row.created_at) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="updatedAt" label="更新时间" > <el-table-column prop="updated_at" label="更新时间" >
<template #default="scope"> <template #default="scope">
{{ datetimeFormat(scope.row.updatedAt) }} {{ datetimeFormat(scope.row.updated_at) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" > <el-table-column label="操作" >
@ -67,18 +67,18 @@
<el-form-item label="允许的URI"> <el-form-item label="允许的URI">
<el-input v-model="uri.include"> <el-input v-model="uri.include">
<template #append> <template #append>
<el-button icon="Plus" @click="addUri('includeUri', uri.include)"></el-button> <el-button icon="Plus" @click="addUri('include_uri', uri.include)"></el-button>
</template> </template>
</el-input> </el-input>
<el-tag v-for="uri in formData.includeUri" :key="uri" closable @close="removeUri('includeUri', uri)">{{uri}}</el-tag> <el-tag v-for="uri in formData.include_uri" :key="uri" closable @close="removeUri('include_uri', uri)">{{uri}}</el-tag>
</el-form-item> </el-form-item>
<el-form-item label="禁止的URI"> <el-form-item label="禁止的URI">
<el-input v-model="uri.exclude"> <el-input v-model="uri.exclude">
<template #append> <template #append>
<el-button icon="Plus" @click="addUri('excludeUri', uri.exclude)"></el-button> <el-button icon="Plus" @click="addUri('exclude_uri', uri.exclude)"></el-button>
</template> </template>
</el-input> </el-input>
<el-tag v-for="uri in formData.excludeUri" :key="uri" closable @close="removeUri('excludeUri', uri)">{{uri}}</el-tag> <el-tag v-for="uri in formData.exclude_uri" :key="uri" closable @close="removeUri('exclude_uri', uri)">{{uri}}</el-tag>
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
@ -133,14 +133,14 @@ const formData = reactive<SystemRoleModel>({
name: null, name: null,
description: null, description: null,
methods: [], methods: [],
includeUri: [], include_uri: [],
excludeUri: [] exclude_uri: []
}) })
const roleForm = ref<VForm>() const roleForm = ref<VForm>()
async function loadData() { async function loadData() {
loading.value = true loading.value = true
const data = await http.get<{params: SystemRolePage}, any>('/api/v2/system/role/list', {params: search}) const data = await http.get<{params: SystemRolePage}, any>('/api/v1/system/role/list', {params: search})
loading.value = false loading.value = false
total.value = data.total total.value = data.total
systemRoleData.value = data.data systemRoleData.value = data.data
@ -155,22 +155,22 @@ function add() {
name: null, name: null,
description: null, description: null,
methods: [], methods: [],
includeUri: [], include_uri: [],
excludeUri: [] exclude_uri: []
}) })
modalTitle.value = '新增角色' modalTitle.value = '新增角色'
addModal.value = true addModal.value = true
clearValidate() clearValidate()
} }
function addUri(fieldName: 'includeUri' | 'excludeUri', uriValue: string | null) { function addUri(fieldName: 'include_uri' | 'exclude_uri', uriValue: string | null) {
if(!uriValue) return if(!uriValue) return
if(formData[fieldName].indexOf(uriValue) === -1) { if(formData[fieldName].indexOf(uriValue) === -1) {
formData[fieldName].push(uriValue) formData[fieldName].push(uriValue)
} }
} }
function removeUri(fieldName: 'includeUri' | 'excludeUri', uriValue: string) { function removeUri(fieldName: 'include_uri' | 'exclude_uri', uriValue: string) {
let index = formData[fieldName].indexOf(uriValue) let index = formData[fieldName].indexOf(uriValue)
if(index !== -1) { if(index !== -1) {
formData[fieldName].splice(index, 1) formData[fieldName].splice(index, 1)
@ -185,8 +185,8 @@ function update(row: SystemRoleModel) {
name: row.name, name: row.name,
description: row.description, description: row.description,
methods: row.methods, methods: row.methods,
includeUri: row.includeUri, include_uri: row.include_uri,
excludeUri: row.excludeUri exclude_uri: row.exclude_uri
}) })
modalTitle.value = '修改角色' modalTitle.value = '修改角色'
addModal.value = true addModal.value = true
@ -195,7 +195,7 @@ function update(row: SystemRoleModel) {
function remove(row: SystemRoleModel) { function remove(row: SystemRoleModel) {
ElMessageBox.confirm(`是否确认删除 ${row.name} 角色?`, '确认删除', {type: 'warning'}).then(async () => { ElMessageBox.confirm(`是否确认删除 ${row.name} 角色?`, '确认删除', {type: 'warning'}).then(async () => {
const data = await http.delete<{params: {id: string}}, any>('/api/v2/system/role/delete', {params: {id: row._id}}) const data = await http.delete<{params: {id: string}}, any>('/api/v1/system/role/delete', {params: {id: row._id}})
if(data.status) { if(data.status) {
ElMessage.success(data.message) ElMessage.success(data.message)
loadData() loadData()
@ -209,7 +209,7 @@ async function save() {
roleForm.value?.validate(async (valid: boolean) => { roleForm.value?.validate(async (valid: boolean) => {
if (!valid) return if (!valid) return
modalLoading.value = true modalLoading.value = true
const data = await http.post<SystemRoleModel, any>('/api/v2/system/role/save', formData) const data = await http.post<SystemRoleModel, any>('/api/v1/system/role/save', formData)
modalLoading.value = false modalLoading.value = false
addModal.value = false addModal.value = false
ElMessage.success(data.message) ElMessage.success(data.message)

View File

@ -16,14 +16,14 @@
<el-table :data="systemUserData" v-loading="loading" stripe> <el-table :data="systemUserData" v-loading="loading" stripe>
<el-table-column prop="username" label="用户名" /> <el-table-column prop="username" label="用户名" />
<el-table-column prop="realname" label="昵称" /> <el-table-column prop="realname" label="昵称" />
<el-table-column prop="createdAt" label="创建时间" > <el-table-column prop="created_at" label="创建时间" >
<template #default="scope"> <template #default="scope">
{{ datetimeFormat(scope.row.createdAt) }} {{ datetimeFormat(scope.row.created_at) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="updatedAt" label="更新时间" > <el-table-column prop="updated_at" label="更新时间" >
<template #default="scope"> <template #default="scope">
{{ datetimeFormat(scope.row.updatedAt) }} {{ datetimeFormat(scope.row.updated_at) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" > <el-table-column label="操作" >
@ -56,7 +56,7 @@
<el-input v-model="formData.realname" /> <el-input v-model="formData.realname" />
</el-form-item> </el-form-item>
<el-form-item label="角色" prop="realname"> <el-form-item label="角色" prop="realname">
<el-select v-model="formData.roleIds" multiple > <el-select v-model="formData.role_ids" multiple >
<el-option v-for="role in roles" :key="role._id" :value="role._id" :label="role.name"></el-option> <el-option v-for="role in roles" :key="role._id" :value="role._id" :label="role.name"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -102,7 +102,7 @@ const formData = reactive<SystemUserModel>({
username: null, username: null,
password: null, password: null,
realname: null, realname: null,
roleIds: [] role_ids: []
}) })
const userForm = ref<VForm>() const userForm = ref<VForm>()
@ -110,7 +110,7 @@ const ruleValidate = computed(() => ({
username: [ username: [
{ required: true, message: '请输入用户名', trigger: 'blur' }, { required: true, message: '请输入用户名', trigger: 'blur' },
{ validator: async (rule: object, value: string, callback: Function) => { { validator: async (rule: object, value: string, callback: Function) => {
const data = await http.get<any, any>('/api/v2/system/user/exists', {params: {username: value, id: formData._id}}) const data = await http.get<any, any>('/api/v1/system/user/exists', {params: {username: value, id: formData._id}})
if(data.data.exists) { if(data.data.exists) {
callback(new Error('用户名已存在')) callback(new Error('用户名已存在'))
} else { } else {
@ -128,7 +128,7 @@ const ruleValidate = computed(() => ({
async function loadData() { async function loadData() {
loading.value = true loading.value = true
const data = await http.get<{params: SystemUserPage}, any>('/api/v2/system/user/list', {params: search}) const data = await http.get<{params: SystemUserPage}, any>('/api/v1/system/user/list', {params: search})
loading.value = false loading.value = false
total.value = data.total total.value = data.total
systemUserData.value = data.data systemUserData.value = data.data
@ -141,7 +141,7 @@ function add() {
username: null, username: null,
password: null, password: null,
realname: null, realname: null,
roleIds: [] role_ids: []
}) })
modalTitle.value = '新增用户' modalTitle.value = '新增用户'
addModal.value = true addModal.value = true
@ -153,7 +153,7 @@ function update(row: SystemUserModel) {
_id: row._id, _id: row._id,
username: row.username, username: row.username,
realname: row.realname, realname: row.realname,
roleIds: row.roleIds role_ids: row.role_ids
}) })
modalTitle.value = '修改用户' modalTitle.value = '修改用户'
addModal.value = true addModal.value = true
@ -164,7 +164,7 @@ async function save() {
userForm.value?.validate(async (valid: boolean) => { userForm.value?.validate(async (valid: boolean) => {
if (!valid) return if (!valid) return
modalLoading.value = true modalLoading.value = true
const data = await http.post<SystemUserModel, any>('/api/v2/system/user/save', formData) const data = await http.post<SystemUserModel, any>('/api/v1/system/user/save', formData)
modalLoading.value = false modalLoading.value = false
addModal.value = false addModal.value = false
ElMessage.success(data.message) ElMessage.success(data.message)
@ -174,7 +174,7 @@ async function save() {
function remove(row: SystemUserModel) { function remove(row: SystemUserModel) {
ElMessageBox.confirm(`是否确认删除 ${row.username} 用户?`, '确认删除', {type: 'warning'}).then(async () => { ElMessageBox.confirm(`是否确认删除 ${row.username} 用户?`, '确认删除', {type: 'warning'}).then(async () => {
const data = await http.delete<{params: {id: string}}, any>('/api/v2/system/user/delete', {params: {id: row._id}}) const data = await http.delete<{params: {id: string}}, any>('/api/v1/system/user/delete', {params: {id: row._id}})
if(data.status) { if(data.status) {
ElMessage.success(data.message) ElMessage.success(data.message)
loadData() loadData()
@ -191,7 +191,7 @@ function clearValidate() {
} }
loadData() loadData()
http.get<never, any>('/api/v2/system/role/listAll').then(data => { http.get<never, any>('/api/v1/system/role/listAll').then(data => {
roles.value = data roles.value = data
}) })
</script> </script>