mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
5.0
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
package com.gitee.sop.adminbackend.common.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 来源类型,1-torna,2-自建
|
||||||
|
*
|
||||||
|
* @author 六如
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum DocSourceTypeEnum implements IntEnum {
|
||||||
|
TORNA(1, "Torna"),
|
||||||
|
CUSTOM(2, "自建");
|
||||||
|
private final Integer value;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,21 @@
|
|||||||
|
package com.gitee.sop.adminbackend.common.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文档类型,0:http,1:dubbo,2:富文本,3:Markdown
|
||||||
|
*
|
||||||
|
* @author 六如
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum DocTypeEnum implements IntEnum {
|
||||||
|
HTTP(0, "HTTP"),
|
||||||
|
DUBBO(1, "dubbo"),
|
||||||
|
RICH_TEXT(2, "富文本"),
|
||||||
|
MARKDOWN(3, "Markdown");
|
||||||
|
private final Integer value;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,24 @@
|
|||||||
|
package com.gitee.sop.adminbackend.common.enums;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 六如
|
||||||
|
*/
|
||||||
|
public interface IEnum<T extends Serializable> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取值
|
||||||
|
*
|
||||||
|
* @return 返回枚举值
|
||||||
|
*/
|
||||||
|
T getValue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取描述
|
||||||
|
*
|
||||||
|
* @return 返回枚举描述
|
||||||
|
*/
|
||||||
|
String getDescription();
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,24 @@
|
|||||||
|
package com.gitee.sop.adminbackend.common.enums;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 六如
|
||||||
|
*/
|
||||||
|
public interface IntEnum extends IEnum<Integer> {
|
||||||
|
|
||||||
|
static <T extends IntEnum> Optional<T> of(T[] values, Integer value) {
|
||||||
|
for (IntEnum intEnum : values) {
|
||||||
|
if (Objects.equals(intEnum.getValue(), value)) {
|
||||||
|
return Optional.of((T) intEnum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends IntEnum> Optional<String> ofDescription(T[] values, Integer value) {
|
||||||
|
return of(values, value).map(IntEnum::getDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,5 +1,6 @@
|
|||||||
package com.gitee.sop.adminbackend.common.enums;
|
package com.gitee.sop.adminbackend.common.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -8,25 +9,23 @@ import java.util.Objects;
|
|||||||
* @author 六如
|
* @author 六如
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
public enum StatusEnum {
|
@AllArgsConstructor
|
||||||
DISABLED((byte) 2),
|
public enum StatusEnum implements IntEnum {
|
||||||
ENABLE((byte) 1),
|
DISABLED(2, "禁用"),
|
||||||
SET_PWD((byte) 3);
|
ENABLE(1, "启用"),
|
||||||
|
SET_PWD(3, "重置密码");
|
||||||
|
|
||||||
private final int status;
|
private final Integer value;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
public static StatusEnum of(Integer value) {
|
public static StatusEnum of(Integer value) {
|
||||||
for (StatusEnum statusEnum : StatusEnum.values()) {
|
for (StatusEnum statusEnum : StatusEnum.values()) {
|
||||||
if (Objects.equals(statusEnum.status, value)) {
|
if (Objects.equals(statusEnum.value, value)) {
|
||||||
return statusEnum;
|
return statusEnum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DISABLED;
|
return DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusEnum(byte style) {
|
|
||||||
this.status = style;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,24 @@
|
|||||||
|
package com.gitee.sop.adminbackend.common.enums;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 六如
|
||||||
|
*/
|
||||||
|
public interface StringEnum extends IEnum<String> {
|
||||||
|
|
||||||
|
static <T extends StringEnum> Optional<T> of(T[] values, String value) {
|
||||||
|
for (StringEnum intEnum : values) {
|
||||||
|
if (Objects.equals(intEnum.getValue(), value)) {
|
||||||
|
return Optional.of((T) intEnum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends StringEnum> Optional<String> ofDescription(T[] values, String value) {
|
||||||
|
return of(values, value).map(StringEnum::getDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -10,14 +10,18 @@ import java.util.Objects;
|
|||||||
*/
|
*/
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Getter
|
@Getter
|
||||||
public enum YesOrNoEnum {
|
public enum YesOrNoEnum implements IntEnum {
|
||||||
YES(1),
|
YES(1, "是"),
|
||||||
NO(0);
|
NO(0, "否");
|
||||||
|
|
||||||
private final int value;
|
private final Integer value;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
public static YesOrNoEnum of(Integer value) {
|
public static YesOrNoEnum of(Number value) {
|
||||||
return Objects.equals(value, YES.value) ? YES : NO;
|
if (value == null) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
return Objects.equals(value.intValue(), YES.value) ? YES : NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static YesOrNoEnum of(Boolean value) {
|
public static YesOrNoEnum of(Boolean value) {
|
||||||
|
@@ -3,15 +3,20 @@ 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.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.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.service.doc.DocService;
|
import com.gitee.sop.adminbackend.service.doc.DocService;
|
||||||
import com.gitee.sop.adminbackend.service.website.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 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;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -34,9 +39,22 @@ public class DocController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("app/add")
|
@PostMapping("app/add")
|
||||||
public Result<Integer> addApp(@Validated @RequestBody DocAppAddParam param) {
|
public Result<Long> addApp(@Validated @RequestBody DocAppAddParam param) {
|
||||||
docService.addDocApp(param.getTornaToken());
|
Long docAppId = docService.addDocApp(param.getTornaToken());
|
||||||
return Result.ok(1);
|
return Result.ok(docAppId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("info/tree")
|
||||||
|
public Result<List<DocInfoTreeVO>> docTree(@RequestParam Long docAppId) {
|
||||||
|
List<DocInfoTreeDTO> docInfoTreeDTOS = docService.listDocTree(docAppId);
|
||||||
|
List<DocInfoTreeVO> docInfoTreeVOS = CopyUtil.deepCopyList(docInfoTreeDTOS, DocInfoTreeVO.class);
|
||||||
|
return Result.ok(docInfoTreeVOS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("info/publish")
|
||||||
|
public Result<Integer> publish(@Validated @RequestBody DocInfoUpdateParam param) {
|
||||||
|
int cnt = docService.publish(CopyUtil.copyBean(param, DocInfoPublishUpdateDTO::new));
|
||||||
|
return Result.ok(cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
package com.gitee.sop.adminbackend.controller.doc.param;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 六如
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class DocInfoUpdateParam {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private Integer isPublish;
|
||||||
|
|
||||||
|
}
|
@@ -1,10 +1,12 @@
|
|||||||
package com.gitee.sop.adminbackend.controller.website.vo;
|
package com.gitee.sop.adminbackend.controller.doc.vo;
|
||||||
|
|
||||||
import com.gitee.fastmybatis.core.support.TreeNode;
|
import com.gitee.fastmybatis.core.support.TreeNode;
|
||||||
|
import com.gitee.sop.adminbackend.common.enums.YesOrNoEnum;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,6 +32,11 @@ public class DocInfoTreeVO implements TreeNode<DocInfoTreeVO, Long> {
|
|||||||
*/
|
*/
|
||||||
private Long docId;
|
private Long docId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文档标题
|
||||||
|
*/
|
||||||
|
private String docTitle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文档code
|
* 文档code
|
||||||
*/
|
*/
|
||||||
@@ -95,7 +102,7 @@ public class DocInfoTreeVO implements TreeNode<DocInfoTreeVO, Long> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long takeId() {
|
public Long takeId() {
|
||||||
return id;
|
return docId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -103,4 +110,11 @@ public class DocInfoTreeVO implements TreeNode<DocInfoTreeVO, Long> {
|
|||||||
return parentId;
|
return parentId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getDocName() {
|
||||||
|
if (Objects.equals(isFolder, YesOrNoEnum.YES.getValue())) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return docName;
|
||||||
|
}
|
||||||
}
|
}
|
@@ -4,10 +4,10 @@ import com.gitee.sop.adminbackend.common.annotation.NoToken;
|
|||||||
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.DocAppVO;
|
import com.gitee.sop.adminbackend.controller.doc.vo.DocAppVO;
|
||||||
import com.gitee.sop.adminbackend.controller.website.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.website.WebsiteService;
|
||||||
import com.gitee.sop.adminbackend.service.website.dto.DocAppDTO;
|
import com.gitee.sop.adminbackend.service.doc.dto.DocAppDTO;
|
||||||
import com.gitee.sop.adminbackend.service.website.dto.DocInfoTreeDTO;
|
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.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;
|
||||||
|
@@ -34,6 +34,11 @@ public class DocInfo {
|
|||||||
*/
|
*/
|
||||||
private Long docId;
|
private Long docId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文档标题
|
||||||
|
*/
|
||||||
|
private String docTitle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文档code
|
* 文档code
|
||||||
*/
|
*/
|
||||||
@@ -54,6 +59,11 @@ public class DocInfo {
|
|||||||
*/
|
*/
|
||||||
private String docName;
|
private String docName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本号
|
||||||
|
*/
|
||||||
|
private String docVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 描述
|
* 描述
|
||||||
*/
|
*/
|
||||||
|
@@ -0,0 +1,16 @@
|
|||||||
|
package com.gitee.sop.adminbackend.service.doc;
|
||||||
|
|
||||||
|
import com.gitee.fastmybatis.core.support.LambdaService;
|
||||||
|
import com.gitee.sop.adminbackend.dao.entity.DocApp;
|
||||||
|
import com.gitee.sop.adminbackend.dao.mapper.DocAppMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 六如
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class DocAppService implements LambdaService<DocApp, DocAppMapper> {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,107 @@
|
|||||||
|
package com.gitee.sop.adminbackend.service.doc;
|
||||||
|
|
||||||
|
import com.gitee.fastmybatis.core.support.LambdaService;
|
||||||
|
import com.gitee.sop.adminbackend.common.enums.DocSourceTypeEnum;
|
||||||
|
import com.gitee.sop.adminbackend.common.enums.YesOrNoEnum;
|
||||||
|
import com.gitee.sop.adminbackend.dao.entity.DocApp;
|
||||||
|
import com.gitee.sop.adminbackend.dao.entity.DocInfo;
|
||||||
|
import com.gitee.sop.adminbackend.dao.mapper.DocAppMapper;
|
||||||
|
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.TornaDocInfoDTO;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 六如
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class DocInfoService implements LambdaService<DocInfo, DocInfoMapper> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TornaClient tornaClient;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DocAppMapper docAppMapper;
|
||||||
|
|
||||||
|
public List<DocInfo> listChildDoc(Long parentId) {
|
||||||
|
return this.list(DocInfo::getParentId, parentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void syncDocInfo(Long docAppId) {
|
||||||
|
Map<Object, DocInfo> nameVersionMap = this.list(DocInfo::getDocAppId, docAppId)
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(docInfo -> docInfo.getDocName() + ":" + docInfo.getDocVersion(), Function.identity(), (v1, v2) -> v2));
|
||||||
|
|
||||||
|
DocApp docApp = docAppMapper.getById(docAppId);
|
||||||
|
String token = docApp.getToken();
|
||||||
|
// add doc
|
||||||
|
TornaDocDTO tornaDocDTO = tornaClient.execute("doc.list", null, token, TornaDocDTO.class);
|
||||||
|
List<TornaDocInfoDTO> docList = tornaDocDTO.getDocList();
|
||||||
|
|
||||||
|
if (!CollectionUtils.isEmpty(docList)) {
|
||||||
|
List<DocInfo> updateList = new ArrayList<>();
|
||||||
|
for (TornaDocInfoDTO tornaDocInfoDTO : docList) {
|
||||||
|
String key = tornaDocInfoDTO.getUrl() + ":" + tornaDocInfoDTO.getVersion();
|
||||||
|
DocInfo docInfo = nameVersionMap.get(key);
|
||||||
|
// 需要修改的文档
|
||||||
|
if (docInfo != null) {
|
||||||
|
docInfo.setDocId(tornaDocInfoDTO.getId());
|
||||||
|
docInfo.setDocTitle(tornaDocInfoDTO.getName());
|
||||||
|
docInfo.setDocCode("");
|
||||||
|
if (YesOrNoEnum.of(tornaDocInfoDTO.getIsFolder()) == YesOrNoEnum.YES) {
|
||||||
|
docInfo.setDocName(tornaDocInfoDTO.getName());
|
||||||
|
}
|
||||||
|
docInfo.setDocId(tornaDocInfoDTO.getId());
|
||||||
|
docInfo.setDocType(tornaDocInfoDTO.getType().intValue());
|
||||||
|
docInfo.setDescription(tornaDocInfoDTO.getDescription());
|
||||||
|
docInfo.setIsFolder(tornaDocInfoDTO.getIsFolder().intValue());
|
||||||
|
docInfo.setParentId(tornaDocInfoDTO.getParentId());
|
||||||
|
updateList.add(docInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (DocInfo docInfo : updateList) {
|
||||||
|
this.update(docInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增的文档
|
||||||
|
List<DocInfo> saveList = docList.stream()
|
||||||
|
.filter(tornaDocInfoDTO -> {
|
||||||
|
String key = tornaDocInfoDTO.getUrl() + ":" + tornaDocInfoDTO.getVersion();
|
||||||
|
return !nameVersionMap.containsKey(key);
|
||||||
|
})
|
||||||
|
.map(tornaDocInfoDTO -> {
|
||||||
|
DocInfo docInfo = new DocInfo();
|
||||||
|
docInfo.setDocAppId(docAppId);
|
||||||
|
docInfo.setDocId(tornaDocInfoDTO.getId());
|
||||||
|
docInfo.setDocTitle(tornaDocInfoDTO.getName());
|
||||||
|
docInfo.setDocCode("");
|
||||||
|
docInfo.setDocType(tornaDocInfoDTO.getType().intValue());
|
||||||
|
docInfo.setSourceType(DocSourceTypeEnum.TORNA.getValue());
|
||||||
|
if (YesOrNoEnum.of(tornaDocInfoDTO.getIsFolder()) == YesOrNoEnum.YES) {
|
||||||
|
docInfo.setDocName(tornaDocInfoDTO.getName());
|
||||||
|
} else {
|
||||||
|
docInfo.setDocName(tornaDocInfoDTO.getUrl());
|
||||||
|
}
|
||||||
|
docInfo.setDocVersion(tornaDocInfoDTO.getVersion());
|
||||||
|
docInfo.setDescription(tornaDocInfoDTO.getDescription());
|
||||||
|
docInfo.setIsFolder(tornaDocInfoDTO.getIsFolder().intValue());
|
||||||
|
docInfo.setIsPublish(YesOrNoEnum.NO.getValue());
|
||||||
|
docInfo.setParentId(tornaDocInfoDTO.getParentId());
|
||||||
|
return docInfo;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
this.saveBatch(saveList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -1,30 +1,27 @@
|
|||||||
package com.gitee.sop.adminbackend.service.doc;
|
package com.gitee.sop.adminbackend.service.doc;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.gitee.fastmybatis.core.util.TreeUtil;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import com.gitee.httphelper.HttpHelper;
|
|
||||||
import com.gitee.sop.adminbackend.common.enums.ConfigKeyEnum;
|
import com.gitee.sop.adminbackend.common.enums.ConfigKeyEnum;
|
||||||
import com.gitee.sop.adminbackend.common.exception.BizException;
|
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.mapper.DocAppMapper;
|
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.DocSettingDTO;
|
||||||
import com.gitee.sop.adminbackend.service.doc.dto.TornaModuleDTO;
|
import com.gitee.sop.adminbackend.service.doc.dto.TornaModuleDTO;
|
||||||
import com.gitee.sop.adminbackend.service.sys.SysConfigService;
|
import com.gitee.sop.adminbackend.service.sys.SysConfigService;
|
||||||
import com.gitee.sop.adminbackend.service.sys.dto.SystemConfigDTO;
|
import com.gitee.sop.adminbackend.service.sys.dto.SystemConfigDTO;
|
||||||
import java.io.IOException;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import java.time.LocalDateTime;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import com.gitee.sop.adminbackend.service.website.dto.DocAppDTO;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.util.ObjectUtils;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,10 +34,12 @@ public class DocService {
|
|||||||
private SysConfigService sysConfigService;
|
private SysConfigService sysConfigService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DocAppMapper docAppMapper;
|
private DocAppService docAppService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TornaClient tornaClient;
|
private TornaClient tornaClient;
|
||||||
|
@Autowired
|
||||||
|
private DocInfoService docInfoService;
|
||||||
|
|
||||||
public DocSettingDTO getDocSetting() {
|
public DocSettingDTO getDocSetting() {
|
||||||
DocSettingDTO docSettingDTO = new DocSettingDTO();
|
DocSettingDTO docSettingDTO = new DocSettingDTO();
|
||||||
@@ -58,21 +57,55 @@ public class DocService {
|
|||||||
sysConfigService.save(systemConfigDTOS);
|
sysConfigService.save(systemConfigDTOS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDocApp(String token) {
|
public Long addDocApp(String token) {
|
||||||
if (docAppMapper.checkExist(DocApp::getToken, token)) {
|
|
||||||
throw new BizException("该应用已添加");
|
|
||||||
}
|
|
||||||
TornaModuleDTO tornaModuleDTO = tornaClient.execute("module.get", null, token, TornaModuleDTO.class);
|
TornaModuleDTO tornaModuleDTO = tornaClient.execute("module.get", null, token, TornaModuleDTO.class);
|
||||||
DocApp docApp = new DocApp();
|
DocApp docApp = docAppService.get(DocApp::getToken, token);
|
||||||
docApp.setAppName(tornaModuleDTO.getName());
|
if (docApp == null) {
|
||||||
docApp.setToken(token);
|
docApp = new DocApp();
|
||||||
docAppMapper.saveIgnoreNull(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() {
|
public List<DocAppDTO> listDocApp() {
|
||||||
List<DocApp> docApps = docAppMapper.listAll();
|
List<DocApp> docApps = docAppService.listAll();
|
||||||
return CopyUtil.copyList(docApps, DocAppDTO::new);
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package com.gitee.sop.adminbackend.service.doc;
|
package com.gitee.sop.adminbackend.service.doc;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.gitee.httphelper.HttpHelper;
|
import com.gitee.httphelper.HttpHelper;
|
||||||
import com.gitee.sop.adminbackend.common.enums.ConfigKeyEnum;
|
import com.gitee.sop.adminbackend.common.enums.ConfigKeyEnum;
|
||||||
@@ -10,6 +11,7 @@ import org.springframework.util.ObjectUtils;
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,6 +21,16 @@ import java.util.Objects;
|
|||||||
public class TornaClient {
|
public class TornaClient {
|
||||||
|
|
||||||
public <T> T execute(String name, Object param, String token, Class<T> respClass) {
|
public <T> T execute(String name, Object param, String token, Class<T> respClass) {
|
||||||
|
JSONObject data = request(name, param, token).getJSONObject("data");
|
||||||
|
return data.toJavaObject(respClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> List<T> executeList(String name, Object param, String token, Class<T> respClass) {
|
||||||
|
JSONArray data = request(name, param, token).getJSONArray("data");
|
||||||
|
return data.toList(respClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject request(String name, Object param, String token) {
|
||||||
try {
|
try {
|
||||||
HttpHelper httpHelper = HttpHelper.get(getTornaApiUrl())
|
HttpHelper httpHelper = HttpHelper.get(getTornaApiUrl())
|
||||||
.parameter("name", name)
|
.parameter("name", name)
|
||||||
@@ -33,8 +45,7 @@ public class TornaClient {
|
|||||||
if (!Objects.equals("0", jsonObject.getString("code"))) {
|
if (!Objects.equals("0", jsonObject.getString("code"))) {
|
||||||
throw new BizException(jsonObject.getString("msg"));
|
throw new BizException(jsonObject.getString("msg"));
|
||||||
}
|
}
|
||||||
JSONObject data = jsonObject.getJSONObject("data");
|
return jsonObject;
|
||||||
return data.toJavaObject(respClass);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,7 @@
|
|||||||
package com.gitee.sop.adminbackend.service.website.dto;
|
package com.gitee.sop.adminbackend.service.doc.dto;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
import com.gitee.fastmybatis.annotation.Pk;
|
|
||||||
import com.gitee.fastmybatis.annotation.PkStrategy;
|
|
||||||
import com.gitee.fastmybatis.annotation.Table;
|
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
@@ -0,0 +1,18 @@
|
|||||||
|
package com.gitee.sop.adminbackend.service.doc.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 六如
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class DocInfoPublishUpdateDTO {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private Integer isPublish;
|
||||||
|
|
||||||
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
package com.gitee.sop.adminbackend.service.website.dto;
|
package com.gitee.sop.adminbackend.service.doc.dto;
|
||||||
|
|
||||||
import com.gitee.fastmybatis.core.support.TreeNode;
|
import com.gitee.fastmybatis.core.support.TreeNode;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -30,6 +30,11 @@ public class DocInfoTreeDTO implements TreeNode<DocInfoTreeDTO, Long> {
|
|||||||
*/
|
*/
|
||||||
private Long docId;
|
private Long docId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文档标题
|
||||||
|
*/
|
||||||
|
private String docTitle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文档code
|
* 文档code
|
||||||
*/
|
*/
|
||||||
@@ -50,6 +55,11 @@ public class DocInfoTreeDTO implements TreeNode<DocInfoTreeDTO, Long> {
|
|||||||
*/
|
*/
|
||||||
private String docName;
|
private String docName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本号
|
||||||
|
*/
|
||||||
|
private String docVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 描述
|
* 描述
|
||||||
*/
|
*/
|
||||||
@@ -95,7 +105,7 @@ public class DocInfoTreeDTO implements TreeNode<DocInfoTreeDTO, Long> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long takeId() {
|
public Long takeId() {
|
||||||
return id;
|
return docId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@@ -0,0 +1,15 @@
|
|||||||
|
package com.gitee.sop.adminbackend.service.doc.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 六如
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TornaDocDTO {
|
||||||
|
|
||||||
|
private List<TornaDocInfoDTO> docList;
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,62 @@
|
|||||||
|
package com.gitee.sop.adminbackend.service.doc.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TornaDocInfoDTO {
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文档名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文档概述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 访问URL
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本号
|
||||||
|
*/
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http方法
|
||||||
|
*/
|
||||||
|
private String httpMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* contentType
|
||||||
|
*/
|
||||||
|
private String contentType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文档类型,0:http,1:dubbo,2:富文本,3:Markdown
|
||||||
|
*/
|
||||||
|
private Byte type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是分类,0:不是,1:是
|
||||||
|
*/
|
||||||
|
private Byte isFolder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 父节点
|
||||||
|
*/
|
||||||
|
private Long parentId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示
|
||||||
|
*/
|
||||||
|
private Byte isShow;
|
||||||
|
|
||||||
|
}
|
@@ -100,7 +100,7 @@ public class IsvInfoService implements LambdaService<IsvInfo, IsvInfoMapper> {
|
|||||||
IsvInfo rec = CopyUtil.copyBean(isvInfoAddDTO, IsvInfo::new);
|
IsvInfo rec = CopyUtil.copyBean(isvInfoAddDTO, IsvInfo::new);
|
||||||
String appKey = new SimpleDateFormat("yyyyMMdd").format(new Date()) + IdGen.nextId();
|
String appKey = new SimpleDateFormat("yyyyMMdd").format(new Date()) + IdGen.nextId();
|
||||||
rec.setAppId(appKey);
|
rec.setAppId(appKey);
|
||||||
rec.setStatus(StatusEnum.ENABLE.getStatus());
|
rec.setStatus(StatusEnum.ENABLE.getValue());
|
||||||
this.save(rec);
|
this.save(rec);
|
||||||
this.sendChangeEvent(rec.getId());
|
this.sendChangeEvent(rec.getId());
|
||||||
return rec.getId();
|
return rec.getId();
|
||||||
|
@@ -122,7 +122,7 @@ public class LoginService {
|
|||||||
userInfo.setPassword(GenerateUtil.getUUID());
|
userInfo.setPassword(GenerateUtil.getUUID());
|
||||||
userInfo.setNickname(loginResult.getNickname());
|
userInfo.setNickname(loginResult.getNickname());
|
||||||
userInfo.setAvatar("");
|
userInfo.setAvatar("");
|
||||||
userInfo.setStatus(StatusEnum.ENABLE.getStatus());
|
userInfo.setStatus(StatusEnum.ENABLE.getValue());
|
||||||
userInfo.setRegType(loginResult.getRegTypeEnum().getValue());
|
userInfo.setRegType(loginResult.getRegTypeEnum().getValue());
|
||||||
userInfo.setEmail(loginResult.getEmail());
|
userInfo.setEmail(loginResult.getEmail());
|
||||||
sysAdminUserService.save(userInfo);
|
sysAdminUserService.save(userInfo);
|
||||||
|
@@ -75,7 +75,7 @@ public class DefaultUserCacheManager implements UserCacheManager, InitializingBe
|
|||||||
log.warn("登录用户不存在,userId:{}", id);
|
log.warn("登录用户不存在,userId:{}", id);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (userInfo.getStatus() == StatusEnum.DISABLED.getStatus()) {
|
if (userInfo.getStatus() == StatusEnum.DISABLED.getValue()) {
|
||||||
log.warn("用户被禁用, userId:{}, username:{}, nickname:{}", userInfo.getId(), userInfo.getUsername(), userInfo.getNickname());
|
log.warn("用户被禁用, userId:{}, username:{}, nickname:{}", userInfo.getId(), userInfo.getUsername(), userInfo.getNickname());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@@ -6,8 +6,8 @@ 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.website.dto.DocAppDTO;
|
import com.gitee.sop.adminbackend.service.doc.dto.DocAppDTO;
|
||||||
import com.gitee.sop.adminbackend.service.website.dto.DocInfoTreeDTO;
|
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.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@@ -48,6 +48,7 @@
|
|||||||
"url": "https://github.com/xiaoxian521"
|
"url": "https://github.com/xiaoxian521"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@element-plus/icons-vue": "^2.3.1",
|
||||||
"@pureadmin/descriptions": "1.2.1",
|
"@pureadmin/descriptions": "1.2.1",
|
||||||
"@pureadmin/table": "3.2.0",
|
"@pureadmin/table": "3.2.0",
|
||||||
"@pureadmin/utils": "2.4.8",
|
"@pureadmin/utils": "2.4.8",
|
||||||
|
3
sop-admin/sop-admin-frontend/pnpm-lock.yaml
generated
3
sop-admin/sop-admin-frontend/pnpm-lock.yaml
generated
@@ -8,6 +8,9 @@ importers:
|
|||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@element-plus/icons-vue':
|
||||||
|
specifier: ^2.3.1
|
||||||
|
version: 2.3.1(vue@3.4.38(typescript@5.5.4))
|
||||||
'@pureadmin/descriptions':
|
'@pureadmin/descriptions':
|
||||||
specifier: 1.2.1
|
specifier: 1.2.1
|
||||||
version: 1.2.1(echarts@5.5.1)(element-plus@2.8.0(vue@3.4.38(typescript@5.5.4)))(typescript@5.5.4)
|
version: 1.2.1(echarts@5.5.1)(element-plus@2.8.0(vue@3.4.38(typescript@5.5.4)))(typescript@5.5.4)
|
||||||
|
@@ -4,7 +4,9 @@ import type { Result } from "@/model";
|
|||||||
// 后端请求接口
|
// 后端请求接口
|
||||||
const apiUrl: any = createUrl({
|
const apiUrl: any = createUrl({
|
||||||
addApp: "/doc/app/add",
|
addApp: "/doc/app/add",
|
||||||
listApp: "/doc/app/list"
|
listApp: "/doc/app/list",
|
||||||
|
listDocTree: "/doc/info/tree",
|
||||||
|
publish: "/doc/info/publish"
|
||||||
});
|
});
|
||||||
|
|
||||||
interface DocApp {
|
interface DocApp {
|
||||||
@@ -28,5 +30,19 @@ 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 表单内容
|
||||||
|
*/
|
||||||
|
publish(data: object) {
|
||||||
|
return http.post<Result<any>, any>(apiUrl.publish, { data });
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 查询文档树
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
listDocTree(params: object) {
|
||||||
|
return http.get<Result<Array<any>>, any>(apiUrl.listDocTree, { params });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -75,3 +75,9 @@ getPlatformConfig(app).then(async config => {
|
|||||||
// .use(useEcharts);
|
// .use(useEcharts);
|
||||||
app.mount("#app");
|
app.mount("#app");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// element-plus icon
|
||||||
|
import * as ElementPlusIconsVue from "@element-plus/icons-vue";
|
||||||
|
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||||
|
app.component(key, component);
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,12 @@
|
|||||||
import { ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import { ElMessage, ElMessageBox } from "element-plus";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
import { api } from "@/api/doc";
|
import { api } from "@/api/doc";
|
||||||
|
import {
|
||||||
|
type ButtonsCallBackParams,
|
||||||
|
type PlusColumn,
|
||||||
|
useTable
|
||||||
|
} from "plus-pro-components";
|
||||||
|
import { YesOrNoEnum } from "@/model/enums";
|
||||||
|
|
||||||
export const tabsData = ref<Array<any>>([
|
export const tabsData = ref<Array<any>>([
|
||||||
{
|
{
|
||||||
@@ -10,9 +16,163 @@ export const tabsData = ref<Array<any>>([
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
export const activeName = ref(0);
|
export const activeName = ref(0);
|
||||||
|
const docAppId = ref(0);
|
||||||
|
|
||||||
|
// 表格对象
|
||||||
|
export const { tableData, buttons: actionButtons } = useTable<any[]>();
|
||||||
|
|
||||||
|
export const filterText = ref("");
|
||||||
|
|
||||||
|
export const tableRows = computed(() => {
|
||||||
|
let search = filterText.value;
|
||||||
|
if (!search) {
|
||||||
|
return tableData.value;
|
||||||
|
}
|
||||||
|
search = search.toLowerCase();
|
||||||
|
return searchRow(search, tableData.value, searchContent, isFolder);
|
||||||
|
});
|
||||||
|
|
||||||
|
const isFolder = row => {
|
||||||
|
return row.isFolder === 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchContent = (searchText, row) => {
|
||||||
|
return (
|
||||||
|
(row.docName && row.docName.toLowerCase().indexOf(searchText) > -1) ||
|
||||||
|
(row.docTitle && row.docTitle.toLowerCase().indexOf(searchText) > -1)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 表格字段定义
|
||||||
|
export const tableColumns: PlusColumn[] = [
|
||||||
|
{
|
||||||
|
label: "文档标题",
|
||||||
|
prop: "docTitle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "接口名",
|
||||||
|
prop: "docName"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "版本号",
|
||||||
|
prop: "docVersion"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "描述",
|
||||||
|
prop: "description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "发布状态",
|
||||||
|
prop: "isPublish",
|
||||||
|
valueType: "select",
|
||||||
|
width: 100,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: "已发布",
|
||||||
|
value: YesOrNoEnum.YES,
|
||||||
|
color: "green"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "未发布",
|
||||||
|
value: YesOrNoEnum.NO,
|
||||||
|
color: "red"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
renderHTML: (value, { row }) => {
|
||||||
|
if (row.isFolder) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
? `<div style="color:green;">已发布</div>`
|
||||||
|
: `<div style="color:gray;">未发布</div>`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 160,
|
||||||
|
label: "添加时间",
|
||||||
|
prop: "addTime"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 160,
|
||||||
|
label: "修改时间",
|
||||||
|
prop: "updateTime"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
// 表格按钮定义
|
||||||
|
actionButtons.value = [
|
||||||
|
{
|
||||||
|
text: row => (row.isPublish ? "下线" : "发布"),
|
||||||
|
confirm: {
|
||||||
|
options: { draggable: false },
|
||||||
|
popconfirmProps: { width: 300 },
|
||||||
|
message: params => {
|
||||||
|
const row = params.row;
|
||||||
|
const opt = row.isPublish ? "下线" : "发布";
|
||||||
|
const isFolder = row.isFolder;
|
||||||
|
return isFolder === 1
|
||||||
|
? `确定要${opt}[${row.docTitle}]下所有接口吗?`
|
||||||
|
: `确定要${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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "下线",
|
||||||
|
confirm: {
|
||||||
|
options: { draggable: false },
|
||||||
|
popconfirmProps: { width: 300 },
|
||||||
|
message: params => {
|
||||||
|
const row = params.row;
|
||||||
|
const opt = "下线";
|
||||||
|
return `确定要${opt}[${row.docTitle}]下所有接口吗?`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
type: "danger"
|
||||||
|
},
|
||||||
|
onConfirm(params: ButtonsCallBackParams) {
|
||||||
|
const data = {
|
||||||
|
id: params.row.id,
|
||||||
|
isPublish: 0
|
||||||
|
};
|
||||||
|
api.publish(data).then(() => {
|
||||||
|
ElMessage.success("下线成功");
|
||||||
|
search();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
show: (row: any) => row.isFolder === 1
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// 点击查询按钮
|
||||||
|
export const handleSearch = () => {
|
||||||
|
search();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查询
|
||||||
|
const search = async () => {
|
||||||
|
loadContent(docAppId.value);
|
||||||
|
};
|
||||||
|
|
||||||
export const handleClick = data => {
|
export const handleClick = data => {
|
||||||
const id = data.props.name;
|
const id = data.props.name;
|
||||||
|
activeTab(id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const activeTab = id => {
|
||||||
|
docAppId.value = id;
|
||||||
loadContent(id);
|
loadContent(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -27,30 +187,78 @@ export const handleAddApp = () => {
|
|||||||
const data = {
|
const data = {
|
||||||
tornaToken: value
|
tornaToken: value
|
||||||
};
|
};
|
||||||
api.addApp(data).then(() => {
|
api.addApp(data).then(resp => {
|
||||||
ElMessage.success("添加成功");
|
ElMessage.success("添加成功");
|
||||||
loadTabs(true);
|
loadTabs(resp.data);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadTabs = showLast => {
|
const loadTabs = docAppId => {
|
||||||
api.listApp().then(resp => {
|
api.listApp().then(resp => {
|
||||||
tabsData.value = resp.data;
|
tabsData.value = resp.data;
|
||||||
const length = tabsData.value.length;
|
const length = tabsData.value.length;
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
const showData = showLast
|
let targetId;
|
||||||
? tabsData.value[length - 1]
|
for (const id of tabsData.value) {
|
||||||
: tabsData.value[0];
|
if (id === docAppId) {
|
||||||
activeName.value = showData.id;
|
targetId = id;
|
||||||
loadContent(showData.id);
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!targetId) {
|
||||||
|
targetId = tabsData.value[0].id;
|
||||||
|
}
|
||||||
|
activeName.value = targetId;
|
||||||
|
activeTab(targetId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadContent = id => {
|
const searchRow = (search, rows, searchHandler, folderHandler) => {
|
||||||
console.log(id);
|
if (!folderHandler) {
|
||||||
|
folderHandler = isFolder;
|
||||||
|
}
|
||||||
|
const ret = [];
|
||||||
|
for (const row of rows) {
|
||||||
|
// 找到分类
|
||||||
|
if (folderHandler(row)) {
|
||||||
|
if (searchHandler(search, row)) {
|
||||||
|
ret.push(row);
|
||||||
|
} else {
|
||||||
|
// 分类名字没找到,需要从子文档中找
|
||||||
|
const children = row.children || [];
|
||||||
|
const searchedChildren = searchRow(
|
||||||
|
search,
|
||||||
|
children,
|
||||||
|
searchHandler,
|
||||||
|
folderHandler
|
||||||
|
);
|
||||||
|
// 如果子文档中有
|
||||||
|
if (searchedChildren && searchedChildren.length > 0) {
|
||||||
|
const rowCopy = Object.assign({}, row);
|
||||||
|
rowCopy.children = searchedChildren;
|
||||||
|
ret.push(rowCopy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 不是分类且被找到
|
||||||
|
if (searchHandler(search, row)) {
|
||||||
|
ret.push(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
loadTabs(false);
|
const loadContent = id => {
|
||||||
|
const data = {
|
||||||
|
docAppId: id
|
||||||
|
};
|
||||||
|
api.listDocTree(data).then(resp => {
|
||||||
|
tableData.value = resp.data;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
loadTabs(0);
|
||||||
|
@@ -1,14 +1,32 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { activeName, handleClick, handleAddApp, tabsData } from "./index";
|
import {
|
||||||
|
activeName,
|
||||||
|
handleClick,
|
||||||
|
handleAddApp,
|
||||||
|
tabsData,
|
||||||
|
actionButtons,
|
||||||
|
tableColumns,
|
||||||
|
tableRows,
|
||||||
|
filterText,
|
||||||
|
handleSearch
|
||||||
|
} from "./index";
|
||||||
|
import { Search } from "@element-plus/icons-vue";
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
|
<div v-show="tabsData.length === 0">
|
||||||
|
<el-button type="primary" @click="handleAddApp">添加应用</el-button>
|
||||||
|
</div>
|
||||||
<el-tabs
|
<el-tabs
|
||||||
v-show="tabsData.length > 0"
|
v-show="tabsData.length > 0"
|
||||||
v-model="activeName"
|
v-model="activeName"
|
||||||
type="card"
|
addable
|
||||||
@tab-click="handleClick"
|
@tab-click="handleClick"
|
||||||
|
@tab-add="handleAddApp"
|
||||||
>
|
>
|
||||||
|
<template #add-icon>
|
||||||
|
<el-icon style="font-size: 20px"><CirclePlusFilled /></el-icon>
|
||||||
|
</template>
|
||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
v-for="item in tabsData"
|
v-for="item in tabsData"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@@ -16,8 +34,29 @@ import { activeName, handleClick, handleAddApp, tabsData } from "./index";
|
|||||||
:name="item.id"
|
:name="item.id"
|
||||||
/>
|
/>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
<PlusTable
|
||||||
|
v-show="tabsData.length > 0"
|
||||||
|
:columns="tableColumns"
|
||||||
|
:table-data="tableRows"
|
||||||
|
:action-bar="{
|
||||||
|
buttons: actionButtons,
|
||||||
|
confirmType: 'popconfirm',
|
||||||
|
width: 120
|
||||||
|
}"
|
||||||
|
adaptive
|
||||||
|
>
|
||||||
|
<template #title>
|
||||||
|
<el-input
|
||||||
|
v-model="filterText"
|
||||||
|
type="text"
|
||||||
|
placeholder="过滤,支持接口标题,接口名称"
|
||||||
|
style="width: 300px"
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<el-button :icon="Search" @click="handleSearch" />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
</PlusTable>
|
||||||
</el-card>
|
</el-card>
|
||||||
<div v-show="tabsData.length === 0" style="margin: 20px">
|
|
||||||
<el-button type="primary" @click="handleAddApp">添加应用</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
32
sop-website/sop-website-frontend/src/api/doc.ts
Normal file
32
sop-website/sop-website-frontend/src/api/doc.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { createUrl, http } from "@/utils/http";
|
||||||
|
import type { Result } from "@/model";
|
||||||
|
|
||||||
|
// 后端请求接口
|
||||||
|
const apiUrl: any = createUrl({
|
||||||
|
listApp: "/website/listDocApp",
|
||||||
|
listDocTree: "/doc/info/tree"
|
||||||
|
});
|
||||||
|
|
||||||
|
interface DocApp {
|
||||||
|
id: number;
|
||||||
|
appName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口管理
|
||||||
|
*/
|
||||||
|
export const api: any = {
|
||||||
|
/**
|
||||||
|
* 分页查询
|
||||||
|
*/
|
||||||
|
listApp(): Promise<Result<Array<DocApp>>> {
|
||||||
|
return http.get<Result<Array<DocApp>>, any>(apiUrl.listApp, {});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 查询文档树
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
listDocTree(params: object) {
|
||||||
|
return http.get<Result<Array<any>>, any>(apiUrl.listDocTree, { params });
|
||||||
|
}
|
||||||
|
};
|
16
sop-website/sop-website-frontend/src/model/index.ts
Normal file
16
sop-website/sop-website-frontend/src/model/index.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
export interface Result<T> {
|
||||||
|
success: boolean;
|
||||||
|
data: T;
|
||||||
|
msg: "";
|
||||||
|
code: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PageResult {
|
||||||
|
success: boolean;
|
||||||
|
msg: "";
|
||||||
|
code: "";
|
||||||
|
data: {
|
||||||
|
total: 0;
|
||||||
|
list: Array<any>;
|
||||||
|
};
|
||||||
|
}
|
@@ -14,6 +14,24 @@ 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";
|
||||||
|
|
||||||
|
export const baseUrl = (url: string) => {
|
||||||
|
if (!url) {
|
||||||
|
throw new Error("url不能为空");
|
||||||
|
}
|
||||||
|
if (url.startsWith("/")) {
|
||||||
|
url = url.substring(1);
|
||||||
|
}
|
||||||
|
return `/api/${url}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createUrl = (data: object) => {
|
||||||
|
const ret = {};
|
||||||
|
for (const dataKey in data) {
|
||||||
|
ret[dataKey] = baseUrl(data[dataKey]);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
// 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1
|
// 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1
|
||||||
const defaultConfig: AxiosRequestConfig = {
|
const defaultConfig: AxiosRequestConfig = {
|
||||||
// 请求超时时间
|
// 请求超时时间
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
import { api as docApi } from "@/api/doc";
|
||||||
|
|
||||||
export const defaultActive = ref("overview.md");
|
export const defaultActive = ref("overview.md");
|
||||||
export const activeIndex = ref("1");
|
export const activeIndex = ref("1");
|
||||||
@@ -11,6 +12,10 @@ 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 docAppList = ref([]);
|
||||||
|
export const docTree = ref([]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
参数 类型 是否必填 最大长度 描述 示例值
|
参数 类型 是否必填 最大长度 描述 示例值
|
||||||
app_id String 是 32 支付宝分配给开发者的应用ID 2014072300007148
|
app_id String 是 32 支付宝分配给开发者的应用ID 2014072300007148
|
||||||
@@ -152,3 +157,32 @@ export function loadMarkdown(path) {
|
|||||||
contentShow.value = true;
|
contentShow.value = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function handleChangeDocApp(id) {
|
||||||
|
loadDocTree(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function handleNodeClick(node) {
|
||||||
|
console.log(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadDocApp() {
|
||||||
|
docApi.listApp().then(resp => {
|
||||||
|
docAppList.value = resp.data;
|
||||||
|
if (docAppList.value.length > 0) {
|
||||||
|
loadDocTree(docAppList.value[0].id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadDocTree(id) {
|
||||||
|
docAppId.value = id;
|
||||||
|
const params = {
|
||||||
|
docAppId: id
|
||||||
|
};
|
||||||
|
docApi.listDocTree(params).then(resp => {
|
||||||
|
docTree.value = resp.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadDocApp();
|
||||||
|
@@ -12,15 +12,45 @@ import {
|
|||||||
responseParamsExample,
|
responseParamsExample,
|
||||||
dataNodeType,
|
dataNodeType,
|
||||||
resultData,
|
resultData,
|
||||||
onMenuClick
|
onMenuClick,
|
||||||
|
handleChangeDocApp,
|
||||||
|
docAppId,
|
||||||
|
docAppList,
|
||||||
|
docTree,
|
||||||
|
handleNodeClick
|
||||||
} from "./index";
|
} from "./index";
|
||||||
import { ApiParamTable } from "@/components/ApiParamTable";
|
import { ApiParamTable } from "@/components/ApiParamTable";
|
||||||
import MavonEditor from "mavon-editor";
|
import MavonEditor from "mavon-editor";
|
||||||
|
const defaultProps = {
|
||||||
|
children: "children",
|
||||||
|
label: "docTitle"
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<el-container>
|
<el-container>
|
||||||
<el-aside width="300px">left</el-aside>
|
<el-aside width="300px">
|
||||||
<el-main>
|
<el-select
|
||||||
|
v-show="docAppId > 0"
|
||||||
|
v-model="docAppId"
|
||||||
|
placeholder="Select"
|
||||||
|
size="large"
|
||||||
|
@change="handleChangeDocApp"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in docAppList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.appName"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
<el-tree
|
||||||
|
:data="docTree"
|
||||||
|
:props="defaultProps"
|
||||||
|
style="margin-top: 20px"
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
/>
|
||||||
|
</el-aside>
|
||||||
|
<el-main style="padding-top: 0">
|
||||||
<div v-show="contentShow">
|
<div v-show="contentShow">
|
||||||
<MavonEditor
|
<MavonEditor
|
||||||
v-model="content"
|
v-model="content"
|
||||||
|
@@ -24,7 +24,14 @@ export default ({ mode }: ConfigEnv): UserConfigExport => {
|
|||||||
port: VITE_PORT,
|
port: VITE_PORT,
|
||||||
host: "0.0.0.0",
|
host: "0.0.0.0",
|
||||||
// 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
|
// 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
|
||||||
proxy: {},
|
proxy: {
|
||||||
|
"/api": {
|
||||||
|
// 这里填写后端地址
|
||||||
|
target: "http://127.0.0.1:8082",
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: path => path.replace(/^\/api/, "")
|
||||||
|
}
|
||||||
|
},
|
||||||
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
|
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
|
||||||
warmup: {
|
warmup: {
|
||||||
clientFiles: ["./index.html", "./src/{views,components}/*"]
|
clientFiles: ["./index.html", "./src/{views,components}/*"]
|
||||||
|
Reference in New Issue
Block a user