一言
This commit is contained in:
parent
8253a1b62b
commit
22932ccaf9
@ -8,6 +8,8 @@ import SystemRole from './views/system/SystemRole.vue'
|
||||
import SystemConfig from './views/system/SystemConfig.vue'
|
||||
|
||||
import Music from './views/api/Music.vue'
|
||||
import Hitokoto from './views/api/Hitokoto.vue'
|
||||
import SqlReplace from './views/tool/SqlReplace.vue'
|
||||
|
||||
const routes: Array<RouteRecordRaw> = [
|
||||
{ path: '/login', name: 'Login', component: Login },
|
||||
@ -18,6 +20,9 @@ const routes: Array<RouteRecordRaw> = [
|
||||
{ path: '/system/config', name: 'SystemConfig', component: SystemConfig },
|
||||
|
||||
{ path: '/api/music', name: 'Music', component: Music },
|
||||
{ path: '/api/hitokoto', name: 'Hitokoto', component: Hitokoto },
|
||||
|
||||
{ path: '/tool/sqlReplace', name: 'SqlReplace', component: SqlReplace },
|
||||
]}
|
||||
]
|
||||
|
||||
|
||||
@ -46,9 +46,6 @@ html,body,#app,.layout {
|
||||
}
|
||||
.btn-container {
|
||||
margin-bottom: 10px;
|
||||
button {
|
||||
margin-right: 3px;
|
||||
}
|
||||
.search-btn {
|
||||
float: right;
|
||||
}
|
||||
|
||||
149
src/views/api/Hitokoto.vue
Normal file
149
src/views/api/Hitokoto.vue
Normal file
@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form inline :model="search" @submit.prevent>
|
||||
<el-form-item label="内容:">
|
||||
<el-input size="small" v-model="search.content" />
|
||||
</el-form-item>
|
||||
<el-form-item label="类型:">
|
||||
<el-select size="small" v-model="search.type" multiple collapse-tags>
|
||||
<el-option v-for="item in typeList" :key="item.value" :value="item.value" :label="item.label" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间:">
|
||||
<el-date-picker
|
||||
v-model="search.createdAt"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="btn-container">
|
||||
<el-button size="small" type="primary" @click="addModal = true">添加</el-button>
|
||||
<el-button size="small" type="danger" @click="deleteAll">删除</el-button>
|
||||
<div class="search-btn">
|
||||
<el-button type="primary" @click="loadDataBase(true)" size="small" icon="el-icon-search">搜索</el-button>
|
||||
<el-button @click="reset" size="small" icon="el-icon-refresh-right">重置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<el-table :data="hitokotoData" v-loading="loading" stripe height="520" @selection-change="dataSelect">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="type" label="类型" width="180">
|
||||
<template #default="scope">
|
||||
{{ findTypeText(scope.row.type) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="hitokoto" label="内容" />
|
||||
<el-table-column prop="from" label="来自" width="180"/>
|
||||
<el-table-column prop="creator" label="作者" width="180"/>
|
||||
<el-table-column prop="number" label="编号" width="70"/>
|
||||
<el-table-column prop="created_at" label="创建时间" width="180">
|
||||
<template #default="scope">
|
||||
{{ datetimeFormat(scope.row.created_at) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="page-container">
|
||||
<el-pagination background
|
||||
:page-sizes="$store.state.pageSizeOpts"
|
||||
:layout="$store.state.pageLayout"
|
||||
:total="total"
|
||||
@size-change="pageSizeChange"
|
||||
@current-change="pageChange">
|
||||
</el-pagination>
|
||||
</div>
|
||||
<el-dialog v-model="addModal" title="新增一言" >
|
||||
<hitokoto-add ref="addForm" :typeList="typeList" :formData="formData" />
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="addModal = false">取消</el-button>
|
||||
<el-button type="primary" @click="save" :loading="modalLoading">确定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import HitokotoAdd from './HitokotoAdd.vue'
|
||||
import { Options } from 'vue-class-component'
|
||||
import BaseList from '../../model/baselist'
|
||||
import { Page } from '../../model/common.dto'
|
||||
import HitokotoModel from '../../model/api/hitokoto'
|
||||
import { AxiosResponse } from 'axios'
|
||||
import { ElButton, ElForm, ElFormItem, ElInput, ElTable, ElTableColumn, ElPagination, ElDialog, ElSelect, ElOption, ElDatePicker, ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { ref } from 'vue'
|
||||
|
||||
let selectedData: string[] = []
|
||||
@Options({
|
||||
name: 'Hitokoto',
|
||||
components: { ElButton, ElForm, ElFormItem, ElInput, ElTable, ElTableColumn, ElPagination, ElDialog, ElSelect, ElOption, ElDatePicker, HitokotoAdd }
|
||||
})
|
||||
export default class Hitokoto extends BaseList<HitokotoPage> {
|
||||
private readonly addForm: any = ref('addForm')
|
||||
search = new HitokotoPage()
|
||||
typeList: {label: string, value: string}[] = []
|
||||
hitokotoData: HitokotoModel[] = []
|
||||
formData: {[propName:string]: string | null} = {}
|
||||
addModal: boolean = false
|
||||
|
||||
async loadData() {
|
||||
this.loading = true
|
||||
const { data } = await this.$http.get<HitokotoPage, AxiosResponse<any>>('/api/hitokoto/list', {params:this.search})
|
||||
selectedData = []
|
||||
this.loading = false
|
||||
this.total = data.total
|
||||
this.hitokotoData = data.data
|
||||
}
|
||||
async save() {
|
||||
this.addForm.$refs.hitokotoForm.validate(async (valid: boolean) => {
|
||||
if(!valid) return
|
||||
this.modalLoading = true
|
||||
const { data } = await this.$http.post<any, AxiosResponse<any>>('/api/hitokoto/save', this.formData)
|
||||
this.modalLoading = false
|
||||
this.addModal = false
|
||||
ElMessage.success(data.message)
|
||||
this.loadData()
|
||||
// 清空表单
|
||||
this.formData = {}
|
||||
})
|
||||
}
|
||||
deleteAll() {
|
||||
if(!selectedData.length) {
|
||||
ElMessage.warning('请选择要删除的数据')
|
||||
return
|
||||
}
|
||||
ElMessageBox.confirm(`是否确认删除选中的${selectedData.length}条数据?`, '确认删除', {type: 'warning'}).then(async () => {
|
||||
const { data } = await this.$http.delete<any, AxiosResponse<any>>('/api/hitokoto/delete', {params:{_ids: selectedData}})
|
||||
ElMessage.success(data.message)
|
||||
this.loadData()
|
||||
}).catch(() => {})
|
||||
}
|
||||
dataSelect(selection: HitokotoModel[]) {
|
||||
selectedData = selection.map(item => item._id)
|
||||
}
|
||||
created() {
|
||||
this.loadData()
|
||||
this.$http.get('/api/common/config/hitokoto_type').then(({data}) => {
|
||||
this.typeList = data
|
||||
})
|
||||
}
|
||||
findTypeText(value: string): string | null {
|
||||
const type = this.typeList.find(item => item.value === value)
|
||||
return type ? type.label : null
|
||||
}
|
||||
}
|
||||
|
||||
class HitokotoPage extends Page {
|
||||
content?: string
|
||||
type?: string
|
||||
createdAt?: [Date, Date]
|
||||
reset() {
|
||||
super.reset()
|
||||
this.content = undefined
|
||||
this.type = undefined
|
||||
this.createdAt = undefined
|
||||
}
|
||||
}
|
||||
</script>
|
||||
45
src/views/api/HitokotoAdd.vue
Normal file
45
src/views/api/HitokotoAdd.vue
Normal file
@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="hitokotoForm" :model="formData" :rules="ruleValidate" :label-width="80">
|
||||
<el-form-item label="内容" prop="hitokoto">
|
||||
<el-input v-model="formData.hitokoto" type="textarea" :rows="4"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select v-model="formData.type">
|
||||
<el-option v-for="item in typeList" :value="item.value" :key="item.value" :label="item.label"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="来自">
|
||||
<el-input v-model="formData.from" />
|
||||
</el-form-item>
|
||||
<el-form-item label="作者">
|
||||
<el-input v-model="formData.creator" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Options, Vue } from 'vue-class-component'
|
||||
import { ElForm, ElFormItem, ElInput, ElSelect, ElOption } from 'element-plus'
|
||||
|
||||
@Options({
|
||||
name: 'SystemConfigAdd',
|
||||
components: { ElForm, ElFormItem, ElInput, ElSelect, ElOption },
|
||||
props: {
|
||||
typeList: Array,
|
||||
formData: Object
|
||||
}
|
||||
})
|
||||
export default class HitokotoAdd extends Vue {
|
||||
typeList!: {label: string, value: string}[]
|
||||
formData!: {[propName:string]: string | null}
|
||||
ruleValidate = {
|
||||
hitokoto: [
|
||||
{ required: true, message: '请输入内容', trigger: 'blur' }
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: '请选择类型', trigger: 'blur' }
|
||||
],
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -25,7 +25,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="btn-container">
|
||||
<el-button type="success" plain size="small" icon="el-icon-caret-right" >播放</el-button>
|
||||
<el-button type="success" plain size="small" icon="el-icon-caret-right" @click="playMusic">播放</el-button>
|
||||
<div class="search-btn">
|
||||
<el-button type="primary" @click="loadDataBase(true)" size="small" icon="el-icon-search">搜索</el-button>
|
||||
<el-button @click="reset" size="small" icon="el-icon-refresh-right">重置</el-button>
|
||||
@ -92,7 +92,7 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="modifyModal" title="修改所属歌单" :width="470" >
|
||||
<el-radio-group v-model="currentRow.lib_id">
|
||||
<el-radio-group v-if="currentRow" v-model="currentRow.lib_id">
|
||||
<el-radio v-for="item in musicLibs" :key="item._id" :label="item._id" border>{{item.name}}</el-radio>
|
||||
</el-radio-group>
|
||||
<template #footer>
|
||||
@ -119,15 +119,9 @@ import { AxiosResponse } from 'axios'
|
||||
import { ElButton, ElForm, ElFormItem, ElInput, ElTable, ElTableColumn, ElPagination, ElDialog, ElSelect, ElOption, ElRadioGroup, ElRadio, ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { ref } from 'vue'
|
||||
|
||||
|
||||
import { MusicModel, MusicLibModel, MusicLyricModel, MusicPlayerItem } from '../../model/api/music'
|
||||
import prettyBytes from 'pretty-bytes'
|
||||
// import APlayer, {APlayer as APlayerComponent} from '@moefe/vue-aplayer'
|
||||
|
||||
// Vue.use(APlayer, {
|
||||
// defaultCover: `${Vue.prototype.$http.defaults.baseURL}/api/common/randomBg?id=5ec7770b60990123b7340233`, // 播放器默认封面图片
|
||||
// productionTip: false, // 是否在控制台输出版本信息
|
||||
// })
|
||||
let selectedIds: string[] = []
|
||||
@Options({
|
||||
name: 'Music',
|
||||
@ -184,33 +178,27 @@ export default class Music extends BaseList<MusicPage> {
|
||||
return musicLib ? musicLib.name : null
|
||||
}
|
||||
// 根据当前搜索条件播放音乐
|
||||
// async playMusic() {
|
||||
// // 显示加载进度条
|
||||
// this.$Loading.start()
|
||||
// try {
|
||||
// const { data } = await this.$http.get('/api/music/list/all', {params: selectedIds.length ? {ids: selectedIds} : this.search})
|
||||
// this.musicList = data.map((item: MusicModel, index: number) => {
|
||||
// return {
|
||||
// id: index + 1,
|
||||
// name: item.title || item.name,
|
||||
// artist: item.artist,
|
||||
// album: item.album,
|
||||
// url: `${this.$http.defaults.baseURL || ''}/api/common/music/get/${item._id}`,
|
||||
// cover: `${this.$http.defaults.baseURL || ''}/api/common/music/album/${item._id}`,
|
||||
// lrc: item.lyric_id ? `${this.$http.defaults.baseURL || ''}/api/common/music/lyric/${item.lyric_id}` : undefined
|
||||
// }
|
||||
// })
|
||||
// // 结束加载进度条
|
||||
// this.$Loading.finish()
|
||||
// // 删除原本可能存在的播放器配置(包含播放地址 时间进度等信息)
|
||||
// localStorage.removeItem('aplayer-setting')
|
||||
// this.musicPlaying = true
|
||||
// } catch (err) {
|
||||
// console.error(err)
|
||||
// ElMessage.error('获取播放列表失败')
|
||||
// this.$Loading.error()
|
||||
// }
|
||||
// }
|
||||
async playMusic() {
|
||||
try {
|
||||
const { data } = await this.$http.get<any, AxiosResponse<any>>('/api/music/list/all', {params: selectedIds.length ? {ids: selectedIds} : this.search})
|
||||
this.musicList = data.map((item: MusicModel, index: number) => {
|
||||
return {
|
||||
id: index + 1,
|
||||
name: item.title || item.name,
|
||||
artist: item.artist,
|
||||
album: item.album,
|
||||
url: `${this.$http.defaults.baseURL || ''}/api/common/music/get/${item._id}`,
|
||||
cover: `${this.$http.defaults.baseURL || ''}/api/common/music/album/${item._id}`,
|
||||
lrc: item.lyric_id ? `${this.$http.defaults.baseURL || ''}/api/common/music/lyric/${item.lyric_id}` : undefined
|
||||
}
|
||||
})
|
||||
// 删除原本可能存在的播放器配置(包含播放地址 时间进度等信息)
|
||||
this.musicPlaying = true
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
ElMessage.error('获取播放列表失败')
|
||||
}
|
||||
}
|
||||
update(row: MusicModel) {
|
||||
this.currentRow = row
|
||||
this.modifyModal = true
|
||||
|
||||
@ -56,7 +56,7 @@
|
||||
<el-input v-model="formData.description" />
|
||||
</el-form-item>
|
||||
<el-form-item label="允许的请求类型">
|
||||
<el-select v-model="formData.methods" multiple >
|
||||
<el-select v-model="formData.methods" multiple collapse-tags>
|
||||
<el-option value="GET">GET</el-option>
|
||||
<el-option value="POST">POST</el-option>
|
||||
<el-option value="PUT">PUT</el-option>
|
||||
|
||||
74
src/views/tool/SqlReplace.vue
Normal file
74
src/views/tool/SqlReplace.vue
Normal file
@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form :label-width="100">
|
||||
<el-form-item label="SQL语句">
|
||||
<el-input v-model="sql" type="textarea" :rows="5"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="参数">
|
||||
<el-input v-model="params" type="textarea" :rows="3"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="替换结果">
|
||||
<el-input v-model="replaceResult" ref="resultInput" readonly/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="text-align:center">
|
||||
<el-button-group size="large" >
|
||||
<el-button type="primary" icon="el-icon-document-copy" @click="replacePlaceholder">替换占位符</el-button>
|
||||
<el-button type="default" @click="clear">清空</el-button>
|
||||
</el-button-group>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Options, Vue } from 'vue-class-component'
|
||||
import { ElForm, ElFormItem, ElInput, ElButtonGroup, ElButton, ElMessage } from 'element-plus'
|
||||
import { ref } from 'vue'
|
||||
|
||||
@Options({
|
||||
name: 'SqlReplace',
|
||||
components: { ElForm, ElFormItem, ElInput, ElButtonGroup, ElButton }
|
||||
})
|
||||
export default class SqlReplace extends Vue {
|
||||
private readonly inputInstance: any = ref('resultInput')
|
||||
sql: string = ''
|
||||
params: string = ''
|
||||
replaceResult: string = ''
|
||||
|
||||
replacePlaceholder() {
|
||||
let sql = this.sql
|
||||
const reg = /(.+?)\s*\((String|Integer|Boolean)\),?/g
|
||||
let execResult = reg.exec(this.params)
|
||||
let replaceMent = ''
|
||||
while(execResult && sql.indexOf('?') !== -1) {
|
||||
switch(execResult[2]) {
|
||||
case 'String':
|
||||
replaceMent = `'${execResult[1].trim()}'`
|
||||
break
|
||||
case 'Integer':
|
||||
replaceMent = execResult[1].trim()
|
||||
break
|
||||
case 'Boolean':
|
||||
replaceMent = eval(execResult[1]) ? '1' : '0'
|
||||
break
|
||||
}
|
||||
sql = sql.replace('?', replaceMent)
|
||||
execResult = reg.exec(this.params)
|
||||
}
|
||||
this.replaceResult = sql
|
||||
Promise.resolve('已复制到剪贴板').then(message => {
|
||||
this.inputInstance.select()
|
||||
if (document.execCommand('copy')) {
|
||||
ElMessage.success(message)
|
||||
} else {
|
||||
ElMessage.warning('复制失败,请手动复制')
|
||||
}
|
||||
})
|
||||
}
|
||||
clear() {
|
||||
this.sql = ''
|
||||
this.params = ''
|
||||
this.replaceResult = ''
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -21,6 +21,17 @@ export default defineConfig({
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
assetsDir: 'assets', // 静态资源的存放路径, 相对于outDir
|
||||
cssCodeSplit: true // 是否拆分css
|
||||
cssCodeSplit: true, // 是否拆分css
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks(id) {
|
||||
if (id.includes('element-plus')) {
|
||||
return 'element-plus'
|
||||
} else if(id.includes('node_modules')) {
|
||||
return 'vendor'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user