[Core] Add role

This commit is contained in:
qianmoQ 2023-03-08 15:41:09 +08:00
parent 4f0956f8fa
commit 82c7595365
15 changed files with 644 additions and 2 deletions

View File

@ -0,0 +1,49 @@
package io.edurt.datacap.server.controller.admin;
import io.edurt.datacap.server.body.FilterBody;
import io.edurt.datacap.server.common.Response;
import io.edurt.datacap.server.entity.PageEntity;
import io.edurt.datacap.server.entity.RoleEntity;
import io.edurt.datacap.server.repository.RoleRepository;
import io.edurt.datacap.server.service.RoleService;
import io.edurt.datacap.server.validation.ValidationGroup;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/api/v1/admin/role")
public class RoleController
{
private final RoleRepository roleRepository;
private final RoleService roleService;
public RoleController(RoleRepository roleRepository, RoleService roleService)
{
this.roleRepository = roleRepository;
this.roleService = roleService;
}
@PostMapping(value = "list")
public Response<PageEntity<RoleEntity>> getAllByFilter(@RequestBody FilterBody filter)
{
return this.roleService.getAll(roleRepository, filter);
}
@RequestMapping(method = {RequestMethod.POST, RequestMethod.PUT})
public Response<RoleEntity> save(@RequestBody @Validated(ValidationGroup.Crud.Create.class) RoleEntity configure)
{
return this.roleService.saveOrUpdate(roleRepository, configure);
}
@GetMapping(value = "{id}")
public Response<RoleEntity> getInfo(@PathVariable(value = "id") Long id)
{
return this.roleService.getById(roleRepository, id);
}
}

View File

@ -1,5 +1,6 @@
package io.edurt.datacap.server.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -12,6 +13,7 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.sql.Timestamp;
@ -37,5 +39,22 @@ public class RoleEntity
private String description;
@Column(name = "create_time", columnDefinition = "datetime(5) default CURRENT_TIMESTAMP()")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Timestamp createTime;
@Transient
private boolean isDefault;
@Transient
private String code;
public boolean isDefault()
{
return this.getCode().equals("ROLE_ADMIN") || this.getCode().equals("ROLE_USER") ? true : false;
}
public String getCode()
{
return String.format("ROLE_%s", this.name.toUpperCase());
}
}

View File

@ -0,0 +1,29 @@
package io.edurt.datacap.server.service;
import io.edurt.datacap.server.adapter.PageRequestAdapter;
import io.edurt.datacap.server.body.FilterBody;
import io.edurt.datacap.server.common.Response;
import io.edurt.datacap.server.entity.PageEntity;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
public interface BaseService<T>
{
default Response<PageEntity<T>> getAll(PagingAndSortingRepository repository, FilterBody filter)
{
Pageable pageable = PageRequestAdapter.of(filter);
return Response.success(PageEntity.build(repository.findAll(pageable)));
}
default Response<T> getById(PagingAndSortingRepository repository, Long id)
{
return Response.success(repository.findById(id));
}
default Response<T> saveOrUpdate(PagingAndSortingRepository repository, T configure)
{
return Response.success(repository.save(configure));
}
Response<Long> delete(Long id);
}

View File

@ -0,0 +1,8 @@
package io.edurt.datacap.server.service;
import io.edurt.datacap.server.entity.RoleEntity;
public interface RoleService
extends BaseService<RoleEntity>
{
}

View File

@ -0,0 +1,24 @@
package io.edurt.datacap.server.service.impl;
import io.edurt.datacap.server.common.Response;
import io.edurt.datacap.server.repository.RoleRepository;
import io.edurt.datacap.server.service.RoleService;
import org.springframework.stereotype.Service;
@Service
public class RoleServiceImpl
implements RoleService
{
private final RoleRepository roleRepository;
public RoleServiceImpl(RoleRepository roleRepository)
{
this.roleRepository = roleRepository;
}
@Override
public Response<Long> delete(Long id)
{
return null;
}
}

View File

@ -77,5 +77,8 @@ export default {
ip: 'IP',
ua: 'User Agent',
loginTime: 'Login Time',
ssl: 'SSL'
ssl: 'SSL',
id: 'ID',
authority: 'Authority',
code: 'Code'
}

View File

@ -77,5 +77,8 @@ export default {
ip: 'IP',
ua: '用户代理',
loginTime: '登录时间',
ssl: 'SSL'
ssl: 'SSL',
id: 'ID',
authority: '权限',
code: '代码',
}

View File

@ -0,0 +1,67 @@
export class Pagination
{
current = 1;
total = 0;
size = 10;
constructor(builder: PaginationBuilder)
{
this.current = builder.current;
this.total = builder.total;
this.size = builder.size;
}
}
export class PaginationBuilder
{
private _current: number;
private _total: number;
private _size: number;
setCurrent(value: number)
{
this._current = value;
return this;
}
setTotal(value: number)
{
this._total = value;
return this;
}
setSize(value: number)
{
this._size = value;
return this;
}
get current(): number
{
return this._current;
}
get total(): number
{
return this._total;
}
get size(): number
{
return this._size;
}
build()
{
return new Pagination(this);
}
static newInstance(): Pagination
{
return new PaginationBuilder()
.setCurrent(1)
.setTotal(0)
.setSize(10)
.build();
}
}

View File

@ -135,6 +135,13 @@ const routes: Array<RouteRecordRaw> = [
component: () => import("../views/pages/admin/monitor/processor/ProcessorAdmin.vue")
}
]
},
{
path: "role",
meta: {
roles: ['Admin']
},
component: () => import("@/views/admin/role/RoleHome.vue")
}
]
},

View File

@ -0,0 +1,62 @@
import {Filter} from "@/model/Filter";
import {ResponseModel} from "@/model/ResponseModel";
import {HttpCommon} from "@/common/HttpCommon";
export abstract class BaseService<T>
{
private readonly baseUrl: string;
protected constructor(baseUrl: string)
{
this.baseUrl = baseUrl;
}
/**
* Filter the corresponding data according to the filter
* <p>
* If the filter is empty, all data will be returned.
* Supported filters:
* <ul>
* <li>paging</li>
* <li>order</li>
* </ul>
* </p>
* @param {Filter} filter
* @param filter
*/
getAll<T>(filter: Filter): Promise<ResponseModel>
{
return new HttpCommon().post(`${this.baseUrl}/list`, filter);
}
/**
* Filter the corresponding data according to the id
* @param id
*/
getById<T>(id: number): Promise<ResponseModel>
{
return new HttpCommon().get(`${this.baseUrl}/${id}`);
}
/**
* Report an error or update data, if id > 0 in the data, it is updated, otherwise it is saved
* @param configure
*/
saveOrUpdate<T>(configure: T): Promise<ResponseModel>
{
if (configure['id'] > 0) {
return new HttpCommon().put(this.baseUrl, configure);
}
else {
return new HttpCommon().post(this.baseUrl, configure);
}
}
/**
* Filter the corresponding data according to the name
* @param name
*/
abstract getByName<T>(name: string): Promise<ResponseModel>;
abstract deleteById(id: number): Promise<ResponseModel>;
}

View File

@ -0,0 +1,58 @@
export class Role
{
id = 0;
name: string;
description: string;
constructor(builder: RoleBuilder)
{
this.id = builder.id;
this.name = builder.name;
this.description = builder.description;
}
}
export class RoleBuilder
{
private _id: number;
private _name: string;
private _description: string;
setId(value: number)
{
this._id = value;
return this;
}
setName(value: string)
{
this._name = value;
return this;
}
setDescription(value: string)
{
this._description = value;
return this;
}
get id(): number
{
return this._id;
}
get name(): string
{
return this._name;
}
get description(): string
{
return this._description;
}
build()
{
return new Role(this);
}
}

View File

@ -0,0 +1,27 @@
import {ResponseModel} from '@/model/ResponseModel'
import {BaseService} from "@/services/BaseService";
import {Role} from "@/services/admin/RoleModel";
const baseUrl = '/api/v1/admin/role'
class RoleService
extends BaseService<Role>
{
constructor()
{
super(baseUrl);
}
deleteById(id: number): Promise<ResponseModel>
{
throw new Error('Method not implemented.');
}
getByName<T>(name: string): Promise<ResponseModel>
{
return Promise.resolve(undefined);
}
}
export default new RoleService()

View File

@ -0,0 +1,135 @@
<template>
<div>
<Drawer :title="title" :width="720" :closable="false" v-model="visible" :maskClosable="false" :z-index="9">
<Form :model="formState" ref="formValidate" :rules="ruleValidate">
<FormItem v-if="formState.id > 0" :label="$t('common.id')" :label-width="80" prop="id">
<Input v-model="formState.id" :disabled="formState.id > 0"/>
</FormItem>
<FormItem :label="$t('common.name')" :label-width="80" prop="name">
<Input v-model="formState.name"/>
</FormItem>
<FormItem :label="$t('common.description')" :label-width="80" prop="description">
<Input type="textarea" :rows="10" v-model="formState.description"/>
</FormItem>
</Form>
<div class="datacap-drawer-footer">
<Button :disabled="saving" style="margin-right: 8px" @click="handlerCancel()">{{ $t('common.cancel') }}</Button>
<Button type="primary" :loading="saving" @click="handlerSave()">{{ $t('common.submit') }}</Button>
</div>
<Spin size="large" fix :show="loading"></Spin>
</Drawer>
</div>
</template>
<script lang="ts">
import {defineComponent, reactive} from 'vue';
import {Role, RoleBuilder} from "@/services/admin/RoleModel";
import {useI18n} from "vue-i18n";
import RoleService from "@/services/admin/RoleService";
export default defineComponent({
name: 'RoleDetails',
props: {
isVisible: {
type: Boolean,
default: () => false
},
id: {
type: Number,
default: () => 0
}
},
data()
{
return {
loading: false,
saving: false,
formState: null as Role,
title: null,
ruleValidate: {
name: [
{required: true}
],
description: [
{required: true}
]
}
}
},
created()
{
const role: Role = new RoleBuilder().build();
this.formState = reactive<Role>(role);
this.handlerInitialize();
},
methods: {
handlerInitialize()
{
const i18n = useI18n();
this.title = i18n.t('common.create');
if (this.id > 0) {
this.title = i18n.t('common.modify');
this.loading = true;
RoleService.getById(this.id)
.then(response => {
if (response.status) {
this.formState = reactive<Role>(response.data);
}
})
.finally(() => {
this.loading = false;
});
}
this.title += i18n.t('common.authority');
},
handlerSave()
{
this.$refs['formValidate'].validate((valid) => {
if (valid) {
this.saving = true;
RoleService.saveOrUpdate(this.formState)
.then(response => {
if (response.status) {
this.$Message.success("successful");
this.handlerCancel();
}
else {
this.$Message.error(response.message);
}
})
.finally(() => {
this.saving = false;
});
}
});
},
handlerCancel()
{
this.visible = false;
}
},
computed: {
visible: {
get(): boolean
{
return this.isVisible
},
set(value: boolean)
{
this.$emit('close', value)
}
}
},
});
</script>
<style scoped>
.datacap-drawer-footer {
width: 100%;
position: absolute;
bottom: 0;
left: 0;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: right;
background: #fff;
}
</style>

View File

@ -0,0 +1,39 @@
const createHeaders = (i18n: any) => {
return [
{
title: i18n.t('common.id'),
key: 'id',
ellipsis: true,
tooltip: true
},
{
title: i18n.t('common.name'),
key: 'name',
ellipsis: true
},
{
title: i18n.t('common.code'),
key: 'code',
ellipsis: true
},
{
title: i18n.t('common.description'),
key: 'description',
},
{
title: i18n.t('common.createTime'),
key: 'createTime',
},
{
title: i18n.t('common.action'),
slot: 'action',
key: 'action',
width: 150,
align: 'center'
}
];
};
export {
createHeaders
}

View File

@ -0,0 +1,112 @@
<template>
<div>
<Card style="width:100%" :title="$t('common.authority')">
<template #extra>
<Tooltip>
<template #content>{{ $t('common.create') }}</template>
<Button type="primary" shape="circle" icon="md-add" size="small" @click="handlerVisibleDetail(null, true)"/>
</Tooltip>
</template>
<Table :loading="loading" :columns="headers" :data="finalData?.content">
<template #action="{ row }">
<Space>
<Tooltip :content="$t('common.modify')" transfer>
<Button shape="circle" :disabled="row.default" type="primary" size="small" icon="md-create" @click="handlerVisibleDetail(row.id, true)"/>
</Tooltip>
</Space>
</template>
</Table>
<p v-if="!loading" style="margin-top: 10px;">
<Page v-model="pagination.current" :total="pagination.total" :page-size="pagination.size" show-sizer show-elevator show-total
@on-page-size-change="handlerSizeChange" @on-change="handlerIndexChange"/>
</p>
</Card>
<RoleDetails v-if="visibleDetail" :isVisible="visibleDetail" :id="applyId" @close="handlerVisibleDetail(null, $event)"/>
</div>
</template>
<script lang="ts">
import {defineComponent} from 'vue'
import {useI18n} from 'vue-i18n';
import {createHeaders} from "@/views/admin/role/RoleGenerate";
import RoleService from "@/services/admin/RoleService";
import {Filter} from "@/model/Filter";
import {ResponsePage} from "@/model/ResponsePage";
import RoleDetails from "@/views/admin/role/RoleDetails.vue";
import {Pagination, PaginationBuilder} from "@/model/Pagination";
const filter: Filter = new Filter();
const pagination: Pagination = PaginationBuilder.newInstance();
export default defineComponent({
name: 'AdminRoleHome',
components: {RoleDetails},
setup()
{
const i18n = useI18n();
const headers = createHeaders(i18n);
return {
headers,
filter,
pagination
}
},
data()
{
return {
loading: false,
visibleDetail: false,
applyId: null,
finalData: null as ResponsePage
}
},
created()
{
this.handlerInitialize(this.filter);
},
methods: {
handlerInitialize(filter: Filter)
{
this.loading = true;
RoleService.getAll(filter)
.then((response) => {
if (response.status) {
this.finalData = response.data;
this.pagination.total = response.data.total;
}
})
.finally(() => {
this.loading = false
})
},
handlerVisibleDetail(value: number, isOpened: boolean)
{
if (isOpened) {
this.applyId = value;
this.visibleDetail = true;
}
else {
this.applyId = null;
this.visibleDetail = false;
}
},
handlerSizeChange(size: number)
{
this.pagination.size = size;
this.handlerTableChange(this.pagination);
},
handlerIndexChange(index: number)
{
this.pagination.current = index;
this.handlerTableChange(this.pagination);
},
handlerTableChange(pagination: any)
{
this.pagination.current = pagination.current;
this.pagination.size = pagination.size;
this.filter.page = pagination.current;
this.filter.size = pagination.size;
this.handlerInitialize(this.filter);
}
}
})
</script>