parent
5906272775
commit
6ff5a0c0f7
@ -0,0 +1,74 @@
|
||||
syntax = "proto3";
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "gogoproto/gogo.proto";
|
||||
// import "validate/validate.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
|
||||
package api.v1;
|
||||
|
||||
option go_package = "moredoc/api/v1;v1";
|
||||
option java_multiple_files = true;
|
||||
option java_package = "api.v1";
|
||||
|
||||
message Permission {
|
||||
int64 id = 1;
|
||||
string method = 2;
|
||||
string path = 3;
|
||||
string title = 4;
|
||||
string description = 5;
|
||||
google.protobuf.Timestamp created_at = 6 [ (gogoproto.stdtime) = true ];
|
||||
google.protobuf.Timestamp updated_at = 7 [ (gogoproto.stdtime) = true ];
|
||||
}
|
||||
|
||||
message DeletePermissionRequest { repeated int64 id = 1; }
|
||||
|
||||
message GetPermissionRequest { int64 id = 1; }
|
||||
|
||||
message GetPermissionReply { Permission permission = 1; }
|
||||
|
||||
message ListPermissionRequest {
|
||||
int64 page = 1;
|
||||
int64 size = 2;
|
||||
string wd = 3;
|
||||
repeated string method = 4;
|
||||
string path = 5;
|
||||
}
|
||||
|
||||
message ListPermissionReply {
|
||||
int64 total = 1;
|
||||
repeated Permission permission = 2;
|
||||
}
|
||||
|
||||
// message PermissionTree {
|
||||
// Permission permission = 1;
|
||||
// repeated PermissionTree children = 2;
|
||||
// }
|
||||
|
||||
service PermissionAPI {
|
||||
rpc UpdatePermission(Permission) returns (google.protobuf.Empty) {
|
||||
option (google.api.http) = {
|
||||
put : '/api/v1/permission',
|
||||
body : '*',
|
||||
};
|
||||
}
|
||||
|
||||
rpc GetPermission(GetPermissionRequest) returns (Permission) {
|
||||
option (google.api.http) = {
|
||||
get : '/api/v1/permission',
|
||||
};
|
||||
}
|
||||
|
||||
rpc ListPermission(ListPermissionRequest) returns (ListPermissionReply) {
|
||||
option (google.api.http) = {
|
||||
get : '/api/v1/permission/list',
|
||||
};
|
||||
}
|
||||
|
||||
// rpc ListPermissionTree(google.protobuf.Empty) returns (PermissionTree) {
|
||||
// option (google.api.http) = {
|
||||
// get : '/api/v1/permission/tree',
|
||||
// };
|
||||
// }
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pb "moredoc/api/v1"
|
||||
"moredoc/middleware/auth"
|
||||
"moredoc/model"
|
||||
"moredoc/util"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
type PermissionAPIService struct {
|
||||
pb.UnimplementedPermissionAPIServer
|
||||
dbModel *model.DBModel
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewPermissionAPIService(dbModel *model.DBModel, logger *zap.Logger) (service *PermissionAPIService) {
|
||||
return &PermissionAPIService{dbModel: dbModel, logger: logger.Named("PermissionAPIService")}
|
||||
}
|
||||
|
||||
func (s *PermissionAPIService) checkPermission(ctx context.Context) (*auth.UserClaims, error) {
|
||||
return checkGRPCPermission(s.dbModel, ctx)
|
||||
}
|
||||
|
||||
// UpdatePermission 编辑权限信息。这里只能更新名称和描述,不能更新权限项。
|
||||
func (s *PermissionAPIService) UpdatePermission(ctx context.Context, req *pb.Permission) (*emptypb.Empty, error) {
|
||||
_, err := s.checkPermission(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = s.dbModel.UpdatePermission(&model.Permission{
|
||||
Id: req.Id,
|
||||
Title: req.Title,
|
||||
Description: req.Description,
|
||||
}, "title", "description")
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return &emptypb.Empty{}, nil
|
||||
}
|
||||
|
||||
// GetPermission 查询单个权限信息
|
||||
func (s *PermissionAPIService) GetPermission(ctx context.Context, req *pb.GetPermissionRequest) (*pb.Permission, error) {
|
||||
_, err := s.checkPermission(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
permission, err := s.dbModel.GetPermission(req.Id)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
pbPermission := &pb.Permission{}
|
||||
util.CopyStruct(&permission, pbPermission)
|
||||
|
||||
return pbPermission, nil
|
||||
}
|
||||
|
||||
// ListPermission 查询权限列表
|
||||
func (s *PermissionAPIService) ListPermission(ctx context.Context, req *pb.ListPermissionRequest) (*pb.ListPermissionReply, error) {
|
||||
_, err := s.checkPermission(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
opt := &model.OptionGetPermissionList{
|
||||
Page: int(req.Page),
|
||||
Size: int(req.Size_),
|
||||
WithCount: true,
|
||||
QueryLike: make(map[string][]interface{}),
|
||||
QueryIn: make(map[string][]interface{}),
|
||||
}
|
||||
|
||||
if req.Wd != "" {
|
||||
opt.QueryLike["title"] = []interface{}{req.Wd}
|
||||
opt.QueryLike["description"] = []interface{}{req.Wd}
|
||||
}
|
||||
|
||||
if req.Path != "" {
|
||||
opt.QueryLike["path"] = []interface{}{req.Path}
|
||||
}
|
||||
|
||||
if len(req.Method) > 0 {
|
||||
opt.QueryIn["method"] = util.Slice2Interface(req.Method)
|
||||
}
|
||||
|
||||
permissions, total, err := s.dbModel.GetPermissionList(opt)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
var pbPermissions []*pb.Permission
|
||||
util.CopyStruct(&permissions, &pbPermissions)
|
||||
|
||||
return &pb.ListPermissionReply{
|
||||
Total: total,
|
||||
Permission: pbPermissions,
|
||||
}, nil
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
import service from '~/utils/request'
|
||||
|
||||
export const updatePermission = (data) => {
|
||||
return service({
|
||||
url: '/api/v1/permission',
|
||||
method: 'put',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
export const getPermission = (params) => {
|
||||
return service({
|
||||
url: '/api/v1/permission',
|
||||
method: 'get',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
export const listPermission = (params) => {
|
||||
return service({
|
||||
url: '/api/v1/permission/list',
|
||||
method: 'get',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="com-form-permission">
|
||||
<el-form
|
||||
ref="formPermission"
|
||||
label-position="top"
|
||||
label-width="80px"
|
||||
:model="permission"
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="Method" prop="method">
|
||||
<el-input v-model="permission.method" :disabled="true"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<el-form-item label="API" prop="path">
|
||||
<el-input v-model="permission.path" :disabled="true"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item
|
||||
label="名称"
|
||||
prop="title"
|
||||
:rules="[
|
||||
{ required: true, trigger: 'blur', message: '请输入权限名称' },
|
||||
]"
|
||||
>
|
||||
<el-input
|
||||
v-model="permission.title"
|
||||
placeholder="请输入权限名称"
|
||||
clearable
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述">
|
||||
<el-input
|
||||
v-model="permission.description"
|
||||
type="textarea"
|
||||
rows="5"
|
||||
placeholder="请输入权限相关描述或备注"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
class="btn-block"
|
||||
icon="el-icon-check"
|
||||
:loading="loading"
|
||||
@click="onSubmit"
|
||||
>提交</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { updatePermission } from '~/api/permission'
|
||||
export default {
|
||||
name: 'FormPermission',
|
||||
props: {
|
||||
initPermission: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
permission: {
|
||||
id: 0,
|
||||
title: '',
|
||||
description: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
initPermission: {
|
||||
handler(val) {
|
||||
this.permission = val
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.permission = this.initPermission
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
this.$refs.formPermission.validate(async (valid) => {
|
||||
if (!valid) {
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
const permission = { ...this.permission }
|
||||
if (this.permission.id > 0) {
|
||||
const res = await updatePermission(permission)
|
||||
if (res.status === 200) {
|
||||
this.$message.success('修改成功')
|
||||
this.resetFields()
|
||||
this.$emit('success', res.data)
|
||||
} else {
|
||||
this.$message.error(res.data.message)
|
||||
}
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
clearValidate() {
|
||||
this.$refs.formPermission.clearValidate()
|
||||
},
|
||||
resetFields() {
|
||||
this.$refs.formPermission.resetFields()
|
||||
},
|
||||
reset() {
|
||||
this.resetFields()
|
||||
this.clearValidate()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
@ -1,10 +1,183 @@
|
||||
<template>
|
||||
<div>{{ $route.name }}</div>
|
||||
<div>
|
||||
<el-card shadow="never" class="search-card">
|
||||
<FormSearch
|
||||
:fields="searchFormFields"
|
||||
:loading="loading"
|
||||
:show-create="false"
|
||||
:show-delete="false"
|
||||
:disabled-delete="selectedRow.length === 0"
|
||||
@onSearch="onSearch"
|
||||
/>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mgt-20px">
|
||||
<TableList
|
||||
:table-data="listData"
|
||||
:fields="tableListFields"
|
||||
:show-actions="true"
|
||||
:show-view="false"
|
||||
:show-edit="true"
|
||||
:show-delete="false"
|
||||
:show-select="false"
|
||||
:actions-min-width="'70px'"
|
||||
@editRow="editRow"
|
||||
/>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mgt-20px">
|
||||
<div class="text-right">
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="search.page"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="search.size"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handlePageChange"
|
||||
>
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog title="编辑附件" width="640px" :visible.sync="formVisible">
|
||||
<FormPermission :init-permission="permission" @success="formSuccess" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listPermission, getPermission } from '~/api/permission'
|
||||
import TableList from '~/components/TableList.vue'
|
||||
import FormSearch from '~/components/FormSearch.vue'
|
||||
import FormPermission from '~/components/FormPermission.vue'
|
||||
import { methodOptions } from '~/utils/enum'
|
||||
export default {
|
||||
components: { TableList, FormSearch, FormPermission },
|
||||
layout: 'admin',
|
||||
created() {},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
formVisible: false,
|
||||
search: {
|
||||
wd: '',
|
||||
page: 1,
|
||||
size: 10,
|
||||
},
|
||||
listData: [],
|
||||
total: 0,
|
||||
searchFormFields: [],
|
||||
tableListFields: [],
|
||||
selectedRow: [],
|
||||
permission: {},
|
||||
methodOptions,
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
this.initSearchForm()
|
||||
this.initTableListFields()
|
||||
await this.listPermission()
|
||||
},
|
||||
methods: {
|
||||
async listPermission() {
|
||||
this.loading = true
|
||||
const res = await listPermission(this.search)
|
||||
if (res.status === 200) {
|
||||
this.listData = res.data.permission
|
||||
this.total = res.data.total
|
||||
} else {
|
||||
this.$message.error(res.data.message)
|
||||
}
|
||||
this.loading = false
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.search.size = val
|
||||
this.listPermission()
|
||||
},
|
||||
handlePageChange(val) {
|
||||
this.search.page = val
|
||||
this.listPermission()
|
||||
},
|
||||
onSearch(search) {
|
||||
this.search = { ...this.search, page: 1, ...search }
|
||||
this.listPermission()
|
||||
},
|
||||
async editRow(row) {
|
||||
const res = await getPermission({ id: row.id })
|
||||
if (res.status === 200) {
|
||||
this.permission = res.data
|
||||
this.formVisible = true
|
||||
} else {
|
||||
this.$message.error(res.data.message)
|
||||
}
|
||||
},
|
||||
formSuccess() {
|
||||
this.formVisible = false
|
||||
this.listPermission()
|
||||
},
|
||||
initSearchForm() {
|
||||
this.searchFormFields = [
|
||||
{
|
||||
type: 'text',
|
||||
label: '关键字',
|
||||
name: 'wd',
|
||||
placeholder: '请输入关键字',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
label: 'API',
|
||||
name: 'path',
|
||||
placeholder: '请输入API',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: 'Method',
|
||||
name: 'method',
|
||||
placeholder: '请选择Method',
|
||||
multiple: true,
|
||||
options: this.methodOptions,
|
||||
},
|
||||
]
|
||||
},
|
||||
initTableListFields() {
|
||||
const methodEnum = {
|
||||
GET: {
|
||||
label: 'GET',
|
||||
type: 'info',
|
||||
},
|
||||
POST: {
|
||||
label: 'POST',
|
||||
type: 'success',
|
||||
},
|
||||
GRPC: {
|
||||
label: 'GRPC',
|
||||
type: 'primary',
|
||||
},
|
||||
PUT: {
|
||||
label: 'PUT',
|
||||
type: 'warning',
|
||||
},
|
||||
DELETE: {
|
||||
label: 'DELETE',
|
||||
type: 'danger',
|
||||
},
|
||||
}
|
||||
this.tableListFields = [
|
||||
// { prop: 'id', label: 'ID', width: 80, type: 'number', fixed: 'left' },
|
||||
{ prop: 'title', label: '名称', width: 240, fixed: 'left' },
|
||||
{ prop: 'description', label: '描述', minWidth: 150 },
|
||||
{
|
||||
prop: 'method',
|
||||
label: 'Method',
|
||||
width: 80,
|
||||
type: 'enum',
|
||||
enum: methodEnum,
|
||||
},
|
||||
{ prop: 'path', label: 'API', minWidth: 150 },
|
||||
{ prop: 'created_at', label: '创建时间', width: 160, type: 'datetime' },
|
||||
{ prop: 'updated_at', label: '更新时间', width: 160, type: 'datetime' },
|
||||
]
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
|
Loading…
Reference in new issue