自定义路由

This commit is contained in:
tanghc
2019-06-14 17:28:18 +08:00
parent 3ee105a092
commit b21a02c4a5
36 changed files with 803 additions and 197 deletions

View File

@@ -8,7 +8,7 @@ import { getToken, removeToken } from './auth'
// 创建axios实例
const client = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // api 的 base_url
timeout: 5000 // 请求超时时间
timeout: 10000 // 请求超时时间
})
Object.assign(Vue.prototype, {
@@ -94,6 +94,14 @@ Object.assign(Vue.prototype, {
}
}).catch(function() {})
},
/**
* 重置表单
* @param formName 表单元素的ref
*/
resetForm(formName) {
const frm = this.$refs[formName]
frm && frm.resetFields()
},
logout: function() {
removeToken()
const fullPath = this.$route.fullPath

View File

@@ -1,7 +1,7 @@
<template>
<div class="app-container">
<el-container>
<el-aside style="min-height: 300px;width: 200px;">
<el-aside style="min-height: 300px;width: 250px;">
<el-input v-model="filterText" prefix-icon="el-icon-search" placeholder="搜索服务..." style="margin-bottom:20px;" size="mini" clearable />
<el-tree
ref="tree2"
@@ -17,10 +17,10 @@
@node-click="onNodeClick"
>
<span slot-scope="{ node, data }" class="custom-tree-node">
<span v-if="data.label.length < 15">{{ data.label }}</span>
<span v-if="data.label.length < serviceTextLimitSize">{{ data.label }}</span>
<span v-else>
<el-tooltip :content="data.label" class="item" effect="light" placement="right">
<span>{{ data.label.substring(0, 15) + '...' }}</span>
<span>{{ data.label.substring(0, serviceTextLimitSize) + '...' }}</span>
</el-tooltip>
</span>
</span>
@@ -222,6 +222,7 @@
export default {
data() {
return {
serviceTextLimitSize: 20,
filterText: '',
treeData: [],
tableData: [],
@@ -407,13 +408,8 @@ export default {
}
})
},
resetForm(formName) {
const frm = this.$refs[formName]
frm && frm.resetFields()
},
onLimitDialogClose: function() {
this.resetForm('limitDialogForm')
this.limitDialogVisible = false
},
infoRender: function(row) {
const html = []

View File

@@ -1,27 +1,57 @@
<template>
<div class="app-container">
<el-container>
<el-aside style="min-height: 300px;width: 200px;">
<el-input v-model="filterText" prefix-icon="el-icon-search" placeholder="搜索服务..." style="margin-bottom:20px;" size="mini" clearable />
<el-aside style="min-height: 300px;width: 250px;">
<el-button
type="primary"
plain
size="mini"
icon="el-icon-plus"
@click.stop="addService"
>
新建服务
</el-button>
<el-input
v-model="filterText"
prefix-icon="el-icon-search"
placeholder="搜索服务..."
style="margin-bottom:10px;margin-top:10px;"
size="mini"
clearable
/>
<el-tree
ref="tree2"
ref="serviceTree"
:data="treeData"
:props="defaultProps"
:filter-node-method="filterNode"
:highlight-current="true"
:expand-on-click-node="false"
empty-text="无数据"
node-key="id"
node-key="serviceId"
class="filter-tree"
default-expand-all
@node-click="onNodeClick"
>
<span slot-scope="{ node, data }" class="custom-tree-node">
<span v-if="data.label.length < 15">{{ data.label }}</span>
<span v-else>
<el-tooltip :content="data.label" class="item" effect="light" placement="right">
<span>{{ data.label.substring(0, 15) + '...' }}</span>
<div>
<el-tooltip v-show="data.custom" content="自定义服务" class="item" effect="light" placement="top">
<i class="el-icon-warning-outline"></i>
</el-tooltip>
<span v-if="data.label.length < serviceTextLimitSize">{{ data.label }}</span>
<span v-else>
<el-tooltip :content="data.label" class="item" effect="light" placement="right">
<span>{{ data.label.substring(0, serviceTextLimitSize) + '...' }}</span>
</el-tooltip>
</span>
</div>
<span>
<el-button
v-if="data.custom === 1"
type="text"
size="mini"
icon="el-icon-delete"
title="删除服务"
@click.stop="() => onDelService(data)"/>
</span>
</span>
</el-tree>
@@ -35,10 +65,20 @@
<el-button type="primary" icon="el-icon-search" @click="onSearchTable">查询</el-button>
</el-form-item>
</el-form>
<el-button
v-show="isCustomService"
type="primary"
size="mini"
icon="el-icon-plus"
@click.stop="addRoute"
>
新建路由
</el-button>
<el-table
:data="tableData"
border
max-height="500"
style="margin-top: 10px;"
>
<el-table-column
prop="name"
@@ -69,12 +109,12 @@
</el-table-column>
<el-table-column
prop="ignoreValidate"
label="忽略验证"
label="签名校验"
width="80"
>
<template slot-scope="scope">
<span v-if="scope.row.ignoreValidate === 1" style="color:#67C23A"></span>
<span v-if="scope.row.ignoreValidate === 0" style="color:#909399"></span>
<span v-if="scope.row.ignoreValidate === 0" style="color:#67C23A">校验</span>
<span v-if="scope.row.ignoreValidate === 1" style="color:#E6A23C">不校验</span>
</template>
</el-table-column>
<el-table-column
@@ -93,7 +133,7 @@
width="80"
>
<template slot-scope="scope">
<span v-if="scope.row.status === 0" style="color:#909399">待审核</span>
<span v-if="scope.row.status === 0" style="color:#E6A23C">待审核</span>
<span v-if="scope.row.status === 1" style="color:#67C23A">已启用</span>
<span v-if="scope.row.status === 2" style="color:#F56C6C">已禁用</span>
</template>
@@ -106,79 +146,170 @@
<template slot-scope="scope">
<el-button type="text" size="mini" @click="onTableUpdate(scope.row)">修改</el-button>
<el-button v-if="scope.row.permission" type="text" size="mini" @click="onTableAuth(scope.row)">授权</el-button>
<el-button v-if="scope.row.custom" type="text" size="mini" @click="onTableDel(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- route dialog -->
<el-dialog title="修改路由" :visible.sync="routeDialogVisible" :close-on-click-modal="false">
<el-form
:model="routeDialogFormData"
label-width="120px"
size="mini"
>
<el-form-item label="id">
<el-input v-model="routeDialogFormData.id" readonly="readonly" />
</el-form-item>
<el-form-item label="uri">
<el-input v-model="routeDialogFormData.uri" />
</el-form-item>
<el-form-item label="path">
<el-input v-model="routeDialogFormData.path" />
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="routeDialogFormData.status">
<el-radio :label="1" name="status">启用</el-radio>
<el-radio :label="2" name="status" style="color:#F56C6C">禁用</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="routeDialogVisible = false"> </el-button>
<el-button type="primary" @click="onRouteDialogSave"> </el-button>
</div>
</el-dialog>
<!-- auth dialog -->
<el-dialog title="路由授权" :visible.sync="authDialogVisible" :close-on-click-modal="false">
<el-form
:model="authDialogFormData"
label-width="120px"
size="mini"
>
<el-form-item label="id">
<el-input v-model="authDialogFormData.routeId" readonly="readonly" />
</el-form-item>
<el-form-item label="角色">
<el-checkbox-group v-model="authDialogFormData.roleCode">
<el-checkbox v-for="item in roles" :key="item.roleCode" :label="item.roleCode">{{ item.description }}</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="authDialogVisible = false"> </el-button>
<el-button type="primary" @click="onAuthDialogSave"> </el-button>
</div>
</el-dialog>
</el-main>
</el-container>
<!-- route dialog -->
<el-dialog
:title="routeDialogTitle"
:visible.sync="routeDialogVisible"
:close-on-click-modal="false"
@close="onCloseRouteDialog"
>
<el-form
ref="routeDialogFormRef"
:model="routeDialogFormData"
:rules="routeDialogFormRules"
label-width="120px"
size="mini"
>
<el-input v-show="false" v-model="routeDialogFormData.id" />
<el-form-item label="接口名" prop="name">
<el-input v-model="routeDialogFormData.name" placeholder="接口名product.goods.list" :disabled="Boolean(routeDialogFormData.id)" />
</el-form-item>
<el-form-item label="版本号" prop="version">
<el-input v-model="routeDialogFormData.version" placeholder="版本号1.0" :disabled="Boolean(routeDialogFormData.id)" />
</el-form-item>
<el-form-item label="uri" prop="uri">
<el-input v-model="routeDialogFormData.uri" placeholder="如http://www.xx.com" :disabled="routePropDisabled()" />
</el-form-item>
<el-form-item label="path" prop="path">
<el-input v-model="routeDialogFormData.path" placeholder="如:/order/list" :disabled="routePropDisabled()" />
</el-form-item>
<el-form-item label="签名校验">
<el-radio-group v-model="routeDialogFormData.ignoreValidate" :disabled="routePropDisabled()">
<el-radio :label="0" name="ignoreValidate">校验</el-radio>
<el-radio :label="1" name="ignoreValidate">不校验</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="统一格式输出">
<el-radio-group v-model="routeDialogFormData.mergeResult" :disabled="routePropDisabled()">
<el-radio :label="1" name="mergeResult"></el-radio>
<el-radio :label="0" name="mergeResult"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="routeDialogFormData.status">
<el-radio :label="1" name="status">启用</el-radio>
<el-radio :label="2" name="status" style="color:#F56C6C">禁用</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="routeDialogVisible = false"> </el-button>
<el-button type="primary" @click="onRouteDialogSave"> </el-button>
</div>
</el-dialog>
<!-- auth dialog -->
<el-dialog
title="路由授权"
:visible.sync="authDialogVisible"
:close-on-click-modal="false"
>
<el-form
:model="authDialogFormData"
label-width="120px"
size="mini"
>
<el-form-item label="id">
<el-input v-model="authDialogFormData.routeId" readonly="readonly" />
</el-form-item>
<el-form-item label="角色">
<el-checkbox-group v-model="authDialogFormData.roleCode">
<el-checkbox v-for="item in roles" :key="item.roleCode" :label="item.roleCode">{{ item.description }}</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="authDialogVisible = false"> </el-button>
<el-button type="primary" @click="onAuthDialogSave"> </el-button>
</div>
</el-dialog>
<!--添加服务-->
<el-dialog
title="添加服务"
:visible.sync="addServiceDialogVisible"
:close-on-click-modal="false"
@close="closeAddServiceDlg"
>
<el-form
ref="addServiceForm"
:model="addServiceForm"
:rules="addServiceFormRules"
label-width="200px"
>
<el-form-item label="服务名serviceId" prop="serviceId">
<el-input v-model="addServiceForm.serviceId" placeholder="服务名order-service" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addServiceDialogVisible = false"> </el-button>
<el-button type="primary" @click="onAddService"> </el-button>
</span>
</el-dialog>
</div>
</template>
<style>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
.el-input.is-disabled .el-input__inner {color: #909399;}
.el-radio__input.is-disabled+span.el-radio__label {color: #909399;}
</style>
<script>
export default {
data() {
return {
serviceTextLimitSize: 20,
filterText: '',
treeData: [],
tableData: [],
serviceId: '',
searchFormData: {},
isCustomService: false,
searchFormData: {
id: '',
serviceId: ''
},
defaultProps: {
children: 'children',
label: 'label'
},
routeDialogTitle: '修改路由',
// dialog
routeDialogFormData: {
status: 1
id: '',
name: '',
version: '1.0',
uri: '',
path: '',
status: 1,
mergeResult: 1,
ignoreValidate: 0
},
routeDialogFormRules: {
name: [
{ required: true, message: '不能为空', trigger: 'blur' },
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'blur' }
],
version: [
{ required: true, message: '不能为空', trigger: 'blur' },
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'blur' }
],
uri: [
{ required: true, message: '不能为空', trigger: 'blur' },
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'blur' }
],
path: [
{ min: 0, max: 100, message: '长度不能超过 100 个字符', trigger: 'blur' }
]
},
routeDialogVisible: false,
roles: [],
@@ -186,12 +317,23 @@ export default {
routeId: '',
roleCode: []
},
authDialogVisible: false
authDialogVisible: false,
// addService
addServiceDialogVisible: false,
addServiceForm: {
serviceId: ''
},
addServiceFormRules: {
serviceId: [
{ required: true, message: '请输入服务名称', trigger: 'blur' },
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'blur' }
]
}
}
},
watch: {
filterText(val) {
this.$refs.tree2.filter(val)
this.$refs.serviceTree.filter(val)
}
},
created() {
@@ -204,6 +346,12 @@ export default {
this.post('service.list', {}, function(resp) {
const respData = resp.data
this.treeData = this.convertToTreeData(respData, 0)
this.$nextTick(() => {
// 高亮已选中的
if (this.serviceId) {
this.$refs.serviceTree.setCurrentKey(this.serviceId)
}
})
})
},
// 树搜索
@@ -216,6 +364,7 @@ export default {
if (data.parentId) {
this.serviceId = data.label
this.searchFormData.serviceId = this.serviceId
this.isCustomService = Boolean(data.custom)
this.loadTable()
}
},
@@ -250,16 +399,18 @@ export default {
}
const children = []
for (let i = 0; i < data.length; i++) {
const item = { label: data[i].serviceId, parentId: 1 }
children.push(item)
data[i].parentId = 1
data[i].label = data[i].serviceId
children.push(data[i])
}
root.children = children
result.push(root)
return result
},
// table
loadTable: function() {
this.post('route.list', this.searchFormData, function(resp) {
loadTable: function(param) {
const postData = param || this.searchFormData
this.post('route.list', postData, function(resp) {
this.tableData = resp.data
})
},
@@ -267,8 +418,11 @@ export default {
this.loadTable()
},
onTableUpdate: function(row) {
Object.assign(this.routeDialogFormData, row)
this.routeDialogTitle = '修改路由'
this.routeDialogVisible = true
this.$nextTick(() => {
Object.assign(this.routeDialogFormData, row)
})
},
onTableAuth: function(row) {
this.authDialogFormData.routeId = row.id
@@ -283,6 +437,28 @@ export default {
this.authDialogVisible = true
})
},
onTableDel: function(row) {
this.confirm(`确认要删除路由【${row.id}】吗?`, function(done) {
const data = {
serviceId: this.serviceId,
id: row.id
}
this.post('route.del', data, function() {
done()
this.tip('删除成功')
this.loadTable()
})
})
},
onCloseRouteDialog: function() {
this.resetForm('routeDialogFormRef')
},
routePropDisabled: function() {
if (!this.routeDialogFormData.id) {
return false
}
return !this.isCustomService
},
loadRouteRole: function() {
if (this.roles.length === 0) {
this.post('role.listall', {}, function(resp) {
@@ -290,6 +466,15 @@ export default {
})
}
},
addRoute: function() {
this.routeDialogTitle = '新建路由'
this.routeDialogVisible = true
this.$nextTick(() => {
Object.assign(this.routeDialogFormData, {
id: ''
})
})
},
roleRender: function(row) {
if (!row.permission) {
return '(公开)'
@@ -302,18 +487,52 @@ export default {
return html.length > 0 ? html.join(', ') : '<span class="x-red">未授权</span>'
},
onRouteDialogSave: function() {
this.routeDialogFormData.serviceId = this.serviceId
this.post('route.update', this.routeDialogFormData, function() {
this.routeDialogVisible = false
this.loadTable()
this.$refs.routeDialogFormRef.validate((valid) => {
if (valid) {
const uri = this.routeDialogFormData.id ? 'route.update' : 'route.add'
this.routeDialogFormData.serviceId = this.serviceId
this.post(uri, this.routeDialogFormData, function() {
this.routeDialogVisible = false
this.loadTable()
})
}
})
},
onAuthDialogSave: function() {
this.post('route.role.update', this.authDialogFormData, function() {
console.log(this.authDialogFormData)
this.authDialogVisible = false
this.loadTable()
})
},
addService: function() {
this.addServiceDialogVisible = true
},
closeAddServiceDlg: function() {
this.$refs.addServiceForm.resetFields()
},
onAddService: function() {
this.$refs.addServiceForm.validate((valid) => {
if (valid) {
this.post('service.custom.add', this.addServiceForm, function(resp) {
this.addServiceDialogVisible = false
this.tip('添加成功')
this.loadTree()
})
}
})
},
onDelService: function(data) {
const serviceId = data.serviceId
this.confirm('确认要删除服务' + serviceId + '吗,【对应的路由配置会一起删除】', function(done) {
const postData = {
serviceId: serviceId
}
this.post('service.custom.del', postData, function() {
done()
this.tip('删除成功')
this.loadTree()
})
})
}
}
}