Browse Source

数据备份页面/远程挂接页面/配合菜单调整

master
xuhuajiao 9 months ago
parent
commit
a38fbccdec
  1. 10
      src/assets/iconfonts/light/iconfont.css
  2. 2
      src/assets/iconfonts/light/iconfont.js
  3. 7
      src/assets/iconfonts/light/iconfont.json
  4. BIN
      src/assets/iconfonts/light/iconfont.ttf
  5. BIN
      src/assets/iconfonts/light/iconfont.woff
  6. BIN
      src/assets/iconfonts/light/iconfont.woff2
  7. 9
      src/views/collectReorganizi/batchConnection/index.vue
  8. 40
      src/views/collectReorganizi/batchConnection/module/form.vue
  9. 16
      src/views/system/baseConfig/index.vue
  10. 16
      src/views/system/categoryConfig/index.vue
  11. 303
      src/views/system/database/index.vue
  12. 16
      src/views/system/fileLibraryConfig/index.vue
  13. 16
      src/views/system/otherConfig/index.vue
  14. 282
      src/views/system/remoteConnection/index.vue
  15. 16
      src/views/system/serviceConfig/index.vue

10
src/assets/iconfonts/light/iconfont.css

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 3966148 */
src: url('iconfont.woff2?t=1710738984247') format('woff2'),
url('iconfont.woff?t=1710738984247') format('woff'),
url('iconfont.ttf?t=1710738984247') format('truetype');
src: url('iconfont.woff2?t=1715829351281') format('woff2'),
url('iconfont.woff?t=1715829351281') format('woff'),
url('iconfont.ttf?t=1715829351281') format('truetype');
}
.iconfont {
@ -13,6 +13,10 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-yuanchengkongzhi:before {
content: "\e7d4";
}
.icon-attachment:before {
content: "\e6a9";
}

2
src/assets/iconfonts/light/iconfont.js
File diff suppressed because it is too large
View File

7
src/assets/iconfonts/light/iconfont.json

@ -5,6 +5,13 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "30849212",
"name": "远程控制",
"font_class": "yuanchengkongzhi",
"unicode": "e7d4",
"unicode_decimal": 59348
},
{
"icon_id": "265327",
"name": "附件",

BIN
src/assets/iconfonts/light/iconfont.ttf

BIN
src/assets/iconfonts/light/iconfont.woff

BIN
src/assets/iconfonts/light/iconfont.woff2

9
src/views/collectReorganizi/batchConnection/index.vue

@ -12,10 +12,14 @@
</div>
<crudOperation>
<template v-slot:right>
<el-button size="mini" @click="doLoalHitch">
<el-button size="mini" @click="doLoalHitch(0)">
<i class="iconfont icon-bendiguajie" />
本地挂接
</el-button>
<el-button size="mini" @click="doLoalHitch(1)">
<i class="iconfont icon-yuanchengkongzhi" style="font-size: 18px;" />
远程挂接
</el-button>
<el-button :loading="crud.downloadLoading" size="mini" :disabled="crud.selections.length === 0" @click="doExport(crud.selections)">
<i class="iconfont icon-daochu" />
导出
@ -155,8 +159,9 @@ export default {
this.crud.refresh()
}
},
doLoalHitch() {
doLoalHitch(type) {
this.$nextTick(() => {
this.$refs.localForm.connectionType = type
this.$refs.localForm.localHitchVisible = true
})
},

40
src/views/collectReorganizi/batchConnection/module/form.vue

@ -40,7 +40,7 @@
/>
</el-select>
</el-form-item>
<el-form-item label="上传附件" prop="file">
<el-form-item v-if="!connectionType" label="上传附件" prop="file">
<div class="upload-bgColor">
<input class="upload-input" type="file" accept=".zip" style="width: 110px; height: 32px;" @change="handleFile">
<el-button size="small" type="primary"><i class="iconfont icon-shangchuan" />点击上传</el-button>
@ -55,6 +55,19 @@
</div>
<el-input v-show="false" v-model="form.file" />
</el-form-item>
<el-form-item v-if="connectionType" label="挂接类型" prop="batchType">
<el-select v-model="form.batchType" placeholder="请选择" style="width: 400px;">
<el-option
v-for="item in batchTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item v-if="connectionType" label="文件路径" prop="filePath">
<el-input v-model="form.filePath" style="width: 400px;" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="handleCancel">取消</el-button>
@ -84,12 +97,15 @@ export default {
return {
localHitchVisible: false,
hitchRemarkArray: [],
connectionType: 0,
form: {
checkRepeatType: null,
hitchFiled: null,
matchingMode: 1,
fields: null,
file: null
file: null,
batchType: null,
filePath: null
},
fileList: [],
typeOptions: [
@ -120,6 +136,20 @@ export default {
label: '后缀模糊匹配'
}
],
batchTypeOptions: [
{
value: 1,
label: '服务端挂接'
},
{
value: 2,
label: 'FTP挂接'
},
{
value: 3,
label: 'SFTP挂接'
}
],
fieldOptions: [],
rules: {
checkRepeatType: [
@ -133,6 +163,12 @@ export default {
],
matchingMode: [
{ required: true, message: '请选择', trigger: 'change' }
],
batchType: [
{ required: true, message: '请选择', trigger: 'change' }
],
filePath: [
{ required: true, message: '请选择', trigger: 'blur' }
]
}
}

16
src/views/system/baseConfig/index.vue

@ -0,0 +1,16 @@
<template>
<div>
<router-view />
</div>
</template>
<script>
export default {
name: 'BaseConfig',
data() {
return {
}
}
}
</script>
<style scoped>
</style>

16
src/views/system/categoryConfig/index.vue

@ -0,0 +1,16 @@
<template>
<div>
<router-view />
</div>
</template>
<script>
export default {
name: 'CategoryConfig',
data() {
return {
}
}
}
</script>
<style scoped>
</style>

303
src/views/system/database/index.vue

@ -0,0 +1,303 @@
<template>
<div class="app-container row-container">
<div class="head-container">
<div class="head-search">
<!-- 搜索 -->
<el-input v-model="query.search" clearable size="small" placeholder="输入关键字搜索" prefix-icon="el-icon-search" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<date-range-picker v-model="blurryTime" class="date-item" />
<rrOperation>
<template v-slot:right>
<el-button class="filter-item filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetQuery()">重置</el-button>
</template>
</rrOperation>
</div>
<crudOperation :permission="permission">
<template v-slot:middle>
<el-button slot="reference" size="mini" :loading="crud.delAllLoading" :disabled="crud.selections.length === 0" @click="toVerify('del')">
<i class="iconfont icon-shanchu" />
删除
</el-button>
</template>
<template v-slot:right>
<el-button :loading="crud.downloadLoading" size="mini" :disabled="crud.selections.length !== 1" @click="toVerify('download')">
<i class="iconfont icon-daochu" />
导出
</el-button>
<el-button size="mini" :disabled="crud.selections.length !== 1" @click="toVerify('return')">
<i class="iconfont icon-huifu" />
还原
</el-button>
</template>
</crudOperation>
</div>
<div class="container-wrap">
<span class="right-top-line" />
<span class="left-bottom-line" />
<!--表格渲染-->
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column type="selection" align="center" width="55" />
<el-table-column prop="name" :show-overflow-tooltip="true" label="备份文件名" min-width="240" />
<el-table-column prop="remark" :show-overflow-tooltip="true" label="备注" min-width="200" />
<el-table-column prop="file_size" label="大小" min-width="85">
<!-- <template slot-scope="scope">
{{ getFileSize(scope.row.file_size) }}
</template> -->
</el-table-column>
<el-table-column prop="createBy" label="操作人" align="center" width="100" />
<el-table-column prop="createTime" label="操作时间" align="center" width="180">
<template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</div>
<el-dialog class="tip-dialog tip-middle-dialog" title="操作提示" :close-on-click-modal="false" :modal-append-to-body="false" append-to-body :visible.sync="verifyDialogVisible" :before-close="handleClose">
<div class="setting-dialog">
<div class="tip-content">
<p class="tipMsg">这里为技术人员维护系统时使用普通用户无需设置</p>
<p class="delt-tip"><span>注意强行修改会导致系统数据异常或丢失如因用户强行修改本系统不负责因此导致的相关后果</span></p>
</div>
<el-form :model="form" style="margin-top:30px;" @submit.native.prevent>
<el-form-item label="维护验证码" label-width="110px">
<el-input v-model="form.verifyCode" show-password style="width: 480px;" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="verifyDialogVisible=false">取消 </el-button>
<el-button type="primary" @click.native="handleConfirm">确定</el-button>
</div>
</div>
</el-dialog>
<!-- form -->
<el-dialog append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="crud.cancelCU" :visible="crud.status.cu > 0" :title="crud.status.title">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<el-form ref="form" :rules="rules" :model="form" size="small" label-width="100px">
<el-form-item label="备份名称" prop="name">
<el-input v-model="form.name" style="width: 580px;" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" :rows="4" style="width: 580px;" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">保存</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import { verifyMaintenance } from '@/api/system/field'
import { encrypt } from '@/utils/rsaEncrypt'
import crudNotify from '@/api/system/notify'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import rrOperation from '@crud/RR.operation'
import DateRangePicker from '@/components/DateRangePicker'
import pagination from '@crud/Pagination'
import { mapGetters } from 'vuex'
// import { exportFile } from '@/utils/index'
// import qs from 'qs'
const defaultForm = { id: null, name: '', remark: null }
export default {
name: 'Database',
components: { crudOperation, rrOperation, DateRangePicker, pagination },
cruds() {
return CRUD({
title: '数据备份',
url: 'api/notice/initNotice',
crudMethod: { ...crudNotify },
sort: [],
optShow: {
add: true,
edit: false,
del: false,
download: false,
group: false,
reset: false
}
})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
permission: {
add: ['admin', 'database:add'],
edit: ['admin', 'database:edit'],
del: ['admin', 'database:del']
},
verifyDialogVisible: false,
form: {
verifyCode: ''
},
btn: '',
showVerifyDialog: true,
blurryTime: null,
rules: {
name: [
{ required: true, message: '备份名称不可为空', trigger: 'blur' }
]
}
}
},
computed: {
...mapGetters([
'baseApi'
])
},
created() {
},
methods: {
[CRUD.HOOK.beforeToCU](crud, form, btn) {
if (this.showVerifyDialog) {
//
this.verifyDialogVisible = true
this.btn = btn
return false
}
},
getFileSize(fileSize) {
const fileSizeInKB = (fileSize / 1024).toFixed(2) + 'kB'
const fileSizeInB = fileSize + 'B'
return (fileSize / 1024) <= 0.01 ? fileSizeInB : fileSizeInKB
},
[CRUD.HOOK.beforeRefresh]() {
if (this.blurryTime) {
this.crud.query.startTime = this.blurryTime[0]
this.crud.query.endTime = this.blurryTime[1]
} else {
this.crud.query.startTime = null
this.crud.query.endTime = null
}
},
//
[CRUD.HOOK.afterValidateCU](crud) {
console.log(crud.form)
return true
},
resetQuery() {
this.crud.query.search = ''
this.blurryTime = null
this.crud.query.startTime = null
this.crud.query.endTime = null
this.crud.toQuery()
},
toVerify(btn) {
if (this.showVerifyDialog) {
//
this.verifyDialogVisible = true
this.btn = btn
return false
}
},
handleConfirm() {
verifyMaintenance(encrypt(this.form.verifyCode)).then((res) => {
if (res) {
//
this.verifyDialogVisible = false
this.form.verifyCode = ''
this.showVerifyDialog = false
if (this.btn === 'add') {
this.crud.toAdd()
} else if (this.btn === 'edit') {
this.crud.toEdit(this.crud.selections[0])
} else if (this.btn === 'del') {
this.toDelete(this.crud.selections)
} else if (this.btn === 'download') {
this.doExport(this.crud.selections[0])
} else if (this.btn === 'return') {
this.toReturn(this.crud.selections[0])
}
this.showVerifyDialog = true
} else {
this.$message({ message: '验证码错误!', type: 'error', offset: 8 })
}
})
},
handleClose(done) {
this.form.verifyCode = ''
done()
},
toDelete(data) {
this.$confirm('此操作将删除当前所选数据' + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
// const ids = data.map(item => item.id)
// const params = {
// 'ids': ids,
// 'operator': this.user.username
// }
// crudEditing.del(params).then((res) => {
// console.log(res)
// if (res.code !== 500) {
// this.$message({ message: '', type: 'success', offset: 8 })
// } else {
// this.$message({ message: res.message, type: 'error', offset: 8 })
// }
// this.initData()
// }).catch(err => {
// console.log(err)
// })
}).catch(() => {
})
},
doExport(data) {
//
this.crud.downloadLoading = true
this.$confirm('此操作将导出所选数据' + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
// const params = {
// 'isType': this.isType
// }
// exportFile(this.baseApi + '/api/categoryField/download?' + qs.stringify(params, { indices: false }))
this.crud.downloadLoading = false
}).catch(() => {
})
},
toReturn(data) {
//
this.$confirm('此操作将还原当前所选备份' + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
// const params = {
// 'isType': this.isType
// }
// exportFile(this.baseApi + '/api/categoryField/download?' + qs.stringify(params, { indices: false }))
}).catch(() => {
})
}
}
}
</script>
<style lang="scss" scoped>
::v-deep div.el-dialog__footer {
text-align: center;
}
</style>

16
src/views/system/fileLibraryConfig/index.vue

@ -0,0 +1,16 @@
<template>
<div>
<router-view />
</div>
</template>
<script>
export default {
name: 'FileLibraryConfig',
data() {
return {
}
}
}
</script>
<style scoped>
</style>

16
src/views/system/otherConfig/index.vue

@ -0,0 +1,16 @@
<template>
<div>
<router-view />
</div>
</template>
<script>
export default {
name: 'OtherConfig',
data() {
return {
}
}
}
</script>
<style scoped>
</style>

282
src/views/system/remoteConnection/index.vue

@ -0,0 +1,282 @@
<template>
<div class="app-container row-container">
<div class="head-container">
<div class="head-search">
<!-- 搜索 -->
<el-input v-model="query.search" clearable size="small" placeholder="输入关键字搜索" prefix-icon="el-icon-search" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<el-select v-model="query.type" placeholder="请选择协议" style="width: 140px;" @change="crud.toQuery">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<date-range-picker v-model="blurryTime" class="date-item" />
<rrOperation>
<template v-slot:right>
<el-button class="filter-item filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetQuery()">重置</el-button>
</template>
</rrOperation>
</div>
<crudOperation :permission="permission">
<template v-slot:middle>
<el-button slot="reference" size="mini" :loading="crud.delAllLoading" :disabled="crud.selections.length === 0" @click="toDelete(crud.selections)">
<i class="iconfont icon-shanchu" />
删除
</el-button>
</template>
<template v-slot:right>
<el-button :loading="crud.downloadLoading" size="mini" :disabled="crud.selections.length === 0" @click="doExport(crud.selections)">
<i class="iconfont icon-daochu" />
导出
</el-button>
</template>
</crudOperation>
</div>
<!--表格渲染-->
<div class="container-wrap">
<span class="right-top-line" />
<span class="left-bottom-line" />
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column type="selection" align="center" width="55" />
<el-table-column prop="name" label="名称" min-width="160" />
<el-table-column prop="type" label="协议" min-width="100" />
<el-table-column prop="location" label="地址" min-width="100" />
<el-table-column prop="port" label="端口" min-width="85" />
<el-table-column prop="file_size" label="根目录" min-width="85" />
<el-table-column prop="createBy" label="操作人" align="center" width="100" />
<el-table-column prop="createTime" label="操作时间" align="center" width="180">
<template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</div>
<!-- form -->
<el-dialog append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="crud.cancelCU" :visible="crud.status.cu > 0" :title="crud.status.title">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<el-form ref="form" :rules="rules" :model="form" size="small" label-width="100px">
<el-form-item label="名称" prop="name">
<el-input v-model="form.name" placeholder="请输入" style="width: 580px;" />
</el-form-item>
<el-form-item label="协议" prop="protocol">
<el-radio-group v-model="form.protocol" style="width: 580px;">
<el-radio :label="0">服务器磁盘</el-radio>
<el-radio :label="1">FTP</el-radio>
<el-radio :label="2">SFTP</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="地址" prop="location">
<el-input v-model="form.location" placeholder="请输入" style="width: 580px;" />
</el-form-item>
<el-form-item label="端口" prop="port">
<el-input v-model="form.port" placeholder="请输入" style="width: 580px;" />
</el-form-item>
<el-form-item label="账号" prop="account">
<el-input v-model="form.account" placeholder="请输入" style="width: 580px;" />
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="form.password" placeholder="请输入" style="width: 580px;" />
</el-form-item>
<el-form-item label="根目录" prop="root">
<el-input v-model="form.root" placeholder="请输入" style="width: 580px;" />
</el-form-item>
<el-form-item label="成功后操作" prop="operate">
<el-radio-group v-model="form.operate">
<el-radio :label="0">保留文件</el-radio>
<el-radio :label="1">移除文件</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入" :rows="4" style="width: 580px;" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">保存</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import crudNotify from '@/api/system/notify'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import rrOperation from '@crud/RR.operation'
import DateRangePicker from '@/components/DateRangePicker'
import pagination from '@crud/Pagination'
import { mapGetters } from 'vuex'
// import { exportFile } from '@/utils/index'
// import qs from 'qs'
const defaultForm = { id: null, name: '', protocol: 0, location: null, port: null, account: null, password: null, root: null, operate: null, remark: null }
export default {
name: 'RemoteConnection',
components: { crudOperation, rrOperation, DateRangePicker, pagination },
cruds() {
return CRUD({
title: '远程设置',
url: 'api/notice/initNotice',
crudMethod: { ...crudNotify },
sort: [],
optShow: {
add: true,
edit: true,
del: false,
download: false,
group: false,
reset: false
}
})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
permission: {
add: ['admin', 'remoteConnection:add'],
edit: ['admin', 'remoteConnection:edit'],
del: ['admin', 'remoteConnection:del']
},
blurryTime: null,
options: [
{
value: 1,
label: '服务端磁盘'
},
{
value: 2,
label: 'FTP'
},
{
value: 3,
label: 'SFTP'
}
],
rules: {
name: [
{ required: true, message: '名称不可为空', trigger: 'blur' }
],
protocol: [
{ required: true, message: '请选择', trigger: 'change' }
],
location: [
{ required: true, message: '地址不可为空', trigger: 'blur' }
],
port: [
{ required: true, message: '端口不可为空', trigger: 'blur' }
],
account: [
{ required: true, message: '账号不可为空', trigger: 'blur' }
],
password: [
{ required: true, message: '密码不可为空', trigger: 'blur' }
],
root: [
{ required: true, message: '根目录不可为空', trigger: 'blur' }
],
operate: [
{ required: true, message: '请选择', trigger: 'change' }
]
}
}
},
computed: {
...mapGetters([
'baseApi'
])
},
created() {
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
if (this.blurryTime) {
this.crud.query.startTime = this.blurryTime[0]
this.crud.query.endTime = this.blurryTime[1]
} else {
this.crud.query.startTime = null
this.crud.query.endTime = null
}
},
//
[CRUD.HOOK.afterValidateCU](crud) {
console.log(crud.form)
return true
},
resetQuery() {
this.crud.query.search = ''
this.crud.query.type = null
this.blurryTime = null
this.crud.query.startTime = null
this.crud.query.endTime = null
this.crud.toQuery()
},
toDelete(data) {
this.$confirm('此操作将删除当前所选设置' + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
// const ids = data.map(item => item.id)
// const params = {
// 'ids': ids,
// 'operator': this.user.username
// }
// crudEditing.del(params).then((res) => {
// console.log(res)
// if (res.code !== 500) {
// this.$message({ message: '', type: 'success', offset: 8 })
// } else {
// this.$message({ message: res.message, type: 'error', offset: 8 })
// }
// this.initData()
// }).catch(err => {
// console.log(err)
// })
}).catch(() => {
})
},
doExport(data) {
this.crud.downloadLoading = true
this.$confirm('此操作将导出所选数据' + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
// const params = {
// 'isType': this.isType
// }
// exportFile(this.baseApi + '/api/categoryField/download?' + qs.stringify(params, { indices: false }))
this.crud.downloadLoading = false
}).catch(() => {
this.crud.downloadLoading = false
})
},
handleClose(done) {
done()
}
}
}
</script>
<style lang="scss" scoped>
::v-deep div.el-dialog__footer {
text-align: center;
}
</style>

16
src/views/system/serviceConfig/index.vue

@ -0,0 +1,16 @@
<template>
<div>
<router-view />
</div>
</template>
<script>
export default {
name: 'ServiceConfig',
data() {
return {
}
}
}
</script>
<style scoped>
</style>
Loading…
Cancel
Save