mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
5.0
This commit is contained in:
44
sop-admin/sop-admin-backend/admin-service/pom.xml
Executable file
44
sop-admin/sop-admin-backend/admin-service/pom.xml
Executable file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-admin-backend</artifactId>
|
||||
<version>5.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>admin-service</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>admin-common</artifactId>
|
||||
<version>5.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>admin-dao</artifactId>
|
||||
<version>5.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@@ -0,0 +1,52 @@
|
||||
package com.gitee.sop.admin.service.doc;
|
||||
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.common.user.User;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.dao.entity.DocApp;
|
||||
import com.gitee.sop.admin.dao.mapper.DocAppMapper;
|
||||
import com.gitee.sop.admin.service.doc.dto.DocAppDTO;
|
||||
import com.gitee.sop.admin.service.doc.dto.torna.TornaModuleDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class DocAppService implements ServiceSupport<DocApp, DocAppMapper> {
|
||||
|
||||
@Autowired
|
||||
private TornaClient tornaClient;
|
||||
|
||||
@Autowired
|
||||
private DocInfoService docInfoService;
|
||||
@Autowired
|
||||
private DocInfoSyncService docInfoSyncService;
|
||||
|
||||
public Long addDocApp(String token, User user) {
|
||||
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);
|
||||
}
|
||||
// 同步文档
|
||||
docInfoSyncService.syncDocInfo(docApp, null, user);
|
||||
return docApp.getId();
|
||||
}
|
||||
|
||||
public List<DocAppDTO> listDocApp() {
|
||||
List<DocApp> docApps = this.listAll();
|
||||
return CopyUtil.copyList(docApps, DocAppDTO::new);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
package com.gitee.sop.admin.service.doc;
|
||||
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.dao.entity.DocContent;
|
||||
import com.gitee.sop.admin.dao.mapper.DocContentMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class DocContentService implements ServiceSupport<DocContent, DocContentMapper> {
|
||||
|
||||
public void saveContent(Long docInfoId, String content) {
|
||||
DocContent docContent = this.get(DocContent::getDocInfoId, docInfoId);
|
||||
boolean save = false;
|
||||
if (docContent == null) {
|
||||
save = true;
|
||||
docContent = new DocContent();
|
||||
}
|
||||
docContent.setDocInfoId(docInfoId);
|
||||
docContent.setContent(content);
|
||||
if (save) {
|
||||
this.save(docContent);
|
||||
} else {
|
||||
this.update(docContent);
|
||||
}
|
||||
}
|
||||
|
||||
public String getContent(Long docInfoId) {
|
||||
return this.query()
|
||||
.eq(DocContent::getDocInfoId, docInfoId)
|
||||
.getValueOptional(DocContent::getContent)
|
||||
.orElse("");
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,115 @@
|
||||
package com.gitee.sop.admin.service.doc;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.gitee.fastmybatis.core.util.TreeUtil;
|
||||
import com.gitee.sop.admin.common.constants.YesOrNo;
|
||||
import com.gitee.sop.admin.common.exception.BizException;
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.dao.entity.DocApp;
|
||||
import com.gitee.sop.admin.dao.entity.DocInfo;
|
||||
import com.gitee.sop.admin.dao.mapper.DocAppMapper;
|
||||
import com.gitee.sop.admin.dao.mapper.DocInfoMapper;
|
||||
import com.gitee.sop.admin.service.doc.dto.DocInfoPublishUpdateDTO;
|
||||
import com.gitee.sop.admin.service.doc.dto.DocInfoTreeDTO;
|
||||
import com.gitee.sop.admin.service.doc.dto.torna.TornaDocInfoViewDTO;
|
||||
import com.gitee.sop.admin.service.sys.SysUserService;
|
||||
import com.google.common.collect.Lists;
|
||||
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.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class DocInfoService implements ServiceSupport<DocInfo, DocInfoMapper> {
|
||||
|
||||
@Autowired
|
||||
private DocAppMapper docAppMapper;
|
||||
@Autowired
|
||||
private DocContentService docContentService;
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
|
||||
public List<DocInfo> listChildDoc(Long parentId) {
|
||||
return this.list(DocInfo::getParentId, parentId);
|
||||
}
|
||||
|
||||
public List<DocInfoTreeDTO> listDocTree(Long docAppId) {
|
||||
List<DocInfo> list = this.list(DocInfo::getDocAppId, docAppId);
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
Set<Long> userIds = list.stream().flatMap(docInfo -> Lists.newArrayList(docInfo.getAddBy(), docInfo.getUpdateBy()).stream())
|
||||
.filter(val -> val != null && val > 0)
|
||||
.collect(Collectors.toSet());
|
||||
List<DocInfoTreeDTO> docInfoTreeDTOS = CopyUtil.copyList(list, DocInfoTreeDTO::new);
|
||||
sysUserService.fillShowName(docInfoTreeDTOS);
|
||||
return TreeUtil.convertTree(docInfoTreeDTOS, 0L);
|
||||
}
|
||||
|
||||
public int publish(DocInfoPublishUpdateDTO docInfoUpdateDTO) {
|
||||
DocInfo docInfo = this.getById(docInfoUpdateDTO.getId());
|
||||
Integer isPublish = docInfoUpdateDTO.getIsPublish();
|
||||
|
||||
// 如果是文件夹,发布下面所有的文档
|
||||
int i;
|
||||
if (YesOrNo.yes(docInfo.getIsFolder())) {
|
||||
List<DocInfo> children = this.listChildDoc(docInfo.getDocId());
|
||||
Set<Long> ids = children.stream().map(DocInfo::getId).collect(Collectors.toSet());
|
||||
i = this.query()
|
||||
.in(DocInfo::getId, ids)
|
||||
.set(DocInfo::getIsPublish, isPublish)
|
||||
.update();
|
||||
} else {
|
||||
// 发布单个文档
|
||||
i = this.query()
|
||||
.eq(DocInfo::getId, docInfoUpdateDTO.getId())
|
||||
.set(DocInfo::getIsPublish, isPublish)
|
||||
.update();
|
||||
}
|
||||
|
||||
// 发布一个接口自动发布所属应用
|
||||
Long docAppId = docInfo.getDocAppId();
|
||||
if (YesOrNo.yes(isPublish)) {
|
||||
docAppMapper.query()
|
||||
.eq(DocApp::getId, docAppId)
|
||||
.set(DocApp::getIsPublish, isPublish)
|
||||
.update();
|
||||
} else {
|
||||
// 如果应用下的接口都未发布,应用也改成未发布
|
||||
long count = this.query()
|
||||
.eq(DocInfo::getDocAppId, docAppId)
|
||||
.eq(DocInfo::getIsFolder, YesOrNo.NO)
|
||||
.eq(DocInfo::getIsPublish, YesOrNo.YES)
|
||||
.getCount();
|
||||
if (count == 0) {
|
||||
docAppMapper.query()
|
||||
.eq(DocApp::getId, docAppId)
|
||||
.set(DocApp::getIsPublish, YesOrNo.NO)
|
||||
.update();
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
public TornaDocInfoViewDTO getDocDetail(Long id) {
|
||||
DocInfo docInfo = this.getById(id);
|
||||
if (docInfo == null || !YesOrNo.yes(docInfo.getIsPublish())) {
|
||||
throw new BizException("文档不存在");
|
||||
}
|
||||
String content = docContentService.getContent(docInfo.getId());
|
||||
return JSON.parseObject(content, TornaDocInfoViewDTO.class);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,222 @@
|
||||
package com.gitee.sop.admin.service.doc;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.gitee.fastmybatis.core.util.TreeUtil;
|
||||
import com.gitee.sop.admin.common.constants.YesOrNo;
|
||||
import com.gitee.sop.admin.common.enums.DocSourceTypeEnum;
|
||||
import com.gitee.sop.admin.common.user.User;
|
||||
import com.gitee.sop.admin.dao.entity.DocApp;
|
||||
import com.gitee.sop.admin.dao.entity.DocInfo;
|
||||
import com.gitee.sop.admin.dao.mapper.DocAppMapper;
|
||||
import com.gitee.sop.admin.service.doc.dto.torna.DocIdParam;
|
||||
import com.gitee.sop.admin.service.doc.dto.torna.DocIdsParam;
|
||||
import com.gitee.sop.admin.service.doc.dto.torna.TornaDocDTO;
|
||||
import com.gitee.sop.admin.service.doc.dto.torna.TornaDocInfoDTO;
|
||||
import com.gitee.sop.admin.service.doc.dto.torna.TornaDocInfoViewDTO;
|
||||
import com.gitee.sop.admin.service.doc.dto.torna.TornaDocParamDTO;
|
||||
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.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 接口信息同步
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class DocInfoSyncService {
|
||||
|
||||
@Autowired
|
||||
private TornaClient tornaClient;
|
||||
@Autowired
|
||||
private DocAppMapper docAppMapper;
|
||||
@Autowired
|
||||
private DocInfoService docInfoService;
|
||||
@Autowired
|
||||
private DocContentService docContentService;
|
||||
|
||||
public void syncAppDoc(Long docAppId, User user) {
|
||||
DocApp docApp = docAppMapper.getById(docAppId);
|
||||
this.syncDocInfo(docApp, null, user);
|
||||
}
|
||||
|
||||
public void syncDoc(Long docInfoId, User user) {
|
||||
DocInfo docInfo = docInfoService.getById(docInfoId);
|
||||
DocApp docApp = docAppMapper.getById(docInfo.getDocAppId());
|
||||
this.syncDocInfo(docApp, docInfoId, user);
|
||||
}
|
||||
|
||||
public void syncDocInfo(DocApp docApp, Long docInfoId, User user) {
|
||||
Long docAppId = docApp.getId();
|
||||
Map<String, DocInfo> nameVersionMap = docInfoService.list(DocInfo::getDocAppId, docAppId)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(docInfo -> docInfo.getDocName() + ":" + docInfo.getDocVersion(), Function.identity(), (v1, v2) -> v2));
|
||||
|
||||
String token = docApp.getToken();
|
||||
// add doc
|
||||
DocIdsParam docIdsParam = buildSearchParam(docInfoId);
|
||||
TornaDocDTO tornaDocDTO = tornaClient.execute("doc.list", docIdsParam, token, TornaDocDTO.class);
|
||||
List<TornaDocInfoDTO> docList = tornaDocDTO.getDocList();
|
||||
if (CollectionUtils.isEmpty(docList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<DocInfo> updateList = new ArrayList<>();
|
||||
for (TornaDocInfoDTO tornaDocInfoDTO : docList) {
|
||||
String key = buildKey(tornaDocInfoDTO);
|
||||
DocInfo docInfo = nameVersionMap.get(key);
|
||||
// 需要修改的文档
|
||||
if (docInfo != null) {
|
||||
docInfo.setDocId(tornaDocInfoDTO.getId());
|
||||
docInfo.setDocTitle(tornaDocInfoDTO.getName());
|
||||
docInfo.setDocCode("");
|
||||
if (YesOrNo.yes(tornaDocInfoDTO.getIsFolder())) {
|
||||
docInfo.setIsPublish(YesOrNo.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());
|
||||
docInfo.setUpdateBy(user.getUserId());
|
||||
updateList.add(docInfo);
|
||||
}
|
||||
}
|
||||
for (DocInfo docInfo : updateList) {
|
||||
docInfoService.update(docInfo);
|
||||
}
|
||||
|
||||
// 新增的文档
|
||||
List<DocInfo> saveList = docList.stream()
|
||||
.filter(tornaDocInfoDTO -> {
|
||||
String key = buildKey(tornaDocInfoDTO);
|
||||
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 (YesOrNo.yes(tornaDocInfoDTO.getIsFolder())) {
|
||||
docInfo.setIsPublish(YesOrNo.YES);
|
||||
docInfo.setDocName(tornaDocInfoDTO.getName());
|
||||
} else {
|
||||
docInfo.setIsPublish(YesOrNo.NO);
|
||||
docInfo.setDocName(tornaDocInfoDTO.getUrl());
|
||||
}
|
||||
docInfo.setDocVersion(tornaDocInfoDTO.getVersion());
|
||||
docInfo.setDescription(tornaDocInfoDTO.getDescription());
|
||||
docInfo.setIsFolder(tornaDocInfoDTO.getIsFolder().intValue());
|
||||
docInfo.setParentId(tornaDocInfoDTO.getParentId());
|
||||
docInfo.setAddBy(user.getUserId());
|
||||
return docInfo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
docInfoService.saveBatch(saveList);
|
||||
|
||||
Set<Long> docIds = docList.stream().map(TornaDocInfoDTO::getId).collect(Collectors.toSet());
|
||||
this.syncContent(docApp, docIds);
|
||||
}
|
||||
|
||||
private void syncContent(DocApp docApp, Set<Long> docIds) {
|
||||
List<DocInfo> list = docInfoService.query()
|
||||
.eq(DocInfo::getDocAppId, docApp.getId())
|
||||
.in(DocInfo::getDocId, docIds)
|
||||
.list();
|
||||
|
||||
Map<Long, String> docIdMap = this.getContentMap(docApp.getToken(), docIds);
|
||||
for (DocInfo docInfo : list) {
|
||||
String content = docIdMap.getOrDefault(docInfo.getDocId(), "");
|
||||
docContentService.saveContent(
|
||||
docInfo.getId(),
|
||||
content
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量获取Torna文档内容
|
||||
*
|
||||
* @param token token
|
||||
* @param docIds Torna文档id
|
||||
* @return key:文档id, value:文档内容
|
||||
*/
|
||||
private Map<Long, String> getContentMap(String token, Collection<Long> docIds) {
|
||||
// 获取torna文档信息
|
||||
List<TornaDocInfoViewDTO> tornaDocInfoViewList = tornaClient.executeList(
|
||||
"doc.details",
|
||||
new DocIdsParam(docIds),
|
||||
token,
|
||||
TornaDocInfoViewDTO.class
|
||||
);
|
||||
for (TornaDocInfoViewDTO docInfoViewDTO : tornaDocInfoViewList) {
|
||||
convertTree(docInfoViewDTO);
|
||||
}
|
||||
return tornaDocInfoViewList.stream()
|
||||
.collect(Collectors.toMap(TornaDocInfoViewDTO::getId, JSON::toJSONString, (v1, v2) -> v1));
|
||||
}
|
||||
|
||||
private String getContent(String token, Long docId) {
|
||||
// 获取torna文档信息
|
||||
TornaDocInfoViewDTO tornaDocInfoViewDTO = tornaClient.execute(
|
||||
"doc.detail",
|
||||
new DocIdParam(docId),
|
||||
token,
|
||||
TornaDocInfoViewDTO.class
|
||||
);
|
||||
convertTree(tornaDocInfoViewDTO);
|
||||
return JSON.toJSONString(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);
|
||||
}
|
||||
|
||||
private DocIdsParam buildSearchParam(Long docInfoId) {
|
||||
if (docInfoId == null) {
|
||||
return null;
|
||||
}
|
||||
DocIdsParam docIdsParam = new DocIdsParam();
|
||||
DocInfo docInfo = docInfoService.getById(docInfoId);
|
||||
List<Long> docIdList = new ArrayList<>();
|
||||
docIdList.add(docInfo.getDocId());
|
||||
// 如果是文件夹,找下面的子文档
|
||||
if (YesOrNo.yes(docInfo.getIsFolder())) {
|
||||
List<Long> docIds = this.listChildrenDocId(docInfo.getDocId());
|
||||
docIdList.addAll(docIds);
|
||||
}
|
||||
docIdsParam.setDocIds(docIdList);
|
||||
return docIdsParam;
|
||||
}
|
||||
|
||||
private List<Long> listChildrenDocId(Long parentId) {
|
||||
return docInfoService.query()
|
||||
.eq(DocInfo::getParentId, parentId)
|
||||
.listValue(DocInfo::getDocId);
|
||||
}
|
||||
|
||||
private String buildKey(TornaDocInfoDTO tornaDocInfoDTO) {
|
||||
return YesOrNo.yes(tornaDocInfoDTO.getIsFolder()) ?
|
||||
tornaDocInfoDTO.getName() + ":" + tornaDocInfoDTO.getVersion()
|
||||
: tornaDocInfoDTO.getUrl() + ":" + tornaDocInfoDTO.getVersion();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
package com.gitee.sop.admin.service.doc;
|
||||
|
||||
import com.gitee.sop.admin.common.enums.ConfigKeyEnum;
|
||||
import com.gitee.sop.admin.service.doc.dto.DocSettingDTO;
|
||||
import com.gitee.sop.admin.service.sys.SysConfigService;
|
||||
import com.gitee.sop.admin.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);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
package com.gitee.sop.admin.service.doc;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.gitee.httphelper.HttpHelper;
|
||||
import com.gitee.sop.admin.common.enums.ConfigKeyEnum;
|
||||
import com.gitee.sop.admin.common.exception.BizException;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Component
|
||||
public class TornaClient {
|
||||
|
||||
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) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("name", name);
|
||||
params.put("access_token", token);
|
||||
if (param != null) {
|
||||
String json = JSON.toJSONString(param);
|
||||
params.put("data", UriUtils.encode(json, StandardCharsets.UTF_8));
|
||||
}
|
||||
try {
|
||||
String body = HttpHelper.postJson(getTornaApiUrl(), JSON.toJSONString(params))
|
||||
.execute()
|
||||
.asString();
|
||||
JSONObject jsonObject = JSON.parseObject(body);
|
||||
if (!Objects.equals("0", jsonObject.getString("code"))) {
|
||||
throw new BizException(jsonObject.getString("msg"));
|
||||
}
|
||||
return jsonObject;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getTornaApiUrl() {
|
||||
String value = ConfigKeyEnum.TORNA_SERVER_ADDR.getValue();
|
||||
if (ObjectUtils.isEmpty(value)) {
|
||||
throw new BizException("Torna服务器地址未配置");
|
||||
}
|
||||
return StringUtils.trimTrailingCharacter(value, '/') + "/api";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
package com.gitee.sop.admin.service.doc.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
|
||||
/**
|
||||
* 备注:文档应用
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class DocAppDTO {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 应用名称
|
||||
*/
|
||||
private String appName;
|
||||
|
||||
/**
|
||||
* Torna应用token
|
||||
*/
|
||||
private String token;
|
||||
|
||||
/**
|
||||
* 添加时间
|
||||
*/
|
||||
private LocalDateTime addTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 创建人id
|
||||
*/
|
||||
private Long addBy;
|
||||
|
||||
/**
|
||||
* 修改人id
|
||||
*/
|
||||
private Long updateBy;
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package com.gitee.sop.admin.service.doc.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class DocInfoConfigDTO {
|
||||
|
||||
private String openProdUrl;
|
||||
private String openSandboxUrl;
|
||||
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package com.gitee.sop.admin.service.doc.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class DocInfoPublishUpdateDTO {
|
||||
|
||||
@NotNull
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 1-发布,0-下线
|
||||
*/
|
||||
private Integer isPublish;
|
||||
|
||||
}
|
@@ -0,0 +1,107 @@
|
||||
package com.gitee.sop.admin.service.doc.dto;
|
||||
|
||||
import com.gitee.fastmybatis.core.support.TreeNode;
|
||||
import com.gitee.sop.admin.common.dto.UserDTO;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 备注:文档信息
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class DocInfoTreeDTO extends UserDTO implements TreeNode<DocInfoTreeDTO, Long> {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* doc_app.id
|
||||
*/
|
||||
private Long docAppId;
|
||||
|
||||
/**
|
||||
* 文档id
|
||||
*/
|
||||
private Long docId;
|
||||
|
||||
/**
|
||||
* 文档标题
|
||||
*/
|
||||
private String docTitle;
|
||||
|
||||
/**
|
||||
* 文档code
|
||||
*/
|
||||
private String docCode;
|
||||
|
||||
/**
|
||||
* 文档类型,1-dubbo,2-富文本,3-Markdown
|
||||
*/
|
||||
private Integer docType;
|
||||
|
||||
/**
|
||||
* 来源类型,1-torna,2-自建
|
||||
*/
|
||||
private Integer sourceType;
|
||||
|
||||
/**
|
||||
* 文档名称
|
||||
*/
|
||||
private String docName;
|
||||
|
||||
/**
|
||||
* 版本号
|
||||
*/
|
||||
private String docVersion;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 是否分类
|
||||
*/
|
||||
private Integer isFolder;
|
||||
|
||||
/**
|
||||
* 状态, 0-未发布,1-已发布
|
||||
*/
|
||||
private Integer isPublish;
|
||||
|
||||
/**
|
||||
* 父节点id
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 添加时间
|
||||
*/
|
||||
private LocalDateTime addTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
private List<DocInfoTreeDTO> children;
|
||||
|
||||
|
||||
@Override
|
||||
public Long takeId() {
|
||||
return docId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long takeParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
package com.gitee.sop.admin.service.doc.dto;
|
||||
|
||||
import com.gitee.sop.admin.service.doc.dto.torna.TornaDocInfoViewDTO;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class DocInfoViewDTO {
|
||||
|
||||
private TornaDocInfoViewDTO docInfoView;
|
||||
|
||||
private DocInfoConfigDTO docInfoConfig;
|
||||
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package com.gitee.sop.admin.service.doc.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class DocSettingDTO {
|
||||
|
||||
@Length(max = 256)
|
||||
private String tornaServerAddr;
|
||||
@Length(max = 256)
|
||||
private String openProdUrl;
|
||||
@Length(max = 256)
|
||||
private String openSandboxUrl;
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
package com.gitee.sop.admin.service.doc.dto.torna;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class DocIdParam {
|
||||
|
||||
private Long docId;
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package com.gitee.sop.admin.service.doc.dto.torna;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class DocIdsParam {
|
||||
|
||||
@NotNull
|
||||
private Collection<Long> docIds;
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
package com.gitee.sop.admin.service.doc.dto.torna;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class TornaDocDTO {
|
||||
|
||||
private List<TornaDocInfoDTO> docList;
|
||||
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
package com.gitee.sop.admin.service.doc.dto.torna;
|
||||
|
||||
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;
|
||||
|
||||
}
|
@@ -0,0 +1,178 @@
|
||||
package com.gitee.sop.admin.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,2:富文本,3:Markdown
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* 模块id,module.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;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,128 @@
|
||||
package com.gitee.sop.admin.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;
|
||||
|
||||
/**
|
||||
* 是否必须,1:是,0:否
|
||||
*/
|
||||
|
||||
private Byte required;
|
||||
|
||||
/**
|
||||
* 最大长度
|
||||
*/
|
||||
|
||||
private String maxLength;
|
||||
|
||||
/**
|
||||
* 示例值
|
||||
*/
|
||||
private String example;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
|
||||
private String description;
|
||||
|
||||
|
||||
private Long enumId;
|
||||
|
||||
/**
|
||||
* doc_info.id
|
||||
*/
|
||||
|
||||
private Long docId;
|
||||
|
||||
/**
|
||||
* 父节点
|
||||
*/
|
||||
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 0:header, 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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
package com.gitee.sop.admin.service.doc.dto.torna;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class TornaModuleDTO {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
}
|
@@ -0,0 +1,166 @@
|
||||
package com.gitee.sop.admin.service.isv;
|
||||
|
||||
import com.gitee.fastmybatis.core.PageInfo;
|
||||
import com.gitee.fastmybatis.core.query.LambdaQuery;
|
||||
import com.gitee.sop.admin.common.constants.YesOrNo;
|
||||
import com.gitee.sop.admin.common.context.SpringContext;
|
||||
import com.gitee.sop.admin.common.dto.StatusUpdateDTO;
|
||||
import com.gitee.sop.admin.common.enums.StatusEnum;
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.common.util.IdGen;
|
||||
import com.gitee.sop.admin.common.util.RSATool;
|
||||
import com.gitee.sop.admin.dao.entity.IsvInfo;
|
||||
import com.gitee.sop.admin.dao.entity.IsvKeys;
|
||||
import com.gitee.sop.admin.dao.mapper.IsvInfoMapper;
|
||||
import com.gitee.sop.admin.service.isv.dto.IsvInfoAddDTO;
|
||||
import com.gitee.sop.admin.service.isv.dto.IsvInfoDTO;
|
||||
import com.gitee.sop.admin.service.isv.dto.IsvInfoUpdateDTO;
|
||||
import com.gitee.sop.admin.service.isv.dto.IsvInfoUpdateKeysDTO;
|
||||
import com.gitee.sop.admin.service.isv.dto.IsvKeysDTO;
|
||||
import com.gitee.sop.admin.service.isv.event.ChangeIsvInfoEvent;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class IsvInfoService implements ServiceSupport<IsvInfo, IsvInfoMapper> {
|
||||
|
||||
@Autowired
|
||||
private IsvKeysService isvKeysService;
|
||||
@Autowired
|
||||
private PermIsvGroupService permIsvGroupService;
|
||||
|
||||
public PageInfo<IsvInfoDTO> doPage(LambdaQuery<IsvInfo> query) {
|
||||
query.orderByDesc(IsvInfo::getId);
|
||||
PageInfo<IsvInfo> page = this.page(query);
|
||||
List<IsvInfo> list = page.getList();
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return page.convert(isvInfo -> new IsvInfoDTO());
|
||||
}
|
||||
List<Long> idList = list.stream()
|
||||
.map(IsvInfo::getId).collect(Collectors.toList());
|
||||
|
||||
Map<Long, IsvKeys> isvIdMap = isvKeysService.query()
|
||||
.in(IsvKeys::getIsvId, idList)
|
||||
.map(IsvKeys::getIsvId, Function.identity());
|
||||
|
||||
Map<Long, List<String>> isvGroupMap = permIsvGroupService.getIsvGroupNameMap(idList);
|
||||
|
||||
// 格式转换
|
||||
return page.convert(isvInfo -> {
|
||||
IsvInfoDTO isvInfoDTO = CopyUtil.copyBean(isvInfo, IsvInfoDTO::new);
|
||||
boolean hasKey = false;
|
||||
Optional<IsvKeys> isvKeysOpt = Optional.ofNullable(isvIdMap.get(isvInfo.getId()));
|
||||
if (isvKeysOpt.isPresent()) {
|
||||
IsvKeys isvKeys = isvKeysOpt.get();
|
||||
hasKey = !StringUtils.isAllBlank(
|
||||
isvKeys.getPrivateKeyIsv(),
|
||||
isvKeys.getPrivateKeyPlatform(),
|
||||
isvKeys.getPublicKeyIsv(),
|
||||
isvKeys.getPublicKeyPlatform()
|
||||
);
|
||||
}
|
||||
isvInfoDTO.setHasKeys(YesOrNo.of(hasKey));
|
||||
List<String> groupNames = isvGroupMap.getOrDefault(isvInfo.getId(), Collections.emptyList());
|
||||
isvInfoDTO.setGroupNames(String.join("/", groupNames));
|
||||
return isvInfoDTO;
|
||||
});
|
||||
}
|
||||
|
||||
public RSATool.KeyStore createKeys(RSATool.KeyFormat keyFormat) throws Exception {
|
||||
if (keyFormat == null) {
|
||||
keyFormat = RSATool.KeyFormat.PKCS8;
|
||||
}
|
||||
RSATool rsaTool = new RSATool(keyFormat, RSATool.KeyLength.LENGTH_2048);
|
||||
return rsaTool.createKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加ISV
|
||||
*
|
||||
* @param isvInfoAddDTO
|
||||
* @return 返回id
|
||||
*/
|
||||
public long add(IsvInfoAddDTO isvInfoAddDTO) {
|
||||
IsvInfo rec = CopyUtil.copyBean(isvInfoAddDTO, IsvInfo::new);
|
||||
String appKey = new SimpleDateFormat("yyyyMMdd").format(new Date()) + IdGen.nextId();
|
||||
rec.setAppId(appKey);
|
||||
rec.setStatus(StatusEnum.ENABLE.getValue());
|
||||
this.save(rec);
|
||||
this.sendChangeEvent(rec.getId());
|
||||
return rec.getId();
|
||||
}
|
||||
|
||||
public int update(IsvInfoUpdateDTO isvInfoUpdateDTO) {
|
||||
IsvInfo isvInfo = new IsvInfo();
|
||||
isvInfo.setId(isvInfoUpdateDTO.getId());
|
||||
isvInfo.setStatus(isvInfoUpdateDTO.getStatus());
|
||||
isvInfo.setRemark(isvInfoUpdateDTO.getRemark());
|
||||
int cnt = this.update(isvInfo);
|
||||
sendChangeEvent(isvInfoUpdateDTO.getId());
|
||||
return cnt;
|
||||
}
|
||||
|
||||
public int updateKeys(IsvInfoUpdateKeysDTO isvInfoUpdateKeysDTO) {
|
||||
return isvKeysService.saveKeys(isvInfoUpdateKeysDTO);
|
||||
}
|
||||
|
||||
public IsvKeysDTO getKeys(Long isvId) {
|
||||
IsvKeys isvKeys = isvKeysService.get(IsvKeys::getIsvId, isvId);
|
||||
IsvKeysDTO isvKeysDTO;
|
||||
if (isvKeys == null) {
|
||||
isvKeysDTO = new IsvKeysDTO();
|
||||
isvKeysDTO.setIsvId(isvId);
|
||||
isvKeysDTO.setKeyFormat(RSATool.KeyFormat.PKCS8.getValue());
|
||||
isvKeysDTO.setPublicKeyIsv("");
|
||||
isvKeysDTO.setPrivateKeyIsv("");
|
||||
isvKeysDTO.setPublicKeyPlatform("");
|
||||
isvKeysDTO.setPrivateKeyPlatform("");
|
||||
} else {
|
||||
isvKeysDTO = CopyUtil.copyBean(isvKeys, IsvKeysDTO::new);
|
||||
}
|
||||
|
||||
IsvInfo isvInfo = this.getById(isvId);
|
||||
isvKeysDTO.setAppId(isvInfo.getAppId());
|
||||
|
||||
return isvKeysDTO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改状态
|
||||
*
|
||||
* @param statusUpdateDTO 修改值
|
||||
* @return 返回影响行数
|
||||
*/
|
||||
public int updateStatus(StatusUpdateDTO statusUpdateDTO) {
|
||||
Long isvId = statusUpdateDTO.getId();
|
||||
int cnt = this.query()
|
||||
.eq(IsvInfo::getId, isvId)
|
||||
.set(IsvInfo::getStatus, statusUpdateDTO.getStatus())
|
||||
.update();
|
||||
// 同步isv信息
|
||||
this.sendChangeEvent(isvId);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
private void sendChangeEvent(Long isvId) {
|
||||
SpringContext.publishEvent(new ChangeIsvInfoEvent(Collections.singletonList(isvId)));
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
package com.gitee.sop.admin.service.isv;
|
||||
|
||||
import com.gitee.sop.admin.common.context.SpringContext;
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.dao.entity.IsvKeys;
|
||||
import com.gitee.sop.admin.dao.mapper.IsvKeysMapper;
|
||||
import com.gitee.sop.admin.service.isv.dto.IsvInfoUpdateKeysDTO;
|
||||
import com.gitee.sop.admin.service.isv.event.ChangeIsvKeyEvent;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class IsvKeysService implements ServiceSupport<IsvKeys, IsvKeysMapper> {
|
||||
|
||||
public int saveKeys(IsvInfoUpdateKeysDTO isvInfoUpdateKeysDTO) {
|
||||
IsvKeys isvKeys = this.get(IsvKeys::getIsvId, isvInfoUpdateKeysDTO.getIsvId());
|
||||
if (isvKeys == null) {
|
||||
isvKeys = new IsvKeys();
|
||||
}
|
||||
CopyUtil.copyPropertiesIgnoreNull(isvInfoUpdateKeysDTO, isvKeys);
|
||||
int cnt = this.saveOrUpdate(isvKeys);
|
||||
// 发送变更事件
|
||||
SpringContext.publishEvent(new ChangeIsvKeyEvent(Collections.singletonList(isvInfoUpdateKeysDTO.getIsvId())));
|
||||
return cnt;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,114 @@
|
||||
package com.gitee.sop.admin.service.isv;
|
||||
|
||||
import com.gitee.fastmybatis.core.PageInfo;
|
||||
import com.gitee.fastmybatis.core.query.LambdaQuery;
|
||||
import com.gitee.sop.admin.common.context.SpringContext;
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.dao.entity.ApiInfo;
|
||||
import com.gitee.sop.admin.dao.entity.PermGroupPermission;
|
||||
import com.gitee.sop.admin.dao.entity.PermIsvGroup;
|
||||
import com.gitee.sop.admin.dao.mapper.ApiInfoMapper;
|
||||
import com.gitee.sop.admin.dao.mapper.PermGroupPermissionMapper;
|
||||
import com.gitee.sop.admin.dao.mapper.PermIsvGroupMapper;
|
||||
import com.gitee.sop.admin.service.isv.dto.PermGroupPermissionDTO;
|
||||
import com.gitee.sop.admin.service.isv.event.ChangeIsvPermEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class PermGroupPermissionService implements ServiceSupport<PermGroupPermission, PermGroupPermissionMapper> {
|
||||
|
||||
@Autowired
|
||||
private ApiInfoMapper apiInfoMapper;
|
||||
@Autowired
|
||||
private PermIsvGroupMapper permIsvGroupMapper;
|
||||
|
||||
public PageInfo<PermGroupPermission> doPage(LambdaQuery<PermGroupPermission> query) {
|
||||
query.orderByDesc(PermGroupPermission::getId);
|
||||
PageInfo<PermGroupPermission> page = this.page(query);
|
||||
|
||||
// 格式转换
|
||||
return page.convert(isvInfo -> {
|
||||
|
||||
return isvInfo;
|
||||
});
|
||||
}
|
||||
|
||||
public PageInfo<ApiInfo> pageGroupApiId(Long groupId, LambdaQuery<ApiInfo> query) {
|
||||
List<Long> apiIds = this.query()
|
||||
.eq(PermGroupPermission::getGroupId, groupId)
|
||||
.listUniqueValue(PermGroupPermission::getApiId);
|
||||
|
||||
if (apiIds.isEmpty()) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
|
||||
query.in(ApiInfo::getId, apiIds);
|
||||
|
||||
return apiInfoMapper.page(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置组权限
|
||||
*
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
public int setting(PermGroupPermissionDTO param) {
|
||||
Long groupId = param.getGroupId();
|
||||
List<Long> apiIdList = param.getApiIdList();
|
||||
if (CollectionUtils.isEmpty(apiIdList)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
List<Long> existApiIdList = this.query()
|
||||
.eq(PermGroupPermission::getGroupId, groupId)
|
||||
.listUniqueValue(PermGroupPermission::getApiId);
|
||||
|
||||
List<PermGroupPermission> saveList = apiIdList.stream()
|
||||
// 已存在的不添加
|
||||
.filter(apiId -> !existApiIdList.contains(apiId))
|
||||
.map(apiId -> {
|
||||
PermGroupPermission permGroupPermission = new PermGroupPermission();
|
||||
permGroupPermission.setGroupId(groupId);
|
||||
permGroupPermission.setApiId(apiId);
|
||||
return permGroupPermission;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
int cnt = this.saveBatch(saveList);
|
||||
|
||||
// 刷新isv权限
|
||||
this.refreshIsvPerm(groupId);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
private void refreshIsvPerm(Long groupId) {
|
||||
List<Long> isvIds = permIsvGroupMapper.query()
|
||||
.eq(PermIsvGroup::getGroupId, groupId)
|
||||
.listUniqueValue(PermIsvGroup::getIsvId);
|
||||
|
||||
SpringContext.publishEvent(new ChangeIsvPermEvent(isvIds));
|
||||
}
|
||||
|
||||
|
||||
public int delete(Long groupId, Collection<Long> apiIds) {
|
||||
int cnt = this.query()
|
||||
.eq(PermGroupPermission::getGroupId, groupId)
|
||||
.in(PermGroupPermission::getApiId, apiIds)
|
||||
.delete();
|
||||
|
||||
this.refreshIsvPerm(groupId);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
package com.gitee.sop.admin.service.isv;
|
||||
|
||||
import com.gitee.fastmybatis.core.PageInfo;
|
||||
import com.gitee.fastmybatis.core.query.LambdaQuery;
|
||||
import com.gitee.sop.admin.common.exception.BizException;
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.dao.entity.PermGroup;
|
||||
import com.gitee.sop.admin.dao.entity.PermIsvGroup;
|
||||
import com.gitee.sop.admin.dao.mapper.PermGroupMapper;
|
||||
import com.gitee.sop.admin.dao.mapper.PermIsvGroupMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class PermGroupService implements ServiceSupport<PermGroup, PermGroupMapper> {
|
||||
|
||||
@Autowired
|
||||
PermIsvGroupMapper permIsvGroupMapper;
|
||||
|
||||
public PageInfo<PermGroup> doPage(LambdaQuery<PermGroup> query) {
|
||||
query.orderByDesc(PermGroup::getId);
|
||||
PageInfo<PermGroup> page = this.page(query);
|
||||
|
||||
// 格式转换
|
||||
return page.convert(isvInfo -> {
|
||||
|
||||
return isvInfo;
|
||||
});
|
||||
}
|
||||
|
||||
public Map<Long, String> getCodeNameMap(Collection<Long> groupIdList) {
|
||||
return this.query()
|
||||
.in(PermGroup::getId, groupIdList)
|
||||
.map(PermGroup::getId, PermGroup::getGroupName);
|
||||
}
|
||||
|
||||
public int delete(Long groupId) {
|
||||
boolean used = permIsvGroupMapper.query()
|
||||
.eq(PermIsvGroup::getGroupId, groupId)
|
||||
.get() != null;
|
||||
if (used) {
|
||||
throw new BizException("无法删除:分组已被使用");
|
||||
}
|
||||
return this.deleteById(groupId);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,90 @@
|
||||
package com.gitee.sop.admin.service.isv;
|
||||
|
||||
import com.gitee.fastmybatis.core.PageInfo;
|
||||
import com.gitee.fastmybatis.core.query.LambdaQuery;
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.dao.entity.PermIsvGroup;
|
||||
import com.gitee.sop.admin.dao.mapper.PermIsvGroupMapper;
|
||||
import com.gitee.sop.admin.service.isv.dto.IsvGroupSettingDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class PermIsvGroupService implements ServiceSupport<PermIsvGroup, PermIsvGroupMapper> {
|
||||
|
||||
@Autowired
|
||||
private PermGroupService permGroupService;
|
||||
|
||||
public PageInfo<PermIsvGroup> doPage(LambdaQuery<PermIsvGroup> query) {
|
||||
query.orderByDesc(PermIsvGroup::getId);
|
||||
PageInfo<PermIsvGroup> page = this.page(query);
|
||||
|
||||
// 格式转换
|
||||
return page.convert(isvInfo -> {
|
||||
|
||||
return isvInfo;
|
||||
});
|
||||
}
|
||||
|
||||
public Map<Long, List<String>> getIsvGroupNameMap(Collection<Long> isvIds) {
|
||||
List<PermIsvGroup> list = this.list(PermIsvGroup::getIsvId, isvIds);
|
||||
if (list.isEmpty()) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
Set<Long> groupIds = list.stream().map(PermIsvGroup::getGroupId).collect(Collectors.toSet());
|
||||
Map<Long, String> groupCodeMap = permGroupService.getCodeNameMap(groupIds);
|
||||
return this.query()
|
||||
.in(PermIsvGroup::getIsvId, isvIds)
|
||||
.group(PermIsvGroup::getIsvId,
|
||||
permIsvGroup -> groupCodeMap.getOrDefault(permIsvGroup.getGroupId(), ""));
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int updateIsvGroup(IsvGroupSettingDTO isvGroupSettingDTO) {
|
||||
// 先删除所有
|
||||
int i = this.deleteByColumn(PermIsvGroup::getIsvId, isvGroupSettingDTO.getIsvId());
|
||||
List<Long> groupIds = isvGroupSettingDTO.getGroupIds();
|
||||
if (CollectionUtils.isEmpty(groupIds)) {
|
||||
return i;
|
||||
}
|
||||
List<PermIsvGroup> saveList = groupIds
|
||||
.stream()
|
||||
.map(groupId -> {
|
||||
PermIsvGroup permIsvGroup = new PermIsvGroup();
|
||||
permIsvGroup.setIsvId(isvGroupSettingDTO.getIsvId());
|
||||
permIsvGroup.setGroupId(groupId);
|
||||
return permIsvGroup;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
return this.saveBatch(saveList);
|
||||
}
|
||||
|
||||
public List<Long> listIsvGroupId(Long isvId) {
|
||||
List<PermIsvGroup> list = this.list(PermIsvGroup::getIsvId, isvId);
|
||||
if (list.isEmpty()) {
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
return list.stream().map(PermIsvGroup::getGroupId).distinct().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public boolean isUsed(Long groupId) {
|
||||
return this.query()
|
||||
.eq(PermIsvGroup::getGroupId, groupId)
|
||||
.getCount() > 0;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package com.gitee.sop.admin.service.isv.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvGroupSettingDTO {
|
||||
|
||||
@NotNull
|
||||
private Long isvId;
|
||||
|
||||
private List<Long> groupIds;
|
||||
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package com.gitee.sop.admin.service.isv.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvInfoAddDTO {
|
||||
|
||||
/**
|
||||
* 1启用,2禁用
|
||||
*/
|
||||
@NotNull
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Length(max = 500)
|
||||
private String remark;
|
||||
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
package com.gitee.sop.admin.service.isv.dto;
|
||||
|
||||
import com.gitee.sop.admin.service.jackson.convert.annotation.UserFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvInfoDTO {
|
||||
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* appKey
|
||||
*/
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* 1启用,2禁用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 是否有秘钥
|
||||
*/
|
||||
private Integer hasKeys;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
private String groupNames;
|
||||
|
||||
private LocalDateTime addTime;
|
||||
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 创建人id
|
||||
*/
|
||||
@UserFormat
|
||||
private Long addBy;
|
||||
|
||||
/**
|
||||
* 修改人id
|
||||
*/
|
||||
@UserFormat
|
||||
private Long updateBy;
|
||||
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package com.gitee.sop.admin.service.isv.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class IsvInfoUpdateDTO extends IsvInfoAddDTO {
|
||||
private Long id;
|
||||
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
package com.gitee.sop.admin.service.isv.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvInfoUpdateKeysDTO {
|
||||
|
||||
private Long isvId;
|
||||
|
||||
/**
|
||||
* 秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用)
|
||||
*/
|
||||
private Integer keyFormat;
|
||||
|
||||
/**
|
||||
* 开发者生成的公钥, 数据库字段:public_key_isv
|
||||
*/
|
||||
private String publicKeyIsv;
|
||||
|
||||
/**
|
||||
* 开发者生成的私钥(交给开发者), 数据库字段:private_key_isv
|
||||
*/
|
||||
private String privateKeyIsv;
|
||||
|
||||
/**
|
||||
* 平台生成的公钥(交给开发者), 数据库字段:public_key_platform
|
||||
*/
|
||||
private String publicKeyPlatform;
|
||||
|
||||
/**
|
||||
* 平台生成的私钥, 数据库字段:private_key_platform
|
||||
*/
|
||||
private String privateKeyPlatform;
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
package com.gitee.sop.admin.service.isv.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvKeysDTO {
|
||||
|
||||
private String appId;
|
||||
|
||||
private Long isvId;
|
||||
|
||||
/**
|
||||
* 秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用)
|
||||
*/
|
||||
private Integer keyFormat;
|
||||
|
||||
/**
|
||||
* 开发者生成的公钥, 数据库字段:public_key_isv
|
||||
*/
|
||||
private String publicKeyIsv;
|
||||
|
||||
/**
|
||||
* 开发者生成的私钥(交给开发者), 数据库字段:private_key_isv
|
||||
*/
|
||||
private String privateKeyIsv;
|
||||
|
||||
/**
|
||||
* 平台生成的公钥(交给开发者), 数据库字段:public_key_platform
|
||||
*/
|
||||
private String publicKeyPlatform;
|
||||
|
||||
/**
|
||||
* 平台生成的私钥, 数据库字段:private_key_platform
|
||||
*/
|
||||
private String privateKeyPlatform;
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package com.gitee.sop.admin.service.isv.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvKeysGenDTO {
|
||||
|
||||
/**
|
||||
* 开发者生成的公钥, 数据库字段:public_key_isv
|
||||
*/
|
||||
private String publicKeyIsv;
|
||||
|
||||
/**
|
||||
* 开发者生成的私钥(交给开发者), 数据库字段:private_key_isv
|
||||
*/
|
||||
private String privateKeyIsv;
|
||||
|
||||
/**
|
||||
* 平台生成的公钥(交给开发者), 数据库字段:public_key_platform
|
||||
*/
|
||||
private String publicKeyPlatform;
|
||||
|
||||
/**
|
||||
* 平台生成的私钥, 数据库字段:private_key_platform
|
||||
*/
|
||||
private String privateKeyPlatform;
|
||||
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package com.gitee.sop.admin.service.isv.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class PermGroupPermissionDTO {
|
||||
|
||||
@NotNull
|
||||
private Long groupId;
|
||||
|
||||
private List<Long> apiIdList;
|
||||
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
package com.gitee.sop.admin.service.isv.event;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class ChangeApiInfoEvent {
|
||||
|
||||
private final Collection<Long> apiIds;
|
||||
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
package com.gitee.sop.admin.service.isv.event;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class ChangeIsvInfoEvent {
|
||||
|
||||
private final Collection<Long> isvIds;
|
||||
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
package com.gitee.sop.admin.service.isv.event;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class ChangeIsvKeyEvent {
|
||||
|
||||
private final List<Long> isvIds;
|
||||
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
package com.gitee.sop.admin.service.isv.event;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class ChangeIsvPermEvent {
|
||||
|
||||
private final List<Long> isvIds;
|
||||
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
package com.gitee.sop.admin.service.isv.listener;
|
||||
|
||||
import com.gitee.sop.admin.dao.entity.IsvInfo;
|
||||
import com.gitee.sop.admin.dao.mapper.IsvInfoMapper;
|
||||
import com.gitee.sop.admin.service.isv.event.ChangeApiInfoEvent;
|
||||
import com.gitee.sop.admin.service.isv.event.ChangeIsvInfoEvent;
|
||||
import com.gitee.sop.admin.service.isv.event.ChangeIsvKeyEvent;
|
||||
import com.gitee.sop.admin.service.isv.event.ChangeIsvPermEvent;
|
||||
import com.gitee.sop.support.service.RefreshService;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 变更监听
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Component
|
||||
public class ChangeListener {
|
||||
|
||||
@DubboReference
|
||||
private RefreshService refreshService;
|
||||
|
||||
@Autowired
|
||||
private IsvInfoMapper isvInfoMapper;
|
||||
|
||||
/**
|
||||
* 监听isv信息变更
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
@EventListener
|
||||
public void onChangeApiInfoEvent(ChangeApiInfoEvent event) {
|
||||
Collection<Long> apiIds = event.getApiIds();
|
||||
refreshService.refreshApi(apiIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听isv信息变更
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
@EventListener
|
||||
public void onChangeIsvInfoEvent(ChangeIsvInfoEvent event) {
|
||||
Collection<Long> isvIds = event.getIsvIds();
|
||||
Collection<String> appIds = isvInfoMapper.query()
|
||||
.in(IsvInfo::getId, isvIds)
|
||||
.listUniqueValue(IsvInfo::getAppId);
|
||||
refreshService.refreshIsv(appIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听isv秘钥变更
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
@EventListener
|
||||
public void onChangeIsvKeyEvent(ChangeIsvKeyEvent event) {
|
||||
List<Long> isvIds = event.getIsvIds();
|
||||
refreshService.refreshSecret(isvIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听isv分组变更
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
@EventListener
|
||||
public void onChangeIsvGroupEvent(ChangeIsvPermEvent event) {
|
||||
List<Long> isvIds = event.getIsvIds();
|
||||
refreshService.refreshIsvPerm(isvIds);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package com.gitee.sop.admin.service.jackson.convert.annotation;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.gitee.sop.admin.service.jackson.convert.serde.UserFormatSerializer;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 序列化自动转换成用户名称
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@JacksonAnnotationsInside
|
||||
@JsonSerialize(using = UserFormatSerializer.class)
|
||||
public @interface UserFormat {
|
||||
|
||||
/**
|
||||
* 显示用户名称
|
||||
* @return
|
||||
*/
|
||||
boolean showName() default true;
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
package com.gitee.sop.admin.service.jackson.convert.serde;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.gitee.sop.admin.common.context.SpringContext;
|
||||
import com.gitee.sop.admin.common.resp.UserVO;
|
||||
import com.gitee.sop.admin.common.user.User;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.service.sys.UserCacheService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Slf4j
|
||||
public class UserFormatSerializer extends JsonSerializer<Object> {
|
||||
|
||||
@Override
|
||||
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||
if (value == null) {
|
||||
gen.writeNull();
|
||||
return;
|
||||
}
|
||||
Long userId = (Long) value;
|
||||
if (Objects.equals(userId, 0L)) {
|
||||
gen.writeNumber(userId);
|
||||
return;
|
||||
}
|
||||
Optional<User> userOpt = SpringContext.getBean(UserCacheService.class).getUser(userId);
|
||||
if (userOpt.isPresent()) {
|
||||
User user = userOpt.get();
|
||||
UserVO userVO = CopyUtil.copyBean(user, UserVO::new);
|
||||
gen.writeObject(userVO);
|
||||
} else {
|
||||
gen.writeObject(value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1 @@
|
||||
package com.gitee.sop.admin.service.jackson;
|
@@ -0,0 +1,47 @@
|
||||
package com.gitee.sop.admin.service.serve;
|
||||
|
||||
import com.gitee.sop.admin.common.context.SpringContext;
|
||||
import com.gitee.sop.admin.common.dto.StatusUpdateDTO;
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.dao.entity.ApiInfo;
|
||||
import com.gitee.sop.admin.dao.mapper.ApiInfoMapper;
|
||||
import com.gitee.sop.admin.service.isv.event.ChangeApiInfoEvent;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class ApiInfoService implements ServiceSupport<ApiInfo, ApiInfoMapper> {
|
||||
|
||||
/**
|
||||
* 修改状态
|
||||
*
|
||||
* @param statusUpdateDTO 修改值
|
||||
* @return 返回影响行数
|
||||
*/
|
||||
public int updateStatus(StatusUpdateDTO statusUpdateDTO) {
|
||||
int cnt = this.query()
|
||||
.eq(ApiInfo::getId, statusUpdateDTO.getId())
|
||||
.set(ApiInfo::getStatus, statusUpdateDTO.getStatus())
|
||||
.update();
|
||||
this.sendChangeEvent(statusUpdateDTO.getId());
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(ApiInfo entity) {
|
||||
int cnt = ServiceSupport.super.update(entity);
|
||||
sendChangeEvent(entity.getId());
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void sendChangeEvent(Long id) {
|
||||
SpringContext.publishEvent(new ChangeApiInfoEvent(Collections.singletonList(id)));
|
||||
}
|
||||
}
|
@@ -0,0 +1,107 @@
|
||||
package com.gitee.sop.admin.service.sys;
|
||||
|
||||
import com.gitee.fastmybatis.core.support.BaseLambdaService;
|
||||
import com.gitee.sop.admin.common.config.IConfig;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.dao.entity.SysConfig;
|
||||
import com.gitee.sop.admin.dao.mapper.SysConfigMapper;
|
||||
import com.gitee.sop.admin.service.sys.dto.SystemConfigDTO;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class SysConfigService extends BaseLambdaService<SysConfig, SysConfigMapper> implements IConfig {
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
// key: configKey, value: configValue
|
||||
private final LoadingCache<String, Optional<String>> configCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(15, TimeUnit.MINUTES)
|
||||
.build(new CacheLoader<String, Optional<String>>() {
|
||||
@Override
|
||||
public Optional<String> load(String key) throws Exception {
|
||||
return Optional.ofNullable(getConfigValue(key, null));
|
||||
}
|
||||
});
|
||||
|
||||
public void save(Collection<SystemConfigDTO> configs) {
|
||||
configs.forEach(this::setConfig);
|
||||
}
|
||||
|
||||
public String getRawValue(String key) {
|
||||
return this.query()
|
||||
.eq(SysConfig::getConfigKey, key)
|
||||
.getValue(SysConfig::getConfigValue);
|
||||
}
|
||||
|
||||
public void setConfig(String key, String value) {
|
||||
setConfig(key, value, "");
|
||||
}
|
||||
|
||||
public void setConfig(String key, String value, String remark) {
|
||||
SystemConfigDTO systemConfigDTO = new SystemConfigDTO();
|
||||
systemConfigDTO.setConfigKey(key);
|
||||
systemConfigDTO.setConfigValue(value);
|
||||
systemConfigDTO.setRemark(remark);
|
||||
setConfig(systemConfigDTO);
|
||||
}
|
||||
|
||||
public void setConfig(SystemConfigDTO systemConfigDTO) {
|
||||
Objects.requireNonNull(systemConfigDTO.getConfigKey(), "need key");
|
||||
Objects.requireNonNull(systemConfigDTO.getConfigValue(), "need value");
|
||||
SysConfig systemConfig = get(SysConfig::getConfigKey, systemConfigDTO.getConfigKey());
|
||||
if (systemConfig == null) {
|
||||
systemConfig = CopyUtil.copyBean(systemConfigDTO, SysConfig::new);
|
||||
this.save(systemConfig);
|
||||
} else {
|
||||
CopyUtil.copyPropertiesIgnoreNull(systemConfigDTO, systemConfig);
|
||||
this.update(systemConfig);
|
||||
}
|
||||
configCache.invalidate(systemConfigDTO.getConfigKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置信息
|
||||
* <pre>
|
||||
* 优先级:
|
||||
* 数据库
|
||||
* Environment
|
||||
* 默认配置
|
||||
* </pre>
|
||||
*
|
||||
* @param key 配置key
|
||||
* @param defaultValue 没有获取到返回的默认值
|
||||
* @return 返回配置信息,如果没有获取到值,则返回默认值
|
||||
*/
|
||||
public String getConfigValue(String key, String defaultValue) {
|
||||
Objects.requireNonNull(key, "need key");
|
||||
SysConfig systemConfig = get(SysConfig::getConfigKey, key);
|
||||
return Optional.ofNullable(systemConfig)
|
||||
.map(SysConfig::getConfigValue)
|
||||
.orElseGet(() -> environment.getProperty(key, defaultValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfig(String key) {
|
||||
return configCache.getUnchecked(key).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfig(String key, String defaultValue) {
|
||||
return configCache.getUnchecked(key).orElse(defaultValue);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
package com.gitee.sop.admin.service.sys;
|
||||
|
||||
import com.gitee.fastmybatis.core.query.LambdaQuery;
|
||||
import com.gitee.fastmybatis.core.util.TreeUtil;
|
||||
import com.gitee.sop.admin.common.dto.StatusUpdateDTO;
|
||||
import com.gitee.sop.admin.common.exception.BizException;
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.dao.entity.SysDept;
|
||||
import com.gitee.sop.admin.dao.mapper.SysDeptMapper;
|
||||
import com.gitee.sop.admin.service.sys.dto.SysDeptDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class SysDeptService implements ServiceSupport<SysDept, SysDeptMapper> {
|
||||
|
||||
public Long addDept(SysDept sysDept) {
|
||||
long count = this.query()
|
||||
.eq(SysDept::getParentId, 0)
|
||||
.getCount();
|
||||
if (count > 0 && Objects.equals(sysDept.getParentId(), 0L)) {
|
||||
throw new BizException("只能有一个根节点");
|
||||
}
|
||||
this.save(sysDept);
|
||||
return sysDept.getId();
|
||||
}
|
||||
|
||||
public List<SysDeptDTO> listTree(LambdaQuery<SysDept> query) {
|
||||
List<SysDept> list = this.list(query);
|
||||
List<SysDeptDTO> sysDeptList = CopyUtil.copyList(list, SysDeptDTO::new);
|
||||
return TreeUtil.convertTree(sysDeptList, 0L);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改状态
|
||||
*
|
||||
* @param statusUpdateDTO 修改值
|
||||
* @return 返回影响行数
|
||||
*/
|
||||
public int updateStatus(StatusUpdateDTO statusUpdateDTO) {
|
||||
return this.query()
|
||||
.eq(SysDept::getId, statusUpdateDTO.getId())
|
||||
.set(SysDept::getStatus, statusUpdateDTO.getStatus())
|
||||
.update();
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
package com.gitee.sop.admin.service.sys;
|
||||
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.dao.entity.SysResource;
|
||||
import com.gitee.sop.admin.dao.mapper.SysResourceMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class SysResourceService implements ServiceSupport<SysResource, SysResourceMapper> {
|
||||
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
package com.gitee.sop.admin.service.sys;
|
||||
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.dao.entity.SysRoleResource;
|
||||
import com.gitee.sop.admin.dao.mapper.SysRoleResourceMapper;
|
||||
import com.gitee.sop.admin.service.sys.dto.SysRoleResourceDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class SysRoleResourceService implements ServiceSupport<SysRoleResource, SysRoleResourceMapper> {
|
||||
|
||||
|
||||
/**
|
||||
* 保存角色菜单配置
|
||||
*
|
||||
* @param sysRoleResourceDTO 入参
|
||||
* @return 返回影响行数
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int saveRoleResource(SysRoleResourceDTO sysRoleResourceDTO) {
|
||||
Long roleId = sysRoleResourceDTO.getRoleId();
|
||||
// 删除之前的
|
||||
this.deleteByColumn(SysRoleResource::getRoleId, roleId);
|
||||
|
||||
List<SysRoleResource> saveList = sysRoleResourceDTO.getResourceIds().stream()
|
||||
.map(resourceId -> {
|
||||
SysRoleResource sysRoleResource = new SysRoleResource();
|
||||
sysRoleResource.setRoleId(roleId);
|
||||
sysRoleResource.setResourceId(resourceId);
|
||||
sysRoleResource.setAddBy(sysRoleResourceDTO.getAddBy());
|
||||
sysRoleResource.setUpdateBy(sysRoleResourceDTO.getAddBy());
|
||||
return sysRoleResource;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return this.saveBatch(saveList);
|
||||
}
|
||||
|
||||
public List<Long> listRoleResource(Long roleId) {
|
||||
return this.query()
|
||||
.eq(SysRoleResource::getRoleId, roleId)
|
||||
.listUniqueValue(SysRoleResource::getResourceId);
|
||||
}
|
||||
|
||||
public List<Long> listRoleResource(Collection<Long> roleIds) {
|
||||
return this.query()
|
||||
.in(SysRoleResource::getRoleId, roleIds)
|
||||
.listUniqueValue(SysRoleResource::getResourceId);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
package com.gitee.sop.admin.service.sys;
|
||||
|
||||
import com.gitee.sop.admin.common.dto.StatusUpdateDTO;
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.dao.entity.SysRole;
|
||||
import com.gitee.sop.admin.dao.mapper.SysRoleMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class SysRoleService implements ServiceSupport<SysRole, SysRoleMapper> {
|
||||
|
||||
|
||||
/**
|
||||
* 修改状态
|
||||
*
|
||||
* @param statusUpdateDTO 修改值
|
||||
* @return 返回影响行数
|
||||
*/
|
||||
public int updateStatus(StatusUpdateDTO statusUpdateDTO) {
|
||||
return this.query()
|
||||
.eq(SysRole::getId, statusUpdateDTO.getId())
|
||||
.set(SysRole::getStatus, statusUpdateDTO.getStatus())
|
||||
.update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,116 @@
|
||||
package com.gitee.sop.admin.service.sys;
|
||||
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.dao.entity.SysDept;
|
||||
import com.gitee.sop.admin.dao.entity.SysUserDept;
|
||||
import com.gitee.sop.admin.dao.mapper.SysDeptMapper;
|
||||
import com.gitee.sop.admin.dao.mapper.SysUserDeptMapper;
|
||||
import com.gitee.sop.admin.service.sys.dto.DeptUserResultDTO;
|
||||
import com.gitee.sop.admin.service.sys.dto.SysDeptDTO;
|
||||
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.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class SysUserDeptService implements ServiceSupport<SysUserDept, SysUserDeptMapper> {
|
||||
|
||||
@Autowired
|
||||
SysDeptMapper sysDeptMapper;
|
||||
|
||||
public Map<Long, SysDeptDTO> getUserDeptId(Collection<Long> userIds) {
|
||||
Map<Long, SysDept> deptIdMap = sysDeptMapper.query()
|
||||
.map(SysDept::getId, Function.identity());
|
||||
return this.query()
|
||||
.in(SysUserDept::getUserId, userIds)
|
||||
.map(SysUserDept::getUserId, sysUserDept -> {
|
||||
SysDept sysDept = deptIdMap.get(sysUserDept.getDeptId());
|
||||
return CopyUtil.copyBean(sysDept, SysDeptDTO::new);
|
||||
}, (v1, v2) -> v2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找部门及子部门下所有用户
|
||||
*
|
||||
* @param deptId 部门
|
||||
* @return 返回空表示选中了根节点或没有选
|
||||
*/
|
||||
public DeptUserResultDTO listDeptUserIdsDeep(Long deptId) {
|
||||
if (deptId == null) {
|
||||
return new DeptUserResultDTO(false, null);
|
||||
}
|
||||
SysDept sysDept = sysDeptMapper.getById(deptId);
|
||||
// 选中了根节点或没有选
|
||||
if (sysDept == null || Objects.equals(sysDept.getParentId(), 0L)) {
|
||||
return new DeptUserResultDTO(false, null);
|
||||
}
|
||||
List<Long> userIdsAll = new ArrayList<>();
|
||||
List<Long> userIds = this.query()
|
||||
.eq(SysUserDept::getDeptId, deptId)
|
||||
.listUniqueValue(SysUserDept::getUserId);
|
||||
|
||||
appendChildren(userIdsAll, deptId);
|
||||
|
||||
userIdsAll.addAll(userIds);
|
||||
return new DeptUserResultDTO(true, userIdsAll);
|
||||
}
|
||||
|
||||
private void appendChildren(List<Long> userIdsAll, Long deptId) {
|
||||
List<Long> deptIds = sysDeptMapper.query()
|
||||
.eq(SysDept::getParentId, deptId)
|
||||
.listUniqueValue(SysDept::getId);
|
||||
if (deptIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<Long> userIds = this.query()
|
||||
.in(SysUserDept::getDeptId, deptIds)
|
||||
.listUniqueValue(SysUserDept::getUserId);
|
||||
userIdsAll.addAll(userIds);
|
||||
|
||||
for (Long childDeptId : deptIds) {
|
||||
appendChildren(userIdsAll, childDeptId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存用户部门
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param deptIds 部门id
|
||||
* @return 返回影响行数
|
||||
*/
|
||||
public int saveUserDept(Long userId, List<Long> deptIds) {
|
||||
this.query()
|
||||
.eq(SysUserDept::getUserId, userId)
|
||||
.delete();
|
||||
|
||||
if (CollectionUtils.isEmpty(deptIds)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
List<SysUserDept> saveList = deptIds.stream()
|
||||
.map(deptId -> {
|
||||
SysUserDept sysUserDept = new SysUserDept();
|
||||
sysUserDept.setUserId(userId);
|
||||
sysUserDept.setDeptId(deptId);
|
||||
return sysUserDept;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return this.saveBatch(saveList);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
package com.gitee.sop.admin.service.sys;
|
||||
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.common.user.User;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.dao.entity.SysRole;
|
||||
import com.gitee.sop.admin.dao.entity.SysUserRole;
|
||||
import com.gitee.sop.admin.dao.mapper.SysRoleMapper;
|
||||
import com.gitee.sop.admin.dao.mapper.SysUserRoleMapper;
|
||||
import com.gitee.sop.admin.service.sys.dto.SysRoleDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class SysUserRoleService implements ServiceSupport<SysUserRole, SysUserRoleMapper> {
|
||||
|
||||
@Autowired
|
||||
private SysRoleMapper sysRoleMapper;
|
||||
|
||||
/**
|
||||
* 设置用户角色
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param roleIds 角色id
|
||||
* @param operator 操作人
|
||||
*/
|
||||
public void setUserRole(Long userId, List<Long> roleIds, User operator) {
|
||||
this.query()
|
||||
.eq(SysUserRole::getUserId, userId)
|
||||
.delete();
|
||||
|
||||
if (CollectionUtils.isEmpty(roleIds)) {
|
||||
return;
|
||||
}
|
||||
List<SysUserRole> saveList = new LinkedHashSet<>(roleIds).stream()
|
||||
.map(roleId -> {
|
||||
SysUserRole sysUserRole = new SysUserRole();
|
||||
sysUserRole.setRoleId(roleId);
|
||||
sysUserRole.setUserId(userId);
|
||||
sysUserRole.setAddBy(operator.getUserId());
|
||||
return sysUserRole;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
this.saveBatch(saveList);
|
||||
}
|
||||
|
||||
public List<Long> listUserRoleIds(Long userId) {
|
||||
return this.query()
|
||||
.eq(SysUserRole::getUserId, userId)
|
||||
.listUniqueValue(SysUserRole::getRoleId);
|
||||
}
|
||||
|
||||
public List<SysRoleDTO> listUserRoles(Long userId) {
|
||||
List<Long> roleIds = this.listUserRoleIds(userId);
|
||||
if (roleIds.isEmpty()) {
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
return sysRoleMapper.query()
|
||||
.in(SysRole::getId, roleIds)
|
||||
.list(sysRole -> CopyUtil.copyBean(sysRole, SysRoleDTO::new));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,180 @@
|
||||
package com.gitee.sop.admin.service.sys;
|
||||
|
||||
import com.gitee.fastmybatis.core.PageInfo;
|
||||
import com.gitee.fastmybatis.core.query.LambdaQuery;
|
||||
import com.gitee.sop.admin.common.config.Configs;
|
||||
import com.gitee.sop.admin.common.dto.StatusUpdateBatchDTO;
|
||||
import com.gitee.sop.admin.common.dto.StatusUpdateDTO;
|
||||
import com.gitee.sop.admin.common.dto.UserDTO;
|
||||
import com.gitee.sop.admin.common.enums.ConfigKeyEnum;
|
||||
import com.gitee.sop.admin.common.support.ServiceSupport;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.common.util.GenerateUtil;
|
||||
import com.gitee.sop.admin.dao.entity.SysUser;
|
||||
import com.gitee.sop.admin.dao.mapper.SysUserMapper;
|
||||
import com.gitee.sop.admin.service.sys.dto.DeptUserResultDTO;
|
||||
import com.gitee.sop.admin.service.sys.dto.SysDeptDTO;
|
||||
import com.gitee.sop.admin.service.sys.dto.SysUserAddDTO;
|
||||
import com.gitee.sop.admin.service.sys.dto.SysUserDTO;
|
||||
import com.gitee.sop.admin.service.sys.dto.SysUserSearchDTO;
|
||||
import com.gitee.sop.admin.service.sys.dto.SysUserUpdateDTO;
|
||||
import com.gitee.sop.admin.service.sys.login.enums.RegTypeEnum;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.bcrypt.BCrypt;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class SysUserService implements ServiceSupport<SysUser, SysUserMapper> {
|
||||
|
||||
@Autowired
|
||||
SysUserDeptService sysUserDeptService;
|
||||
|
||||
public <T extends UserDTO> void fillShowName(Collection<T> userDTOS) {
|
||||
if (CollectionUtils.isEmpty(userDTOS)) {
|
||||
return;
|
||||
}
|
||||
Set<Long> userIds = userDTOS.stream().flatMap(docInfo -> Lists.newArrayList(docInfo.getAddBy(), docInfo.getUpdateBy()).stream())
|
||||
.filter(val -> val != null && val > 0)
|
||||
.collect(Collectors.toSet());
|
||||
Map<Long, SysUserDTO> userIdMap = this.getUserInfo(userIds);
|
||||
for (T userDTO : userDTOS) {
|
||||
SysUserDTO addUser = userIdMap.get(userDTO.getAddBy());
|
||||
if (addUser != null) {
|
||||
userDTO.setAddByName(addUser.getShowName());
|
||||
}
|
||||
SysUserDTO updateUser = userIdMap.get(userDTO.getUpdateBy());
|
||||
if (updateUser != null) {
|
||||
userDTO.setUpdateByName(updateUser.getShowName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Long, SysUserDTO> getUserInfo(Collection<Long> userIds) {
|
||||
if (CollectionUtils.isEmpty(userIds)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return this.query()
|
||||
.in(SysUser::getId, userIds)
|
||||
.map(SysUser::getId, sysUser -> CopyUtil.copyBean(sysUser, SysUserDTO::new));
|
||||
}
|
||||
|
||||
public PageInfo<SysUserDTO> doPage(SysUserSearchDTO sysUserSearchDTO) {
|
||||
LambdaQuery<SysUser> query = sysUserSearchDTO.toLambdaQuery(SysUser.class);
|
||||
Long deptId = sysUserSearchDTO.getDeptId();
|
||||
DeptUserResultDTO deptUserResultDTO = sysUserDeptService.listDeptUserIdsDeep(deptId);
|
||||
if (deptUserResultDTO.getSelect()) {
|
||||
List<Long> userIds = deptUserResultDTO.getUserIds();
|
||||
// 查不到返回空
|
||||
if (CollectionUtils.isEmpty(userIds)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
query.in(SysUser::getId, userIds);
|
||||
}
|
||||
|
||||
query.orderByDesc(SysUser::getId);
|
||||
|
||||
// 格式转换
|
||||
return this.pageAndConvert(query, records -> {
|
||||
if (records.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Set<Long> userIds = records.stream().map(SysUser::getId).collect(Collectors.toSet());
|
||||
Map<Long, SysDeptDTO> userIdDeptMap = sysUserDeptService.getUserDeptId(userIds);
|
||||
|
||||
return CopyUtil.copyList(records, SysUserDTO::new, after -> {
|
||||
SysDeptDTO sysDeptDTO = userIdDeptMap.get(after.getId());
|
||||
after.setDept(sysDeptDTO);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public Long addUser(SysUserAddDTO sysUserAddDTO) {
|
||||
SysUser sysUser = CopyUtil.copyBean(sysUserAddDTO, SysUser::new);
|
||||
String encodedPassword = BCrypt.hashpw(sysUserAddDTO.getPassword(), BCrypt.gensalt());
|
||||
sysUser.setPassword(encodedPassword);
|
||||
sysUser.setRegType(RegTypeEnum.BACKEND.getValue());
|
||||
this.save(sysUser);
|
||||
|
||||
// 添加部门
|
||||
Long deptId = sysUserAddDTO.getParentId();
|
||||
if (deptId != null && deptId > 0) {
|
||||
sysUserDeptService.saveUserDept(sysUser.getId(), Lists.newArrayList(deptId));
|
||||
}
|
||||
|
||||
return sysUser.getId();
|
||||
}
|
||||
|
||||
public int updateUser(SysUserUpdateDTO sysUserUpdateDTO) {
|
||||
SysUser sysUser = CopyUtil.copyBean(sysUserUpdateDTO, SysUser::new);
|
||||
int cnt = this.update(sysUser);
|
||||
|
||||
// 添加部门
|
||||
Long deptId = sysUserUpdateDTO.getParentId();
|
||||
if (deptId != null && deptId > 0) {
|
||||
sysUserDeptService.saveUserDept(sysUser.getId(), Lists.newArrayList(deptId));
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改状态
|
||||
*
|
||||
* @param statusUpdateDTO 修改值
|
||||
* @return 返回影响行数
|
||||
*/
|
||||
public int updateStatus(StatusUpdateDTO statusUpdateDTO) {
|
||||
return this.query()
|
||||
.eq(SysUser::getId, statusUpdateDTO.getId())
|
||||
.set(SysUser::getStatus, statusUpdateDTO.getStatus())
|
||||
.update();
|
||||
}
|
||||
|
||||
public int updateStatus(StatusUpdateBatchDTO statusUpdateDTO) {
|
||||
return this.query()
|
||||
.in(SysUser::getId, statusUpdateDTO.getIds())
|
||||
.set(SysUser::getStatus, statusUpdateDTO.getStatus())
|
||||
.update();
|
||||
}
|
||||
|
||||
public void resetUserPassword(Long userId, String passwordHash) {
|
||||
String encodedPassword = BCrypt.hashpw(passwordHash, BCrypt.gensalt());
|
||||
this.query()
|
||||
.eq(SysUser::getId, userId)
|
||||
.set(SysUser::getPassword, encodedPassword)
|
||||
.update();
|
||||
}
|
||||
|
||||
public SysUser getByUsername(String username) {
|
||||
return this.get(SysUser::getUsername, username);
|
||||
}
|
||||
|
||||
public String getDbPassword(String username, String password) {
|
||||
return getDbPassword(username, password, getPasswordSalt());
|
||||
}
|
||||
|
||||
public String getDbPassword(String username) {
|
||||
return this.query().eq(SysUser::getUsername, username).getValue(SysUser::getPassword);
|
||||
}
|
||||
|
||||
public String getDbPassword(String username, String password, String salt) {
|
||||
return GenerateUtil.getUserPassword(username, password, salt);
|
||||
}
|
||||
|
||||
private String getPasswordSalt() {
|
||||
return Configs.getValue(ConfigKeyEnum.PASSWORD_SALT);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
package com.gitee.sop.admin.service.sys;
|
||||
|
||||
import com.gitee.sop.admin.common.enums.ConfigKeyEnum;
|
||||
import com.gitee.sop.admin.common.util.PasswordUtil;
|
||||
import com.gitee.sop.admin.dao.entity.SysUser;
|
||||
import com.gitee.sop.admin.dao.mapper.UpgradeMapper;
|
||||
import com.gitee.sop.admin.service.sys.login.enums.RegTypeEnum;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.bcrypt.BCrypt;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class UpgradeService {
|
||||
|
||||
@Autowired
|
||||
private SysConfigService sysConfigService;
|
||||
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
|
||||
@Autowired
|
||||
private UpgradeMapper upgradeMapper;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.initJwtSecret();
|
||||
this.insertAdmin();
|
||||
}
|
||||
|
||||
private void initJwtSecret() {
|
||||
String configKey = ConfigKeyEnum.JWT_SECRET.getKey();
|
||||
String value = sysConfigService.getRawValue(configKey);
|
||||
if (StringUtils.isBlank(value)) {
|
||||
value = PasswordUtil.getRandomSimplePassword(30);
|
||||
sysConfigService.setConfig(configKey, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void insertAdmin() {
|
||||
SysUser userInfo = sysUserService.getByUsername("admin");
|
||||
if (userInfo != null) {
|
||||
return;
|
||||
}
|
||||
String username = "admin";
|
||||
String tpl = "INSERT INTO `sys_user` ( `username`, `password`, `nickname`, `reg_type`) VALUES \n" +
|
||||
"\t('%s','%s','%s','%s');";
|
||||
// 初始密码
|
||||
String defPassword = "123456";
|
||||
defPassword = DigestUtils.sha256Hex(defPassword);
|
||||
String encodedPassword = BCrypt.hashpw(defPassword, BCrypt.gensalt());
|
||||
String sql = String.format(tpl, username, encodedPassword, username, RegTypeEnum.BACKEND.getValue());
|
||||
runSql(sql);
|
||||
}
|
||||
|
||||
protected void runSql(String sql) {
|
||||
upgradeMapper.runSql(sql);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package com.gitee.sop.admin.service.sys;
|
||||
|
||||
import com.gitee.sop.admin.common.user.User;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public interface UserCacheService {
|
||||
|
||||
Optional<User> getUser(Long userId);
|
||||
|
||||
}
|
@@ -0,0 +1,99 @@
|
||||
package com.gitee.sop.admin.service.sys;
|
||||
|
||||
import com.gitee.fastmybatis.core.util.TreeUtil;
|
||||
import com.gitee.sop.admin.common.enums.MenuTypeEnum;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.dao.entity.SysResource;
|
||||
import com.gitee.sop.admin.dao.entity.SysRoleResource;
|
||||
import com.gitee.sop.admin.service.sys.dto.MenuTreeDTO;
|
||||
import com.gitee.sop.admin.service.sys.dto.MenuTreeDTO.Meta;
|
||||
import com.gitee.sop.admin.service.sys.dto.SysRoleDTO;
|
||||
import com.gitee.sop.admin.service.sys.dto.UserPermissionDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class UserPermissionService {
|
||||
|
||||
@Autowired
|
||||
private SysResourceService sysResourceService;
|
||||
@Autowired
|
||||
private SysRoleResourceService sysRoleResourceService;
|
||||
@Autowired
|
||||
private SysUserRoleService sysUserRoleService;
|
||||
|
||||
public UserPermissionDTO getUserPermission(Long userId) {
|
||||
List<SysRoleDTO> sysRoleDTOS = sysUserRoleService.listUserRoles(userId);
|
||||
if (sysRoleDTOS.isEmpty()) {
|
||||
return UserPermissionDTO.empty();
|
||||
}
|
||||
|
||||
Set<Long> roleIds = sysRoleDTOS.stream().map(SysRoleDTO::getId).collect(Collectors.toSet());
|
||||
List<String> roleCodes = sysRoleDTOS.stream().map(SysRoleDTO::getCode).distinct().collect(Collectors.toList());
|
||||
|
||||
// 角色对应的资源
|
||||
List<Long> resourceIds = sysRoleResourceService.query()
|
||||
.in(SysRoleResource::getRoleId, roleIds)
|
||||
.listUniqueValue(SysRoleResource::getResourceId);
|
||||
|
||||
// 获取按钮权限
|
||||
List<String> permissions = sysResourceService.query()
|
||||
.eq(SysResource::getMenuType, MenuTypeEnum.BUTTON.getValue())
|
||||
.in(SysResource::getId, resourceIds)
|
||||
.listUniqueValue(SysResource::getAuths);
|
||||
|
||||
UserPermissionDTO userPermissionDTO = new UserPermissionDTO();
|
||||
userPermissionDTO.setRoles(roleCodes);
|
||||
userPermissionDTO.setPermissions(permissions);
|
||||
return userPermissionDTO;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户菜单
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return 返回菜单树
|
||||
*/
|
||||
public List<MenuTreeDTO> listUserMenuTree(Long userId) {
|
||||
List<Long> roleIds = sysUserRoleService.listUserRoleIds(userId);
|
||||
if (roleIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Long> resourceIds = sysRoleResourceService.listRoleResource(roleIds);
|
||||
if (resourceIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<SysResource> list = sysResourceService.query()
|
||||
.in(SysResource::getId, resourceIds)
|
||||
.eq(SysResource::getMenuType, MenuTypeEnum.MENU)
|
||||
.list();
|
||||
|
||||
return convert(list);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private List<MenuTreeDTO> convert(List<SysResource> list) {
|
||||
List<MenuTreeDTO> menuTreeDTOS = list.stream()
|
||||
.map(sysResource -> {
|
||||
MenuTreeDTO menuTreeDTO = CopyUtil.copyBean(sysResource, MenuTreeDTO::new);
|
||||
Meta meta = CopyUtil.copyBean(sysResource, Meta::new);
|
||||
menuTreeDTO.setMeta(meta);
|
||||
return menuTreeDTO;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return TreeUtil.convertTree(menuTreeDTOS, 0L);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package com.gitee.sop.admin.service.sys.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class DeptUserResultDTO {
|
||||
|
||||
private Boolean select = true;
|
||||
|
||||
private List<Long> userIds;
|
||||
|
||||
}
|
@@ -0,0 +1,130 @@
|
||||
package com.gitee.sop.admin.service.sys.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.gitee.fastmybatis.core.support.TreeNode;
|
||||
import com.gitee.sop.admin.common.jackson.convert.annotation.Bool;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 菜单资源
|
||||
*
|
||||
* @author 六如
|
||||
* @see <a href="https://pure-admin.cn/pages/routerMenu/#%E8%B7%AF%E7%94%B1%E5%92%8C%E8%8F%9C%E5%8D%95%E9%85%8D%E7%BD%AE">...</a>
|
||||
*/
|
||||
@Data
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
public class MenuTreeDTO implements TreeNode<MenuTreeDTO, Long> {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 路由路径
|
||||
*/
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 路由名称(必须保持唯一)
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 路由重定向(默认跳转地址)
|
||||
*/
|
||||
private String redirect;
|
||||
|
||||
/**
|
||||
* 父级id
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 路由元信息
|
||||
*/
|
||||
private Meta meta;
|
||||
|
||||
private List<MenuTreeDTO> children;
|
||||
|
||||
@Override
|
||||
public Long takeId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long takeParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 路由元信息,通俗来说就是路由上的额外信息 https://router.vuejs.org/zh/guide/advanced/meta.html#%E8%B7%AF%E7%94%B1%E5%85%83%E4%BF%A1%E6%81%AF
|
||||
*/
|
||||
@Data
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
public static class Meta {
|
||||
/**
|
||||
* 菜单名称(兼容国际化、非国际化,如果用国际化的写法就必须在根目录的locales文件夹下对应添加)
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 菜单图标
|
||||
*/
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 右侧图标
|
||||
*/
|
||||
private String extraIcon;
|
||||
|
||||
/**
|
||||
* 菜单(是否显示该菜单)
|
||||
*/
|
||||
@Bool
|
||||
private Integer showLink;
|
||||
|
||||
/**
|
||||
* 父级菜单(是否显示父级菜单
|
||||
*/
|
||||
@Bool
|
||||
private Integer showParent;
|
||||
|
||||
/**
|
||||
* 链接地址(需要内嵌的`iframe`链接地址)
|
||||
*/
|
||||
private String frameSrc;
|
||||
|
||||
/**
|
||||
* 加载动画(内嵌的`iframe`页面是否开启首次加载动画)
|
||||
*/
|
||||
@Bool
|
||||
private Integer frameLoading;
|
||||
|
||||
/**
|
||||
* 缓存页面
|
||||
*/
|
||||
@Bool
|
||||
private Integer keepAlive;
|
||||
|
||||
/**
|
||||
* 标签页(当前菜单名称或自定义信息禁止添加到标签页)
|
||||
*/
|
||||
@Bool
|
||||
private Integer hiddenTag;
|
||||
|
||||
/**
|
||||
* 菜单激活
|
||||
*/
|
||||
private String activePath;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer rank;
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
package com.gitee.sop.admin.service.sys.dto;
|
||||
|
||||
import com.gitee.fastmybatis.core.support.TreeNode;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 备注:部门表
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class SysDeptDTO implements TreeNode<SysDeptDTO, Long> {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 状态,1:启用,2:禁用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 父级id
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 添加时间
|
||||
*/
|
||||
private LocalDateTime addTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 创建人id
|
||||
*/
|
||||
private Long addBy;
|
||||
|
||||
/**
|
||||
* 修改人id
|
||||
*/
|
||||
private Long updateBy;
|
||||
|
||||
private List<SysDeptDTO> children;
|
||||
|
||||
|
||||
@Override
|
||||
public Long takeId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long takeParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package com.gitee.sop.admin.service.sys.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class SysRoleDTO {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 角色名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 角色code
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package com.gitee.sop.admin.service.sys.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class SysRoleResourceDTO {
|
||||
|
||||
/**
|
||||
* 角色id
|
||||
*/
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 资源id
|
||||
*/
|
||||
private List<Long> resourceIds;
|
||||
|
||||
/**
|
||||
* 添加人
|
||||
*/
|
||||
private Long addBy;
|
||||
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
package com.gitee.sop.admin.service.sys.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class SysUserAddDTO {
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 性别,0-未知,1-男,2-女
|
||||
*/
|
||||
private Integer gender;
|
||||
|
||||
/**
|
||||
* 状态,1:启用,2:禁用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 注册类型,1-系统,2-手动
|
||||
*/
|
||||
private String regType;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 添加时间
|
||||
*/
|
||||
private LocalDateTime addTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 创建人id
|
||||
*/
|
||||
private Long addBy;
|
||||
|
||||
/**
|
||||
* 修改人id
|
||||
*/
|
||||
private Long updateBy;
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
package com.gitee.sop.admin.service.sys.dto;
|
||||
|
||||
import com.gitee.sop.admin.common.user.User;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class SysUserDTO implements User {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 性别,0-未知,1-男,2-女
|
||||
*/
|
||||
private Integer gender;
|
||||
|
||||
/**
|
||||
* 状态,1:启用,2:禁用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 注册类型,1-系统,2-手动
|
||||
*/
|
||||
private String regType;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 添加时间
|
||||
*/
|
||||
private LocalDateTime addTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 创建人id
|
||||
*/
|
||||
private Long addBy;
|
||||
|
||||
/**
|
||||
* 修改人id
|
||||
*/
|
||||
private Long updateBy;
|
||||
|
||||
/**
|
||||
* 部门
|
||||
*/
|
||||
private SysDeptDTO dept;
|
||||
|
||||
@Override
|
||||
public Long getUserId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToken() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getShowName() {
|
||||
return nickname != null && !nickname.isEmpty() ? nickname : username;
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
package com.gitee.sop.admin.service.sys.dto;
|
||||
|
||||
import com.gitee.fastmybatis.core.query.Operator;
|
||||
import com.gitee.fastmybatis.core.query.annotation.Condition;
|
||||
import com.gitee.fastmybatis.core.query.param.PageParam;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 备注:角色表
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class SysUserSearchDTO extends PageParam {
|
||||
private static final long serialVersionUID = 7794265174728302379L;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@Condition(operator = Operator.like)
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
@Condition(operator = Operator.like)
|
||||
private String phone;
|
||||
|
||||
|
||||
/**
|
||||
* 状态,1:启用,2:禁用
|
||||
*/
|
||||
@Condition
|
||||
private Integer status;
|
||||
|
||||
@Condition(ignore = true)
|
||||
private Long deptId;
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
package com.gitee.sop.admin.service.sys.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class SysUserUpdateDTO {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@NotNull(message = "id必填")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 性别,0-未知,1-男,2-女
|
||||
*/
|
||||
private Integer gender;
|
||||
|
||||
/**
|
||||
* 状态,1:启用,2:禁用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 注册类型,1-系统,2-手动
|
||||
*/
|
||||
private String regType;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 修改人id
|
||||
*/
|
||||
private Long updateBy;
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package com.gitee.sop.admin.service.sys.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class SystemConfigDTO {
|
||||
private String configKey;
|
||||
|
||||
private String configValue;
|
||||
|
||||
private String remark;
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
package com.gitee.sop.admin.service.sys.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class UserPermissionDTO {
|
||||
|
||||
/**
|
||||
* 用户角色code
|
||||
*/
|
||||
private List<String> roles;
|
||||
|
||||
/**
|
||||
* 用户按钮级别code
|
||||
*/
|
||||
private List<String> permissions;
|
||||
|
||||
public static UserPermissionDTO empty() {
|
||||
UserPermissionDTO userPermissionDTO = new UserPermissionDTO();
|
||||
userPermissionDTO.setRoles(new ArrayList<>());
|
||||
userPermissionDTO.setPermissions(new ArrayList<>());
|
||||
return userPermissionDTO;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package com.gitee.sop.admin.service.sys.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户角色信息
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class UserRoleInfoDTO {
|
||||
|
||||
private Long userId;
|
||||
|
||||
private List<Long> roleIds;
|
||||
|
||||
private List<String> roleCodes;
|
||||
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
package com.gitee.sop.admin.service.sys.impl;
|
||||
|
||||
import com.gitee.sop.admin.common.user.User;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.dao.entity.SysUser;
|
||||
import com.gitee.sop.admin.service.sys.SysUserService;
|
||||
import com.gitee.sop.admin.service.sys.UserCacheService;
|
||||
import com.gitee.sop.admin.service.sys.dto.SysUserDTO;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public class LocalUserCacheService implements UserCacheService {
|
||||
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
|
||||
// key: configKey, value: configValue
|
||||
private final LoadingCache<Long, Optional<User>> configCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(30, TimeUnit.MINUTES)
|
||||
.build(new CacheLoader<Long, Optional<User>>() {
|
||||
@Override
|
||||
public Optional<User> load(Long key) throws Exception {
|
||||
return Optional.ofNullable(loadFromDb(key));
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public Optional<User> getUser(Long userId) {
|
||||
return configCache.getUnchecked(userId);
|
||||
}
|
||||
|
||||
private User loadFromDb(Long userId) {
|
||||
SysUser sysUser = sysUserService.getById(userId);
|
||||
return CopyUtil.copyBean(sysUser, SysUserDTO::new);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
List<SysUser> sysUsers = sysUserService.listAll();
|
||||
List<SysUserDTO> sysUserDTOS = CopyUtil.copyList(sysUsers, SysUserDTO::new);
|
||||
for (SysUserDTO sysUserDTO : sysUserDTOS) {
|
||||
configCache.put(sysUserDTO.getUserId(), Optional.of(sysUserDTO));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,148 @@
|
||||
package com.gitee.sop.admin.service.sys.login;
|
||||
|
||||
import com.gitee.sop.admin.common.config.Configs;
|
||||
import com.gitee.sop.admin.common.enums.ConfigKeyEnum;
|
||||
import com.gitee.sop.admin.common.enums.StatusEnum;
|
||||
import com.gitee.sop.admin.common.exception.BizException;
|
||||
import com.gitee.sop.admin.common.manager.UserCacheManager;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.common.util.DateUtil;
|
||||
import com.gitee.sop.admin.common.util.GenerateUtil;
|
||||
import com.gitee.sop.admin.common.util.JwtUtil;
|
||||
import com.gitee.sop.admin.dao.entity.SysUser;
|
||||
import com.gitee.sop.admin.service.sys.SysUserService;
|
||||
import com.gitee.sop.admin.service.sys.UserPermissionService;
|
||||
import com.gitee.sop.admin.service.sys.dto.UserPermissionDTO;
|
||||
import com.gitee.sop.admin.service.sys.login.dto.LoginDTO;
|
||||
import com.gitee.sop.admin.service.sys.login.dto.LoginForm;
|
||||
import com.gitee.sop.admin.service.sys.login.dto.LoginResult;
|
||||
import com.gitee.sop.admin.service.sys.login.dto.LoginUser;
|
||||
import com.gitee.sop.admin.service.sys.login.enums.RegTypeEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.bcrypt.BCrypt;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LoginService {
|
||||
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
@Autowired
|
||||
private UserCacheManager userCacheManager;
|
||||
@Autowired
|
||||
private UserPermissionService userPermissionService;
|
||||
|
||||
|
||||
public LoginUser login(LoginDTO loginDTO) {
|
||||
String username = loginDTO.getUsername();
|
||||
String password = loginDTO.getPassword();
|
||||
RegTypeEnum regType = loginDTO.getRegType();
|
||||
SysUser userInfo;
|
||||
switch (regType) {
|
||||
case FORM:
|
||||
throw new UnsupportedOperationException("第三方登录暂未支持");
|
||||
case LDAP:
|
||||
// LDAP登录
|
||||
throw new UnsupportedOperationException("LDAP登录登录暂未支持");
|
||||
default:
|
||||
// 默认注册账号登录
|
||||
userInfo = this.doDatabaseLogin(username, password);
|
||||
}
|
||||
LoginUser loginUser = buildLoginUser(userInfo);
|
||||
// 保存到缓存
|
||||
userCacheManager.saveUser(loginUser);
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
private LoginUser buildLoginUser(SysUser sysUser) {
|
||||
if (StatusEnum.of(sysUser.getStatus()) == StatusEnum.DISABLED) {
|
||||
throw new BizException("账号已禁用,请联系管理员");
|
||||
}
|
||||
// 登录成功
|
||||
LoginUser loginUser = CopyUtil.copyBean(sysUser, LoginUser::new);
|
||||
// 创建token
|
||||
String token = this.createToken(sysUser.getId());
|
||||
loginUser.setAccessToken(token);
|
||||
UserPermissionDTO userPermission = userPermissionService.getUserPermission(loginUser.getUserId());
|
||||
// 角色权限
|
||||
loginUser.setRoles(userPermission.getRoles());
|
||||
loginUser.setPermissions(userPermission.getPermissions());
|
||||
// 设置token过期时间
|
||||
String value = Configs.getValue(ConfigKeyEnum.JWT_TIMEOUT_DAYS);
|
||||
LocalDateTime expireDate = LocalDateTime.now().plusDays(NumberUtils.toInt(value));
|
||||
loginUser.setExpires(DateUtil.formatFrontDate(expireDate));
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
private String createToken(long userId) {
|
||||
Map<String, String> data = new HashMap<>(4);
|
||||
data.put("id", String.valueOf(userId));
|
||||
String value = Configs.getValue(ConfigKeyEnum.JWT_TIMEOUT_DAYS);
|
||||
return JwtUtil.createJwt(data, NumberUtils.toInt(value), getJwtSecret());
|
||||
}
|
||||
|
||||
public static String getJwtSecret() {
|
||||
return Configs.getValue(ConfigKeyEnum.JWT_SECRET);
|
||||
}
|
||||
|
||||
private SysUser doThirdPartyLogin(ThirdPartyLoginManager thirdPartyLoginManager, String username, String password) {
|
||||
LoginForm loginForm = new LoginForm();
|
||||
loginForm.setUsername(username);
|
||||
loginForm.setPassword(password);
|
||||
LoginResult loginResult;
|
||||
try {
|
||||
loginResult = thirdPartyLoginManager.login(loginForm);
|
||||
} catch (Exception e) {
|
||||
log.error("第三方登录失败", e);
|
||||
throw new BizException(e.getMessage());
|
||||
}
|
||||
|
||||
SysUser userInfo = sysUserService.getByUsername(username);
|
||||
|
||||
// 用户第一次登录则插入到user_info表
|
||||
if (userInfo == null) {
|
||||
userInfo = new SysUser();
|
||||
userInfo.setUsername(username);
|
||||
userInfo.setPassword(GenerateUtil.getUUID());
|
||||
userInfo.setNickname(loginResult.getNickname());
|
||||
userInfo.setAvatar("");
|
||||
userInfo.setStatus(StatusEnum.ENABLE.getValue());
|
||||
userInfo.setRegType(loginResult.getRegTypeEnum().getValue());
|
||||
userInfo.setEmail(loginResult.getEmail());
|
||||
sysUserService.save(userInfo);
|
||||
} else {
|
||||
String email = loginResult.getEmail();
|
||||
// 如果更改了邮箱
|
||||
if (StringUtils.hasText(email) && !Objects.equals(email, userInfo.getEmail())) {
|
||||
userInfo.setEmail(email);
|
||||
sysUserService.update(userInfo);
|
||||
}
|
||||
}
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
private SysUser doDatabaseLogin(String username, String password) {
|
||||
SysUser sysUser = sysUserService.getByUsername(username);
|
||||
Assert.notNull(sysUser, () -> "用户名密码不正确");
|
||||
String encodedPasswordDb = sysUser.getPassword();
|
||||
// 校验
|
||||
boolean flag = BCrypt.checkpw(password, encodedPasswordDb);
|
||||
Assert.isTrue(flag, () -> "用户名密码不正确");
|
||||
Assert.isTrue(Objects.equals(sysUser.getStatus(), StatusEnum.ENABLE.getValue()), () -> "用户已禁用");
|
||||
return sysUser;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
package com.gitee.sop.admin.service.sys.login;
|
||||
|
||||
/**
|
||||
* @author thc
|
||||
*/
|
||||
public class NotNullStringBuilder {
|
||||
|
||||
private final StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
public NotNullStringBuilder append(Number o) {
|
||||
stringBuilder.append(formatValue(o));
|
||||
return this;
|
||||
}
|
||||
|
||||
public NotNullStringBuilder append(String o) {
|
||||
stringBuilder.append(formatValue(o));
|
||||
return this;
|
||||
}
|
||||
|
||||
public NotNullStringBuilder append(String o, String defaultValue) {
|
||||
if (o == null || o.length() == 0) {
|
||||
o = defaultValue;
|
||||
}
|
||||
stringBuilder.append(formatValue(o));
|
||||
return this;
|
||||
}
|
||||
|
||||
private static String formatValue(Number o) {
|
||||
return o == null ? "0" : String.valueOf(o);
|
||||
}
|
||||
|
||||
private static String formatValue(String o) {
|
||||
return o == null ? "" : o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
package com.gitee.sop.admin.service.sys.login;
|
||||
|
||||
import com.gitee.sop.admin.service.sys.login.dto.LoginForm;
|
||||
import com.gitee.sop.admin.service.sys.login.dto.LoginResult;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public interface ThirdPartyLoginManager {
|
||||
|
||||
/**
|
||||
* 第三方登录
|
||||
* @param loginForm 登录表单
|
||||
* @return 返回登录结果
|
||||
*/
|
||||
LoginResult login(LoginForm loginForm) throws Exception;
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
package com.gitee.sop.admin.service.sys.login.dto;
|
||||
|
||||
import com.gitee.sop.admin.service.sys.login.enums.RegTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LoginDTO {
|
||||
private String username;
|
||||
private String password;
|
||||
private RegTypeEnum regType = RegTypeEnum.BACKEND;
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
package com.gitee.sop.admin.service.sys.login.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class LoginForm {
|
||||
private String username;
|
||||
private String password;
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package com.gitee.sop.admin.service.sys.login.dto;
|
||||
|
||||
import com.gitee.sop.admin.service.sys.login.enums.RegTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class LoginResult {
|
||||
|
||||
private String username;
|
||||
|
||||
private String nickname;
|
||||
|
||||
private String email;
|
||||
|
||||
private RegTypeEnum regTypeEnum = RegTypeEnum.FORM;
|
||||
|
||||
}
|
@@ -0,0 +1,83 @@
|
||||
package com.gitee.sop.admin.service.sys.login.dto;
|
||||
|
||||
import com.gitee.sop.admin.common.user.User;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class LoginUser implements User {
|
||||
|
||||
/*
|
||||
avatar: "https://avatars.githubusercontent.com/u/44761321",
|
||||
username: "admin",
|
||||
nickname: "小铭",
|
||||
// 一个用户可能有多个角色
|
||||
roles: ["admin"],
|
||||
// 按钮级别权限
|
||||
permissions: ["*:*:*"],
|
||||
accessToken: "eyJhbGciOiJIUzUxMiJ9.admin",
|
||||
refreshToken: "eyJhbGciOiJIUzUxMiJ9.adminRefresh",
|
||||
expires: "2030/10/30 00:00:00"
|
||||
*/
|
||||
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 注册类型
|
||||
*/
|
||||
private Integer regType;
|
||||
|
||||
/**
|
||||
* 状态,1:启用,0:禁用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
private List<String> roles;
|
||||
|
||||
private List<String> permissions;
|
||||
|
||||
private String accessToken;
|
||||
|
||||
private String refreshToken;
|
||||
|
||||
private String expires;
|
||||
|
||||
@Override
|
||||
public Long getUserId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToken() {
|
||||
return accessToken;
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package com.gitee.sop.admin.service.sys.login.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum RegTypeEnum {
|
||||
BACKEND("backend"),
|
||||
FORM("form"),
|
||||
OAUTH("oauth"),
|
||||
LDAP("ldap");
|
||||
|
||||
public static RegTypeEnum of(String source) {
|
||||
for (RegTypeEnum value : RegTypeEnum.values()) {
|
||||
if (Objects.equals(source, value.value)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return RegTypeEnum.BACKEND;
|
||||
}
|
||||
|
||||
private final String value;
|
||||
}
|
@@ -0,0 +1,90 @@
|
||||
package com.gitee.sop.admin.service.sys.login.impl;
|
||||
|
||||
import com.gitee.sop.admin.common.enums.StatusEnum;
|
||||
import com.gitee.sop.admin.common.manager.UserCacheManager;
|
||||
import com.gitee.sop.admin.common.user.User;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.dao.entity.SysUser;
|
||||
import com.gitee.sop.admin.service.sys.SysUserService;
|
||||
import com.gitee.sop.admin.service.sys.login.dto.LoginUser;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class DefaultUserCacheManager implements UserCacheManager, InitializingBean {
|
||||
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
|
||||
@Value("${admin.user-cache-timeout-minutes:15}")
|
||||
private int timeoutMinutes;
|
||||
|
||||
// key: userId
|
||||
private LoadingCache<Long, Optional<User>> userCache;
|
||||
|
||||
@Override
|
||||
public User getUser(long userId) {
|
||||
return userCache.getUnchecked(userId).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveUser(User user) {
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
userCache.put(user.getUserId(), Optional.of(user));
|
||||
}
|
||||
|
||||
private LoadingCache<Long, Optional<User>> buildCache(int timeout) {
|
||||
if (timeout <= 0) {
|
||||
throw new IllegalArgumentException("timeout must be gt 0");
|
||||
}
|
||||
CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder();
|
||||
cacheBuilder.expireAfterAccess(timeout, TimeUnit.MINUTES);
|
||||
return cacheBuilder
|
||||
.build(new CacheLoader<Long, Optional<User>>() {
|
||||
@Override
|
||||
public Optional<User> load(Long id) throws Exception {
|
||||
User user = getLoginUser(id);
|
||||
return Optional.ofNullable(user);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登陆用户
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
private User getLoginUser(long id) {
|
||||
SysUser userInfo = sysUserService.getById(id);
|
||||
if (userInfo == null) {
|
||||
log.warn("登录用户不存在,userId:{}", id);
|
||||
return null;
|
||||
}
|
||||
if (userInfo.getStatus() == StatusEnum.DISABLED.getValue()) {
|
||||
log.warn("用户被禁用, userId:{}, username:{}, nickname:{}", userInfo.getId(), userInfo.getUsername(), userInfo.getNickname());
|
||||
return null;
|
||||
}
|
||||
return CopyUtil.copyBean(userInfo, LoginUser::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
userCache = buildCache(timeoutMinutes);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
package com.gitee.sop.admin.service.website;
|
||||
|
||||
import com.gitee.fastmybatis.core.util.TreeUtil;
|
||||
import com.gitee.sop.admin.common.constants.YesOrNo;
|
||||
import com.gitee.sop.admin.common.util.CopyUtil;
|
||||
import com.gitee.sop.admin.dao.entity.DocApp;
|
||||
import com.gitee.sop.admin.dao.entity.DocInfo;
|
||||
import com.gitee.sop.admin.service.doc.DocAppService;
|
||||
import com.gitee.sop.admin.service.doc.DocInfoService;
|
||||
import com.gitee.sop.admin.service.doc.DocSettingService;
|
||||
import com.gitee.sop.admin.service.doc.dto.DocAppDTO;
|
||||
import com.gitee.sop.admin.service.doc.dto.DocInfoConfigDTO;
|
||||
import com.gitee.sop.admin.service.doc.dto.DocInfoTreeDTO;
|
||||
import com.gitee.sop.admin.service.doc.dto.DocInfoViewDTO;
|
||||
import com.gitee.sop.admin.service.doc.dto.DocSettingDTO;
|
||||
import com.gitee.sop.admin.service.doc.dto.torna.TornaDocInfoViewDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class WebsiteService {
|
||||
|
||||
@Autowired
|
||||
private DocAppService docAppService;
|
||||
@Autowired
|
||||
private DocInfoService docInfoService;
|
||||
@Autowired
|
||||
private DocSettingService docSettingService;
|
||||
|
||||
public List<DocAppDTO> listDocApp() {
|
||||
List<DocApp> docApps = docAppService.list(DocApp::getIsPublish, YesOrNo.YES);
|
||||
return CopyUtil.copyList(docApps, DocAppDTO::new);
|
||||
}
|
||||
|
||||
public List<DocInfoTreeDTO> listDocMenuTree(Long docAppId) {
|
||||
List<DocInfo> list = docInfoService.query()
|
||||
.eq(DocInfo::getDocAppId, docAppId)
|
||||
.eq(DocInfo::getIsPublish, YesOrNo.YES)
|
||||
.list();
|
||||
List<DocInfoTreeDTO> treeList = CopyUtil.copyList(list, DocInfoTreeDTO::new);
|
||||
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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user