This commit is contained in:
六如
2024-11-27 10:08:24 +08:00
parent 5e2c3fab46
commit 85b33e7c3d
36 changed files with 837 additions and 419 deletions

View File

@@ -24,7 +24,16 @@ public enum YesOrNoEnum implements IntEnum {
return Objects.equals(value.intValue(), YES.value) ? YES : NO; return Objects.equals(value.intValue(), YES.value) ? YES : NO;
} }
public static boolean yes(Number value) {
return of(value) == YES;
}
public static YesOrNoEnum of(Boolean value) { public static YesOrNoEnum of(Boolean value) {
return Objects.equals(value, true) ? YES : NO; return Objects.equals(value, true) ? YES : NO;
} }
@Override
public String toString() {
return value.toString();
}
} }

View File

@@ -1,15 +1,17 @@
package com.gitee.sop.adminbackend.controller.doc; package com.gitee.sop.adminbackend.controller.doc;
import com.gitee.sop.adminbackend.common.req.IdParam;
import com.gitee.sop.adminbackend.common.resp.Result; import com.gitee.sop.adminbackend.common.resp.Result;
import com.gitee.sop.adminbackend.common.util.CopyUtil; import com.gitee.sop.adminbackend.common.util.CopyUtil;
import com.gitee.sop.adminbackend.controller.doc.param.DocAppAddParam; import com.gitee.sop.adminbackend.controller.doc.param.DocAppAddParam;
import com.gitee.sop.adminbackend.controller.doc.param.DocInfoUpdateParam; import com.gitee.sop.adminbackend.controller.doc.param.DocInfoUpdateParam;
import com.gitee.sop.adminbackend.controller.doc.vo.DocAppVO; import com.gitee.sop.adminbackend.controller.doc.vo.DocAppVO;
import com.gitee.sop.adminbackend.controller.doc.vo.DocInfoTreeVO; import com.gitee.sop.adminbackend.controller.doc.vo.DocInfoTreeVO;
import com.gitee.sop.adminbackend.service.doc.DocService; import com.gitee.sop.adminbackend.service.doc.DocAppService;
import com.gitee.sop.adminbackend.service.doc.DocInfoService;
import com.gitee.sop.adminbackend.service.doc.dto.DocAppDTO; import com.gitee.sop.adminbackend.service.doc.dto.DocAppDTO;
import com.gitee.sop.adminbackend.service.doc.dto.DocInfoTreeDTO;
import com.gitee.sop.adminbackend.service.doc.dto.DocInfoPublishUpdateDTO; import com.gitee.sop.adminbackend.service.doc.dto.DocInfoPublishUpdateDTO;
import com.gitee.sop.adminbackend.service.doc.dto.DocInfoTreeDTO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -29,31 +31,39 @@ import java.util.List;
public class DocController { public class DocController {
@Autowired @Autowired
private DocService docService; private DocInfoService docInfoService;
@Autowired
private DocAppService docAppService;
@GetMapping("app/list") @GetMapping("app/list")
public Result<List<DocAppVO>> listApp() { public Result<List<DocAppVO>> listApp() {
List<DocAppDTO> docAppDTOS = docService.listDocApp(); List<DocAppDTO> docAppDTOS = docAppService.listDocApp();
List<DocAppVO> docAppVOS = CopyUtil.copyList(docAppDTOS, DocAppVO::new); List<DocAppVO> docAppVOS = CopyUtil.copyList(docAppDTOS, DocAppVO::new);
return Result.ok(docAppVOS); return Result.ok(docAppVOS);
} }
@PostMapping("app/add") @PostMapping("app/add")
public Result<Long> addApp(@Validated @RequestBody DocAppAddParam param) { public Result<Long> addApp(@Validated @RequestBody DocAppAddParam param) {
Long docAppId = docService.addDocApp(param.getTornaToken()); Long docAppId = docAppService.addDocApp(param.getTornaToken());
return Result.ok(docAppId); return Result.ok(docAppId);
} }
@PostMapping("app/syncDoc")
public Result<Integer> syncDocInfo(@Validated @RequestBody IdParam param) {
docInfoService.syncDocInfo(param.getId());
return Result.ok(1);
}
@GetMapping("info/tree") @GetMapping("info/tree")
public Result<List<DocInfoTreeVO>> docTree(@RequestParam Long docAppId) { public Result<List<DocInfoTreeVO>> docTree(@RequestParam Long docAppId) {
List<DocInfoTreeDTO> docInfoTreeDTOS = docService.listDocTree(docAppId); List<DocInfoTreeDTO> docInfoTreeDTOS = docInfoService.listDocTree(docAppId);
List<DocInfoTreeVO> docInfoTreeVOS = CopyUtil.deepCopyList(docInfoTreeDTOS, DocInfoTreeVO.class); List<DocInfoTreeVO> docInfoTreeVOS = CopyUtil.deepCopyList(docInfoTreeDTOS, DocInfoTreeVO.class);
return Result.ok(docInfoTreeVOS); return Result.ok(docInfoTreeVOS);
} }
@PostMapping("info/publish") @PostMapping("info/publish")
public Result<Integer> publish(@Validated @RequestBody DocInfoUpdateParam param) { public Result<Integer> publish(@Validated @RequestBody DocInfoUpdateParam param) {
int cnt = docService.publish(CopyUtil.copyBean(param, DocInfoPublishUpdateDTO::new)); int cnt = docInfoService.publish(CopyUtil.copyBean(param, DocInfoPublishUpdateDTO::new));
return Result.ok(cnt); return Result.ok(cnt);
} }

View File

@@ -3,7 +3,7 @@ package com.gitee.sop.adminbackend.controller.doc;
import com.gitee.sop.adminbackend.common.resp.Result; import com.gitee.sop.adminbackend.common.resp.Result;
import com.gitee.sop.adminbackend.common.util.CopyUtil; import com.gitee.sop.adminbackend.common.util.CopyUtil;
import com.gitee.sop.adminbackend.controller.doc.vo.DocSettingVO; import com.gitee.sop.adminbackend.controller.doc.vo.DocSettingVO;
import com.gitee.sop.adminbackend.service.doc.DocService; import com.gitee.sop.adminbackend.service.doc.DocSettingService;
import com.gitee.sop.adminbackend.service.doc.dto.DocSettingDTO; import com.gitee.sop.adminbackend.service.doc.dto.DocSettingDTO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -23,18 +23,18 @@ import org.springframework.web.bind.annotation.RestController;
public class DocSettingController { public class DocSettingController {
@Autowired @Autowired
private DocService docService; private DocSettingService docSettingService;
@GetMapping("get") @GetMapping("get")
public Result<DocSettingVO> get() { public Result<DocSettingVO> get() {
DocSettingDTO docSetting = docService.getDocSetting(); DocSettingDTO docSetting = docSettingService.getDocSetting();
DocSettingVO docSettingVO = CopyUtil.copyBean(docSetting, DocSettingVO::new); DocSettingVO docSettingVO = CopyUtil.copyBean(docSetting, DocSettingVO::new);
return Result.ok(docSettingVO); return Result.ok(docSettingVO);
} }
@PostMapping("save") @PostMapping("save")
public Result<Integer> save(@Validated @RequestBody DocSettingDTO docSettingVO) { public Result<Integer> save(@Validated @RequestBody DocSettingDTO docSettingVO) {
docService.save(docSettingVO); docSettingService.save(docSettingVO);
return Result.ok(1); return Result.ok(1);
} }

View File

@@ -57,6 +57,11 @@ public class DocInfoTreeVO implements TreeNode<DocInfoTreeVO, Long> {
*/ */
private String docName; private String docName;
/**
* 版本号
*/
private String docVersion;
/** /**
* 描述 * 描述
*/ */
@@ -67,35 +72,11 @@ public class DocInfoTreeVO implements TreeNode<DocInfoTreeVO, Long> {
*/ */
private Integer isFolder; private Integer isFolder;
/**
* 状态, 0-未发布,1-已发布
*/
private Integer isPublish;
/** /**
* 父节点id * 父节点id
*/ */
private Long parentId; private Long parentId;
/**
* 添加时间
*/
private LocalDateTime addTime;
/**
* 修改时间
*/
private LocalDateTime updateTime;
/**
* 创建人id
*/
private Long addBy;
/**
* 修改人id
*/
private Long updateBy;
private List<DocInfoTreeVO> children; private List<DocInfoTreeVO> children;

View File

@@ -5,9 +5,10 @@ import com.gitee.sop.adminbackend.common.resp.Result;
import com.gitee.sop.adminbackend.common.util.CopyUtil; import com.gitee.sop.adminbackend.common.util.CopyUtil;
import com.gitee.sop.adminbackend.controller.doc.vo.DocAppVO; import com.gitee.sop.adminbackend.controller.doc.vo.DocAppVO;
import com.gitee.sop.adminbackend.controller.doc.vo.DocInfoTreeVO; import com.gitee.sop.adminbackend.controller.doc.vo.DocInfoTreeVO;
import com.gitee.sop.adminbackend.service.website.WebsiteService;
import com.gitee.sop.adminbackend.service.doc.dto.DocAppDTO; import com.gitee.sop.adminbackend.service.doc.dto.DocAppDTO;
import com.gitee.sop.adminbackend.service.doc.dto.DocInfoTreeDTO; import com.gitee.sop.adminbackend.service.doc.dto.DocInfoTreeDTO;
import com.gitee.sop.adminbackend.service.doc.dto.DocInfoViewDTO;
import com.gitee.sop.adminbackend.service.website.WebsiteService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@@ -28,11 +29,10 @@ public class WebsiteController {
@Autowired @Autowired
private WebsiteService websiteService; private WebsiteService websiteService;
/** /**
* 获取文档应用列表 * 获取文档应用列表
*/ */
@GetMapping("listDocApp") @GetMapping("docapp/list")
public Result<List<DocAppVO>> listDocApp() { public Result<List<DocAppVO>> listDocApp() {
List<DocAppDTO> docAppDTOS = websiteService.listDocApp(); List<DocAppDTO> docAppDTOS = websiteService.listDocApp();
List<DocAppVO> docAppVOS = CopyUtil.deepCopyList(docAppDTOS, DocAppVO.class); List<DocAppVO> docAppVOS = CopyUtil.deepCopyList(docAppDTOS, DocAppVO.class);
@@ -44,11 +44,22 @@ public class WebsiteController {
* *
* @param docAppId 应用id * @param docAppId 应用id
*/ */
@GetMapping("listDocMenuTree") @GetMapping("docinfo/tree")
public Result<List<DocInfoTreeVO>> listDocMenuTree(Long docAppId) { public Result<List<DocInfoTreeVO>> listDocMenuTree(Long docAppId) {
List<DocInfoTreeDTO> docInfoTreeDTOS = websiteService.listDocMenuTree(docAppId); List<DocInfoTreeDTO> docInfoTreeDTOS = websiteService.listDocMenuTree(docAppId);
List<DocInfoTreeVO> docAppVOS = CopyUtil.deepCopyList(docInfoTreeDTOS, DocInfoTreeVO.class); List<DocInfoTreeVO> docAppVOS = CopyUtil.deepCopyList(docInfoTreeDTOS, DocInfoTreeVO.class);
return Result.ok(docAppVOS); return Result.ok(docAppVOS);
} }
/**
* 获取文档详情
*
* @param id id
*/
@GetMapping("docinfo/detail")
public Result<DocInfoViewDTO> getDocDetail(Long id) {
DocInfoViewDTO docDetail = websiteService.getDocDetail(id);
return Result.ok(docDetail);
}
} }

View File

@@ -34,6 +34,11 @@ public class DocApp {
*/ */
private String token; private String token;
/**
* 状态, 0-未发布,1-已发布
*/
private Integer isPublish;
/** /**
* 添加时间 * 添加时间
*/ */

View File

@@ -9,5 +9,9 @@ import org.apache.ibatis.annotations.Mapper;
*/ */
@Mapper @Mapper
public interface DocAppMapper extends BaseMapper<DocApp> { public interface DocAppMapper extends BaseMapper<DocApp> {
default String getToken(Long id) {
return this.query()
.eq(DocApp::getId, id)
.getValue(DocApp::getToken);
}
} }

View File

@@ -1,10 +1,16 @@
package com.gitee.sop.adminbackend.service.doc; package com.gitee.sop.adminbackend.service.doc;
import com.gitee.fastmybatis.core.support.LambdaService; import com.gitee.fastmybatis.core.support.LambdaService;
import com.gitee.sop.adminbackend.common.util.CopyUtil;
import com.gitee.sop.adminbackend.dao.entity.DocApp; import com.gitee.sop.adminbackend.dao.entity.DocApp;
import com.gitee.sop.adminbackend.dao.mapper.DocAppMapper; import com.gitee.sop.adminbackend.dao.mapper.DocAppMapper;
import com.gitee.sop.adminbackend.service.doc.dto.DocAppDTO;
import com.gitee.sop.adminbackend.service.doc.dto.torna.TornaModuleDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
/** /**
* @author 六如 * @author 六如
@@ -12,5 +18,32 @@ import org.springframework.stereotype.Service;
@Service @Service
public class DocAppService implements LambdaService<DocApp, DocAppMapper> { public class DocAppService implements LambdaService<DocApp, DocAppMapper> {
@Autowired
private TornaClient tornaClient;
@Autowired
private DocInfoService docInfoService;
public Long addDocApp(String token) {
TornaModuleDTO tornaModuleDTO = tornaClient.execute("module.get", null, token, TornaModuleDTO.class);
DocApp docApp = this.get(DocApp::getToken, token);
if (docApp == null) {
docApp = new DocApp();
docApp.setAppName(tornaModuleDTO.getName());
docApp.setToken(token);
this.save(docApp);
} else {
docApp.setAppName(tornaModuleDTO.getName());
this.update(docApp);
}
// 同步文档
docInfoService.syncDocInfo(docApp);
return docApp.getId();
}
public List<DocAppDTO> listDocApp() {
List<DocApp> docApps = this.listAll();
return CopyUtil.copyList(docApps, DocAppDTO::new);
}
} }

View File

@@ -1,14 +1,22 @@
package com.gitee.sop.adminbackend.service.doc; package com.gitee.sop.adminbackend.service.doc;
import com.gitee.fastmybatis.core.support.LambdaService; import com.gitee.fastmybatis.core.support.LambdaService;
import com.gitee.fastmybatis.core.util.TreeUtil;
import com.gitee.sop.adminbackend.common.enums.DocSourceTypeEnum; import com.gitee.sop.adminbackend.common.enums.DocSourceTypeEnum;
import com.gitee.sop.adminbackend.common.enums.YesOrNoEnum; import com.gitee.sop.adminbackend.common.enums.YesOrNoEnum;
import com.gitee.sop.adminbackend.common.exception.BizException;
import com.gitee.sop.adminbackend.common.util.CopyUtil;
import com.gitee.sop.adminbackend.dao.entity.DocApp; import com.gitee.sop.adminbackend.dao.entity.DocApp;
import com.gitee.sop.adminbackend.dao.entity.DocInfo; import com.gitee.sop.adminbackend.dao.entity.DocInfo;
import com.gitee.sop.adminbackend.dao.mapper.DocAppMapper; import com.gitee.sop.adminbackend.dao.mapper.DocAppMapper;
import com.gitee.sop.adminbackend.dao.mapper.DocInfoMapper; import com.gitee.sop.adminbackend.dao.mapper.DocInfoMapper;
import com.gitee.sop.adminbackend.service.doc.dto.TornaDocDTO; import com.gitee.sop.adminbackend.service.doc.dto.DocInfoPublishUpdateDTO;
import com.gitee.sop.adminbackend.service.doc.dto.TornaDocInfoDTO; import com.gitee.sop.adminbackend.service.doc.dto.DocInfoTreeDTO;
import com.gitee.sop.adminbackend.service.doc.dto.torna.DocIdParam;
import com.gitee.sop.adminbackend.service.doc.dto.torna.TornaDocDTO;
import com.gitee.sop.adminbackend.service.doc.dto.torna.TornaDocInfoDTO;
import com.gitee.sop.adminbackend.service.doc.dto.torna.TornaDocInfoViewDTO;
import com.gitee.sop.adminbackend.service.doc.dto.torna.TornaDocParamDTO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@@ -16,6 +24,7 @@ import org.springframework.util.CollectionUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -37,11 +46,16 @@ public class DocInfoService implements LambdaService<DocInfo, DocInfoMapper> {
} }
public void syncDocInfo(Long docAppId) { public void syncDocInfo(Long docAppId) {
Map<Object, DocInfo> nameVersionMap = this.list(DocInfo::getDocAppId, docAppId) DocApp docApp = docAppMapper.getById(docAppId);
this.syncDocInfo(docApp);
}
public void syncDocInfo(DocApp docApp) {
Long docAppId = docApp.getId();
Map<String, DocInfo> nameVersionMap = this.list(DocInfo::getDocAppId, docAppId)
.stream() .stream()
.collect(Collectors.toMap(docInfo -> docInfo.getDocName() + ":" + docInfo.getDocVersion(), Function.identity(), (v1, v2) -> v2)); .collect(Collectors.toMap(docInfo -> docInfo.getDocName() + ":" + docInfo.getDocVersion(), Function.identity(), (v1, v2) -> v2));
DocApp docApp = docAppMapper.getById(docAppId);
String token = docApp.getToken(); String token = docApp.getToken();
// add doc // add doc
TornaDocDTO tornaDocDTO = tornaClient.execute("doc.list", null, token, TornaDocDTO.class); TornaDocDTO tornaDocDTO = tornaClient.execute("doc.list", null, token, TornaDocDTO.class);
@@ -50,7 +64,7 @@ public class DocInfoService implements LambdaService<DocInfo, DocInfoMapper> {
if (!CollectionUtils.isEmpty(docList)) { if (!CollectionUtils.isEmpty(docList)) {
List<DocInfo> updateList = new ArrayList<>(); List<DocInfo> updateList = new ArrayList<>();
for (TornaDocInfoDTO tornaDocInfoDTO : docList) { for (TornaDocInfoDTO tornaDocInfoDTO : docList) {
String key = tornaDocInfoDTO.getUrl() + ":" + tornaDocInfoDTO.getVersion(); String key = buildKey(tornaDocInfoDTO);
DocInfo docInfo = nameVersionMap.get(key); DocInfo docInfo = nameVersionMap.get(key);
// 需要修改的文档 // 需要修改的文档
if (docInfo != null) { if (docInfo != null) {
@@ -75,7 +89,7 @@ public class DocInfoService implements LambdaService<DocInfo, DocInfoMapper> {
// 新增的文档 // 新增的文档
List<DocInfo> saveList = docList.stream() List<DocInfo> saveList = docList.stream()
.filter(tornaDocInfoDTO -> { .filter(tornaDocInfoDTO -> {
String key = tornaDocInfoDTO.getUrl() + ":" + tornaDocInfoDTO.getVersion(); String key = buildKey(tornaDocInfoDTO);
return !nameVersionMap.containsKey(key); return !nameVersionMap.containsKey(key);
}) })
.map(tornaDocInfoDTO -> { .map(tornaDocInfoDTO -> {
@@ -87,14 +101,15 @@ public class DocInfoService implements LambdaService<DocInfo, DocInfoMapper> {
docInfo.setDocType(tornaDocInfoDTO.getType().intValue()); docInfo.setDocType(tornaDocInfoDTO.getType().intValue());
docInfo.setSourceType(DocSourceTypeEnum.TORNA.getValue()); docInfo.setSourceType(DocSourceTypeEnum.TORNA.getValue());
if (YesOrNoEnum.of(tornaDocInfoDTO.getIsFolder()) == YesOrNoEnum.YES) { if (YesOrNoEnum.of(tornaDocInfoDTO.getIsFolder()) == YesOrNoEnum.YES) {
docInfo.setIsPublish(YesOrNoEnum.YES.getValue());
docInfo.setDocName(tornaDocInfoDTO.getName()); docInfo.setDocName(tornaDocInfoDTO.getName());
} else { } else {
docInfo.setIsPublish(YesOrNoEnum.NO.getValue());
docInfo.setDocName(tornaDocInfoDTO.getUrl()); docInfo.setDocName(tornaDocInfoDTO.getUrl());
} }
docInfo.setDocVersion(tornaDocInfoDTO.getVersion()); docInfo.setDocVersion(tornaDocInfoDTO.getVersion());
docInfo.setDescription(tornaDocInfoDTO.getDescription()); docInfo.setDescription(tornaDocInfoDTO.getDescription());
docInfo.setIsFolder(tornaDocInfoDTO.getIsFolder().intValue()); docInfo.setIsFolder(tornaDocInfoDTO.getIsFolder().intValue());
docInfo.setIsPublish(YesOrNoEnum.NO.getValue());
docInfo.setParentId(tornaDocInfoDTO.getParentId()); docInfo.setParentId(tornaDocInfoDTO.getParentId());
return docInfo; return docInfo;
}) })
@@ -103,5 +118,66 @@ public class DocInfoService implements LambdaService<DocInfo, DocInfoMapper> {
} }
} }
private String buildKey(TornaDocInfoDTO tornaDocInfoDTO) {
return YesOrNoEnum.yes(tornaDocInfoDTO.getIsFolder()) ?
tornaDocInfoDTO.getName() + ":" + tornaDocInfoDTO.getVersion()
: tornaDocInfoDTO.getUrl() + ":" + tornaDocInfoDTO.getVersion();
}
public List<DocInfoTreeDTO> listDocTree(Long docAppId) {
List<DocInfo> list = this.list(DocInfo::getDocAppId, docAppId);
if (CollectionUtils.isEmpty(list)) {
return new ArrayList<>(0);
}
List<DocInfoTreeDTO> docInfoTreeDTOS = CopyUtil.copyList(list, DocInfoTreeDTO::new);
return TreeUtil.convertTree(docInfoTreeDTOS, 0L);
}
public int publish(DocInfoPublishUpdateDTO docInfoUpdateDTO) {
DocInfo docInfo = this.getById(docInfoUpdateDTO.getId());
// 如果是文件夹,发布下面所有的文档
if (YesOrNoEnum.of(docInfo.getIsFolder()) == YesOrNoEnum.YES) {
List<DocInfo> children = this.listChildDoc(docInfo.getDocId());
Set<Long> ids = children.stream().map(DocInfo::getId).collect(Collectors.toSet());
return this.query()
.in(DocInfo::getId, ids)
.set(DocInfo::getIsPublish, docInfoUpdateDTO.getIsPublish())
.update();
} else {
// 发布单个文档
return this.query()
.eq(DocInfo::getId, docInfoUpdateDTO.getId())
.set(DocInfo::getIsPublish, docInfoUpdateDTO.getIsPublish())
.update();
}
}
public TornaDocInfoViewDTO getDocDetail(Long id) {
DocInfo docInfo = this.getById(id);
if (docInfo == null) {
throw new BizException("文档不存在");
}
// 获取torna文档信息
String token = docAppMapper.getToken(docInfo.getDocAppId());
TornaDocInfoViewDTO tornaDocInfoViewDTO = tornaClient.execute(
"doc.detail",
new DocIdParam(docInfo.getDocId()),
token,
TornaDocInfoViewDTO.class
);
convertTree(tornaDocInfoViewDTO);
return tornaDocInfoViewDTO;
}
private void convertTree(TornaDocInfoViewDTO tornaDocInfoViewDTO) {
List<TornaDocParamDTO> requestParams = tornaDocInfoViewDTO.getRequestParams();
List<TornaDocParamDTO> responseParams = tornaDocInfoViewDTO.getResponseParams();
List<TornaDocParamDTO> requestTree = TreeUtil.convertTree(requestParams, 0L);
List<TornaDocParamDTO> responseTree = TreeUtil.convertTree(responseParams, 0L);
tornaDocInfoViewDTO.setRequestParams(requestTree);
tornaDocInfoViewDTO.setResponseParams(responseTree);
}
} }

View File

@@ -1,111 +0,0 @@
package com.gitee.sop.adminbackend.service.doc;
import com.gitee.fastmybatis.core.util.TreeUtil;
import com.gitee.sop.adminbackend.common.enums.ConfigKeyEnum;
import com.gitee.sop.adminbackend.common.enums.YesOrNoEnum;
import com.gitee.sop.adminbackend.common.util.CopyUtil;
import com.gitee.sop.adminbackend.dao.entity.DocApp;
import com.gitee.sop.adminbackend.dao.entity.DocInfo;
import com.gitee.sop.adminbackend.service.doc.dto.DocAppDTO;
import com.gitee.sop.adminbackend.service.doc.dto.DocInfoPublishUpdateDTO;
import com.gitee.sop.adminbackend.service.doc.dto.DocInfoTreeDTO;
import com.gitee.sop.adminbackend.service.doc.dto.DocSettingDTO;
import com.gitee.sop.adminbackend.service.doc.dto.TornaModuleDTO;
import com.gitee.sop.adminbackend.service.sys.SysConfigService;
import com.gitee.sop.adminbackend.service.sys.dto.SystemConfigDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author 六如
*/
@Service
public class DocService {
@Autowired
private SysConfigService sysConfigService;
@Autowired
private DocAppService docAppService;
@Autowired
private TornaClient tornaClient;
@Autowired
private DocInfoService docInfoService;
public DocSettingDTO getDocSetting() {
DocSettingDTO docSettingDTO = new DocSettingDTO();
docSettingDTO.setTornaServerAddr(ConfigKeyEnum.TORNA_SERVER_ADDR.getValue());
docSettingDTO.setOpenProdUrl(ConfigKeyEnum.OPEN_PROD_URL.getValue());
docSettingDTO.setOpenSandboxUrl(ConfigKeyEnum.OPEN_SANDBOX_URL.getValue());
return docSettingDTO;
}
public void save(DocSettingDTO docSettingDTO) {
Collection<SystemConfigDTO> systemConfigDTOS = new ArrayList<>();
systemConfigDTOS.add(new SystemConfigDTO(ConfigKeyEnum.TORNA_SERVER_ADDR.getKey(), docSettingDTO.getTornaServerAddr(), "Torna服务器地址"));
systemConfigDTOS.add(new SystemConfigDTO(ConfigKeyEnum.OPEN_PROD_URL.getKey(), docSettingDTO.getOpenProdUrl(), "开放平台线上地址"));
systemConfigDTOS.add(new SystemConfigDTO(ConfigKeyEnum.OPEN_SANDBOX_URL.getKey(), docSettingDTO.getOpenSandboxUrl(), "开放平台沙箱地址"));
sysConfigService.save(systemConfigDTOS);
}
public Long addDocApp(String token) {
TornaModuleDTO tornaModuleDTO = tornaClient.execute("module.get", null, token, TornaModuleDTO.class);
DocApp docApp = docAppService.get(DocApp::getToken, token);
if (docApp == null) {
docApp = new DocApp();
docApp.setAppName(tornaModuleDTO.getName());
docApp.setToken(token);
docAppService.save(docApp);
} else {
docApp.setAppName(tornaModuleDTO.getName());
docAppService.update(docApp);
}
// 同步文档
docInfoService.syncDocInfo(docApp.getId());
return docApp.getId();
}
public List<DocAppDTO> listDocApp() {
List<DocApp> docApps = docAppService.listAll();
return CopyUtil.copyList(docApps, DocAppDTO::new);
}
public List<DocInfoTreeDTO> listDocTree(Long docAppId) {
List<DocInfo> list = docInfoService.list(DocInfo::getDocAppId, docAppId);
if (CollectionUtils.isEmpty(list)) {
return new ArrayList<>(0);
}
List<DocInfoTreeDTO> docInfoTreeDTOS = CopyUtil.copyList(list, DocInfoTreeDTO::new);
return TreeUtil.convertTree(docInfoTreeDTOS, 0L);
}
public int publish(DocInfoPublishUpdateDTO docInfoUpdateDTO) {
DocInfo docInfo = docInfoService.getById(docInfoUpdateDTO.getId());
// 如果是文件夹,发布下面所有的文档
if (YesOrNoEnum.of(docInfo.getIsFolder()) == YesOrNoEnum.YES) {
List<DocInfo> children = this.docInfoService.listChildDoc(docInfo.getDocId());
Set<Long> ids = children.stream().map(DocInfo::getId).collect(Collectors.toSet());
return docInfoService.query()
.in(DocInfo::getId, ids)
.set(DocInfo::getIsPublish, docInfoUpdateDTO.getIsPublish())
.update();
} else {
// 发布单个文档
return docInfoService.query()
.eq(DocInfo::getId, docInfoUpdateDTO.getId())
.set(DocInfo::getIsPublish, docInfoUpdateDTO.getIsPublish())
.update();
}
}
}

View File

@@ -0,0 +1,40 @@
package com.gitee.sop.adminbackend.service.doc;
import com.gitee.sop.adminbackend.common.enums.ConfigKeyEnum;
import com.gitee.sop.adminbackend.service.doc.dto.DocSettingDTO;
import com.gitee.sop.adminbackend.service.sys.SysConfigService;
import com.gitee.sop.adminbackend.service.sys.dto.SystemConfigDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collection;
/**
* @author 六如
*/
@Service
public class DocSettingService {
@Autowired
private SysConfigService sysConfigService;
public DocSettingDTO getDocSetting() {
DocSettingDTO docSettingDTO = new DocSettingDTO();
docSettingDTO.setTornaServerAddr(ConfigKeyEnum.TORNA_SERVER_ADDR.getValue());
docSettingDTO.setOpenProdUrl(ConfigKeyEnum.OPEN_PROD_URL.getValue());
docSettingDTO.setOpenSandboxUrl(ConfigKeyEnum.OPEN_SANDBOX_URL.getValue());
return docSettingDTO;
}
public void save(DocSettingDTO docSettingDTO) {
Collection<SystemConfigDTO> systemConfigDTOS = new ArrayList<>();
systemConfigDTOS.add(new SystemConfigDTO(ConfigKeyEnum.TORNA_SERVER_ADDR.getKey(), docSettingDTO.getTornaServerAddr(), "Torna服务器地址"));
systemConfigDTOS.add(new SystemConfigDTO(ConfigKeyEnum.OPEN_PROD_URL.getKey(), docSettingDTO.getOpenProdUrl(), "开放平台线上地址"));
systemConfigDTOS.add(new SystemConfigDTO(ConfigKeyEnum.OPEN_SANDBOX_URL.getKey(), docSettingDTO.getOpenSandboxUrl(), "开放平台沙箱地址"));
sysConfigService.save(systemConfigDTOS);
}
}

View File

@@ -0,0 +1,14 @@
package com.gitee.sop.adminbackend.service.doc.dto;
import lombok.Data;
/**
* @author 六如
*/
@Data
public class DocInfoConfigDTO {
private String openProdUrl;
private String openSandboxUrl;
}

View File

@@ -0,0 +1,16 @@
package com.gitee.sop.adminbackend.service.doc.dto;
import com.gitee.sop.adminbackend.service.doc.dto.torna.TornaDocInfoViewDTO;
import lombok.Data;
/**
* @author 六如
*/
@Data
public class DocInfoViewDTO {
private TornaDocInfoViewDTO docInfoView;
private DocInfoConfigDTO docInfoConfig;
}

View File

@@ -0,0 +1,13 @@
package com.gitee.sop.adminbackend.service.doc.dto.torna;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DocIdParam {
private Long docId;
}

View File

@@ -1,4 +1,4 @@
package com.gitee.sop.adminbackend.service.doc.dto; package com.gitee.sop.adminbackend.service.doc.dto.torna;
import lombok.Data; import lombok.Data;

View File

@@ -1,4 +1,4 @@
package com.gitee.sop.adminbackend.service.doc.dto; package com.gitee.sop.adminbackend.service.doc.dto.torna;
import lombok.Data; import lombok.Data;

View File

@@ -0,0 +1,178 @@
package com.gitee.sop.adminbackend.service.doc.dto.torna;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
/**
* @author tanghc
*/
@Data
public class TornaDocInfoViewDTO {
private Long id;
/**
* 文档名称
*/
private String name;
/**
* 文档概述
*/
private String description;
/**
* 0:http,1:dubbo
*/
private Byte type;
/**
* 访问URL
*/
private String url;
/**
* 版本号
*/
private String version = "";
private String docKey;
/**
* http方法
*/
private String httpMethod;
/**
* contentType
*/
private String contentType;
/**
* 是否是分类0不是1
*/
private Byte isFolder;
/**
* 父节点
*/
private Long parentId;
/**
* 模块idmodule.id
*/
private Long moduleId;
/**
* 项目id
*/
private Long projectId;
/**
* 是否使用全局请求参数
*/
private Byte isUseGlobalHeaders;
/**
* 是否使用全局请求参数
*/
private Byte isUseGlobalParams;
/**
* 是否使用全局返回参数
*/
private Byte isUseGlobalReturns;
/**
* 是否请求数组
*/
private Byte isRequestArray;
/**
* 是否返回数组
*/
private Byte isResponseArray;
/**
* 请求数组时元素类型
*/
private String requestArrayType;
/**
* 返回数组时元素类型
*/
private String responseArrayType;
/**
* 文档状态
*/
private Byte status;
private String remark;
private Integer orderIndex;
/**
* 数据库字段gmt_create
*/
private LocalDateTime gmtCreate;
/**
* 数据库字段gmt_modified
*/
private LocalDateTime gmtModified;
private List<TornaDocParamDTO> pathParams = Collections.emptyList();
private List<TornaDocParamDTO> headerParams = Collections.emptyList();
private List<TornaDocParamDTO> headerParamsRaw = Collections.emptyList();
private List<TornaDocParamDTO> queryParams = Collections.emptyList();
private List<TornaDocParamDTO> requestParams = Collections.emptyList();
private List<TornaDocParamDTO> responseParams = Collections.emptyList();
private List<TornaDocParamDTO> errorCodeParams = Collections.emptyList();
private List<TornaDocParamDTO> globalHeaders = Collections.emptyList();
private List<TornaDocParamDTO> globalParams = Collections.emptyList();
private List<TornaDocParamDTO> globalReturns = Collections.emptyList();
private String errorCodeInfo;
private List<TornaDocInfoViewDTO> children = Collections.emptyList();
public String getDocName() {
return name;
}
public String getDocTitle() {
return name;
}
}

View File

@@ -0,0 +1,128 @@
package com.gitee.sop.adminbackend.service.doc.dto.torna;
import com.gitee.fastmybatis.core.support.TreeNode;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
/**
* @author tanghc
*/
@Data
public class TornaDocParamDTO implements TreeNode<TornaDocParamDTO, Long> {
private Long id;
/**
* 字段名称
*/
private String name;
/**
* 字段类型
*/
private String type;
/**
* 是否必须10
*/
private Byte required;
/**
* 最大长度
*/
private String maxLength;
/**
* 示例值
*/
private String example;
/**
* 描述
*/
private String description;
private Long enumId;
/**
* doc_info.id
*/
private Long docId;
/**
* 父节点
*/
private Long parentId;
/**
* 0header, 1请求参数2返回参数3错误码
*/
private Byte style;
/**
* 新增操作方式0人工操作1开放平台推送
*/
private Byte createMode;
/**
* 修改操作方式0人工操作1开放平台推送
*/
private Byte modifyMode;
/**
* 创建人
*/
private String creatorName;
/**
* 修改人
*/
private String modifierName;
/**
* 排序
*/
private Integer orderIndex;
private Byte isDeleted;
/**
* 数据库字段gmt_create
*/
private LocalDateTime gmtCreate;
/**
* 数据库字段gmt_modified
*/
private LocalDateTime gmtModified;
private boolean global;
private List<TornaDocParamDTO> children;
public boolean getRequire() {
return Objects.equals(this.required, 1);
}
@Override
public Long takeId() {
return id;
}
@Override
public Long takeParentId() {
return parentId;
}
}

View File

@@ -1,4 +1,4 @@
package com.gitee.sop.adminbackend.service.doc.dto; package com.gitee.sop.adminbackend.service.doc.dto.torna;
import lombok.Data; import lombok.Data;

View File

@@ -1,13 +1,19 @@
package com.gitee.sop.adminbackend.service.website; package com.gitee.sop.adminbackend.service.website;
import com.gitee.fastmybatis.core.util.TreeUtil; import com.gitee.fastmybatis.core.util.TreeUtil;
import com.gitee.sop.adminbackend.common.enums.YesOrNoEnum;
import com.gitee.sop.adminbackend.common.util.CopyUtil; import com.gitee.sop.adminbackend.common.util.CopyUtil;
import com.gitee.sop.adminbackend.dao.entity.DocApp; import com.gitee.sop.adminbackend.dao.entity.DocApp;
import com.gitee.sop.adminbackend.dao.entity.DocInfo; import com.gitee.sop.adminbackend.dao.entity.DocInfo;
import com.gitee.sop.adminbackend.dao.mapper.DocAppMapper; import com.gitee.sop.adminbackend.service.doc.DocAppService;
import com.gitee.sop.adminbackend.dao.mapper.DocInfoMapper; import com.gitee.sop.adminbackend.service.doc.DocInfoService;
import com.gitee.sop.adminbackend.service.doc.DocSettingService;
import com.gitee.sop.adminbackend.service.doc.dto.DocAppDTO; import com.gitee.sop.adminbackend.service.doc.dto.DocAppDTO;
import com.gitee.sop.adminbackend.service.doc.dto.DocInfoConfigDTO;
import com.gitee.sop.adminbackend.service.doc.dto.DocInfoTreeDTO; import com.gitee.sop.adminbackend.service.doc.dto.DocInfoTreeDTO;
import com.gitee.sop.adminbackend.service.doc.dto.DocInfoViewDTO;
import com.gitee.sop.adminbackend.service.doc.dto.DocSettingDTO;
import com.gitee.sop.adminbackend.service.doc.dto.torna.TornaDocInfoViewDTO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -20,19 +26,39 @@ import java.util.List;
public class WebsiteService { public class WebsiteService {
@Autowired @Autowired
private DocAppMapper docAppMapper; private DocAppService docAppService;
@Autowired @Autowired
private DocInfoMapper docInfoMapper; private DocInfoService docInfoService;
@Autowired
private DocSettingService docSettingService;
public List<DocAppDTO> listDocApp() { public List<DocAppDTO> listDocApp() {
List<DocApp> docApps = docAppMapper.listAll(); List<DocApp> docApps = docAppService.list(DocApp::getIsPublish, YesOrNoEnum.YES.getValue());
return CopyUtil.copyList(docApps, DocAppDTO::new); return CopyUtil.copyList(docApps, DocAppDTO::new);
} }
public List<DocInfoTreeDTO> listDocMenuTree(Long docAppId) { public List<DocInfoTreeDTO> listDocMenuTree(Long docAppId) {
List<DocInfo> list = docInfoMapper.list(DocInfo::getDocAppId, docAppId); List<DocInfo> list = docInfoService.query()
.eq(DocInfo::getDocAppId, docAppId)
.eq(DocInfo::getIsPublish, YesOrNoEnum.YES.getValue())
.list();
List<DocInfoTreeDTO> treeList = CopyUtil.copyList(list, DocInfoTreeDTO::new); List<DocInfoTreeDTO> treeList = CopyUtil.copyList(list, DocInfoTreeDTO::new);
return TreeUtil.convertTree(treeList, 0L); return TreeUtil.convertTree(treeList, 0L);
} }
public DocInfoViewDTO getDocDetail(Long id) {
TornaDocInfoViewDTO tornaDocInfoViewDTO = docInfoService.getDocDetail(id);
DocInfoConfigDTO docInfoConfigDTO = buildDocInfoConfig();
DocInfoViewDTO docInfoViewDTO = new DocInfoViewDTO();
docInfoViewDTO.setDocInfoView(tornaDocInfoViewDTO);
docInfoViewDTO.setDocInfoConfig(docInfoConfigDTO);
return docInfoViewDTO;
}
private DocInfoConfigDTO buildDocInfoConfig() {
DocSettingDTO docSetting = docSettingService.getDocSetting();
return CopyUtil.copyBean(docSetting, DocInfoConfigDTO::new);
}
} }

View File

@@ -4,6 +4,7 @@ import type { Result } from "@/model";
// 后端请求接口 // 后端请求接口
const apiUrl: any = createUrl({ const apiUrl: any = createUrl({
addApp: "/doc/app/add", addApp: "/doc/app/add",
syncDoc: "/doc/app/syncDoc",
listApp: "/doc/app/list", listApp: "/doc/app/list",
listDocTree: "/doc/info/tree", listDocTree: "/doc/info/tree",
publish: "/doc/info/publish" publish: "/doc/info/publish"
@@ -31,6 +32,16 @@ export const api: any = {
addApp(data: object) { addApp(data: object) {
return http.post<Result<any>, any>(apiUrl.addApp, { data }); return http.post<Result<any>, any>(apiUrl.addApp, { data });
}, },
/**
* 同步文档
* @param data 表单内容
*/
syncDoc(docAppId) {
const data = {
id: docAppId
};
return http.post<Result<any>, any>(apiUrl.syncDoc, { data });
},
/** /**
* 发布 * 发布
* @param data 表单内容 * @param data 表单内容

View File

@@ -17,6 +17,7 @@ export const tabsData = ref<Array<any>>([
export const activeName = ref(0); export const activeName = ref(0);
const docAppId = ref(0); const docAppId = ref(0);
export const loading = ref(false);
// 表格对象 // 表格对象
export const { tableData, buttons: actionButtons } = useTable<any[]>(); export const { tableData, buttons: actionButtons } = useTable<any[]>();
@@ -55,11 +56,15 @@ export const tableColumns: PlusColumn[] = [
}, },
{ {
label: "版本号", label: "版本号",
prop: "docVersion" prop: "docVersion",
width: 80
}, },
{ {
label: "描述", label: "描述",
prop: "description" prop: "description",
tableColumnProps: {
showOverflowTooltip: true
}
}, },
{ {
label: "发布状态", label: "发布状态",
@@ -101,21 +106,17 @@ export const tableColumns: PlusColumn[] = [
// 表格按钮定义 // 表格按钮定义
actionButtons.value = [ actionButtons.value = [
{ {
text: row => (row.isPublish ? "下线" : "发布"), text: "发布",
confirm: { confirm: {
options: { draggable: false }, options: { draggable: false },
popconfirmProps: { width: 300 }, popconfirmProps: { width: 300 },
message: params => { message: params => {
const row = params.row; const row = params.row;
const opt = row.isPublish ? "下线" : "发布"; return `确定要发布[${row.docTitle}]下所有接口吗?`;
const isFolder = row.isFolder;
return isFolder === 1
? `确定要${opt}[${row.docTitle}]下所有接口吗?`
: `确定要${opt}[${row.docTitle}]吗?`;
} }
}, },
props: (row: any) => ({ props: (_: any) => ({
type: row.isPublish === 1 ? "danger" : "success" type: "success"
}), }),
onConfirm(params: ButtonsCallBackParams) { onConfirm(params: ButtonsCallBackParams) {
const data = { const data = {
@@ -126,7 +127,8 @@ actionButtons.value = [
ElMessage.success("保存成功"); ElMessage.success("保存成功");
search(); search();
}); });
} },
show: (row: any) => row.isFolder === 1
}, },
{ {
text: "下线", text: "下线",
@@ -153,6 +155,32 @@ actionButtons.value = [
}); });
}, },
show: (row: any) => row.isFolder === 1 show: (row: any) => row.isFolder === 1
},
{
text: row => (row.isPublish ? "下线" : "发布"),
confirm: {
options: { draggable: false },
popconfirmProps: { width: 300 },
message: params => {
const row = params.row;
const opt = row.isPublish ? "下线" : "发布";
return `确定要${opt}[${row.docTitle}]吗?`;
}
},
props: (row: any) => ({
type: row.isPublish === 1 ? "danger" : "success"
}),
onConfirm(params: ButtonsCallBackParams) {
const data = {
id: params.row.id,
isPublish: params.row.isPublish === 1 ? 0 : 1
};
api.publish(data).then(() => {
ElMessage.success("保存成功");
search();
});
},
show: (row: any) => row.isFolder === 0
} }
]; ];
@@ -166,6 +194,28 @@ const search = async () => {
loadContent(docAppId.value); loadContent(docAppId.value);
}; };
export function handleSyncApi() {
ElMessageBox.confirm("确定要同步远程接口吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
loading.value = true;
api
.syncDoc(docAppId.value)
.then(() => {
loading.value = false;
ElMessage.success("同步成功");
search();
})
.catch(() => {
loading.value = false;
});
})
.catch(() => {});
}
export const handleClick = data => { export const handleClick = data => {
const id = data.props.name; const id = data.props.name;
activeTab(id); activeTab(id);

View File

@@ -3,17 +3,19 @@ import {
activeName, activeName,
handleClick, handleClick,
handleAddApp, handleAddApp,
handleSyncApi,
tabsData, tabsData,
actionButtons, actionButtons,
tableColumns, tableColumns,
tableRows, tableRows,
filterText, filterText,
loading,
handleSearch handleSearch
} from "./index"; } from "./index";
import { Search } from "@element-plus/icons-vue"; import { Search } from "@element-plus/icons-vue";
</script> </script>
<template> <template>
<el-card shadow="never"> <el-card v-loading="loading" shadow="never">
<div v-show="tabsData.length === 0"> <div v-show="tabsData.length === 0">
<el-button type="primary" @click="handleAddApp">添加应用</el-button> <el-button type="primary" @click="handleAddApp">添加应用</el-button>
</div> </div>
@@ -57,6 +59,9 @@ import { Search } from "@element-plus/icons-vue";
</template> </template>
</el-input> </el-input>
</template> </template>
<template #toolbar>
<el-button type="primary" @click="handleSyncApi">同步接口</el-button>
</template>
</PlusTable> </PlusTable>
</el-card> </el-card>
</template> </template>

View File

@@ -1,8 +1,8 @@
package com.gitee.sop.payment.impl; package com.gitee.sop.payment.impl;
import com.gitee.sop.payment.open.OpenPayment; import com.gitee.sop.payment.open.OpenPayment;
import com.gitee.sop.payment.open.req.AlipayTradeWapPayRequest; import com.gitee.sop.payment.open.req.PayTradeWapPayRequest;
import com.gitee.sop.payment.open.resp.AlipayTradeWapPayResponse; import com.gitee.sop.payment.open.resp.PayTradeWapPayResponse;
import org.apache.dubbo.config.annotation.DubboService; import org.apache.dubbo.config.annotation.DubboService;
import java.util.UUID; import java.util.UUID;
@@ -17,9 +17,9 @@ import java.util.UUID;
public class OpenPaymentImpl implements OpenPayment { public class OpenPaymentImpl implements OpenPayment {
@Override @Override
public AlipayTradeWapPayResponse tradeWapPay(AlipayTradeWapPayRequest request) { public PayTradeWapPayResponse tradeWapPay(PayTradeWapPayRequest request) {
AlipayTradeWapPayResponse alipayTradeWapPayResponse = new AlipayTradeWapPayResponse(); PayTradeWapPayResponse payTradeWapPayResponse = new PayTradeWapPayResponse();
alipayTradeWapPayResponse.setPageRedirectionData(UUID.randomUUID().toString()); payTradeWapPayResponse.setPageRedirectionData(UUID.randomUUID().toString());
return alipayTradeWapPayResponse; return payTradeWapPayResponse;
} }
} }

View File

@@ -1,7 +1,7 @@
package com.gitee.sop.payment.open; package com.gitee.sop.payment.open;
import com.gitee.sop.payment.open.req.AlipayTradeWapPayRequest; import com.gitee.sop.payment.open.req.PayTradeWapPayRequest;
import com.gitee.sop.payment.open.resp.AlipayTradeWapPayResponse; import com.gitee.sop.payment.open.resp.PayTradeWapPayResponse;
import com.gitee.sop.support.annotation.Open; import com.gitee.sop.support.annotation.Open;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@@ -15,13 +15,13 @@ import io.swagger.annotations.ApiOperation;
public interface OpenPayment { public interface OpenPayment {
@ApiOperation( @ApiOperation(
value = "alipay.trade.wap.pay(手机网站支付接口2.0)", value = "手机网站支付接口2.0",
notes = "该接口是页面跳转接口,用于生成用户访问支付宝的跳转链接。" + notes = "该接口是页面跳转接口,用于生成用户访问跳转链接。" +
"请在服务端执行支付宝SDK中pageExecute方法读取响应中的body()结果。" + "请在服务端执行SDK中pageExecute方法读取响应中的body()结果。" +
"该结果用于跳转到支付宝页面,返回到用户浏览器渲染或重定向跳转到支付宝页面。" + "该结果用于跳转到页面,返回到用户浏览器渲染或重定向跳转到页面。" +
"具体使用方法请参考 <a href=\"https://torna.cn\" target=\"_blank\">接入指南</a>" "具体使用方法请参考 <a href=\"https://torna.cn\" target=\"_blank\">接入指南</a>"
) )
@Open(value = "alipay.trade.wap.pay", version = "2.0") @Open(value = "pay.trade.wap.pay", version = "2.0")
AlipayTradeWapPayResponse tradeWapPay(AlipayTradeWapPayRequest request); PayTradeWapPayResponse tradeWapPay(PayTradeWapPayRequest request);
} }

View File

@@ -16,7 +16,7 @@ import java.util.List;
* https://opendocs.alipay.com/open/29ae8cb6_alipay.trade.wap.pay?pathHash=1ef587fd&ref=api&scene=21 * https://opendocs.alipay.com/open/29ae8cb6_alipay.trade.wap.pay?pathHash=1ef587fd&ref=api&scene=21
*/ */
@Data @Data
public class AlipayTradeWapPayRequest { public class PayTradeWapPayRequest {
@ApiModelProperty(value = "商户网站唯一订单号", required = true, example = "70501111111S001111119") @ApiModelProperty(value = "商户网站唯一订单号", required = true, example = "70501111111S001111119")

View File

@@ -7,7 +7,7 @@ import lombok.Data;
* @author 六如 * @author 六如
*/ */
@Data @Data
public class AlipayTradeWapPayResponse { public class PayTradeWapPayResponse {
@ApiModelProperty( @ApiModelProperty(
value = "用于跳转支付宝页面的信息POST和GET方法生成内容不同使用POST方法执行结果为html form表单在浏览器渲染即可使用GET方法会得到支付宝URL需要打开或重定向到该URL。建议使用POST方式。具体使用方法请参考", value = "用于跳转支付宝页面的信息POST和GET方法生成内容不同使用POST方法执行结果为html form表单在浏览器渲染即可使用GET方法会得到支付宝URL需要打开或重定向到该URL。建议使用POST方式。具体使用方法请参考",

View File

@@ -49,7 +49,6 @@ import lombok.Data;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
@@ -74,7 +73,6 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -84,6 +82,8 @@ import java.util.stream.Stream;
*/ */
public class SwaggerPluginService { public class SwaggerPluginService {
public static final String DUBBO = "dubbo";
public static final String VERSION = "1.0";
private final TornaConfig tornaConfig; private final TornaConfig tornaConfig;
private final OpenClient client; private final OpenClient client;
private boolean existsApiIgnore = true; private boolean existsApiIgnore = true;
@@ -224,22 +224,27 @@ public class SwaggerPluginService {
List<DocItem> folders = new ArrayList<>(controllerDocMap.size()); List<DocItem> folders = new ArrayList<>(controllerDocMap.size());
for (Map.Entry<String, List<DocItem>> entry : folderDocMap.entrySet()) { for (Map.Entry<String, List<DocItem>> entry : folderDocMap.entrySet()) {
String name = entry.getKey(); String name = entry.getKey();
ControllerInfo info = controllerInfoList ControllerInfo ctrlInfo = controllerInfoList
.stream() .stream()
.filter(controllerInfo -> name.equals(controllerInfo.getName())) .filter(controllerInfo -> name.equals(controllerInfo.getName()))
.findFirst() .findFirst()
.orElse(null); .orElse(null);
if (info == null) { if (ctrlInfo == null) {
continue; continue;
} }
DocItem docItem = new DocItem(); DocItem docItem = new DocItem();
docItem.setName(name); docItem.setName(name);
docItem.setDefinition(info.getDescription()); docItem.setDefinition(ctrlInfo.getDescription());
docItem.setOrderIndex(info.getPosition()); docItem.setOrderIndex(ctrlInfo.getPosition());
docItem.setIsFolder(Booleans.TRUE); docItem.setIsFolder(Booleans.TRUE);
List<DocItem> items = entry.getValue(); List<DocItem> items = entry.getValue();
items.sort(Comparator.comparing(DocItem::getOrderIndex)); items.sort(Comparator.comparing(DocItem::getOrderIndex));
docItem.setItems(items); docItem.setItems(items);
DubboInfo dubboInfo = new DubboInfo();
dubboInfo.setInterfaceName(ctrlInfo.getControllerClass().getName());
dubboInfo.setVersion(VERSION);
dubboInfo.setProtocol(DUBBO);
docItem.setDubboInfo(dubboInfo);
folders.add(docItem); folders.add(docItem);
} }
return folders; return folders;
@@ -416,45 +421,7 @@ public class SwaggerPluginService {
} }
protected List<DocParamPath> buildPathParams(Method method) { protected List<DocParamPath> buildPathParams(Method method) {
List<ApiImplicitParam> apiImplicitParamList = buildApiImplicitParams(method, param -> "path".equalsIgnoreCase(param.paramType())); return Collections.emptyList();
List<DocParamPath> docParamPaths = new ArrayList<>(apiImplicitParamList.size());
if (!apiImplicitParamList.isEmpty()) {
for (ApiImplicitParam apiImplicitParam : apiImplicitParamList) {
DocParamPath docParamPath = new DocParamPath();
docParamPath.setName(apiImplicitParam.name());
docParamPath.setRequired(Booleans.toValue(apiImplicitParam.required()));
docParamPath.setDescription(apiImplicitParam.value());
docParamPath.setExample(apiImplicitParam.example());
docParamPath.setType(getDataType(apiImplicitParam));
docParamPaths.add(docParamPath);
}
}
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
PathVariable pathVariable = parameter.getAnnotation(PathVariable.class);
if (pathVariable != null) {
String name = pathVariable.value();
if (StringUtils.isEmpty(name)) {
name = pathVariable.name();
}
if (StringUtils.isEmpty(name)) {
name = parameter.getName();
}
// 如果已经有了不添加
if (containsName(docParamPaths, name) || isIgnoreParameter(parameter)) {
continue;
}
DocParamInfo docParamInfo = buildDocParamInfo(parameter);
DocParamPath docParamPath = new DocParamPath();
docParamPath.setName(name);
docParamPath.setType(docParamInfo.getType());
docParamPath.setRequired(Booleans.toValue(pathVariable.required()));
docParamPath.setDescription(docParamInfo.getDescription());
docParamPath.setExample(docParamInfo.getExample());
docParamPaths.add(docParamPath);
}
}
return docParamPaths;
} }
private static DocParamInfo buildDocParamInfo(Parameter parameter) { private static DocParamInfo buildDocParamInfo(Parameter parameter) {
@@ -487,87 +454,11 @@ public class SwaggerPluginService {
} }
protected List<DocParamHeader> buildHeaderParams(Method method) { protected List<DocParamHeader> buildHeaderParams(Method method) {
List<ApiImplicitParam> apiImplicitParamList = buildApiImplicitParams(method, param -> "header".equalsIgnoreCase(param.paramType())); return Collections.emptyList();
List<DocParamHeader> docParamHeaders = new ArrayList<>(apiImplicitParamList.size());
if (!apiImplicitParamList.isEmpty()) {
for (ApiImplicitParam apiImplicitParam : apiImplicitParamList) {
DocParamHeader docParamHeader = new DocParamHeader();
docParamHeader.setName(apiImplicitParam.name());
docParamHeader.setRequired(Booleans.toValue(apiImplicitParam.required()));
docParamHeader.setDescription(apiImplicitParam.value());
docParamHeader.setExample(apiImplicitParam.example());
docParamHeaders.add(docParamHeader);
}
}
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
RequestHeader requestHeader = parameter.getAnnotation(RequestHeader.class);
if (requestHeader != null) {
String name = getParameterName(parameter);
// 如果已经有了不添加
if (containsName(docParamHeaders, name) || isIgnoreParameter(parameter)) {
continue;
}
DocParamInfo docParamInfo = buildDocParamInfo(parameter);
DocParamHeader docParamHeader = new DocParamHeader();
docParamHeader.setName(name);
docParamHeader.setRequired(Booleans.toValue(requestHeader.required()));
docParamHeader.setDescription(docParamInfo.getDescription());
docParamHeader.setExample(docParamInfo.getExample());
docParamHeaders.add(docParamHeader);
}
}
return docParamHeaders;
} }
protected List<DocParamReq> buildQueryParams(Method method, String httpMethod) { protected List<DocParamReq> buildQueryParams(Method method, String httpMethod) {
List<ApiImplicitParam> apiImplicitParamList = buildApiImplicitParams(method, param -> "query".equalsIgnoreCase(param.paramType())); return Collections.emptyList();
List<DocParamReq> docParamReqs = new ArrayList<>(apiImplicitParamList.size());
if (!apiImplicitParamList.isEmpty()) {
for (ApiImplicitParam apiImplicitParam : apiImplicitParamList) {
DocParamReq paramReq = new DocParamReq();
paramReq.setName(apiImplicitParam.name());
paramReq.setRequired(Booleans.toValue(apiImplicitParam.required()));
paramReq.setDescription(apiImplicitParam.value());
paramReq.setExample(apiImplicitParam.example());
paramReq.setType(getDataType(apiImplicitParam));
docParamReqs.add(paramReq);
}
}
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
PathVariable pathVariable = parameter.getAnnotation(PathVariable.class);
if (pathVariable != null) {
continue;
}
RequestHeader requestHeader = parameter.getAnnotation(RequestHeader.class);
if (requestHeader != null) {
continue;
}
Class<?> parameterType = parameter.getType();
String name = getParameterName(parameter);
// 如果已经有了不添加
if (containsName(docParamReqs, name) || isIgnoreParameter(parameter)) {
continue;
}
RequestParam requestParam = parameter.getAnnotation(RequestParam.class);
// 如果是Get请求
if (httpMethod.equalsIgnoreCase(HttpMethod.GET.name()) || requestParam != null) {
boolean isPojo = PluginUtil.isPojo(parameterType);
// 当get请求时遇到普通类则认为类中的属性都是query参数
if (isPojo) {
List<DocParamReq> docParamReqList = buildReqClassParams(parameterType);
docParamReqs.addAll(docParamReqList);
} else {
DocParamReq docParamReq = buildDocParamReq(parameter);
Optional<Boolean> requiredOpt = Optional.ofNullable(requestParam).map(RequestParam::required);
// 如果定义了RequestParamrequired由它来指定
requiredOpt.ifPresent(aBoolean -> docParamReq.setRequired(Booleans.toValue(aBoolean)));
docParamReqs.add(docParamReq);
}
}
}
return docParamReqs;
} }
protected DocParamReq buildDocParamReq(Parameter parameter) { protected DocParamReq buildDocParamReq(Parameter parameter) {
@@ -594,38 +485,7 @@ public class SwaggerPluginService {
if (StringUtils.hasText(fieldName)) { if (StringUtils.hasText(fieldName)) {
return fieldName; return fieldName;
} }
RequestParam requestParam = parameter.getAnnotation(RequestParam.class); return parameter.getName();
PathVariable pathVariable = parameter.getAnnotation(PathVariable.class);
RequestHeader requestHeader = parameter.getAnnotation(RequestHeader.class);
String name = parameter.getName();
if (requestParam != null) {
String val = requestParam.value();
if (StringUtils.isEmpty(val)) {
val = requestParam.name();
}
if (StringUtils.hasText(val)) {
name = val;
}
}
if (pathVariable != null) {
String val = pathVariable.value();
if (StringUtils.isEmpty(val)) {
val = pathVariable.name();
}
if (StringUtils.hasText(val)) {
name = val;
}
}
if (requestHeader != null) {
String val = requestHeader.value();
if (StringUtils.isEmpty(val)) {
val = requestHeader.name();
}
if (StringUtils.hasText(val)) {
name = val;
}
}
return name;
} }
protected DocParamReqWrapper buildRequestParams(ControllerInfo controllerInfo, Method method, String httpMethod) { protected DocParamReqWrapper buildRequestParams(ControllerInfo controllerInfo, Method method, String httpMethod) {
@@ -662,7 +522,6 @@ public class SwaggerPluginService {
continue; continue;
} }
int mode = tornaConfig.getMode(); int mode = tornaConfig.getMode();
RequestBody requestBody = parameter.getAnnotation(RequestBody.class);
Class<?> type = parameter.getType(); Class<?> type = parameter.getType();
Type parameterizedType = parameter.getParameterizedType(); Type parameterizedType = parameter.getParameterizedType();
if (parameterizedType instanceof TypeVariable) { if (parameterizedType instanceof TypeVariable) {
@@ -677,7 +536,7 @@ public class SwaggerPluginService {
ApiParamWrapper apiParamWrapper = new ApiParamWrapper(parameter.getAnnotation(ApiParam.class)); ApiParamWrapper apiParamWrapper = new ApiParamWrapper(parameter.getAnnotation(ApiParam.class));
array = PluginUtil.isCollectionOrArray(type); array = PluginUtil.isCollectionOrArray(type);
Map<String, Class<?>> genericParamMap = buildParamsByGeneric(controllerInfo, parameterizedType); Map<String, Class<?>> genericParamMap = buildParamsByGeneric(controllerInfo, parameterizedType);
if (requestBody != null || mode == ModeEnum.DUBBO.getValue()) { if (mode == ModeEnum.DUBBO.getValue()) {
List<DocParamReq> docParamReqList; List<DocParamReq> docParamReqList;
if (array) { if (array) {
// 获取数元素类型 // 获取数元素类型
@@ -957,7 +816,7 @@ public class SwaggerPluginService {
return Collections.emptyMap(); return Collections.emptyMap();
} else { } else {
ParameterizedType parameterizedType = (ParameterizedType) genType; ParameterizedType parameterizedType = (ParameterizedType) genType;
Class<?> rawType = (Class<?>)parameterizedType.getRawType(); Class<?> rawType = (Class<?>) parameterizedType.getRawType();
List<String> classGenericParamNameList = PluginUtil.getClassGenericParamName(rawType); List<String> classGenericParamNameList = PluginUtil.getClassGenericParamName(rawType);
Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
Class<?> superclass = controllerClass.getSuperclass(); Class<?> superclass = controllerClass.getSuperclass();

View File

@@ -3,10 +3,6 @@ package cn.torna.swaggerplugin.builder;
import cn.torna.swaggerplugin.bean.ControllerInfo; import cn.torna.swaggerplugin.bean.ControllerInfo;
import cn.torna.swaggerplugin.bean.TornaConfig; import cn.torna.swaggerplugin.bean.TornaConfig;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@@ -29,19 +25,6 @@ public abstract class HttpMethodInfoBuilder implements RequestInfoBuilder {
@Override @Override
public String getHttpMethod() { public String getHttpMethod() {
String httpMethod = apiOperation.httpMethod();
if (StringUtils.hasText(httpMethod)) {
return httpMethod;
}
RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class);
if (requestMapping != null) {
RequestMethod[] methods = requestMapping.method();
if (methods.length == 0) {
return this.tornaConfig.getMethodWhenMulti();
} else {
return methods[0].name();
}
}
return tornaConfig.getDefaultHttpMethod(); return tornaConfig.getDefaultHttpMethod();
} }

View File

@@ -1,9 +1,6 @@
package cn.torna.swaggerplugin.util; package cn.torna.swaggerplugin.util;
import cn.torna.swaggerplugin.scaner.ClassScanner; import cn.torna.swaggerplugin.scaner.ClassScanner;
import org.springframework.http.HttpMethod;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.multipart.MultipartRequest;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -74,12 +71,9 @@ public class ClassUtil {
public static boolean isSpecialType(Class<?> paramType) { public static boolean isSpecialType(Class<?> paramType) {
// 特殊参数 // 特殊参数
boolean special = ( boolean special = (
WebRequest.class.isAssignableFrom(paramType) ||
MultipartRequest.class.isAssignableFrom(paramType) ||
Principal.class.isAssignableFrom(paramType) || Principal.class.isAssignableFrom(paramType) ||
InputStream.class.isAssignableFrom(paramType) || InputStream.class.isAssignableFrom(paramType) ||
Reader.class.isAssignableFrom(paramType) || Reader.class.isAssignableFrom(paramType) ||
HttpMethod.class == paramType ||
Locale.class == paramType || Locale.class == paramType ||
TimeZone.class == paramType || TimeZone.class == paramType ||
ZoneId.class == paramType || ZoneId.class == paramType ||

View File

@@ -3,8 +3,9 @@ import type { Result } from "@/model";
// 后端请求接口 // 后端请求接口
const apiUrl: any = createUrl({ const apiUrl: any = createUrl({
listApp: "/website/listDocApp", listApp: "/website/docapp/list",
listDocTree: "/doc/info/tree" listDocTree: "/website/docinfo/tree",
getDocDetail: "/website/docinfo/detail"
}); });
interface DocApp { interface DocApp {
@@ -28,5 +29,12 @@ export const api: any = {
*/ */
listDocTree(params: object) { listDocTree(params: object) {
return http.get<Result<Array<any>>, any>(apiUrl.listDocTree, { params }); return http.get<Result<Array<any>>, any>(apiUrl.listDocTree, { params });
},
/**
* 查询文档详情
* @param data
*/
getDocDetail(params: object) {
return http.get<Result<any>, any>(apiUrl.getDocDetail, { params });
} }
}; };

View File

@@ -1,12 +1,6 @@
import apiParamTable from "@/components/ApiParamTable/index.vue"; import apiParamTable from "@/components/ApiParamTable/index.vue";
import { withInstall } from "@pureadmin/utils"; import { withInstall } from "@pureadmin/utils";
export function hasNoParentAndChildren(row) {
const children = row.children;
const noChildren = !children || children.length === 0;
return !row.parentId && noChildren;
}
const ApiParamTable = withInstall(apiParamTable); const ApiParamTable = withInstall(apiParamTable);
export { ApiParamTable }; export { ApiParamTable };

View File

@@ -28,3 +28,14 @@
.danger { .danger {
color: #F56C6C; color: #F56C6C;
} }
.doc-view {
.api-description {
font-size: 14px;
a {
color: #406eeb;
}
}
.is-bordered-label {
width: 200px !important;
}
}

View File

@@ -13,6 +13,7 @@ import { stringify } from "qs";
import NProgress from "../progress"; import NProgress from "../progress";
import { getToken, formatToken } from "@/utils/auth"; import { getToken, formatToken } from "@/utils/auth";
import { useUserStoreHook } from "@/store/modules/user"; import { useUserStoreHook } from "@/store/modules/user";
import { ElMessage } from "element-plus";
export const baseUrl = (url: string) => { export const baseUrl = (url: string) => {
if (!url) { if (!url) {
@@ -181,8 +182,13 @@ class PureHttp {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
PureHttp.axiosInstance PureHttp.axiosInstance
.request(config) .request(config)
.then((response: undefined) => { .then((response: any) => {
resolve(response); if (response.code && response.code !== "0") {
const msg = response.msg || "后台出错,请查看日志";
ElMessage.error(msg);
} else {
resolve(response);
}
}) })
.catch(error => { .catch(error => {
reject(error); reject(error);

View File

@@ -1,4 +1,4 @@
import { ref } from "vue"; import { computed, ref } from "vue";
import { api as docApi } from "@/api/doc"; import { api as docApi } from "@/api/doc";
export const defaultActive = ref("overview.md"); export const defaultActive = ref("overview.md");
@@ -8,13 +8,42 @@ export const contentShow = ref(false);
export const openMenu = ref([]); export const openMenu = ref([]);
export const apiModules = ref([]); export const apiModules = ref([]);
export const dataNodeType = ref("Object"); export const dataNodeType = ref("Object");
export const api = ref<any>({});
export const requestParamsExample = ref({}); export const requestParamsExample = ref({});
export const responseParamsExample = ref({}); export const responseParamsExample = ref({});
export const docAppId = ref(0); export const docAppId = ref(0);
export const docAppList = ref([]); export const docAppList = ref([]);
export const docTree = ref([]); export const docTree = ref([]);
export const docDetail = ref({
docInfoView: {
url: "",
version: "",
docName: "",
description: "",
remark: "",
requestParams: [],
responseParams: []
},
docInfoConfig: {
openProdUrl: "",
openSandboxUrl: ""
}
});
export const showUrl = computed(() => {
return (
docDetail.value.docInfoConfig?.openProdUrl?.length > 0 &&
docDetail.value.docInfoConfig?.openSandboxUrl?.length > 0
);
});
export const showProdUrl = computed(() => {
return docDetail.value.docInfoConfig?.openProdUrl?.length > 0;
});
export const showSandBoxUrl = computed(() => {
return docDetail.value.docInfoConfig?.openSandboxUrl?.length > 0;
});
/* /*
参数 类型 是否必填 最大长度 描述 示例值 参数 类型 是否必填 最大长度 描述 示例值
@@ -43,8 +72,8 @@ export const commonParams = ref([
type: "String", type: "String",
maxLength: 128, maxLength: 128,
required: 1, required: 1,
description: "版本号", description: "接口名称",
example: "1.0" example: "shop.order.create"
}, },
{ {
name: "format", name: "format",
@@ -92,7 +121,7 @@ export const commonParams = ref([
maxLength: 3, maxLength: 3,
required: 1, required: 1,
description: "调用的接口版本固定为1.0", description: "调用的接口版本固定为1.0",
example: "1.0" example: "xxxx"
}, },
{ {
name: "app_auth_token", name: "app_auth_token",
@@ -100,7 +129,7 @@ export const commonParams = ref([
maxLength: 40, maxLength: 40,
required: 0, required: 0,
description: "详见应用授权概述", description: "详见应用授权概述",
example: "1.0" example: "xxxx"
}, },
{ {
name: "biz_content", name: "biz_content",
@@ -163,7 +192,15 @@ export function handleChangeDocApp(id) {
} }
export function handleNodeClick(node) { export function handleNodeClick(node) {
console.log(node); if (node.isFolder === 1) {
return;
}
const params = {
id: node.id
};
docApi.getDocDetail(params).then(resp => {
docDetail.value = resp.data;
});
} }
function loadDocApp() { function loadDocApp() {

View File

@@ -1,23 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import { import {
openMenu,
defaultActive,
apiModules,
contentShow, contentShow,
content, content,
api, docDetail,
commonParams, commonParams,
activeIndex,
requestParamsExample,
responseParamsExample,
dataNodeType, dataNodeType,
resultData, resultData,
onMenuClick,
handleChangeDocApp, handleChangeDocApp,
docAppId, docAppId,
docAppList, docAppList,
docTree, docTree,
handleNodeClick handleNodeClick,
showUrl,
showProdUrl,
showSandBoxUrl
} from "./index"; } from "./index";
import { ApiParamTable } from "@/components/ApiParamTable"; import { ApiParamTable } from "@/components/ApiParamTable";
import MavonEditor from "mavon-editor"; import MavonEditor from "mavon-editor";
@@ -27,7 +23,7 @@ const defaultProps = {
}; };
</script> </script>
<template> <template>
<el-container> <el-container class="doc-view">
<el-aside width="300px"> <el-aside width="300px">
<el-select <el-select
v-show="docAppId > 0" v-show="docAppId > 0"
@@ -43,14 +39,20 @@ const defaultProps = {
:value="item.id" :value="item.id"
/> />
</el-select> </el-select>
<div style="margin-top: 10px">
<el-link type="primary" href="" target="_blank">签名算法</el-link>
</div>
<el-tree <el-tree
:data="docTree" :data="docTree"
:props="defaultProps" :props="defaultProps"
style="margin-top: 20px" style="margin-top: 10px"
@node-click="handleNodeClick" @node-click="handleNodeClick"
/> />
</el-aside> </el-aside>
<el-main style="padding-top: 0"> <el-main
v-show="docDetail?.docInfoView?.url?.length > 0"
style="padding-top: 0"
>
<div v-show="contentShow"> <div v-show="contentShow">
<MavonEditor <MavonEditor
v-model="content" v-model="content"
@@ -62,11 +64,44 @@ const defaultProps = {
/> />
</div> </div>
<div v-show="!contentShow"> <div v-show="!contentShow">
<h3>{{ api.description }}</h3> <h2>
<div v-if="api.remark" class="api-remark"> {{ docDetail.docInfoView.url + `(${docDetail.docInfoView.docName})` }}
{{ api.remark }} </h2>
<div v-if="docDetail.docInfoView.description">
<h3>接口说明</h3>
<div
class="api-description"
v-html="docDetail.docInfoView.description"
/>
</div> </div>
<div>接口名{{ api.name }} 版本号{{ api.version }}</div> <el-descriptions border style="margin-top: 20px">
<el-descriptions-item label="接口名称">
{{ docDetail.docInfoView.url }}
</el-descriptions-item>
<el-descriptions-item label="版本号">
{{ docDetail.docInfoView.version }}
</el-descriptions-item>
</el-descriptions>
<el-descriptions
v-show="showUrl"
:column="1"
title="请求地址"
border
style="margin-top: 20px"
>
<el-descriptions-item v-show="showProdUrl">
<template #label>
<div class="cell-item">生产环境</div>
</template>
{{ docDetail.docInfoConfig.openProdUrl }}
</el-descriptions-item>
<el-descriptions-item v-show="showSandBoxUrl">
<template #label>
<div class="cell-item">沙箱环境</div>
</template>
{{ docDetail.docInfoConfig.openSandboxUrl }}
</el-descriptions-item>
</el-descriptions>
<h3>公共请求参数</h3> <h3>公共请求参数</h3>
<el-table :data="commonParams" border highlight-current-row> <el-table :data="commonParams" border highlight-current-row>
<el-table-column prop="name" label="名称" width="200" /> <el-table-column prop="name" label="名称" width="200" />
@@ -93,11 +128,7 @@ const defaultProps = {
<el-table-column prop="example" label="示例值" width="200" /> <el-table-column prop="example" label="示例值" width="200" />
</el-table> </el-table>
<h3>业务请求参数</h3> <h3>业务请求参数</h3>
<api-param-table :data="api.requestParams" /> <ApiParamTable :data="docDetail.docInfoView.requestParams" />
<h4>请求示例</h4>
<pre class="normal-text">
{{ JSON.stringify(requestParamsExample, null, 4) }}
</pre>
<h3>公共返回参数</h3> <h3>公共返回参数</h3>
<el-table :data="resultData" border highlight-current-row> <el-table :data="resultData" border highlight-current-row>
<el-table-column label="名称" prop="name" width="200" /> <el-table-column label="名称" prop="name" width="200" />
@@ -126,11 +157,7 @@ const defaultProps = {
<el-table-column label="示例值" prop="example" width="200" /> <el-table-column label="示例值" prop="example" width="200" />
</el-table> </el-table>
<h4>业务返回参数</h4> <h4>业务返回参数</h4>
<ApiParamTable :data="api.responseParams" /> <ApiParamTable :data="docDetail.docInfoView.responseParams" />
<h4>返回示例</h4>
<pre class="normal-text">
{{ JSON.stringify(responseParamsExample, null, 4) }}
</pre>
</div> </div>
</el-main> </el-main>
</el-container> </el-container>