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,130 @@
package com.zyplayer.doc.api.controller;
import com.zyplayer.doc.api.controller.vo.DocUserAuthVo;
import com.zyplayer.doc.api.service.ApiDocAuthJudgeService;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.json.DocResponseJson;
import com.zyplayer.doc.core.json.ResponseJson;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.*;
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 com.zyplayer.doc.data.service.manage.UserInfoService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* api权限控制器
*
* @author 暮光:城中城
* @since 2021年12月12日
*/
@AuthMan
@RestController
@RequestMapping("/doc-api/doc/auth")
public class ApiDocAuthController {
private static Logger logger = LoggerFactory.getLogger(ApiDocAuthController.class);
@Resource
UserAuthService userAuthService;
@Resource
AuthInfoService authInfoService;
@Resource
UserInfoService userInfoService;
@Resource
ApiDocService apiDocService;
@Resource
ApiDocAuthJudgeService apiDocAuthJudgeService;
@PostMapping("/list")
public ResponseJson<Object> list(Long docId) {
if (!apiDocAuthJudgeService.haveManageAuth(docId)) {
return DocResponseJson.warn("没有此文档的操作权限");
}
List<UserAuth> authList = userAuthService.getModuleAuthList(DocSysType.API.getType(), DocSysModuleType.Api.DOC.getType(), docId);
if (CollectionUtils.isEmpty(authList)) {
return DocResponseJson.ok();
}
// 权限ID对应的权限名
Collection<AuthInfo> authInfoList = authInfoService.listByIds(authList.stream().map(UserAuth::getAuthId).collect(Collectors.toSet()));
Map<Long, String> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getId, AuthInfo::getAuthName));
Collection<UserInfo> userInfoList = userInfoService.listByIds(authList.stream().map(UserAuth::getUserId).collect(Collectors.toSet()));
Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getId, val -> val));
// 返回结果组装
List<DocUserAuthVo> authVoList = new LinkedList<>();
for (UserAuth userAuth : authList) {
UserInfo userInfo = userInfoMap.get(userAuth.getUserId());
String authCode = authInfoMap.get(userAuth.getAuthId());
DocUserAuthVo authVo = new DocUserAuthVo();
authVo.setAuthType(ApiAuthType.typeOf(authCode).getType());
authVo.setUserId(userAuth.getUserId());
authVo.setUserNo(userInfo.getUserNo());
authVo.setUserName(userInfo.getUserName());
authVo.setEmail(userInfo.getEmail());
authVo.setPhone(userInfo.getPhone());
authVo.setSex(userInfo.getSex());
authVoList.add(authVo);
}
return DocResponseJson.ok(authVoList);
}
@PostMapping("/assign")
public ResponseJson<Object> assign(Long docId, Long userId, Integer authType) {
if (!apiDocAuthJudgeService.haveManageAuth(docId)) {
return DocResponseJson.warn("没有此文档的操作权限");
}
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
String authCode = ApiAuthType.typeOf(authType).getCode();
AuthInfo authInfo = authInfoService.getByCode(authCode);
List<UserAuth> userModuleAuthList = userAuthService.getUserModuleAuthList(userId, DocSysType.API.getType(), DocSysModuleType.Api.DOC.getType(), docId);
if (CollectionUtils.isNotEmpty(userModuleAuthList)) {
UserAuth userAuth = userModuleAuthList.remove(0);
// 错误数据兼容移除
if (userModuleAuthList.size() > 0) {
List<Long> authIdList = userModuleAuthList.stream().map(UserAuth::getId).collect(Collectors.toList());
userAuthService.removeByIds(authIdList);
}
userAuth.setAuthId(authInfo.getId());
userAuth.setUpdateTime(new Date());
userAuth.setUpdateUid(currentUser.getUserId());
userAuthService.updateById(userAuth);
} else {
UserAuth userAuth = new UserAuth();
userAuth.setUserId(userId);
userAuth.setSysType(DocSysType.API.getType());
userAuth.setSysModuleType(DocSysModuleType.Api.DOC.getType());
userAuth.setSysModuleId(docId);
userAuth.setAuthId(authInfo.getId());
userAuth.setCreationTime(new Date());
userAuth.setCreateUid(currentUser.getUserId());
userAuth.setUpdateTime(new Date());
userAuth.setUpdateUid(currentUser.getUserId());
userAuth.setDelFlag(0);
userAuthService.save(userAuth);
}
return DocResponseJson.ok();
}
@PostMapping("/delete")
public ResponseJson<Object> delete(Long docId, Long userId) {
if (!apiDocAuthJudgeService.haveManageAuth(docId)) {
return DocResponseJson.warn("没有此文档的操作权限");
}
userAuthService.deleteUserModuleAuth(userId, DocSysType.API.getType(), DocSysModuleType.Api.DOC.getType(), docId);
return DocResponseJson.ok();
}
}

View File

@@ -2,9 +2,9 @@ package com.zyplayer.doc.api.controller;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zyplayer.doc.api.framework.utils.SwaggerDocUtil; import com.zyplayer.doc.api.framework.utils.SwaggerDocUtil;
import com.zyplayer.doc.api.service.ApiDocAuthJudgeService;
import com.zyplayer.doc.api.service.SwaggerHttpRequestService; import com.zyplayer.doc.api.service.SwaggerHttpRequestService;
import com.zyplayer.doc.core.annotation.AuthMan; import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.json.DocResponseJson; import com.zyplayer.doc.core.json.DocResponseJson;
@@ -12,6 +12,7 @@ import com.zyplayer.doc.core.json.ResponseJson;
import com.zyplayer.doc.data.config.security.DocUserDetails; import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil; 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.ApiDoc;
import com.zyplayer.doc.data.repository.manage.vo.ApiDocVo;
import com.zyplayer.doc.data.service.manage.ApiDocService; import com.zyplayer.doc.data.service.manage.ApiDocService;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -41,7 +42,9 @@ public class ApiDocumentController {
private static Logger logger = LoggerFactory.getLogger(ApiDocumentController.class); private static Logger logger = LoggerFactory.getLogger(ApiDocumentController.class);
@Resource @Resource
private ApiDocService swaggerDocService; ApiDocAuthJudgeService apiDocAuthJudgeService;
@Resource
private ApiDocService apiDocService;
@Resource @Resource
private SwaggerHttpRequestService swaggerHttpRequestService; private SwaggerHttpRequestService swaggerHttpRequestService;
@@ -54,8 +57,8 @@ public class ApiDocumentController {
*/ */
@ResponseBody @ResponseBody
@PostMapping(value = "/list") @PostMapping(value = "/list")
public ResponseJson<List<ApiDoc>> list(ApiDoc apiDoc, Integer pageNum, Integer pageSize) { public ResponseJson<List<ApiDocVo>> list(ApiDoc apiDoc, Integer pageNum, Integer pageSize) {
IPage<ApiDoc> docList = swaggerDocService.getApiDocList(apiDoc, pageNum, pageSize); IPage<ApiDocVo> docList = apiDocService.getApiDocList(apiDoc, pageNum, pageSize);
return DocResponseJson.ok(docList); return DocResponseJson.ok(docList);
} }
@@ -69,7 +72,10 @@ public class ApiDocumentController {
@ResponseBody @ResponseBody
@PostMapping(value = "/detail") @PostMapping(value = "/detail")
public ResponseJson<List<ApiDoc>> detail(Long id) { public ResponseJson<List<ApiDoc>> detail(Long id) {
ApiDoc apiDoc = swaggerDocService.getById(id); ApiDoc apiDoc = apiDocService.getById(id);
if (!apiDocAuthJudgeService.haveDevelopAuth(apiDoc)) {
return DocResponseJson.warn("没有此文档的查看权限");
}
return DocResponseJson.ok(apiDoc); return DocResponseJson.ok(apiDoc);
} }
@@ -91,10 +97,13 @@ public class ApiDocumentController {
if (apiDoc.getId() == null) { if (apiDoc.getId() == null) {
apiDoc.setShareUuid(IdUtil.simpleUUID()); apiDoc.setShareUuid(IdUtil.simpleUUID());
} else { } else {
ApiDoc apiDocSel = swaggerDocService.getById(apiDoc.getId()); ApiDoc apiDocSel = apiDocService.getById(apiDoc.getId());
if (apiDocSel == null) { if (apiDocSel == null) {
return DocResponseJson.warn("未找到指定的文档记录信息"); return DocResponseJson.warn("未找到指定的文档记录信息");
} }
if (!apiDocAuthJudgeService.haveManageAuth(apiDocSel)) {
return DocResponseJson.warn("没有此文档的操作权限");
}
if (StringUtils.isBlank(apiDocSel.getShareUuid())) { if (StringUtils.isBlank(apiDocSel.getShareUuid())) {
apiDoc.setShareUuid(IdUtil.simpleUUID()); apiDoc.setShareUuid(IdUtil.simpleUUID());
} }
@@ -118,7 +127,7 @@ public class ApiDocumentController {
} }
// 删除原有文档 // 删除原有文档
if (apiDoc.getId() != null) { if (apiDoc.getId() != null) {
swaggerDocService.removeById(apiDoc.getId()); apiDocService.removeById(apiDoc.getId());
} }
// 存明细地址 // 存明细地址
for (SwaggerResource resource : resourceList) { for (SwaggerResource resource : resourceList) {
@@ -126,13 +135,13 @@ public class ApiDocumentController {
apiDoc.setDocUrl(swaggerDomain + resource.getUrl()); apiDoc.setDocUrl(swaggerDomain + resource.getUrl());
apiDoc.setName(resource.getName()); apiDoc.setName(resource.getName());
apiDoc.setShareUuid(IdUtil.simpleUUID()); apiDoc.setShareUuid(IdUtil.simpleUUID());
swaggerDocService.save(apiDoc); apiDocService.save(apiDoc);
} }
} else { } else {
swaggerDocService.saveOrUpdate(apiDoc); apiDocService.saveOrUpdate(apiDoc);
} }
} else if (Objects.equals(apiDoc.getDocType(), 2) || Objects.equals(apiDoc.getDocType(), 4)) { } else if (Objects.equals(apiDoc.getDocType(), 2) || Objects.equals(apiDoc.getDocType(), 4)) {
swaggerDocService.saveOrUpdate(apiDoc); apiDocService.saveOrUpdate(apiDoc);
} else { } else {
return DocResponseJson.warn("暂不支持的文档类型"); return DocResponseJson.warn("暂不支持的文档类型");
} }
@@ -152,32 +161,40 @@ public class ApiDocumentController {
if (apiDoc.getId() == null) { if (apiDoc.getId() == null) {
return DocResponseJson.warn("请指定修改的记录ID"); return DocResponseJson.warn("请指定修改的记录ID");
} }
// 基本信息可以改,删除需要管理员权限
if (Objects.equals(apiDoc.getYn(), 0)) {
if (!apiDocAuthJudgeService.haveManageAuth(apiDoc.getId())) {
return DocResponseJson.warn("没有此文档的删除权限");
}
} else {
if (!apiDocAuthJudgeService.haveDevelopAuth(apiDoc.getId())) {
return DocResponseJson.warn("没有此文档的编辑权限");
}
}
ApiDoc swaggerDocUp = new ApiDoc(); ApiDoc swaggerDocUp = new ApiDoc();
swaggerDocUp.setId(apiDoc.getId()); swaggerDocUp.setId(apiDoc.getId());
swaggerDocUp.setDocStatus(apiDoc.getDocStatus()); swaggerDocUp.setDocStatus(apiDoc.getDocStatus());
swaggerDocUp.setShareInstruction(apiDoc.getShareInstruction()); swaggerDocUp.setShareInstruction(apiDoc.getShareInstruction());
swaggerDocUp.setYn(apiDoc.getYn()); swaggerDocUp.setYn(apiDoc.getYn());
swaggerDocService.updateById(swaggerDocUp); apiDocService.updateById(swaggerDocUp);
return DocResponseJson.ok(); return DocResponseJson.ok();
} }
@RequestMapping("/apis") @RequestMapping("/apis")
public ResponseJson<List<ApiDoc>> resources() { public ResponseJson<List<ApiDoc>> resources() {
QueryWrapper<ApiDoc> queryWrapper = new QueryWrapper<>(); List<ApiDoc> docList = apiDocService.getApiDocList();
queryWrapper.eq("yn", 1);
queryWrapper.eq("doc_status", 1);
queryWrapper.orderByAsc("id");
queryWrapper.select("id", "name", "doc_type", "doc_url", "rewrite_domain", "open_visit", "doc_status");
List<ApiDoc> docList = swaggerDocService.list(queryWrapper);
return DocResponseJson.ok(docList); return DocResponseJson.ok(docList);
} }
@RequestMapping("/apis/detail") @RequestMapping("/apis/detail")
public ResponseJson<Object> detail(HttpServletRequest request, Long id) { public ResponseJson<Object> detail(HttpServletRequest request, Long id) {
ApiDoc apiDoc = swaggerDocService.getById(id); ApiDoc apiDoc = apiDocService.getById(id);
if (apiDoc == null) { if (apiDoc == null) {
return DocResponseJson.warn("文档不存在"); return DocResponseJson.warn("文档不存在");
} }
if (!apiDocAuthJudgeService.haveDevelopAuth(apiDoc)) {
return DocResponseJson.warn("没有此文档的查看权限");
}
if (Objects.equals(apiDoc.getDocType(), 1)) { if (Objects.equals(apiDoc.getDocType(), 1)) {
try { try {
String docsDomain = SwaggerDocUtil.getV2ApiDocsDomain(apiDoc.getDocUrl()); String docsDomain = SwaggerDocUtil.getV2ApiDocsDomain(apiDoc.getDocUrl());

View File

@@ -1,17 +1,10 @@
package com.zyplayer.doc.api.controller; package com.zyplayer.doc.api.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zyplayer.doc.api.framework.utils.SwaggerDocUtil; import com.zyplayer.doc.api.framework.utils.SwaggerDocUtil;
import com.zyplayer.doc.api.service.SwaggerHttpRequestService; import com.zyplayer.doc.api.service.SwaggerHttpRequestService;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.json.DocResponseJson; import com.zyplayer.doc.core.json.DocResponseJson;
import com.zyplayer.doc.core.json.ResponseJson; import com.zyplayer.doc.core.json.ResponseJson;
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.ApiDoc;
import com.zyplayer.doc.data.repository.manage.entity.ApiGlobalParam;
import com.zyplayer.doc.data.service.manage.ApiDocService; import com.zyplayer.doc.data.service.manage.ApiDocService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -19,11 +12,9 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.swagger.web.SwaggerResource;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;

View File

@@ -47,6 +47,7 @@ public class ApiSwaggerProxyController {
QueryWrapper<ApiDoc> queryWrapper = new QueryWrapper<>(); QueryWrapper<ApiDoc> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("yn", 1); queryWrapper.eq("yn", 1);
queryWrapper.eq("doc_status", 1); queryWrapper.eq("doc_status", 1);
queryWrapper.eq("open_visit", 1);
queryWrapper.in("doc_type", 1, 2); queryWrapper.in("doc_type", 1, 2);
queryWrapper.orderByAsc("id"); queryWrapper.orderByAsc("id");
queryWrapper.select("id", "name", "rewrite_domain"); queryWrapper.select("id", "name", "rewrite_domain");
@@ -66,7 +67,7 @@ public class ApiSwaggerProxyController {
@RequestMapping(value = "/v2/api-docs", produces = {MimeTypeUtils.APPLICATION_JSON_VALUE, HAL_MEDIA_TYPE}) @RequestMapping(value = "/v2/api-docs", produces = {MimeTypeUtils.APPLICATION_JSON_VALUE, HAL_MEDIA_TYPE})
public ResponseEntity<Object> content(HttpServletRequest request, Long id) { public ResponseEntity<Object> content(HttpServletRequest request, Long id) {
ApiDoc swaggerDoc = swaggerDocService.getById(id); ApiDoc swaggerDoc = swaggerDocService.getById(id);
if (swaggerDoc == null) { if (swaggerDoc == null || !Objects.equals(swaggerDoc.getOpenVisit(), 1)) {
throw new ConfirmException("文档不存在"); throw new ConfirmException("文档不存在");
} }
if (Objects.equals(swaggerDoc.getDocType(), 1)) { if (Objects.equals(swaggerDoc.getDocType(), 1)) {

View File

@@ -0,0 +1,211 @@
package com.zyplayer.doc.api.controller.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 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;
}
}

View File

@@ -0,0 +1,101 @@
package com.zyplayer.doc.api.controller.vo;
/**
* 用户权限返回值对象
*
* @author 暮光:城中城
* @since 2021年12月12日
*/
public class DocUserAuthVo {
/**
* 权限类型
*/
private Integer authType;
/**
* 用户ID
*/
private Long userId;
/**
* 用户编号,用于登录等
*/
private String userNo;
/**
* 用户名
*/
private String userName;
/**
* 邮箱
*/
private String email;
/**
* 手机号
*/
private String phone;
/**
* 性别 0=女 1=男
*/
private Integer sex;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUserNo() {
return userNo;
}
public void setUserNo(String userNo) {
this.userNo = userNo;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Integer getAuthType() {
return authType;
}
public void setAuthType(Integer authType) {
this.authType = authType;
}
}

View File

@@ -0,0 +1,99 @@
package com.zyplayer.doc.api.service;
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.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.List;
import java.util.Objects;
/**
* 判断文档权限
*
* @author 暮光:城中城
* @since 2021-12-12
*/
@Service
public class ApiDocAuthJudgeService {
@Resource
UserAuthService userAuthService;
@Resource
AuthInfoService authInfoService;
@Resource
ApiDocService apiDocService;
/**
* 判断当前用户是否有管理员权限
*
* @author 暮光:城中城
* @since 2021-12-12
*/
public boolean haveManageAuth(Long docId) {
ApiDoc apiDoc = apiDocService.getById(docId);
return haveManageAuth(apiDoc);
}
/**
* 判断当前用户是否有管理员权限
*
* @author 暮光:城中城
* @since 2021-12-12
*/
public boolean haveManageAuth(ApiDoc apiDoc) {
if (apiDoc == null) {
return false;
}
// 创建者
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
if (Objects.equals(apiDoc.getCreateUserId(), currentUser.getUserId())) {
return true;
}
// 管理员
AuthInfo authInfo = authInfoService.getByCode(ApiAuthType.MANAGE.getCode());
List<UserAuth> userModuleAuthList = userAuthService.getUserModuleAuthList(currentUser.getUserId(), DocSysType.API.getType(), DocSysModuleType.Api.DOC.getType(), apiDoc.getId());
return userModuleAuthList.stream().anyMatch(auth -> Objects.equals(auth.getAuthId(), authInfo.getId()));
}
/**
* 判断当前用户是否有查看权限
*
* @author 暮光:城中城
* @since 2021-12-12
*/
public boolean haveDevelopAuth(Long docId) {
ApiDoc apiDoc = apiDocService.getById(docId);
return haveDevelopAuth(apiDoc);
}
/**
* 判断当前用户是否有查看权限
*
* @author 暮光:城中城
* @since 2021-12-12
*/
public boolean haveDevelopAuth(ApiDoc apiDoc) {
if (apiDoc == null) {
return false;
}
// 创建者
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
if (Objects.equals(apiDoc.getCreateUserId(), currentUser.getUserId())) {
return true;
}
// 开发人员,存在则说明肯定是管理员或开发人员
List<UserAuth> userModuleAuthList = userAuthService.getUserModuleAuthList(currentUser.getUserId(), DocSysType.API.getType(), DocSysModuleType.Api.DOC.getType(), apiDoc.getId());
return CollectionUtils.isNotEmpty(userModuleAuthList);
}
}

View File

@@ -1 +1 @@
import{u as S,ak as D,r as i,o as t,c as l,w as o,a as n,m as s,t as c,b as p,F as f,k as r,e as m,d as w}from"./vendor.2a860d56.js";import{m as M}from"./mavon-editor.824ddc3c.js";import"./index.c860d973.js";import{_ as j}from"./main.4232e7c8.js";const B={setup(){const _=S(),A=D(()=>_.state.openApiDoc),u=D(()=>_.state.openApiDoc.info),e=D(()=>_.state.openApiMethodStatistic);return{openApiDoc:A,openApiDocInfo:u,openApiMethodStatistic:e,getDescription:I=>M.exports.markdownIt.render(I||"")}}},C=["href"],N=["href"],V=["href"],L=["innerHTML"],O={key:1,style:{"text-align":"center"}};function T(_,A,u,e,v,I){const a=i("a-form-item"),k=i("a-divider"),b=i("a-statistic"),h=i("a-card"),y=i("a-col"),g=i("a-row"),x=i("a-form");return t(),l(h,null,{default:o(()=>[e.openApiDocInfo?(t(),l(x,{key:0,"label-col":{span:4},"wrapper-col":{span:20}},{default:o(()=>[n(a,{label:"\u6807\u9898"},{default:o(()=>[s(c(e.openApiDocInfo.title),1)]),_:1}),n(a,{label:"\u7248\u672C"},{default:o(()=>[s(c(e.openApiDocInfo.version),1)]),_:1}),e.openApiDocInfo.contact?(t(),l(a,{key:0,label:"\u4F5C\u8005"},{default:o(()=>[e.openApiDocInfo.contact.name?(t(),p(f,{key:0},[s(c(e.openApiDocInfo.contact.name),1)],64)):r("",!0),e.openApiDocInfo.contact.email?(t(),p(f,{key:1},[n(k,{type:"vertical"}),s(c(e.openApiDocInfo.contact.email),1)],64)):r("",!0),e.openApiDocInfo.contact.url?(t(),p(f,{key:2},[n(k,{type:"vertical"}),m("a",{href:e.openApiDocInfo.contact.url,target:"_blank"},c(e.openApiDocInfo.contact.url),9,C)],64)):r("",!0)]),_:1})):r("",!0),n(a,{label:"host"},{default:o(()=>[s(c(e.openApiDoc.host),1)]),_:1}),e.openApiDocInfo.license?(t(),l(a,{key:1,label:"\u8BB8\u53EF\u8BC1"},{default:o(()=>[m("a",{href:e.openApiDocInfo.license.url,target:"_blank"},c(e.openApiDocInfo.license.name),9,N)]),_:1})):r("",!0),e.openApiDocInfo.termsOfService?(t(),l(a,{key:2,label:"\u670D\u52A1\u6761\u6B3E"},{default:o(()=>[m("a",{href:e.openApiDocInfo.termsOfService,target:"_blank"},c(e.openApiDocInfo.termsOfService),9,V)]),_:1})):r("",!0),n(a,{label:"\u6587\u6863\u8BF4\u660E"},{default:o(()=>[m("div",{class:"markdown-body",innerHTML:e.getDescription(e.openApiDocInfo.description)},null,8,L)]),_:1}),n(a,{label:"\u63A5\u53E3\u7EDF\u8BA1"},{default:o(()=>[n(g,{gutter:[16,16]},{default:o(()=>[(t(),p(f,null,w(["get","post","put","delete","head","patch","options","trace","total"],d=>(t(),p(f,null,[e.openApiMethodStatistic[d]?(t(),l(y,{key:0,span:6},{default:o(()=>[n(h,{size:"small"},{default:o(()=>[n(b,{title:d==="total"?"\u603B\u8BA1":d.toUpperCase()+"\u65B9\u6CD5",value:e.openApiMethodStatistic[d],suffix:"\u4E2A"},null,8,["title","value"])]),_:2},1024)]),_:2},1024)):r("",!0)],64))),64))]),_:1})]),_:1})]),_:1})):(t(),p("div",O,"\u6682\u65E0\u6587\u6863\u4FE1\u606F\uFF0C\u8BF7\u5148\u9009\u62E9\u6587\u6863"))]),_:1})}var U=j(B,[["render",T]]);export{U as default}; import{u as S,al as D,r as i,o as t,c as l,w as o,a as n,m as s,t as c,b as p,F as f,k as r,e as m,d as w}from"./vendor.1b910c8a.js";import{m as M}from"./mavon-editor.ee685efd.js";import"./index.c860d973.js";import{_ as j}from"./main.a6c14cdf.js";const B={setup(){const _=S(),A=D(()=>_.state.openApiDoc),u=D(()=>_.state.openApiDoc.info),e=D(()=>_.state.openApiMethodStatistic);return{openApiDoc:A,openApiDocInfo:u,openApiMethodStatistic:e,getDescription:I=>M.exports.markdownIt.render(I||"")}}},C=["href"],N=["href"],V=["href"],L=["innerHTML"],O={key:1,style:{"text-align":"center"}};function T(_,A,u,e,v,I){const a=i("a-form-item"),h=i("a-divider"),b=i("a-statistic"),k=i("a-card"),y=i("a-col"),g=i("a-row"),x=i("a-form");return t(),l(k,null,{default:o(()=>[e.openApiDocInfo?(t(),l(x,{key:0,"label-col":{span:4},"wrapper-col":{span:20}},{default:o(()=>[n(a,{label:"\u6807\u9898"},{default:o(()=>[s(c(e.openApiDocInfo.title),1)]),_:1}),n(a,{label:"\u7248\u672C"},{default:o(()=>[s(c(e.openApiDocInfo.version),1)]),_:1}),e.openApiDocInfo.contact?(t(),l(a,{key:0,label:"\u4F5C\u8005"},{default:o(()=>[e.openApiDocInfo.contact.name?(t(),p(f,{key:0},[s(c(e.openApiDocInfo.contact.name),1)],64)):r("",!0),e.openApiDocInfo.contact.email?(t(),p(f,{key:1},[n(h,{type:"vertical"}),s(c(e.openApiDocInfo.contact.email),1)],64)):r("",!0),e.openApiDocInfo.contact.url?(t(),p(f,{key:2},[n(h,{type:"vertical"}),m("a",{href:e.openApiDocInfo.contact.url,target:"_blank"},c(e.openApiDocInfo.contact.url),9,C)],64)):r("",!0)]),_:1})):r("",!0),n(a,{label:"host"},{default:o(()=>[s(c(e.openApiDoc.host),1)]),_:1}),e.openApiDocInfo.license?(t(),l(a,{key:1,label:"\u8BB8\u53EF\u8BC1"},{default:o(()=>[m("a",{href:e.openApiDocInfo.license.url,target:"_blank"},c(e.openApiDocInfo.license.name),9,N)]),_:1})):r("",!0),e.openApiDocInfo.termsOfService?(t(),l(a,{key:2,label:"\u670D\u52A1\u6761\u6B3E"},{default:o(()=>[m("a",{href:e.openApiDocInfo.termsOfService,target:"_blank"},c(e.openApiDocInfo.termsOfService),9,V)]),_:1})):r("",!0),n(a,{label:"\u6587\u6863\u8BF4\u660E"},{default:o(()=>[m("div",{class:"markdown-body",innerHTML:e.getDescription(e.openApiDocInfo.description)},null,8,L)]),_:1}),n(a,{label:"\u63A5\u53E3\u7EDF\u8BA1"},{default:o(()=>[n(g,{gutter:[16,16]},{default:o(()=>[(t(),p(f,null,w(["get","post","put","delete","head","patch","options","trace","total"],d=>(t(),p(f,null,[e.openApiMethodStatistic[d]?(t(),l(y,{key:0,span:6},{default:o(()=>[n(k,{size:"small"},{default:o(()=>[n(b,{title:d==="total"?"\u603B\u8BA1":d.toUpperCase()+"\u65B9\u6CD5",value:e.openApiMethodStatistic[d],suffix:"\u4E2A"},null,8,["title","value"])]),_:2},1024)]),_:2},1024)):r("",!0)],64))),64))]),_:1})]),_:1})]),_:1})):(t(),p("div",O,"\u6682\u65E0\u6587\u6863\u4FE1\u606F\uFF0C\u8BF7\u5148\u9009\u62E9\u6587\u6863"))]),_:1})}var U=j(B,[["render",T]]);export{U as default};

View File

@@ -1 +1 @@
import{u as S,ak as w,r as c,o as a,c as l,w as t,a as o,m as g,t as n,b as i,F as f,k as s,e as m,d as M}from"./vendor.2a860d56.js";import{m as j}from"./mavon-editor.824ddc3c.js";import"./index.c860d973.js";import{_ as B}from"./main.4232e7c8.js";const C={setup(){const _=S(),D=w(()=>_.state.swaggerDoc),u=w(()=>_.state.swaggerDoc.info),e=w(()=>_.state.swaggerMethodStatistic);return{swaggerDoc:D,swaggerDocInfo:u,swaggerMethodStatistic:e,getDescription:I=>j.exports.markdownIt.render(I||"")}}},N=["href"],V=["href"],L=["href"],O=["innerHTML"],T={key:1,style:{"text-align":"center"}};function E(_,D,u,e,p,I){const r=c("a-form-item"),k=c("a-divider"),v=c("a-statistic"),h=c("a-card"),b=c("a-col"),y=c("a-row"),x=c("a-form");return a(),l(h,null,{default:t(()=>[e.swaggerDocInfo?(a(),l(x,{key:0,"label-col":{span:4},"wrapper-col":{span:20}},{default:t(()=>[o(r,{label:"\u6807\u9898"},{default:t(()=>[g(n(e.swaggerDocInfo.title),1)]),_:1}),o(r,{label:"\u7248\u672C"},{default:t(()=>[g(n(e.swaggerDocInfo.version),1)]),_:1}),e.swaggerDocInfo.contact?(a(),l(r,{key:0,label:"\u4F5C\u8005"},{default:t(()=>[e.swaggerDocInfo.contact.name?(a(),i(f,{key:0},[g(n(e.swaggerDocInfo.contact.name),1)],64)):s("",!0),e.swaggerDocInfo.contact.email?(a(),i(f,{key:1},[o(k,{type:"vertical"}),g(n(e.swaggerDocInfo.contact.email),1)],64)):s("",!0),e.swaggerDocInfo.contact.url?(a(),i(f,{key:2},[o(k,{type:"vertical"}),m("a",{href:e.swaggerDocInfo.contact.url,target:"_blank"},n(e.swaggerDocInfo.contact.url),9,N)],64)):s("",!0)]),_:1})):s("",!0),o(r,{label:"host"},{default:t(()=>[g(n(e.swaggerDoc.host),1)]),_:1}),e.swaggerDocInfo.license?(a(),l(r,{key:1,label:"\u8BB8\u53EF\u8BC1"},{default:t(()=>[m("a",{href:e.swaggerDocInfo.license.url,target:"_blank"},n(e.swaggerDocInfo.license.name),9,V)]),_:1})):s("",!0),e.swaggerDocInfo.termsOfService?(a(),l(r,{key:2,label:"\u670D\u52A1\u6761\u6B3E"},{default:t(()=>[m("a",{href:e.swaggerDocInfo.termsOfService,target:"_blank"},n(e.swaggerDocInfo.termsOfService),9,L)]),_:1})):s("",!0),o(r,{label:"\u6587\u6863\u8BF4\u660E"},{default:t(()=>[m("div",{class:"markdown-body",innerHTML:e.getDescription(e.swaggerDocInfo.description)},null,8,O)]),_:1}),o(r,{label:"\u63A5\u53E3\u7EDF\u8BA1"},{default:t(()=>[o(y,{gutter:[16,16]},{default:t(()=>[(a(),i(f,null,M(["get","post","put","delete","head","patch","options","trace","total"],d=>(a(),i(f,null,[e.swaggerMethodStatistic[d]?(a(),l(b,{key:0,span:6},{default:t(()=>[o(h,{size:"small"},{default:t(()=>[o(v,{title:d==="total"?"\u603B\u8BA1":d.toUpperCase()+"\u65B9\u6CD5",value:e.swaggerMethodStatistic[d],suffix:"\u4E2A"},null,8,["title","value"])]),_:2},1024)]),_:2},1024)):s("",!0)],64))),64))]),_:1})]),_:1})]),_:1})):(a(),i("div",T,"\u6682\u65E0\u6587\u6863\u4FE1\u606F\uFF0C\u8BF7\u5148\u9009\u62E9\u6587\u6863"))]),_:1})}var q=B(C,[["render",E]]);export{q as default}; import{u as S,al as w,r as c,o as a,c as l,w as t,a as o,m as g,t as n,b as i,F as f,k as s,e as m,d as M}from"./vendor.1b910c8a.js";import{m as j}from"./mavon-editor.ee685efd.js";import"./index.c860d973.js";import{_ as B}from"./main.a6c14cdf.js";const C={setup(){const _=S(),D=w(()=>_.state.swaggerDoc),u=w(()=>_.state.swaggerDoc.info),e=w(()=>_.state.swaggerMethodStatistic);return{swaggerDoc:D,swaggerDocInfo:u,swaggerMethodStatistic:e,getDescription:I=>j.exports.markdownIt.render(I||"")}}},N=["href"],V=["href"],L=["href"],O=["innerHTML"],T={key:1,style:{"text-align":"center"}};function E(_,D,u,e,p,I){const r=c("a-form-item"),h=c("a-divider"),v=c("a-statistic"),k=c("a-card"),b=c("a-col"),y=c("a-row"),x=c("a-form");return a(),l(k,null,{default:t(()=>[e.swaggerDocInfo?(a(),l(x,{key:0,"label-col":{span:4},"wrapper-col":{span:20}},{default:t(()=>[o(r,{label:"\u6807\u9898"},{default:t(()=>[g(n(e.swaggerDocInfo.title),1)]),_:1}),o(r,{label:"\u7248\u672C"},{default:t(()=>[g(n(e.swaggerDocInfo.version),1)]),_:1}),e.swaggerDocInfo.contact?(a(),l(r,{key:0,label:"\u4F5C\u8005"},{default:t(()=>[e.swaggerDocInfo.contact.name?(a(),i(f,{key:0},[g(n(e.swaggerDocInfo.contact.name),1)],64)):s("",!0),e.swaggerDocInfo.contact.email?(a(),i(f,{key:1},[o(h,{type:"vertical"}),g(n(e.swaggerDocInfo.contact.email),1)],64)):s("",!0),e.swaggerDocInfo.contact.url?(a(),i(f,{key:2},[o(h,{type:"vertical"}),m("a",{href:e.swaggerDocInfo.contact.url,target:"_blank"},n(e.swaggerDocInfo.contact.url),9,N)],64)):s("",!0)]),_:1})):s("",!0),o(r,{label:"host"},{default:t(()=>[g(n(e.swaggerDoc.host),1)]),_:1}),e.swaggerDocInfo.license?(a(),l(r,{key:1,label:"\u8BB8\u53EF\u8BC1"},{default:t(()=>[m("a",{href:e.swaggerDocInfo.license.url,target:"_blank"},n(e.swaggerDocInfo.license.name),9,V)]),_:1})):s("",!0),e.swaggerDocInfo.termsOfService?(a(),l(r,{key:2,label:"\u670D\u52A1\u6761\u6B3E"},{default:t(()=>[m("a",{href:e.swaggerDocInfo.termsOfService,target:"_blank"},n(e.swaggerDocInfo.termsOfService),9,L)]),_:1})):s("",!0),o(r,{label:"\u6587\u6863\u8BF4\u660E"},{default:t(()=>[m("div",{class:"markdown-body",innerHTML:e.getDescription(e.swaggerDocInfo.description)},null,8,O)]),_:1}),o(r,{label:"\u63A5\u53E3\u7EDF\u8BA1"},{default:t(()=>[o(y,{gutter:[16,16]},{default:t(()=>[(a(),i(f,null,M(["get","post","put","delete","head","patch","options","trace","total"],d=>(a(),i(f,null,[e.swaggerMethodStatistic[d]?(a(),l(b,{key:0,span:6},{default:t(()=>[o(k,{size:"small"},{default:t(()=>[o(v,{title:d==="total"?"\u603B\u8BA1":d.toUpperCase()+"\u65B9\u6CD5",value:e.swaggerMethodStatistic[d],suffix:"\u4E2A"},null,8,["title","value"])]),_:2},1024)]),_:2},1024)):s("",!0)],64))),64))]),_:1})]),_:1})]),_:1})):(a(),i("div",T,"\u6682\u65E0\u6587\u6863\u4FE1\u606F\uFF0C\u8BF7\u5148\u9009\u62E9\u6587\u6863"))]),_:1})}var q=B(C,[["render",E]]);export{q as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{v as L,u as y,y as a,H as j,r as g,o as h,c as v,w as D,B as k,e as x}from"./vendor.2a860d56.js";import{D as I,s as _}from"./DocContent.9af89d36.js";import{m as M}from"./mavon-editor.824ddc3c.js";import"./index.c860d973.js";import{_ as q}from"./main.4232e7c8.js";import"./logUtil.532ff0b3.js";const S={components:{DocContent:I},setup(){const r=L(),s=y();let d=a("doc"),t=a([]),n=a([]),c=a({url:"",description:"",method:"",consumes:"",produces:""}),o=a(!1),i=0,l;const m=()=>{let P=r.query.path+"."+r.query.method;if(Object.keys(s.state.swaggerUrlMethodMap).length<=0){console.log("\u6587\u6863\u5C1A\u672A\u52A0\u8F7D\uFF0C\u7B49\u5F85\u52A0\u8F7D\u5B8C\u6210"),l||(l=setInterval(()=>{if(o.value||i++>50){clearInterval(l);return}Object.keys(s.state.swaggerUrlMethodMap).length>0&&(console.log("\u6587\u6863\u5185\u5BB9\u6539\u53D8\uFF0C\u91CD\u65B0\u52A0\u8F7D\u6587\u6863"),m())},1e3));return}let e=s.state.swaggerUrlMethodMap[P];if(!e){k.error("\u6CA1\u6709\u627E\u5230\u5BF9\u5E94\u7684\u6587\u6863");return}o.value=!0,s.commit("addTableName",{key:r.fullPath,val:e.summary});let u="",p="";e.consumes&&e.consumes.length>0&&(u=e.consumes.join(" ")),e.produces&&e.produces.length>0&&(p=e.produces.join(" "));let w=M.exports.markdownIt.render(e.description||e.summary||"");c.value={url:e.url,description:w,method:e.method||"",consumes:u,produces:p};let f=s.state.swaggerDefinitions;t.value=_.getRequestParamList(e.parameters,f),n.value=_.getResponseParamList(e.responses,f)};return j(()=>{m()}),{docInfoShow:c,activePage:d,changePage:()=>{},isLoadSuccess:o,requestParamList:t,responseParamList:n}}},C=x("div",{style:{padding:"20px 0",height:"100px"}},null,-1);function b(r,s,d,t,n,c){const o=g("DocContent"),i=g("a-spin");return t.isLoadSuccess?(h(),v(o,{key:0,docInfoShow:t.docInfoShow,requestParamList:t.requestParamList,responseParamList:t.responseParamList},null,8,["docInfoShow","requestParamList","responseParamList"])):(h(),v(i,{key:1,tip:"\u6587\u6863\u6570\u636E\u52A0\u8F7D\u4E2D..."},{default:D(()=>[C]),_:1}))}var A=q(S,[["render",b]]);export{A as default}; import{v as L,u as y,y as a,H as j,r as g,o as h,c as v,w as D,B as k,e as x}from"./vendor.1b910c8a.js";import{D as I,s as _}from"./DocContent.75fb82ce.js";import{m as M}from"./mavon-editor.ee685efd.js";import"./index.c860d973.js";import{_ as q}from"./main.a6c14cdf.js";import"./logUtil.3161557e.js";const S={components:{DocContent:I},setup(){const r=L(),s=y();let m=a("doc"),t=a([]),n=a([]),c=a({url:"",description:"",method:"",consumes:"",produces:""}),o=a(!1),i=0,l;const d=()=>{let P=r.query.path+"."+r.query.method;if(Object.keys(s.state.swaggerUrlMethodMap).length<=0){console.log("\u6587\u6863\u5C1A\u672A\u52A0\u8F7D\uFF0C\u7B49\u5F85\u52A0\u8F7D\u5B8C\u6210"),l||(l=setInterval(()=>{if(o.value||i++>50){clearInterval(l);return}Object.keys(s.state.swaggerUrlMethodMap).length>0&&(console.log("\u6587\u6863\u5185\u5BB9\u6539\u53D8\uFF0C\u91CD\u65B0\u52A0\u8F7D\u6587\u6863"),d())},1e3));return}let e=s.state.swaggerUrlMethodMap[P];if(!e){k.error("\u6CA1\u6709\u627E\u5230\u5BF9\u5E94\u7684\u6587\u6863");return}o.value=!0,s.commit("addTableName",{key:r.fullPath,val:e.summary});let u="",p="";e.consumes&&e.consumes.length>0&&(u=e.consumes.join(" ")),e.produces&&e.produces.length>0&&(p=e.produces.join(" "));let w=M.exports.markdownIt.render(e.description||e.summary||"");c.value={url:e.url,description:w,method:e.method||"",consumes:u,produces:p};let f=s.state.swaggerDefinitions;t.value=_.getRequestParamList(e.parameters,f),n.value=_.getResponseParamList(e.responses,f)};return j(()=>{d()}),{docInfoShow:c,activePage:m,changePage:()=>{},isLoadSuccess:o,requestParamList:t,responseParamList:n}}},C=x("div",{style:{padding:"20px 0",height:"100px"}},null,-1);function b(r,s,m,t,n,c){const o=g("DocContent"),i=g("a-spin");return t.isLoadSuccess?(h(),v(o,{key:0,docInfoShow:t.docInfoShow,requestParamList:t.requestParamList,responseParamList:t.responseParamList},null,8,["docInfoShow","requestParamList","responseParamList"])):(h(),v(i,{key:1,tip:"\u6587\u6863\u6570\u636E\u52A0\u8F7D\u4E2D..."},{default:D(()=>[C]),_:1}))}var A=q(S,[["render",b]]);export{A as default};

View File

@@ -1 +1 @@
import{v as y,u as j,y as n,H as D,r as h,o as v,c as g,w as k,B as w,e as x}from"./vendor.2a860d56.js";import{D as I,o as _}from"./DocContent.658bc0f2.js";import{m as M}from"./mavon-editor.824ddc3c.js";import"./index.c860d973.js";import{_ as q}from"./main.4232e7c8.js";import"./logUtil.532ff0b3.js";const S={components:{DocContent:I},setup(){const a=y(),t=j();let p=n("doc"),o=n([]),r=n([]),i=n({url:"",description:"",method:"",consumes:"",produces:""}),s=n(!1),c=0,l;const d=()=>{let P=a.query.path+"."+a.query.method;if(Object.keys(t.state.openApiUrlMethodMap).length<=0){console.log("\u6587\u6863\u5C1A\u672A\u52A0\u8F7D\uFF0C\u7B49\u5F85\u52A0\u8F7D\u5B8C\u6210"),l||(l=setInterval(()=>{if(s.value||c++>50){clearInterval(l);return}Object.keys(t.state.openApiUrlMethodMap).length>0&&(console.log("\u6587\u6863\u5185\u5BB9\u6539\u53D8\uFF0C\u91CD\u65B0\u52A0\u8F7D\u6587\u6863"),d())},1e3));return}let e=t.state.openApiUrlMethodMap[P];if(!e){w.error("\u6CA1\u6709\u627E\u5230\u5BF9\u5E94\u7684\u6587\u6863");return}s.value=!0,t.commit("addTableName",{key:a.fullPath,val:e.summary});let m="",u="";e.consumes&&e.consumes.length>0&&(m=e.consumes.join(" ")),e.produces&&e.produces.length>0&&(u=e.produces.join(" "));let L=M.exports.markdownIt.render(e.description||e.summary||"");i.value={url:e.url,description:L,method:e.method||"",consumes:m,produces:u};let f=t.state.openApiDefinitions;o.value=_.getRequestParamList(e.parameters,f),r.value=_.getResponseParamList(e.responses,f)};return D(()=>{d()}),{docInfoShow:i,activePage:p,changePage:()=>{},isLoadSuccess:s,requestParamList:o,responseParamList:r}}},A=x("div",{style:{padding:"20px 0",height:"100px"}},null,-1);function C(a,t,p,o,r,i){const s=h("DocContent"),c=h("a-spin");return o.isLoadSuccess?(v(),g(s,{key:0,docInfoShow:o.docInfoShow,requestParamList:o.requestParamList,responseParamList:o.responseParamList},null,8,["docInfoShow","requestParamList","responseParamList"])):(v(),g(c,{key:1,tip:"\u6587\u6863\u6570\u636E\u52A0\u8F7D\u4E2D..."},{default:k(()=>[A]),_:1}))}var V=q(S,[["render",C]]);export{V as default}; import{v as y,u as j,y as n,H as D,r as h,o as v,c as g,w as k,B as w,e as x}from"./vendor.1b910c8a.js";import{D as I,o as _}from"./DocContent.9bbd9b50.js";import{m as M}from"./mavon-editor.ee685efd.js";import"./index.c860d973.js";import{_ as b}from"./main.a6c14cdf.js";import"./logUtil.3161557e.js";const q={components:{DocContent:I},setup(){const a=y(),t=j();let p=n("doc"),o=n([]),r=n([]),i=n({url:"",description:"",method:"",consumes:"",produces:""}),s=n(!1),c=0,l;const d=()=>{let P=a.query.path+"."+a.query.method;if(Object.keys(t.state.openApiUrlMethodMap).length<=0){console.log("\u6587\u6863\u5C1A\u672A\u52A0\u8F7D\uFF0C\u7B49\u5F85\u52A0\u8F7D\u5B8C\u6210"),l||(l=setInterval(()=>{if(s.value||c++>50){clearInterval(l);return}Object.keys(t.state.openApiUrlMethodMap).length>0&&(console.log("\u6587\u6863\u5185\u5BB9\u6539\u53D8\uFF0C\u91CD\u65B0\u52A0\u8F7D\u6587\u6863"),d())},1e3));return}let e=t.state.openApiUrlMethodMap[P];if(!e){w.error("\u6CA1\u6709\u627E\u5230\u5BF9\u5E94\u7684\u6587\u6863");return}s.value=!0,t.commit("addTableName",{key:a.fullPath,val:e.summary});let m="",u="";e.consumes&&e.consumes.length>0&&(m=e.consumes.join(" ")),e.produces&&e.produces.length>0&&(u=e.produces.join(" "));let L=M.exports.markdownIt.render(e.description||e.summary||"");i.value={url:e.url,description:L,method:e.method||"",consumes:m,produces:u};let f=t.state.openApiDefinitions;o.value=_.getRequestParamList(e.parameters,f),r.value=_.getResponseParamList(e.responses,f)};return D(()=>{d()}),{docInfoShow:i,activePage:p,changePage:()=>{},isLoadSuccess:s,requestParamList:o,responseParamList:r}}},S=x("div",{style:{padding:"20px 0",height:"100px"}},null,-1);function A(a,t,p,o,r,i){const s=h("DocContent"),c=h("a-spin");return o.isLoadSuccess?(v(),g(s,{key:0,docInfoShow:o.docInfoShow,requestParamList:o.requestParamList,responseParamList:o.responseParamList},null,8,["docInfoShow","requestParamList","responseParamList"])):(v(),g(c,{key:1,tip:"\u6587\u6863\u6570\u636E\u52A0\u8F7D\u4E2D..."},{default:k(()=>[S]),_:1}))}var V=b(q,[["render",A]]);export{V as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
var G=Object.defineProperty;var V=Object.getOwnPropertySymbols;var K=Object.prototype.hasOwnProperty,N=Object.prototype.propertyIsEnumerable;var w=(c,e,l)=>e in c?G(c,e,{enumerable:!0,configurable:!0,writable:!0,value:l}):c[e]=l,I=(c,e)=>{for(var l in e||(e={}))K.call(e,l)&&w(c,l,e[l]);if(V)for(var l of V(e))N.call(e,l)&&w(c,l,e[l]);return c};import{z as D}from"./custom.ece90331.js";import{u as P,y as x,H as U,r as v,o,b as r,e as A,a as s,w as n,F as y,B as F,c as k,t as B,k as C,m as d}from"./vendor.2a860d56.js";import{_ as S}from"./main.4232e7c8.js";const j={setup(){const c=P();let e=x([]),l=x(!1);const a=async()=>{i.value={},l.value=!0,D.docApiGlobalParamList().then(t=>{setTimeout(()=>l.value=!1,500),e.value=t.data||[],c.commit("setGlobalParam",e.value)})};let i=x({}),T=x();const p=()=>{i.value.isEdit&&f(i.value);let t={isEdit:!0};e.value.unshift(t),i.value=t,setTimeout(()=>{let _=document.getElementsByClassName("ant-table-body")[0];_.scrollTop=0},0)},g=t=>{i.value.isEdit&&f(i.value),t.isEdit=!0,i.value=I({},t)},f=t=>{t.isEdit=!1,t.id?e.value.forEach(_=>_.isEdit=!1):e.value=e.value.filter(_=>_!==t),i.value={}},L=t=>{if(!i.value.paramKey||!i.value.paramValue){F.error("\u53C2\u6570\u540D\u6216\u53C2\u6570\u503C\u4E0D\u80FD\u4E3A\u7A7A");return}D.docApiGlobalParamUpdate(i.value).then(_=>{t.isEdit=!1,a()})},h=async t=>{D.docApiGlobalParamUpdate({id:t.id,yn:0}).then(_=>{a()})};return U(()=>{a()}),{docList:e,docListLoading:l,docEdit:i,tableRef:T,searchDocList:a,deleteDoc:h,editDoc:g,saveEditDoc:L,cancelEditDoc:f,addDocLine:p,docListColumns:[{title:"\u53C2\u6570\u540D\u79F0",dataIndex:"paramKey",width:250},{title:"\u53C2\u6570\u503C",dataIndex:"paramValue"},{title:"\u53C2\u6570\u4F4D\u7F6E",dataIndex:"paramType",width:120},{title:"\u64CD\u4F5C",dataIndex:"operation",fixed:"right",width:170}]}}},z={style:{"margin-bottom":"10px","text-align":"right"}},H=d("\u5237\u65B0"),M=d("\u65B0\u5EFA"),R={key:1},q={key:1},J=d("Form"),O=d("Header"),Q=d("Cookie"),W=d("Form"),X=d("Header"),Y=d("Cookie"),Z=d("\u53D6\u6D88"),$=d("\u4FDD\u5B58"),ee=d("\u7F16\u8F91"),ae=d("\u5220\u9664");function te(c,e,l,a,i,T){const p=v("a-button"),g=v("a-input"),f=v("a-select-option"),L=v("a-select"),h=v("a-tag"),t=v("a-popconfirm"),_=v("a-table");return o(),r(y,null,[A("div",z,[s(p,{onClick:a.searchDocList,type:"primary"},{default:n(()=>[H]),_:1},8,["onClick"]),s(p,{onClick:a.addDocLine},{default:n(()=>[M]),_:1},8,["onClick"])]),s(_,{dataSource:a.docList,columns:a.docListColumns,size:"middle",id:"paramTable",loading:a.docListLoading,pagination:!1,scroll:{x:1e3,y:"calc(100vh - 240px)"}},{bodyCell:n(({column:b,text:E,record:m})=>[b.dataIndex==="paramKey"?(o(),r(y,{key:0},[m.isEdit?(o(),k(g,{key:0,placeholder:"\u8BF7\u8F93\u5165\u53C2\u6570\u540D\u79F0",value:a.docEdit.paramKey,"onUpdate:value":e[0]||(e[0]=u=>a.docEdit.paramKey=u)},null,8,["value"])):(o(),r("span",R,B(E),1))],64)):C("",!0),b.dataIndex==="paramValue"?(o(),r(y,{key:1},[m.isEdit?(o(),k(g,{key:0,rows:1,placeholder:"\u8BF7\u8F93\u5165\u53C2\u6570\u503C",value:a.docEdit.paramValue,"onUpdate:value":e[1]||(e[1]=u=>a.docEdit.paramValue=u)},null,8,["value"])):(o(),r("span",q,B(E),1))],64)):C("",!0),b.dataIndex==="paramType"?(o(),r(y,{key:2},[m.isEdit?(o(),k(L,{key:0,placeholder:"\u53C2\u6570\u4F4D\u7F6E",value:a.docEdit.paramType,"onUpdate:value":e[2]||(e[2]=u=>a.docEdit.paramType=u),style:{width:"110px"}},{default:n(()=>[s(f,{value:1},{default:n(()=>[J]),_:1}),s(f,{value:2},{default:n(()=>[O]),_:1}),s(f,{value:3},{default:n(()=>[Q]),_:1})]),_:1},8,["value"])):(o(),r(y,{key:1},[E===1?(o(),k(h,{key:0,color:"green"},{default:n(()=>[W]),_:1})):E===2?(o(),k(h,{key:1,color:"pink"},{default:n(()=>[X]),_:1})):E===3?(o(),k(h,{key:2,color:"pink"},{default:n(()=>[Y]),_:1})):C("",!0)],64))],64)):C("",!0),b.dataIndex==="operation"?(o(),r(y,{key:3},[m.isEdit?(o(),r(y,{key:0},[s(p,{type:"link",onClick:u=>a.cancelEditDoc(m)},{default:n(()=>[Z]),_:2},1032,["onClick"]),s(p,{type:"link",onClick:u=>a.saveEditDoc(m)},{default:n(()=>[$]),_:2},1032,["onClick"])],64)):(o(),r(y,{key:1},[s(p,{type:"link",onClick:u=>a.editDoc(m)},{default:n(()=>[ee]),_:2},1032,["onClick"]),s(t,{title:"\u786E\u5B9A\u8981\u5220\u9664\u5417\uFF1F",onConfirm:u=>a.deleteDoc(m)},{default:n(()=>[s(p,{type:"link",danger:""},{default:n(()=>[ae]),_:1})]),_:2},1032,["onConfirm"])],64))],64)):C("",!0)]),_:1},8,["dataSource","columns","loading","scroll"])],64)}var de=S(j,[["render",te]]);export{de as default}; var G=Object.defineProperty;var V=Object.getOwnPropertySymbols;var K=Object.prototype.hasOwnProperty,N=Object.prototype.propertyIsEnumerable;var w=(c,e,l)=>e in c?G(c,e,{enumerable:!0,configurable:!0,writable:!0,value:l}):c[e]=l,I=(c,e)=>{for(var l in e||(e={}))K.call(e,l)&&w(c,l,e[l]);if(V)for(var l of V(e))N.call(e,l)&&w(c,l,e[l]);return c};import{z as D}from"./custom.f7427cee.js";import{u as P,y as x,H as U,r as v,o,b as r,e as A,a as s,w as n,F as f,B as F,c as k,t as B,k as C,m as d}from"./vendor.1b910c8a.js";import{_ as S}from"./main.a6c14cdf.js";const j={setup(){const c=P();let e=x([]),l=x(!1);const a=async()=>{i.value={},l.value=!0,D.docApiGlobalParamList().then(t=>{setTimeout(()=>l.value=!1,500),e.value=t.data||[],c.commit("setGlobalParam",e.value)})};let i=x({}),T=x();const p=()=>{i.value.isEdit&&y(i.value);let t={isEdit:!0};e.value.unshift(t),i.value=t,setTimeout(()=>{let _=document.getElementsByClassName("ant-table-body")[0];_.scrollTop=0},0)},b=t=>{i.value.isEdit&&y(i.value),t.isEdit=!0,i.value=I({},t)},y=t=>{t.isEdit=!1,t.id?e.value.forEach(_=>_.isEdit=!1):e.value=e.value.filter(_=>_!==t),i.value={}},L=t=>{if(!i.value.paramKey||!i.value.paramValue){F.error("\u53C2\u6570\u540D\u6216\u53C2\u6570\u503C\u4E0D\u80FD\u4E3A\u7A7A");return}D.docApiGlobalParamUpdate(i.value).then(_=>{t.isEdit=!1,a()})},h=async t=>{D.docApiGlobalParamUpdate({id:t.id,yn:0}).then(_=>{a()})};return U(()=>{a()}),{docList:e,docListLoading:l,docEdit:i,tableRef:T,searchDocList:a,deleteDoc:h,editDoc:b,saveEditDoc:L,cancelEditDoc:y,addDocLine:p,docListColumns:[{title:"\u53C2\u6570\u540D\u79F0",dataIndex:"paramKey",width:250},{title:"\u53C2\u6570\u503C",dataIndex:"paramValue"},{title:"\u53C2\u6570\u4F4D\u7F6E",dataIndex:"paramType",width:120},{title:"\u64CD\u4F5C",dataIndex:"operation",fixed:"right",width:170}]}}},z={style:{"margin-bottom":"10px","text-align":"right"}},H=d("\u5237\u65B0"),M=d("\u65B0\u5EFA"),R={key:1},q={key:1},J=d("Form"),O=d("Header"),Q=d("Cookie"),W=d("Form"),X=d("Header"),Y=d("Cookie"),Z=d("\u53D6\u6D88"),$=d("\u4FDD\u5B58"),ee=d("\u7F16\u8F91"),ae=d("\u5220\u9664");function te(c,e,l,a,i,T){const p=v("a-button"),b=v("a-input"),y=v("a-select-option"),L=v("a-select"),h=v("a-tag"),t=v("a-popconfirm"),_=v("a-table");return o(),r(f,null,[A("div",z,[s(p,{onClick:a.searchDocList,type:"primary"},{default:n(()=>[H]),_:1},8,["onClick"]),s(p,{onClick:a.addDocLine},{default:n(()=>[M]),_:1},8,["onClick"])]),s(_,{dataSource:a.docList,columns:a.docListColumns,size:"middle",id:"paramTable",loading:a.docListLoading,pagination:!1,scroll:{x:1e3,y:"calc(100vh - 240px)"}},{bodyCell:n(({column:g,text:E,record:m})=>[g.dataIndex==="paramKey"?(o(),r(f,{key:0},[m.isEdit?(o(),k(b,{key:0,placeholder:"\u8BF7\u8F93\u5165\u53C2\u6570\u540D\u79F0",value:a.docEdit.paramKey,"onUpdate:value":e[0]||(e[0]=u=>a.docEdit.paramKey=u)},null,8,["value"])):(o(),r("span",R,B(E),1))],64)):C("",!0),g.dataIndex==="paramValue"?(o(),r(f,{key:1},[m.isEdit?(o(),k(b,{key:0,rows:1,placeholder:"\u8BF7\u8F93\u5165\u53C2\u6570\u503C",value:a.docEdit.paramValue,"onUpdate:value":e[1]||(e[1]=u=>a.docEdit.paramValue=u)},null,8,["value"])):(o(),r("span",q,B(E),1))],64)):C("",!0),g.dataIndex==="paramType"?(o(),r(f,{key:2},[m.isEdit?(o(),k(L,{key:0,placeholder:"\u53C2\u6570\u4F4D\u7F6E",value:a.docEdit.paramType,"onUpdate:value":e[2]||(e[2]=u=>a.docEdit.paramType=u),style:{width:"110px"}},{default:n(()=>[s(y,{value:1},{default:n(()=>[J]),_:1}),s(y,{value:2},{default:n(()=>[O]),_:1}),s(y,{value:3},{default:n(()=>[Q]),_:1})]),_:1},8,["value"])):(o(),r(f,{key:1},[E===1?(o(),k(h,{key:0,color:"green"},{default:n(()=>[W]),_:1})):E===2?(o(),k(h,{key:1,color:"pink"},{default:n(()=>[X]),_:1})):E===3?(o(),k(h,{key:2,color:"pink"},{default:n(()=>[Y]),_:1})):C("",!0)],64))],64)):C("",!0),g.dataIndex==="operation"?(o(),r(f,{key:3},[m.isEdit?(o(),r(f,{key:0},[s(p,{type:"link",onClick:u=>a.cancelEditDoc(m)},{default:n(()=>[Z]),_:2},1032,["onClick"]),s(p,{type:"link",onClick:u=>a.saveEditDoc(m)},{default:n(()=>[$]),_:2},1032,["onClick"])],64)):(o(),r(f,{key:1},[s(p,{type:"link",onClick:u=>a.editDoc(m)},{default:n(()=>[ee]),_:2},1032,["onClick"]),s(t,{title:"\u786E\u5B9A\u8981\u5220\u9664\u5417\uFF1F",onConfirm:u=>a.deleteDoc(m)},{default:n(()=>[s(p,{type:"link",danger:""},{default:n(()=>[ae]),_:1})]),_:2},1032,["onConfirm"])],64))],64)):C("",!0)]),_:1},8,["dataSource","columns","loading","scroll"])],64)}var de=S(j,[["render",te]]);export{de as default};

View File

@@ -0,0 +1 @@
import{_ as e}from"./main.a6c14cdf.js";import{o as t,b as o}from"./vendor.1b910c8a.js";const n={name:"SettingView",components:{},data(){return{}},computed:{},mounted(){},methods:{}};function r(a,c,s,m,d,i){return t(),o("div",null," \u5C55\u793A\u914D\u7F6E\u9875\u9762 ")}var f=e(n,[["render",r]]);export{f as default};

View File

@@ -1 +0,0 @@
import{_ as e}from"./main.4232e7c8.js";import{o as t,b as o}from"./vendor.2a860d56.js";const n={name:"SettingView",components:{},data(){return{}},computed:{},mounted(){},methods:{}};function r(a,s,c,m,d,i){return t(),o("div",null," \u5C55\u793A\u914D\u7F6E\u9875\u9762 ")}var u=e(n,[["render",r]]);export{u as default};

View File

@@ -1 +1 @@
import{u as p,y as g,H as f,G as x,o as i,b as l,e as _,F as w,d as L,aq as N,ar as C,t as H,ak as I,r as m,a as v,w as u,c as S,k as A}from"./vendor.2a860d56.js";import{m as T}from"./mavon-editor.824ddc3c.js";import"./index.c860d973.js";import{_ as y}from"./main.4232e7c8.js";const D={props:{heading:{type:Array,default:[]}},setup(r){const s=p();let a=g("100px");f(()=>{window.onresize=()=>{n()},setTimeout(()=>{n()},100)}),x(s.getters.getLeftAsideWidth,()=>{n()});let e=g();const n=()=>{a.value=window.getComputedStyle(e.value,null).width};return{navigationRef:e,navigationWidth:a,headingItemClick:t=>{t.node.scrollIntoView({behavior:"smooth",block:"start",inline:"nearest"})}}}},b={class:"navigation"},j={ref:"navigationRef",style:{display:"inline-block",width:"100%",height:"1px"}},q=["onClick"];function B(r,s,a,e,n,c){return i(),l("div",b,[_("div",j,null,512),_("div",{class:"navigation-heading",style:N({width:e.navigationWidth})},[(i(!0),l(w,null,L(a.heading,t=>(i(),l("div",{class:C("heading-item heading-"+t.level),onClick:o=>e.headingItemClick(t)},H(t.text),11,q))),256))],4)])}var M=y(D,[["render",B]]);const R={components:{Navigation:M},setup(){const r=p(),s=I(()=>r.state.apiDoc);let a=g();x(r.getters.getApiDoc,()=>{setTimeout(()=>{c(".share-instruction")},100)});const e=t=>T.exports.markdownIt.render(t||"");let n=g([]);const c=t=>{if(!document.querySelector(t))return[];let o=document.querySelector(t).querySelectorAll("h1,h2,h3,h4,h5,h6");if(o.length<=0)return[];let d=[];o.forEach(h=>{let k=h.innerHTML.replace(/^\s+/g,"").replace(/\s+$/g,"").replace(/<\/?[^>]+(>|$)/g,"");d.push({node:h,level:parseInt(h.tagName.replace(/[h]/i,""),10),text:k})}),n.value=d};return f(()=>{}),{apiDoc:s,navigationRef:a,navigationList:n,markdownToHtml:e}}},V={key:0},W=["innerHTML"],$={key:1,style:{"text-align":"center"}};function z(r,s,a,e,n,c){const t=m("Navigation"),o=m("a-col"),d=m("a-row");return e.apiDoc.shareInstruction?(i(),l("div",V,[v(d,null,{default:u(()=>[e.navigationList.length>0?(i(),S(o,{key:0,xs:0,sm:4,md:4,lg:6,xl:6},{default:u(()=>[v(t,{ref:"navigationRef",heading:e.navigationList},null,8,["heading"])]),_:1})):A("",!0),v(o,{xs:24,sm:e.navigationList.length>0?20:24,md:e.navigationList.length>0?20:24,lg:e.navigationList.length>0?18:24,xl:e.navigationList.length>0?18:24},{default:u(()=>[_("div",{class:"markdown-body share-instruction",innerHTML:e.markdownToHtml(e.apiDoc.shareInstruction),style:{margin:"0 auto","max-width":"1000px"}},null,8,W)]),_:1},8,["sm","md","lg","xl"])]),_:1})])):(i(),l("div",$,"\u6B22\u8FCE\u8BBF\u95EE\u5F00\u653EAPI\u6587\u6863"))}var J=y(R,[["render",z]]);export{J as default}; import{u as p,y as g,H as f,G as x,o as i,b as l,e as _,F as w,d as L,ar as N,as as C,t as H,al as I,r as m,a as v,w as u,c as S,k as A}from"./vendor.1b910c8a.js";import{m as T}from"./mavon-editor.ee685efd.js";import"./index.c860d973.js";import{_ as y}from"./main.a6c14cdf.js";const b={props:{heading:{type:Array,default:[]}},setup(r){const s=p();let a=g("100px");f(()=>{window.onresize=()=>{n()},setTimeout(()=>{n()},100)}),x(s.getters.getLeftAsideWidth,()=>{n()});let e=g();const n=()=>{a.value=window.getComputedStyle(e.value,null).width};return{navigationRef:e,navigationWidth:a,headingItemClick:t=>{t.node.scrollIntoView({behavior:"smooth",block:"start",inline:"nearest"})}}}},D={class:"navigation"},j={ref:"navigationRef",style:{display:"inline-block",width:"100%",height:"1px"}},B=["onClick"];function M(r,s,a,e,n,c){return i(),l("div",D,[_("div",j,null,512),_("div",{class:"navigation-heading",style:N({width:e.navigationWidth})},[(i(!0),l(w,null,L(a.heading,t=>(i(),l("div",{class:C("heading-item heading-"+t.level),onClick:o=>e.headingItemClick(t)},H(t.text),11,B))),256))],4)])}var R=y(b,[["render",M]]);const V={components:{Navigation:R},setup(){const r=p(),s=I(()=>r.state.apiDoc);let a=g();x(r.getters.getApiDoc,()=>{setTimeout(()=>{c(".share-instruction")},100)});const e=t=>T.exports.markdownIt.render(t||"");let n=g([]);const c=t=>{if(!document.querySelector(t))return[];let o=document.querySelector(t).querySelectorAll("h1,h2,h3,h4,h5,h6");if(o.length<=0)return[];let d=[];o.forEach(h=>{let k=h.innerHTML.replace(/^\s+/g,"").replace(/\s+$/g,"").replace(/<\/?[^>]+(>|$)/g,"");d.push({node:h,level:parseInt(h.tagName.replace(/[h]/i,""),10),text:k})}),n.value=d};return f(()=>{}),{apiDoc:s,navigationRef:a,navigationList:n,markdownToHtml:e}}},W={key:0},$=["innerHTML"],q={key:1,style:{"text-align":"center"}};function z(r,s,a,e,n,c){const t=m("Navigation"),o=m("a-col"),d=m("a-row");return e.apiDoc.shareInstruction?(i(),l("div",W,[v(d,null,{default:u(()=>[e.navigationList.length>0?(i(),S(o,{key:0,xs:0,sm:4,md:4,lg:6,xl:6},{default:u(()=>[v(t,{ref:"navigationRef",heading:e.navigationList},null,8,["heading"])]),_:1})):A("",!0),v(o,{xs:24,sm:e.navigationList.length>0?20:24,md:e.navigationList.length>0?20:24,lg:e.navigationList.length>0?18:24,xl:e.navigationList.length>0?18:24},{default:u(()=>[_("div",{class:"markdown-body share-instruction",innerHTML:e.markdownToHtml(e.apiDoc.shareInstruction),style:{margin:"0 auto","max-width":"1000px"}},null,8,$)]),_:1},8,["sm","md","lg","xl"])]),_:1})])):(i(),l("div",q,"\u6B22\u8FCE\u8BBF\u95EE\u5F00\u653EAPI\u6587\u6863"))}var J=y(V,[["render",z]]);export{J as default};

View File

@@ -1 +1 @@
var x=Object.defineProperty,E=Object.defineProperties;var O=Object.getOwnPropertyDescriptors;var L=Object.getOwnPropertySymbols;var k=Object.prototype.hasOwnProperty,M=Object.prototype.propertyIsEnumerable;var b=(r,e,t)=>e in r?x(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,y=(r,e)=>{for(var t in e||(e={}))k.call(e,t)&&b(r,t,e[t]);if(L)for(var t of L(e))M.call(e,t)&&b(r,t,e[t]);return r},v=(r,e)=>E(r,O(e));import{_ as R}from"./main.4232e7c8.js";import{H as j,y as T,o as z,b as C,e as w}from"./vendor.2a860d56.js";const D=["get","head","post","put","patch","delete","options","trace"];function W(r){let e={},t={},o={},h=r.paths;return h?(Object.keys(h).forEach(n=>{let s=h[n];for(let a of D){if(!s[a]||!s[a].tags)continue;let d=a.toLowerCase();o[d]=(o[d]||0)+1,o.total=(o.total||0)+1,s[a].tags.forEach(c=>{let i=e[c];i||(i=e[c]={});let l=i[n];l||(l=i[n]={});let f=n+"."+a;l[a]=s[a],l[a].path=f,l[a].url=n,l[a].method=a,t[f]=s[a]})}}),{urlMethodMap:t,tagPathMap:e,methodStatistic:o}):{urlMethodMap:t,tagPathMap:e,methodStatistic:o}}function H(r,e,t,o){let h=[],n=1,s=r.tags||[];return s.length<=0&&Object.keys(e).forEach(a=>s.push({name:a})),s.forEach(a=>{let d=1,c=[],i=e[a.name];!i||(Object.keys(i).forEach(l=>{let f=1,p=i[l];Object.keys(p).forEach(g=>{let m=n+"_"+d+"_"+f,u=p[g];if(!I(l,u,t))return;u.treeId=m;let _=u.summary||u.path;c.push({title:_,key:m,isLeaf:!0,method:u.method,query:v(y({},o),{path:u.url,method:u.method})}),f++}),d++}),c.length>0&&h.push({title:a.name,key:n,children:c}),n++)}),[{key:"main",title:r.info.title||"Swagger\u63A5\u53E3\u6587\u6863",children:h}]}function I(r,e,t){if(!t||!r||(r=r.toLowerCase(),t=t.toLowerCase(),r.indexOf(t)>=0))return!0;let o=e.path+e.method+e.summary+e.description+e.tags;return o&&o.toLowerCase().indexOf(t)>=0}const $=["get","head","post","put","patch","delete","options","trace"];function V(r){let e={},t={},o={},h=r.paths;return h?(Object.keys(h).forEach(n=>{let s=h[n];for(let a of $){if(!s[a]||!s[a].tags)continue;let d=a.toLowerCase();o[d]=(o[d]||0)+1,o.total=(o.total||0)+1,s[a].tags.forEach(c=>{let i=e[c];i||(i=e[c]={});let l=i[n];l||(l=i[n]={});let f=n+"."+a;l[a]=s[a],l[a].path=f,l[a].url=n,l[a].method=a,t[f]=s[a]})}}),{urlMethodMap:t,tagPathMap:e,methodStatistic:o}):{urlMethodMap:t,tagPathMap:e,methodStatistic:o}}function G(r,e,t,o){let h=[],n=1,s=r.tags||[];return s.length<=0&&Object.keys(e).forEach(a=>s.push({name:a})),s.forEach(a=>{let d=1,c=[],i=e[a.name];!i||(Object.keys(i).forEach(l=>{let f=1,p=i[l];Object.keys(p).forEach(g=>{let m=n+"_"+d+"_"+f,u=p[g];if(!B(l,u,t))return;u.treeId=m;let _=u.summary||u.path;c.push({title:_,key:m,isLeaf:!0,method:u.method,query:v(y({},o),{path:u.url,method:u.method})}),f++}),d++}),c.length>0&&h.push({title:a.name,key:n,children:c}),n++)}),[{key:"main",title:r.info.title||"Swagger\u63A5\u53E3\u6587\u6863",children:h}]}function B(r,e,t){if(!t||!r||(r=r.toLowerCase(),t=t.toLowerCase(),r.indexOf(t)>=0))return!0;let o=e.path+e.method+e.summary+e.description+e.tags;return o&&o.toLowerCase().indexOf(t)>=0}const P={emits:["update:value","change"],setup(r,{emit:e}){j(()=>{n()});let t=T(300),o=T(),h=T();const n=()=>{let s=o.value,a=h.value;s.onmousedown=d=>{let c=d.clientX;return s.style.background="#ccc",a.style.background="#aaa",s.left=s.offsetLeft,document.onmousemove=i=>{let l=i.clientX,f=c-l;(f<0&&t.value<600||f>0&&t.value>300)&&(c=l,t.value-=f,t.value<300&&(t.value=300),e("update:value",t.value),e("change",t.value))},document.onmouseup=()=>{s.style.background="#fafafa",a.style.background="#ccc",document.onmousemove=null,document.onmouseup=null},!1}};return{leftAsideWidth:t,leftResizeRef:o,leftResizeBarRef:h}}},U={ref:"leftResizeRef",class:"left-resize"},A={ref:"leftResizeBarRef"};function S(r,e,t,o,h,n){return z(),C("div",U,[w("i",A,"...",512)],512)}var J=R(P,[["render",S],["__scopeId","data-v-33303c20"]]),K="assets/api-logo.952f0c92.png";export{J as L,K as _,W as a,V as b,G as c,H as g}; var x=Object.defineProperty,O=Object.defineProperties;var E=Object.getOwnPropertyDescriptors;var L=Object.getOwnPropertySymbols;var k=Object.prototype.hasOwnProperty,M=Object.prototype.propertyIsEnumerable;var b=(r,e,t)=>e in r?x(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,y=(r,e)=>{for(var t in e||(e={}))k.call(e,t)&&b(r,t,e[t]);if(L)for(var t of L(e))M.call(e,t)&&b(r,t,e[t]);return r},v=(r,e)=>O(r,E(e));import{_ as R}from"./main.a6c14cdf.js";import{H as j,y as T,o as z,b as C,e as D}from"./vendor.1b910c8a.js";const w=["get","head","post","put","patch","delete","options","trace"];function W(r){let e={},t={},o={},h=r.paths;return h?(Object.keys(h).forEach(n=>{let s=h[n];for(let a of w){if(!s[a]||!s[a].tags)continue;let p=a.toLowerCase();o[p]=(o[p]||0)+1,o.total=(o.total||0)+1,s[a].tags.forEach(c=>{let i=e[c];i||(i=e[c]={});let l=i[n];l||(l=i[n]={});let f=n+"."+a;l[a]=s[a],l[a].path=f,l[a].url=n,l[a].method=a,t[f]=s[a]})}}),{urlMethodMap:t,tagPathMap:e,methodStatistic:o}):{urlMethodMap:t,tagPathMap:e,methodStatistic:o}}function H(r,e,t,o){let h=[],n=1,s=r.tags||[];return s.length<=0&&Object.keys(e).forEach(a=>s.push({name:a})),s.forEach(a=>{let p=1,c=[],i=e[a.name];!i||(Object.keys(i).forEach(l=>{let f=1,d=i[l];Object.keys(d).forEach(g=>{let m=n+"_"+p+"_"+f,u=d[g];if(!I(l,u,t))return;u.treeId=m;let _=u.summary||u.path;c.push({title:_,key:m,isLeaf:!0,method:u.method,query:v(y({},o),{path:u.url,method:u.method})}),f++}),p++}),c.length>0&&h.push({title:a.name,key:n,children:c}),n++)}),[{key:"main",title:r.info.title||"Swagger\u63A5\u53E3\u6587\u6863",children:h}]}function I(r,e,t){if(!t||!r||(r=r.toLowerCase(),t=t.toLowerCase(),r.indexOf(t)>=0))return!0;let o=e.path+e.method+e.summary+e.description+e.tags;return o&&o.toLowerCase().indexOf(t)>=0}const $=["get","head","post","put","patch","delete","options","trace"];function V(r){let e={},t={},o={},h=r.paths;return h?(Object.keys(h).forEach(n=>{let s=h[n];for(let a of $){if(!s[a]||!s[a].tags)continue;let p=a.toLowerCase();o[p]=(o[p]||0)+1,o.total=(o.total||0)+1,s[a].tags.forEach(c=>{let i=e[c];i||(i=e[c]={});let l=i[n];l||(l=i[n]={});let f=n+"."+a;l[a]=s[a],l[a].path=f,l[a].url=n,l[a].method=a,t[f]=s[a]})}}),{urlMethodMap:t,tagPathMap:e,methodStatistic:o}):{urlMethodMap:t,tagPathMap:e,methodStatistic:o}}function G(r,e,t,o){let h=[],n=1,s=r.tags||[];return s.length<=0&&Object.keys(e).forEach(a=>s.push({name:a})),s.forEach(a=>{let p=1,c=[],i=e[a.name];!i||(Object.keys(i).forEach(l=>{let f=1,d=i[l];Object.keys(d).forEach(g=>{let m=n+"_"+p+"_"+f,u=d[g];if(!A(l,u,t))return;u.treeId=m;let _=u.summary||u.path;c.push({title:_,key:m,isLeaf:!0,method:u.method,query:v(y({},o),{path:u.url,method:u.method})}),f++}),p++}),c.length>0&&h.push({title:a.name,key:n,children:c}),n++)}),[{key:"main",title:r.info.title||"OpenApi\u63A5\u53E3\u6587\u6863",children:h}]}function A(r,e,t){if(!t||!r||(r=r.toLowerCase(),t=t.toLowerCase(),r.indexOf(t)>=0))return!0;let o=e.path+e.method+e.summary+e.description+e.tags;return o&&o.toLowerCase().indexOf(t)>=0}const B={emits:["update:value","change"],setup(r,{emit:e}){j(()=>{n()});let t=T(300),o=T(),h=T();const n=()=>{let s=o.value,a=h.value;s.onmousedown=p=>{let c=p.clientX;return s.style.background="#ccc",a.style.background="#aaa",s.left=s.offsetLeft,document.onmousemove=i=>{let l=i.clientX,f=c-l;(f<0&&t.value<600||f>0&&t.value>300)&&(c=l,t.value-=f,t.value<300&&(t.value=300),e("update:value",t.value),e("change",t.value))},document.onmouseup=()=>{s.style.background="#fafafa",a.style.background="#ccc",document.onmousemove=null,document.onmouseup=null},!1}};return{leftAsideWidth:t,leftResizeRef:o,leftResizeBarRef:h}}},P={ref:"leftResizeRef",class:"left-resize"},U={ref:"leftResizeBarRef"};function S(r,e,t,o,h,n){return z(),C("div",P,[D("i",U,"...",512)],512)}var J=R(B,[["render",S],["__scopeId","data-v-33303c20"]]),K="assets/api-logo.952f0c92.png";export{J as L,K as _,W as a,V as b,G as c,H as g};

View File

@@ -1 +1 @@
import{B as r}from"./vendor.2a860d56.js";var g={log(o,l,s){console.log(o+"-\u9047\u5230\u672A\u5904\u7406\u7684\u7C7B\u578B\uFF0C\u8BF7\u8054\u7CFB\u5F00\u53D1\u4EBA\u5458\u4FEE\u6539\uFF1A"+l,s)},logMessage(o,l,s){console.log(o+"-\u9047\u5230\u672A\u5904\u7406\u7684\u7C7B\u578B\uFF0C\u8BF7\u8054\u7CFB\u5F00\u53D1\u4EBA\u5458\u4FEE\u6539\uFF1A"+l,s),r.error(o+"-\u9047\u5230\u672A\u5904\u7406\u7684\u7C7B\u578B\uFF0C\u8BF7\u8054\u7CFB\u5F00\u53D1\u4EBA\u5458\u4FEE\u6539\uFF1A"+l)}};export{g as l}; import{B as r}from"./vendor.1b910c8a.js";var g={log(o,l,s){console.log(o+"-\u9047\u5230\u672A\u5904\u7406\u7684\u7C7B\u578B\uFF0C\u8BF7\u8054\u7CFB\u5F00\u53D1\u4EBA\u5458\u4FEE\u6539\uFF1A"+l,s)},logMessage(o,l,s){console.log(o+"-\u9047\u5230\u672A\u5904\u7406\u7684\u7C7B\u578B\uFF0C\u8BF7\u8054\u7CFB\u5F00\u53D1\u4EBA\u5458\u4FEE\u6539\uFF1A"+l,s),r.error(o+"-\u9047\u5230\u672A\u5904\u7406\u7684\u7C7B\u578B\uFF0C\u8BF7\u8054\u7CFB\u5F00\u53D1\u4EBA\u5458\u4FEE\u6539\uFF1A"+l)}};export{g as l};

View File

@@ -5,8 +5,8 @@
<link rel="icon" href="api-logo.png" /> <link rel="icon" href="api-logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>API文档管理</title> <title>API文档管理</title>
<script type="module" crossorigin src="assets/main.4232e7c8.js"></script> <script type="module" crossorigin src="assets/main.a6c14cdf.js"></script>
<link rel="modulepreload" href="assets/vendor.2a860d56.js"> <link rel="modulepreload" href="assets/vendor.1b910c8a.js">
<link rel="stylesheet" href="assets/style.a6d9edcc.css"> <link rel="stylesheet" href="assets/style.a6d9edcc.css">
</head> </head>
<body> <body>

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 * @since 2019-08-22
*/ */
public class DocAuthConst { 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 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 USER_MANAGE = "USER_MANAGE";
public static final String AUTH_MANAGE = "AUTH_MANAGE"; public static final String AUTH_MANAGE = "AUTH_MANAGE";
public static final String AUTH_ASSIGN = "AUTH_ASSIGN"; 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 { public enum DocSysType {
// 系统类型 1=manage 2=wiki 3=db // 系统类型 1=manage 2=wiki 3=db
MANAGE(1), WIKI(2), DB(3), MANAGE(1), WIKI(2), DB(3), API(4),
; ;
DocSysType(int type) { DocSysType(int type) {

View File

@@ -1,8 +1,11 @@
package com.zyplayer.doc.data.service.manage; package com.zyplayer.doc.data.service.manage;
import com.baomidou.mybatisplus.core.metadata.IPage; 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.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> * <p>
@@ -13,7 +16,27 @@ import com.baomidou.mybatisplus.extension.service.IService;
* @since 2021-11-25 * @since 2021-11-25
*/ */
public interface ApiDocService extends IService<ApiDoc> { 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); ApiDoc getByShareUuid(String shareUuid);
} }

View File

@@ -12,5 +12,6 @@ import com.zyplayer.doc.data.repository.manage.entity.AuthInfo;
* @since 2018-12-03 * @since 2018-12-03
*/ */
public interface AuthInfoService extends IService<AuthInfo> { 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> { 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; package com.zyplayer.doc.data.service.manage.impl;
import java.util.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 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.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.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.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 org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.stream.Collectors;
/** /**
* <p> * <p>
* api文档地址 服务实现类 * api文档地址 服务实现类
@@ -20,17 +35,82 @@ import org.springframework.stereotype.Service;
@Service @Service
public class ApiDocServiceImpl extends ServiceImpl<ApiDocMapper, ApiDoc> implements ApiDocService { public class ApiDocServiceImpl extends ServiceImpl<ApiDocMapper, ApiDoc> implements ApiDocService {
@Resource
UserAuthService userAuthService;
@Resource
AuthInfoService authInfoService;
@Override @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<ApiDoc> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("yn", 1); queryWrapper.eq("yn", 1);
queryWrapper.eq(apiDoc.getDocType() != null, "doc_type", apiDoc.getDocType()); queryWrapper.eq(apiDoc.getDocType() != null, "doc_type", apiDoc.getDocType());
queryWrapper.eq(apiDoc.getOpenVisit() != null, "open_visit", apiDoc.getOpenVisit()); queryWrapper.eq(apiDoc.getOpenVisit() != null, "open_visit", apiDoc.getOpenVisit());
queryWrapper.eq(apiDoc.getDocStatus() != null, "doc_status", apiDoc.getDocStatus()); 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.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); 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 @Override

View File

@@ -1,5 +1,6 @@
package com.zyplayer.doc.data.service.manage.impl; 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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyplayer.doc.data.repository.manage.entity.AuthInfo; import com.zyplayer.doc.data.repository.manage.entity.AuthInfo;
import com.zyplayer.doc.data.repository.manage.mapper.AuthInfoMapper; import com.zyplayer.doc.data.repository.manage.mapper.AuthInfoMapper;
@@ -16,5 +17,9 @@ import org.springframework.stereotype.Service;
*/ */
@Service @Service
public class AuthInfoServiceImpl extends ServiceImpl<AuthInfoMapper, AuthInfo> implements AuthInfoService { 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.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 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.config.security.UserAuthVo;
import com.zyplayer.doc.data.repository.manage.entity.AuthInfo; 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.entity.UserAuth;
import com.zyplayer.doc.data.repository.manage.mapper.UserAuthMapper; 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.AuthInfoService;
import com.zyplayer.doc.data.service.manage.UserAuthService; import com.zyplayer.doc.data.service.manage.UserAuthService;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
@@ -30,9 +34,9 @@ public class UserAuthServiceImpl extends ServiceImpl<UserAuthMapper, UserAuth> i
AuthInfoService authInfoService; AuthInfoService authInfoService;
@Override @Override
public List<UserAuthVo> getUserAuthSet(Long id) { public List<UserAuthVo> getUserAuthSet(Long userId) {
QueryWrapper<UserAuth> authWrapper = new QueryWrapper<>(); 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); List<UserAuth> userAuthList = this.list(authWrapper);
if (CollectionUtils.isEmpty(userAuthList)) { if (CollectionUtils.isEmpty(userAuthList)) {
return Collections.emptyList(); return Collections.emptyList();
@@ -47,4 +51,47 @@ public class UserAuthServiceImpl extends ServiceImpl<UserAuthMapper, UserAuth> i
} }
return userAuthVoList; 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);
}
} }

View File

@@ -57,17 +57,13 @@ public class DbDataSourceAuthController {
queryWrapper.in("auth_name", authNameList); queryWrapper.in("auth_name", authNameList);
Collection<AuthInfo> authInfoList = authInfoService.list(queryWrapper); Collection<AuthInfo> authInfoList = authInfoService.list(queryWrapper);
Map<String, Long> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getAuthName, AuthInfo::getId)); Map<String, Long> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getAuthName, AuthInfo::getId));
// 先删除所有用户的权限 // 先删除所有用户的权限
QueryWrapper<UserAuth> updateWrapper = new QueryWrapper<>(); userAuthService.deleteModuleAuth(DocSysType.DB.getType(), DocSysModuleType.Db.DATASOURCE.getType(), sourceId);
updateWrapper.eq("auth_custom_suffix", DocAuthConst.DB + sourceId);
updateWrapper.eq("del_flag", 0);
userAuthService.remove(updateWrapper);
List<UserDbAuthVo> authVoList = JSON.parseArray(authList, UserDbAuthVo.class); List<UserDbAuthVo> authVoList = JSON.parseArray(authList, UserDbAuthVo.class);
for (UserDbAuthVo authVo : authVoList) { for (UserDbAuthVo authVo : authVoList) {
List<UserAuth> userAuthList = new LinkedList<>(); List<UserAuth> userAuthList = new LinkedList<>();
Integer executeAuth = Optional.ofNullable(authVo.getExecuteAuth()).orElse(0); int executeAuth = Optional.ofNullable(authVo.getExecuteAuth()).orElse(0);
if (executeAuth <= 0) { if (executeAuth <= 0) {
Long authId = authInfoMap.get(DbAuthType.NO_AUTH.getName()); Long authId = authInfoMap.get(DbAuthType.NO_AUTH.getName());
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId); UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
@@ -98,9 +94,6 @@ public class DbDataSourceAuthController {
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId); UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth); userAuthList.add(userAuth);
} }
if (userAuthList.size() <= 0) {
continue;
}
// 保存权限,重新登录后可用,后期可以考虑在这里直接修改缓存里的用户权限 // 保存权限,重新登录后可用,后期可以考虑在这里直接修改缓存里的用户权限
userAuthService.saveBatch(userAuthList); userAuthService.saveBatch(userAuthList);
} }
@@ -109,10 +102,7 @@ public class DbDataSourceAuthController {
@PostMapping("/list") @PostMapping("/list")
public ResponseJson<Object> list(Long sourceId) { public ResponseJson<Object> list(Long sourceId) {
QueryWrapper<UserAuth> queryWrapper = new QueryWrapper<>(); List<UserAuth> authList = userAuthService.getModuleAuthList(DocSysType.DB.getType(), DocSysModuleType.Db.DATASOURCE.getType(), sourceId);
queryWrapper.eq("auth_custom_suffix", DocAuthConst.DB + sourceId);
queryWrapper.eq("del_flag", 0);
List<UserAuth> authList = userAuthService.list(queryWrapper);
if (CollectionUtils.isEmpty(authList)) { if (CollectionUtils.isEmpty(authList)) {
return DocResponseJson.ok(); return DocResponseJson.ok();
} }

View File

@@ -41,12 +41,13 @@ public class UserAuthController {
public ResponseJson<Object> list(Long userId) { public ResponseJson<Object> list(Long userId) {
QueryWrapper<UserAuth> userAuthWrapper = new QueryWrapper<>(); QueryWrapper<UserAuth> userAuthWrapper = new QueryWrapper<>();
userAuthWrapper.eq("user_id", userId); userAuthWrapper.eq("user_id", userId);
userAuthWrapper.eq("del_flag", 0);
List<UserAuth> userAuthList = userAuthService.list(userAuthWrapper); List<UserAuth> userAuthList = userAuthService.list(userAuthWrapper);
if (userAuthList == null || userAuthList.isEmpty()) { if (userAuthList == null || userAuthList.isEmpty()) {
return DocResponseJson.ok(); return DocResponseJson.ok();
} }
QueryWrapper<AuthInfo> authQueryWrapper = new QueryWrapper<>(); QueryWrapper<AuthInfo> authQueryWrapper = new QueryWrapper<>();
authQueryWrapper.in("id", userAuthList.stream().collect(Collectors.mapping(UserAuth::getAuthId, Collectors.toList()))); authQueryWrapper.in("id", userAuthList.stream().map(UserAuth::getAuthId).collect(Collectors.toSet()));
List<AuthInfo> authList = authInfoService.list(authQueryWrapper); List<AuthInfo> authList = authInfoService.list(authQueryWrapper);
return DocResponseJson.ok(authList); return DocResponseJson.ok(authList);
} }

View File

@@ -76,18 +76,18 @@ public class UserInfoController {
return DocResponseJson.ok(selfInfoVo); return DocResponseJson.ok(selfInfoVo);
} }
@AuthMan
@PostMapping("/search") @PostMapping("/search")
@AuthMan(DocAuthConst.USER_MANAGE)
public ResponseJson<Object> search(String search) { public ResponseJson<Object> search(String search) {
if (StringUtils.isBlank(search)) { if (StringUtils.isBlank(search)) {
return DocResponseJson.ok(); return DocResponseJson.ok();
} }
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(); QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.and(con -> con.and(conSub -> conSub.like("user_name", search).or().like("user_no", search) queryWrapper.and(con -> con.and(conSub -> conSub.like("user_name", search).or().like("user_no", search)
.or().like("email", search)).and(conSub -> conSub.eq("del_flag", 0))); .or().like("email", search).or().like("phone", search)).and(conSub -> conSub.eq("del_flag", 0)));
queryWrapper.select("id", "user_name"); queryWrapper.select("id", "user_name");
// 搜索最多返回20条 // 搜索最多返回20条
IPage<UserInfo> page = new Page<>(1, 20, false); IPage<UserInfo> page = Page.of(1, 20, false);
userInfoService.page(page, queryWrapper); userInfoService.page(page, queryWrapper);
return DocResponseJson.ok(page); return DocResponseJson.ok(page);
} }

View File

@@ -54,6 +54,8 @@ INSERT INTO `auth_info` VALUES (15, 'DB_SELECT_', '数据源查询权', 0, 1, '2
INSERT INTO `auth_info` VALUES (16, 'DB_UPDATE_', '数据源增删改查权', 0, 1, '2019-08-18 23:25:17', 0); INSERT INTO `auth_info` VALUES (16, 'DB_UPDATE_', '数据源增删改查权', 0, 1, '2019-08-18 23:25:17', 0);
INSERT INTO `auth_info` VALUES (17, 'DB_DESC_EDIT_', '表字段注释修改权', 0, 1, '2019-08-18 23:25:17', 0); INSERT INTO `auth_info` VALUES (17, 'DB_DESC_EDIT_', '表字段注释修改权', 0, 1, '2019-08-18 23:25:17', 0);
INSERT INTO `auth_info` VALUES (18, 'DB_PROC_EDIT_', '存储过程修改权', 0, 1, '2021-04-24 23:25:17', 0); INSERT INTO `auth_info` VALUES (18, 'DB_PROC_EDIT_', '存储过程修改权', 0, 1, '2021-04-24 23:25:17', 0);
INSERT INTO `auth_info` VALUES (19, 'API_DOC_MANAGE', 'api文档管理权', 0, 1, '2021-12-12 23:25:17', 0);
INSERT INTO `auth_info` VALUES (20, 'API_DOC_DEVELOPER', 'api文档编辑权', 0, 1, '2021-12-12 23:25:17', 0);
-- ---------------------------- -- ----------------------------
-- Table structure for db_datasource -- Table structure for db_datasource
@@ -161,18 +163,18 @@ CREATE TABLE `user_auth` (
-- ---------------------------- -- ----------------------------
-- Records of user_auth -- Records of user_auth
-- ---------------------------- -- ----------------------------
INSERT INTO `user_auth` VALUES (9, 2, 1, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL); INSERT INTO `user_auth` VALUES (9, 2, 1, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (10, 2, 2, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL); INSERT INTO `user_auth` VALUES (10, 2, 2, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (11, 2, 3, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL); INSERT INTO `user_auth` VALUES (11, 2, 3, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (12, 2, 4, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL); INSERT INTO `user_auth` VALUES (12, 2, 4, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (31, 3, 1, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL); INSERT INTO `user_auth` VALUES (31, 3, 1, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (32, 3, 2, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL); INSERT INTO `user_auth` VALUES (32, 3, 2, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (33, 3, 3, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL); INSERT INTO `user_auth` VALUES (33, 3, 3, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (34, 3, 4, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL); INSERT INTO `user_auth` VALUES (34, 3, 4, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (44, 1, 3, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL); INSERT INTO `user_auth` VALUES (44, 1, 3, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (45, 1, 4, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL); INSERT INTO `user_auth` VALUES (45, 1, 4, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (46, 1, 12, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL); INSERT INTO `user_auth` VALUES (46, 1, 12, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (47, 1, 13, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL); INSERT INTO `user_auth` VALUES (47, 1, 13, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL, NULL, NULL);
-- ---------------------------- -- ----------------------------
-- Table structure for user_info -- Table structure for user_info

View File

@@ -57,6 +57,8 @@ INSERT INTO `auth_info` VALUES (15, 'DB_SELECT_', '数据源查询权', 0, 1, '2
INSERT INTO `auth_info` VALUES (16, 'DB_UPDATE_', '数据源增删改查权', 0, 1, '2019-08-18 23:25:17', 0); INSERT INTO `auth_info` VALUES (16, 'DB_UPDATE_', '数据源增删改查权', 0, 1, '2019-08-18 23:25:17', 0);
INSERT INTO `auth_info` VALUES (17, 'DB_DESC_EDIT_', '表字段注释修改权', 0, 1, '2019-08-18 23:25:17', 0); INSERT INTO `auth_info` VALUES (17, 'DB_DESC_EDIT_', '表字段注释修改权', 0, 1, '2019-08-18 23:25:17', 0);
INSERT INTO `auth_info` VALUES (18, 'DB_PROC_EDIT_', '存储过程修改权', 0, 1, '2021-04-24 23:25:17', 0); INSERT INTO `auth_info` VALUES (18, 'DB_PROC_EDIT_', '存储过程修改权', 0, 1, '2021-04-24 23:25:17', 0);
INSERT INTO `auth_info` VALUES (19, 'API_DOC_MANAGE', 'api文档管理权', 0, 1, '2021-12-12 23:25:17', 0);
INSERT INTO `auth_info` VALUES (20, 'API_DOC_DEVELOPER', 'api文档编辑权', 0, 1, '2021-12-12 23:25:17', 0);
-- ---------------------------- -- ----------------------------
-- Table structure for db_datasource -- Table structure for db_datasource
@@ -164,18 +166,18 @@ CREATE TABLE `user_auth` (
-- ---------------------------- -- ----------------------------
-- Records of user_auth -- Records of user_auth
-- ---------------------------- -- ----------------------------
INSERT INTO `user_auth` VALUES (9, 2, 1, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL); INSERT INTO `user_auth` VALUES (9, 2, 1, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (10, 2, 2, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL); INSERT INTO `user_auth` VALUES (10, 2, 2, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (11, 2, 3, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL); INSERT INTO `user_auth` VALUES (11, 2, 3, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (12, 2, 4, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL); INSERT INTO `user_auth` VALUES (12, 2, 4, 1, NULL, 0, '2018-12-15 22:19:59', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (31, 3, 1, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL); INSERT INTO `user_auth` VALUES (31, 3, 1, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (32, 3, 2, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL); INSERT INTO `user_auth` VALUES (32, 3, 2, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (33, 3, 3, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL); INSERT INTO `user_auth` VALUES (33, 3, 3, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (34, 3, 4, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL); INSERT INTO `user_auth` VALUES (34, 3, 4, 1, NULL, 0, '2019-06-21 15:19:51', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (44, 1, 3, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL); INSERT INTO `user_auth` VALUES (44, 1, 3, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (45, 1, 4, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL); INSERT INTO `user_auth` VALUES (45, 1, 4, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (46, 1, 12, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL); INSERT INTO `user_auth` VALUES (46, 1, 12, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL, NULL, NULL);
INSERT INTO `user_auth` VALUES (47, 1, 13, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL); INSERT INTO `user_auth` VALUES (47, 1, 13, 1, NULL, 0, '2019-08-12 13:10:11', NULL, NULL, NULL, NULL);
-- ---------------------------- -- ----------------------------
-- Table structure for user_info -- Table structure for user_info

View File

@@ -66,3 +66,8 @@ ADD COLUMN `sys_module_id` bigint(20) NULL COMMENT '系统模块ID';
update user_auth set sys_type=3, sys_module_type=1, sys_module_id=replace(auth_custom_suffix, 'DB_', '') where auth_custom_suffix like 'DB_%'; update user_auth set sys_type=3, sys_module_type=1, sys_module_id=replace(auth_custom_suffix, 'DB_', '') where auth_custom_suffix like 'DB_%';
update user_auth set sys_type=2, sys_module_type=1, sys_module_id=replace(auth_custom_suffix, 'WIKI_', '') where auth_custom_suffix like 'WIKI_%'; update user_auth set sys_type=2, sys_module_type=1, sys_module_id=replace(auth_custom_suffix, 'WIKI_', '') where auth_custom_suffix like 'WIKI_%';
INSERT INTO `auth_info`(auth_name, auth_desc, can_edit, create_uid, creation_time, auth_type) VALUES
('API_DOC_MANAGE', 'api文档管理权', 0, 1, '2021-12-12 23:25:17', 0),
('API_DOC_DEVELOPER', 'api文档编辑权', 0, 1, '2021-12-12 23:25:17', 0);

View File

@@ -1,6 +1,9 @@
import apiClient from './request/zyplayer.js' import apiClient from './request/zyplayer.js'
export const zyplayerApi = { export const zyplayerApi = {
searchUserList: data => apiClient({url: '/user/info/search', method: 'post', data: data}),
getSelfUserInfo: data => apiClient({url: '/user/info/selfInfo', method: 'post', data: data}), getSelfUserInfo: data => apiClient({url: '/user/info/selfInfo', method: 'post', data: data}),
userLogout: data => apiClient({url: '/logout', method: 'post', data: data}), userLogout: data => apiClient({url: '/logout', method: 'post', data: data}),
systemUpgradeInfo: data => apiClient({url: '/system/info/upgrade', method: 'post', data: data}), systemUpgradeInfo: data => apiClient({url: '/system/info/upgrade', method: 'post', data: data}),
@@ -15,5 +18,9 @@ export const zyplayerApi = {
requestUrl: data => apiClient({url: '/doc-api/proxy/request', method: 'post', data: data}), requestUrl: data => apiClient({url: '/doc-api/proxy/request', method: 'post', data: data}),
apiShareDocDetail: data => apiClient({url: '/doc-api/share/detail', method: 'post', data: data}), apiShareDocDetail: data => apiClient({url: '/doc-api/share/detail', method: 'post', data: data}),
apiShareDocApisDetail: data => apiClient({url: '/doc-api/share/apis/detail', method: 'post', data: data}), apiShareDocApisDetail: data => apiClient({url: '/doc-api/share/apis/detail', method: 'post', data: data}),
docAuthList: data => apiClient({url: '/doc-api/doc/auth/list', method: 'post', data: data}),
docAuthAssign: data => apiClient({url: '/doc-api/doc/auth/assign', method: 'post', data: data}),
docAuthDelete: data => apiClient({url: '/doc-api/doc/auth/delete', method: 'post', data: data}),
}; };

View File

@@ -63,7 +63,6 @@ export function analysisOpenApiData(swagger) {
* @param tagPathMap 分组信息{分组名: {url: {...接口信息, path: '', url: '', method: ''}}} * @param tagPathMap 分组信息{分组名: {url: {...接口信息, path: '', url: '', method: ''}}}
* @param keywords 过滤关键字 * @param keywords 过滤关键字
* @param metaInfo 接口元信息点击时放入URL的参数 * @param metaInfo 接口元信息点击时放入URL的参数
* @returns {{children: [], title: (*|string), key: string}[]}
*/ */
export function getTreeDataForTag(swagger, tagPathMap, keywords, metaInfo) { export function getTreeDataForTag(swagger, tagPathMap, keywords, metaInfo) {
let treeData = []; let treeData = [];
@@ -116,7 +115,7 @@ export function getTreeDataForTag(swagger, tagPathMap, keywords, metaInfo) {
return [ return [
{ {
key: 'main', key: 'main',
title: swagger.info.title || 'Swagger接口文档', title: swagger.info.title || 'OpenApi接口文档',
children: treeData children: treeData
} }
]; ];

View File

@@ -63,7 +63,6 @@ export function analysisSwaggerData(swagger) {
* @param tagPathMap 分组信息{分组名: {url: {...接口信息, path: '', url: '', method: ''}}} * @param tagPathMap 分组信息{分组名: {url: {...接口信息, path: '', url: '', method: ''}}}
* @param keywords 过滤关键字 * @param keywords 过滤关键字
* @param metaInfo 接口元信息点击时放入URL的参数 * @param metaInfo 接口元信息点击时放入URL的参数
* @returns {{children: [], title: (*|string), key: string}[]}
*/ */
export function getTreeDataForTag(swagger, tagPathMap, keywords, metaInfo) { export function getTreeDataForTag(swagger, tagPathMap, keywords, metaInfo) {
let treeData = []; let treeData = [];

View File

@@ -1,6 +1,9 @@
<template> <template>
<a-directory-tree :showIcon="false" :tree-data="treeData" v-model:expandedKeys="expandedKeys" @select="docChecked"> <a-directory-tree :showIcon="false" :tree-data="treeData" v-model:expandedKeys="expandedKeys" @select="docChecked">
<template #title="{ title, isLeaf, method, children, key }"> <template #title="{ title, isLeaf, method, children, key }">
<template v-if="key === 'info'">
<file-text-outlined style="margin-right: 3px;"/>
</template>
<template v-if="isLeaf"> <template v-if="isLeaf">
<a-tag color="pink" v-if="method === 'get'">get</a-tag> <a-tag color="pink" v-if="method === 'get'">get</a-tag>
<a-tag color="red" v-else-if="method === 'post'">post</a-tag> <a-tag color="red" v-else-if="method === 'post'">post</a-tag>
@@ -22,10 +25,12 @@
import { useRouter, useRoute } from "vue-router"; import { useRouter, useRoute } from "vue-router";
import {useStore} from 'vuex'; import {useStore} from 'vuex';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import {InfoCircleOutlined, FileTextOutlined} from '@ant-design/icons-vue';
import {zyplayerApi} from '../../../api' import {zyplayerApi} from '../../../api'
import {analysisOpenApiData, getTreeDataForTag} from '../../../assets/core/OpenApiTreeAnalysis.js' import {analysisOpenApiData, getTreeDataForTag} from '../../../assets/core/OpenApiTreeAnalysis.js'
export default { export default {
components: {InfoCircleOutlined, FileTextOutlined},
setup() { setup() {
const store = useStore(); const store = useStore();
const route = useRoute(); const route = useRoute();
@@ -39,7 +44,7 @@
let searchKeywords = ref(''); let searchKeywords = ref('');
const docChecked = (val, node) => { const docChecked = (val, node) => {
if (node.node.key === 'main') { if (node.node.key === 'info') {
router.push({path: '/openapi/info'}); router.push({path: '/openapi/info'});
} else if (node.node.isLeaf) { } else if (node.node.isLeaf) {
let dataRef = node.node.dataRef; let dataRef = node.node.dataRef;
@@ -64,17 +69,12 @@
tagPathMap.value = treeData.tagPathMap; tagPathMap.value = treeData.tagPathMap;
loadTreeData(); loadTreeData();
callback(); callback();
setTimeout(() => {
let isViewPage = (route.path === '/openapi/view' && route.query.id);
if (!isViewPage) {
router.push({path: '/openapi/info'});
}
}, 0);
}); });
}; };
const loadTreeData = async () => { const loadTreeData = async () => {
let metaInfo = {id: choiceDocId.value}; let metaInfo = {id: choiceDocId.value};
treeData.value = getTreeDataForTag(openApiDoc.value, tagPathMap.value, searchKeywords.value, metaInfo); treeData.value = getTreeDataForTag(openApiDoc.value, tagPathMap.value, searchKeywords.value, metaInfo);
treeData.value.unshift({key: 'info', title: '文档说明信息', isLeaf: true});
await nextTick(); await nextTick();
expandedKeys.value = ['main']; expandedKeys.value = ['main'];
}; };

View File

@@ -1,6 +1,9 @@
<template> <template>
<a-directory-tree :showIcon="false" :tree-data="treeData" v-model:expandedKeys="expandedKeys" @select="docChecked"> <a-directory-tree :showIcon="false" :tree-data="treeData" v-model:expandedKeys="expandedKeys" @select="docChecked">
<template #title="{ title, isLeaf, method, children, key }"> <template #title="{ title, isLeaf, method, children, key }">
<template v-if="key === 'info'">
<file-text-outlined style="margin-right: 3px;"/>
</template>
<template v-if="isLeaf"> <template v-if="isLeaf">
<a-tag color="pink" v-if="method === 'get'">get</a-tag> <a-tag color="pink" v-if="method === 'get'">get</a-tag>
<a-tag color="red" v-else-if="method === 'post'">post</a-tag> <a-tag color="red" v-else-if="method === 'post'">post</a-tag>
@@ -22,10 +25,12 @@
import { useRouter, useRoute } from "vue-router"; import { useRouter, useRoute } from "vue-router";
import {useStore} from 'vuex'; import {useStore} from 'vuex';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import {InfoCircleOutlined, FileTextOutlined} from '@ant-design/icons-vue';
import {zyplayerApi} from '../../../api' import {zyplayerApi} from '../../../api'
import {analysisSwaggerData, getTreeDataForTag} from '../../../assets/core/SwaggerTreeAnalysis.js' import {analysisSwaggerData, getTreeDataForTag} from '../../../assets/core/SwaggerTreeAnalysis.js'
export default { export default {
components: {InfoCircleOutlined, FileTextOutlined},
setup() { setup() {
const store = useStore(); const store = useStore();
const route = useRoute(); const route = useRoute();
@@ -39,7 +44,7 @@
let searchKeywords = ref(''); let searchKeywords = ref('');
const docChecked = (val, node) => { const docChecked = (val, node) => {
if (node.node.key === 'main') { if (node.node.key === 'info') {
router.push({path: '/swagger/info'}); router.push({path: '/swagger/info'});
} else if (node.node.isLeaf) { } else if (node.node.isLeaf) {
let dataRef = node.node.dataRef; let dataRef = node.node.dataRef;
@@ -64,17 +69,12 @@
tagPathMap.value = treeData.tagPathMap; tagPathMap.value = treeData.tagPathMap;
loadTreeData(); loadTreeData();
callback(true); callback(true);
setTimeout(() => {
let isViewPage = (route.path === '/swagger/view' && route.query.id);
if (!isViewPage) {
router.push({path: '/swagger/info'});
}
}, 0);
}); });
}; };
const loadTreeData = async () => { const loadTreeData = async () => {
let metaInfo = {id: choiceDocId.value}; let metaInfo = {id: choiceDocId.value};
treeData.value = getTreeDataForTag(swaggerDoc.value, tagPathMap.value, searchKeywords.value, metaInfo); treeData.value = getTreeDataForTag(swaggerDoc.value, tagPathMap.value, searchKeywords.value, metaInfo);
treeData.value.unshift({key: 'info', title: '文档说明信息', isLeaf: true});
await nextTick(); await nextTick();
expandedKeys.value = ['main']; expandedKeys.value = ['main'];
}; };

View File

@@ -1,329 +1,33 @@
<template> <template>
<a-form layout="inline" style="margin-bottom: 20px;"> <DocManageList v-if="showView === 'list'" @showMembers="showMembers"></DocManageList>
<a-form-item label="文档类型"> <div v-else>
<a-select placeholder="请选择文档类型" v-model:value="searchParam.docType" style="width: 150px;"> <DocManageMembers v-if="showView === 'members'" @showDocList="showDocList" :doc="docInfo"></DocManageMembers>
<a-select-option value="">全部</a-select-option> </div>
<a-select-option :value="1">URL添加</a-select-option>
<a-select-option :value="2">JSON内容</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="开放访问">
<a-select placeholder="请选择开放访问" v-model:value="searchParam.openVisit" style="width: 150px;">
<a-select-option value="">全部</a-select-option>
<a-select-option :value="0"></a-select-option>
<a-select-option :value="1"></a-select-option>
</a-select>
</a-form-item>
<a-form-item label="状态">
<a-select placeholder="请选择状态" v-model:value="searchParam.docStatus" style="width: 150px;">
<a-select-option value="">全部</a-select-option>
<a-select-option :value="1">启用</a-select-option>
<a-select-option :value="2">禁用</a-select-option>
</a-select>
</a-form-item>
<a-form-item>
<a-button @click="searchDocList" type="primary">查询</a-button>
<a-button @click="openNewDoc" :style="{ marginLeft: '8px' }">新建</a-button>
</a-form-item>
</a-form>
<a-table :dataSource="docList" :columns="docListColumns" size="middle"
:loading="docListLoading" :pagination="pagination"
@change="handleTableChange"
:scroll="{ x: 1400, y: 'calc(100vh - 300px)' }">
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'operation'">
<a-button size="small" type="link" @click="editDoc(record)">编辑</a-button>
<a-popconfirm title="确定要删除吗?" @confirm="deleteDoc(record)">
<a-button size="small" type="link" danger>删除</a-button>
</a-popconfirm>
<a-dropdown :trigger="['click']">
<template #overlay>
<a-menu @click="handleActionMenuClick($event, record)">
<a-menu-item key="shareView"><link-outlined /> 查看开放文档</a-menu-item>
<a-menu-item key="shareInstruction"><edit-outlined /> 编辑开放文档说明</a-menu-item>
</a-menu>
</template>
<a-button type="link" size="small">更多<DownOutlined /></a-button>
</a-dropdown>
</template>
<template v-if="column.dataIndex === 'docType'">
<a-tag color="red" v-if="text === 1">Swagger URL</a-tag>
<a-tag color="blue" v-else-if="text === 2">Swagger JSON</a-tag>
<a-tag color="green" v-else-if="text === 4">OpenApi JSON</a-tag>
</template>
<template v-if="column.dataIndex === 'openVisit'">
<a-tag color="pink" v-if="text === 0">未开放</a-tag>
<a-tag color="green" v-else-if="text === 1">已开放</a-tag>
</template>
<template v-if="column.dataIndex === 'docStatus'">
<a-tag color="green" v-if="text === 1">启用</a-tag>
<a-tag color="pink" v-else-if="text === 2">禁用</a-tag>
</template>
</template>
</a-table>
<a-modal v-model:visible="newDocVisible" :title="docEdit.isNew?'新增文档':'编辑文档'" @ok="handleNewDocOk" :width="800">
<a-form layout="horizontal" ref="newDocFormRef" :rules="newDocRules" :model="docEdit" :label-col="{span: 4}" :wrapper-col="{span: 20}">
<a-form-item label="文档名称" required name="name">
<a-input placeholder="请输入文档名称" v-model:value="docEdit.name"></a-input>
</a-form-item>
<a-form-item label="文档类型" required name="docType">
<a-radio-group v-model:value="docEdit.docType">
<a-radio :value="1">Swagger URL</a-radio>
<a-radio :value="2">Swagger JSON</a-radio>
<a-radio :value="3">OpenApi URL</a-radio>
<a-radio :value="4">OpenApi JSON</a-radio>
<a-radio :value="5" disabled>自建API</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="文档地址" required name="docUrl" v-if="docEdit.docType === 1">
<a-input placeholder="请输入文档地址URL" v-model:value="docEdit.docUrl"></a-input>
<template #extra>
查看文档地址
<a-popover title="文档地址支持以下任一格式">
<template #content>
<p>格式一http://doc.zyplayer.com/v2/api-docs</p>
<p>格式二http://doc.zyplayer.com/swagger-resources</p>
<p>格式三http://doc.zyplayer.com/swagger-ui.html</p>
</template>
<a>示例</a>
</a-popover>
</template>
</a-form-item>
<a-form-item label="文档内容" required name="jsonContent" v-else-if="docEdit.docType === 2">
<!-- textarea在内容很多的时候>300KB会卡顿ace不会-->
<ace-editor v-model:value="docEdit.jsonContent" lang="json" theme="monokai" width="100%" height="100" :options="aceEditorConfig"></ace-editor>
<!-- <a-textarea placeholder="请输入JSON格式的Swagger文档内容" v-model:value="docEdit.jsonContent" :auto-size="{ minRows: 5, maxRows: 10 }"></a-textarea>-->
<template #extra>
查看文档内容
<a-popover title="文档内容说明">
<template #content>
<div>支持以下格式的Swagger文档内容输入其中 {"swagger": "2.0"} 为必要属性</div>
<div v-highlight>
<pre><code class="lang-json">{{swaggerDocDemo}}</code></pre>
</div>
</template>
<a>说明</a>
</a-popover>
</template>
</a-form-item>
<a-form-item label="文档地址" required name="docUrl" v-if="docEdit.docType === 3">
<a-input placeholder="请输入文档地址URL" v-model:value="docEdit.docUrl"></a-input>
<template #extra>
查看文档地址
<a-popover title="文档地址支持以下任一格式">
<template #content>
<p>格式一http://doc.zyplayer.com/v3/api-docs</p>
</template>
<a>示例</a>
</a-popover>
</template>
</a-form-item>
<a-form-item label="文档内容" required name="jsonContent" v-else-if="docEdit.docType === 4">
<ace-editor v-model:value="docEdit.jsonContent" lang="json" theme="monokai" width="100%" height="100" :options="aceEditorConfig"></ace-editor>
<!-- <a-textarea placeholder="请输入JSON格式的OpenApi文档内容" v-model:value="docEdit.jsonContent" :auto-size="{ minRows: 5, maxRows: 10 }"></a-textarea>-->
<template #extra>
查看文档内容
<a-popover title="文档内容说明">
<template #content>
<div>支持以下格式的OpenApi文档内容输入其中 {"openapi": "3.x.x"} 为必要属性</div>
<div v-highlight>
<pre><code class="lang-json">{{openApiDocDemo}}</code></pre>
</div>
</template>
<a>说明</a>
</a-popover>
</template>
</a-form-item>
<a-form-item label="目标域名" name="rewriteDomain">
<a-input placeholder="请输入目标域名" v-model:value="docEdit.rewriteDomain"></a-input>
<template #extra>
目标域名
<a-popover title="目标域名说明">
<template #content>
<p>在文档的在线调试界面访问的域名可以初始为此处录入的域名而非文档本身的域名地址</p>
<p>可便于不同环境间的接口测试http://doc.zyplayer.com</p>
</template>
<a>说明</a>
</a-popover>
</template>
</a-form-item>
<a-form-item label="开放访问" required name="openVisit">
<a-radio-group v-model:value="docEdit.openVisit">
<a-radio :value="0"></a-radio>
<a-radio :value="1">开放访问</a-radio>
</a-radio-group>
<template #extra>
开放访问后无需登录即可通过<a @click="openShareViewWindow(docEdit)">开放文档URL</a>访问该文档信息
</template>
</a-form-item>
<a-form-item label="状态" required name="docStatus">
<a-radio-group v-model:value="docEdit.docStatus">
<a-radio :value="1">启用</a-radio>
<a-radio :value="2">禁用</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
</a-modal>
<EditShareInstruction ref="instruction"></EditShareInstruction>
</template> </template>
<script> <script>
import { toRefs, ref, reactive, onMounted } from 'vue'; import { toRefs, ref, reactive, onMounted } from 'vue';
import {zyplayerApi} from '../../api'; import DocManageList from "./DocManageList.vue";
import {useStore} from 'vuex'; import DocManageMembers from "./DocManageMembers.vue";
import aceEditor from "../../assets/ace-editor";
import EditShareInstruction from "./components/EditShareInstruction.vue";
import {getZyplayerApiBaseUrl} from "../../api/request/utils";
import {DownOutlined, LinkOutlined, EditOutlined} from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
export default { export default {
components: {aceEditor, EditShareInstruction, DownOutlined, LinkOutlined, EditOutlined}, components: {DocManageList, DocManageMembers},
setup() { setup() {
const store = useStore(); let showView = ref('list');
let docList = ref([]); let docInfo = ref({});
let docListLoading = ref(false); const showMembers = (doc) => {
let searchParam = ref({docType: '', openVisit: '', docStatus: '', pageNum: 1, pageSize: 20}); docInfo.value = doc;
let pagination = ref({ showView.value = 'members';
pageSize: 20, };
pageNum: 1, const showDocList = () => {
total: 0, showView.value = 'list';
showSizeChanger: true, };
pageSizeOptions: ['20', '50', '100'],
showTotal: total => `${total}`
});
const handleTableChange = (paginationNew, filters, sorter) => {
pagination.value.pageNum = paginationNew.current;
pagination.value.pageSize = paginationNew.pageSize;
searchParam.value.pageNum = paginationNew.current;
searchParam.value.pageSize = paginationNew.pageSize;
searchDocList();
};
const searchDocList = async () => {
docListLoading.value = true;
zyplayerApi.apiDocList(searchParam.value).then(res => {
setTimeout(() => docListLoading.value = false, 500);
docList.value = res.data || [];
pagination.value.total = res.total || 0;
});
};
let docEdit = ref({});
let newDocFormRef = ref();
let newDocVisible = ref(false);
const handleNewDocOk = async () => {
newDocFormRef.value.validate().then(() => {
zyplayerApi.apiDocAdd(docEdit.value).then(res => {
searchDocList();
newDocVisible.value = false;
store.commit('addDocChangedNum');
});
}).catch(error => {
console.log('error', error);
});
};
const openNewDoc = async () => {
newDocVisible.value = true;
docEdit.value = {
docType: 1, openVisit: 0, docStatus: 1, isNew: 1
};
};
const editDoc = (record) => {
zyplayerApi.apiDocDetail({id: record.id}).then(res => {
docEdit.value = res.data;
newDocVisible.value = true;
});
};
const updateDoc = async (id, docStatus, yn) => {
zyplayerApi.apiDocUpdate({id, docStatus, yn}).then(res => {
searchDocList();
store.commit('addDocChangedNum');
});
};
const deleteDoc = async (row) => updateDoc(row.id, null, 0);
// 打开开放文档新窗口
const openShareViewWindow = record => {
if (!record.shareUuid) {
message.warning('请先保存文档后再试');
} else if (record.openVisit !== 1) {
message.warning('该文档尚未开启开放访问功能,请在编辑页选择开放后再试');
} else {
window.open(getZyplayerApiBaseUrl() + '/doc-api#/share/home?uuid=' + record.shareUuid);
}
};
const handleActionMenuClick = (item, record) => {
if (item.key === 'shareView') {
openShareViewWindow(record);
} else if (item.key === 'shareInstruction') {
instruction.value.editDoc(record.id);
}
}
let instruction = ref();
onMounted(() => {
searchDocList();
});
return { return {
searchParam, showView,
docList, docInfo,
docListLoading, showMembers,
newDocVisible, showDocList,
docEdit, }
newDocFormRef,
searchDocList,
openNewDoc,
handleNewDocOk,
deleteDoc,
editDoc,
handleTableChange,
openShareViewWindow,
handleActionMenuClick,
pagination,
instruction,
newDocRules: {
name: [{required: true, message: '请输入文档名称', trigger: 'change'}],
docUrl: [{required: true, message: '请输入文档地址', trigger: 'change'}],
jsonContent: [{required: true, message: '请输入JSON格式的swagger文档内容', trigger: 'change'}],
docType: [{type: 'number', required: true, message: '请选择文档类型', trigger: 'change'}],
openVisit: [{type: 'number', required: true, message: '请选择是否开放访问', trigger: 'change'}],
docStatus: [{type: 'number', required: true, message: '请选择文档状态', trigger: 'change'}],
},
docListColumns: [
{title: 'ID', dataIndex: 'id', width: 70},
{title: '文档名称', dataIndex: 'name', width: 250},
{title: '文档类型', dataIndex: 'docType', width: 120},
{title: '开放访问', dataIndex: 'openVisit', width: 90},
{title: '状态', dataIndex: 'docStatus', width: 90},
{title: '文档地址', dataIndex: 'docUrl'},
{title: '目标域名', dataIndex: 'rewriteDomain', width: 250},
{title: '操作', dataIndex: 'operation', fixed: 'right', width: 200},
],
aceEditorConfig: {
wrap: true,
autoScrollEditorIntoView: true,
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
minLines: 10,
maxLines: 15,
},
swaggerDocDemo:
'{\n'
+ ' "swagger": "2.0",\n'
+ ' "info": {},\n'
+ ' "host": "doc.zyplayer.com",\n'
+ ' "basePath":"/",\n'
+ ' "tags": [],\n'
+ ' "paths": {},\n'
+ ' "definitions": {}\n'
+ '}',
openApiDocDemo:
'{\n'
+ ' "openapi": "3.0.3",\n'
+ ' "components": {}\n'
+ ' "servers": [],\n'
+ ' "paths": {},\n'
+ ' "info": {},\n'
+ '}',
};
}, },
}; };
</script> </script>

View File

@@ -0,0 +1,337 @@
<template>
<a-form layout="inline" style="margin-bottom: 20px;">
<a-form-item label="文档类型">
<a-select placeholder="请选择文档类型" v-model:value="searchParam.docType" style="width: 150px;">
<a-select-option value="">全部</a-select-option>
<a-select-option :value="1">URL添加</a-select-option>
<a-select-option :value="2">JSON内容</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="开放访问">
<a-select placeholder="请选择开放访问" v-model:value="searchParam.openVisit" style="width: 150px;">
<a-select-option value="">全部</a-select-option>
<a-select-option :value="0"></a-select-option>
<a-select-option :value="1"></a-select-option>
</a-select>
</a-form-item>
<a-form-item label="状态">
<a-select placeholder="请选择状态" v-model:value="searchParam.docStatus" style="width: 150px;">
<a-select-option value="">全部</a-select-option>
<a-select-option :value="1">启用</a-select-option>
<a-select-option :value="2">禁用</a-select-option>
</a-select>
</a-form-item>
<a-form-item>
<a-button @click="searchDocList" type="primary">查询</a-button>
<a-button @click="openNewDoc" :style="{ marginLeft: '8px' }">新建</a-button>
</a-form-item>
</a-form>
<a-table :dataSource="docList" :columns="docListColumns" size="middle"
:loading="docListLoading" :pagination="pagination"
@change="handleTableChange"
:scroll="{ x: 1400, y: 'calc(100vh - 300px)' }">
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'operation'">
<a-button size="small" type="link" @click="editDoc(record)">编辑</a-button>
<template v-if="record.authType === 1">
<a-button size="small" type="link" @click="showMembers(record)">成员管理</a-button>
<a-popconfirm title="确定要删除吗?" @confirm="deleteDoc(record)">
<a-button size="small" type="link" danger>删除</a-button>
</a-popconfirm>
</template>
<a-dropdown :trigger="['click']">
<template #overlay>
<a-menu @click="handleActionMenuClick($event, record)">
<a-menu-item key="shareView"><link-outlined /> 查看开放文档</a-menu-item>
<a-menu-item key="shareInstruction"><edit-outlined /> 编辑开放文档说明</a-menu-item>
</a-menu>
</template>
<a-button type="link" size="small">更多<DownOutlined /></a-button>
</a-dropdown>
</template>
<template v-if="column.dataIndex === 'docType'">
<a-tag color="red" v-if="text === 1">Swagger URL</a-tag>
<a-tag color="blue" v-else-if="text === 2">Swagger JSON</a-tag>
<a-tag color="green" v-else-if="text === 4">OpenApi JSON</a-tag>
</template>
<template v-if="column.dataIndex === 'openVisit'">
<a-tag color="pink" v-if="text === 0">未开放</a-tag>
<a-tag color="green" v-else-if="text === 1">已开放</a-tag>
</template>
<template v-if="column.dataIndex === 'docStatus'">
<a-tag color="green" v-if="text === 1">启用</a-tag>
<a-tag color="pink" v-else-if="text === 2">禁用</a-tag>
</template>
</template>
</a-table>
<a-modal v-model:visible="newDocVisible" :title="docEdit.isNew?'新增文档':'编辑文档'" @ok="handleNewDocOk" :width="800">
<a-form layout="horizontal" ref="newDocFormRef" :rules="newDocRules" :model="docEdit" :label-col="{span: 4}" :wrapper-col="{span: 20}">
<a-form-item label="文档名称" required name="name">
<a-input placeholder="请输入文档名称" v-model:value="docEdit.name"></a-input>
</a-form-item>
<a-form-item label="文档类型" required name="docType">
<a-radio-group v-model:value="docEdit.docType">
<a-radio :value="1">Swagger URL</a-radio>
<a-radio :value="2">Swagger JSON</a-radio>
<a-radio :value="3">OpenApi URL</a-radio>
<a-radio :value="4">OpenApi JSON</a-radio>
<a-radio :value="5" disabled>自建API</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="文档地址" required name="docUrl" v-if="docEdit.docType === 1">
<a-input placeholder="请输入文档地址URL" v-model:value="docEdit.docUrl"></a-input>
<template #extra>
查看文档地址
<a-popover title="文档地址支持以下任一格式">
<template #content>
<p>格式一http://doc.zyplayer.com/v2/api-docs</p>
<p>格式二http://doc.zyplayer.com/swagger-resources</p>
<p>格式三http://doc.zyplayer.com/swagger-ui.html</p>
</template>
<a>示例</a>
</a-popover>
</template>
</a-form-item>
<a-form-item label="文档内容" required name="jsonContent" v-else-if="docEdit.docType === 2">
<!-- textarea在内容很多的时候>300KB会卡顿ace不会-->
<ace-editor v-model:value="docEdit.jsonContent" lang="json" theme="monokai" width="100%" height="100" :options="aceEditorConfig"></ace-editor>
<!-- <a-textarea placeholder="请输入JSON格式的Swagger文档内容" v-model:value="docEdit.jsonContent" :auto-size="{ minRows: 5, maxRows: 10 }"></a-textarea>-->
<template #extra>
查看文档内容
<a-popover title="文档内容说明">
<template #content>
<div>支持以下格式的Swagger文档内容输入其中 {"swagger": "2.0"} 为必要属性</div>
<div v-highlight>
<pre><code class="lang-json">{{swaggerDocDemo}}</code></pre>
</div>
</template>
<a>说明</a>
</a-popover>
</template>
</a-form-item>
<a-form-item label="文档地址" required name="docUrl" v-if="docEdit.docType === 3">
<a-input placeholder="请输入文档地址URL" v-model:value="docEdit.docUrl"></a-input>
<template #extra>
查看文档地址
<a-popover title="文档地址支持以下任一格式">
<template #content>
<p>格式一http://doc.zyplayer.com/v3/api-docs</p>
</template>
<a>示例</a>
</a-popover>
</template>
</a-form-item>
<a-form-item label="文档内容" required name="jsonContent" v-else-if="docEdit.docType === 4">
<ace-editor v-model:value="docEdit.jsonContent" lang="json" theme="monokai" width="100%" height="100" :options="aceEditorConfig"></ace-editor>
<!-- <a-textarea placeholder="请输入JSON格式的OpenApi文档内容" v-model:value="docEdit.jsonContent" :auto-size="{ minRows: 5, maxRows: 10 }"></a-textarea>-->
<template #extra>
查看文档内容
<a-popover title="文档内容说明">
<template #content>
<div>支持以下格式的OpenApi文档内容输入其中 {"openapi": "3.x.x"} 为必要属性</div>
<div v-highlight>
<pre><code class="lang-json">{{openApiDocDemo}}</code></pre>
</div>
</template>
<a>说明</a>
</a-popover>
</template>
</a-form-item>
<a-form-item label="目标域名" name="rewriteDomain">
<a-input placeholder="请输入目标域名" v-model:value="docEdit.rewriteDomain"></a-input>
<template #extra>
目标域名
<a-popover title="目标域名说明">
<template #content>
<p>在文档的在线调试界面访问的域名可以初始为此处录入的域名而非文档本身的域名地址</p>
<p>可便于不同环境间的接口测试http://doc.zyplayer.com</p>
</template>
<a>说明</a>
</a-popover>
</template>
</a-form-item>
<a-form-item label="开放访问" required name="openVisit">
<a-radio-group v-model:value="docEdit.openVisit">
<a-radio :value="0"></a-radio>
<a-radio :value="1">开放访问</a-radio>
</a-radio-group>
<template #extra>
开放访问后无需登录即可通过<a @click="openShareViewWindow(docEdit)">开放文档URL</a>访问该文档信息
</template>
</a-form-item>
<a-form-item label="状态" required name="docStatus">
<a-radio-group v-model:value="docEdit.docStatus">
<a-radio :value="1">启用</a-radio>
<a-radio :value="2">禁用</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
</a-modal>
<EditShareInstruction ref="instruction"></EditShareInstruction>
</template>
<script>
import { toRefs, ref, reactive, onMounted } from 'vue';
import {zyplayerApi} from '../../api';
import {useStore} from 'vuex';
import aceEditor from "../../assets/ace-editor";
import EditShareInstruction from "./components/EditShareInstruction.vue";
import {getZyplayerApiBaseUrl} from "../../api/request/utils";
import {DownOutlined, LinkOutlined, EditOutlined} from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
export default {
emits: ['showMembers'],
components: {aceEditor, EditShareInstruction, DownOutlined, LinkOutlined, EditOutlined},
setup(props, {emit}) {
const store = useStore();
let docList = ref([]);
let docListLoading = ref(false);
let searchParam = ref({docType: '', openVisit: '', docStatus: '', pageNum: 1, pageSize: 20});
let pagination = ref({
pageSize: 20,
pageNum: 1,
total: 0,
showSizeChanger: true,
pageSizeOptions: ['20', '50', '100'],
showTotal: total => `${total}`
});
const handleTableChange = (paginationNew, filters, sorter) => {
pagination.value.pageNum = paginationNew.current;
pagination.value.pageSize = paginationNew.pageSize;
searchParam.value.pageNum = paginationNew.current;
searchParam.value.pageSize = paginationNew.pageSize;
searchDocList();
};
const searchDocList = async () => {
docListLoading.value = true;
zyplayerApi.apiDocList(searchParam.value).then(res => {
setTimeout(() => docListLoading.value = false, 500);
docList.value = res.data || [];
pagination.value.total = res.total || 0;
});
};
let docEdit = ref({});
let newDocFormRef = ref();
let newDocVisible = ref(false);
const handleNewDocOk = async () => {
newDocFormRef.value.validate().then(() => {
zyplayerApi.apiDocAdd(docEdit.value).then(res => {
searchDocList();
newDocVisible.value = false;
store.commit('addDocChangedNum');
});
}).catch(error => {
console.log('error', error);
});
};
const openNewDoc = async () => {
newDocVisible.value = true;
docEdit.value = {
docType: 1, openVisit: 0, docStatus: 1, isNew: 1
};
};
const showMembers = (record) => {
emit('showMembers', record);
};
const editDoc = (record) => {
zyplayerApi.apiDocDetail({id: record.id}).then(res => {
docEdit.value = res.data;
newDocVisible.value = true;
});
};
const updateDoc = async (id, docStatus, yn) => {
zyplayerApi.apiDocUpdate({id, docStatus, yn}).then(res => {
searchDocList();
store.commit('addDocChangedNum');
});
};
const deleteDoc = async (row) => updateDoc(row.id, null, 0);
// 打开开放文档新窗口
const openShareViewWindow = record => {
if (!record.shareUuid) {
message.warning('请先保存文档后再试');
} else if (record.openVisit !== 1) {
message.warning('该文档尚未开启开放访问功能,请在编辑页选择开放后再试');
} else {
window.open(getZyplayerApiBaseUrl() + '/doc-api#/share/home?uuid=' + record.shareUuid);
}
};
const handleActionMenuClick = (item, record) => {
if (item.key === 'shareView') {
openShareViewWindow(record);
} else if (item.key === 'shareInstruction') {
instruction.value.editDoc(record.id);
}
}
let instruction = ref();
onMounted(() => {
searchDocList();
});
return {
searchParam,
docList,
docListLoading,
newDocVisible,
docEdit,
newDocFormRef,
searchDocList,
openNewDoc,
handleNewDocOk,
deleteDoc,
editDoc,
showMembers,
handleTableChange,
openShareViewWindow,
handleActionMenuClick,
pagination,
instruction,
newDocRules: {
name: [{required: true, message: '请输入文档名称', trigger: 'change'}],
docUrl: [{required: true, message: '请输入文档地址', trigger: 'change'}],
jsonContent: [{required: true, message: '请输入JSON格式的swagger文档内容', trigger: 'change'}],
docType: [{type: 'number', required: true, message: '请选择文档类型', trigger: 'change'}],
openVisit: [{type: 'number', required: true, message: '请选择是否开放访问', trigger: 'change'}],
docStatus: [{type: 'number', required: true, message: '请选择文档状态', trigger: 'change'}],
},
docListColumns: [
{title: 'ID', dataIndex: 'id', width: 70},
{title: '文档名称', dataIndex: 'name', width: 250},
{title: '文档类型', dataIndex: 'docType', width: 120},
{title: '开放访问', dataIndex: 'openVisit', width: 90},
{title: '状态', dataIndex: 'docStatus', width: 90},
{title: '文档地址', dataIndex: 'docUrl'},
{title: '目标域名', dataIndex: 'rewriteDomain', width: 250},
{title: '操作', dataIndex: 'operation', fixed: 'right', width: 280},
],
aceEditorConfig: {
wrap: true,
autoScrollEditorIntoView: true,
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
minLines: 10,
maxLines: 15,
},
swaggerDocDemo:
'{\n'
+ ' "swagger": "2.0",\n'
+ ' "info": {},\n'
+ ' "host": "doc.zyplayer.com",\n'
+ ' "basePath":"/",\n'
+ ' "tags": [],\n'
+ ' "paths": {},\n'
+ ' "definitions": {}\n'
+ '}',
openApiDocDemo:
'{\n'
+ ' "openapi": "3.0.3",\n'
+ ' "components": {}\n'
+ ' "servers": [],\n'
+ ' "paths": {},\n'
+ ' "info": {},\n'
+ '}',
};
},
};
</script>

View File

@@ -0,0 +1,200 @@
<template>
<a-page-header
title="成员管理"
:sub-title="doc.name||''"
@back="showDocList">
<template #extra>
<a-button @click="searchDocMemberList" type="primary">查询</a-button>
<a-button @click="openAddDocMember" :style="{ marginLeft: '8px' }">添加用户</a-button>
</template>
</a-page-header>
<a-table :dataSource="docMemberList" :columns="docListColumns" size="middle"
:loading="docMemberListLoading" :pagination="false"
@change="handleTableChange"
:scroll="{ x: 1400, y: 'calc(100vh - 300px)' }">
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'operation'">
<a-popconfirm title="确定要删除吗?" @confirm="deleteDocMember(record)">
<a-button size="small" type="link" danger>删除</a-button>
</a-popconfirm>
</template>
<template v-if="column.dataIndex === 'sex'">
<a-tag color="pink" v-if="record.sex === 1"></a-tag>
<a-tag color="red" v-else-if="record.sex === 0"></a-tag>
<a-tag color="orange" v-else>-</a-tag>
</template>
<template v-if="column.dataIndex === 'authType'">
<a-select placeholder="请选择角色" v-model:value="record.authType" @change="userAuthTypeChange(record)" style="width: 150px;">
<a-select-option :value="1">管理员</a-select-option>
<a-select-option :value="2">开发人员</a-select-option>
</a-select>
</template>
</template>
</a-table>
<a-modal v-model:visible="addUserVisible" title="添加用户" @ok="handleAddUserOk" :width="600">
<a-form layout="horizontal" ref="addUserFormRef" :model="userAdd" :rules="addUserRules" :label-col="{span: 4}" :wrapper-col="{span: 20}">
<a-form-item label="选择用户" required name="userId">
<a-select
v-model:value="userAdd.userId"
show-search
placeholder="输入用户名、邮箱、手机号搜索"
:default-active-first-option="false"
:show-arrow="true"
:filter-option="false"
:not-found-content="undefined"
:options="userSearchList"
@search="handleUserSearch"
>
<template v-if="userSearchState.fetching" #notFoundContent>
<a-spin size="small" />
</template>
</a-select>
</a-form-item>
<a-form-item label="用户角色" required name="authType">
<a-radio-group v-model:value="userAdd.authType">
<a-radio :value="1">管理员</a-radio>
<a-radio :value="2">开发人员</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
</a-modal>
</template>
<script>
import { toRefs, ref, reactive, onMounted } from 'vue';
import {zyplayerApi} from '../../api';
import {useStore} from 'vuex';
import {getZyplayerApiBaseUrl} from "../../api/request/utils";
import {DownOutlined, LinkOutlined, EditOutlined} from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
export default {
emits: ['showDocList'],
components: {DownOutlined, LinkOutlined, EditOutlined},
props: {
doc: {
type: Object,
required: true
},
},
setup(props, {emit}) {
const store = useStore();
let docMemberList = ref([]);
let docMemberListLoading = ref(false);
let searchParam = ref({docId: '', pageNum: 1, pageSize: 20});
// 项目应该加不了很多的人,暂不分页
let pagination = ref({
pageSize: 20,
pageNum: 1,
total: 0,
showSizeChanger: true,
pageSizeOptions: ['20', '50', '100'],
showTotal: total => `${total}`
});
const handleTableChange = (paginationNew, filters, sorter) => {
pagination.value.pageNum = paginationNew.current;
pagination.value.pageSize = paginationNew.pageSize;
searchParam.value.pageNum = paginationNew.current;
searchParam.value.pageSize = paginationNew.pageSize;
searchDocMemberList();
};
const searchDocMemberList = async () => {
docMemberListLoading.value = true;
searchParam.value.docId = props.doc.id;
zyplayerApi.docAuthList(searchParam.value).then(res => {
setTimeout(() => docMemberListLoading.value = false, 500);
docMemberList.value = res.data || [];
pagination.value.total = res.total || 0;
});
};
let userAdd = ref({});
let userSearchState = ref({
data: [],
search: '',
fetching: false,
});
let userSearchList = ref([]);
let addUserFormRef = ref();
let addUserVisible = ref(false);
const handleUserSearch = (search) => {
userSearchState.value.search = search;
if (userSearchState.value.fetching) {
return;
}
userSearchState.value.fetching = true;
userSearchList.value = [];
setTimeout(() => {
zyplayerApi.searchUserList({search: userSearchState.value.search}).then(res => {
let resArr = res.data || [];
resArr.forEach(item => userSearchList.value.push({label: item.userName, value: item.id}));
userSearchState.value.fetching = false;
});
}, 500);
};
const handleAddUserOk = async () => {
addUserFormRef.value.validate().then(() => {
zyplayerApi.docAuthAssign(userAdd.value).then(res => {
searchDocMemberList();
addUserVisible.value = false;
});
}).catch(error => {
console.log('error', error);
});
};
const userAuthTypeChange = async (record) => {
let param = {...record, docId: props.doc.id};
zyplayerApi.docAuthAssign(param).then(res => {
message.success('修改成功');
});
};
const openAddDocMember = async () => {
addUserVisible.value = true;
userAdd.value = {docId: props.doc.id, userId: undefined, authType: 1};
};
const deleteDocMember = async (row) => {
zyplayerApi.docAuthDelete({docId: props.doc.id, userId: row.userId}).then(res => {
searchDocMemberList();
});
};
const showDocList = () => {
emit('showDocList');
}
onMounted(() => {
searchDocMemberList();
});
return {
showDocList,
searchParam,
docMemberList,
docMemberListLoading,
addUserVisible,
userAdd,
userSearchList,
addUserFormRef,
userSearchState,
handleUserSearch,
searchDocMemberList,
openAddDocMember,
handleAddUserOk,
userAuthTypeChange,
deleteDocMember,
handleTableChange,
pagination,
docListColumns: [
{title: 'ID', dataIndex: 'userId', width: 70},
{title: '用户名', dataIndex: 'userName'},
{title: '帐号', dataIndex: 'userNo'},
{title: '邮箱', dataIndex: 'email'},
{title: '手机号', dataIndex: 'phone'},
{title: '性别', dataIndex: 'sex', width: 90},
{title: '角色', dataIndex: 'authType', width: 200},
{title: '操作', dataIndex: 'operation', fixed: 'right', width: 100},
],
addUserRules: {
userId: [{type: 'number', required: true, message: '请选择用户', trigger: 'change'}],
authType: [{type: 'number', required: true, message: '请选择用户角色', trigger: 'change'}],
},
};
},
};
</script>

View File

@@ -10,7 +10,6 @@ import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.config.security.UserAuthVo; import com.zyplayer.doc.data.config.security.UserAuthVo;
import com.zyplayer.doc.data.repository.manage.entity.*; import com.zyplayer.doc.data.repository.manage.entity.*;
import com.zyplayer.doc.data.repository.manage.mapper.UserGroupAuthMapper; import com.zyplayer.doc.data.repository.manage.mapper.UserGroupAuthMapper;
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.DocSysModuleType;
import com.zyplayer.doc.data.repository.support.consts.DocSysType; import com.zyplayer.doc.data.repository.support.consts.DocSysType;
import com.zyplayer.doc.data.repository.support.consts.UserMsgType; import com.zyplayer.doc.data.repository.support.consts.UserMsgType;
@@ -75,12 +74,8 @@ public class WikiPageAuthController {
queryWrapper.in("auth_name", authNameList); queryWrapper.in("auth_name", authNameList);
Collection<AuthInfo> authInfoList = authInfoService.list(queryWrapper); Collection<AuthInfo> authInfoList = authInfoService.list(queryWrapper);
Map<String, Long> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getAuthName, AuthInfo::getId)); Map<String, Long> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getAuthName, AuthInfo::getId));
// 先删除页面的所有用户的权限 // 先删除页面的所有用户的权限
QueryWrapper<UserAuth> updateWrapper = new QueryWrapper<>(); userAuthService.deleteModuleAuth(DocSysType.WIKI.getType(), DocSysModuleType.Wiki.PAGE.getType(), pageId);
updateWrapper.eq("auth_custom_suffix", DocAuthConst.WIKI + pageId);
updateWrapper.eq("del_flag", 0);
userAuthService.remove(updateWrapper);
List<UserPageAuthVo> authVoList = JSON.parseArray(authList, UserPageAuthVo.class); List<UserPageAuthVo> authVoList = JSON.parseArray(authList, UserPageAuthVo.class);
for (UserPageAuthVo authVo : authVoList) { for (UserPageAuthVo authVo : authVoList) {
@@ -137,15 +132,12 @@ public class WikiPageAuthController {
if (canConfigAuth != null) { if (canConfigAuth != null) {
return DocResponseJson.warn(canConfigAuth); return DocResponseJson.warn(canConfigAuth);
} }
QueryWrapper<UserAuth> queryWrapper = new QueryWrapper<>(); List<UserAuth> authList = userAuthService.getModuleAuthList(DocSysType.WIKI.getType(), DocSysModuleType.Wiki.PAGE.getType(), pageId);
queryWrapper.eq("auth_custom_suffix", DocAuthConst.WIKI + pageId);
queryWrapper.eq("del_flag", 0);
List<UserAuth> authList = userAuthService.list(queryWrapper);
if (CollectionUtils.isEmpty(authList)) { if (CollectionUtils.isEmpty(authList)) {
return DocResponseJson.ok(); return DocResponseJson.ok();
} }
// 权限ID对应的权限名 // 权限ID对应的权限名
Collection<AuthInfo> authInfoList = authInfoService.listByIds(authList.stream().map(UserAuth::getAuthId).collect(Collectors.toList())); Collection<AuthInfo> authInfoList = authInfoService.listByIds(authList.stream().map(UserAuth::getAuthId).collect(Collectors.toSet()));
Map<Long, String> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getId, AuthInfo::getAuthName)); Map<Long, String> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getId, AuthInfo::getAuthName));
// 查询用户信息 // 查询用户信息
Map<Long, List<UserAuth>> userAuthGroup = authList.stream().collect(Collectors.groupingBy(UserAuth::getUserId)); Map<Long, List<UserAuth>> userAuthGroup = authList.stream().collect(Collectors.groupingBy(UserAuth::getUserId));