本文章主要用来介绍如何集成在 datacap 中开发新的功能UI篇。我们这里以 github 中的 issues-481 为例来讲解。
准备工作
重要 克隆源码到本地(如果您需要提交代码到主仓库中需要先将源码 fork 到您的 github 账户中)
git clone https://github.com/devlive-community/datacap.git
如果您已经 fork 源码到您的账户中,请将
devlive-community替换为您的 github 账户的 ID
重要 以下是基本的环境配置
| 环境 | 版本 | 必需 |
|---|---|---|
JDK | 1.8 | 11 | 必须 |
Maven | >= 3.5 | 可选 |
IDEA | Eclipse | 其他 | 任意版本 | 必须 |
在本文中我们使用的是
IDEA编辑器环境,用户可以根据自己喜好更换相应编辑器。
可参考 服务端 文档中的 加载源码到 IDEA 部分。
UI 端的源码大致可以分为以下部分:
- 构建菜单
- 构建 Vue 页面
构建菜单
如果构建的功能不支持菜单,可以忽略此步骤。此操作需要登录管理员权限。
构建菜单可以参考 管理菜单。
该功能的配置如下
跳转到权限模块进行新菜单权限的分配。
国际化配置
在修改国际化配置需要修改两个配置文件(如果增加了其他的国际化文件修改的会更多)
core/datacap-web/src/i18n/langs/en/common.tscore/datacap-web/src/i18n/langs/zhCn/common.ts
在文件中增加以下代码
report: 'Report'
report: '报表'
构建资源访问器
在 core/datacap-web/src/services/admin 目录下新建 ReportService.ts 文件,代码如下:
import {ResponseModel} from '@/model/ResponseModel';
import {BaseService} from '@/services/BaseService';
const baseUrl = '/api/v1/report';
class ReportService
extends BaseService<any>
{
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 ReportService();
构建 Vue 页面
在 core/datacap-web/src/views/admin 目录下新建 report 目录,并在该文件夹下创建 ReportUtils.ts 文件,代码如下:
const createHeaders = (i18n: any) => {
return [
{
title: i18n.t('common.no'),
key: 'id',
sortable: 'custom'
},
{
title: i18n.t('common.name'),
key: 'name'
},
{
title: i18n.t('common.type'),
key: 'type'
},
{
title: i18n.t('common.createTime'),
key: 'createTime',
ellipsis: true,
tooltip: true
},
{
title: i18n.t('common.endTime'),
key: 'endTime',
ellipsis: true,
tooltip: true
},
{
title: i18n.t('common.action'),
slot: 'action',
key: 'action'
}
];
}
export {
createHeaders
};
在 core/datacap-web/src/views/admin 目录下新建 report 目录,并在该文件夹下创建 AdminReport.vue 文件,代码如下:
<template>
<div>
<Card style="width:100%"
:title="$t('common.report')"
dis-hover>
<Table :loading="loading"
:columns="headers"
:data="data.content">
<template #action="{ row }">
<Space>
</Space>
</template>
</Table>
<p v-if="!loading"
style="margin-top: 10px;">
<Page v-model="pagination.current"
show-sizer
show-elevator
show-total
:total="pagination.total"
:page-size="pagination.pageSize"
@on-page-size-change="handlerSizeChange"
@on-change="handlerIndexChange">
</Page>
</p>
</Card>
</div>
</template>
<script lang="ts">
import {defineComponent} from "vue";
import {useI18n} from 'vue-i18n';
import Common from "@/common/Common";
import {ResponsePage} from "@/model/ResponsePage";
import {createHeaders} from "@/views/admin/report/ReportUtils";
import ReportService from "@/services/admin/ReportService";
import {Filter} from "@/model/Filter";
import {Pagination, PaginationBuilder} from "@/model/Pagination";
const filter: Filter = new Filter();
const pagination: Pagination = PaginationBuilder.newInstance();
export default defineComponent({
name: "ReportAdmin",
setup()
{
const i18n = useI18n();
const headers = createHeaders(i18n);
const currentUserId = Common.getCurrentUserId();
return {
headers,
filter,
currentUserId
}
},
data()
{
return {
data: ResponsePage,
loading: false,
pagination: {
total: 0,
current: 1,
pageSize: 10
}
}
},
created()
{
this.handlerInitialize(this.filter);
},
methods: {
handlerInitialize(filter: Filter)
{
this.loading = true;
ReportService.getAll(filter)
.then((response) => {
if (response.status) {
this.data = response.data;
this.pagination.total = response.data.total;
}
this.loading = false;
})
},
handlerSizeChange(size: number)
{
this.pagination.pageSize = 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.pageSize = pagination.pageSize;
this.handlerInitialize(this.filter)
}
}
});
</script>