Compare commits

..

No commits in common. "master" and "dev_PMS_ZPK" have entirely different histories.

827 changed files with 3840 additions and 59350 deletions

1
.gitignore vendored
View File

@ -43,7 +43,6 @@ nbdist/
*.log
*.xml.versionsBackup
*.swp
logs
!*/build/*.java
!*/build/*.html

View File

@ -1,36 +0,0 @@
## 系统模块
~~~
com.microservices
├── microservices-ui // 前端框架
├── microservices-gateway // 网关模块
├── microservices-auth // 认证中心
├── microservices-api // 接口模块
│ └── microservices-api-system // 系统接口
├── microservices-common // 通用模块
│ └── microservices-common-async // 异步线程池配置
│ └── microservices-common-core // 核心模块
│ └── microservices-common-datascope // 权限范围
│ └── microservices-common-datasource // 多数据源
│ └── microservices-common-httpClient // http调用
│ └── microservices-common-log // 日志记录
│ └── microservices-common-redis // 缓存服务
│ └── microservices-common-seata // seata分布式事务
│ └── microservices-common-security // 安全模块
│ └── microservices-common-swagger // 系统接口
├── microservices-modules // 业务模块
│ └── microservices-cms // 内容管理模块
│ └── microservices-dms // 数据管理体系模块
│ └── microservices-dss // 数据统计系统模块
│ └── microservices-file // 文件服务
│ └── microservices-gen // 代码生成
│ └── microservices-job // 定时任务
│ └── microservices-pms // 项目管理系统模块
│ └── microservices-system // 系统模块
│ └── microservices-wiki // Wiki模块
│ └── microservices-zone // 特色专区系统模块
├── microservices-visual // 图形化管理模块
│ └── microservices-visual-monitor // 监控中心
├──pom.xml // 公共依赖
~~~

View File

@ -1,6 +1,5 @@
package com.microservices.system.api;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.constant.SecurityConstants;
import com.microservices.common.core.constant.ServiceNameConstants;
import com.microservices.common.core.domain.R;
@ -9,8 +8,6 @@ import com.microservices.system.api.factory.RemoteCmsFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 用户服务
*
@ -32,8 +29,6 @@ public interface RemoteCmsService {
@PathVariable("userId") Long userId
, @RequestParam("oldDeptId") Long oldDeptId
, @RequestParam("newDeptId") Long newDeptId
, @RequestParam("oldRoleId") Long oldRoleId
, @RequestParam("newRoleId") Long newRoleId
, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
@ -47,17 +42,6 @@ public interface RemoteCmsService {
public R<Long> getCmsCountByDeptId(@PathVariable(value = "deptId") Long deptId
, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 通过组织Id获取专区下文章阅读数量
*
* @param deptId 组织id
* @param source 来源
* @return 结果
*/
@GetMapping("/doc/getCmsDocVisitsByDeptId/{deptId}")
public R<Long> getCmsDocVisitsByDeptId(@PathVariable(value = "deptId") Long deptId
, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 通过组织Id获取专区下待审核文章数量
*
@ -156,26 +140,4 @@ public interface RemoteCmsService {
@DeleteMapping("/project/removeByDeptId/{deptId}")
public R<Boolean> removeByDeptId(@PathVariable(value = "deptId") Long deptId
, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
@GetMapping("/doc/getJSONObject/{cmsDocId}")
R<JSONObject> selectCmsDocJSONObjectById(@PathVariable(value = "cmsDocId") Long cmsDocId
, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
@PutMapping("/project/changeOrgRole/user/{userId}/operate/{operate}")
R<Boolean> changeUserOrgRole(@PathVariable("userId") Long userId, @PathVariable("operate") int operate
, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 首页文章合并列表接收置顶文章 docId 有序列表返回合并去重后的结果
* Zone 服务 /open/getTopDoc 改造后调用
*
* @param zoneId 专区ID
* @param topDocIds 置顶文章 docId 有序列表
* @param source 来源
* @return 合并后的首页文章 JSONObject 列表
*/
@PostMapping("/doc/homePageDocMergeList/{zoneId}")
R<List<JSONObject>> selectHomePageDocMergeList(@PathVariable("zoneId") Long zoneId,
@RequestBody List<Long> topDocIds,
@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@ -85,7 +85,7 @@ public interface RemoteDeptService {
* 根据组织id删除部门
*
* @param deptId 部门id
* @param source 请求来源
* @param source 请求来源
* @return 是否删除成功
*/
@DeleteMapping("/dept/deleteDeptByDeptId")
@ -105,7 +105,7 @@ public interface RemoteDeptService {
* 通过用户名查询用户下组织及组织对应角色列表
*
* @param deptId 组织ID
* @param source 请求来源
* @param source 请求来源
* @return 用户下组织及组织对应角色列表
*/
@GetMapping("/SysUserDeptRole/userByDeptId/{deptId}/list")
@ -115,7 +115,7 @@ public interface RemoteDeptService {
/**
* 查询组织编号下拥有传入角色权限字符串的用户名
*
* @param deptId 组织编号
* @param deptId 组织编号
* @param roleKeys 角色权限字符串
* @return 组织下拥有传入角色权限字符串的用户名列表
*/
@ -126,7 +126,7 @@ public interface RemoteDeptService {
* 检查用户是否在指定部门下具有指定角色
*
* @param currentDeptId 组织编号
* @param roleKey 角色权限字符串
* @param roleKey 角色权限字符串
* @return 组织下拥有传入角色权限字符串的用户名列表
*/
@GetMapping("/SysUserDeptRole/checkUserInDeptHasRole")
@ -143,17 +143,6 @@ public interface RemoteDeptService {
@GetMapping("/SysUserDeptRole/checkUserInDeptHasPerms")
R<Boolean> checkUserInDeptHasPerms(@RequestParam("currentDeptId") Long currentDeptId, @RequestParam("userId") Long userId, @RequestParam("perms") String perms, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 检查用户是否在指定部门或指定部门的父级部门下具有指定菜单权限
*
* @param deptId 指定组织id
* @param userId 用户id
* @param perms 菜单权限
* @return 用户是否在指定部门下具有菜单权限 是true 否false
*/
@GetMapping("/SysUserDeptRole/checkUserInDeptOrParentDeptHasPerms")
R<Boolean> checkUserInDeptOrParentDeptHasPerms(@RequestParam("deptId") Long deptId, @RequestParam("userId") Long userId, @RequestParam("perms") String perms, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 检查用户是否在指定部门下
*
@ -163,7 +152,4 @@ public interface RemoteDeptService {
*/
@GetMapping("/SysUserDeptRole/checkUserInDept")
R<Boolean> checkUserInDept(@RequestParam("currentDeptId") Long currentDeptId, @RequestParam("userId") Long userId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
@GetMapping("/SysUserDeptRole/getSysUserDeptRoleByDeptIdAndUserId")
R<SysUserDeptRole> getSysUserDeptRoleByDeptIdAndUserId(@RequestParam("deptId") Long deptId, @RequestParam("userId") Long userId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@ -6,13 +6,12 @@ import com.microservices.common.core.domain.R;
import com.microservices.system.api.domain.SysFile;
import com.microservices.system.api.domain.SysFileInfo;
import com.microservices.system.api.factory.RemoteFileFallbackFactory;
import feign.Response;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.io.File;
import java.util.List;
/**
@ -29,10 +28,7 @@ public interface RemoteFileService {
* @return 结果
*/
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<SysFile> upload(@RequestPart(value = "file") MultipartFile file,
@RequestParam("type") String type,
@RequestParam("hierarchy") String hierarchy,
@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
public R<SysFile> upload(@RequestPart(value = "file") MultipartFile file);
/**
* 根据文件Id列表获取文件列表
@ -52,16 +48,6 @@ public interface RemoteFileService {
@GetMapping("/open/getFile/{fileId}")
public R<SysFileInfo> getFile(@PathVariable("fileId") Long fileId);
/**
* 根据文件Id获取文件信息
*
* @param fileIdentifier 文件标识
* @return 结果
*/
@GetMapping("/common/getFileByFileIdentifier/{fileIdentifier}")
public R<SysFileInfo> getFileByFileIdentifier(@PathVariable("fileIdentifier") String fileIdentifier,
@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 根据文件标识列表获取文件详情列表
*
@ -85,46 +71,9 @@ public interface RemoteFileService {
* 根据文件标识获取文件实体
*
* @param fileIdentifier 文件标识
* @return 文件实体
*/
@GetMapping("/common/getFileEntityByIdentifier/{fileIdentifier}")
Response getFileEntityByIdentifier(@PathVariable("fileIdentifier") String fileIdentifier,
@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 打包文件
*
* @param packagedStructure 打包结构<文件包内路径,文件来源文件标识或文件下载地址>
* @param zipFileName 压缩文件名不包含文件后缀
* @param type 微服务类型
* @param hierarchy 层次结构
* @param source 鉴权
* @return 压缩包文件标识
*/
@PostMapping(value = "/common/packagedFile")
R<String> packagedFile(
@RequestBody HashMap<String, String> packagedStructure,
@RequestParam("zipFileName") String zipFileName,
@RequestParam("type") String type,
@RequestParam("hierarchy") String hierarchy,
@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 通过Url下载文件到本地
*/
@PostMapping(value = "/common/downloadFileByUrl")
R<String> downloadFileByUrl(
@RequestParam("fileUrl") String fileUrl
, @RequestParam("type") String type
, @RequestParam("hierarchy") String hierarchy,
@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 上传本地文件到Forge
*
* @param fileIdentifiers 文件标识列表逗号分隔
* @return Forge文件标识列表
*/
@PostMapping(value = "/common/uploadFileToForge/{fileIdentifiers}")
R<List<String>> uploadFileToForge(@PathVariable("fileIdentifiers") String fileIdentifiers,
R<File> getFileEntityByIdentifier(@PathVariable("fileIdentifier") String fileIdentifier,
@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@ -1,46 +0,0 @@
package com.microservices.system.api;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.constant.ServiceNameConstants;
import com.microservices.system.api.factory.RemoteGatewayFallbackFactory;
import feign.Response;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Map;
/**
* 网关
*
* @author microservices
*/
@Component
@FeignClient(contextId = "remoteGatewayService", value = ServiceNameConstants.GATEWAY_SERVICE, fallbackFactory = RemoteGatewayFallbackFactory.class)
public interface RemoteGatewayService {
/**
* 登录Sentinel
*
* @return 响应
*/
@PostMapping("/sentinel/auth/login")
Response loginSentinel(@RequestParam("username") String username, @RequestParam("password") String password);
/**
* 登录Nacos
*
* @return 响应
*/
@PostMapping(value = "/nacos/v1/auth/users/login", consumes = {"application/x-www-form-urlencoded"})
Response loginNacos(Map<String, ?> formParams);
/**
* 登录Portainer
*
* @return 响应
*/
@PostMapping("/portainer/api/auth")
Response loginPortainer(@RequestBody JSONObject loginBody);
}

View File

@ -7,9 +7,9 @@ import com.microservices.system.api.domain.SysLogininfor;
import com.microservices.system.api.domain.SysOperLog;
import com.microservices.system.api.factory.RemoteLogFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
/**
* 日志服务
@ -38,20 +38,4 @@ public interface RemoteLogService
*/
@PostMapping("/logininfor")
public R<Boolean> saveLogininfor(@RequestBody SysLogininfor sysLogininfor, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 获取操作日志列表
*
* @param title 日志标题
* @param operUrl 操作地址
* @param status 操作状态
* @param topN 获取最新N条
* @return 操作日志列表
*/
@GetMapping("/operlog/latest")
R<List<SysOperLog>> getLatestOperLogList(@RequestParam(value = "title", required = false) String title,
@RequestParam(value = "operUrl", required = false) String operUrl,
@RequestParam(value = "status", required = false) Integer status,
@RequestParam(value = "topN") Integer topN,
@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@ -57,15 +57,6 @@ public interface RemoteUserService {
@GetMapping("/user/getSysUserByUserId/{userId}")
public R<SysUser> getSysUserByUserId(@PathVariable("userId") Long userId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 通过用户ID数组批量获取用户信息POST方法解决URL长度限制
*
* @param userIds 用户ID数组
* @param source 请求来源
* @return 结果
*/
@PostMapping("/user/getSysUserListByUserIds")
R<List<SysUser>> postSysUserListByUserIds(@RequestBody Long[] userIds, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 组织下新增用户身份
@ -73,7 +64,7 @@ public interface RemoteUserService {
* @param deptId
* @param userId
* @param roleKey
* @param source 请求来源
* @param source 请求来源
* @return 结果
*/
@PostMapping("/SysUserDeptRole/dept/{deptId}/user/{userId}/role/{roleKey}")
@ -83,13 +74,14 @@ public interface RemoteUserService {
, @PathVariable("roleKey") String roleKey
, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 组织下删除用户身份
*
* @param deptId
* @param userId
* @param roleKey
* @param source 请求来源
* @param source 请求来源
* @return 结果
*/
@DeleteMapping("/SysUserDeptRole/dept/{deptId}/user/{userId}/role/{roleKey}")
@ -99,16 +91,18 @@ public interface RemoteUserService {
@PathVariable("roleKey") String roleKey,
@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 注册用户信息
*
* @param sysUser 用户信息
* @param source 请求来源
* @param source 请求来源
* @return 结果
*/
@PostMapping("/user/register")
public R<Boolean> registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 通过GitLinkToken获取本系统Token
*
@ -129,6 +123,7 @@ public interface RemoteUserService {
@GetMapping("/SysUserDeptRole/userByUserName/{userName}/list")
public R<List<SysUserDeptRole>> getSysUserDeptRoleListByUserName(@PathVariable("userName") String userName, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 通过用户名查询用户下第一个身份
*
@ -200,7 +195,7 @@ public interface RemoteUserService {
/**
* 通过GitLink用户Id创建用户
*
* @param gitLinkUserId GitLinkUserId
* @param gitLinkUserId GitLink用户Id
* @param source 请求来源
* @return 系统用户
*/
@ -211,24 +206,11 @@ public interface RemoteUserService {
* 根据角色Key获取菜单权限集合
*
* @param roleKey 角色Key
* @param source 请求来源
* @param source 请求来源
* @return 菜单权限集合
*/
@GetMapping("/menu/roleMenuPermissionByRoleKey/{roleKey}")
R<Set<String>> selectMenuPermissionByRoleKey(@PathVariable("roleKey") String roleKey
, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 根据部门Id和用户Id获取所有状态的用户身份
*
* @param deptId 组织Id
* @param userId 用户Id
* @param source 请求来源
* @return 用户身份
*/
@GetMapping("/SysUserDeptRole/dept/{deptId}/user/{userId}/allStatus")
R<SysUserDeptRole> getAllStatusUserIdentityByDeptIdAndUserId(
@PathVariable("deptId") Long deptId,
@PathVariable("userId") Long userId,
@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@ -4,7 +4,7 @@ import com.microservices.common.core.constant.SecurityConstants;
import com.microservices.common.core.constant.ServiceNameConstants;
import com.microservices.common.core.domain.R;
import com.microservices.system.api.domain.SysDept;
import com.microservices.system.api.factory.RemoteZoneFallbackFactory;
import com.microservices.system.api.factory.RemoteCmsFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
@ -15,7 +15,7 @@ import java.util.List;
*
* @author microservices
*/
@FeignClient(contextId = "remoteZoneService", value = ServiceNameConstants.ZONE_SERVICE, fallbackFactory = RemoteZoneFallbackFactory.class)
@FeignClient(contextId = "remoteZoneService", value = ServiceNameConstants.ZONE_SERVICE, fallbackFactory = RemoteCmsFallbackFactory.class)
public interface RemoteZoneService {
/**
* 新增组织时自动创建特色专区

View File

@ -1,19 +1,15 @@
package com.microservices.system.api.domain;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 文件信息
*
* @author microservices
*/
@Data
public class SysFile
{
/**
* 文件标识
*/
private String fileIdentifier;
/**
* 文件名称
*/
@ -23,4 +19,32 @@ public class SysFile
* 文件地址
*/
private String url;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getUrl()
{
return url;
}
public void setUrl(String url)
{
this.url = url;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("name", getName())
.append("url", getUrl())
.toString();
}
}

View File

@ -1,23 +0,0 @@
package com.microservices.system.api.domain;
import lombok.Data;
import java.io.InputStream;
/**
* 文件流
*
* @author microservices
*/
@Data
public class SysFileBytes {
/**
* 文件名称
*/
private String fileName;
/**
* 文件流
*/
private InputStream fileInputStream;
}

View File

@ -1,13 +1,10 @@
package com.microservices.system.api.domain;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.microservices.common.core.utils.file.FileUtils;
import com.microservices.common.core.web.domain.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.File;
/**
* 文件管理对象 sys_file_info
*
@ -106,21 +103,6 @@ public class SysFileInfo extends BaseEntity {
@ApiModelProperty(value = "是否部分匹配")
private Integer isPartialMatch;
public SysFileInfo() {
}
public SysFileInfo(String fileIdentifier, File file, String filePath) {
System.out.println(file.getPath());
this.setFileIdentifier(fileIdentifier);
this.setFilePath(filePath);
this.setFileSizeInfo(FileUtils.calcFileSize(file.length()));
this.setFileOriginName(file.getName());
this.setDelFlag("N");
this.setFileOriginName(file.getName());
int separatorIndex = file.getName().lastIndexOf(".");
this.setFileSuffix(file.getName().substring(separatorIndex + 1).toLowerCase());
}
public SimpleGitlinkFileInfo toSimpleGitlinkFileInfo(){
SimpleGitlinkFileInfo simpleGitlinkFileInfo=new SimpleGitlinkFileInfo();
simpleGitlinkFileInfo.setId(this.getFileId());

View File

@ -3,8 +3,6 @@ package com.microservices.system.api.domain;
import com.microservices.common.core.annotation.Excel;
import com.microservices.common.core.annotation.Excel.ColumnType;
import com.microservices.common.core.annotation.Excel.Type;
import com.microservices.common.core.constant.UserConstants;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.core.utils.bean.BeanUtils;
import com.microservices.common.core.utils.html.EscapeUtil;
import com.microservices.common.core.web.domain.BaseEntity;
@ -97,10 +95,8 @@ public class SysUser extends BaseEntity {
public SimpleSysUser toSimpleSysUser(String gitlinkBaseUrl) {
SimpleSysUser target = new SimpleSysUser();
BeanUtils.copyProperties(this, target);
if (StringUtils.isNotEmpty(this.userName)) {
String gitlinkUrl = EscapeUtil.removeExtraSlashOfUrl(gitlinkBaseUrl + "/" + this.userName);
target.setGitlinkUrl(gitlinkUrl);
}
String gitlinkUrl = EscapeUtil.removeExtraSlashOfUrl(gitlinkBaseUrl + "/" + this.userName);
target.setGitlinkUrl(gitlinkUrl);
return target;
}
@ -157,27 +153,4 @@ public class SysUser extends BaseEntity {
{
return phonenumber;
}
/**
* 设置已注销账户信息
*
* @return 已注销用户
*/
public SysUser toDeleteUser() {
SysUser sysUser = new SysUser();
sysUser.setUserId(this.userId);
sysUser.setGitlinkUserId(this.gitlinkUserId);
sysUser.setAvatar(UserConstants.DELETE_USER_AVATAR);
sysUser.setNickName(UserConstants.DELETE_USER_NICKNAME);
return sysUser;
}
public static SysUser genDeleteUser() {
SysUser sysUser = new SysUser();
sysUser.setUserId(-1L);
sysUser.setGitlinkUserId(-1L);
sysUser.setAvatar(UserConstants.DELETE_USER_AVATAR);
sysUser.setNickName(UserConstants.DELETE_USER_NICKNAME);
return sysUser;
}
}

View File

@ -2,11 +2,11 @@ package com.microservices.system.api.domain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Objects;
/**
* @author otto
*/
@Data
@ApiModel("用户与部门及部门对应角色的关联对象")
public class SysUserDeptRole {
@ -30,9 +30,6 @@ public class SysUserDeptRole {
@ApiModelProperty("角色ID")
private Long roleId;
@ApiModelProperty("身份状态")
private String state;
/**
* 部门对象
*/
@ -48,4 +45,81 @@ public class SysUserDeptRole {
*/
@ApiModelProperty(value = "角色对象", hidden = true)
private SysRole sysRole;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SysUserDeptRole that = (SysUserDeptRole) o;
return deptId.equals(that.deptId) && userId.equals(that.userId) && roleId.equals(that.roleId);
}
@Override
public int hashCode() {
return Objects.hash(deptId, userId, roleId);
}
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Long getRoleId() {
return roleId;
}
public void setRoleId(Long roleId) {
this.roleId = roleId;
}
public SysDept getSysDept() {
return sysDept;
}
public void setSysDept(SysDept sysDept) {
this.sysDept = sysDept;
}
public SysUser getSysUser() {
return sysUser;
}
public void setSysUser(SysUser sysUser) {
this.sysUser = sysUser;
}
public SysRole getSysRole() {
return sysRole;
}
public void setSysRole(SysRole sysRole) {
this.sysRole = sysRole;
}
@Override
public String toString() {
return "SysUserDeptRole{" +
"deptId=" + deptId +
", userId=" + userId +
", roleId=" + roleId +
", sysDept=" + sysDept +
", sysUser=" + sysUser +
", sysRole=" + sysRole +
'}';
}
}

View File

@ -1,6 +1,5 @@
package com.microservices.system.api.factory;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.domain.R;
import com.microservices.system.api.RemoteCmsService;
import com.microservices.system.api.domain.SysDept;
@ -9,8 +8,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 内容管理服务降级处理
*
@ -24,10 +21,8 @@ public class RemoteCmsFallbackFactory implements FallbackFactory<RemoteCmsServic
public RemoteCmsService create(Throwable throwable) {
log.error("Cms服务调用失败:{}", throwable.getMessage());
return new RemoteCmsService() {
@Override
public R<Boolean> changeUserRole(Long userId, Long oldDeptId, Long newDeptId, Long oldRoleId, Long newRoleId, String source) {
public R<Boolean> changeUserRole(Long userId, Long oldDeptId, Long newDeptId, String source) {
return R.fail("修改用户在GitLInk项目中的权限失败:" + throwable.getMessage());
}
@ -36,11 +31,6 @@ public class RemoteCmsFallbackFactory implements FallbackFactory<RemoteCmsServic
return R.fail("通过组织Id获取专区下文章数量失败:" + throwable.getMessage());
}
@Override
public R<Long> getCmsDocVisitsByDeptId(Long deptId, String source) {
return R.fail("通过组织Id获取专区下文章阅读数量失败:" + throwable.getMessage());
}
@Override
public R<Long> getNotAuditCmsCountByDeptId(Long deptId, String source) {
return R.fail("通过组织Id获取专区下待审核文章数量失败:" + throwable.getMessage());
@ -80,21 +70,6 @@ public class RemoteCmsFallbackFactory implements FallbackFactory<RemoteCmsServic
public R<Boolean> removeByDeptId(Long deptId, String source) {
return R.fail("删除专区项目失败:" + throwable.getMessage());
}
@Override
public R<JSONObject> selectCmsDocJSONObjectById(Long cmsDocId, String source) {
return R.fail("获取文章JSON对象失败:" + throwable.getMessage());
}
@Override
public R<Boolean> changeUserOrgRole(Long userId, int operate, String source) {
return R.fail("更新组织权限失败:" + throwable.getMessage());
}
@Override
public R<List<JSONObject>> selectHomePageDocMergeList(Long zoneId, List<Long> topDocIds, String source) {
return R.fail("获取首页文章合并列表失败:" + throwable.getMessage());
}
};
}
}

View File

@ -83,20 +83,10 @@ public class RemoteDeptFallbackFactory implements FallbackFactory<RemoteDeptServ
return R.fail("检查用户是否在指定部门下具有指定菜单权限失败:" + throwable.getMessage());
}
@Override
public R<Boolean> checkUserInDeptOrParentDeptHasPerms(Long deptId, Long userId, String perms, String source) {
return R.fail("检查用户是否在指定部门或指定部门的父级部门下具有指定菜单权限失败:" + throwable.getMessage());
}
@Override
public R<Boolean> checkUserInDept(Long currentDeptId, Long userId, String source) {
return R.fail("检查用户是否在指定部门下失败:" + throwable.getMessage());
}
@Override
public R<SysUserDeptRole> getSysUserDeptRoleByDeptIdAndUserId(Long deptId, Long userId, String source) {
return R.fail("获取用户在指定部门下的角色失败:" + throwable.getMessage());
}
};
}
}

View File

@ -1,18 +1,16 @@
package com.microservices.system.api.factory;
import com.microservices.common.core.domain.R;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.system.api.RemoteFileService;
import com.microservices.system.api.domain.SysFile;
import com.microservices.system.api.domain.SysFileInfo;
import feign.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.io.File;
import java.util.List;
/**
@ -30,9 +28,8 @@ public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileServ
{
log.error("文件服务调用失败:{}", throwable.getMessage());
return new RemoteFileService() {
@Override
public R<SysFile> upload(MultipartFile file, String type, String hierarchy, String source) {
public R<SysFile> upload(MultipartFile file) {
return R.fail("上传文件失败:" + throwable.getMessage());
}
@ -46,11 +43,6 @@ public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileServ
return R.fail("根据文件Id获取文件信息失败:" + throwable.getMessage());
}
@Override
public R<SysFileInfo> getFileByFileIdentifier(String fileIdentifier, String source) {
return R.fail("根据文件标识获取文件信息失败:" + throwable.getMessage());
}
@Override
public R<List<SysFileInfo>> getFileListByIdentifier(String fileIdentifiers) {
return R.fail("根据文件标识列表获取文件详情列表失败:" + throwable.getMessage());
@ -62,23 +54,8 @@ public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileServ
}
@Override
public Response getFileEntityByIdentifier(String fileIdentifier, String source) {
throw new ServiceException("文件获取失败:" + throwable.getMessage());
}
@Override
public R<String> packagedFile(HashMap<String, String> packagedStructure, String zipFileName, String type, String hierarchy, String source) {
return R.fail("打包文件失败:" + throwable.getMessage());
}
@Override
public R<String> downloadFileByUrl(String fileUrl, String type, String hierarchy, String source) {
return R.fail("通过Url下载文件到本地失败:" + throwable.getMessage());
}
@Override
public R<List<String>> uploadFileToForge(String fileIdentifiers, String source) {
return R.fail("上传本地文件到Forge失败:" + throwable.getMessage());
public R<File> getFileEntityByIdentifier(String fileIdentifier, String source) {
return R.fail("根据文件标识获取文件实体失败:" + throwable.getMessage());
}
};
}

View File

@ -1,44 +0,0 @@
package com.microservices.system.api.factory;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.system.api.RemoteGatewayService;
import feign.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 用户服务降级处理
*
* @author microservices
*/
@Component
public class RemoteGatewayFallbackFactory implements FallbackFactory<RemoteGatewayService> {
private static final Logger log = LoggerFactory.getLogger(RemoteGatewayFallbackFactory.class);
@Override
public RemoteGatewayService create(Throwable throwable) {
log.error("网关服务调用失败:{}", throwable.getMessage());
return new RemoteGatewayService() {
@Override
public Response loginSentinel(String password, String username) {
return null;
}
@Override
public Response loginNacos(Map<String, ?> formParams) {
return null;
}
@Override
public Response loginPortainer(JSONObject loginBody) {
System.out.println(throwable.getMessage());
return null;
}
};
}
}

View File

@ -9,8 +9,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 日志服务降级处理
*
@ -38,12 +36,6 @@ public class RemoteLogFallbackFactory implements FallbackFactory<RemoteLogServic
{
return null;
}
@Override
public R<List<SysOperLog>> getLatestOperLogList(String title, String operUrl, Integer status, Integer topN, String source)
{
return R.fail("获取最新操作日志失败:" + throwable.getMessage());
}
};
}

View File

@ -52,12 +52,6 @@ public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserServ
return R.fail("获取用户失败:" + throwable.getMessage());
}
@Override
public R<List<SysUser>> postSysUserListByUserIds(Long[] userIds, String source) {
return R.fail("批量获取用户失败:" + throwable.getMessage());
}
@Override
public R<Boolean> addUserIdentify(Long deptId, Long userId, String roleKey, String source) {
return R.fail("组织下新增用户身份失败:" + throwable.getMessage());
@ -123,11 +117,6 @@ public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserServ
public R<Set<String>> selectMenuPermissionByRoleKey(String roleKey, String source) {
return R.fail("根据角色Key获取菜单权限集合失败:" + throwable.getMessage());
}
@Override
public R<SysUserDeptRole> getAllStatusUserIdentityByDeptIdAndUserId(Long deptId, Long userId, String source) {
return R.fail("根据部门Id和用户Id获取所有状态的用户身份失败:" + throwable.getMessage());
}
};
}
}

View File

@ -5,4 +5,3 @@ com.microservices.system.api.factory.RemoteFileFallbackFactory
com.microservices.system.api.factory.RemoteCmsFallbackFactory
com.microservices.system.api.factory.RemoteZoneFallbackFactory
com.microservices.system.api.factory.RemotePmsFallbackFactory
com.microservices.system.api.factory.RemoteGatewayFallbackFactory

View File

@ -5,7 +5,8 @@ package com.microservices.common.core.constant;
*
* @author microservices
*/
public class CacheConstants {
public class CacheConstants
{
/**
* 缓存有效期默认720分钟
*/
@ -80,10 +81,6 @@ public class CacheConstants {
* 通过组织Id获取专区详情JSON对象
*/
public final static String ZONE_JSON_OF_DEPT_ID_KEY = "zoneJSONOfDeptId:";
/**
* 积分发放部门
*/
public final static String ZONE_POINTS_DEPT_ID_KEY = "zonePointsDeptId";
/**
* 内容管理同步缓存前缀
*/
@ -170,24 +167,6 @@ public class CacheConstants {
return ENTERPRISE_ID_KEY + id;
}
/**
* 锁定企业下制品库 Key前缀
*/
public final static String LOCK_ENTERPRISE_IDENTIFIER_REPO_ID_KEY = "lock_enterprise_identifier_repo_id_key:";
public static String getLockEnterpriseIdentifierRepoIdKey(String enterpriseIdentifier, Long repoId) {
return LOCK_ENTERPRISE_IDENTIFIER_REPO_ID_KEY + enterpriseIdentifier + ":" + repoId;
}
/**
* 锁定制品库制品 Key前缀
*/
public final static String LOCK_PRODUCT_LIBRARY_ID_COMPONENT_ID_KEY = "lock_product_library_id_component_id_key:";
public static String getLockProductLibraryIdComponentIdKey(Long productRepoId, String componentId) {
return LOCK_PRODUCT_LIBRARY_ID_COMPONENT_ID_KEY + productRepoId + ":" + componentId;
}
/**
* 企业标识Redis Key前缀
*/
@ -206,74 +185,9 @@ public class CacheConstants {
/**
* Gitlink组织开通企业是否完成 Key前缀
*/
private final static String GITLINK_ORG_ID_OPEN_ENTERPRISE_KEY = "gitlink_org_id_open_enterprise_key:";
public final static String GITLINK_ORG_ID_OPEN_ENTERPRISE_KEY = "gitlink_org_id_open_enterprise_key:";
public static String getGitlinkOrgIdOpenEnterpriseKey(Long gitlinkOrgId) {
return GITLINK_ORG_ID_OPEN_ENTERPRISE_KEY + gitlinkOrgId;
}
/**
* Sentinel Token缓存Key
*/
public final static String SENTINEL_TOKEN = "sentinel_token";
/**
* Nacos Token缓存Key
*/
public static final String NACOS_TOKEN = "nacos_token";
/**
* Portainer Token缓存Key
*/
public static final String PORTAINER_TOKEN = "portainer_token";
/**
* 专区项目Gitlink信息 Key前缀
*/
private final static String ZONE_PROJECT_GITLINK_INFO = "zone_project_gitlink_info:";
/**
* 专区下项目分数排序 Key前缀
*/
private final static String ZONE_PROJECT_SORT_BY_SCORE = "zone_project_sort_by_score:";
public static String getZoneProjectGitlinkInfo(Long gitlinkProjectId) {
return ZONE_PROJECT_GITLINK_INFO + gitlinkProjectId;
}
public static String getZoneProjectSortByScore(String date, Long zoneId, Long projectTypeId) {
return ZONE_PROJECT_SORT_BY_SCORE + date + ":" + zoneId + ":" + projectTypeId;
}
public static String getAllZoneProjectSortByScore(Long zoneId) {
return ZONE_PROJECT_SORT_BY_SCORE + "*:" + zoneId + ":*";
}
/**
* 专区统计数据缓存前缀
*/
private final static String ZONE_STATISTICS_KEY = "zone:statistics:";
/**
* 获取专区统计数据缓存key
*/
public static String getZoneStatisticsKey(Long zoneId) {
return ZONE_STATISTICS_KEY + zoneId;
}
/**
* 文件打包是否完成0代表未完成1代表已完成-1代表打包失败需要重新打包
*/
private final static String PACKAGE_FILE_IS_FINISH = "packageFileIsFinish:";
public static String getPackageFileIsFinish(String fileIdentifier) {
return PACKAGE_FILE_IS_FINISH + fileIdentifier;
}
// 全局资源数据缓存最近一年统计数据
public final static String GLOBAL_RESOURCES_DATA_KEY = "GLOBAL_RESOURCES_DATA:";
public static String getGlobalResourcesDataKey(String startDate, String endDate) {
return GLOBAL_RESOURCES_DATA_KEY + startDate + "_TO_" + endDate;
}
}

View File

@ -1,17 +0,0 @@
package com.microservices.common.core.constant;
/**
* 异常信息常量
*
* @author otto
*/
public class ExceptionMsgConstants {
/**
* 平台通用异常
*/
public static final String SYSTEM_EXEC_ERROR = "请求处理异常,请联系管理员处理";
/**
* 重试异常
*/
public static final String RETRY_ERROR = "请求发生异常,请重新请求";
}

View File

@ -32,8 +32,4 @@ public class ServiceNameConstants {
* 项目管理模块的serviceid
*/
public static final String PMS_SERVICE = "microservices-pms";
/**
* 网关模块的serviceid
*/
public static final String GATEWAY_SERVICE = "microservices-gateway";
}

View File

@ -18,15 +18,6 @@ public class TokenConstants {
* GitLink令牌标识
*/
public static final String GitLink_Token_Key = "autologin_trustie=";
/**
* Sentinel令牌标识
*/
public static final String Sentinel_Token_Key = "sentinel_dashboard_cookie";
public static final String Portainer_Token_Key = "portainer_api_key";
/**
* Sentinel令牌标识
*/
public static final String Nacos_Token_Key = "Accesstoken";
/**
* Cookie中令牌标识
*/

View File

@ -5,111 +5,62 @@ package com.microservices.common.core.constant;
*
* @author microservices
*/
public class UserConstants {
public class UserConstants
{
/**
* 平台内系统用户的唯一标志
*/
public static final String SYS_USER = "SYS_USER";
/**
* 平台内系统用户的唯一标志
*/
public static final String DELETE_USER_NICKNAME = "已注销";
/**
* 已删除用户默认头像
*/
public static final String DELETE_USER_AVATAR = "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MCIgaGVpZ2h0PSI3MCIgdmlld0JveD0iMCAwIDcwIDcwIj4KICA8ZyBpZD0i57uEXzk5NzEiIGRhdGEtbmFtZT0i57uEIDk5NzEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIxODQwIDE0NDA3KSI+CiAgICA8Y2lyY2xlIGlkPSLmpK3lnIZfMjI3IiBkYXRhLW5hbWU9IuakreWchiAyMjciIGN4PSIzNSIgY3k9IjM1IiByPSIzNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIxODQwIC0xNDQwNykiIGZpbGw9IiM4Zjk1OWUiLz4KICAgIDxwYXRoIGlkPSLlt7Lms6jplIAiIGQ9Ik0xMDEuMTM3LDY5LjJhOS4yLDkuMiwwLDEsMS05LjIsOS4yLDkuMiw5LjIsMCwwLDEsOS4yLTkuMlptLTkuNjE5LTIuNzY4YTE0LjMyMywxNC4zMjMsMCwwLDEsNS4xMDguOTM2LDExLjUsMTEuNSwwLDAsMC01LjA2OSwxOC41NTFsLTE2LjY0NSwwYTUuMTI3LDUuMTI3LDAsMCwxLTUuMTI3LTUuMTI3QTE0LjM1NywxNC4zNTcsMCwwLDEsODMuNjE0LDY2LjQ0NmwuNTI4LS4wMTJoNy4zNzVabTEzLjA2OCwxMC44MTdoLTYuOWExLjE1LDEuMTUsMCwwLDAtLjIwNywyLjI4MWwuMjA3LjAxOGg2LjlhMS4xNSwxLjE1LDAsMCwwLDAtMi4zWk04Ny44Myw0NS45NzhhOS44MTUsOS44MTUsMCwxLDEtOS44MTUsOS44MTVBOS44MTUsOS44MTUsMCwwLDEsODcuODMsNDUuOTc4WiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIxODk0Ljc4NSAtMTQ0MzguOTc4KSIgZmlsbD0iI2ZmZiIgb3BhY2l0eT0iMC45NCIvPgogIDwvZz4KPC9zdmc+Cg==";
/**
* 已删除标记
*/
public static final String DEL_FLAG_TRUE = "2";
/**
* 未删除标记
*/
public static final String DEL_FLAG_FALSE = "0";
/**
* 正常状态
*/
/** 正常状态 */
public static final String NORMAL = "0";
/**
* 异常状态
*/
/** 异常状态 */
public static final String EXCEPTION = "1";
/**
* 用户封禁状态
*/
/** 用户封禁状态 */
public static final String USER_DISABLE = "1";
/**
* 角色封禁状态
*/
/** 角色封禁状态 */
public static final String ROLE_DISABLE = "1";
/**
* 部门正常状态
*/
/** 部门正常状态 */
public static final String DEPT_NORMAL = "0";
/**
* 部门停用状态
*/
/** 部门停用状态 */
public static final String DEPT_DISABLE = "1";
/**
* 字典正常状态
*/
/** 字典正常状态 */
public static final String DICT_NORMAL = "0";
/**
* 是否为系统默认
*/
/** 是否为系统默认(是) */
public static final String YES = "Y";
/**
* 是否菜单外链
*/
/** 是否菜单外链(是) */
public static final String YES_FRAME = "0";
/**
* 是否菜单外链
*/
/** 是否菜单外链(否) */
public static final String NO_FRAME = "1";
/**
* 菜单类型目录
*/
/** 菜单类型(目录) */
public static final String TYPE_DIR = "M";
/**
* 菜单类型菜单
*/
/** 菜单类型(菜单) */
public static final String TYPE_MENU = "C";
/**
* 菜单类型按钮
*/
/** 菜单类型(按钮) */
public static final String TYPE_BUTTON = "F";
/**
* Layout组件标识
*/
/** Layout组件标识 */
public final static String LAYOUT = "Layout";
/**
* ParentView组件标识
*/
/** ParentView组件标识 */
public final static String PARENT_VIEW = "ParentView";
/**
* InnerLink组件标识
*/
/** InnerLink组件标识 */
public final static String INNER_LINK = "InnerLink";
/**
* 校验是否唯一的返回标识
*/
/** 校验是否唯一的返回标识 */
public final static boolean UNIQUE = true;
public final static boolean NOT_UNIQUE = false;
@ -155,28 +106,4 @@ public class UserConstants {
* 项目管理-知识库管理权限
*/
public static final String PMS_PERMS_DOCS_MANAGE = "pms:docs:manage";
/**
* 文章管理-文章删除权限
*/
public static final String CMS_PERMS_DOCS_DELETE = "cms:doc:remove";
/**
* 文章管理-新增文章权限
*/
public static final String CMS_PERMS_DOCS_ADD = "cms:doc:add";
/**
* 文章管理-编辑文章权限
*/
public static final String CMS_PERMS_DOCS_EDIT = "cms:doc:edit";
/**
* 文章管理-审核文章权限
*/
public static final String CMS_PERMS_DOCS_AUDIT = "cms:doc:audit";
/**
* 专区管理-审核项目权限
*/
public static final String ZONE_PERMS_PROJECT_AUDIT = "zone:project:audit";
/**
* 专区管理-审核资源权限
*/
public static final String ZONE_PERMS_RESOURCE_AUDIT = "zone:resource:audit";
}

View File

@ -8,7 +8,7 @@ package com.microservices.common.core.enums;
public enum DocAndZoneOperation
{
OPERATION_CREATE("创建", "create"), OPERATION_UPDATE("更新", "update"),
OPERATION_DELETE("删除", "delete"), OPERATION_NON_REPO_UPDATE("非仓库更新", "nonRepoUpdate");
OPERATION_DELETE("删除", "delete");
private final String operationName;
private final String operationCode;

View File

@ -1,41 +0,0 @@
package com.microservices.common.core.enums;
import lombok.Getter;
/**
* 用户身份状态
*
* @author OTTO
*/
@Getter
public enum UserIdentityStatus {
NORMAL("normal", "正常"),
QUIT("quit", "离职"),
DELETE("delete", "已注销");
private final String state;
private final String info;
UserIdentityStatus(String state, String info) {
this.state = state;
this.info = info;
}
/**
* 获取非正常状态
*
* @param state 状态值
* @return 状态
*/
public static UserIdentityStatus getNonNormalState(String state) {
for (UserIdentityStatus status : values()) {
if (status == QUIT && status.state.equals(state)) {
return status;
}
}
return null;
}
public String getStateInfo() {
return "(" + this.getInfo() + ")";
}
}

View File

@ -1,40 +0,0 @@
package com.microservices.common.core.utils;
import java.util.HashMap;
public class CookieUtil {
public static HashMap<String, String> getCookieMap(String cookie) {
HashMap<String, String> map = new HashMap<>();
if (cookie != null) {
String[] cookies = cookie.split(";");
for (String cookieStr : cookies) {
String[] cookieArr = cookieStr.split("=");
String key = cookieArr[0].trim();
String value = cookieArr[1].trim();
map.put(key, value);
}
}
return map;
}
public static String getCookieValue(String cookie, String key) {
HashMap<String, String> map = getCookieMap(cookie);
return map.get(key);
}
public static String removeCookieKey(String cookie, String key) {
HashMap<String, String> map = getCookieMap(cookie);
map.remove(key);
return genCookieStr(map);
}
private static String genCookieStr(HashMap<String, String> cookieMap) {
StringBuilder stringBuilder = new StringBuilder();
for (String key : cookieMap.keySet()) {
stringBuilder.append(key).append("=").append(cookieMap.get(key)).append(";");
}
return stringBuilder.toString();
}
}

View File

@ -26,8 +26,6 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
private static String[] parsePatterns = {
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
@ -146,14 +144,14 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
* @param startTime 开始时间
* @return 时间差/小时/分钟
*/
public static String timeDistance(Date endTime, Date startTime)
public static String timeDistance(Date endDate, Date startTime)
{
long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60;
long nm = 1000 * 60;
// long ns = 1000;
// 获得两个时间的毫秒时间差异
long diff = endTime.getTime() - startTime.getTime();
long diff = endDate.getTime() - startTime.getTime();
// 计算差多少天
long day = diff / nd;
// 计算差多少小时
@ -215,61 +213,4 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
/**
* 获取某个日期对应的 日期 的周一
*
* @param theDate 某个日期 null的话表示当前日期
* @return Date
*/
private static Date mondayOfThisWeek(Date theDate) {
Calendar c = Calendar.getInstance();
if (theDate != null) {
c.setTime(theDate);
}
// 获取 周一
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
return c.getTime();
}
/**
* 获取某个日期对应的 日期 的周日
*
* @param theDate 某个日期 null的话表示当前日期
* 获取当前日期的周7,注意 日历获取的周期是
* 周日,1,2,3,4,5,6 不是中国传统的
* 1,2,3,4,5,6,周日
* 所以要加7
* @return Date
*/
private static Date sundayOfThisWeek(Date theDate) {
Calendar c = Calendar.getInstance();
if (theDate != null) {
c.setTime(theDate);
}
// 获取 周日
c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
// 获取 中国意义上的 周日
c.add(Calendar.DAY_OF_MONTH, 7);
return c.getTime();
}
public static String mondayOfLastWeek(Date date, int times) {
Calendar cal = Calendar.getInstance();
cal.setTime(DateUtils.mondayOfThisWeek(date));
cal.add(Calendar.DATE, -7 * times);
return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, cal.getTime());
}
public static String sundayOfLastWeek(Date date, int times) {
Calendar cal = Calendar.getInstance();
cal.setTime(DateUtils.sundayOfThisWeek(date));
cal.add(Calendar.DATE, -7 * times);
return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, cal.getTime());
}
public static long dateTimeToUnix(Date date) {
// date.getTime() 返回当前 Date 对象表示的毫秒数除以 1000 后得到以秒为单位的时间戳 10 位时间戳
return date.getTime() / 1000;
}
}

View File

@ -1,6 +1,5 @@
package com.microservices.common.core.utils;
import com.microservices.common.core.exception.ServiceException;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
@ -30,7 +29,7 @@ public class PinYinStringUtils {
try {
pinyinStr += PinyinHelper.toHanyuPinyinStringArray(newChar[i], defaultFormat)[0].charAt(0);
} catch (BadHanyuPinyinOutputFormatCombination e) {
throw new ServiceException("转换拼音失败");
e.printStackTrace();
}
} else {
pinyinStr += newChar[i];
@ -56,7 +55,7 @@ public class PinYinStringUtils {
try {
pinyinStr += PinyinHelper.toHanyuPinyinStringArray(newChar[i], defaultFormat)[0];
} catch (BadHanyuPinyinOutputFormatCombination e) {
throw new ServiceException("转换拼音失败");
e.printStackTrace();
}
} else {
pinyinStr += newChar[i];
@ -89,7 +88,8 @@ public class PinYinStringUtils {
}
return result.toString();
} catch (BadHanyuPinyinOutputFormatCombination e1) {
throw new ServiceException("转换拼音失败");
e1.printStackTrace();
}
return result.toString();
}
}

View File

@ -34,46 +34,53 @@ import java.util.Map;
*
* @author microservices
*/
public class ServletUtils {
public class ServletUtils
{
/**
* 获取String参数
*/
public static String getParameter(String name) {
public static String getParameter(String name)
{
return getRequest().getParameter(name);
}
/**
* 获取String参数
*/
public static String getParameter(String name, String defaultValue) {
public static String getParameter(String name, String defaultValue)
{
return Convert.toStr(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Integer参数
*/
public static Integer getParameterToInt(String name) {
public static Integer getParameterToInt(String name)
{
return Convert.toInt(getRequest().getParameter(name));
}
/**
* 获取Integer参数
*/
public static Integer getParameterToInt(String name, Integer defaultValue) {
public static Integer getParameterToInt(String name, Integer defaultValue)
{
return Convert.toInt(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Boolean参数
*/
public static Boolean getParameterToBool(String name) {
public static Boolean getParameterToBool(String name)
{
return Convert.toBool(getRequest().getParameter(name));
}
/**
* 获取Boolean参数
*/
public static Boolean getParameterToBool(String name, Boolean defaultValue) {
public static Boolean getParameterToBool(String name, Boolean defaultValue)
{
return Convert.toBool(getRequest().getParameter(name), defaultValue);
}
@ -83,7 +90,8 @@ public class ServletUtils {
* @param request 请求对象{@link ServletRequest}
* @return Map
*/
public static Map<String, String[]> getParams(ServletRequest request) {
public static Map<String, String[]> getParams(ServletRequest request)
{
final Map<String, String[]> map = request.getParameterMap();
return Collections.unmodifiableMap(map);
}
@ -94,9 +102,11 @@ public class ServletUtils {
* @param request 请求对象{@link ServletRequest}
* @return Map
*/
public static Map<String, String> getParamMap(ServletRequest request) {
public static Map<String, String> getParamMap(ServletRequest request)
{
Map<String, String> params = new HashMap<>();
for (Map.Entry<String, String[]> entry : getParams(request).entrySet()) {
for (Map.Entry<String, String[]> entry : getParams(request).entrySet())
{
params.put(entry.getKey(), StringUtils.join(entry.getValue(), ","));
}
return params;
@ -105,10 +115,14 @@ public class ServletUtils {
/**
* 获取request
*/
public static HttpServletRequest getRequest() {
try {
public static HttpServletRequest getRequest()
{
try
{
return getRequestAttributes().getRequest();
} catch (Exception e) {
}
catch (Exception e)
{
return null;
}
}
@ -116,10 +130,14 @@ public class ServletUtils {
/**
* 获取response
*/
public static HttpServletResponse getResponse() {
try {
public static HttpServletResponse getResponse()
{
try
{
return getRequestAttributes().getResponse();
} catch (Exception e) {
}
catch (Exception e)
{
return null;
}
}
@ -127,32 +145,42 @@ public class ServletUtils {
/**
* 获取session
*/
public static HttpSession getSession() {
public static HttpSession getSession()
{
return getRequest().getSession();
}
public static ServletRequestAttributes getRequestAttributes() {
try {
public static ServletRequestAttributes getRequestAttributes()
{
try
{
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes) attributes;
} catch (Exception e) {
}
catch (Exception e)
{
return null;
}
}
public static String getHeader(HttpServletRequest request, String name) {
public static String getHeader(HttpServletRequest request, String name)
{
String value = request.getHeader(name);
if (StringUtils.isEmpty(value)) {
if (StringUtils.isEmpty(value))
{
return StringUtils.EMPTY;
}
return urlDecode(value);
}
public static Map<String, String> getHeaders(HttpServletRequest request) {
public static Map<String, String> getHeaders(HttpServletRequest request)
{
Map<String, String> map = new LinkedCaseInsensitiveMap<>();
Enumeration<String> enumeration = request.getHeaderNames();
if (enumeration != null) {
while (enumeration.hasMoreElements()) {
if (enumeration != null)
{
while (enumeration.hasMoreElements())
{
String key = enumeration.nextElement();
String value = request.getHeader(key);
map.put(key, value);
@ -163,39 +191,47 @@ public class ServletUtils {
/**
* 将字符串渲染到客户端
*
*
* @param response 渲染对象
* @param string 待渲染的字符串
* @param string 待渲染的字符串
*/
public static void renderString(HttpServletResponse response, String string) {
try {
public static void renderString(HttpServletResponse response, String string)
{
try
{
response.setStatus(200);
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().print(string);
} catch (IOException e) {
}
catch (IOException e)
{
e.printStackTrace();
}
}
/**
* 是否是Ajax异步请求
*
*
* @param request
*/
public static boolean isAjaxRequest(HttpServletRequest request) {
public static boolean isAjaxRequest(HttpServletRequest request)
{
String accept = request.getHeader("accept");
if (accept != null && accept.contains("application/json")) {
if (accept != null && accept.contains("application/json"))
{
return true;
}
String xRequestedWith = request.getHeader("X-Requested-With");
if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) {
if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest"))
{
return true;
}
String uri = request.getRequestURI();
if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) {
if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
{
return true;
}
@ -205,64 +241,36 @@ public class ServletUtils {
/**
* 内容编码
*
*
* @param str 内容
* @return 编码后的内容
*/
public static String urlEncode(String str) {
try {
public static String urlEncode(String str)
{
try
{
return URLEncoder.encode(str, Constants.UTF8);
} catch (UnsupportedEncodingException e) {
}
catch (UnsupportedEncodingException e)
{
return StringUtils.EMPTY;
}
}
/**
* 内容编码(排除斜杠并且支持重复编码)
*
* @param str 内容
* @return 编码后的内容
*/
public static String urlEncodeExcludeSlashesApplyDuplicate(String str) {
try {
StringBuilder stringBuffer = new StringBuilder();
String[] strings = str.split("/");
for (String string : strings) {
string = URLEncoder.encode(string, Constants.UTF8);
stringBuffer.append("/").append(string);
}
return stringBuffer.toString().replaceAll("\\+", "%20");
} catch (UnsupportedEncodingException e) {
return StringUtils.EMPTY;
}
}
/**
* 判断字符串是否经过URLEncode
* 1. 使用URLDecoder.decode对字符串进行解码
* 2. 再使用URLEncoder.encode对解码后的字符串重新编码
* 3. 如果重新编码后的字符串与原始字符串相同则说明原始字符串是经过URL编码的
*
* @param encodedString 需encode的字符串
* @return 是否经过URLEncode
* @throws UnsupportedEncodingException 编码异常
*/
public static boolean isUrlEncoded(String encodedString) throws UnsupportedEncodingException {
String decodedString = URLDecoder.decode(encodedString, "UTF-8");
String reencodedString = URLEncoder.encode(decodedString, "UTF-8");
return encodedString.equalsIgnoreCase(reencodedString);
}
/**
* 内容解码
*
*
* @param str 内容
* @return 解码后的内容
*/
public static String urlDecode(String str) {
try {
public static String urlDecode(String str)
{
try
{
return URLDecoder.decode(str, Constants.UTF8);
} catch (UnsupportedEncodingException e) {
}
catch (UnsupportedEncodingException e)
{
return StringUtils.EMPTY;
}
}
@ -271,10 +279,11 @@ public class ServletUtils {
* 设置webflux模型响应
*
* @param response ServerHttpResponse
* @param value 响应内容
* @param value 响应内容
* @return Mono<Void>
*/
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value) {
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value)
{
return webFluxResponseWriter(response, HttpStatus.OK, value, R.FAIL);
}
@ -282,11 +291,12 @@ public class ServletUtils {
* 设置webflux模型响应
*
* @param response ServerHttpResponse
* @param code 响应状态码
* @param value 响应内容
* @param code 响应状态码
* @param value 响应内容
* @return Mono<Void>
*/
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value, int code) {
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value, int code)
{
return webFluxResponseWriter(response, HttpStatus.OK, value, code);
}
@ -294,26 +304,28 @@ public class ServletUtils {
* 设置webflux模型响应
*
* @param response ServerHttpResponse
* @param status http状态码
* @param code 响应状态码
* @param value 响应内容
* @param status http状态码
* @param code 响应状态码
* @param value 响应内容
* @return Mono<Void>
*/
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value, int code) {
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value, int code)
{
return webFluxResponseWriter(response, MediaType.APPLICATION_JSON_VALUE, status, value, code);
}
/**
* 设置webflux模型响应
*
* @param response ServerHttpResponse
* @param response ServerHttpResponse
* @param contentType content-type
* @param status http状态码
* @param code 响应状态码
* @param value 响应内容
* @param status http状态码
* @param code 响应状态码
* @param value 响应内容
* @return Mono<Void>
*/
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status, Object value, int code) {
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status, Object value, int code)
{
response.setStatusCode(status);
response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType);
R<?> result = R.fail(code, value.toString());

View File

@ -1,20 +1,13 @@
package com.microservices.common.core.utils.file;
import com.microservices.common.core.utils.StringUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
/**
* 文件处理工具类
@ -36,6 +29,7 @@ public class FileUtils
*
* @param filePath 文件路径
* @param os 输出流
* @return
*/
public static void writeBytes(String filePath, OutputStream os) throws IOException
{
@ -60,6 +54,7 @@ public class FileUtils
* 删除文件
*
* @param filePath 文件
* @return
*/
public static boolean deleteFile(String filePath)
{
@ -228,43 +223,4 @@ public class FileUtils
String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
return encode.replaceAll("\\+", "%20");
}
/**
* 通过InputStream构建MultipartFile用于内部上传接口调用
*
* @param inputStream 文件输入流
* @param fileName 文件名
* @return MultipartFile
*/
public static MultipartFile createMultipartFile(InputStream inputStream, String fileName) throws IOException {
FileItemFactory factory = new DiskFileItemFactory(16, null);
String textFieldName = "file";
FileItem item = factory.createItem(textFieldName, MediaType.MULTIPART_FORM_DATA_VALUE, true, fileName);
int bytesRead = 0;
byte[] buffer = new byte[4096];
//使用输出流输出输入流的字节
try (OutputStream os = item.getOutputStream()) {
while ((bytesRead = inputStream.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
inputStream.close();
} finally {
if (inputStream != null) {
inputStream.close();
}
}
return new CommonsMultipartFile(item);
}
public static String calcFileSize(long fileSize) {
// 计算文件大小信息
String fileSizeInfo = "0kB";
if (fileSize != 0) {
String[] unitNames = new String[]{"B", "kB", "MB", "GB", "TB", "EB"};
int digitGroups = Math.min(unitNames.length - 1, (int) (Math.log10(fileSize) / Math.log10(1024)));
fileSizeInfo = new DecimalFormat("#,##0.##").format(fileSize / Math.pow(1024, digitGroups)) + " " + unitNames[digitGroups];
}
return fileSizeInfo;
}
}

View File

@ -30,7 +30,7 @@ public class EscapeUtil
/**
* 转义文本中的HTML字符为安全的字符
*
*
* @param text 被转义的文本
* @return 转义后的文本
*/
@ -41,7 +41,7 @@ public class EscapeUtil
/**
* 还原被转义的HTML特殊字符
*
*
* @param content 包含转义符的HTML内容
* @return 转换后的字符串
*/
@ -52,7 +52,7 @@ public class EscapeUtil
/**
* 清除所有HTML标签但是不删除标签内的内容
*
*
* @param content 文本
* @return 清除标签后的文本
*/
@ -63,7 +63,7 @@ public class EscapeUtil
/**
* Escape编码
*
*
* @param text 被编码的文本
* @return 编码后的字符
*/
@ -104,7 +104,7 @@ public class EscapeUtil
/**
* Escape解码
*
*
* @param content 被转义的内容
* @return 解码后的字符串
*/

View File

@ -3,7 +3,6 @@ package com.microservices.common.core.web.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.microservices.common.core.utils.DateUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -64,12 +63,4 @@ public class BaseEntity implements Serializable
}
return params;
}
public void setCreateAndUpdate(String username) {
Date nowDate = DateUtils.getNowDate();
this.createBy = username;
this.updateBy = username;
this.createTime = nowDate;
this.updateTime = nowDate;
}
}

View File

@ -59,7 +59,7 @@ public class GitLinkRequestUrl {
}
public static GitLinkRequestUrl GET_LIST_BY_PAGES(String url, Integer page, Integer limit) {
return getAdminGitLinkRequestUrl(String.format("%s?page=%d&limit=%d", url, page, limit));
return getGitLinkRequestUrl(String.format("%s?page=%d&limit=%d", url, page, limit));
}
/**

View File

@ -5,11 +5,8 @@ import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.constant.Constants;
import com.microservices.common.core.constant.HttpStatus;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.httpClient.domain.CustomHttpDelete;
import com.microservices.system.api.domain.SysFileBytes;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
@ -25,6 +22,7 @@ import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@ -32,6 +30,7 @@ import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import static com.microservices.common.core.web.domain.AjaxResult.DATA_TAG;
@ -127,32 +126,16 @@ public class HttpAPIService {
public JSONObject doPostFile(String url, MultipartFile file, HashMap<String, String> headers) throws Exception {
HttpPost httpPost = new HttpPost(url);
// 创建一个输入流
InputStream inputStream = file.getInputStream();
try {
// 构建文件上传请求的实体
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody(
"file",
inputStream,
ContentType.create("application/octet-stream"),
URLEncoder.encode(file.getOriginalFilename(), StandardCharsets.UTF_8.toString())
);
// 对文件名进行URL编码
String encodedFilename = URLEncoder.encode(Objects.requireNonNull(file.getOriginalFilename()), StandardCharsets.UTF_8.toString());
HttpEntity entity = builder.build();
httpPost.setEntity(entity);
return doRequest(httpPost, headers);
} finally {
// 确保输入流被关闭以释放资源
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
// Log the exception
logger.error("Failed to close input stream", e);
}
}
}
// 构建文件上传请求的实体
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("file", file.getBytes(), ContentType.DEFAULT_BINARY, encodedFilename);
HttpEntity entity = builder.build();
httpPost.setEntity(entity);
return doRequest(httpPost, headers);
}
public JSONObject doPostFormData(String url, HttpEntity httpEntity, HashMap<String, String> headers) throws Exception {
@ -211,17 +194,6 @@ public class HttpAPIService {
return doRequest(httpDelete, headers);
}
/**
* 不带Header的get请求
*
* @param url
* @return
* @throws Exception
*/
public JSONObject doGet(String url) throws Exception {
return doGet(url, null);
}
/**
* 带Header的get请求
*
@ -293,10 +265,6 @@ public class HttpAPIService {
long length = httpEntity.getContentLength();
if (length != 0L) {
String result = EntityUtils.toString(httpEntity);
if (!JSON.isValid(result)) {
logger.error("平台接口响应格式异常,状态码:{},响应内容:{}", httpStatusCode, result);
throw new ServiceException("平台接口响应格式异常");
}
Object resultObj = JSON.parse(result);
if (resultObj instanceof JSONArray) {
JSONObject jsonObject = new JSONObject();
@ -369,7 +337,7 @@ public class HttpAPIService {
}
}
public SysFileBytes doGetFileInputStream(String url, HashMap<String, String> headers) throws Exception {
public byte[] doGetFileInputStream(String url, HashMap<String, String> headers) throws Exception {
// 声明httpGet请求
HttpGet request = new HttpGet(url);
// 加入配置信息
@ -381,17 +349,20 @@ public class HttpAPIService {
try (CloseableHttpResponse response = httpClient.execute(request)) {
if (response != null) {
int httpStatusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.checkSuccess(httpStatusCode)) {
HttpEntity httpEntity = response.getEntity();
if (httpEntity != null) {
InputStream input = httpEntity.getContent();
InputStream cloneInput = IOUtils.toBufferedInputStream(input);
String fileName = url.substring(url.lastIndexOf('/') + 1);
SysFileBytes sysFileBytes = new SysFileBytes();
sysFileBytes.setFileInputStream(cloneInput);
sysFileBytes.setFileName(fileName);
return sysFileBytes;
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
return output.toByteArray();
}
}
}
throw new Exception("请求响应失败");

View File

@ -205,7 +205,7 @@ public class GitLinkRequestHelper {
public JSONArray getAllDataByPage(String url, String listKey) {
JSONArray jsonArray = new JSONArray();
boolean isAllData = false;
int pageNum = 1;
int pageNum = 0;
// 循环分页获取gitlink组织下所有成员
while (!isAllData) {
JSONObject result = doGet(GitLinkRequestUrl.GET_LIST_BY_PAGES(url, pageNum, 50)
@ -229,7 +229,7 @@ public class GitLinkRequestHelper {
public <T> List<T> getAllDataByPage(String url, String listKey, Class<T> tClass) {
List<T> allList = new ArrayList<>();
boolean isAllData = false;
int pageNum = 1;
int pageNum = 0;
// 循环分页获取gitlink组织下所有成员
while (!isAllData) {
JSONObject result = doGet(GitLinkRequestUrl.GET_LIST_BY_PAGES(url, pageNum, 50)

View File

@ -1,7 +1,6 @@
package com.microservices.common.redis.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisZSetCommands;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
@ -34,27 +33,6 @@ public class RedisService
redisTemplate.opsForValue().set(key, value);
}
public <T> void setSortSetObject(final String key, final T value, final double score, final Long timeout, final TimeUnit timeUnit) {
redisTemplate.opsForZSet().add(key, value, score);
redisTemplate.expire(key, timeout, timeUnit);
}
public <T> void removeSortSetObject(final String key, final T value) {
redisTemplate.opsForZSet().remove(key, value);
}
public <T> Set<T> getSortSetBySize(final String key) {
return redisTemplate.opsForZSet().reverseRangeByLex(key, RedisZSetCommands.Range.unbounded(), RedisZSetCommands.Limit.unlimited());
}
public <T> Long getSortSetRank(final String key, final T value) {
return redisTemplate.opsForZSet().reverseRank(key, value);
}
public Long getSortSetCount(final String key) {
return redisTemplate.opsForZSet().zCard(key);
}
/**
* 缓存基本的对象IntegerString实体类等
*

View File

@ -115,7 +115,8 @@ public class AuthLogic {
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public boolean hasPermi(String permission) {
public boolean hasPermi(String permission)
{
return hasPermi(tokenService.getMenuPermissions(), permission);
}
@ -125,8 +126,10 @@ public class AuthLogic {
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public void checkPermi(String permission) {
if (!hasPermi(tokenService.getMenuPermissions(), permission)) {
public void checkPermi(String permission)
{
if (!hasPermi(tokenService.getMenuPermissions(), permission))
{
throw new NotPermissionException(permission);
}
}
@ -150,10 +153,13 @@ public class AuthLogic {
*
* @param permissions 权限列表
*/
public void checkPermiAnd(String... permissions) {
public void checkPermiAnd(String... permissions)
{
Set<String> permissionList = tokenService.getMenuPermissions();
for (String permission : permissions) {
if (!hasPermi(permissionList, permission)) {
for (String permission : permissions)
{
if (!hasPermi(permissionList, permission))
{
throw new NotPermissionException(permission);
}
}
@ -164,10 +170,13 @@ public class AuthLogic {
*
* @param permissions 权限码数组
*/
public void checkPermiOr(String... permissions) {
public void checkPermiOr(String... permissions)
{
Set<String> permissionList = tokenService.getMenuPermissions();
for (String permission : permissions) {
if (hasPermi(permissionList, permission)) {
for (String permission : permissions)
{
if (hasPermi(permissionList, permission))
{
return;
}
}
@ -182,7 +191,8 @@ public class AuthLogic {
* @param role 角色标识
* @return 用户是否具备某角色
*/
public boolean hasRole(String role) {
public boolean hasRole(String role)
{
return hasRole(tokenService.getRolePermissions(), role);
}
@ -215,10 +225,13 @@ public class AuthLogic {
*
* @param roles 角色标识数组
*/
public void checkRoleAnd(String... roles) {
public void checkRoleAnd(String... roles)
{
Set<String> roleList = tokenService.getRolePermissions();
for (String role : roles) {
if (!hasRole(roleList, role)) {
for (String role : roles)
{
if (!hasRole(roleList, role))
{
throw new NotRoleException(role);
}
}
@ -229,14 +242,18 @@ public class AuthLogic {
*
* @param roles 角色标识数组
*/
public void checkRoleOr(String... roles) {
public void checkRoleOr(String... roles)
{
Set<String> roleList = tokenService.getRolePermissions();
for (String role : roles) {
if (hasRole(roleList, role)) {
for (String role : roles)
{
if (hasRole(roleList, role))
{
return;
}
}
if (roles.length > 0) {
if (roles.length > 0)
{
throw new NotRoleException(roles);
}
}
@ -306,9 +323,6 @@ public class AuthLogic {
public boolean hasUserIdentity(Long deptId, String roleKey) {
LoginUser loginUser = getLoginUser();
List<SysUserDeptRole> sysUserDeptRoleList = tokenService.getAllUserIdentity(loginUser.getUsername());
if (sysUserDeptRoleList == null) {
return false;
}
return sysUserDeptRoleList.stream()
.anyMatch(x -> {
if (x.getDeptId() != null && x.getSysRole() != null && x.getDeptId().equals(deptId)) {

View File

@ -1,16 +1,9 @@
package com.microservices.common.security.feign;
import feign.RequestInterceptor;
import feign.codec.Encoder;
import feign.form.FormEncoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Feign 配置注册
*
@ -19,20 +12,9 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignAutoConfiguration
{
// 这里会由容器自动注入HttpMessageConverters的对象工厂
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
public RequestInterceptor requestInterceptor()
{
return new FeignRequestInterceptor();
}
// new一个form编码器实现支持form表单提交
// 注意这里方法名称也就是bean的名称是什么不重要
// 重要的是返回类型要是 Encoder 并且实现类必须是 FormEncoder 或者其子类
@Bean
public Encoder feignFormEncoder() {
return new FormEncoder(new SpringEncoder(messageConverters));
}
}

View File

@ -11,7 +11,6 @@ import com.microservices.common.core.utils.uuid.IdUtils;
import com.microservices.common.redis.service.RedisService;
import com.microservices.common.security.interceptor.HeaderInterceptor;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.system.api.RemoteDeptService;
import com.microservices.system.api.RemoteUserService;
import com.microservices.system.api.domain.SysRole;
import com.microservices.system.api.domain.SysUser;
@ -39,8 +38,6 @@ public class TokenService {
private RedisService redisService;
@Autowired
private RemoteUserService remoteUserService;
@Autowired
private RemoteDeptService remoteDeptService;
protected static final long MILLIS_SECOND = 1000;
@ -332,16 +329,4 @@ public class TokenService {
}
return loginUser.getSysUser();
}
public Boolean hasDeptPerms(Long deptId, String perms) {
LoginUser loginUser = SecurityUtils.getLoginUser();
Boolean hasPerms = FeignUtils.getReturnData(
remoteDeptService.checkUserInDeptOrParentDeptHasPerms(deptId, loginUser.getUserId(), perms, SecurityConstants.INNER)
);
if (hasPerms == null) {
hasPerms = false;
}
return hasPerms;
}
}

View File

@ -114,7 +114,7 @@ public class SecurityUtils
*/
public static Boolean checkCurrentDeptId(Long deptId) {
Boolean ignoreDataScopeCheck = getIgnoreDataScopeCheck();
if (ignoreDataScopeCheck) {
if (ignoreDataScopeCheck != null && ignoreDataScopeCheck) {
return true;
}
SysUserDeptRole userIdentify = getUserIdentity();

View File

@ -2,18 +2,13 @@ package com.microservices.gateway.config;
import feign.codec.Decoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.util.stream.Collectors;
/**
* @author otto
*/
@ -30,10 +25,4 @@ public class FeignConfig {
(new MappingJackson2HttpMessageConverter());
return () -> httpMessageConverters;
}
@Bean
@ConditionalOnMissingBean
public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
}
}

View File

@ -11,8 +11,6 @@ import com.microservices.common.core.utils.ServletUtils;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.redis.service.RedisService;
import com.microservices.gateway.config.properties.IgnoreWhiteProperties;
import com.microservices.gateway.service.ThirdPartyToolService;
import com.microservices.gateway.utils.CustomExecutorFactory;
import com.microservices.system.api.RemoteUserService;
import com.microservices.system.api.domain.SysUserDeptRole;
import com.microservices.system.api.utils.FeignUtils;
@ -30,8 +28,9 @@ import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 网关鉴权
@ -52,12 +51,7 @@ public class AuthFilter implements GlobalFilter, Ordered {
@Autowired
private RemoteUserService remoteUserService;
@Lazy
@Autowired
private ThirdPartyToolService thirdPartyToolService;
ThreadPoolExecutor threadPoolExecutor = CustomExecutorFactory.threadPoolExecutor;
ExecutorService executorService = Executors.newFixedThreadPool(1);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
@ -81,16 +75,12 @@ public class AuthFilter implements GlobalFilter, Ordered {
}
if (StringUtils.isEmpty(token)) {
if (StringUtils.isNotEmpty(gitLinkCookie)) {
return unauthorizedResponse(exchange, "令牌已过期或验证不正确!");
}
return unauthorizedResponse(exchange, "令牌不能为空");
}
Claims claims;
try {
claims = JwtUtils.parseToken(token);
} catch (Exception e) {
log.error("令牌解析失败:{}", e.getMessage());
return unauthorizedResponse(exchange, "令牌格式不正确!");
}
if (claims == null) {
@ -115,11 +105,6 @@ public class AuthFilter implements GlobalFilter, Ordered {
ServletUtils.addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username);
// 内部请求来源参数清除
ServletUtils.removeHeader(mutate, SecurityConstants.FROM_SOURCE);
Mono<Void> thirdPartyRes = thirdPartyToolService.handleRequestForThirdPartyTools(exchange, request, mutate);
if (thirdPartyRes != null) {
return thirdPartyRes;
}
return chain.filter(exchange.mutate().request(mutate.build()).build());
}
@ -131,7 +116,7 @@ public class AuthFilter implements GlobalFilter, Ordered {
boolean hasUserIdentifyList = redisService.hasKey(redisKey);
if (!hasUserIdentifyList) {
// 网关采用异步架构所以此处需要通过异步请求获取本系统Token
Future<R<List<SysUserDeptRole>>> future = threadPoolExecutor.submit(
Future<R<List<SysUserDeptRole>>> future = executorService.submit(
() -> remoteUserService.getSysUserDeptRoleListByUserName(username, SecurityConstants.INNER));
try {
List<SysUserDeptRole> feignResult = FeignUtils.getReturnData(
@ -145,7 +130,7 @@ public class AuthFilter implements GlobalFilter, Ordered {
}
private String genCookieByToken(String token) {
return String.format("%s%s;", TokenConstants.GitLink_Token_Key, token);
return String.format("%s%s;",TokenConstants.GitLink_Token_Key, token);
}
private String getGitLinkRequestCookie(ServerHttpRequest request) {
@ -156,7 +141,7 @@ public class AuthFilter implements GlobalFilter, Ordered {
String token = request.getHeaders().getFirst(TokenConstants.AUTHENTICATION);
if (token != null) {
// 网关采用异步架构所以此处需要通过异步请求获取本系统Token
Future<R<Boolean>> future = threadPoolExecutor.submit(
Future<R<Boolean>> future = executorService.submit(
() -> remoteUserService.checkGitLinkUserLogin(token, SecurityConstants.INNER));
try {
Boolean feignResult = FeignUtils.getReturnData(
@ -209,7 +194,7 @@ public class AuthFilter implements GlobalFilter, Ordered {
private String getGitLinkToken(String cookie) {
if (StringUtils.isNotEmpty(cookie)) {
// 网关采用异步架构所以此处需要通过异步请求获取本系统Token
Future<R<String>> future = threadPoolExecutor.submit(() -> remoteUserService
Future<R<String>> future = executorService.submit(() -> remoteUserService
.getSysUserTokenByGitLinkCookie(cookie, SecurityConstants.INNER));
R<String> feignResult;
try {

View File

@ -1,218 +0,0 @@
package com.microservices.gateway.filter;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.constant.CacheConstants;
import com.microservices.common.core.constant.ExceptionMsgConstants;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.common.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
@Slf4j
@Component
public class GlobalResponseFilter implements GlobalFilter, Ordered {
@Autowired
private RedisService redisService;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String lowerUrl = request.getURI().getPath().toLowerCase();
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
// 当请求为Nacos时Nacos返回的所有非JSON响应都会被自动转换为结构化的错误信息同时将HTTP状态码设置为200适合用于规范化微服务架构的响应格式
if (lowerUrl.startsWith("/nacos")) {
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
HttpStatus status = getStatusCode() != null ? getStatusCode() : HttpStatus.INTERNAL_SERVER_ERROR;
if (!status.isError()) {
return super.writeWith(body);
}
if (status == HttpStatus.FORBIDDEN) {
log.error("nacos鉴权异常已清理redis中nacos token");
// 设置新的状态码为 200
setStatusCode(HttpStatus.OK);
// 设置响应内容类型为 JSON
getHeaders().setContentType(MediaType.APPLICATION_JSON);
// 清理Sentinel失效token
redisService.deleteObject(CacheConstants.NACOS_TOKEN);
// 创建自定义的 JSON 响应内容
String jsonBody = JSON.toJSONString(AjaxResult.error(ExceptionMsgConstants.RETRY_ERROR));
byte[] bytes = jsonBody.getBytes(StandardCharsets.UTF_8);
getHeaders().setContentLength(bytes.length);
DataBuffer dataBuffer = bufferFactory.wrap(bytes);
// 返回新的响应内容
return super.writeWith(Mono.just(dataBuffer));
}
return Flux.from(body).<String>handle((dataBuffer, synchronousSink) -> {
if (status.isError()) {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
//释放掉内存
DataBufferUtils.release(dataBuffer);
String result = new String(bytes, StandardCharsets.UTF_8);
synchronousSink.next(result);
return;
}
synchronousSink.complete();
}).flatMap(resStr -> {
// 保留原始状态码
originalResponse.setStatusCode(HttpStatus.OK);
String errMsg;
if (!JSON.isValid(resStr)) {
errMsg = resStr;
} else {
JSONObject resJson = JSONObject.parseObject(resStr);
if (resJson.containsKey("message")) {
errMsg = resJson.getString("message");
} else {
errMsg = ExceptionMsgConstants.SYSTEM_EXEC_ERROR;
}
}
byte[] bytes = JSON.toJSONBytes(AjaxResult.error(errMsg));
getHeaders().setContentLength(bytes.length);
DataBuffer buffer = bufferFactory.wrap(bytes);
return super.writeWith(Mono.just(buffer));
}).then();
}
};
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
if (lowerUrl.startsWith("/portainer")) {
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
HttpStatus status = getStatusCode() != null ? getStatusCode() : HttpStatus.INTERNAL_SERVER_ERROR;
if (!status.isError()) {
return super.writeWith(body);
}
return Flux.from(body).<String>handle((dataBuffer, synchronousSink) -> {
if (status.isError()) {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
//释放掉内存
DataBufferUtils.release(dataBuffer);
String result = new String(bytes, StandardCharsets.UTF_8);
synchronousSink.next(result);
}
synchronousSink.complete();
}).flatMap(resStr -> {
log.error("Portainer响应处理异常异常信息{}", resStr);
originalResponse.setStatusCode(HttpStatus.OK);
byte[] bytes;
if (JSON.isValid(resStr)) {
JSONObject resJson = JSONObject.parseObject(resStr);
if (resJson.containsKey("message")) {
String message = resJson.getString("message");
if (StringUtils.isNotBlank(message) && message.contains("A valid authorisation token is missing")) {
log.error("Portainer鉴权异常已清理redis中Portainer token");
//token失效清除redis缓存
redisService.deleteObject(CacheConstants.PORTAINER_TOKEN);
bytes = JSON.toJSONBytes(AjaxResult.error(ExceptionMsgConstants.RETRY_ERROR));
} else {
bytes = JSON.toJSONBytes(AjaxResult.error(message));
}
} else {
bytes = JSON.toJSONBytes(AjaxResult.error(ExceptionMsgConstants.SYSTEM_EXEC_ERROR));
}
} else {
bytes = JSON.toJSONBytes(AjaxResult.error(ExceptionMsgConstants.SYSTEM_EXEC_ERROR));
}
getHeaders().setContentLength(bytes.length);
DataBuffer buffer = bufferFactory.wrap(bytes);
return super.writeWith(Mono.just(buffer));
}).then();
}
};
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
if (lowerUrl.startsWith("/sentinel")) {
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
HttpStatus status = getStatusCode() != null ? getStatusCode() : HttpStatus.INTERNAL_SERVER_ERROR;
if (!status.isError()) {
return super.writeWith(body);
}
if (status == HttpStatus.UNAUTHORIZED) {
log.error("sentinel鉴权异常已清理redis中sentinel token");
// 设置新的状态码为 200
setStatusCode(HttpStatus.OK);
// 设置响应内容类型为 JSON
getHeaders().setContentType(MediaType.APPLICATION_JSON);
// 清理Sentinel失效token
redisService.deleteObject(CacheConstants.SENTINEL_TOKEN);
// 创建自定义的 JSON 响应内容
String jsonBody = JSON.toJSONString(AjaxResult.error(ExceptionMsgConstants.RETRY_ERROR));
byte[] bytes = jsonBody.getBytes(StandardCharsets.UTF_8);
getHeaders().setContentLength(bytes.length);
DataBuffer dataBuffer = bufferFactory.wrap(bytes);
// 返回新的响应内容
return super.writeWith(Mono.just(dataBuffer));
}
return Flux.from(body).<String>handle((dataBuffer, synchronousSink) -> {
if (status.isError()) {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
//释放掉内存
DataBufferUtils.release(dataBuffer);
String result = new String(bytes, StandardCharsets.UTF_8);
synchronousSink.next(result);
}
synchronousSink.complete();
}).flatMap(resStr -> {
log.error("Sentinel响应处理异常异常信息{}", resStr);
byte[] bytes;
bytes = JSON.toJSONBytes(AjaxResult.error(ExceptionMsgConstants.SYSTEM_EXEC_ERROR));
setStatusCode(HttpStatus.OK);
getHeaders().setContentLength(bytes.length);
DataBuffer buffer = bufferFactory.wrap(bytes);
return super.writeWith(Mono.just(buffer));
}).then();
}
};
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
//WRITE_RESPONSE_FILTER 之前执行
return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 1;
}
}

View File

@ -1,6 +1,5 @@
package com.microservices.gateway.handler;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.ServletUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -20,27 +19,33 @@ import reactor.core.publisher.Mono;
*/
@Order(-1)
@Configuration
public class GatewayExceptionHandler implements ErrorWebExceptionHandler {
public class GatewayExceptionHandler implements ErrorWebExceptionHandler
{
private static final Logger log = LoggerFactory.getLogger(GatewayExceptionHandler.class);
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex)
{
ServerHttpResponse response = exchange.getResponse();
if (exchange.getResponse().isCommitted()) {
if (exchange.getResponse().isCommitted())
{
return Mono.error(ex);
}
String msg;
if (ex instanceof NotFoundException) {
if (ex instanceof NotFoundException)
{
msg = "服务未找到";
} else if (ex instanceof ServiceException) {
msg = ex.getMessage();
} else if (ex instanceof ResponseStatusException) {
}
else if (ex instanceof ResponseStatusException)
{
ResponseStatusException responseStatusException = (ResponseStatusException) ex;
msg = responseStatusException.getMessage();
} else {
}
else
{
msg = "内部服务器错误";
}

View File

@ -1,22 +0,0 @@
package com.microservices.gateway.service;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* 第三方工具服务类
*
* @author OTTO
*/
public interface ThirdPartyToolService {
/**
* 处理第三方工具请求
*
* @param exchange
* @param request 请求
* @param mutate 请求头获取器
*/
Mono<Void> handleRequestForThirdPartyTools(ServerWebExchange exchange, ServerHttpRequest request, ServerHttpRequest.Builder mutate);
}

View File

@ -1,232 +0,0 @@
package com.microservices.gateway.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.constant.CacheConstants;
import com.microservices.common.core.constant.ExceptionMsgConstants;
import com.microservices.common.core.constant.TokenConstants;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.CookieUtil;
import com.microservices.common.core.utils.ServletUtils;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.redis.service.RedisService;
import com.microservices.gateway.service.ThirdPartyToolService;
import com.microservices.gateway.utils.CustomExecutorFactory;
import com.microservices.system.api.RemoteGatewayService;
import feign.Response;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author OTTO
*/
@Service
public class ThirdPartyToolServiceImpl implements ThirdPartyToolService {
private static final Logger log = LoggerFactory.getLogger(ThirdPartyToolServiceImpl.class);
@Value("${thirdPartyTools.nacos.auth.username:}")
public String nacosUsername;
@Value("${thirdPartyTools.nacos.auth.password:}")
public String nacosPassword;
@Value("${thirdPartyTools.sentinel.auth.username:}")
public String sentinelUsername;
@Value("${thirdPartyTools.sentinel.auth.password:}")
public String sentinelPassword;
@Value("${thirdPartyTools.portainer.auth.username:}")
public String portainerUsername;
@Value("${thirdPartyTools.portainer.auth.password:}")
public String portainerPassword;
@Value("${thirdPartyTools.portainer.endpoints:}")
public Integer portainerEndpoints;
ThreadPoolExecutor threadPoolExecutor = CustomExecutorFactory.threadPoolExecutor;
@Lazy
@Autowired
private RemoteGatewayService remoteGatewayService;
@Autowired
private RedisService redisService;
/**
* 处理第三方工具请求
*/
@Override
public Mono<Void> handleRequestForThirdPartyTools(ServerWebExchange exchange, ServerHttpRequest request, ServerHttpRequest.Builder mutate) {
String url = request.getURI().getPath();
String lowerUrl = url.toLowerCase();
if (StringUtils.isEmpty(lowerUrl)) {
return null;
}
// 处理Sentinel请求
if (lowerUrl.startsWith("/sentinel")) {
// 检查Cookie中是否携带sentinel cookie
String cookie = request.getHeaders().getFirst(TokenConstants.Cookie);
if (StringUtils.isNotEmpty(CookieUtil.getCookieValue(cookie, TokenConstants.Sentinel_Token_Key))) {
cookie = CookieUtil.removeCookieKey(cookie, TokenConstants.Sentinel_Token_Key);
}
String sentinelCookie = null;
if (redisService.hasKey(CacheConstants.SENTINEL_TOKEN)) {
sentinelCookie = redisService.getCacheObject(CacheConstants.SENTINEL_TOKEN);
} else {
// 网关采用异步架构所以此处需要通过异步请求获取Sentinel Token
Future<Response> future = threadPoolExecutor.submit(() -> remoteGatewayService.loginSentinel(sentinelUsername, sentinelPassword));
try {
Response response = future.get(1, TimeUnit.SECONDS);
Map<String, Collection<String>> header = response.headers();
if (header != null && header.containsKey("set-cookie")) {
sentinelCookie = header.get("set-cookie").iterator().next();
//Sentinel登录状态默认30分钟失效将Sentinel Token缓存过期时间调整为28分钟
redisService.setCacheObject(CacheConstants.SENTINEL_TOKEN, sentinelCookie, 28L, TimeUnit.MINUTES);
}
} catch (TimeoutException e) {
log.error("获取Sentinel Token超时");
} catch (InterruptedException | ExecutionException e) {
log.error("获取Sentinel Token失败{}", e.getMessage());
}
}
if (StringUtils.isNotEmpty(sentinelCookie)) {
ServletUtils.removeHeader(mutate, TokenConstants.Cookie);
mutate.header(TokenConstants.Cookie, String.format("%s;%s;", cookie, sentinelCookie));
} else {
throw new ServiceException("Sentinel服务获取Token失败");
}
}
// 处理Nacos请求
if (lowerUrl.startsWith("/nacos")) {
String nacosToken = null;
if (redisService.hasKey(CacheConstants.NACOS_TOKEN)) {
nacosToken = redisService.getCacheObject(CacheConstants.NACOS_TOKEN);
} else {
Map<String, String> nacosMap = new HashMap<>();
nacosMap.put("username", nacosUsername);
nacosMap.put("password", nacosPassword);
// 网关采用异步架构所以此处需要通过异步请求获取Nacos Token
Future<Response> future = threadPoolExecutor.submit(() -> remoteGatewayService.loginNacos(nacosMap));
try {
Response res = future.get(1, TimeUnit.SECONDS);
StringWriter writer = new StringWriter();
IOUtils.copy(res.body().asInputStream(), writer, StandardCharsets.UTF_8.name());
String str = writer.toString();
if (!JSON.isValid(str)) {
return exceptionResponse(exchange, str, res.status());
}
JSONObject resJsonObject = JSONObject.parseObject(str);
if (resJsonObject == null) {
return exceptionResponse(exchange, str, res.status());
}
nacosToken = resJsonObject.getString("accessToken");
Long tokenTtl = resJsonObject.getLong("tokenTtl");
if (nacosToken != null && tokenTtl != null) {
redisService.setCacheObject(CacheConstants.NACOS_TOKEN, nacosToken, tokenTtl - 10, TimeUnit.SECONDS);
}
} catch (TimeoutException e) {
log.error("获取Nacos Token超时");
} catch (InterruptedException | ExecutionException | IOException | NullPointerException e) {
log.error("获取Nacos Token失败{}", e.getMessage());
}
}
if (StringUtils.isNotEmpty(nacosToken)) {
mutate.header(TokenConstants.Nacos_Token_Key, nacosToken);
} else {
throw new ServiceException("Nacos服务获取Token失败");
}
}
// 处理portainer请求
if (lowerUrl.startsWith("/portainer")) {
// 处理portainer指定endpoints的问题
if (lowerUrl.startsWith("/portainer/api/endpoints/")) {
String regex = "^/portainer/api/endpoints/\\d+(/?.*)";
if (Pattern.matches(regex, lowerUrl)) {
// 替换掉endpoints
regex = "(^/portainer/api/endpoints/)(\\d+)(/?.*)";
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(url);
if (matcher.find()) {
// 替换数字部分
url = matcher.replaceAll(matcher.group(1) + portainerEndpoints + matcher.group(3));
try {
mutate.uri(new URI(url));
} catch (URISyntaxException e) {
log.error("替换Portainer请求中Endpoints时发生异常{}", e.getMessage());
}
}
}
}
String portainerToken = null;
String cookie = request.getHeaders().getFirst(TokenConstants.Cookie);
if (StringUtils.isNotEmpty(CookieUtil.getCookieValue(cookie, TokenConstants.Portainer_Token_Key))) {
cookie = CookieUtil.removeCookieKey(cookie, TokenConstants.Portainer_Token_Key);
}
if (redisService.hasKey(CacheConstants.PORTAINER_TOKEN)) {
portainerToken = redisService.getCacheObject(CacheConstants.PORTAINER_TOKEN);
} else {
// 网关采用异步架构所以此处需要通过异步请求获取Portainer Token
JSONObject loginPortainerBody = new JSONObject();
loginPortainerBody.put("username", portainerUsername);
loginPortainerBody.put("password", portainerPassword);
Future<Response> future = threadPoolExecutor.submit(() -> remoteGatewayService.loginPortainer(loginPortainerBody));
try {
Response res = future.get(1, TimeUnit.SECONDS);
StringWriter writer = new StringWriter();
IOUtils.copy(res.body().asInputStream(), writer, StandardCharsets.UTF_8.name());
String str = writer.toString();
if (!JSON.isValid(str)) {
return exceptionResponse(exchange, str, res.status());
}
JSONObject resJsonObject = JSONObject.parseObject(str);
portainerToken = resJsonObject.getString("jwt");
if (portainerToken == null) {
return exceptionResponse(exchange, str, res.status());
}
String[] tokenSplit = portainerToken.split("\\.");
String tokenBodyStr = new String(Base64.getDecoder().decode(tokenSplit[1]), StandardCharsets.UTF_8);
JSONObject tokenBody = JSONObject.parseObject(tokenBodyStr);
Long expiration = tokenBody.getLong("exp");
Long now = new Date().getTime() / 1000;
long portainerTokenTtl = expiration - now;
if (portainerTokenTtl > 20) {
redisService.setCacheObject(CacheConstants.PORTAINER_TOKEN, portainerToken, portainerTokenTtl - 10, TimeUnit.SECONDS);
}
} catch (TimeoutException e) {
log.error("获取Portainer Token超时");
} catch (InterruptedException | ExecutionException | IOException | NullPointerException e) {
log.error("获取Portainer Token失败{}", e.getMessage());
}
}
if (StringUtils.isNotEmpty(portainerToken)) {
ServletUtils.removeHeader(mutate, TokenConstants.Cookie);
ServletUtils.removeHeader(mutate, TokenConstants.AUTHENTICATION);
mutate.header(TokenConstants.AUTHENTICATION, TokenConstants.PREFIX + portainerToken);
mutate.header(TokenConstants.Cookie, String.format("%s;%s;", cookie, portainerToken));
} else {
throw new ServiceException("Portainer服务获取Token失败");
}
}
return null;
}
private Mono<Void> exceptionResponse(ServerWebExchange exchange, String msg, int code) {
log.error("[第三方工具请求处理异常]请求路径:{},异常信息:{}", exchange.getRequest().getPath(), msg);
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), ExceptionMsgConstants.SYSTEM_EXEC_ERROR, code);
}
}

View File

@ -1,35 +0,0 @@
package com.microservices.gateway.utils;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.threadPool.ThreadPoolExecutorWrap;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author OTTO
*/
public class CustomExecutorFactory {
/**
* 创建线程池
* 存在并发处理的情况设置核心线程为2设置有界队列长度为100最大线程数为10
* 当超出队列已满且达到最大线程数时抛出异常
* Ncpu=CPU数量
* Ucpu=目标CPU的使用率0<=Ucpu<=1
* W/C=任务等待时间与任务计算时间的比率
* Nthreads =Ncpu*Ucpu*(1+W/C)
*/
public static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutorWrap(
4
, 10
, 10
, TimeUnit.SECONDS
, new ArrayBlockingQueue<>(100)
, Executors.defaultThreadFactory()
, (r, executor) -> {
throw new ServiceException("目前处理的人太多了,请稍后再试");
}
);
}

View File

@ -1,9 +1,7 @@
package com.microservices.cms.doc.controller;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.cms.doc.domain.*;
import com.microservices.cms.doc.service.ICmsDocService;
import com.microservices.common.core.constant.UserConstants;
import com.microservices.common.core.domain.R;
import com.microservices.common.core.web.controller.BaseController;
import com.microservices.common.core.web.domain.AjaxResult;
@ -18,7 +16,6 @@ import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
@ -108,13 +105,23 @@ public class CmsDocController extends BaseController {
@ApiImplicitParam(name = "pageNum", value = "当前记录起始索引", paramType = "query", dataType = "Integer"),
@ApiImplicitParam(name = "pageSize", value = "每页显示记录数", paramType = "query", dataType = "Integer"),
})
public GenericsTableDataInfo<CmsDocAllDto> docListByZone(
public TableDataInfo docListByZone(
@ApiParam(name = "zoneId", value = "专区Id") @PathVariable("zoneId") Long zoneId
, CmsDocSearchVo cmsDocSearchVo) {
Long deptId = cmsDocService.getDeptIdByZoneId(zoneId);
cmsDocSearchVo.setIsOpen(true);
cmsDocSearchVo.setIsOpen(false);
startPage();
return cmsDocService.selectAllDocList(deptId, cmsDocSearchVo);
List<CmsDocAllDto> list = cmsDocService.selectCmsDocListByDept(deptId, cmsDocSearchVo);
list.forEach(x -> {
String docDetailUrl = cmsDocService.getDocDetailUrl(x.getDeptId(), x.getId());
x.setDocDetailUrl(docDetailUrl);
Boolean editable = cmsDocService.isCmsDocEditable(x);
x.setEditable(editable);
});
int count = cmsDocService.selectCmsDocCountByDept(deptId, cmsDocSearchVo);
return getDataTable(list, count);
}
/**
@ -156,7 +163,7 @@ public class CmsDocController extends BaseController {
/**
* 新增文章信息
*/
@RequiresPermissions(UserConstants.CMS_PERMS_DOCS_ADD)
@RequiresPermissions("cms:doc:add")
@Log(title = "文章信息", businessType = BusinessType.INSERT)
@PostMapping("/dir/{dirId}")
@ApiOperation("在栏目下创建文章")
@ -193,7 +200,7 @@ public class CmsDocController extends BaseController {
/**
* 删除文章
*/
@RequiresPermissions(UserConstants.CMS_PERMS_DOCS_DELETE)
@RequiresPermissions("cms:doc:remove")
@Log(title = "文章信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@ApiOperation("删除文章/栏目")
@ -204,13 +211,13 @@ public class CmsDocController extends BaseController {
/**
* 修改文章信息
*/
@RequiresPermissions(UserConstants.CMS_PERMS_DOCS_EDIT)
@RequiresPermissions("cms:doc:edit")
@Log(title = "文章信息", businessType = BusinessType.UPDATE)
@PutMapping("/{id}")
@ApiOperation("更新文章")
public AjaxResult edit(@ApiParam(name = "id", value = "文章Id") @PathVariable Long id,
@ApiParam(name = "cmsDoc", value = "文章实体对象") @RequestBody CmsDocDto cmsDocDto) {
return success(cmsDocService.updateCmsDoc(id, cmsDocDto));
return toAjax(cmsDocService.updateCmsDoc(id, cmsDocDto));
}
/**
@ -223,18 +230,18 @@ public class CmsDocController extends BaseController {
public AjaxResult editCmsDIr(@ApiParam(name = "id", value = "栏目Id") @PathVariable Long id,
@ApiParam(name = "cmsDirUpdateVo", value = "栏目更新对象") @RequestBody CmsDirUpdateVo cmsDirUpdateVo) {
cmsDocService.updateCmsDir(id, cmsDirUpdateVo);
return success("栏目信息更新成功");
return success("异步更新栏目信息");
}
/**
* 审核文章信息
*/
@RequiresPermissions(UserConstants.CMS_PERMS_DOCS_AUDIT)
@RequiresPermissions("cms:doc:audit")
@Log(title = "文章信息", businessType = BusinessType.UPDATE)
@PutMapping("/{id}/audit")
@ApiOperation("审核文章")
public AjaxResult audit(@ApiParam(name = "id", value = "文章Id") @PathVariable Long id,
@ApiParam(name = "cmsDocAuditVo", value = "文章审核对象") @RequestBody CmsDocAuditVo cmsDocAuditVo) {
@ApiParam(name = "cmsDocAuditVo", value = "文章审核对象") @RequestBody CmsDocAuditVo cmsDocAuditVo) {
return toAjax(cmsDocService.auditCmsDoc(id, cmsDocAuditVo));
}
@ -296,43 +303,4 @@ public class CmsDocController extends BaseController {
, @RequestBody CmsDocInputDto cmsDocInputDto) {
return R.ok(cmsDocService.initCmsDoc(dirId, cmsDocInputDto));
}
@InnerAuth
@GetMapping("/getJSONObject/{cmsDocId}")
R<JSONObject> selectCmsDocJSONObjectById(@PathVariable(value = "cmsDocId") Long cmsDocId) {
CmsDoc cmsDoc = cmsDocService.selectBaseCmsDocById(cmsDocId);
JSONObject cmsDocJSONObject = JSONObject.from(cmsDoc);
String docDetailUrl = cmsDocService.getDocDetailUrl(cmsDoc.getDeptId(), cmsDoc.getId());
cmsDocJSONObject.put("docDetailUrl", docDetailUrl);
return R.ok(cmsDocJSONObject);
}
/**
* 内部接口首页文章合并列表接收置顶文章 docId 有序列表返回合并去重后的结果
* Zone 服务 Feign 调用用于 /open/getTopDoc 改造
*/
@InnerAuth
@PostMapping("/homePageDocMergeList/{zoneId}")
@ApiOperation(value = "首页文章合并列表", hidden = true)
public R<List<JSONObject>> selectHomePageDocMergeList(
@PathVariable("zoneId") Long zoneId,
@RequestBody List<Long> topDocIds) {
List<CmsDocBaseDto> list = cmsDocService.selectHomePageDocMergeList(zoneId, topDocIds);
List<JSONObject> result = new ArrayList<>();
for (CmsDocBaseDto dto : list) {
result.add(JSONObject.from(dto));
}
return R.ok(result);
}
/**
* 通过组织Id获取专区下文章阅读数量
*
* @param deptId 组织id
* @return 结果
*/
@GetMapping("/getCmsDocVisitsByDeptId/{deptId}")
public R<Long> getCmsDocVisitsByDeptId(@PathVariable(value = "deptId") Long deptId) {
return R.ok(cmsDocService.getCmsDocVisitsByDeptId(deptId));
}
}

View File

@ -5,17 +5,12 @@ import com.microservices.cms.doc.domain.*;
import com.microservices.cms.doc.service.ICmsDocCommentService;
import com.microservices.cms.doc.service.ICmsDocService;
import com.microservices.cms.doc.service.ICmsWechatService;
import com.microservices.cms.search.dto.DocSearchResult;
import com.microservices.common.core.web.controller.BaseController;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.common.core.web.domain.GenericsAjaxResult;
import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.common.core.web.page.TableDataInfo;
import com.microservices.common.log.annotation.Log;
import com.microservices.common.log.enums.BusinessType;
import com.microservices.cms.search.dto.DocSearchRequest;
import com.microservices.cms.search.dto.DocSearchResponse;
import com.microservices.cms.search.service.IGlobalSearchService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -40,22 +35,6 @@ public class OpenController extends BaseController {
@Autowired
private ICmsWechatService cmsWechatService;
@Autowired
private IGlobalSearchService globalSearchService;
/**
* 文章搜索接口
*
* @return 搜索结果
*/
@ApiOperation("文章搜索")
@PostMapping("/search")
public GenericsTableDataInfo<DocSearchResult> docSearch(@RequestBody DocSearchRequest docSearchRequest) {
logger.info("文章搜索请求: keyword={}", docSearchRequest.getKeyword());
DocSearchResponse response = globalSearchService.docSearch(docSearchRequest);
return new GenericsTableDataInfo<>(response.getResults(), response.getTotal());
}
/**
* 查询栏目列表
*/
@ -89,7 +68,7 @@ public class OpenController extends BaseController {
public GenericsTableDataInfo<CmsDocBaseDto> docList(@ApiParam(name = "dirId", value = "栏目Id") @PathVariable("dirId") Long dirId
, CmsDocSearchVo cmsDocSearchVo) {
cmsDocSearchVo.setIsOpen(true);
List<CmsDocBaseDto> list = cmsDocService.selectSetDefaultHeadImgCmsDocList(dirId, cmsDocSearchVo);
List<CmsDocBaseDto> list = cmsDocService.selectCmsDocList(dirId, cmsDocSearchVo);
return getAllGenericsDataTableToPage(list);
}
@ -121,19 +100,6 @@ public class OpenController extends BaseController {
return getAllGenericsDataTableToPage(list);
}
/**
* 查询文章列表不区分栏目
*/
@GetMapping("/zone/{zoneId}/allDocList")
@ApiOperation("查询文章列表(不区分栏目)")
public GenericsTableDataInfo<CmsDocAllDto> allDocList(@ApiParam(name = "zoneId", value = "专区Id") @PathVariable("zoneId") Long zoneId,
CmsDocSearchVo cmsDocSearchVo) {
Long deptId = cmsDocService.getDeptIdByZoneId(zoneId);
cmsDocSearchVo.setIsOpen(true);
startPage();
return cmsDocService.selectAllDocList(deptId, cmsDocSearchVo);
}
/**
* 查询首页文章列表
*/
@ -209,9 +175,9 @@ public class OpenController extends BaseController {
@Log(title = "同步文章数据", businessType = BusinessType.UPDATE)
public AjaxResult syncDocData(
@ApiParam(name = "deptId", value = "组织Id", required = true) @PathVariable("deptId") Long deptId
, @RequestBody() String bodyStr
,@RequestBody() String bodyStr
, HttpServletRequest request) {
cmsDocService.syncDocData(deptId, bodyStr);
cmsDocService.syncDocData(deptId,bodyStr);
return AjaxResult.success("同步消息发送成功");
}

View File

@ -41,9 +41,6 @@ public class CmsDir implements Comparable<CmsDir> {
@ApiModelProperty(value = "排序", hidden = true)
private Integer sort;
@ApiModelProperty(value = "文章头图")
private String headImg;
public String getName() {
if (name != null) {
name = name.replaceAll(CmsConstants.DIR_SEPARATOR,

View File

@ -21,6 +21,9 @@ public class CmsDirUpdateVo {
@ApiModelProperty(value = "顺序")
private Integer order;
@ApiModelProperty(value = "文章头图")
private String headImg;
public CmsDir toCmsDir() {
CmsDir cmsDir = new CmsDir();
cmsDir.setName(name);
return cmsDir;
}
}

View File

@ -3,7 +3,6 @@ package com.microservices.cms.doc.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.microservices.cms.utils.CmsConstants;
import com.microservices.common.core.annotation.Excel;
import com.microservices.common.core.utils.bean.BeanUtils;
import com.microservices.common.core.web.domain.BaseSortEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -37,27 +36,19 @@ public class CmsDoc extends BaseSortEntity {
@Excel(name = "文件名称")
private String fileName;
/**
* 文件路径
*/
/** 文件路径 */
@Excel(name = "文件路径")
private String filePath;
/**
* 文件SHA
*/
/** 文件SHA */
@Excel(name = "文件SHA")
private String fileSha;
/**
* 文件大小
*/
/** 文件大小 */
@Excel(name = "文件大小")
private Long fileSize;
/**
* 文件URL
*/
/** 文件URL */
@Excel(name = "文件URL")
private String fileUrl;
@ -166,21 +157,10 @@ public class CmsDoc extends BaseSortEntity {
*/
private String auditEditableStatus;
/**
* 关键词
*/
private String keywords;
/**
* 备注
*/
private String remark;
public CmsDir copyToCmsDir() {
CmsDir cmsDir = new CmsDir();
cmsDir.setId(id);
cmsDir.setName(name);
cmsDir.setHeadImg(headImg);
cmsDir.setSort(this.getSort());
cmsDir.setCreatedAt(getCreateTime());
return cmsDir;
@ -201,8 +181,6 @@ public class CmsDoc extends BaseSortEntity {
HotCmsDocDto hotCmsDocDto = new HotCmsDocDto();
hotCmsDocDto.setId(id);
hotCmsDocDto.setName(name);
hotCmsDocDto.setSummary(summary);
hotCmsDocDto.setPublishTime(publishTime);
return hotCmsDocDto;
}
@ -224,12 +202,29 @@ public class CmsDoc extends BaseSortEntity {
}
private CmsDocBaseDto getCmsDocBaseDto(CmsDocBaseDto cmsDocDto) {
BeanUtils.copyProperties(this, cmsDocDto);
cmsDocDto.setId(id);
cmsDocDto.setName(name);
cmsDocDto.setHeadImg(headImg);
cmsDocDto.setIsHomepage(isHomepage);
cmsDocDto.setSummary(summary);
cmsDocDto.setEditorType(editorType);
cmsDocDto.setDeptId(deptId);
if (visits == null) {
cmsDocDto.setVisits(0L);
} else {
cmsDocDto.setVisits(visits);
}
cmsDocDto.setPublishTime(publishTime);
cmsDocDto.setPublishUser(publishUser);
cmsDocDto.setPublishUserUrl(publishUserUrl);
cmsDocDto.setPublishUserImage(publishUserImage);
cmsDocDto.setPublishUserNickname(publishUserNickname);
cmsDocDto.setAuditStatus(auditStatus);
cmsDocDto.setAuditType(auditType);
cmsDocDto.setCreateBy(createBy);
return cmsDocDto;
}

View File

@ -20,10 +20,4 @@ public class CmsDocAuditVo {
*/
@ApiModelProperty(value = "是否重新编辑: 0不允许重新编辑 1允许重新编辑")
private Integer reedit;
/**
* 备注
*/
@ApiModelProperty(value = "审核备注")
private String remark;
}

View File

@ -96,15 +96,6 @@ public class CmsDocBaseDto {
@ApiModelProperty("文章创建者")
private String createBy;
/**
* 关键词
*/
@ApiModelProperty("关键词")
private String keywords;
/**
* 备注
*/
private String remark;
public void setPublishTime(Date publishTime) {
if (publishTime != null) {

View File

@ -65,11 +65,6 @@ public class CmsDocDto {
@ApiModelProperty("是否在栏目下修改")
private boolean isChangeOnDir;
/**
* 关键词
*/
@ApiModelProperty("关键词")
private String keywords;
public String getName() {
if (name != null) {

View File

@ -45,11 +45,6 @@ public class CmsDocInputDto {
*/
@ApiModelProperty("文本编辑器类型")
private String editorType;
/**
* 关键词
*/
@ApiModelProperty("关键词")
private String keywords;
public String getContent() {
String base64decodedString;
@ -83,7 +78,6 @@ public class CmsDocInputDto {
cmsDoc.setHeadImg(this.getHeadImg());
cmsDoc.setDeptId(dirDoc.getDeptId());
cmsDoc.setEditorType(this.editorType);
cmsDoc.setKeywords(this.keywords);
return cmsDoc;
}
}

View File

@ -78,15 +78,4 @@ public class CmsDocSearchVo {
*/
@ApiModelProperty(value = "创建者", hidden = true)
private String createBy;
/**
* 关键词
*/
@ApiModelProperty("关键词")
private String keywords;
/**
* 排除文章Id
*/
@ApiModelProperty(value = "排除文章Id", hidden = true)
private Long excludeId;
}

View File

@ -1,23 +0,0 @@
package com.microservices.cms.doc.domain;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* CmsDoc with full-text search score
* 用于全局搜索结果包含全文搜索相关度评分
*
* @author otto
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class CmsDocWithScore extends CmsDoc implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 全文搜索相关度评分来自 MySQL MATCH...AGAINST
*/
private Double searchScore;
}

View File

@ -1,13 +1,10 @@
package com.microservices.cms.doc.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.microservices.common.core.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* @author otto
*/
@ -26,11 +23,4 @@ public class HotCmsDocDto {
@Excel(name = "文章名称")
@ApiModelProperty("文章名称")
private String name;
@ApiModelProperty("文章概要")
private String summary;
@JsonFormat(pattern = "yyyy-MM-dd")
@ApiModelProperty("发布时间")
private Date publishTime;
}

View File

@ -1,7 +1,5 @@
package com.microservices.cms.doc.domain.gitlink;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.exception.ServiceException;
import lombok.Data;
/**
@ -24,12 +22,4 @@ public class EntryDto implements Comparable<EntryDto> {
// 重写Comparable接口的compareTo方法根据年龄升序排列降序修改相减顺序即可
return Math.toIntExact(entryDto.getCommit().getCreated_at_unix() - this.commit.getCreated_at_unix());
}
public static EntryDto getEntryDtoFromJson(JSONObject subEntriesResult) {
FileEntryDto fileEntryDto = subEntriesResult.toJavaObject(FileEntryDto.class);
if (fileEntryDto == null || fileEntryDto.getEntries() == null) {
throw new ServiceException("该文章不存在");
}
return fileEntryDto.getEntries();
}
}

View File

@ -2,7 +2,6 @@ package com.microservices.cms.doc.mapper;
import com.microservices.cms.doc.domain.CmsDoc;
import com.microservices.cms.doc.domain.CmsDocSearchVo;
import com.microservices.cms.doc.domain.CmsDocWithScore;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -24,14 +23,6 @@ public interface CmsDocMapper {
*/
public CmsDoc selectCmsDocById(Long id);
/**
* 批量查询文章信息
*
* @param ids 文章ID列表
* @return 文章信息列表
*/
List<CmsDoc> selectCmsDocByIds(@Param("ids") List<Long> ids);
/**
* 查询文章信息列表
*
@ -40,17 +31,6 @@ public interface CmsDocMapper {
*/
public List<CmsDoc> selectCmsDocList(CmsDocSearchVo cmsDocSearchVo);
/**
* 查询文章信息列表(设置默认头图为栏目头图)
*
* @param cmsDocSearchVo 文章信息
* @return 文章信息集合
*/
List<CmsDoc> selectCmsDocListSetDefaultHeadImg(CmsDocSearchVo cmsDocSearchVo);
/**
* 新增文章信息
*
@ -91,11 +71,6 @@ public interface CmsDocMapper {
CmsDoc selectCmsDocByFilePathAndDeptId(@Param("filePath") String filePath, @Param("deptId") Long deptId);
/**
* 按文章名+deptId查询忽略dirName用于Webhook防重判断
*/
CmsDoc selectCmsDocByNameAndDeptIdIgnoreDirName(@Param("name") String name, @Param("deptId") Long deptId);
List<CmsDoc> selectHotCmsDocList(CmsDoc cmsDocInput);
List<CmsDoc> selectCmsDocDirByDeptIdAndInName(@Param("deptId") Long deptId, @Param("cmsDirNameList") List<String> cmsDirNameList);
@ -195,52 +170,4 @@ public interface CmsDocMapper {
* @return
*/
Long getNotAuditCmsCountByDeptId(Long deptId);
Long getCmsDocVisitsByDeptId(Long deptId);
/**
* 根据组织id获取专区下所有文章和栏目
* @param deptId 组织id
* @return 文章和栏目列表
*/
List<CmsDoc> selectCmsDocAndDirListByDept(Long deptId);
void updateCmsDocShaByPathAndDeptId(@Param("sha") String sha, @Param("filePath") String filePath, @Param("deptId") Long deptId);
/**
* 全局搜索 - 全文索引查询
*
* @param keyword 搜索关键词
* @param deptId 组织ID可选
* @param offset 偏移量
* @param pageSize 每页数量
* @return 搜索结果列表
*/
List<CmsDoc> globalSearch(@Param("keyword") String keyword, @Param("deptId") Long deptId,
@Param("offset") int offset, @Param("pageSize") int pageSize);
/**
* 全局搜索结果计数
*
* @param keyword 搜索关键词
* @param deptId 组织ID可选
* @return 结果数量
*/
Long globalSearchCount(@Param("keyword") String keyword, @Param("deptId") Long deptId);
/**
* 全局搜索 - 全文索引查询含评分
*
* @param keyword 搜索关键词
* @param deptId 组织ID可选
* @param offset 偏移量
* @param pageSize 每页数量
* @return 搜索结果列表含评分
*/
List<CmsDocWithScore> globalSearchWithScore(
@Param("keyword") String keyword,
@Param("deptId") Long deptId,
@Param("offset") int offset,
@Param("pageSize") int pageSize
);
}

View File

@ -91,7 +91,7 @@ public interface ICmsAsyncService {
void asyncCreateBranchAndDeleteFileAndCreatePR(CmsDoc newDocWithAudit, CmsProject cmsProject);
void asyncMoveFileToNewDir(CmsProject cmsProject, CmsDoc oldCmsDir, String newCmsDirName);
void asyncMoveFileToNewDir(CmsProject cmsProject, CmsDoc oldCmsDir, CmsDoc newCmsDir);
/**
* 推送文章数据到搜索引擎
@ -99,38 +99,4 @@ public interface ICmsAsyncService {
* @param cmsDoc 文章
*/
void pushDocDataSearchEngine(CmsDoc cmsDoc);
void clearTmpDoc(CmsProject cmsProject,List<CmsDoc> tmpDocList);
/**
* 异步增加文章发布积分
*
* @param deptId 组织ID
* @param createBy 创建人用户名
* @param docId 文章ID
* @param subjectDesc 文章标题
*/
void addPublishDocPointsAsync(Long deptId, String createBy, Long docId, String subjectDesc);
/**
* 异步增加文章浏览积分每满100次+2上限50
*
* @param deptId 组织ID
* @param createBy 创建人用户名
* @param docId 文章ID
* @param docName 文章名称
* @param totalVisits 累计阅读次数
* @param pointsTriggerCount 当前第几次增加积分
*/
void addVisitsDocPointsAsync(Long deptId, String createBy, Long docId, String docName, Long totalVisits);
/**
* 异步增加文章被设为精选的积分
*
* @param deptId 组织ID
* @param createBy 创建人用户名
* @param docId 文章ID
* @param subjectDesc 文章标题
*/
void addFeaturedDocPointsAsync(Long deptId, String createBy, Long docId, String subjectDesc);
}

View File

@ -5,7 +5,6 @@ import com.microservices.cms.doc.domain.*;
import com.microservices.cms.doc.domain.gitlink.EntryDto;
import com.microservices.cms.doc.domain.gitlink.FileEntryDto;
import com.microservices.cms.project.domain.CmsProject;
import com.microservices.common.core.web.page.GenericsTableDataInfo;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@ -57,9 +56,9 @@ public interface ICmsDocService {
*
* @param id
* @param cmsDocDto 文章信息
* @return 结果 文章id
* @return 结果
*/
public Long updateCmsDoc(Long id, CmsDocDto cmsDocDto);
public boolean updateCmsDoc(Long id, CmsDocDto cmsDocDto);
/**
* 批量删除文章信息
@ -145,15 +144,6 @@ public interface ICmsDocService {
*/
List<CmsDocBaseDto> selectHomePageDocList(Long deptId);
/**
* 查询首页文章合并列表积分置顶文章 + 首页推荐文章自动去重置顶在前
*
* @param zoneId 专区ID
* @param topDocIds 置顶文章 docId 有序列表前端按此顺序排列
* @return 合并后的首页文章列表isTop=true 标识置顶文章
*/
List<CmsDocBaseDto> selectHomePageDocMergeList(Long zoneId, List<Long> topDocIds);
/**
* 初始化栏目
*
@ -208,8 +198,6 @@ public interface ICmsDocService {
*/
List<CmsDocAllDto> selectCmsDocListByDept(Long deptId, CmsDocSearchVo cmsDocSearchVo);
GenericsTableDataInfo<CmsDocAllDto> selectAllDocList(Long deptId, CmsDocSearchVo cmsDocSearchVo);
/**
* 查询专区下文章数量
*
@ -298,14 +286,4 @@ public interface ICmsDocService {
* @return 文章基础信息
*/
CmsDocBaseDto selectCmsDocBaseInfoById(Long id);
Long getCmsDocVisitsByDeptId(Long deptId);
List<CmsDocBaseDto> selectSetDefaultHeadImgCmsDocList(Long dirId, CmsDocSearchVo cmsDocSearchVo);
List<CmsDoc> selectCmsDocAndDirListByDept(Long deptId);
void updateCmsDocShaByPathAndDeptId(String sha, String filePath, Long deptId);
List<CmsDoc> getTmpDocList(CmsDoc cmsDoc);
}

View File

@ -16,18 +16,14 @@ import com.microservices.cms.project.service.ICmsProjectService;
import com.microservices.cms.utils.CmsConstants;
import com.microservices.cms.utils.CmsGitLinkRequestUrl;
import com.microservices.cms.utils.CmsUtils;
import com.microservices.cms.utils.CustomExecutorFactory;
import com.microservices.common.core.constant.CacheConstants;
import com.microservices.common.core.constant.Constants;
import com.microservices.common.core.constant.SecurityConstants;
import com.microservices.common.core.enums.DocAndZoneOperation;
import com.microservices.common.core.enums.DocAuditStatus;
import com.microservices.common.core.enums.SystemRole;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.core.utils.html.EscapeUtil;
import com.microservices.common.core.utils.sign.Base64;
import com.microservices.common.core.utils.uuid.IdUtils;
import com.microservices.common.httpClient.constant.GitLinkConstants;
import com.microservices.common.httpClient.service.HttpAPIService;
@ -35,7 +31,6 @@ import com.microservices.common.httpClient.util.GitLinkRequestHelper;
import com.microservices.common.redis.service.RedisService;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.system.api.RemoteDeptService;
import com.microservices.system.api.RemoteUserService;
import com.microservices.system.api.RemoteZoneService;
import com.microservices.system.api.utils.FeignUtils;
import org.apache.http.client.config.RequestConfig;
@ -52,7 +47,6 @@ import org.springframework.util.DigestUtils;
import java.net.URISyntaxException;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@ -98,10 +92,7 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
@Autowired
private RemoteZoneService remoteZoneService;
@Autowired
private RemoteUserService remoteUserService;
@Autowired
private RequestConfig config;
/**
* 异步设置文章更新时间
*
@ -118,7 +109,7 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
} else {
redisService.setCacheObject(updateDocIntervalKey, cmsProject.getName(), 1L, TimeUnit.MINUTES);
}
CmsDocSearchVo cmsDocSearch = new CmsDocSearchVo();
CmsDocSearchVo cmsDocSearch=new CmsDocSearchVo();
cmsDocSearch.setDeptId(cmsProject.getDeptId());
List<CmsDoc> cmsDocList = cmsDocMapper.selectCmsDocList(cmsDocSearch);
for (EntryDto entryDto : entryDtoList) {
@ -159,7 +150,7 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
webhook.put("eventCondition", "push");
webhook.put("http_method", "POST");
webhook.put("secret", "");
webhook.put("url", gatewayUrl + "/cms/doc/open/dept/" + cmsProject.getDeptId());
webhook.put("url", gatewayUrl+"/cms/doc/open/dept/"+cmsProject.getDeptId());
webhook.put("events", new String[]{"push"});
jsonObject.put("webhook", webhook);
//增加Webhook
@ -240,7 +231,7 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
}
private void syncDocAddedData(CmsProject cmsProject, List<String> addedList) {
for (String addedFilePath : addedList) {
for (String addedFilePath:addedList) {
try {
String[] filePathList = addedFilePath.split("/");
if (filePathList.length != 2) {
@ -256,27 +247,18 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
}
CmsDoc cmsDoc = cmsDocMapper.selectCmsDocByNameAndDeptId(CmsUtils.getFileNameNoSuffix(entry.getName()), cmsProject.getDeptId(), dirName);
if (cmsDoc == null) {
// 防重按文章名+deptId查一次排除正在移动栏目的已有记录
String docName = CmsUtils.getFileNameNoSuffix(entry.getName());
CmsDoc existingDoc = cmsDocMapper.selectCmsDocByNameAndDeptIdIgnoreDirName(docName, cmsProject.getDeptId());
if (existingDoc != null) {
existingDoc.setDirName(dirName);
existingDoc.setFilePath(dirName + "/" + existingDoc.getFileName());
cmsDocMapper.updateCmsDoc(existingDoc);
} else {
syncCreateDoc(entry, dirName, cmsProject.getDeptId(), fileEntry.getLast_commit());
}
syncCreateDoc(entry, dirName, cmsProject.getDeptId(), fileEntry.getLast_commit());
}
}
} catch (Exception e) {
}catch (Exception e){
logger.error("[{}]同步新增文章发生异常:{}"
, cmsProject.getName(), e.getMessage());
}
}
}
private void syncDocRemovedData(CmsProject cmsProject, List<String> removedList) {
for (String removedFilePath : removedList) {
private void syncDocRemovedData(CmsProject cmsProject,List<String> removedList) {
for (String removedFilePath:removedList) {
try {
String[] filePathList = removedFilePath.split("/");
if (filePathList.length != 2) {
@ -375,7 +357,7 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
cmsDocSearch.setDeptId(cmsDir.getDeptId());
cmsDocSearch.setDirName(cmsDir.getName());
cmsDocSearch.setIsDir(false);
List<CmsDoc> cmsDocList = cmsDocMapper.selectCmsDocList(cmsDocSearch);
List<CmsDoc> cmsDocList=cmsDocMapper.selectCmsDocList(cmsDocSearch);
//获取数据库所有文件的filePath
List<String> databaseFilePathList = cmsDocList.stream().map(CmsDoc::getFilePath).collect(Collectors.toList());
//获取需要新增的文章
@ -401,16 +383,16 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
@Override
public void asyncDocData(Long deptId, String bodyStr) {
//防止多次操作同时执行将同步内容放入队列根据先后时间执行同步动作
String cmsSyncDeptIdKey = CacheConstants.CMS_SYNC_DEPT_ID_KEY + deptId;
String cmsSyncDeptIdKey=CacheConstants.CMS_SYNC_DEPT_ID_KEY+deptId;
//为当前同步操作生成UUID若拿到的UUID为自身则执行本次同步动作
String UUID = IdUtils.fastSimpleUUID();
String UUID= IdUtils.fastSimpleUUID();
redisService.leftPush(cmsSyncDeptIdKey, UUID);
//设置缓存过期时间防止异常情况导致同步无法继续执行
redisService.expire(cmsSyncDeptIdKey, 3600, TimeUnit.SECONDS);
String currentUUID = String.valueOf(redisService.listIndexOf(cmsSyncDeptIdKey, -1));
//设置最大循环阈值防止意外情况导致死循环(7200次约1小时左右)
int threshold = 7200;
while (!UUID.equals(currentUUID) && threshold != 0) {
int threshold=7200;
while (!UUID.equals(currentUUID)&&threshold!=0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
@ -420,41 +402,41 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
threshold--;
}
try {
CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(deptId);
JSONObject body = JSONObject.parseObject(bodyStr);
try{
CmsProject cmsProject=cmsProjectService.selectCmsProjectByDeptId(deptId);
JSONObject body=JSONObject.parseObject(bodyStr);
//获取本次推送中Commit总数
Integer totalCommits = body.getInteger("total_commits");
Integer totalCommits=body.getInteger("total_commits");
//从webhook请求中获取本次提交内容
JSONArray commits = body.getJSONArray("commits");
JSONArray commits=body.getJSONArray("commits");
//当commit总数大于提交的列表数量时代表此次PUSH未携带所有commit此时进行一次全量同步
if (totalCommits != null
&& commits != null
&& totalCommits > commits.size()) {
if(totalCommits!=null
&&commits!=null
&&totalCommits>commits.size()){
fullSyncDocData(cmsProject);
} else {
for (int i = commits.size() - 1; i >= 0; i--) {
JSONObject commit = commits.getJSONObject(i);
}else{
for (int i = commits.size()-1; i >=0 ; i--) {
JSONObject commit=commits.getJSONObject(i);
//获取新增的文件列表
JSONArray addedList = commit.getJSONArray("added");
if (addedList != null) {
syncDocAddedData(cmsProject, addedList.toJavaList(String.class));
JSONArray addedList=commit.getJSONArray("added");
if(addedList!=null){
syncDocAddedData(cmsProject,addedList.toJavaList(String.class));
}
//获取删除的文件列表
JSONArray removedList = commit.getJSONArray("removed");
if (removedList != null) {
syncDocRemovedData(cmsProject, removedList.toJavaList(String.class));
JSONArray removedList=commit.getJSONArray("removed");
if(removedList!=null){
syncDocRemovedData(cmsProject,removedList.toJavaList(String.class));
}
//获取更新的文件列表
JSONArray modifiedList = commit.getJSONArray("modified");
if (modifiedList != null) {
JSONArray modifiedList=commit.getJSONArray("modified");
if(modifiedList!=null){
syncDocModifiedData(cmsProject, modifiedList.toJavaList(String.class));
}
}
}
} catch (Exception e) {
}catch (Exception e) {
logger.error("同步文章时发送异常:{}", e.getMessage());
} finally {
}finally {
//本次同步执行完成后再弹出该UUID
redisService.rightPop(cmsSyncDeptIdKey, 500, TimeUnit.MICROSECONDS);
}
@ -487,12 +469,12 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
}
@Override
public void syncCreateDir(String dirName, EntryDto entry, CmsProject cmsProject, boolean isCreateKeep) {
public void syncCreateDir(String dirName,EntryDto entry,CmsProject cmsProject,boolean isCreateKeep){
CmsDoc cmsDir = new CmsDoc();
cmsDir.setName(dirName);
cmsDir.setCreateTime(entry.getCommit().getCreated_at());
boolean insertResult;
if (isCreateKeep) {
if(isCreateKeep){
//若该栏目不存在检查文件夹中是否存在.keep文件
JSONObject subEntriesResult = gitLinkRequestHelper.doGet(
CmsGitLinkRequestUrl.GET_FILE_SUB_ENTRIES(cmsProject, cmsDir.getName(), CmsConstants.BRANCH_MASTER));
@ -502,14 +484,14 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
if (keepEntry != null) {
//若存在则在数据库中创建该栏目
insertResult = createCmsDir(cmsDir, cmsProject.getDeptId(), keepEntry);
insertResult=createCmsDir(cmsDir,cmsProject.getDeptId(),keepEntry);
} else {
//若不存在则在数据库中创建该栏目同时在仓库的该文件夹下创建.keep文件
insertResult = cmsDocService.insertCmsDocDir(cmsProject.getDeptId(), cmsDir.copyToCmsDir());
}
} else {
}else{
//若不自动创建则在数据库中创建根据文件名该栏目
insertResult = createCmsDir(cmsDir, cmsProject.getDeptId(), entry);
insertResult=createCmsDir(cmsDir,cmsProject.getDeptId(),entry);
}
@ -518,7 +500,7 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
}
}
private boolean createCmsDir(CmsDoc cmsDir, Long deptId, EntryDto entry) {
private boolean createCmsDir(CmsDoc cmsDir,Long deptId,EntryDto entry){
cmsDir.setIsDir(true);
cmsDir.setFilePath(cmsDir.getDirPath());
cmsDir.setDeptId(deptId);
@ -632,12 +614,11 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
100, "..."), tmpBranchName);
} catch (ServiceException e) {
//忽略重复创建PR异常
if (!e.getMessage().contains("合并请求已存在")) {
if (!"请求GitLink失败(合并请求已存在)".equals(e.getMessage())) {
throw new ServiceException(e.getMessage());
}
}
cmsDocService.updateCmsCommonDatabase(cmsDoc, tmpBranchName);
}
@ -697,7 +678,6 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
requestBody);
cmsDoc.setAuditPrNumber(result.getString("pull_request_number") + "-" + result.getString("pull_request_id"));
}
@Override
public CmsDoc updateCmsDocDatabaseAndUpdateForGitLink(CmsDoc oldCmsDoc, CmsDocDto cmsDocDto, String branchName) {
if (oldCmsDoc == null) {
@ -738,8 +718,8 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
if (isChangeName || isChangeDir) {
oldCmsDoc = renameAndChangeDirCmsDoc(oldCmsDoc, cmsProject, newName, newDirName, branchName);
// 立即更新数据库中的dirName/filePath避免GitLink Webhook回调时查不到记录导致重复INSERT
cmsDocMapper.updateCmsDoc(oldCmsDoc);
//todo 此处是否需要更新数据库待讨论
//updateCmsCommonDatabase(oldCmsDoc);
}
boolean isChangeContent = false;
@ -891,87 +871,27 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
}
@Override
public void asyncMoveFileToNewDir(CmsProject cmsProject, CmsDoc oldCmsDir, String newCmsDirName) {
@Async
public void asyncMoveFileToNewDir(CmsProject cmsProject, CmsDoc oldCmsDir, CmsDoc newCmsDir) {
try {
JSONObject dirFilesJson = gitLinkRequestHelper.doGet(CmsGitLinkRequestUrl.GET_DIR_SUB_ENTRIES(
cmsProject,
oldCmsDir.getName(),
CmsConstants.BRANCH_MASTER));
List<EntryDto> entryDtoList = cmsDocService.getEntriesFromRequestResult(dirFilesJson, cmsProject, false);
CountDownLatch countDownLatch = new CountDownLatch(entryDtoList.size());
// 异步获取每篇文章内容
entryDtoList.forEach(entryDto -> {
CustomExecutorFactory.threadPoolExecutor.execute(() -> {
try {
JSONObject fileSubEntriesResult = gitLinkRequestHelper.doGet(
CmsGitLinkRequestUrl.GET_FILE_SUB_ENTRIES(
cmsProject,
entryDto.getPath(),
CmsConstants.BRANCH_MASTER));
EntryDto cmsDocEntryDto = EntryDto.getEntryDtoFromJson(fileSubEntriesResult);
entryDto.setContent(cmsDocEntryDto.getContent());
} finally {
countDownLatch.countDown();
}
});
});
try {
countDownLatch.await();
} catch (InterruptedException e) {
logger.error("栏目重命名失败(将对应代码库中文章移动至新文件夹失败):{}", e.getMessage());
throw new ServiceException("栏目重命名失败");
}
for (EntryDto entryDto : entryDtoList) {
JSONObject updateFileBody = new JSONObject();
updateFileBody.put("branch", CmsConstants.BRANCH_MASTER);
updateFileBody.put("message", "移动文章至新栏目");
updateFileBody.put("from_path", entryDto.getPath());
String newFilePath = newCmsDirName + "/" + entryDto.getName();
updateFileBody.put("filepath", newFilePath);
updateFileBody.put("base64_filepath", Base64.contentToBase64(newFilePath));
updateFileBody.put("sha", entryDto.getSha());
String content = entryDto.getContent();
if (content == null) {
content = "";
}
updateFileBody.put("content", content);
gitLinkRequestHelper.doPut(CmsGitLinkRequestUrl.UPDATE_FILE(cmsProject), updateFileBody);
}
CmsDoc newCmsDoc = oldCmsDir.copyToRenameCmsDir(newCmsDirName);
//在数据库中重命名该栏目
cmsDocService.updateCmsCommonDatabase(newCmsDoc, CmsConstants.BRANCH_MASTER);
remoteZoneService.lockCmsByDeptId(cmsProject.getDeptId(), 1, SecurityConstants.INNER);
//创建新栏目
String message = String.format("重命名栏目:由[%s]重命名为[%s]", oldCmsDir.getName(), newCmsDir.getName());
cmsDocService.createFileByGitLink(newCmsDir, message, "");
//在数据库中重命名该栏目防止后续操作推送的WebHook重复创建栏目
cmsDocService.updateCmsCommonDatabase(newCmsDir, CmsConstants.BRANCH_MASTER);
//将原栏目中所有文章移动到新栏目中
moveCmsDocToNewCmsDir(cmsProject, oldCmsDir.getName(), newCmsDir.getName(), message);
//删除旧栏目
deleteCmsDocByGitLink(cmsProject, oldCmsDir);
} catch (Exception e) {
logger.error("重命名栏目失败(原栏目名称[{}],新栏目名称[{}]){}", oldCmsDir.getName(), newCmsDirName, e.getMessage());
throw new ServiceException("重命名栏目失败(原栏目名称[" + oldCmsDir.getName() + "],新栏目名称[" + newCmsDirName + "])");
logger.error("重命名栏目失败(原栏目名称[{}],新栏目名称[{}]){}", oldCmsDir.getName(), newCmsDir.getName(), e.getMessage());
throw new ServiceException("重命名栏目失败(原栏目名称[" + oldCmsDir.getName() + "],新栏目名称[" + newCmsDir.getName() + "])");
} finally {
remoteZoneService.lockCmsByDeptId(cmsProject.getDeptId(), 0, SecurityConstants.INNER);
}
// finally {
// remoteZoneService.lockCmsByDeptId(cmsProject.getDeptId(), 0, SecurityConstants.INNER);
// }
}
// @Override
// @Async
// public void asyncMoveFileToNewDir(CmsProject cmsProject, CmsDoc oldCmsDir, CmsDoc newCmsDir) {
// try {
// remoteZoneService.lockCmsByDeptId(cmsProject.getDeptId(), 1, SecurityConstants.INNER);
// //创建新栏目
// String message = String.format("重命名栏目:由[%s]重命名为[%s]", oldCmsDir.getName(), newCmsDir.getName());
// cmsDocService.createFileByGitLink(newCmsDir, message, "");
// //在数据库中重命名该栏目防止后续操作推送的WebHook重复创建栏目
// cmsDocService.updateCmsCommonDatabase(newCmsDir, CmsConstants.BRANCH_MASTER);
// //将原栏目中所有文章移动到新栏目中
// moveCmsDocToNewCmsDir(cmsProject, oldCmsDir.getName(), newCmsDir.getName(), message);
// //删除旧栏目
// deleteCmsDocByGitLink(cmsProject, oldCmsDir);
// } catch (Exception e) {
// logger.error("重命名栏目失败(原栏目名称[{}],新栏目名称[{}]){}", oldCmsDir.getName(), newCmsDir.getName(), e.getMessage());
// throw new ServiceException("重命名栏目失败(原栏目名称[" + oldCmsDir.getName() + "],新栏目名称[" + newCmsDir.getName() + "])");
// } finally {
// remoteZoneService.lockCmsByDeptId(cmsProject.getDeptId(), 0, SecurityConstants.INNER);
// }
// }
@Async
@Override
public void pushDocDataSearchEngine(CmsDoc cmsDoc) {
@ -1018,23 +938,6 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
}
}
@Override
public void clearTmpDoc(CmsProject cmsProject, List<CmsDoc> tmpDocList) {
CustomExecutorFactory.threadPoolExecutor.execute(() -> {
for (CmsDoc tmpDoc : tmpDocList) {
//拒绝GitLink合并请求
String gitLinkPullRequestNumber = tmpDoc.getAuditPrNumber().split("-")[0];
gitLinkRequestHelper.doPost(
CmsGitLinkRequestUrl.REFUSE_MERGE_PULL_REQUEST(cmsProject, gitLinkPullRequestNumber), null);
gitLinkRequestHelper.doPost(CmsGitLinkRequestUrl.DELETE_BRANCH(cmsProject, tmpDoc.getAuditTmpBranchName()), null);
// 所有删除操作调整为将审核状态设置为已拒绝
tmpDoc.setAuditStatus(DocAuditStatus.AUDIT_FAIL.getAuditCode());
tmpDoc.setRemark("管理员删除");
cmsDocMapper.updateCmsDoc(tmpDoc);
}
});
}
private void moveCmsDocToNewCmsDir(CmsProject cmsProject, String oldDirName, String newDirName, String message) {
CmsDocSearchVo cmsDocSearch = new CmsDocSearchVo();
cmsDocSearch.setIsDir(false);
@ -1087,127 +990,4 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService {
}
}
/**
* 检查是否为积分部门
*
* @param deptId 部门ID
* @return 是否为积分部门
*/
private boolean isPointsDept(Long deptId) {
Long cachedPointsDeptId = redisService.getCacheObject(CacheConstants.ZONE_POINTS_DEPT_ID_KEY);
return cachedPointsDeptId != null && cachedPointsDeptId > 0 && cachedPointsDeptId.equals(deptId);
}
@Async
@Override
public void addPublishDocPointsAsync(Long deptId, String createBy, Long docId, String subjectDesc) {
try {
if (deptId == null || createBy == null) {
logger.warn("文章审核通过增加积分失败deptId或createBy为空docId={}", docId);
return;
}
// 检查是否为积分部门
if (!isPointsDept(deptId)) {
logger.info("文章审核通过增加积分跳过非积分部门deptId={}docId={}", deptId, docId);
return;
}
// 获取用户ID
com.microservices.system.api.domain.SysUser sysUser = FeignUtils.getReturnData(
remoteUserService.getSysUserByUserName(createBy, SecurityConstants.INNER));
if (sysUser == null || sysUser.getUserId() == null) {
logger.warn("文章审核通过增加积分失败未找到用户信息createBy={}docId={}", createBy, docId);
return;
}
// 直接写入 Redis 积分队列 Zone 模块定时任务消费
JSONObject task = new JSONObject();
task.put("sourceType", CmsConstants.PUBLISH_DOC);
task.put("userId", sysUser.getUserId());
task.put("deptId", deptId);
task.put("sourceId", docId);
task.put("subjectDesc", subjectDesc);
task.put("operatorId", sysUser.getUserId());
redisService.leftPush(CmsConstants.ZONE_POINTS_ASYNC_QUEUE_KEY, task.toJSONString());
logger.info("文章审核通过增加积分任务已写入队列docId={}userId={}deptId={}", docId, sysUser.getUserId(), deptId);
} catch (Exception e) {
// 捕获异常确保不影响主事务
logger.error("文章审核通过增加积分异常docId={}", docId, e);
}
}
@Async
@Override
public void addVisitsDocPointsAsync(Long deptId, String createBy, Long docId, String docName, Long totalVisits) {
try {
if (deptId == null || createBy == null) {
logger.warn("文章浏览增加积分失败参数不合法deptId={}createBy={}", deptId, createBy);
return;
}
// 检查是否为积分部门
if (!isPointsDept(deptId)) {
logger.info("文章浏览增加积分跳过非积分部门deptId={}docId={}", deptId, docId);
return;
}
// 获取用户ID
com.microservices.system.api.domain.SysUser sysUser = FeignUtils.getReturnData(
remoteUserService.getSysUserByUserName(createBy, SecurityConstants.INNER));
if (sysUser == null || sysUser.getUserId() == null) {
logger.warn("文章浏览增加积分失败未找到用户信息createBy={}docId={}", createBy, docId);
return;
}
// 直接写入 Redis 积分队列 Zone 模块定时任务消费
JSONObject task = new JSONObject();
task.put("sourceType", CmsConstants.VISITS_DOC);
task.put("userId", sysUser.getUserId());
task.put("deptId", deptId);
task.put("sourceId", docId);
// JSONObject sourceData = new JSONObject();
// sourceData.put("totalVisits", totalVisits);
// sourceData.put("currentIncrement", pointsTriggerCount);
task.put("sourceData", totalVisits);
task.put("subjectDesc", docName);
task.put("operatorId", SecurityUtils.getUserId());
redisService.leftPush(CmsConstants.ZONE_POINTS_ASYNC_QUEUE_KEY, task.toJSONString());
logger.info("文章浏览增加积分任务已写入队列docId={}userId={}deptId={}totalVisits={}", docId, sysUser.getUserId(), deptId, totalVisits);
} catch (Exception e) {
// 捕获异常确保不影响主事务
logger.error("文章浏览增加积分异常docId={}", docId, e);
}
}
@Async
@Override
public void addFeaturedDocPointsAsync(Long deptId, String createBy, Long docId, String subjectDesc) {
try {
if (deptId == null || createBy == null) {
logger.warn("积分-文章精选参数不合法deptId={}createBy={}", deptId, createBy);
return;
}
// 检查是否为积分部门
if (!isPointsDept(deptId)) {
logger.info("积分-文章精选非积分部门deptId={}docId={}", deptId, docId);
return;
}
// 获取用户ID
com.microservices.system.api.domain.SysUser sysUser = FeignUtils.getReturnData(
remoteUserService.getSysUserByUserName(createBy, SecurityConstants.INNER));
if (sysUser == null || sysUser.getUserId() == null) {
logger.warn("积分-文章精选未找到用户信息createBy={}docId={}", createBy, docId);
return;
}
// 直接写入 Redis 积分队列 Zone 模块定时任务消费
JSONObject task = new JSONObject();
task.put("sourceType", CmsConstants.FEATURED_DOC);
task.put("userId", sysUser.getUserId());
task.put("deptId", deptId);
task.put("sourceId", docId);
task.put("subjectDesc", "" + subjectDesc + "》管理员标记");
task.put("operatorId", SecurityUtils.getUserId());
redisService.leftPush(CmsConstants.ZONE_POINTS_ASYNC_QUEUE_KEY, task.toJSONString());
logger.info("文章被设为精选增加积分任务已写入队列docId={}userId={}deptId={}", docId, sysUser.getUserId(), deptId);
} catch (Exception e) {
// 捕获异常确保不影响主事务
logger.error("文章被设为精选增加积分异常docId={}", docId, e);
}
}
}

View File

@ -166,7 +166,7 @@ public class CmsDocCommentServiceImpl implements ICmsDocCommentService {
return true;
}
// 判断是否为当前组织下的专区管理员
return deptId.equals(SecurityUtils.getDeptId())
return deptId.equals(SecurityUtils.getUserIdentity().getDeptId())
&& SystemRole.ZONE_ADMIN.getRoleKey().equals(SecurityUtils.getRoleKey());
}

View File

@ -15,7 +15,6 @@ import com.microservices.cms.utils.CmsGitLinkRequestUrl;
import com.microservices.common.core.constant.CacheConstants;
import com.microservices.common.core.constant.HttpStatus;
import com.microservices.common.core.constant.SecurityConstants;
import com.microservices.common.core.constant.UserConstants;
import com.microservices.common.core.enums.DocAndZoneOperation;
import com.microservices.common.core.enums.DocAuditStatus;
import com.microservices.common.core.enums.SystemRole;
@ -24,12 +23,10 @@ import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.core.utils.bean.BeanUtils;
import com.microservices.common.core.utils.html.EscapeUtil;
import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.common.httpClient.constant.GitLinkConstants;
import com.microservices.common.httpClient.util.GitLinkRequestHelper;
import com.microservices.common.redis.service.RedisService;
import com.microservices.common.security.auth.AuthUtil;
import com.microservices.common.security.service.TokenService;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.system.api.RemoteDeptService;
import com.microservices.system.api.RemoteUserService;
@ -50,11 +47,7 @@ import javax.servlet.http.HttpServletRequest;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@ -86,8 +79,6 @@ public class CmsDocServiceImpl implements ICmsDocService {
@Autowired
private RemoteDeptService remoteDeptService;
@Autowired
private TokenService tokenService;
@Autowired
@Lazy
private ICmsDocCommentService cmsDocCommentService;
@Value("${cms.detailPath:/newdetail}")
@ -97,7 +88,7 @@ public class CmsDocServiceImpl implements ICmsDocService {
* 查询文章信息
*
* @param id 文章信息主键
* @param isOpen 是否公开访问
* @param isOpen
* @return 文章信息
*/
@Override
@ -112,14 +103,7 @@ public class CmsDocServiceImpl implements ICmsDocService {
CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(cmsDoc.getDeptId());
// 确定查询文件的分支已发布文章或非仓库改动使用 master其他使用临时分支
String branchName;
if (DocAuditStatus.AUDIT_PASS.getAuditCode().equals(cmsDoc.getAuditStatus())
|| (cmsDoc.getAuditType() != null && cmsDoc.getAuditType().contains(DocAndZoneOperation.OPERATION_NON_REPO_UPDATE.getOperationCode()))) {
branchName = CmsConstants.BRANCH_MASTER;
} else {
branchName = cmsDoc.getAuditTmpBranchName();
}
String branchName = DocAuditStatus.AUDIT_PASS.getAuditCode().equals(cmsDoc.getAuditStatus()) ? CmsConstants.BRANCH_MASTER : cmsDoc.getAuditTmpBranchName();
FileEntryDto fileEntryDto = getFileEntryDto(cmsProject, cmsDoc.getFilePath(), branchName);
EntryDto entryDto = fileEntryDto.getEntries();
@ -130,7 +114,7 @@ public class CmsDocServiceImpl implements ICmsDocService {
if (cmsDoc.getPublishTime() != null && cmsDoc.getPublishTime().after(cmsDoc.getCreateTime())) {
cmsDocDto.setIsFirstPublish(false);
}
if (isOpen && DocAuditStatus.AUDIT_PASS.getAuditCode().equals(cmsDoc.getAuditStatus())) {
if (isOpen) {
updateVisits(cmsDocDto.getId());
}
return cmsDocDto;
@ -186,21 +170,6 @@ public class CmsDocServiceImpl implements ICmsDocService {
return cmsDocList.stream().map(CmsDoc::copyToCmsDocAllDto).collect(Collectors.toList());
}
@Override
public GenericsTableDataInfo<CmsDocAllDto> selectAllDocList(Long deptId, CmsDocSearchVo cmsDocSearchVo) {
List<CmsDocAllDto> list = selectCmsDocListByDept(deptId, cmsDocSearchVo);
list.forEach(x -> {
String docDetailUrl = getDocDetailUrl(x.getDeptId(), x.getId());
x.setDocDetailUrl(docDetailUrl);
Boolean editable = isCmsDocEditable(x);
x.setEditable(editable);
});
int count = selectCmsDocCountByDept(deptId, cmsDocSearchVo);
return new GenericsTableDataInfo<>(list, Long.valueOf(count));
}
@Override
public int selectCmsDocCountByDept(Long deptId, CmsDocSearchVo cmsDocSearchVo) {
cmsDocSearchVo.setDeptId(deptId);
@ -228,21 +197,20 @@ public class CmsDocServiceImpl implements ICmsDocService {
@Override
public void updateCmsDir(Long id, CmsDirUpdateVo cmsDirUpdateVo) {
CmsDoc oldCmsDir = selectCmsDir(id);
checkCmsLockStatus(oldCmsDir.getDeptId());
//设置栏目排序
setCmsSort(cmsDirUpdateVo.getOrder(), oldCmsDir, false, null);
oldCmsDir.setHeadImg(cmsDirUpdateVo.getHeadImg());
updateCmsCommonDatabase(oldCmsDir, CmsConstants.BRANCH_MASTER);
CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(oldCmsDir.getDeptId());
String newCmsDirName = cmsDirUpdateVo.getName();
CmsDoc newCmsDir = oldCmsDir.copyToRenameCmsDir(cmsDirUpdateVo.getName());
if (StringUtils.isNotEmpty(newCmsDirName) && !newCmsDirName.equals(oldCmsDir.getName())) {
CmsDoc cmsDir = cmsDocMapper.selectCmsDocDirByNameAndDeptId(newCmsDirName, oldCmsDir.getDeptId());
if (StringUtils.isNotEmpty(newCmsDir.getName()) && !newCmsDir.getName().equals(oldCmsDir.getName())) {
CmsDoc cmsDir = cmsDocMapper.selectCmsDocDirByNameAndDeptId(newCmsDir.getName(), oldCmsDir.getDeptId());
if (cmsDir != null) {
throw new ServiceException("栏目名称已存在,不允许进行重命名(新栏目名称[" + newCmsDirName + "])");
throw new ServiceException("栏目名称已存在,不允许进行重命名(新栏目名称[" + newCmsDir.getName() + "])");
}
cmsAsyncService.asyncMoveFileToNewDir(cmsProject, oldCmsDir, newCmsDir);
}
// 异步修改栏目名称将仓库内原文件夹下所有文章移动到新文件夹下
cmsAsyncService.asyncMoveFileToNewDir(cmsProject, oldCmsDir, newCmsDirName);
}
}
@Override
@ -263,14 +231,14 @@ public class CmsDocServiceImpl implements ICmsDocService {
@Override
public List<CmsDocDetailDto> selectCmsDocDetailList(Long dirId) {
List<CmsDocDetailDto> cmsDocDetailDtoList = new ArrayList<>();
CmsDoc cmsDir = selectCmsDir(dirId);
CmsDoc cmsDir = cmsDocMapper.selectCmsDocDirById(dirId);
CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(cmsDir.getDeptId());
CmsDocSearchVo cmsDocSearchVo = new CmsDocSearchVo();
cmsDocSearchVo.setDirName(cmsDir.getName());
cmsDocSearchVo.setDeptId(cmsDir.getDeptId());
cmsDocSearchVo.setIsDir(false);
List<CmsDoc> cmsDocList = cmsDocMapper.selectCmsDocListSetDefaultHeadImg(cmsDocSearchVo);
List<CompletableFuture<CmsDocDetailDto>> futures = new ArrayList<>();
List<CmsDoc> cmsDocList = cmsDocMapper.selectCmsDocList(cmsDocSearchVo);
List<CompletableFuture<CmsDocDetailDto>> futures = new ArrayList();
for (CmsDoc cmsDoc : cmsDocList) {
CompletableFuture<CmsDocDetailDto> future = CompletableFuture.supplyAsync(() -> {
CmsDocDetailDto cmsDocDetailDto = cmsDoc.copyToCmsDocDetailDto();
@ -315,21 +283,6 @@ public class CmsDocServiceImpl implements ICmsDocService {
return selectCmsDocListByDatabase(dirId, cmsDocSearchVo);
}
@Override
public List<CmsDocBaseDto> selectSetDefaultHeadImgCmsDocList(Long dirId, CmsDocSearchVo cmsDocSearchVo) {
return selectCmsDocListSetDefaultHeadImgByDatabase(dirId, cmsDocSearchVo);
}
@Override
public List<CmsDoc> selectCmsDocAndDirListByDept(Long deptId) {
return cmsDocMapper.selectCmsDocAndDirListByDept(deptId);
}
@Override
public void updateCmsDocShaByPathAndDeptId(String sha, String filePath, Long deptId) {
cmsDocMapper.updateCmsDocShaByPathAndDeptId(sha, filePath, deptId);
}
private List<CmsDocBaseDto> selectCmsDocListByDatabase(Long dirId, CmsDocSearchVo cmsDocSearchVo) {
CmsDoc cmsDocDir = selectCmsDir(dirId);
@ -342,25 +295,6 @@ public class CmsDocServiceImpl implements ICmsDocService {
return cmsDocList.stream().map(CmsDoc::copyToCmsDocBaseDto).collect(Collectors.toList());
}
/**
* 设置文章默认头图为栏目头图
*
* @param dirId 栏目id
* @param cmsDocSearchVo 文章查询条件
* @return 文章列表
*/
private List<CmsDocBaseDto> selectCmsDocListSetDefaultHeadImgByDatabase(Long dirId, CmsDocSearchVo cmsDocSearchVo) {
CmsDoc cmsDocDir = selectCmsDir(dirId);
cmsDocSearchVo.setDeptId(cmsDocDir.getDeptId());
cmsDocSearchVo.setDirName(cmsDocDir.getName());
List<CmsDoc> cmsDocList = cmsDocMapper.selectCmsDocListSetDefaultHeadImg(cmsDocSearchVo);
if (cmsDocList == null || cmsDocList.isEmpty()) {
return new ArrayList<>();
}
return cmsDocList.stream().map(CmsDoc::copyToCmsDocBaseDto).collect(Collectors.toList());
}
/**
* 检查专区资讯是否处于锁定状态若处于则抛出异常
*
@ -390,16 +324,12 @@ public class CmsDocServiceImpl implements ICmsDocService {
checkCmsLockStatus(dirDoc.getDeptId());
CmsDoc cmsDoc = cmsDocInputDto.toCmsDoc(dirDoc);
if (isNoAuditRequired(dirDoc.getDeptId()) || tokenService.hasDeptPerms(dirDoc.getDeptId(), UserConstants.CMS_PERMS_DOCS_AUDIT)) {
if (isNoAuditRequired(dirDoc.getDeptId()) || isCurrentUserZoneAdmin(dirDoc.getDeptId())) {
//文章自动置为审核通过状态值
cmsDoc.setAuditStatus(DocAuditStatus.AUDIT_PASS.getAuditCode());
boolean success = insertCommonCmsDoc(cmsDoc,
"创建文章:" + StringUtils.truncateStringAndConcatenatingSpecifiedString(cmsDoc.getName(), 100, "..."),
cmsDocInputDto.getContent());
if (success) {
// 自动审核通过时也需要增加积分
cmsAsyncService.addPublishDocPointsAsync(cmsDoc.getDeptId(), cmsDoc.getCreateBy(), cmsDoc.getId(), cmsDoc.getName());
}
return success ? cmsDoc.getId().intValue() : null;
} else {
//创建临时分支创建文件创建PR
@ -437,9 +367,7 @@ public class CmsDocServiceImpl implements ICmsDocService {
public String getCmsDocFileContent(CmsProject cmsProject, CmsDoc cmsDoc) {
String branchName = CmsConstants.BRANCH_MASTER;
if (!DocAuditStatus.AUDIT_PASS.getAuditCode().equals(cmsDoc.getAuditStatus())) {
if (StringUtils.isNotEmpty(cmsDoc.getAuditTmpBranchName())) {
branchName = cmsDoc.getAuditTmpBranchName();
}
branchName = cmsDoc.getAuditTmpBranchName();
}
//当删除文章为文件夹时判断该文件夹下是否存在文章若存在需先删除所有文章
JSONObject getSubEntriesResult = gitLinkRequestHelper.doGet(
@ -459,34 +387,9 @@ public class CmsDocServiceImpl implements ICmsDocService {
@Transactional(rollbackFor = Exception.class)
public boolean auditCmsDoc(Long docId, CmsDocAuditVo cmsDocAuditVo) {
CmsDoc cmsDoc = cmsDocMapper.selectCmsDocById(docId);
if (cmsDoc == null) {
throw new ServiceException("该文章不存在");
}
checkCmsLockStatus(cmsDoc.getDeptId());
CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(cmsDoc.getDeptId());
// 设置审核备注
cmsDoc.setRemark(cmsDocAuditVo.getRemark());
if (cmsDocAuditVo.getPass() == 1) {
// 处理非仓库改动的审核通过
if (cmsDoc.getAuditType() != null
&& cmsDoc.getAuditType().contains(DocAndZoneOperation.OPERATION_NON_REPO_UPDATE.getOperationCode())) {
Long oldCmsDocId = Long.parseLong(cmsDoc.getAuditType().split("-")[1]);
CmsDoc oldCmsDoc = cmsDocMapper.selectCmsDocById(oldCmsDocId);
// 用新文章的非仓库字段更新旧文章
oldCmsDoc.setHeadImg(cmsDoc.getHeadImg());
oldCmsDoc.setSummary(cmsDoc.getSummary());
oldCmsDoc.setKeywords(cmsDoc.getKeywords());
oldCmsDoc.setRemark(cmsDoc.getRemark());
cmsDocMapper.updateCmsDoc(oldCmsDoc);
// 删除待审核记录
cmsDocMapper.deleteCmsDocById(cmsDoc.getId());
return true;
}
//同意合并请求
JSONObject result = mergePullRequestByGitLink(cmsProject, cmsDoc);
if (result.containsKey(GitLinkConstants.STATUS_KEY)) {
@ -508,16 +411,8 @@ public class CmsDocServiceImpl implements ICmsDocService {
}
}
if (cmsDocAuditVo.getPass() == 0) {
// 处理非仓库改动的审核拒绝
if (cmsDoc.getAuditType().contains(DocAndZoneOperation.OPERATION_NON_REPO_UPDATE.getOperationCode())) {
handleCmsDocWithNoPassByReedit(cmsDocAuditVo, cmsDoc, cmsProject);
return true;
}
//拒绝GitLink合并请求
String gitLinkPullRequestNumber = cmsDoc.getAuditPrNumber().split("-")[0];
JSONObject result = gitLinkRequestHelper.doPost(
CmsGitLinkRequestUrl.REFUSE_MERGE_PULL_REQUEST(cmsProject, gitLinkPullRequestNumber), null);
JSONObject result = refuseMergePullRequestByGitLink(cmsDoc, cmsProject);
if (result.containsKey(GitLinkConstants.STATUS_KEY)) {
//2.若拒绝GitLink合并请求操作返回正确的状态值,更新数据库
if (result.getInteger(GitLinkConstants.STATUS_KEY).equals(1)) {
@ -564,10 +459,8 @@ public class CmsDocServiceImpl implements ICmsDocService {
if (cmsDocAuditVo.getReedit().equals(0)) {
//删除待审核文章
cmsDocMapper.deleteCmsDocById(cmsDoc.getId());
// 删除分支如果有
if (StringUtils.isNotEmpty(cmsDoc.getAuditTmpBranchName())) {
gitLinkRequestHelper.doPost(CmsGitLinkRequestUrl.DELETE_BRANCH(cmsProject, cmsDoc.getAuditTmpBranchName()), null);
}
//删除分支
gitLinkRequestHelper.doDelete(CmsGitLinkRequestUrl.DELETE_BRANCH(cmsProject, cmsDoc.getAuditTmpBranchName()));
return;
}
}
@ -579,7 +472,7 @@ public class CmsDocServiceImpl implements ICmsDocService {
int success = deleteCmsDocDatabaseById(ids);
if (success == ids.length) {
//删除临时分支
gitLinkRequestHelper.doPost(CmsGitLinkRequestUrl.DELETE_BRANCH(cmsProject, cmsDoc.getAuditTmpBranchName()), null);
gitLinkRequestHelper.doDelete(CmsGitLinkRequestUrl.DELETE_BRANCH(cmsProject, cmsDoc.getAuditTmpBranchName()));
}
}
@ -599,7 +492,7 @@ public class CmsDocServiceImpl implements ICmsDocService {
int success = cmsDocMapper.deleteCmsDocById(newDocId);
if (success > 0) {
//删除临时分支
gitLinkRequestHelper.doPost(CmsGitLinkRequestUrl.DELETE_BRANCH(cmsProject, cmsDoc.getAuditTmpBranchName()), null);
gitLinkRequestHelper.doDelete(CmsGitLinkRequestUrl.DELETE_BRANCH(cmsProject, cmsDoc.getAuditTmpBranchName()));
}
}
@ -613,13 +506,11 @@ public class CmsDocServiceImpl implements ICmsDocService {
int success = cmsDocMapper.updateCmsDoc(cmsDoc);
if (success > 0) {
//删除临时分支
gitLinkRequestHelper.doPost(CmsGitLinkRequestUrl.DELETE_BRANCH(cmsProject, cmsDoc.getAuditTmpBranchName()), null);
gitLinkRequestHelper.doDelete(CmsGitLinkRequestUrl.DELETE_BRANCH(cmsProject, cmsDoc.getAuditTmpBranchName()));
}
// 推送文章地址到搜索引擎
cmsAsyncService.pushDocDataSearchEngine(cmsDoc);
// 文章审核通过后给作者增加积分异步执行不影响主事务
cmsAsyncService.addPublishDocPointsAsync(cmsDoc.getDeptId(), cmsDoc.getCreateBy(), cmsDoc.getId(), cmsDoc.getName());
}
private JSONObject mergePullRequestByGitLink(CmsProject cmsProject, CmsDoc cmsDoc) {
@ -634,6 +525,12 @@ public class CmsDocServiceImpl implements ICmsDocService {
CmsGitLinkRequestUrl.MERGE_PULL_REQUEST(cmsProject, gitLinkPullRequestId), requestBody);
}
private JSONObject refuseMergePullRequestByGitLink(CmsDoc cmsDoc, CmsProject cmsProject) {
//1.调用gitlink拒绝合并请求接口
return gitLinkRequestHelper.doPost(
CmsGitLinkRequestUrl.REFUSE_MERGE_PULL_REQUEST(cmsProject, cmsDoc.getAuditPrNumber()), null);
}
public static String sha1(String data) {
try {
MessageDigest md = MessageDigest.getInstance("SHA1");
@ -655,7 +552,6 @@ public class CmsDocServiceImpl implements ICmsDocService {
throw new ServiceException("计算字符串Sha出错");
}
}
@Override
public void setCmsSort(Integer order, CmsDoc oldCmsDoc, boolean isChangeOnDir, String isHomePage) {
//调整文章/栏目顺序
@ -775,69 +671,14 @@ public class CmsDocServiceImpl implements ICmsDocService {
* @return 结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Long updateCmsDoc(Long id, CmsDocDto cmsDocDto) {
public boolean updateCmsDoc(Long id, CmsDocDto cmsDocDto) {
CmsDoc oldCmsDoc = cmsDocMapper.selectCmsDocById(id);
checkCmsLockStatus(oldCmsDoc.getDeptId());
if (!hasRepoRelatedChanged(oldCmsDoc, cmsDocDto)) {
// 更新非仓库字段到原文章对象
if (StringUtils.isNotEmpty(cmsDocDto.getHeadImg())) {
oldCmsDoc.setHeadImg(cmsDocDto.getHeadImg());
}
if (StringUtils.isNotEmpty(cmsDocDto.getSummary())) {
oldCmsDoc.setSummary(cmsDocDto.getSummary());
}
if (StringUtils.isNotEmpty(cmsDocDto.getKeywords())) {
oldCmsDoc.setKeywords(cmsDocDto.getKeywords());
}
// 管理员或免审核直接更新原记录
if (tokenService.hasDeptPerms(oldCmsDoc.getDeptId(), UserConstants.CMS_PERMS_DOCS_AUDIT)
|| isNoAuditRequired(oldCmsDoc.getDeptId())) {
cmsDocMapper.updateCmsDoc(oldCmsDoc);
return oldCmsDoc.getId();
}
// 需要审核创建新的待审核记录与仓库改动逻辑一致
if (oldCmsDoc.getAuditStatus().equals(DocAuditStatus.AUDIT_PASS.getAuditCode())) {
CmsDoc newDocWithAudit = insertDocWithAudit(oldCmsDoc,
DocAndZoneOperation.OPERATION_NON_REPO_UPDATE.getOperationCode() + "-" + oldCmsDoc.getId(),
DocAuditStatus.TO_BE_AUDIT.getAuditCode());
return newDocWithAudit.getId();
}
oldCmsDoc.setAuditStatus(DocAuditStatus.TO_BE_AUDIT.getAuditCode());
if (oldCmsDoc.getAuditType().contains(DocAndZoneOperation.OPERATION_CREATE.getOperationCode())
|| oldCmsDoc.getAuditType().contains(DocAndZoneOperation.OPERATION_UPDATE.getOperationCode())) {
CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(oldCmsDoc.getDeptId());
// 重新开启PR
String gitLinkPullRequestNumber = oldCmsDoc.getAuditPrNumber().split("-")[0];
gitLinkRequestHelper.doPost(CmsGitLinkRequestUrl.REOPEN_PULL_REQUEST(cmsProject, gitLinkPullRequestNumber), null);
}
// 待审核/未通过文章重新编辑
cmsDocMapper.updateCmsDoc(oldCmsDoc);
return oldCmsDoc.getId();
}
// 当文章名称发生更改时判断文章名是否在当前栏目下已存在
if (StringUtils.isNotEmpty(cmsDocDto.getName()) && !cmsDocDto.getName().equals(oldCmsDoc.getName())) {
String dirName = oldCmsDoc.getDirName();
if (cmsDocDto.getDirId() != null) {
CmsDir cmsDir = selectCmsDirById(cmsDocDto.getDirId(), false);
if (!cmsDir.getName().equals(dirName)) {
dirName = cmsDir.getName();
}
}
checkDocName(cmsDocDto.getName(), oldCmsDoc.getDeptId(), dirName);
}
// 当用户更新栏目时需检查新栏目下是否已存在相同文章名
if (cmsDocDto.getDirId() != null) {
CmsDir cmsDir = selectCmsDirById(cmsDocDto.getDirId(), false);
if (cmsDir != null && !cmsDir.getName().equals(oldCmsDoc.getDirName())) {
checkDocName(cmsDocDto.getName(), oldCmsDoc.getDeptId(), cmsDir.getName());
}
return cmsDocMapper.updateCmsDoc(oldCmsDoc) > 0;
}
//用户为专区管理员或专区无审核机制时直接更新文章及仓库主分支
if (tokenService.hasDeptPerms(oldCmsDoc.getDeptId(), UserConstants.CMS_PERMS_DOCS_AUDIT) || isNoAuditRequired(oldCmsDoc.getDeptId())) {
if (isCurrentUserZoneAdmin(oldCmsDoc.getDeptId()) || isNoAuditRequired(oldCmsDoc.getDeptId())) {
//专区管理员重新编辑并提交审核未通过文章 重新编辑并提交待审核文章时专区不需审核机制
if (!oldCmsDoc.getAuditStatus().equals(DocAuditStatus.AUDIT_PASS.getAuditCode())) {
//文章审核类型update-原文章id 取出原文章id直接更新删除待审核更新类型文章
@ -845,78 +686,39 @@ public class CmsDocServiceImpl implements ICmsDocService {
Long originCmsDocId = Long.parseLong(oldCmsDoc.getAuditType().split("-")[1]);
CmsDoc originCmsDoc = cmsDocMapper.selectCmsDocById(originCmsDocId);
deleteTmpBranchIfBranchExist(oldCmsDoc);
BeanUtils.copyProperties(originCmsDoc, oldCmsDoc);
BeanUtils.copyProperties(originCmsDoc,oldCmsDoc);
cmsDocMapper.deleteCmsDocById(id);
} else
//文章审核类型create 直接新增文章
if (oldCmsDoc.getAuditType() != null && oldCmsDoc.getAuditType().contains(DocAndZoneOperation.OPERATION_CREATE.getOperationCode())) {
deleteTmpBranchIfBranchExist(oldCmsDoc);
cmsDocMapper.deleteCmsDocById(id);
directlyInsertAuditedCmsDocWhenZoneHasNoAuditRequired(cmsDocDto, oldCmsDoc);
return oldCmsDoc.getId();
return directlyInsertAuditedCmsDocWhenZoneHasNoAuditRequired(cmsDocDto, oldCmsDoc);
}
}
String branchName = CmsConstants.BRANCH_MASTER;
oldCmsDoc = cmsAsyncService.updateCmsDocDatabaseAndUpdateForGitLink(oldCmsDoc, cmsDocDto, branchName);
oldCmsDoc.setAuditStatus(DocAuditStatus.AUDIT_PASS.getAuditCode());
oldCmsDoc.setAuditTmpBranchName(null);
oldCmsDoc.setKeywords(cmsDocDto.getKeywords());
updateCmsCommonDatabase(oldCmsDoc, CmsConstants.BRANCH_MASTER);
return oldCmsDoc.getId();
return updateCmsCommonDatabase(oldCmsDoc, CmsConstants.BRANCH_MASTER) > 0;
} else {
CmsDoc newDocWithAudit = new CmsDoc();
//待审核未通过文章重新编辑并提交
if (DocAuditStatus.AUDIT_FAIL.getAuditCode().equals(oldCmsDoc.getAuditStatus())
|| DocAuditStatus.TO_BE_AUDIT.getAuditCode().equals(oldCmsDoc.getAuditStatus())) {
// 非仓库改动待审核记录检查是否有仓库改动
if (oldCmsDoc.getAuditType() != null
&& oldCmsDoc.getAuditType().contains(DocAndZoneOperation.OPERATION_NON_REPO_UPDATE.getOperationCode())) {
if (!hasRepoRelatedChanged(oldCmsDoc, cmsDocDto)) {
// 纯非仓库改动继续在当前记录上更新
oldCmsDoc.setAuditStatus(DocAuditStatus.TO_BE_AUDIT.getAuditCode());
if (StringUtils.isNotEmpty(cmsDocDto.getHeadImg())) {
oldCmsDoc.setHeadImg(cmsDocDto.getHeadImg());
}
if (StringUtils.isNotEmpty(cmsDocDto.getSummary())) {
oldCmsDoc.setSummary(cmsDocDto.getSummary());
}
if (StringUtils.isNotEmpty(cmsDocDto.getKeywords())) {
oldCmsDoc.setKeywords(cmsDocDto.getKeywords());
}
cmsDocMapper.updateCmsDoc(oldCmsDoc);
return oldCmsDoc.getId();
} else {
// 有仓库改动转为仓库改动类型删除当前记录重新创建
Long oldCmsDocId = Long.parseLong(oldCmsDoc.getAuditType().split("-")[1]);
CmsDoc originCmsDoc = cmsDocMapper.selectCmsDocById(oldCmsDocId);
cmsDocMapper.deleteCmsDocById(oldCmsDoc.getId());
// 按照仓库改动逻辑重新创建
newDocWithAudit = insertDocWithAudit(originCmsDoc,
DocAndZoneOperation.OPERATION_UPDATE.getOperationCode() + "-" + oldCmsDocId,
DocAuditStatus.TO_BE_AUDIT.getAuditCode());
cmsAsyncService.asyncUpdateBranchAndFileAndCreatePR(newDocWithAudit, cmsDocDto);
return newDocWithAudit.getId();
}
}
// 仓库改动待审核记录继续在当前记录上更新
oldCmsDoc.setAuditStatus(DocAuditStatus.TO_BE_AUDIT.getAuditCode());
newDocWithAudit = oldCmsDoc;
} else {
} else
//更新已发布文章
if (oldCmsDoc.getAuditStatus().equals(DocAuditStatus.AUDIT_PASS.getAuditCode())) {
//1.创建一条auditType="update-原文章id"audit_status为2其余字段与待更新文章一致的新文章数据
newDocWithAudit = insertDocWithAudit(oldCmsDoc,
DocAndZoneOperation.OPERATION_UPDATE.getOperationCode() + "-" + id,
DocAuditStatus.TO_BE_AUDIT.getAuditCode());
}
//1.创建一条auditType="update-原文章id"audit_status为2其余字段与待更新文章一致的新文章数据
newDocWithAudit = insertDocWithAudit(oldCmsDoc,
DocAndZoneOperation.OPERATION_UPDATE.getOperationCode() + "-" + id,
DocAuditStatus.TO_BE_AUDIT.getAuditCode());
}
cmsAsyncService.asyncUpdateBranchAndFileAndCreatePR(newDocWithAudit, cmsDocDto);
return newDocWithAudit.getId();
return true;
}
}
@ -959,7 +761,6 @@ public class CmsDocServiceImpl implements ICmsDocService {
}
}
oldCmsDoc.setKeywords(cmsDocDto.getKeywords());
oldCmsDoc.setSummary(cmsDocDto.getSummary());
oldCmsDoc.setHeadImg(cmsDocDto.getHeadImg());
return isChangeName || isChangeContent || isChangeDir;
@ -968,10 +769,10 @@ public class CmsDocServiceImpl implements ICmsDocService {
private void deleteTmpBranchIfBranchExist(CmsDoc cmsDoc) {
CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(cmsDoc.getDeptId());
try {
gitLinkRequestHelper.doPost(CmsGitLinkRequestUrl.DELETE_BRANCH(cmsProject, cmsDoc.getAuditTmpBranchName()), null);
gitLinkRequestHelper.doDelete(CmsGitLinkRequestUrl.DELETE_BRANCH(cmsProject, cmsDoc.getAuditTmpBranchName()));
} catch (ServiceException e) {
//忽略分支不存在异常
if (!"分支不存在!".equals(e.getMessage())) {
if(!"分支不存在!".equals(e.getMessage())) {
throw new ServiceException(e.getMessage());
}
}
@ -999,29 +800,15 @@ public class CmsDocServiceImpl implements ICmsDocService {
}
private CmsDoc insertDocWithAudit(CmsDoc oldCmsDoc, String auditType, String auditStatus) {
List<CmsDoc> tmpDocList = getTmpDocList(oldCmsDoc);
if (!tmpDocList.isEmpty()) {
throw new ServiceException("已存在待审核操作,请等待审核完成后再进行操作");
}
oldCmsDoc.setId(null);
oldCmsDoc.setAuditType(auditType);
oldCmsDoc.setAuditStatus(auditStatus);
oldCmsDoc.setCreateBy(SecurityUtils.getUsername());
// repo 改动显式设置 auditTmpBranchName null没有对应的分支
if (auditType != null && auditType.contains(DocAndZoneOperation.OPERATION_NON_REPO_UPDATE.getOperationCode())) {
oldCmsDoc.setAuditTmpBranchName(null);
}
cmsDocMapper.insertCmsDoc(oldCmsDoc);
return oldCmsDoc;
}
private CmsDoc insertDeletedDocWithAudit(CmsDoc oldCmsDoc, Long oldCmsDocId) {
List<CmsDoc> tmpDocList = getTmpDocList(oldCmsDoc);
if (!tmpDocList.isEmpty()) {
throw new ServiceException("已存在待审核操作,请等待审核完成后再进行操作");
}
oldCmsDoc.setId(null);
oldCmsDoc.setAuditType(DocAndZoneOperation.OPERATION_DELETE.getOperationCode() + "-" + oldCmsDocId);
oldCmsDoc.setAuditStatus(DocAuditStatus.TO_BE_AUDIT.getAuditCode());
@ -1063,7 +850,6 @@ public class CmsDocServiceImpl implements ICmsDocService {
cmsDoc.setIsDir(true);
cmsDoc.setFilePath(cmsDoc.getDirPath(cmsDir.getName()));
cmsDoc.setDeptId(deptId);
cmsDoc.setHeadImg(cmsDir.getHeadImg());
cmsDoc.setName(cmsDir.getName());
return insertCommonCmsDoc(cmsDoc, "创建栏目:" + cmsDir.getName(), "");
}
@ -1150,7 +936,7 @@ public class CmsDocServiceImpl implements ICmsDocService {
List<CmsDoc> cmsDocList = cmsDocMapper.selectHotCmsDocList(cmsDocInput);
if (cmsDocList != null) {
//todo:需检查该文章是否在GitLink中存在
return cmsDocList.stream().map(CmsDoc::copyToHotCmsDocDto).collect(Collectors.toList());
return cmsDocList.stream().map(x -> x.copyToHotCmsDocDto()).collect(Collectors.toList());
}
return new ArrayList<>();
@ -1167,13 +953,7 @@ public class CmsDocServiceImpl implements ICmsDocService {
visits = visits + cmsDoc.getVisits();
}
cmsDoc.setVisits(visits);
int rows = cmsDocMapper.updateCmsDoc(cmsDoc);
if (rows > 0) {
cmsAsyncService.addVisitsDocPointsAsync(cmsDoc.getDeptId(), cmsDoc.getCreateBy(),
cmsDoc.getId(), cmsDoc.getName(), cmsDoc.getVisits());
return true;
}
return false;
return cmsDocMapper.updateCmsDoc(cmsDoc) > 0;
}
@Override
@ -1197,7 +977,7 @@ public class CmsDocServiceImpl implements ICmsDocService {
for (CmsDoc cmsDir : cmsDirList) {
CmsDocSearchVo cmsDocSearchVo = new CmsDocSearchVo();
cmsDocSearchVo.setIsOpen(isOpen);
List<CmsDocBaseDto> cmsDocBaseDtoList = selectSetDefaultHeadImgCmsDocList(cmsDir.getId(), cmsDocSearchVo);
List<CmsDocBaseDto> cmsDocBaseDtoList = selectCmsDocList(cmsDir.getId(), cmsDocSearchVo);
CmsDocOverviewDto cmsDocOverviewDto = new CmsDocOverviewDto();
cmsDocOverviewDto.setId(cmsDir.getId());
cmsDocOverviewDto.setName(cmsDir.getName());
@ -1297,9 +1077,6 @@ public class CmsDocServiceImpl implements ICmsDocService {
//首页推荐时需将顺序设置为1
setCmsSort(1, cmsDoc, false, null);
cmsDoc.setIsHomepage(CmsConstants.TRUE);
// 文章被设为精选异步增加作者积分
cmsAsyncService.addFeaturedDocPointsAsync(cmsDoc.getDeptId(), cmsDoc.getCreateBy(),
cmsDoc.getId(), cmsDoc.getName());
}
return cmsDocMapper.updateCmsDoc(cmsDoc);
}
@ -1314,7 +1091,7 @@ public class CmsDocServiceImpl implements ICmsDocService {
CmsDocSearchVo cmsDocSearch = new CmsDocSearchVo();
cmsDocSearch.setDeptId(deptId);
cmsDocSearch.setIsHomepage(CmsConstants.TRUE);
List<CmsDoc> cmsDocList = cmsDocMapper.selectCmsDocListSetDefaultHeadImg(cmsDocSearch);
List<CmsDoc> cmsDocList = cmsDocMapper.selectCmsDocList(cmsDocSearch);
List<CmsDocBaseDto> cmsDocBaseDtoList = new ArrayList<>();
for (CmsDoc cmsDoc : cmsDocList) {
CmsDocBaseDto cmsDocBaseDto = cmsDoc.copyToCmsDocBaseDto();
@ -1323,41 +1100,6 @@ public class CmsDocServiceImpl implements ICmsDocService {
return cmsDocBaseDtoList;
}
@Override
public List<CmsDocBaseDto> selectHomePageDocMergeList(Long zoneId, List<Long> topDocIds) {
Long deptId = getDeptIdByZoneId(zoneId);
Set<Long> addedDocIds = new HashSet<>();
// 1. 获取首页推荐文章列表
List<CmsDocBaseDto> homePageDocs = selectHomePageDocList(deptId);
List<CmsDocBaseDto> result = new ArrayList<>();
// 2. 批量查询置顶文章完整数据按传入顺序放入结果头部
if (topDocIds != null && !topDocIds.isEmpty()) {
List<CmsDoc> topCmsDocs = cmsDocMapper.selectCmsDocByIds(topDocIds);
Map<Long, CmsDoc> topDocMap = new HashMap<>();
for (CmsDoc doc : topCmsDocs) {
topDocMap.put(doc.getId(), doc);
}
for (Long docId : topDocIds) {
CmsDoc doc = topDocMap.get(docId);
if (doc != null) {
result.add(doc.copyToCmsDocBaseDto());
addedDocIds.add(docId);
}
}
}
// 3. 追加首页推荐文章跳过已在置顶列表中的
for (CmsDocBaseDto doc : homePageDocs) {
if (!addedDocIds.contains(doc.getId())) {
result.add(doc);
}
}
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public CmsDir initCmsDir(Long deptId, CmsDir cmsDirInput) {
@ -1391,7 +1133,16 @@ public class CmsDocServiceImpl implements ICmsDocService {
}
private boolean insertCommonCmsDoc(CmsDoc cmsDoc, String message, String content) {
checkDocName(cmsDoc.getName(), cmsDoc.getDeptId(), cmsDoc.getDirName());
//检查该文件是否已存在
CmsDoc oldCmsDoc = cmsDocMapper.selectCmsDocByNameAndDeptId(cmsDoc.getName(), cmsDoc.getDeptId(), cmsDoc.getDirName());
if (oldCmsDoc != null) {
if (oldCmsDoc.getIsDir()) {
throw new ServiceException("该栏目已存在(栏目名称[" + cmsDoc.getName() + "])");
} else {
throw new ServiceException("该文章已存在(文章名称[" + cmsDoc.getName() + "])");
}
}
createFileByGitLink(cmsDoc, message, content);
boolean success = insertCmsDocDatabase(cmsDoc, content);
// 推送文章地址到搜索引擎
@ -1399,19 +1150,6 @@ public class CmsDocServiceImpl implements ICmsDocService {
return success;
}
private void checkDocName(String docName, Long deptId, String dirName) {
//检查该文件是否已存在
CmsDoc oldCmsDoc = cmsDocMapper.selectCmsDocByNameAndDeptId(docName, deptId, dirName);
if (oldCmsDoc != null) {
if (oldCmsDoc.getIsDir()) {
throw new ServiceException("该栏目已存在(栏目名称[%s])", docName);
} else {
throw new ServiceException("该文章在当前栏目下已存在(文章名称[%s],栏目名称[%s])", docName, dirName);
}
}
}
private boolean insertCmsDocWithAudit(CmsDoc cmsDoc, String message, String content) {
//检查该文件是否已存在
CmsDoc oldCmsDoc = cmsDocMapper.selectCmsDocByNameAndDeptId(cmsDoc.getName(), cmsDoc.getDeptId(), cmsDoc.getDirName());
@ -1456,11 +1194,6 @@ public class CmsDocServiceImpl implements ICmsDocService {
return cmsDoc.copyToCmsDocBaseDto();
}
@Override
public Long getCmsDocVisitsByDeptId(Long deptId) {
return cmsDocMapper.getCmsDocVisitsByDeptId(deptId);
}
@Override
public boolean insertCmsDocDatabase(CmsDoc cmsDoc, String content) {
//设置排序值为当前最大的排序值+1
@ -1504,17 +1237,6 @@ public class CmsDocServiceImpl implements ICmsDocService {
cmsAsyncService.updateCmsPublishDataByGitLink(cmsProject, cmsDoc, branchName);
}
private int deleteCmsDir(CmsProject cmsProject, CmsDoc cmsDir) {
if (!isNoAuditRequired(cmsDir.getDeptId()) || tokenService.hasDeptPerms(cmsDir.getDeptId(), UserConstants.CMS_PERMS_DOCS_AUDIT)) {
boolean deleteResult = cmsAsyncService.deleteCmsDocForGitLink(cmsDir, cmsProject, CmsConstants.BRANCH_MASTER);
if (deleteResult) {
return cmsDocMapper.deleteCmsDocById(cmsDir.getId());
}
throw new ServiceException("栏目删除失败");
}
throw new ServiceException("无权限删除栏目");
}
@Override
public int deleteCmsDocById(Long id) {
CmsDoc cmsDoc = cmsDocMapper.selectCmsDocById(id);
@ -1524,42 +1246,22 @@ public class CmsDocServiceImpl implements ICmsDocService {
checkCmsLockStatus(cmsDoc.getDeptId());
//2获取专区项目
CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(cmsDoc.getDeptId());
if (cmsDoc.getIsDir()) {
return deleteCmsDir(cmsProject, cmsDoc);
}
//删除待审核审核未通过文章删除临时分支拒绝合并请求
if (DocAuditStatus.TO_BE_AUDIT.getAuditCode().equals(cmsDoc.getAuditStatus())) {
// 非仓库改动类型直接删除
if (cmsDoc.getAuditType().contains(DocAndZoneOperation.OPERATION_NON_REPO_UPDATE.getOperationCode())) {
return cmsDocMapper.deleteCmsDocById(cmsDoc.getId());
}
//拒绝GitLink合并请求
String gitLinkPullRequestNumber = cmsDoc.getAuditPrNumber().split("-")[0];
gitLinkRequestHelper.doPost(
CmsGitLinkRequestUrl.REFUSE_MERGE_PULL_REQUEST(cmsProject, gitLinkPullRequestNumber), null);
gitLinkRequestHelper.doPost(CmsGitLinkRequestUrl.DELETE_BRANCH(cmsProject, cmsDoc.getAuditTmpBranchName()), null);
return cmsDocMapper.deleteCmsDocById(cmsDoc.getId());
if (DocAuditStatus.TO_BE_AUDIT.getAuditCode().equals(cmsDoc.getAuditStatus())
|| DocAuditStatus.AUDIT_FAIL.getAuditCode().equals(cmsDoc.getAuditStatus())) {
gitLinkRequestHelper.doDelete(CmsGitLinkRequestUrl.DELETE_BRANCH(cmsProject, cmsDoc.getAuditTmpBranchName()));
cmsDocMapper.deleteCmsDocById(id);
return 1;
}
if (DocAuditStatus.AUDIT_FAIL.getAuditCode().equals(cmsDoc.getAuditStatus())) {
return cmsDocMapper.deleteCmsDocById(cmsDoc.getId());
}
// 判读当前用户是否拥有文章直接删除权限
if (tokenService.hasDeptPerms(cmsDoc.getDeptId(), UserConstants.CMS_PERMS_DOCS_AUDIT) //当前用户为专区管理员
if (isCurrentUserZoneAdmin(cmsDoc.getDeptId()) //当前用户为专区管理员
|| isNoAuditRequired(cmsDoc.getDeptId()) //当前专区文章发布无需审核机制
) {
String branchName = CmsConstants.BRANCH_MASTER;
boolean deleteResult = cmsAsyncService.deleteCmsDocForGitLink(cmsDoc, cmsProject, branchName);
if (deleteResult) {
// 拒绝相关合并请求并清理所有临时分支同时删除所有临时申请
List<CmsDoc> tmpDocList = getTmpDocList(cmsDoc);
cmsAsyncService.clearTmpDoc(cmsProject, tmpDocList);
cmsDoc.setAuditStatus(DocAuditStatus.AUDIT_FAIL.getAuditCode());
cmsDoc.setRemark("管理员删除");
return cmsDocMapper.updateCmsDoc(cmsDoc);
return deleteCmsDocDatabaseById(cmsDoc.getId());
}
} else {
//1.创建一条auditType="delete-原文章id",audit_status=2其余字段与待删除文章一致的新文章数据
CmsDoc newDocWithAudit = insertDeletedDocWithAudit(cmsDoc, id);
@ -1569,18 +1271,6 @@ public class CmsDocServiceImpl implements ICmsDocService {
throw new ServiceException("文件删除失败");
}
@Override
public List<CmsDoc> getTmpDocList(CmsDoc cmsDoc) {
CmsDocSearchVo cmsDocSearchVo = new CmsDocSearchVo();
cmsDocSearchVo.setName(cmsDoc.getName());
cmsDocSearchVo.setDeptId(cmsDoc.getDeptId());
cmsDocSearchVo.setIsDir(false);
cmsDocSearchVo.setDirName(cmsDoc.getDirName());
cmsDocSearchVo.setAuditStatus(DocAuditStatus.TO_BE_AUDIT.getAuditCode());
// 拒绝相关合并请求并清理所有临时分支同时删除所有临时申请
return cmsDocMapper.selectCmsDocList(cmsDocSearchVo);
}
public int deleteCmsDocDatabaseById(Long id) {
CmsDoc cmsDoc = cmsDocMapper.selectCmsDocById(id);
if (cmsDoc != null && !cmsDoc.getIsDir()) {

View File

@ -5,7 +5,6 @@ import com.microservices.cms.doc.domain.WechatSignatureInput;
import com.microservices.cms.doc.domain.WechatSignatureVo;
import com.microservices.cms.doc.service.ICmsWechatService;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.httpClient.service.HttpAPIService;
import com.microservices.common.redis.service.RedisService;
import org.slf4j.Logger;
@ -34,16 +33,13 @@ public class CmsWechatServiceImpl implements ICmsWechatService {
@Autowired
private RedisService redisService;
@Value("${cms.wechat.appID:}")
@Value("${cms.wechat.appID}")
public String appID;
@Value("${cms.wechat.appSecret:}")
@Value("${cms.wechat.appSecret}")
public String appSecret;
@Override
public WechatSignatureVo getWechatSignature(WechatSignatureInput wechatSignatureInput) {
if (StringUtils.isEmpty(appID) || StringUtils.isEmpty(appSecret)) {
throw new ServiceException("请配置微信参数");
}
// 待签名的参数
Map<String, String> params = new HashMap<>();
String nonceStr = generateSecureRandomString(16);

View File

@ -41,24 +41,11 @@ public class CmsProjectController extends BaseController {
@ApiOperation(value = "修改用户所在GItLink项目中的权限", hidden = true)
public R<Boolean> changeUserRole(@PathVariable("userId") Long userId,
@RequestParam(value = "oldDeptId", required = false) Long oldDeptId,
@RequestParam(value = "newDeptId", required = false) Long newDeptId,
@RequestParam(value = "oldRoleId", required = false) Long oldRoleId,
@RequestParam(value = "newRoleId", required = false) Long newRoleId
) {
Boolean changeRoleResult = cmsProjectService.changeUserRole(userId, oldDeptId, newDeptId, oldRoleId, newRoleId);
@RequestParam(value = "newDeptId", required = false) Long newDeptId) {
Boolean changeRoleResult = cmsProjectService.changeUserRole(userId, oldDeptId, newDeptId);
return R.ok(changeRoleResult);
}
@InnerAuth
@PutMapping("/changeOrgRole/user/{userId}/operate/{operate}")
@ApiOperation(value = "修改用户所在GItLink组织中的权限", hidden = true)
public R<Boolean> changeUserOrgRole(@PathVariable("userId") Long userId, @PathVariable("operate") Long operate
) {
Boolean changeRoleResult = cmsProjectService.changeUserOrgRole(userId, operate);
return R.ok(changeRoleResult);
}
/**
* 查询专区对应项目列表
*/
@ -105,12 +92,8 @@ public class CmsProjectController extends BaseController {
@GetMapping("/getProjectByDeptId/{deptId}")
public R<String> getProjectByDeptId(
@ApiParam(name = "deptId", value = "组织Id") @PathVariable(value = "deptId") Long deptId) {
CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptIdAndNoException(deptId);
if (cmsProject == null) {
return R.ok(null);
} else {
return R.ok(JSONObject.toJSONString(cmsProject));
}
CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(deptId);
return R.ok(JSONObject.toJSONString(cmsProject));
}
/**
@ -184,16 +167,4 @@ public class CmsProjectController extends BaseController {
public R<Boolean> removeByDeptId(@PathVariable(value = "deptId") Long deptId) {
return R.ok(cmsProjectService.deleteCmsProjectByDeptId(deptId) > 0);
}
/**
* 初始化专区对应项目
*/
@RequiresPermissions("zone:project:add")
@ApiOperation("初始化专区对应项目")
@Log(title = "初始化专区对应项目", businessType = BusinessType.INSERT)
@PostMapping("initCmsProject/dept/{deptId}")
public AjaxResult initCmsProject(
@ApiParam(name = "deptId", value = "组织Id") @PathVariable(value = "deptId") Long deptId) {
return toAjax(cmsProjectService.initZoneCmsProjectByDept(deptId));
}
}

View File

@ -1,21 +0,0 @@
package com.microservices.cms.project.domain;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @author otto
*/
@Data
public class GitlinkOrganizationTeamVo implements Serializable {
@ApiModelProperty(value = "团队权限")
private String authorize;
@ApiModelProperty(value = "团队Id")
private Long id;
@ApiModelProperty(value = "团队名称")
private String name;
@ApiModelProperty(value = "团队昵称")
private String nickname;
}

View File

@ -1,8 +1,6 @@
package com.microservices.cms.project.mapper;
import com.microservices.cms.project.domain.CmsProject;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -12,7 +10,6 @@ import java.util.List;
* @author otto
* @date 2023-03-27
*/
@Mapper
public interface CmsProjectMapper {
/**
* 查询专区对应项目
@ -65,25 +62,4 @@ public interface CmsProjectMapper {
CmsProject selectCmsProjectByDeptId(Long deptId);
CmsProject selectCmsProjectByIdentifier(String identifier);
/**
* 全局搜索 - 全文索引查询
*
* @param keyword 搜索关键词
* @param deptId 组织ID可选
* @param offset 偏移量
* @param pageSize 每页数量
* @return 搜索结果列表
*/
List<CmsProject> globalSearch(@Param("keyword") String keyword, @Param("deptId") Long deptId,
@Param("offset") int offset, @Param("pageSize") int pageSize);
/**
* 全局搜索结果计数
*
* @param keyword 搜索关键词
* @param deptId 组织ID可选
* @return 结果数量
*/
Long globalSearchCount(@Param("keyword") String keyword, @Param("deptId") Long deptId);
}

View File

@ -71,17 +71,11 @@ public interface ICmsProjectService {
CmsProject selectCmsProjectByDeptId(Long deptId);
Boolean changeUserRole(Long userId, Long oldDeptId, Long newDeptId, Long oldRoleId, Long newRoleId);
Boolean changeUserRole(Long userId, Long oldDeptId, Long newDeptId);
JSONObject getDeptProjectList();
Boolean updateCmsProjectByDept(SysDept dept);
boolean operateProtectedBranchByZoneAuditSetting(String userName, String identifier, Long deptId, String operationType);
boolean initZoneCmsProjectByDept(Long deptId);
CmsProject selectCmsProjectByDeptIdAndNoException(Long deptId);
Boolean changeUserOrgRole(Long userId, Long operate);
}

View File

@ -1,32 +1,28 @@
package com.microservices.cms.project.service.impl;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.cms.doc.domain.*;
import com.microservices.cms.doc.domain.CmsDir;
import com.microservices.cms.doc.domain.CmsDocBaseDto;
import com.microservices.cms.doc.domain.CmsDocSearchVo;
import com.microservices.cms.doc.service.ICmsAsyncService;
import com.microservices.cms.doc.service.ICmsDocService;
import com.microservices.cms.project.domain.CmsProject;
import com.microservices.cms.project.domain.GitlinkOrganizationTeamVo;
import com.microservices.cms.project.mapper.CmsProjectMapper;
import com.microservices.cms.project.service.ICmsProjectService;
import com.microservices.cms.utils.CmsConstants;
import com.microservices.cms.utils.CmsGitLinkRequestUrl;
import com.microservices.common.core.constant.HttpStatus;
import com.microservices.common.core.constant.SecurityConstants;
import com.microservices.common.core.enums.SystemRole;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.PinYinStringUtils;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.datascope.annotation.DataScope;
import com.microservices.common.httpClient.domain.GitLinkRequestUrl;
import com.microservices.common.httpClient.util.GitLinkRequestHelper;
import com.microservices.system.api.RemoteDeptService;
import com.microservices.system.api.RemoteUserService;
import com.microservices.system.api.domain.SysDept;
import com.microservices.system.api.domain.SysRole;
import com.microservices.system.api.domain.SysUser;
import com.microservices.system.api.domain.SysUserDeptRole;
import com.microservices.system.api.utils.FeignUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
@ -41,7 +37,6 @@ import java.util.List;
* @author otto
* @date 2023-03-27
*/
@Slf4j
@Service
public class CmsProjectServiceImpl implements ICmsProjectService {
@Autowired
@ -183,12 +178,12 @@ public class CmsProjectServiceImpl implements ICmsProjectService {
throw new ServiceException("该组织不存在(组织id[" + deptId + "])");
}
Long organizationId = getOrganizationId();
String cmsProjectKey = "TSZQ_" + PinYinStringUtils.toCamelCasePinyin(sysDept.getDeptName());
CmsProject cmsProjectByKey = cmsProjectMapper.selectCmsProjectByIdentifier(cmsProjectKey);
int cmsProjectKeyExtra = 1;
while (cmsProjectByKey != null) {
cmsProjectKey += cmsProjectKeyExtra;
cmsProjectByKey = cmsProjectMapper.selectCmsProjectByIdentifier(cmsProjectKey);
String cmsProjectKey="TSZQ_"+PinYinStringUtils.toCamelCasePinyin(sysDept.getDeptName());
CmsProject cmsProjectByKey=cmsProjectMapper.selectCmsProjectByIdentifier(cmsProjectKey);
int cmsProjectKeyExtra=1;
while (cmsProjectByKey!=null){
cmsProjectKey+=cmsProjectKeyExtra;
cmsProjectByKey=cmsProjectMapper.selectCmsProjectByIdentifier(cmsProjectKey);
cmsProjectKeyExtra++;
}
JSONObject jsonObject = new JSONObject();
@ -219,7 +214,7 @@ public class CmsProjectServiceImpl implements ICmsProjectService {
@Override
public boolean operateProtectedBranchByZoneAuditSetting(String userName, String identifier, Long deptId, String operationType) {
switch (operationType) {
switch (operationType){
case "create":
cmsAsyncService.asyncCreateProtectedBranchSetting(userName, identifier, deptId);
break;
@ -233,74 +228,6 @@ public class CmsProjectServiceImpl implements ICmsProjectService {
return true;
}
@Override
public boolean initZoneCmsProjectByDept(Long deptId) {
boolean initResult = false;
CmsProject cmsProject = cmsProjectMapper.selectCmsProjectByDeptId(deptId);
if (cmsProject != null) {
JSONObject project = null;
try {
project = gitLinkRequestHelper.doGet(CmsGitLinkRequestUrl.GET_PROJECT_DETAIL(cmsProject.getUsername(), cmsProject.getIdentifier()));
} catch (ServiceException e) {
if (!e.getCode().equals(HttpStatus.NOT_FOUND)) {
throw new ServiceException(e.getCode(), e.getMessage());
}
}
if (project != null) {
throw new ServiceException("专区对应项目已存在,不能重复初始化");
} else {
Long organizationId = getOrganizationId();
// 创建专区对应项目
JSONObject jsonObject = new JSONObject();
jsonObject.put("user_id", organizationId);
jsonObject.put("name", cmsProject.getName());
jsonObject.put("repository_name", cmsProject.getIdentifier());
jsonObject.put("description", cmsProject.getDescription());
jsonObject.put("private", false);
//调用GitLink接口创建项目
JSONObject result = gitLinkRequestHelper.doPost(CmsGitLinkRequestUrl.CREATE_PROJECT(), jsonObject);
initResult = result != null && cmsProject.getIdentifier().equals(result.getString("identifier"));
}
} else {
Long projectId = insertZoneCmsProjectByDept(deptId);
if (projectId != null && projectId > 0) {
cmsProject = cmsProjectMapper.selectCmsProjectById(projectId);
initResult = true;
}
}
if (initResult) {
// 批量创建文章对应代码库文件
List<CmsDoc> cmsDocAndDirList = cmsDocService.selectCmsDocAndDirListByDept(deptId);
if (cmsDocAndDirList == null || cmsDocAndDirList.isEmpty()) {
return initResult;
}
JSONObject docCommitJson = new JSONObject();
docCommitJson.put("branch", CmsConstants.BRANCH_MASTER);
docCommitJson.put("message", "初始化专区文章对应代码库文件");
JSONArray docFiles = new JSONArray();
for (CmsDoc cmsDoc : cmsDocAndDirList) {
JSONObject docFile = new JSONObject();
docFile.put("action_type", "create");
docFile.put("content", "");
docFile.put("encoding", "text");
docFile.put("file_path", cmsDoc.getFilePath());
docFiles.add(docFile);
}
docCommitJson.put("files", docFiles);
JSONObject result = gitLinkRequestHelper.doPost(
CmsGitLinkRequestUrl.BATCH_COMMIT(cmsProject.getUsername(), cmsProject.getIdentifier())
, docCommitJson);
if (result == null) {
throw new ServiceException("专区对应项目初始化成功,但专区文章在项目中创建失败");
}
JSONArray resultContents = result.getJSONArray("contents");
for (int i = 0; i < resultContents.size(); i++) {
JSONObject contentJson = resultContents.getJSONObject(i);
cmsDocService.updateCmsDocShaByPathAndDeptId(contentJson.getString("sha"), contentJson.getString("path"), deptId);
}
}
return initResult;
}
private String handleSpecialCharacters(String name) {
@ -317,46 +244,7 @@ public class CmsProjectServiceImpl implements ICmsProjectService {
}
@Override
public CmsProject selectCmsProjectByDeptIdAndNoException(Long deptId) {
return cmsProjectMapper.selectCmsProjectByDeptId(deptId);
}
@Override
public Boolean changeUserOrgRole(Long userId, Long operate) {
Long gitlinkOrgId = getOrganizationId();
SysUser sysUser = FeignUtils.getReturnData(remoteUserService.getSysUserByUserId(userId, SecurityConstants.INNER));
if (sysUser == null) {
return false;
}
List<GitlinkOrganizationTeamVo> gitlinkOrganizationTeamVoList = gitLinkRequestHelper.getAllDataByPage(
CmsGitLinkRequestUrl.TEAMS_BY_ORGANIZATION_URL(gitlinkOrgId), "teams", GitlinkOrganizationTeamVo.class
);
GitlinkOrganizationTeamVo ownerTeam = gitlinkOrganizationTeamVoList.stream().filter(x -> "owner".equals(x.getAuthorize())).findFirst().orElse(null);
if (ownerTeam == null) {
return false;
}
if (operate == 1) {
JSONObject addUserToTeam = new JSONObject();
addUserToTeam.put("username", sysUser.getUserName());
gitLinkRequestHelper.doPost(
CmsGitLinkRequestUrl.ADD_USER_TO_ORGANIZATION_TEAM(gitLinkOrganization, ownerTeam.getId()), addUserToTeam);
}
if (operate == 3) {
try {
gitLinkRequestHelper.doDelete(CmsGitLinkRequestUrl.DELETE_USER_FROM_ORGANIZATION_TEAM(
gitLinkOrganization,
ownerTeam.getId(),
sysUser.getUserName()
));
} catch (Exception e) {
return false;
}
}
return false;
}
@Override
public Boolean changeUserRole(Long userId, Long oldDeptId, Long newDeptId, Long oldRoleId, Long newRoleId) {
public Boolean changeUserRole(Long userId, Long oldDeptId, Long newDeptId) {
SysUser sysUser = FeignUtils.getReturnData(remoteUserService.getSysUserByUserId(userId, SecurityConstants.INNER));
if (sysUser == null || sysUser.getGitlinkUserId() == null) {
return false;
@ -370,45 +258,32 @@ public class CmsProjectServiceImpl implements ICmsProjectService {
"(用户名[" + sysUser.getUserName() + "],原组织项目名[" + oldCmsProject.getName() + "]");
}
//将用户从原项目中移除
try {
gitLinkRequestHelper.doDelete(CmsGitLinkRequestUrl.REMOVE_USER_FROM_PROJECT(oldCmsProject), requestBody);
} catch (ServiceException e) {
log.error("将用户从原项目中移除发生异常:{}", e.getMessage());
// if (!e.getMessage().contains("用户为组织成员,请到组织下操作")||!e.getMessage().contains("还不是项目成员")) {
// throw new ServiceException(e.getMessage());
// }
}
gitLinkRequestHelper.doDelete(CmsGitLinkRequestUrl.REMOVE_USER_FROM_PROJECT(oldCmsProject), requestBody);
}
//将用户加入新的项目
CmsProject newCmsProject = cmsProjectMapper.selectCmsProjectByDeptId(newDeptId);
if (newCmsProject != null) {
try {
gitLinkRequestHelper.doPost(CmsGitLinkRequestUrl.ADD_USER_FROM_PROJECT(newCmsProject), requestBody);
} catch (ServiceException e) {
if (!e.getMessage().contains("已经是项目成员")) {
throw new ServiceException(e.getMessage());
}
}
gitLinkRequestHelper.doPost(CmsGitLinkRequestUrl.ADD_USER_FROM_PROJECT(newCmsProject), requestBody);
}
//判断是否为专区管理员角色-赋予项目管理员角色-不发起赋予
if (newRoleId != null) {
SysRole newRole = FeignUtils.getReturnData(
remoteUserService.getRoleInfoByInner(newRoleId, SecurityConstants.INNER)
);
if (newRole != null && SystemRole.ZONE_ADMIN.getRoleKey().equals(newRole.getRoleKey())) {
requestBody = new JSONObject();
requestBody.put("user_id", String.valueOf(sysUser.getGitlinkUserId()));
requestBody.put("role", "Manager");
try {
if (newCmsProject != null) {
gitLinkRequestHelper.doPut(CmsGitLinkRequestUrl.CHANGE_ROLE(newCmsProject), requestBody);
}
} catch (ServiceException e) {
if (!e.getMessage().contains("用户为组织成员,请到组织下操作")) {
throw new ServiceException(e.getMessage());
}
}
}
List<SysUserDeptRole> sysUserDeptRoleList = FeignUtils.getReturnData(remoteUserService.getSysUserDeptRoleListByUserName(sysUser.getUserName(), SecurityConstants.INNER));
boolean hasZoneAdminRole = false;
if (sysUserDeptRoleList != null && !sysUserDeptRoleList.isEmpty()) {
hasZoneAdminRole = sysUserDeptRoleList.stream().anyMatch(
sysUserDeptRole -> {
if (sysUserDeptRole.getDeptId() != null) {
return sysUserDeptRole.getDeptId().equals(newDeptId)
&& sysUserDeptRole.getSysRole().getRoleKey().equals(SystemRole.ZONE_ADMIN.getRoleKey());
}
return false;
});
}
if (hasZoneAdminRole) {
requestBody = new JSONObject();
requestBody.put("user_id", String.valueOf(sysUser.getGitlinkUserId()));
requestBody.put("role", "Manager");
gitLinkRequestHelper.doPut(CmsGitLinkRequestUrl.CHANGE_ROLE(newCmsProject), requestBody);
}
//更新分支保护推动白名单设置

View File

@ -1,43 +0,0 @@
package com.microservices.cms.search.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 文章搜索请求对象
*
* @author microservices
*/
@Data
@ApiModel("文章搜索请求对象")
public class DocSearchRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 搜索关键词
*/
@ApiModelProperty(value = "搜索关键词", required = true)
private String keyword;
/**
* 专区ID
*/
@ApiModelProperty(value = "专区ID")
private Long zoneId;
/**
* 页码
*/
@ApiModelProperty(value = "页码")
private Integer pageNum = 1;
/**
* 每页数量
*/
@ApiModelProperty(value = "每页数量")
private Integer pageSize = 20;
}

View File

@ -1,63 +0,0 @@
package com.microservices.cms.search.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* 全局搜索响应对象
*
* @author microservices
*/
@Data
@ApiModel("文章搜索响应对象")
public class DocSearchResponse implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 总结果数
*/
@ApiModelProperty(value = "总结果数")
private Long total;
/**
* 搜索结果列表
*/
@ApiModelProperty(value = "搜索结果列表")
private List<DocSearchResult> results;
/**
* 各类型结果数量统计
*/
@ApiModelProperty(value = "各类型结果数量统计")
private Map<String, Long> typeCounts;
/**
* 搜索耗时毫秒
*/
@ApiModelProperty(value = "搜索耗时(毫秒)")
private Long searchTime;
/**
* 搜索关键词
*/
@ApiModelProperty(value = "搜索关键词")
private String keyword;
/**
* 当前页码
*/
@ApiModelProperty(value = "当前页码")
private Integer pageNum;
/**
* 每页数量
*/
@ApiModelProperty(value = "每页数量")
private Integer pageSize;
}

View File

@ -1,65 +0,0 @@
package com.microservices.cms.search.dto;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 文章搜索结果对象
*
* @author microservices
*/
@Data
@ApiModel("文章搜索结果对象")
public class DocSearchResult implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ApiModelProperty(value = "ID")
private Long id;
/**
* 标题
*/
@ApiModelProperty(value = "标题")
private String title;
/**
* 内容摘要
*/
@ApiModelProperty(value = "内容摘要")
private String content;
/**
* 组织ID
*/
@ApiModelProperty(value = "组织ID")
private Long deptId;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建时间")
private Date createTime;
/**
* 相关度评分
*/
@ApiModelProperty(value = "相关度评分")
private Double score;
/**
* 扩展数据JSON格式
*/
@ApiModelProperty(value = "扩展数据")
private JSONObject extendData;
}

View File

@ -1,20 +0,0 @@
package com.microservices.cms.search.service;
import com.microservices.cms.search.dto.DocSearchRequest;
import com.microservices.cms.search.dto.DocSearchResponse;
/**
* 全局搜索服务接口
*
* @author microservices
*/
public interface IGlobalSearchService {
/**
* 全局搜索
*
* @param request 搜索请求
* @return 搜索响应
*/
DocSearchResponse docSearch(DocSearchRequest request);
}

View File

@ -1,215 +0,0 @@
package com.microservices.cms.search.service.impl;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.cms.doc.domain.CmsDoc;
import com.microservices.cms.doc.domain.CmsDocWithScore;
import com.microservices.cms.doc.mapper.CmsDocMapper;
import com.microservices.cms.doc.service.ICmsDocService;
import com.microservices.cms.search.service.IGlobalSearchService;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.redis.service.RedisService;
import com.microservices.cms.search.dto.DocSearchRequest;
import com.microservices.cms.search.dto.DocSearchResponse;
import com.microservices.cms.search.dto.DocSearchResult;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.system.api.model.LoginUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
/**
* 全局搜索服务实现
*
* @author microservices
*/
@Service
public class GlobalSearchServiceImpl implements IGlobalSearchService {
private static final Logger logger = LoggerFactory.getLogger(GlobalSearchServiceImpl.class);
@Autowired
private CmsDocMapper cmsDocMapper;
@Autowired
private RedisService redisService;
@Autowired
private ICmsDocService cmsDocService;
private static final String SEARCH_CACHE_PREFIX = "search:cache:";
private static final Long CACHE_EXPIRE_SECONDS = 300L; // 5分钟
@Override
public DocSearchResponse docSearch(DocSearchRequest request) {
long startTime = System.currentTimeMillis();
// 参数校验
if (StringUtils.isEmpty(request.getKeyword())) {
return buildEmptyResponse(request);
}
// 1. 尝试从缓存获取仅第一页
if (request.getPageNum() == 1) {
String cacheKey = buildCacheKey(request);
DocSearchResponse cached = redisService.getCacheObject(SEARCH_CACHE_PREFIX + cacheKey);
if (cached != null) {
cached.setSearchTime(System.currentTimeMillis() - startTime);
return cached;
}
}
// 2. 并行搜索各类型
List<DocSearchResult> allResults = new ArrayList<>();
Map<String, Long> typeCounts = new HashMap<>();
// 获取当前用户信息
LoginUser loginUser = SecurityUtils.getLoginUser();
// 搜索CMS文章
List<DocSearchResult> docResults = searchDocs(request);
allResults.addAll(docResults);
typeCounts.put("doc", (long) docResults.size());
// 3. 按相关度评分排序
allResults.sort((a, b) -> {
if (b.getScore() != null && a.getScore() != null) {
return b.getScore().compareTo(a.getScore());
}
return 0;
});
// 4. 分页
int total = allResults.size();
int start = (request.getPageNum() - 1) * request.getPageSize();
int end = Math.min(start + request.getPageSize(), total);
List<DocSearchResult> pagedResults = start < total ?
allResults.subList(start, end) : new ArrayList<>();
// 5. 构建响应
DocSearchResponse response = new DocSearchResponse();
response.setTotal((long) total);
response.setResults(pagedResults);
response.setTypeCounts(typeCounts);
response.setKeyword(request.getKeyword());
response.setPageNum(request.getPageNum());
response.setPageSize(request.getPageSize());
response.setSearchTime(System.currentTimeMillis() - startTime);
// 6. 缓存结果仅第一页
if (request.getPageNum() == 1) {
String cacheKey = buildCacheKey(request);
redisService.setCacheObject(SEARCH_CACHE_PREFIX + cacheKey, response, CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS);
}
// 7. 记录搜索日志
recordSearchLog(request, response, loginUser);
return response;
}
/**
* 记录搜索日志
*/
private void recordSearchLog(DocSearchRequest request, DocSearchResponse response, LoginUser loginUser) {
Long userId = loginUser != null ? loginUser.getUserId() : null;
String searchTypes = "文章";
Long deptId = cmsDocService.getDeptIdByZoneId(request.getZoneId());
logger.info("全局搜索 - 关键词: {}, 用户ID: {}, 耗时: {}ms, 结果数: {}, 类型: {}, 专区Id: {}, 组织ID: {}",
request.getKeyword(),
userId,
response.getSearchTime(),
response.getTotal(),
searchTypes,
request.getZoneId(),
deptId
);
}
/**
* 搜索CMS文章
*/
private List<DocSearchResult> searchDocs(DocSearchRequest request) {
List<DocSearchResult> results = new ArrayList<>();
try {
// 使用部门ID参数
Long deptId = cmsDocService.getDeptIdByZoneId(request.getZoneId());
// 使用新的带评分的查询方法
List<CmsDocWithScore> docs = cmsDocMapper.globalSearchWithScore(
request.getKeyword(),
deptId,
(request.getPageNum() - 1) * request.getPageSize(),
request.getPageSize()
);
for (CmsDocWithScore doc : docs) {
DocSearchResult result = new DocSearchResult();
result.setId(doc.getId());
result.setTitle(highlightKeyword(doc.getName(), request.getKeyword()));
result.setContent(highlightKeyword(doc.getSummary(), request.getKeyword()));
result.setDeptId(doc.getDeptId());
result.setCreateTime(doc.getCreateTime());
// 使用数据库返回的实际搜索评分
Double score = doc.getSearchScore();
if (score == null || score == 0.0) {
// 对于 LIKE 匹配无全文评分赋予最小评分
score = 0.1;
}
result.setScore(score);
JSONObject extendData = new JSONObject();
extendData.put("visits", doc.getVisits());
extendData.put("publishTime", doc.getPublishTime());
result.setExtendData(extendData);
results.add(result);
}
} catch (Exception e) {
// 记录错误但继续处理其他类型
System.err.println("搜索CMS文章失败: " + e.getMessage());
}
return results;
}
/**
* 构建缓存键
*/
private String buildCacheKey(DocSearchRequest request) {
Long deptId = cmsDocService.getDeptIdByZoneId(request.getZoneId());
StringBuilder key = new StringBuilder(request.getKeyword());
key.append(":").append(String.join(",", "Doc"));
if (deptId != null) {
key.append(":dept=").append(deptId);
}
return key.toString();
}
/**
* 构建空响应
*/
private DocSearchResponse buildEmptyResponse(DocSearchRequest request) {
DocSearchResponse response = new DocSearchResponse();
response.setTotal(0L);
response.setResults(new ArrayList<>());
response.setTypeCounts(new HashMap<>());
response.setKeyword(request.getKeyword());
response.setPageNum(request.getPageNum());
response.setPageSize(request.getPageSize());
response.setSearchTime(0L);
return response;
}
/**
* 将文本中的关键词用 <em> 标签包裹不区分大小写
*/
private String highlightKeyword(String text, String keyword) {
if (StringUtils.isEmpty(text) || StringUtils.isEmpty(keyword)) {
return text;
}
return text.replaceAll("(?i)(" + Pattern.quote(keyword) + ")", "<em>$1</em>");
}
}

View File

@ -1,4 +1,4 @@
package com.microservices.cms.service.impl;
package com.microservices.cms.common.service.impl;
import com.microservices.cms.common.service.ISysUserService;
import com.microservices.common.core.constant.SecurityConstants;

View File

@ -25,24 +25,4 @@ public class CmsConstants {
*
*/
public final static String TRUE = "1";
/**
* 专区积分异步队列 Redis Key Zone 模块保持一致
*/
public final static String ZONE_POINTS_ASYNC_QUEUE_KEY = "zone:points:async:queue";
/**
* 发布文章积分类型
*/
public final static String PUBLISH_DOC = "publishDoc";
/**
* 浏览文章积分类型
*/
public final static String VISITS_DOC = "visitsDoc";
/**
* 精选文章积分类型
*/
public final static String FEATURED_DOC = "featuredDoc";
}

View File

@ -12,18 +12,6 @@ import java.util.Map;
public class CmsGitLinkRequestUrl extends GitLinkRequestUrl {
public static GitLinkRequestUrl ADD_USER_TO_ORGANIZATION_TEAM(String orgIdentifier, Long teamId) {
return getAdminGitLinkRequestUrl(String.format("/api/organizations/%s/teams/%d/team_users.json", orgIdentifier, teamId));
}
public static String TEAMS_BY_ORGANIZATION_URL(Long orgId) {
return String.format("/api/organizations/%s/teams.json", orgId);
}
public static GitLinkRequestUrl DELETE_USER_FROM_ORGANIZATION_TEAM(String orgIdentifier, Long teamId, String username) {
return getAdminGitLinkRequestUrl(String.format("/api/organizations/%s/teams/%d/team_users/%s.json", orgIdentifier, teamId, username));
}
/**
* 创建项目
*/
@ -78,7 +66,7 @@ public class CmsGitLinkRequestUrl extends GitLinkRequestUrl {
public static GitLinkRequestUrl DELETE_BRANCH(CmsProject cmsProject, String branchName) {
return getGitLinkRequestUrl(
String.format("/api/v1/%s/%s/branches/delete.json?branch_name=%s", cmsProject.getUsername(), cmsProject.getIdentifier(), branchName)
String.format("/api/v1/%s/%s/branches/%s.json", cmsProject.getUsername(), cmsProject.getIdentifier(), branchName)
);
}
@ -88,12 +76,6 @@ public class CmsGitLinkRequestUrl extends GitLinkRequestUrl {
);
}
public static GitLinkRequestUrl REOPEN_PULL_REQUEST(CmsProject cmsProject, String giteaPrNumber) {
return getGitLinkRequestUrl(
String.format("/api/v1/%s/%s/pulls/%s/reopen", cmsProject.getUsername(), cmsProject.getIdentifier(), giteaPrNumber)
);
}
public static GitLinkRequestUrl GET_PULL_REQUEST_DETAILS(CmsProject cmsProject, String giteaPrNumber) {
return getGitLinkRequestUrl(
String.format("/api/%s/%s/pulls/%s.json", cmsProject.getUsername(), cmsProject.getIdentifier(), giteaPrNumber)
@ -119,7 +101,7 @@ public class CmsGitLinkRequestUrl extends GitLinkRequestUrl {
}
public static GitLinkRequestUrl ADD_USER_FROM_PROJECT(CmsProject cmsProject) {
return getAdminGitLinkRequestUrl(
return getGitLinkRequestUrl(
String.format("/api/%s/%s/collaborators.json", cmsProject.getUsername(), cmsProject.getIdentifier())
);
}
@ -166,19 +148,19 @@ public class CmsGitLinkRequestUrl extends GitLinkRequestUrl {
);
}
public static GitLinkRequestUrl CREATE_PROTECTED_BRANCHES(String username, String identifier, Map<String, String> params, List<String> pushWhitelistUsernames) throws URISyntaxException {
public static GitLinkRequestUrl CREATE_PROTECTED_BRANCHES(String username, String identifier, Map<String,String> params, List<String> pushWhitelistUsernames) throws URISyntaxException {
String path = buildUri(String.format("/api/%s/%s/protected_branches.json", username, identifier), params);
path = concatenateParametersAfterUrl(path, "push_whitelist_usernames[]", pushWhitelistUsernames);
return getGitLinkRequestUrl(path);
}
public static GitLinkRequestUrl UPDATE_PROTECTED_BRANCHES(String username, String identifier, Map<String, String> params, List<String> pushWhitelistUsernames) throws URISyntaxException {
public static GitLinkRequestUrl UPDATE_PROTECTED_BRANCHES(String username, String identifier, Map<String,String> params, List<String> pushWhitelistUsernames) throws URISyntaxException {
String path = buildUri(String.format("/api/%s/%s/protected_branches/master.json", username, identifier), params);
path = concatenateParametersAfterUrl(path, "push_whitelist_usernames[]", pushWhitelistUsernames);
return getGitLinkRequestUrl(path);
}
public static GitLinkRequestUrl DELETE_PROTECTED_BRANCHES(String username, String identifier, Map<String, String> params, List<String> pushWhitelistUsernames) throws URISyntaxException {
public static GitLinkRequestUrl DELETE_PROTECTED_BRANCHES(String username, String identifier, Map<String,String> params, List<String> pushWhitelistUsernames) throws URISyntaxException {
String path = buildUri(String.format("/api/%s/%s/protected_branches/master.json", username, identifier), params);
path = concatenateParametersAfterUrl(path, "push_whitelist_usernames[]", pushWhitelistUsernames);
return getGitLinkRequestUrl(path);
@ -215,12 +197,4 @@ public class CmsGitLinkRequestUrl extends GitLinkRequestUrl {
public static String ZONE_DOC_URL(String gitlinkUrl, String zoneKey, Long docId) {
return EscapeUtil.removeExtraSlashOfUrl(String.format("%s/zone/%s/newdetail/%d", gitlinkUrl, zoneKey, docId));
}
public static GitLinkRequestUrl GET_PROJECT_DETAIL(String username, String identifier) {
return getAdminGitLinkRequestUrl(String.format("/api/%s/%s/detail.json", username, identifier));
}
public static GitLinkRequestUrl BATCH_COMMIT(String username, String identifier) {
return getAdminGitLinkRequestUrl(String.format("/api/v1/%s/%s/contents/batch.json", username, identifier));
}
}

View File

@ -1,37 +0,0 @@
package com.microservices.cms.utils;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.threadPool.ThreadPoolExecutorWrap;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 线程池工厂
*
* @author OTTO
*/
public class CustomExecutorFactory {
/**
* 创建线程池
* 存在并发处理的情况设置核心线程为2设置有界队列长度为100最大线程数为10
* 当超出队列已满且达到最大线程数时抛出异常
* Ncpu=CPU数量
* Ucpu=目标CPU的使用率0<=Ucpu<=1
* W/C=任务等待时间与任务计算时间的比率
* Nthreads =Ncpu*Ucpu*(1+W/C)
*/
public static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutorWrap(
5
, 10
, 10
, TimeUnit.SECONDS
, new ArrayBlockingQueue<>(100)
, Executors.defaultThreadFactory()
, (r, executor) -> {
throw new ServiceException("目前处理的人太多了,请稍后再试");
}
);
}

View File

@ -36,8 +36,6 @@
<result property="auditType" column="audit_type"/>
<result property="auditTmpBranchName" column="audit_tmp_branch_name"/>
<result property="auditPrNumber" column="audit_pr_number"/>
<result property="keywords" column="keywords"/>
<result property="remark" column="remark"/>
</resultMap>
<sql id="selectCmsDocVo">
@ -71,9 +69,7 @@
audit_status,
audit_type,
audit_tmp_branch_name,
keywords,
audit_pr_number,
remark
audit_pr_number
from cms_doc
</sql>
@ -104,104 +100,10 @@
cd.issue_id,
cd.is_homepage,
cd.editor_type,
cd.keywords,
cd.is_dir,
cd.audit_status,
cd.audit_type,
cd.audit_tmp_branch_name,
cd.audit_pr_number,
cd.remark
cd.is_dir
from cms_doc cd
</sql>
<sql id="selectCmsDocWithScoreVo">
select cd.id,
cd.create_by,
cd.create_time,
cd.update_by,
cd.update_time,
cd.name,
cd.file_name,
cd.file_path,
cd.file_sha,
cd.file_size,
cd.file_url,
cd.html_url,
cd.visits,
cd.sort,
cd.publish_time,
cd.publish_user,
cd.publish_user_image,
cd.publish_user_url,
cd.publish_user_nickname,
cd.summary,
cd.head_img,
cd.dir_name,
cd.dept_id,
cd.issue_id,
cd.is_homepage,
cd.editor_type,
cd.keywords,
cd.is_dir,
cd.audit_status,
cd.audit_type,
cd.audit_tmp_branch_name,
cd.audit_pr_number,
-- 计算全文搜索相关度评分
MATCH(cd.name, cd.summary) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE) AS search_score,
cd.remark
from cms_doc cd
</sql>
<sql id="selectCmsDocAliasSetDefaultHeadImgVo">
select cd.id,
cd.create_by,
cd.create_time,
cd.update_by,
cd.update_time,
cd.name,
cd.file_name,
cd.file_path,
cd.file_sha,
cd.file_size,
cd.file_url,
cd.html_url,
cd.visits,
cd.sort,
cd.publish_time,
cd.publish_user,
cd.publish_user_image,
cd.publish_user_url,
cd.publish_user_nickname,
cd.summary,
-- 处理文章和栏目头图为NULL或空字符串的情况
CASE
-- 文章头图不为空非NULL且非空字符串
WHEN cd.head_img IS NOT NULL AND TRIM(cd.head_img) != '' THEN cd.head_img
-- 栏目存在且头图不为空
WHEN dir.head_img IS NOT NULL AND TRIM(dir.head_img) != '' THEN dir.head_img
END AS head_img,
cd.dir_name,
cd.dept_id,
cd.issue_id,
cd.is_homepage,
cd.editor_type,
cd.keywords,
cd.is_dir,
cd.audit_status,
cd.audit_type,
cd.audit_tmp_branch_name,
cd.audit_pr_number,
cd.remark
from cms_doc cd
left join cms_doc dir on cd.dir_name = dir.name and cd.dept_id = dir.dept_id and dir.is_dir=1
</sql>
<select id="selectCmsDocAndDirListByDept" resultMap="CmsDocResult">
<include refid="selectCmsDocVo"/>
where dept_id=#{deptId}
</select>
<select id="selectCmsDocList" parameterType="com.microservices.cms.doc.domain.CmsDocSearchVo"
resultMap="CmsDocResult">
<include refid="selectCmsDocVo"/>
@ -217,19 +119,10 @@
where id = #{id}
</select>
<select id="selectCmsDocByIds" resultMap="CmsDocResult">
<include refid="selectCmsDocVo"/>
where id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<select id="selectCmsDocByNameAndDeptId" resultMap="CmsDocResult">
<include refid="selectCmsDocVo"/>
<where>
and name = #{name}
and audit_status != 0
and dept_id = #{deptId}
<choose>
<when test="dirName != null">
@ -241,10 +134,6 @@
</choose>
</where>
</select>
<select id="selectCmsDocByNameAndDeptIdIgnoreDirName" resultMap="CmsDocResult">
<include refid="selectCmsDocVo"/>
where name = #{name} and dept_id = #{deptId} and is_dir = 0
</select>
<select id="selectCmsDocDirByNameAndDeptId" resultMap="CmsDocResult">
<include refid="selectCmsDocVo"/>
where name = #{name} and dept_id = #{deptId} and is_dir = 1
@ -258,13 +147,13 @@
where file_path = #{filePath} and dept_id = #{deptId} and is_dir = 0
</select>
<select id="selectHotCmsDocList" parameterType="com.microservices.cms.doc.domain.CmsDoc" resultMap="CmsDocResult">
<include refid="selectCmsDocAliasSetDefaultHeadImgVo"/>
<include refid="selectListWhereAlias"/>
<include refid="selectCmsDocVo"/>
<include refid="selectListWhere"/>
ORDER BY
cd.visits DESC,
cd.sort DESC,
cd.update_time DESC,
cd.create_time DESC
visits DESC,
sort DESC,
update_time DESC,
create_time DESC
</select>
<select id="selectCmsDocCount" resultType="java.lang.Integer">
@ -274,7 +163,6 @@
<sql id="selectListWhere">
<where>
<if test="name != null and name != ''">and name like concat('%', #{name}, '%')</if>
<if test="keywords != null and keywords != ''">and keywords like concat('%', #{keywords}, '%')</if>
<if test="fileName != null and fileName != ''">and file_name like concat('%', #{fileName}, '%')</if>
<if test="filePath != null and filePath != ''">and file_path = #{filePath}</if>
<if test="publishTime != null ">and publish_time = #{publishTime}</if>
@ -285,24 +173,6 @@
<if test="auditStatus != null and auditStatus != '-1' ">and audit_status = #{auditStatus}</if>
<if test="auditStatus == null ">and audit_status = '1'</if>
<if test="createBy != null and createBy != '' ">and create_by = #{createBy}</if>
<if test="excludeId != null ">and id != #{excludeId}</if>
</where>
</sql>
<sql id="selectListWhereAlias">
<where>
<if test="name != null and name != ''">and cd.name like concat('%', #{name}, '%')</if>
<if test="keywords != null and keywords != ''">and cd.keywords like concat('%', #{keywords}, '%')</if>
<if test="fileName != null and fileName != ''">and cd.file_name like concat('%', #{fileName}, '%')</if>
<if test="filePath != null and filePath != ''">and cd.file_path = #{filePath}</if>
<if test="publishTime != null ">and cd.publish_time = #{publishTime}</if>
<if test="isDir != null ">and cd.is_dir = #{isDir}</if>
<if test="dirName != null ">and cd.dir_name = #{dirName}</if>
<if test="deptId != null ">and cd.dept_id = #{deptId}</if>
<if test="isHomepage != null ">and cd.is_homepage = #{isHomepage}</if>
<if test="auditStatus != null and auditStatus != '-1' ">and cd.audit_status = #{auditStatus}</if>
<if test="auditStatus == null ">and cd.audit_status = '1'</if>
<if test="createBy != null and createBy != '' ">and cd.create_by = #{createBy}</if>
</where>
</sql>
@ -404,20 +274,6 @@
and is_dir = 0
and audit_status = '2'
</select>
<select id="getCmsDocVisitsByDeptId" resultType="java.lang.Long">
select SUM(visits)
from cms_doc
where dept_id = #{deptId};
</select>
<select id="selectCmsDocListSetDefaultHeadImg" parameterType="com.microservices.cms.doc.domain.CmsDocSearchVo"
resultMap="CmsDocResult">
<include refid="selectCmsDocAliasSetDefaultHeadImgVo"/>
<include refid="selectListWhereAlias"/>
ORDER BY
cd.sort DESC,
cd.update_time DESC,
cd.create_time DESC
</select>
<insert id="insertCmsDoc" parameterType="com.microservices.cms.doc.domain.CmsDoc" useGeneratedKeys="true"
keyProperty="id">
@ -453,7 +309,6 @@
<if test="auditType != null">audit_type,</if>
<if test="auditTmpBranchName != null">audit_tmp_branch_name,</if>
<if test="auditPrNumber != null">audit_pr_number,</if>
<if test="keywords != null">keywords,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="createBy != null">#{createBy},</if>
@ -486,7 +341,6 @@
<if test="auditType != null">#{auditType},</if>
<if test="auditTmpBranchName != null">#{auditTmpBranchName},</if>
<if test="auditPrNumber != null">#{auditPrNumber},</if>
<if test="keywords != null">#{keywords},</if>
</trim>
</insert>
@ -522,8 +376,6 @@
<if test="auditType != null">audit_type = #{auditType},</if>
<if test="auditTmpBranchName != null">audit_tmp_branch_name = #{auditTmpBranchName},</if>
<if test="auditPrNumber != null">audit_pr_number = #{auditPrNumber},</if>
<if test="keywords != null">keywords = #{keywords},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where id = #{id}
</update>
@ -541,12 +393,6 @@
and dept_id = #{deptId}
and is_dir = #{isDir};
</update>
<update id="updateCmsDocShaByPathAndDeptId">
update cms_doc
set file_sha=#{sha}
where file_path=#{filePath}
and dept_id=#{deptId}
</update>
<delete id="deleteCmsDocById" parameterType="Long">
delete
@ -560,70 +406,4 @@
#{id}
</foreach>
</delete>
<!-- 全局搜索 - 全文索引查询(含 LIKE 后备搜索) -->
<select id="globalSearch" resultMap="CmsDocResult">
<include refid="selectCmsDocAliasVo"/>
WHERE
cd.is_dir = 0
AND cd.audit_status = '1'
AND (
MATCH(cd.name, cd.summary) AGAINST(#{keyword} IN BOOLEAN MODE)
OR cd.name LIKE CONCAT('%', #{keyword}, '%')
OR cd.summary LIKE CONCAT('%', #{keyword}, '%')
)
<if test="deptId != null">
AND cd.dept_id = #{deptId}
</if>
ORDER BY
CASE
WHEN MATCH(cd.name, cd.summary) AGAINST(#{keyword} IN BOOLEAN MODE) > 0 THEN 1
ELSE 2
END,
cd.update_time DESC
LIMIT #{offset}, #{pageSize}
</select>
<select id="globalSearchCount" resultType="java.lang.Long">
SELECT COUNT(*)
FROM cms_doc cd
WHERE
cd.is_dir = 0
AND cd.audit_status = '1'
AND (
MATCH(cd.name, cd.summary) AGAINST(#{keyword} IN BOOLEAN MODE)
OR cd.name LIKE CONCAT('%', #{keyword}, '%')
OR cd.summary LIKE CONCAT('%', #{keyword}, '%')
)
<if test="deptId != null">
AND cd.dept_id = #{deptId}
</if>
</select>
<!-- ResultMap for CmsDocWithScore -->
<resultMap type="com.microservices.cms.doc.domain.CmsDocWithScore" id="CmsDocWithScoreResult" extends="CmsDocResult">
<result property="searchScore" column="search_score"/>
</resultMap>
<!-- 全局搜索 - 带评分的全文索引查询 -->
<select id="globalSearchWithScore" resultMap="CmsDocWithScoreResult">
<include refid="selectCmsDocWithScoreVo"/>
WHERE
cd.is_dir = 0
AND cd.audit_status = '1'
AND (
MATCH(cd.name, cd.summary) AGAINST(#{keyword} IN BOOLEAN MODE)
OR cd.name LIKE CONCAT('%', #{keyword}, '%')
OR cd.summary LIKE CONCAT('%', #{keyword}, '%')
)
<if test="deptId != null">
AND cd.dept_id = #{deptId}
</if>
ORDER BY
-- 主要排序:按相关度评分降序
search_score DESC,
-- 次要排序:更新时间降序
cd.update_time DESC
LIMIT #{offset}, #{pageSize}
</select>
</mapper>

View File

@ -159,38 +159,4 @@
item="id" collection="array" open="(" separator="," close=")">#{id}
</foreach>
</delete>
<!-- 全局搜索 - 全文索引查询 -->
<select id="globalSearch" resultMap="CmsProjectResult">
SELECT id,
name,
description,
user_id,
dept_id,
identifier,
username,
create_by,
create_time,
update_time
FROM cms_project cp
WHERE
MATCH(cp.name) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE)
<if test="deptId != null">
AND cp.dept_id = #{deptId}
</if>
ORDER BY
MATCH(cp.name) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE) DESC,
cp.update_time DESC
LIMIT #{offset}, #{pageSize}
</select>
<select id="globalSearchCount" resultType="java.lang.Long">
SELECT COUNT(*)
FROM cms_project cp
WHERE
MATCH(cp.name) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE)
<if test="deptId != null">
AND cp.dept_id = #{deptId}
</if>
</select>
</mapper>

View File

@ -1,156 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.microservices</groupId>
<artifactId>microservices-modules</artifactId>
<version>3.6.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>microservices-modules-dms</artifactId>
<description>
microservices-modules-dms数据管理体系模块
</description>
<dependencies>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Swagger UI -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Microservices Common Async -->
<dependency>
<groupId>com.microservices</groupId>
<artifactId>microservices-common-async</artifactId>
</dependency>
<!-- Microservices Common DataSource -->
<dependency>
<groupId>com.microservices</groupId>
<artifactId>microservices-common-datasource</artifactId>
</dependency>
<!-- Microservices Common DataScope -->
<dependency>
<groupId>com.microservices</groupId>
<artifactId>microservices-common-datascope</artifactId>
</dependency>
<!-- Microservices Common Log -->
<dependency>
<groupId>com.microservices</groupId>
<artifactId>microservices-common-log</artifactId>
</dependency>
<!-- Microservices Common Swagger -->
<dependency>
<groupId>com.microservices</groupId>
<artifactId>microservices-common-swagger</artifactId>
</dependency>
<dependency>
<groupId>com.microservices</groupId>
<artifactId>microservices-common-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
<dependency>
<groupId>com.microservices</groupId>
<artifactId>microservices-common-core</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 处理访问Gitlink相关接口 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
<dependency>
<groupId>com.microservices</groupId>
<artifactId>microservices-common-httpClient</artifactId>
<version>3.6.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.shibing624</groupId>
<artifactId>similarity</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>com.hankcs</groupId>
<artifactId>hanlp</artifactId>
<version>portable-1.8.4</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,25 +0,0 @@
package com.microservices.dms;
import com.microservices.common.security.annotation.EnableCustomConfig;
import com.microservices.common.security.annotation.EnableRyFeignClients;
import com.microservices.common.swagger.annotation.EnableCustomSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* 项目管理模块
*
* @author otto
*/
@EnableCustomConfig
@EnableCustomSwagger2
@EnableRyFeignClients
@SpringBootApplication
@EnableScheduling
public class MicroservicesDmsApplication {
public static void main(String[] args) {
SpringApplication.run(MicroservicesDmsApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 数据管理体系模块启动成功 ლ(´ڡ`ლ)゙ \n");
}
}

View File

@ -1,125 +0,0 @@
package com.microservices.dms.achievementLibrary.controller;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.dms.achievementLibrary.domain.KeyValueVo;
import com.microservices.system.api.domain.SysDictData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.microservices.common.log.annotation.Log;
import com.microservices.common.log.enums.BusinessType;
import com.microservices.common.security.annotation.RequiresPermissions;
import com.microservices.dms.achievementLibrary.domain.AchievementDictData;
import com.microservices.dms.achievementLibrary.service.IAchievementDictDataService;
import com.microservices.common.core.web.controller.BaseController;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.common.core.utils.poi.ExcelUtil;
import com.microservices.common.core.web.page.TableDataInfo;
/**
* 成果相关字典Controller
*
* @author microservices
* @date 2025-05-23
*/
@Api(tags = "数据管理体系-成果字典管理")
@RestController
@RequestMapping("/achDict")
public class AchievementDictDataController extends BaseController
{
@Autowired
private IAchievementDictDataService achievementDictDataService;
/**
* 查询成果相关字典列表
*/
@GetMapping("/list")
public TableDataInfo list(AchievementDictData achievementDictData)
{
startPage();
List<AchievementDictData> list = achievementDictDataService.selectAchievementDictDataList(achievementDictData);
return getDataTable(list);
}
/**
* 导出成果相关字典列表
*/
@Log(title = "成果相关字典", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AchievementDictData achievementDictData)
{
List<AchievementDictData> list = achievementDictDataService.selectAchievementDictDataList(achievementDictData);
ExcelUtil<AchievementDictData> util = new ExcelUtil<AchievementDictData>(AchievementDictData.class);
util.exportExcel(response, list, "成果相关字典数据");
}
/**
* 获取成果相关字典详细信息
*/
@GetMapping(value = "/{dictCode}")
public AjaxResult getInfo(@PathVariable("dictCode") Long dictCode)
{
return success(achievementDictDataService.selectAchievementDictDataByDictCode(dictCode));
}
/**
* 新增成果相关字典
*/
@Log(title = "成果相关字典", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AchievementDictData achievementDictData)
{
return toAjax(achievementDictDataService.insertAchievementDictData(achievementDictData));
}
/**
* 修改成果相关字典
*/
@Log(title = "成果相关字典", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AchievementDictData achievementDictData)
{
return toAjax(achievementDictDataService.updateAchievementDictData(achievementDictData));
}
/**
* 删除成果相关字典
*/
@Log(title = "成果相关字典", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictCodes}")
public AjaxResult remove(@PathVariable Long[] dictCodes)
{
return toAjax(achievementDictDataService.deleteAchievementDictDataByDictCodes(dictCodes));
}
/**
* 根据字典类型查询字典数据信息
*/
@ApiOperation("根据成果字典分类查询成果值")
@GetMapping(value = "/getDictDateByType")
public AjaxResult getDictDateByType(String dictType)
{
List<KeyValueVo> data = achievementDictDataService.selectDictDataByType(dictType);
return success(data);
}
@ApiOperation("根据成果字典分类")
@GetMapping(value = "/getDictTypes")
public AjaxResult getDictTypes()
{
List<String> data = achievementDictDataService.getDictTypes();
return success(data);
}
}

View File

@ -1,102 +0,0 @@
package com.microservices.dms.achievementLibrary.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.microservices.common.log.annotation.Log;
import com.microservices.common.log.enums.BusinessType;
import com.microservices.common.security.annotation.RequiresPermissions;
import com.microservices.dms.achievementLibrary.domain.AchievementTeam;
import com.microservices.dms.achievementLibrary.service.IAchievementTeamService;
import com.microservices.common.core.web.controller.BaseController;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.common.core.utils.poi.ExcelUtil;
import com.microservices.common.core.web.page.TableDataInfo;
/**
* 成果团队Controller
*
* @author microservices
* @date 2025-04-23
*/
@RestController
@Api(tags = "数据管理体系-成果团队接口")
@RequestMapping("/achievementsTeam")
public class AchievementTeamController extends BaseController
{
@Autowired
private IAchievementTeamService achievementTeamService;
/**
* 查询成果团队列表
*/
@GetMapping("/list")
public TableDataInfo list(AchievementTeam achievementTeam)
{
startPage();
List<AchievementTeam> list = achievementTeamService.selectAchievementTeamList(achievementTeam);
return getDataTable(list);
}
/**
* 导出成果团队列表
*/
@Log(title = "成果团队", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AchievementTeam achievementTeam)
{
List<AchievementTeam> list = achievementTeamService.selectAchievementTeamList(achievementTeam);
ExcelUtil<AchievementTeam> util = new ExcelUtil<AchievementTeam>(AchievementTeam.class);
util.exportExcel(response, list, "成果团队数据");
}
/**
* 获取成果团队详细信息
*/
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(achievementTeamService.selectAchievementTeamById(id));
}
/**
* 新增成果团队
*/
@Log(title = "成果团队", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AchievementTeam achievementTeam)
{
return toAjax(achievementTeamService.insertAchievementTeam(achievementTeam));
}
/**
* 修改成果团队
*/
@Log(title = "成果团队", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AchievementTeam achievementTeam)
{
return toAjax(achievementTeamService.updateAchievementTeam(achievementTeam));
}
/**
* 删除成果团队
*/
@Log(title = "成果团队", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(achievementTeamService.deleteAchievementTeamByIds(ids));
}
}

View File

@ -1,310 +0,0 @@
package com.microservices.dms.achievementLibrary.controller;
import com.microservices.common.core.utils.poi.ExcelUtil;
import com.microservices.common.core.web.controller.BaseController;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.common.core.web.page.TableDataInfo;
import com.microservices.common.log.annotation.Log;
import com.microservices.common.log.enums.BusinessType;
import com.microservices.dms.achievementLibrary.domain.AchQueryVo;
import com.microservices.dms.achievementLibrary.domain.Achievements;
import com.microservices.dms.achievementLibrary.service.IAchievementsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 成果Controller
*
* @author microservices
* @date 2025-04-02
*/
@RestController
@RequestMapping("/achievements")
@Api(tags = "数据管理体系-成果库接口")
public class AchievementsController extends BaseController {
@Autowired
private IAchievementsService achievementsService;
/**
* 查询成果列表
*/
@GetMapping("/list")
public TableDataInfo list(Achievements achievements) {
startPage();
List<Achievements> list = achievementsService.selectAchievementsList(achievements);
return getDataTable(list);
}
/**
* 导出成果列表
*/
@Log(title = "成果", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, Achievements achievements) {
List<Achievements> list = achievementsService.selectAchievementsList(achievements);
ExcelUtil<Achievements> util = new ExcelUtil<Achievements>(Achievements.class);
util.exportExcel(response, list, "成果数据");
}
/**
* 获取成果详细信息
*/
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(achievementsService.selectAchievementsById(id));
}
/**
* 新增成果
*/
@Log(title = "成果", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody Achievements achievements) {
return toAjax(achievementsService.insertAchievements(achievements));
}
/**
* 修改成果
*/
@Log(title = "成果", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody Achievements achievements) {
return toAjax(achievementsService.updateAchievements(achievements));
}
/**
* 删除成果
*/
@Log(title = "成果", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(achievementsService.deleteAchievementsByIds(ids));
}
@ApiOperation("删除成果数据")
@DeleteMapping("/deleteById")
public AjaxResult deleteById(Long id) {
return toAjax(achievementsService.deleteAchievementsById(id));
}
/**
* 获取精选成果
*
* @return
*/
@ApiOperation("获取精选成果")
@GetMapping("/getChoiceImport")
public AjaxResult getChoiceImport() {
return success(achievementsService.getChoiceImport());
}
/**
* 根据成果来源对成果数据进行分类统计
*
* @return
*/
@ApiOperation("根据成果来源对成果数据进行分类统计")
@GetMapping("/getTjBySources")
public AjaxResult getTjBySources() {
return success(achievementsService.getTjBySources());
}
/**
* 根据成果领域对成功数据进行汇总
*
* @return
*/
@ApiOperation("根据成果领域对成果数据进行汇总")
@GetMapping("/getTjByAreas")
public AjaxResult getTjByAreas() {
return success(achievementsService.getTjByAreas());
}
/**
* 根据领域分类名称获取领域相关数据(创客任务开放竞赛校企成果
*/
@ApiOperation("根据领域分类名称,获取领域相关数据")
@GetMapping("/getAreasByName")
public AjaxResult getAreasByName(String areaName) {
return success(achievementsService.getAreasByName(areaName));
}
@ApiOperation("根据领域分类名称,获取项目领域")
@GetMapping("/getProjectAreasByName")
public AjaxResult getProjectAreasByName(String areaName) {
return success(achievementsService.getProjectAreasByName(areaName));
}
@ApiOperation("根据领域分类名称,获取专家领域")
@GetMapping("/getExpertAreasByName")
public AjaxResult getExpertAreasByName(String areaName) {
return success(achievementsService.getExpertAreasByName(areaName));
}
/* 获取全部成果,根据成果名称成果领域成果来源进行查询
* @return
*/
@ApiOperation("获取全部成果,根据成果名称、成果领域、成果来源进行查询")
@GetMapping("/getAllResult")
public TableDataInfo getAllResult(AchQueryVo achQueryVo) {
startPage();
return getDataTable(achievementsService.getAllResult(achQueryVo));
}
@ApiOperation("近七日用户行为数据")
@GetMapping("/getUerActionData")
public AjaxResult getUerActionData() {
return success(achievementsService.getUerActionData());
}
@ApiOperation("热门成果")
@GetMapping("/getHotAchievement")
public AjaxResult getHotAchievement() {
return success(achievementsService.getHotAchievement());
}
@ApiOperation("七日新增")
@GetMapping("/get7DayAdd")
public AjaxResult get7DayAdd(AchQueryVo achQueryVo) {
return success(achievementsService.get7DayAdd(achQueryVo));
}
@ApiOperation("首页项目统计")
@GetMapping("/indexProjectStatistic")
public AjaxResult indexProjectStatistic() {
return success(achievementsService.indexProjectStatistic());
}
@ApiOperation("首页task统计")
@GetMapping("/indexTaskStatistic")
public AjaxResult indexTaskStatistic() {
return success(achievementsService.indexTaskStatistic());
}
@ApiOperation("首页Competition统计")
@GetMapping("/indexCompetitionStatistic")
public AjaxResult indexCompetitionStatistic() {
return success(achievementsService.indexCompetitionStatistic());
}
@ApiOperation("首页SchoolEnterprise统计")
@GetMapping("/indexSchoolEnterpriseStatistic")
public AjaxResult indexSchoolEnterpriseStatistic() {
return success(achievementsService.indexSchoolEnterpriseStatistic());
}
@ApiOperation("首页专家统计")
@GetMapping("/indexExpertStatistic")
public AjaxResult indexExpertStatistic() {
return success(achievementsService.indexExpertStatistic());
}
@ApiOperation("根据当前用户以及成果ID,获取当前成果的 是否收藏与关注状态")
@GetMapping("/getWatchFavoriteStatusById")
public AjaxResult getWatchFavoriteStatusById(Long id, Long userId) {
return success(achievementsService.getWatchFavoriteStatusById(id, userId));
}
@ApiOperation("根据成果ID获取近7日成果点击数量折线图")
@GetMapping("/get7AddClickById")
public AjaxResult get7AddClickById(String id,@RequestParam(value = "clickType",required = false, defaultValue = "Achievements")
String clickType) {
return success(achievementsService.get7AddClickById(id,clickType));
}
@ApiOperation("根据专家id获取近7日成果点击数量折线图")
@GetMapping("/getExpert7AddClickById")
public AjaxResult getExpert7AddClickById(String id,@RequestParam(value = "clickType",required = false, defaultValue = "Experts")
String clickType) {
return success(achievementsService.get7AddClickById(id,clickType));
}
@ApiOperation("根据成果ID,获取成果的相关行为数据统计(点击量、搜索量、附件下载量、收藏、关注)")
@GetMapping("/getActDataStatisticById")
public AjaxResult getActDataStatisticById(Long id) {
return success(achievementsService.getActDataStatisticById(id));
}
@ApiOperation("根据领域来源、领域分类名称,获取领域相关数据")
@GetMapping("/getAllAreas")
public AjaxResult getAllAreas(String areaName) {
return success(achievementsService.getAllAreas(areaName));
}
@ApiOperation("根据领域,将成果数据进行分类")
@GetMapping("/getAreaStatistic")
public AjaxResult getAreaStatistic(String areaKey)
{
return success(achievementsService.getAreaStatistic(areaKey));
}
@ApiOperation("根据领域获取领域详情")
@GetMapping("/getAreaDetail")
public AjaxResult getAreaDetail(String areaKey,String kyxmSum,String source)
{
return success(achievementsService.getAreaDetail(areaKey,kyxmSum,source));
}
/**
* 获取开源项目的相关成果
*/
@ApiOperation(value = "获取开源项目的相关成果")
@GetMapping("/getRelatedAch")
public AjaxResult getRelatedAch(Long id,Long sourceId)
{
return success(achievementsService.getRelatedAch(id,sourceId));
}
@ApiOperation(value = "获取开源竞赛的相关成果")
@GetMapping("/getRelatedAchCompetition")
public AjaxResult getRelatedAchCompetition(Long id,Long sourceId)
{
return success(achievementsService.getRelatedAchCompetition(id,sourceId));
}
@ApiOperation(value = "获取创客任务的相关成果")
@GetMapping("/getRelatedAchTask")
public AjaxResult getRelatedAchTask(Long id,Long sourceId)
{
return success(achievementsService.getRelatedAchTask(id,sourceId));
}
@ApiOperation(value = "获取专家-创客任务的相关成果")
@GetMapping("/getRelatedAchTaskOfExpert")
public AjaxResult getRelatedAchTaskOfExpert(Long expertId)
{
return success(achievementsService.getRelatedAchTaskOfExpert(expertId));
}
@ApiOperation(value = "获取专家-开源竞赛的相关成果")
@GetMapping("/getRelatedAchCompetitionOfExpert")
public AjaxResult getRelatedAchCompetitionOfExpert(Long expertId)
{
return success(achievementsService.getRelatedAchCompetitionOfExpert(expertId));
}
@ApiOperation(value = "搜索行为数据记录")
@GetMapping("/getSearchResult")
public AjaxResult getSearchResult(String achName,Long userId)
{
return success(achievementsService.getSearchResult(achName,userId));
}
}

View File

@ -1,99 +0,0 @@
package com.microservices.dms.achievementLibrary.controller;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.dms.achievementLibrary.service.BigScreenStatisticService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
@Api(tags = "数据管理体系-大屏统计接口")
@RequestMapping("/bigScreenStatistic")
public class BigScreenStatisticController {
private final BigScreenStatisticService bigScreenStatisticService;
@GetMapping(value = "/achievement/getAchievementTopStatistic")
@ApiOperation(value = "成果任务统计顶部折线图")
public AjaxResult getAchievementTopStatistic(String source) {
return AjaxResult.success(bigScreenStatisticService.getAchievementTopStatistic(source));
}
@GetMapping(value = "/achievement/getAchievementDataYearly")
@ApiOperation(value = "年度成果数据")
public AjaxResult getAchievementDataYearly() {
return AjaxResult.success(bigScreenStatisticService.getAchievementDataYearly());
}
@GetMapping(value = "/achievement/getAchievementType")
@ApiOperation(value = "成果类型")
public AjaxResult getAchievementType() {
return AjaxResult.success(bigScreenStatisticService.getAchievementType());
}
@GetMapping(value = "/achievement/getAchievementDomain")
@ApiOperation(value = "成果领域分布")
public AjaxResult getAchievementDomain() {
return AjaxResult.success(bigScreenStatisticService.getAchievementDomain());
}
@GetMapping(value = "/achievement/getAchievementAddYearly")
@ApiOperation(value = "近1年新增成果数")
public AjaxResult getAchievementAddYearly() {
return AjaxResult.success(bigScreenStatisticService.getAchievementAddYearly());
}
@GetMapping(value = "/achievement/getAchievementActData")
@ApiOperation(value = "成果行为数据展示")
public AjaxResult getAchievementActData() {
return AjaxResult.success(bigScreenStatisticService.getAchievementActData());
}
@GetMapping(value = "/achievement/getAchievementHotRank")
@ApiOperation(value = "成果热度排行")
public AjaxResult getAchievementHotRank() {
return AjaxResult.success(bigScreenStatisticService.getAchievementHotRank());
}
@GetMapping(value = "/competition/getCompetitionTopStatistic")
@ApiOperation(value = "competition统计顶部")
public AjaxResult getAchievementTopStatistic() {
return AjaxResult.success(bigScreenStatisticService.getCompetitionTopStatistic());
}
@GetMapping(value = "/competition/getCompetitionStatisticYearly")
@ApiOperation(value = "竞赛数据统计")
public AjaxResult getCompetitionStatisticYearly() {
return AjaxResult.success(bigScreenStatisticService.getCompetitionStatisticYearly());
}
@GetMapping(value = "/competition/getCompetitionHot")
@ApiOperation(value = "热门竞赛统计")
public AjaxResult getCompetitionHot() {
return AjaxResult.success(bigScreenStatisticService.getCompetitionHot());
}
@GetMapping(value = "/competition/getCompetitionYearlyPaperAdd")
@ApiOperation(value = "年度竞赛作品新增数")
public AjaxResult getCompetitionYearlyPaperAdd() {
return AjaxResult.success(bigScreenStatisticService.getCompetitionYearlyPaperAdd());
}
@GetMapping(value = "/competition/getCompetitionYearlyFinish")
@ApiOperation(value = "近1年竞赛完成情况")
public AjaxResult getCompetitionYearlyFinish() {
return AjaxResult.success(bigScreenStatisticService.getCompetitionYearlyFinish());
}
}

View File

@ -1,115 +0,0 @@
package com.microservices.dms.achievementLibrary.controller;
import com.microservices.common.core.web.controller.BaseController;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.common.core.web.page.TableDataInfo;
import com.microservices.dms.achievementLibrary.domain.BlockchainListQueryVo;
import com.microservices.dms.achievementLibrary.domain.TokenListVo;
import com.microservices.dms.achievementLibrary.domain.blockchain.InBlockchainData;
import com.microservices.dms.achievementLibrary.domain.blockchain.InLinkProjectVo;
import com.microservices.dms.achievementLibrary.domain.blockchain.UserVo;
import com.microservices.dms.achievementLibrary.service.BlockChainService;
import com.microservices.dms.achievementLibrary.service.InBlockchainDataServiceImpl;
import com.microservices.dms.common.vo.UserCreateVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/blockChain")
@Api(tags = "数据管理体系-数据产权子系统")
public class BlockChainController extends BaseController {
@Autowired
private BlockChainService blockChainService;
@Autowired
private InBlockchainDataServiceImpl inBlockchainDataService;
@GetMapping("/projectTokenList")
@ApiOperation(value = "项目token列表")
public TableDataInfo projectTokenList(String projectName) {
startPage();
List<TokenListVo> list = blockChainService.projectTokenList(projectName);
return getDataTable(list);
}
@GetMapping("/projectTokenDistribute")
@ApiOperation(value = "项目token分配、点击token分配按钮弹出框展示相关数据项目名称、分配token、被分配人")
public AjaxResult projectTokenDistribute(InLinkProjectVo projectVo) {
return blockChainService.projectTokenDistribute(projectVo);
}
@GetMapping("/issueDataList")
@ApiOperation(value = "入链issue列表")
public TableDataInfo issueDataList(BlockchainListQueryVo queryVo) {
startPage();
List<Map<String, Object>> list = blockChainService.issueDataList(queryVo);
return getDataTable(list);
}
@GetMapping("/commitDataList")
@ApiOperation(value = "入链commit列表")
public TableDataInfo commitDataList(BlockchainListQueryVo queryVo) {
startPage();
List<Map<String, Object>> list = blockChainService.commitDataList(queryVo);
return getDataTable(list);
}
@GetMapping("/prDataList")
@ApiOperation(value = "入链PR列表")
public TableDataInfo prDataList(BlockchainListQueryVo queryVo) {
startPage();
List<Map<String, Object>> list = blockChainService.prDataList(queryVo);
return getDataTable(list);
}
@GetMapping("/userDataList")
@ApiOperation(value = "入链user列表")
public TableDataInfo userDataList(BlockchainListQueryVo queryVo) {
List<Map> list = blockChainService.userDataList(queryVo);
return getDataTable(list);
}
@GetMapping("/userList")
@ApiOperation(value = "用户列表列表")
public TableDataInfo userList(UserVo userVo) {
startPage();
List<UserVo> list = blockChainService.userList(userVo);
return getDataTable(list);
}
@GetMapping("/InBlockchainDataList")
@ApiOperation(value = "查询区块链数据入链列表")
public TableDataInfo list(InBlockchainData inBlockchainData) {
startPage();
List<InBlockchainData> list = inBlockchainDataService.selectInBlockchainDataList(inBlockchainData);
return getDataTable(list);
}
@ApiOperation("提供入链项目信息查询")
@GetMapping("/queryBlockInfo")
public AjaxResult queryBlockInfo (String type,String typeId) {
return blockChainService.queryBlockInfo(type,typeId);
}
@ApiOperation("根据项目id获取用户对应的token")
@GetMapping("/getUserTokenByProjectId")
public AjaxResult getUserTokenByProjectId (String type,String userName,String tokenName) {
return blockChainService.getUserTokenByProjectId(type,userName,tokenName);
}
@ApiOperation("获取用户对应的所有项目token")
@GetMapping("/getUserAllProjectToken")
public AjaxResult getUserAllProjectToken (String userName) {
return blockChainService.getUserAllProjectToken(userName);
}
}

View File

@ -1,51 +0,0 @@
package com.microservices.dms.achievementLibrary.controller;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.dms.achievementLibrary.service.BlockChainService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/blockFisco")
@Api(tags = "数据管理体系-数据产权入链交易")
public class BlockFiscoController {
@Autowired
private BlockChainService blockChainService;
@GetMapping("/getTransactionByHash")
@ApiOperation(value = "通过交易哈希获取交易详情")
public AjaxResult getTransactionByHash(String txHash) {
return AjaxResult.success(blockChainService.getTransactionByHash(txHash));
}
@ApiOperation(value = "交易哈希获取交易回执")
@GetMapping("/getTransactionReceipt")
public AjaxResult getTransactionReceipt(String txHash) {
return AjaxResult.success(blockChainService.getTransactionReceipt(txHash));
}
@ApiOperation(value = "获取最新区块号")
@GetMapping("/blockNumber")
public AjaxResult getBlockNumber() {
return AjaxResult.success(blockChainService.getBlockNumber());
}
@ApiOperation(value = "获取区块链总交易数")
@GetMapping("/getTotalTransactionCount")
public AjaxResult getTotalTransactionCount() {
return AjaxResult.success(blockChainService.getTotalTransactionCount());
}
}

View File

@ -1,76 +0,0 @@
package com.microservices.dms.achievementLibrary.controller;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.dms.achievementLibrary.service.ExpertDashboardService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
@Api(tags = "数据管理体系-专家可视化接口")
@RequestMapping("/expertDashboard")
public class ExpertDashboardController {
@Autowired
private ExpertDashboardService expertDashboardService;
@GetMapping(value = "getExpertTotal")
@ApiOperation(value = "获取专家总数")
public AjaxResult getExpertTotal() {
return AjaxResult.success(expertDashboardService.getExpertTotal());
}
@GetMapping(value = "getAuthenticationStatistic")
@ApiOperation(value = "专家实名完成度")
public AjaxResult getAuthenticationStatistic() {
return AjaxResult.success(expertDashboardService.getAuthenticationStatistic());
}
@GetMapping(value = "getTitleRankStatistic")
@ApiOperation(value = "专家职称级分布")
public AjaxResult getTitleRankStatistic() {
return AjaxResult.success(expertDashboardService.getTitleRankStatistic());
}
@GetMapping(value = "getExpertAduit")
@ApiOperation(value = "专家评审作品数排序")
public AjaxResult getExpertAduit() {
return AjaxResult.success(expertDashboardService.getExpertAduit());
}
@GetMapping(value = "getExpertTypeStatistic")
@ApiOperation(value = "专家专业类别")
public AjaxResult getExpertTypeStatistic() {
return AjaxResult.success(expertDashboardService.getExpertTypeStatistic());
}
@GetMapping(value = "getWorkplaceTypeStatistic")
@ApiOperation(value = "专家单位类别分布")
public AjaxResult getWorkplaceTypeStatistic() {
return AjaxResult.success(expertDashboardService.getWorkplaceTypeStatistic());
}
@GetMapping(value = "getHighestDegreeStatistic")
@ApiOperation(value = "专家学历分布")
public AjaxResult getHighestDegreeStatistic() {
return AjaxResult.success(expertDashboardService.getHighestDegreeStatistic());
}
//7年度专家数据统计 cretate_on
@GetMapping(value = "getExpertTotalByYear")
@ApiOperation(value = "年度专家数据统计")
public AjaxResult getExpertTotalByYear() {
return AjaxResult.success(expertDashboardService.getExpertTotalByYear());
}
@GetMapping(value = "getReviewAreasStatistic")
@ApiOperation(value = "热门专家领域")
public AjaxResult getReviewAreasStatistic() {
return AjaxResult.success(expertDashboardService.getReviewAreasStatistic());
}
}

View File

@ -1,62 +0,0 @@
package com.microservices.dms.achievementLibrary.controller;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.dms.achievementLibrary.service.MemoDashboardService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
@Api(tags = "数据管理体系-社区动态可视化接口")
@RequestMapping("/memoDashboard")
public class MemoDashboardController {
@Autowired
private MemoDashboardService memoDashboardService;
@GetMapping(value = "getMemoAduit")
@ApiOperation(value = "帖子审核通过率、帖子总数")
public AjaxResult getMemoAduit() {
return AjaxResult.success(memoDashboardService.getMemoAduit());
}
@GetMapping(value = "getIsOriginalStatistic")
@ApiOperation(value = "帖子原创、非原创")
public AjaxResult getIsOriginalStatistic() {
return AjaxResult.success(memoDashboardService.getIsOriginalStatistic());
}
@GetMapping(value = "getMemoTotalByYear")
@ApiOperation(value = "年度论坛帖子总数")
public AjaxResult getMemoTotalByYear() {
return AjaxResult.success(memoDashboardService.getMemoTotalByYear());
}
@GetMapping(value = "getForumSectionStatistic")
@ApiOperation(value = "帖子分类")
public AjaxResult getForumSectionStatistic() {
return AjaxResult.success(memoDashboardService.getForumSectionStatistic());
}
@GetMapping(value = "getAddMemoStatistic")
@ApiOperation(value = "近一年新增帖子数")
public AjaxResult getAddMemoStatistic() {
return AjaxResult.success(memoDashboardService.getAddMemoStatistic());
}
@GetMapping(value = "getTop5Memos")
@ApiOperation(value = "年度帖子热度top5")
public AjaxResult getTop5Memos() {
return AjaxResult.success(memoDashboardService.getTop5Memos());
}
@GetMapping(value = "get7DayPaise")
@ApiOperation(value = "近7日帖子点赞数")
public AjaxResult get7DayPaise() {
return AjaxResult.success(memoDashboardService.get7DayPaise());
}
}

View File

@ -1,131 +0,0 @@
package com.microservices.dms.achievementLibrary.controller;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.core.utils.poi.ExcelUtil;
import com.microservices.common.core.web.controller.BaseController;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.common.core.web.page.TableDataInfo;
import com.microservices.common.log.annotation.Log;
import com.microservices.common.log.enums.BusinessType;
import com.microservices.dms.achievementLibrary.domain.SchoolEnterpriseAchievements;
import com.microservices.dms.achievementLibrary.service.ISchoolEnterpriseAchievementsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 校企成果Controller
*
* @author microservices
* @date 2025-04-03
*/
@Api(tags = "数据管理体系-校企成果接口")
@RestController
@RequestMapping("/schoolEnterpriseAchievements")
public class SchoolEnterpriseAchievementsController extends BaseController
{
@Autowired
private ISchoolEnterpriseAchievementsService schoolEnterpriseAchievementsService;
/**
* 查询校企成果列表
*/
@GetMapping("/list")
public TableDataInfo list(SchoolEnterpriseAchievements schoolEnterpriseAchievements)
{
startPage();
List<SchoolEnterpriseAchievements> list = schoolEnterpriseAchievementsService.selectSchoolEnterpriseAchievementsList(schoolEnterpriseAchievements);
return getDataTable(list);
}
/**
* 查询校企成果列表
*/
@GetMapping("/listFront")
public TableDataInfo listFront(SchoolEnterpriseAchievements schoolEnterpriseAchievements)
{
startPage();
List<SchoolEnterpriseAchievements> list = schoolEnterpriseAchievementsService.listFront(schoolEnterpriseAchievements);
return getDataTable(list);
}
/**
* 导出校企成果列表
*/
@Log(title = "校企成果", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SchoolEnterpriseAchievements schoolEnterpriseAchievements)
{
List<SchoolEnterpriseAchievements> list = schoolEnterpriseAchievementsService.selectSchoolEnterpriseAchievementsList(schoolEnterpriseAchievements);
ExcelUtil<SchoolEnterpriseAchievements> util = new ExcelUtil<SchoolEnterpriseAchievements>(SchoolEnterpriseAchievements.class);
util.exportExcel(response, list, "校企成果数据");
}
/**
* 获取校企成果详细信息
*/
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(schoolEnterpriseAchievementsService.selectSchoolEnterpriseAchievementsById(id));
}
/**
* 新增校企成果
*/
@Log(title = "校企成果", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SchoolEnterpriseAchievements schoolEnterpriseAchievements)
{
if (!schoolEnterpriseAchievementsService.getCheckSchoolAchName(schoolEnterpriseAchievements)) {
return error("新增校企成果'" + schoolEnterpriseAchievements.getAchievementName() + "'失败,成果名称已存在");
}
return AjaxResult.success(schoolEnterpriseAchievementsService.insertSchoolEnterpriseAchievements(schoolEnterpriseAchievements));
}
/**
* 修改校企成果
*/
@Log(title = "校企成果", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SchoolEnterpriseAchievements schoolEnterpriseAchievements)
{
// if (!schoolEnterpriseAchievementsService.getCheckSchoolAchName(schoolEnterpriseAchievements)) {
// return error("修改校企成果'" + schoolEnterpriseAchievements.getAchievementName() + "'失败,成果名称已存在");
// }
return AjaxResult.success(schoolEnterpriseAchievementsService.updateSchoolEnterpriseAchievements(schoolEnterpriseAchievements));
}
/**
* 删除校企成果
*/
@Log(title = "校企成果", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return AjaxResult.success(schoolEnterpriseAchievementsService.deleteSchoolEnterpriseAchievementsByIds(ids));
}
/**
* 顶部统计
*/
@GetMapping("/topStatistic")
@ApiOperation(value = "顶部统计数据")
@ApiImplicitParams({
@ApiImplicitParam(name = "tags", value = "成果标签", paramType = "query", dataTypeClass = String.class),
@ApiImplicitParam(name = "status", value = "成果状态", paramType = "query", dataTypeClass = Integer.class),
})
public AjaxResult topStatistic(SchoolEnterpriseAchievements schoolEnterpriseAchievements)
{
Long value = schoolEnterpriseAchievementsService.topStatistic(schoolEnterpriseAchievements);
return AjaxResult.success(value);
}
}

View File

@ -1,15 +0,0 @@
package com.microservices.dms.achievementLibrary.domain;
import lombok.Data;
import java.util.List;
@Data
public class AchDetailVo {
private List<Achievements> achievementsList;
private long clickSum;
private long dockSum;
private long favoriteSum;
private long watcherSum;
private String remark;
}

View File

@ -1,49 +0,0 @@
package com.microservices.dms.achievementLibrary.domain;
public class AchQueryVo {
private String areaQuery;//领域
private String source;//来源
private String achievementName;//名称
private Long userId;
private String showAchievementName;
public String getAreaQuery() {
return areaQuery;
}
public void setAreaQuery(String areaQuery) {
this.areaQuery = areaQuery;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getAchievementName() {
return achievementName;
}
public void setAchievementName(String achievementName) {
this.achievementName = achievementName;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getShowAchievementName() {
return showAchievementName;
}
public void setShowAchievementName(String showAchievementName) {
this.showAchievementName = showAchievementName;
}
}

View File

@ -1,24 +0,0 @@
package com.microservices.dms.achievementLibrary.domain;
import java.util.List;
public class AchRelatedResult {
private String year;
private List<AchRelatedVo> achRelatedVoList;
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public List<AchRelatedVo> getAchRelatedVoList() {
return achRelatedVoList;
}
public void setAchRelatedVoList(List<AchRelatedVo> achRelatedVoList) {
this.achRelatedVoList = achRelatedVoList;
}
}

Some files were not shown because too many files have changed in this diff Show More