# 业务对象
# 概述
业务对象扩展开发是为了支撑精细化权限管理业务需求;本文章以项目管理场景为例介绍如何用Afcenter完成项目展示权限控制、不同角色对项目不同权限的业务需求。
# 项目管理场景介绍
1.用户可以看到自己有权限的项目的列表
2.用户可以创建自己的项目;也可以给其他用户添加项目权限
3.用户通过项目列表点击不同的项目后,进入对应的项目的项目管理主页。根据用户在项目里的角色不同,显示的菜单和业务功能也不一样。
项目管理用例图
例如:张三有项目1和项目2。在项目1中张三是项目经理角色,他进入项目1中,在项目管理主页他可以看到权限维护和项目任务两个菜单,在项目任务中有两个按钮,分别是创建任务和创建bug。
在项目2中张三是开发角色,他进入项目2中,在项目管理主页中只能看到项目任务菜单,在项目任务中只有创建bug的按钮。
# 场景实现效果展示
1.项目列表页面
显示当前登录用户有权限的项目的列表
2.创建项目
当用户创建一个项目后,会默认设置他为这个项目的项目经理角色。
3.业务对象主界面菜单
点击项目编号会进入到项目的项目管理主界面;因为当前用户为项目3的项目经理,所以主界面会显示授权管理和项目任务菜单。
4.给项目添加授权对象
给员工y1赋予开发的角色;那么员工y1在项目3中就是开发的角色,y1可以在项目列表中可以看到项目3,进入项目3主页面显示项目任务的菜单
.选择成员
.下一步添加角色
员工y1对于项目3效果展示
5.功能码
根据不同的角色,显示的业务功能也不一样
# 平台能力介绍
业务对象
为了支撑像项目管理类似的业务场景,afcenter提出了业务对象概念。例如项目就是一个业务对象。在平台中可以给业务对象添加角色、添加页面资源、功能码资源、配置菜单、给角色赋予权限;比如可以给项目这个业务对象添加项目经理、开发经理等角色,配置权限维护和项目任务菜单等。
业务对象实例
例如新创建的一个项目-项目A,然后项目A绑定了项目这个业务对象,那么项目A我们就称它是一个业务对象实例。
业务对象实例和业务对象的关系
一个业务对象实例需要绑定一个业务对象;一个业务对象可以与多个业务对象实例进行绑定。
例如:新建一个项目A,项目A需要绑定业务对象-项目。项目这个业务对象可以与多个项目进行绑定。
当一个业务对象实例和业务对象绑定时。那么这个业务对象实例就有了这个业务对象的角色、菜单、资源等。
# 具体实现
平台提供了对应用和业务对象添加资源、角色的能力,并对其角色进行赋予权限;我们可以通过在平台上操作配置对应用和业务对象进行添加资源、菜单、角色和对角色进行赋予相关权限。
那么我们为了做项目管理业务场景还需要做什么呢?
1.首先需要开发’我的项目‘页面和后端逻辑;新建项目、展示用户有权限的项目的列表;
2.当点击项目编号时进入到项目的项目管理主页的前端处理;
3.授权管理组件使用;
# 平台配置
1.创建应用(业务对象demo)-》创建应用功能资源-》创建应用页面资源
2.创建业务对象(code为project)-》创建业务对象功能资源-》创建业务对象页面资源-》创建业务对象菜单
3.创建平台角色(项目管理)-》创建业务对象角色(项目经理、开发经理、开发角色)
4.平台角色赋权-》业务对象角色赋权
# 自己开发部分
# 前端开发参考
下载objectDemo微前端项目。afc-business-object-demo/business-object-demo-ui/objectDemo
1.我的项目页面
在objectDemo\src\views\projectManagement\list.vue中对项目进行增删改查逻辑参考
2.如何跳转到项目的项目管理主页
<el-table-column sortable="code" label="项目编号" prop="code">
<template slot-scope="{row}">
<!--点击项目编号跳转到业务对象菜单-->
<el-link @click="gotoMenu(row)">{{row.code}}</el-link>
</template>
</el-table-column>
//这些数据都是必须在localStorage中存的
gotoMenu(row){
localStorage.setItem('isobjectMenu',true) //标记是是业务对象菜单
localStorage.setItem('businessObjId',row.businessObjId) //记录业务对象id
//记录业务对象实例id,就是项目id
localStorage.setItem('businessObjInstId',row.id)
//记录项目名称,用于展示业务对象菜单页面的标头
localStorage.setItem('businessObjInstNama',row.name)
//记录当前页面地址,用于从业务对象页面返回
localStorage.setItem('returnPlatformRouter',window.location.href)
//重新路由;重新获取菜单,功能码,会获取到业务对象的菜单和功能码
window.location.href = '/'
}
3.授权界面如何使用
base中已经封装好业务对象授权组件-AuthManage;
需要传入业务对象ID(businessObjId)和业务对象实例ID(businessObjInstId)
<template>
<div >
<AuthManage v-if="businessObjInstId && businessObjId" :businessObjId="businessObjId" :businessObjInstId="businessObjInstId"/>
</div>
</template>
<script>
//引入base中的AuthManage权限管理组件
import {AuthManage} from 'base/components'
export default {
components:{AuthManage},
data() {
return {
businessObjId:null,
businessObjInstId:null
}
},
watch:{
},
mounted() {
//在页面加载时,在localStorage获取到businessObjId和businessObjInstId;给AuthManage组件传值
this.businessObjId = localStorage.getItem("businessObjId")
this.businessObjInstId = localStorage.getItem("businessObjInstId")
},
methods:{
},
}
</script>
# 后端开发参考
下载project后端项目;afc-business-object-demo/business-object-demo-server/project
1.创建项目表
DROP TABLE IF EXISTS `afc_project`;
CREATE TABLE `afc_project` (
`ID` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'ID',
`CODE` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '项目编码',
`NAME` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '项目名称',
`BUSINESS_OBJ_ID` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '业务对象ID',
`CREATE_USER` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人',
`UPDATE_USER` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '修改人',
`CREATE_TIME` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`UPDATE_TIME` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
`TENANT_ID` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '项目表' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
2.新建项目后端逻辑 在ProjectController.java中为项目管理增删改查接口;
当新增项目时,会查询到业务对象code为project的业务对象实例,然后把项目与此业务对象id进行绑定;通过AFCenter角色管理中定义的项目经理code查询项目经理角色实体,并为当前项目创建人赋予项目经理角色。
public void create(Project project, boolean isInit) {
String tenantId;
if (StringUtils.isNotBlank(project.getTenantId())) {
tenantId = project.getTenantId();
} else {
tenantId = TenantManager.getCurrentTenantID();
}
projectDao.getPrimaryKey(project);
project.setTenantId(tenantId);
boolean isExist = isExist(project.getCode(), tenantId);
if (isExist) {
throw AFCExceptionCode.RESOURCE_CODE_EXISTED.runtimeException(project.getCode());
}
//为项目绑定业务对象id
IBusinessObjectAPI businessObjectAPI = afcClient.getBusinessObjectAPI();
BusinessObject businessObject = businessObjectAPI.findBusinessObjectByCode(PROJECT_BUSINESS_OBJECT_CODE);
project.setBusinessObjId(businessObject.getId());
projectDao.insertEntity(project);
//创建项目时为当前用户赋予项目经理角色
PartyRole partyRole = createPartyRole(project.getId(), project.getBusinessObjId());
IAuthAPI authAPI = afcClient.getAuthAPI();
authAPI.handlePartyAuth(partyRole);
}
private PartyRole createPartyRole(String businessObjInstId, String businessObjId) {
String userId = UserManager.getCurrentUserId();
PartyRole partyRole = PartyRole.FACTORY.create();
partyRole.setPartyType(USER_PARTY_TYPE);
partyRole.setPartyId(userId);
partyRole.setRoleType(BUSINESS_OBJECT_ROLE);
IRoleApI roleApI = afcClient.getRoleApI();
//通过项目经理code查询项目经理角色
Role role = roleApI.findRoleByCode(PROJECT_MANAGER_ROLE);
partyRole.setRole(role);
partyRole.setBusinessObjId(businessObjId);
partyRole.setBusinessObjInstId(businessObjInstId);
// 是否固定,手动添加,默认为0,否
partyRole.setIsFixed(role.getIsFixed());
return partyRole;
}
3.查询展示出用户有权限的项目的列表
查询项目时会在code为project的业务对象下,根据当前用户的参与者角色权限查询出该用户所拥有项目的ids集合,再根据ids查询出当前用户所拥有的项目列表。
public PageResultList<Project> queryProjectsByCriteria(String name, String code, String tenantId, int pageSize, int pageIndex, String orderFields, String orderDirection) {
//根据当前登录人权限获取项目列表
IBusinessObjectAPI businessObjectAPI = afcClient.getBusinessObjectAPI();
BusinessObject businessObject = businessObjectAPI.findBusinessObjectByCode(PROJECT_BUSINESS_OBJECT_CODE);
String businessObjId = businessObject.getId();
String userId = UserManager.getCurrentUserId();
PageResultList<Project> pageResultList = new PageResultList<>();
//调用SDK查询当前登陆人所拥有项目实例ids
IAuthAPI authAPI = afcClient.getAuthAPI();
List<String> ids = authAPI.queryBusinessObjInstIdsByUserId(userId, businessObjId);
if (ids != null && ids.size()>0){
pageResultList = projectDao.queryProjectsByCriteria(name, code, ids, tenantId, pageSize, pageIndex, orderFields, orderDirection);
}
return pageResultList;
}