api接口文档支持用户权限控制

This commit is contained in:
暮光:城中城
2021-12-11 22:36:05 +08:00
parent a2553097bd
commit 9dfb8f9ac6
59 changed files with 1701 additions and 479 deletions

View File

@@ -0,0 +1,228 @@
package com.zyplayer.doc.data.repository.manage.vo;
import java.io.Serializable;
import java.util.Date;
/**
* api文档地址Vo
*
* @author 暮光:城中城
* @since 2021-11-25
*/
public class ApiDocVo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 权限类型
*/
private Integer authType;
/**
* id
*/
private Long id;
/**
* 文档名称
*/
private String name;
/**
* 文档类型 1=swagger url 2=swagger json 3=openapi url 4=openapi json 5=自建API分组
*/
private Integer docType;
/**
* 文档URL地址
*/
private String docUrl;
/**
* 文档json内容
*/
private String jsonContent;
/**
* 重写的域名
*/
private String rewriteDomain;
/**
* 是否开放访问 0=否 1=是
*/
private Integer openVisit;
/**
* 状态 1=启用 2=禁用
*/
private Integer docStatus;
/**
* 开放文档UUID
*/
private String shareUuid;
/**
* 开放文档使用说明
*/
private String shareInstruction;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人名字
*/
private String createUserName;
/**
* 创建时间
*/
private Date createTime;
/**
* 是否有效 0=无效 1=有效
*/
private Integer yn;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getDocType() {
return docType;
}
public void setDocType(Integer docType) {
this.docType = docType;
}
public String getDocUrl() {
return docUrl;
}
public void setDocUrl(String docUrl) {
this.docUrl = docUrl;
}
public String getJsonContent() {
return jsonContent;
}
public void setJsonContent(String jsonContent) {
this.jsonContent = jsonContent;
}
public String getRewriteDomain() {
return rewriteDomain;
}
public void setRewriteDomain(String rewriteDomain) {
this.rewriteDomain = rewriteDomain;
}
public Integer getOpenVisit() {
return openVisit;
}
public void setOpenVisit(Integer openVisit) {
this.openVisit = openVisit;
}
public Integer getDocStatus() {
return docStatus;
}
public void setDocStatus(Integer docStatus) {
this.docStatus = docStatus;
}
public Long getCreateUserId() {
return createUserId;
}
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getYn() {
return yn;
}
public void setYn(Integer yn) {
this.yn = yn;
}
@Override
public String toString() {
return "ApiDoc{" +
"id=" + id +
", name=" + name +
", docType=" + docType +
", docUrl=" + docUrl +
", jsonContent=" + jsonContent +
", rewriteDomain=" + rewriteDomain +
", openVisit=" + openVisit +
", docStatus=" + docStatus +
", createUserId=" + createUserId +
", createUserName=" + createUserName +
", createTime=" + createTime +
", yn=" + yn +
"}";
}
public String getShareUuid() {
return shareUuid;
}
public void setShareUuid(String shareUuid) {
this.shareUuid = shareUuid;
}
public String getShareInstruction() {
return shareInstruction;
}
public void setShareInstruction(String shareInstruction) {
this.shareInstruction = shareInstruction;
}
public Integer getAuthType() {
return authType;
}
public void setAuthType(Integer authType) {
this.authType = authType;
}
}

View File

@@ -0,0 +1,43 @@
package com.zyplayer.doc.data.repository.support.consts;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* api授权前缀
*
* @author 暮光:城中城
* @since 2021-12-12
*/
public enum ApiAuthType {
MANAGE(1, "API_DOC_MANAGE"),
DEVELOPER(2, "API_DOC_DEVELOPER"),
;
private final Integer type;
private final String code;
ApiAuthType(Integer type, String code) {
this.type = type;
this.code = code;
}
public Integer getType() {
return type;
}
public String getCode() {
return code;
}
private static final Map<Integer, ApiAuthType> API_AUTH_TYPE_MAP = Stream.of(values()).collect(Collectors.toMap(ApiAuthType::getType, (deriveType) -> deriveType));
private static final Map<String, ApiAuthType> API_AUTH_CODE_MAP = Stream.of(values()).collect(Collectors.toMap(ApiAuthType::getCode, (deriveType) -> deriveType));
public static ApiAuthType typeOf(Integer type) {
return API_AUTH_TYPE_MAP.get(type);
}
public static ApiAuthType typeOf(String code) {
return API_AUTH_CODE_MAP.get(code);
}
}

View File

@@ -7,12 +7,10 @@ package com.zyplayer.doc.data.repository.support.consts;
* @since 2019-08-22
*/
public class DocAuthConst {
public static final String DB = "DB_";
public static final String WIKI = "WIKI_";
public static final String DB_DATASOURCE_MANAGE = "DB_DATASOURCE_MANAGE";
public static final String ES_DATASOURCE_MANAGE = "ES_DATASOURCE_MANAGE";
public static final String USER_MANAGE = "USER_MANAGE";
public static final String AUTH_MANAGE = "AUTH_MANAGE";
public static final String AUTH_ASSIGN = "AUTH_ASSIGN";
}

View File

@@ -8,7 +8,7 @@ package com.zyplayer.doc.data.repository.support.consts;
*/
public enum DocSysType {
// 系统类型 1=manage 2=wiki 3=db
MANAGE(1), WIKI(2), DB(3),
MANAGE(1), WIKI(2), DB(3), API(4),
;
DocSysType(int type) {

View File

@@ -1,8 +1,11 @@
package com.zyplayer.doc.data.service.manage;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zyplayer.doc.data.repository.manage.entity.ApiDoc;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zyplayer.doc.data.repository.manage.entity.ApiDoc;
import com.zyplayer.doc.data.repository.manage.vo.ApiDocVo;
import java.util.List;
/**
* <p>
@@ -13,7 +16,27 @@ import com.baomidou.mybatisplus.extension.service.IService;
* @since 2021-11-25
*/
public interface ApiDocService extends IService<ApiDoc> {
IPage<ApiDoc> getApiDocList(ApiDoc apiDoc, Integer pageNum, Integer pageSize);
/**
* 用于管理列表搜索
*
* @author 暮光:城中城
* @since 2021-12-12
*/
IPage<ApiDocVo> getApiDocList(ApiDoc apiDoc, Integer pageNum, Integer pageSize);
/**
* 用于获取左侧可下拉接口列表
*
* @author 暮光:城中城
* @since 2021-12-12
*/
List<ApiDoc> getApiDocList();
/**
* 通过开放文档uuid查询
*
* @author 暮光:城中城
* @since 2021-12-12
*/
ApiDoc getByShareUuid(String shareUuid);
}

View File

@@ -12,5 +12,6 @@ import com.zyplayer.doc.data.repository.manage.entity.AuthInfo;
* @since 2018-12-03
*/
public interface AuthInfoService extends IService<AuthInfo> {
AuthInfo getByCode(String authCode);
}

View File

@@ -16,5 +16,14 @@ import java.util.List;
*/
public interface UserAuthService extends IService<UserAuth> {
List<UserAuthVo> getUserAuthSet(Long id);
List<UserAuthVo> getUserAuthSet(Long userId);
List<UserAuth> getModuleAuthList(Integer sysType, Integer sysModuleType, Long sysModuleId);
List<UserAuth> getUserModuleAuthList(Long userId, Integer sysType, Integer sysModuleType, Long sysModuleId);
boolean deleteModuleAuth(Integer sysType, Integer sysModuleType, Long sysModuleId);
boolean deleteUserModuleAuth(Long userId, Integer sysType, Integer sysModuleType, Long sysModuleId);
}

View File

@@ -1,14 +1,29 @@
package com.zyplayer.doc.data.service.manage.impl;
import java.util.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.ApiDoc;
import com.zyplayer.doc.data.repository.manage.entity.AuthInfo;
import com.zyplayer.doc.data.repository.manage.entity.UserAuth;
import com.zyplayer.doc.data.repository.manage.mapper.ApiDocMapper;
import com.zyplayer.doc.data.repository.manage.vo.ApiDocVo;
import com.zyplayer.doc.data.repository.support.consts.ApiAuthType;
import com.zyplayer.doc.data.repository.support.consts.DocSysModuleType;
import com.zyplayer.doc.data.repository.support.consts.DocSysType;
import com.zyplayer.doc.data.service.manage.ApiDocService;
import com.zyplayer.doc.data.service.manage.AuthInfoService;
import com.zyplayer.doc.data.service.manage.UserAuthService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.stream.Collectors;
/**
* <p>
* api文档地址 服务实现类
@@ -20,17 +35,82 @@ import org.springframework.stereotype.Service;
@Service
public class ApiDocServiceImpl extends ServiceImpl<ApiDocMapper, ApiDoc> implements ApiDocService {
@Resource
UserAuthService userAuthService;
@Resource
AuthInfoService authInfoService;
@Override
public IPage<ApiDoc> getApiDocList(ApiDoc apiDoc, Integer pageNum, Integer pageSize) {
public IPage<ApiDocVo> getApiDocList(ApiDoc apiDoc, Integer pageNum, Integer pageSize) {
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
// 用户权限
List<UserAuth> userModuleAuthList = userAuthService.getUserModuleAuthList(currentUser.getUserId(), DocSysType.API.getType(), DocSysModuleType.Api.DOC.getType(), null);
List<Long> authDocIdList = userModuleAuthList.stream().map(UserAuth::getSysModuleId).collect(Collectors.toList());
// 权限ID对应的权限名
Map<Long, Integer> authDocAuthMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(userModuleAuthList)) {
Collection<AuthInfo> authInfoList = authInfoService.listByIds(userModuleAuthList.stream().map(UserAuth::getAuthId).collect(Collectors.toSet()));
Map<Long, String> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getId, AuthInfo::getAuthName));
Map<Long, Integer> authDocAuthRes = userModuleAuthList.stream().collect(Collectors.toMap(UserAuth::getSysModuleId, val -> ApiAuthType.typeOf(authInfoMap.get(val.getAuthId())).getType()));
authDocAuthMap.putAll(authDocAuthRes);
}
// 条件组装
QueryWrapper<ApiDoc> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("yn", 1);
queryWrapper.eq(apiDoc.getDocType() != null, "doc_type", apiDoc.getDocType());
queryWrapper.eq(apiDoc.getOpenVisit() != null, "open_visit", apiDoc.getOpenVisit());
queryWrapper.eq(apiDoc.getDocStatus() != null, "doc_status", apiDoc.getDocStatus());
queryWrapper.and(consumer ->
consumer.or(or -> or.eq("create_user_id", currentUser.getUserId()))
.or(CollectionUtils.isNotEmpty(authDocIdList), or -> or.in("id", authDocIdList))
);
queryWrapper.orderByAsc("id");
queryWrapper.select("id", "name", "doc_type", "doc_url", "share_uuid", "rewrite_domain", "open_visit", "doc_status", "create_user_id", "create_user_name", "create_time");
queryWrapper.select("id", "name", "doc_type", "doc_url", "share_uuid",
"rewrite_domain", "open_visit", "doc_status", "create_user_id",
"create_user_name", "create_time");
IPage<ApiDoc> page = new Page<>(pageNum, pageSize);
return this.page(page, queryWrapper);
this.page(page, queryWrapper);
// vo转换
return page.convert(doc -> {
// 角色判断
Integer authType = authDocAuthMap.get(doc.getId());
if (Objects.equals(doc.getCreateUserId(), currentUser.getUserId())) {
authType = ApiAuthType.MANAGE.getType();
}
ApiDocVo apiDocVo = new ApiDocVo();
apiDocVo.setAuthType(authType);
apiDocVo.setId(doc.getId());
apiDocVo.setName(doc.getName());
apiDocVo.setDocType(doc.getDocType());
apiDocVo.setDocUrl(doc.getDocUrl());
apiDocVo.setRewriteDomain(doc.getRewriteDomain());
apiDocVo.setOpenVisit(doc.getOpenVisit());
apiDocVo.setDocStatus(doc.getDocStatus());
apiDocVo.setCreateUserId(doc.getCreateUserId());
apiDocVo.setCreateUserName(doc.getCreateUserName());
apiDocVo.setCreateTime(doc.getCreateTime());
apiDocVo.setShareUuid(doc.getShareUuid());
return apiDocVo;
});
}
@Override
public List<ApiDoc> getApiDocList() {
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
// 用户权限
List<UserAuth> userModuleAuthList = userAuthService.getUserModuleAuthList(currentUser.getUserId(), DocSysType.API.getType(), DocSysModuleType.Api.DOC.getType(), null);
List<Long> authDocIdList = userModuleAuthList.stream().map(UserAuth::getSysModuleId).collect(Collectors.toList());
// 条件组装
QueryWrapper<ApiDoc> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("yn", 1);
queryWrapper.eq("doc_status", 1);
queryWrapper.and(consumer ->
consumer.or(or -> or.eq("create_user_id", currentUser.getUserId()))
.or(CollectionUtils.isNotEmpty(authDocIdList), or -> or.in("id", authDocIdList))
);
queryWrapper.orderByAsc("id");
queryWrapper.select("id", "name", "doc_type", "doc_url", "rewrite_domain", "open_visit", "doc_status");
return this.list(queryWrapper);
}
@Override

View File

@@ -1,5 +1,6 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyplayer.doc.data.repository.manage.entity.AuthInfo;
import com.zyplayer.doc.data.repository.manage.mapper.AuthInfoMapper;
@@ -16,5 +17,9 @@ import org.springframework.stereotype.Service;
*/
@Service
public class AuthInfoServiceImpl extends ServiceImpl<AuthInfoMapper, AuthInfo> implements AuthInfoService {
@Override
public AuthInfo getByCode(String authCode) {
return this.getOne(new QueryWrapper<AuthInfo>().eq("auth_name", authCode));
}
}

View File

@@ -2,10 +2,14 @@ package com.zyplayer.doc.data.service.manage.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyplayer.doc.core.exception.ConfirmException;
import com.zyplayer.doc.data.config.security.UserAuthVo;
import com.zyplayer.doc.data.repository.manage.entity.AuthInfo;
import com.zyplayer.doc.data.repository.manage.entity.UserAuth;
import com.zyplayer.doc.data.repository.manage.mapper.UserAuthMapper;
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
import com.zyplayer.doc.data.repository.support.consts.DocSysModuleType;
import com.zyplayer.doc.data.repository.support.consts.DocSysType;
import com.zyplayer.doc.data.service.manage.AuthInfoService;
import com.zyplayer.doc.data.service.manage.UserAuthService;
import org.apache.commons.collections.CollectionUtils;
@@ -30,9 +34,9 @@ public class UserAuthServiceImpl extends ServiceImpl<UserAuthMapper, UserAuth> i
AuthInfoService authInfoService;
@Override
public List<UserAuthVo> getUserAuthSet(Long id) {
public List<UserAuthVo> getUserAuthSet(Long userId) {
QueryWrapper<UserAuth> authWrapper = new QueryWrapper<>();
authWrapper.eq("user_id", id).eq("del_flag", "0");
authWrapper.eq("user_id", userId).eq("del_flag", "0");
List<UserAuth> userAuthList = this.list(authWrapper);
if (CollectionUtils.isEmpty(userAuthList)) {
return Collections.emptyList();
@@ -47,4 +51,47 @@ public class UserAuthServiceImpl extends ServiceImpl<UserAuthMapper, UserAuth> i
}
return userAuthVoList;
}
@Override
public List<UserAuth> getModuleAuthList(Integer sysType, Integer sysModuleType, Long sysModuleId) {
QueryWrapper<UserAuth> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("sys_type", sysType);
queryWrapper.eq("sys_module_type", sysModuleType);
queryWrapper.eq("sys_module_id", sysModuleId);
queryWrapper.eq("del_flag", 0);
return this.list(queryWrapper);
}
@Override
public List<UserAuth> getUserModuleAuthList(Long userId, Integer sysType, Integer sysModuleType, Long sysModuleId) {
QueryWrapper<UserAuth> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id", userId);
queryWrapper.eq("sys_type", sysType);
queryWrapper.eq("sys_module_type", sysModuleType);
// 不传时查询所有有权限的文档
queryWrapper.eq(sysModuleId != null, "sys_module_id", sysModuleId);
queryWrapper.eq("del_flag", 0);
return this.list(queryWrapper);
}
@Override
public boolean deleteModuleAuth(Integer sysType, Integer sysModuleType, Long sysModuleId) {
QueryWrapper<UserAuth> updateWrapper = new QueryWrapper<>();
updateWrapper.eq("sys_type", sysType);
updateWrapper.eq("sys_module_type", sysModuleType);
updateWrapper.eq("sys_module_id", sysModuleId);
updateWrapper.eq("del_flag", 0);
return this.remove(updateWrapper);
}
@Override
public boolean deleteUserModuleAuth(Long userId, Integer sysType, Integer sysModuleType, Long sysModuleId) {
QueryWrapper<UserAuth> updateWrapper = new QueryWrapper<>();
updateWrapper.eq("user_id", userId);
updateWrapper.eq("sys_type", sysType);
updateWrapper.eq("sys_module_type", sysModuleType);
updateWrapper.eq("sys_module_id", sysModuleId);
updateWrapper.eq("del_flag", 0);
return this.remove(updateWrapper);
}
}