qianlishi 3 years ago
commit b13aba3681

@ -3,6 +3,7 @@ package com.anjiplus.template.gaea.business.config;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.flyway.FlywayProperties; import org.springframework.boot.autoconfigure.flyway.FlywayProperties;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -18,6 +19,7 @@ import java.sql.Statement;
@Slf4j @Slf4j
@Component @Component
@AllArgsConstructor @AllArgsConstructor
@ConditionalOnProperty(value = {"spring.flyway.enabled"})
public class DatabaseInitializer { public class DatabaseInitializer {
private final FlywayProperties flywayProperties; private final FlywayProperties flywayProperties;

@ -12,7 +12,7 @@ import java.util.Date;
* @author ·De <lide1202@hotmail.com> * @author ·De <lide1202@hotmail.com>
* @date 2019-02-17 08:50:10.009 * @date 2019-02-17 08:50:10.009
**/ **/
@TableName(value="access_authority") @TableName(keepGlobalPrefix=true, value="access_authority")
@Data @Data
public class AccessAuthority extends GaeaBaseEntity { public class AccessAuthority extends GaeaBaseEntity {
/** 父菜单代码 */ /** 父菜单代码 */
@ -40,4 +40,4 @@ public class AccessAuthority extends GaeaBaseEntity {
} }

@ -11,7 +11,7 @@ import java.util.Date;
* @author ·De <lide1202@hotmail.com> * @author ·De <lide1202@hotmail.com>
* @date 2019-02-17 08:50:14.136 * @date 2019-02-17 08:50:14.136
**/ **/
@TableName(value="access_role") @TableName(keepGlobalPrefix=true, value="access_role")
@Data @Data
public class AccessRole extends GaeaBaseEntity { public class AccessRole extends GaeaBaseEntity {
@ -27,4 +27,4 @@ public class AccessRole extends GaeaBaseEntity {
/** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */ /** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
private Integer enableFlag; private Integer enableFlag;
} }

@ -14,7 +14,7 @@ import java.util.Date;
* @author ·De <lide1202@hotmail.com> * @author ·De <lide1202@hotmail.com>
* @date 2019-02-17 08:50:14.136 * @date 2019-02-17 08:50:14.136
**/ **/
@TableName(value="access_role_authority") @TableName(keepGlobalPrefix=true, value="access_role_authority")
@Data @Data
public class AccessRoleAuthority extends GaeaBaseEntity { public class AccessRoleAuthority extends GaeaBaseEntity {

@ -21,6 +21,7 @@ import org.springframework.stereotype.Service;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
/** /**
* @desc AccessRole * @desc AccessRole
@ -52,7 +53,14 @@ public class AccessRoleServiceImpl implements AccessRoleService {
List<TreeNode> treeData = accessAuthorityService.getAuthorityTree(operator, true); List<TreeNode> treeData = accessAuthorityService.getAuthorityTree(operator, true);
// 该角色已选中的菜单及按钮 // 该角色已选中的菜单及按钮
List<String> checkedKeys = accessRoleMapper.checkedAuthoritys(roleCode); // List<String> checkedKeys = accessRoleMapper.checkedAuthoritys(roleCode);
LambdaQueryWrapper<AccessRoleAuthority> accessRoleAuthorityWrapper = Wrappers.lambdaQuery();
accessRoleAuthorityWrapper.select(AccessRoleAuthority::getTarget, AccessRoleAuthority::getAction);
accessRoleAuthorityWrapper.eq(AccessRoleAuthority::getRoleCode, roleCode);
List<AccessRoleAuthority> accessRoleAuthorities = accessRoleAuthorityMapper.selectList(accessRoleAuthorityWrapper);
List<String> checkedKeys = accessRoleAuthorities.stream()
.map(accessRoleAuthority -> accessRoleAuthority.getTarget().concat("_").concat(accessRoleAuthority.getAction())).distinct().collect(Collectors.toList());
result.put("treeData", treeData); result.put("treeData", treeData);
result.put("checkedKeys", checkedKeys); result.put("checkedKeys", checkedKeys);
@ -90,4 +98,4 @@ public class AccessRoleServiceImpl implements AccessRoleService {
}); });
return true; return true;
} }
} }

@ -11,7 +11,7 @@ import java.util.Date;
* @author ·De <lide1202@hotmail.com> * @author ·De <lide1202@hotmail.com>
* @date 2019-02-17 08:50:11.902 * @date 2019-02-17 08:50:11.902
**/ **/
@TableName(value="access_user") @TableName(keepGlobalPrefix=true, value="access_user")
@Data @Data
public class AccessUser extends GaeaBaseEntity { public class AccessUser extends GaeaBaseEntity {
@ -45,4 +45,4 @@ public class AccessUser extends GaeaBaseEntity {
/** 最后一次登陆时间 */ /** 最后一次登陆时间 */
private Date lastLoginTime; private Date lastLoginTime;
} }

@ -13,7 +13,7 @@ import java.util.Date;
* @author ·De <lide1202@hotmail.com> * @author ·De <lide1202@hotmail.com>
* @date 2019-02-17 08:50:11.902 * @date 2019-02-17 08:50:11.902
**/ **/
@TableName(value="access_user_role") @TableName(keepGlobalPrefix=true, value="access_user_role")
@Data @Data
public class AccessUserRole extends GaeaBaseEntity { public class AccessUserRole extends GaeaBaseEntity {
@ -37,4 +37,4 @@ public class AccessUserRole extends GaeaBaseEntity {
@TableField(exist = false) @TableField(exist = false)
private Integer version; private Integer version;
} }

@ -13,8 +13,10 @@ import com.anji.plus.gaea.utils.GaeaUtils;
import com.anji.plus.gaea.utils.JwtBean; import com.anji.plus.gaea.utils.JwtBean;
import com.anjiplus.template.gaea.business.code.ResponseCode; import com.anjiplus.template.gaea.business.code.ResponseCode;
import com.anjiplus.template.gaea.business.constant.BusinessConstant; import com.anjiplus.template.gaea.business.constant.BusinessConstant;
import com.anjiplus.template.gaea.business.modules.accessrole.dao.AccessRoleAuthorityMapper;
import com.anjiplus.template.gaea.business.modules.accessrole.dao.AccessRoleMapper; import com.anjiplus.template.gaea.business.modules.accessrole.dao.AccessRoleMapper;
import com.anjiplus.template.gaea.business.modules.accessrole.dao.entity.AccessRole; import com.anjiplus.template.gaea.business.modules.accessrole.dao.entity.AccessRole;
import com.anjiplus.template.gaea.business.modules.accessrole.dao.entity.AccessRoleAuthority;
import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.AccessUserDto; import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.AccessUserDto;
import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.GaeaUserDto; import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.GaeaUserDto;
import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.UpdatePasswordDto; import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.UpdatePasswordDto;
@ -31,10 +33,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -54,6 +53,9 @@ public class AccessUserServiceImpl implements AccessUserService {
@Autowired @Autowired
private AccessUserRoleMapper accessUserRoleMapper; private AccessUserRoleMapper accessUserRoleMapper;
@Autowired
private AccessRoleAuthorityMapper accessRoleAuthorityMapper;
@Value("${customer.user.default.password:'123456'}") @Value("${customer.user.default.password:'123456'}")
private String defaultPassword; private String defaultPassword;
@ -168,7 +170,24 @@ public class AccessUserServiceImpl implements AccessUserService {
// 4.读取用户最新人权限主信息 // 4.读取用户最新人权限主信息
String userKey = String.format(BusinessConstant.GAEA_SECURITY_LOGIN_USER, loginName); String userKey = String.format(BusinessConstant.GAEA_SECURITY_LOGIN_USER, loginName);
List<String> authorities = accessUserMapper.queryAuthoritiesByLoginName(loginName); //为了兼容底层其他数据库不再写自定义sql
// List<String> authorities = accessUserMapper.queryAuthoritiesByLoginName(loginName);
//当前用户的roleCode集合
LambdaQueryWrapper<AccessUserRole> accessUserWrapper = Wrappers.lambdaQuery();
accessUserWrapper.select(AccessUserRole::getRoleCode);
accessUserWrapper.eq(AccessUserRole::getLoginName, loginName);
List<AccessUserRole> accessUserRoles = accessUserRoleMapper.selectList(accessUserWrapper);
Set<String> roleCodeSet = accessUserRoles.stream().map(AccessUserRole::getRoleCode).collect(Collectors.toSet());
LambdaQueryWrapper<AccessRoleAuthority> accessRoleAuthorityWrapper = Wrappers.lambdaQuery();
accessRoleAuthorityWrapper.select(AccessRoleAuthority::getTarget, AccessRoleAuthority::getAction);
accessRoleAuthorityWrapper.in(AccessRoleAuthority::getRoleCode, roleCodeSet);
List<AccessRoleAuthority> accessRoleAuthorities = accessRoleAuthorityMapper.selectList(accessRoleAuthorityWrapper);
List<String> authorities = accessRoleAuthorities.stream()
.map(accessRoleAuthority -> accessRoleAuthority.getTarget().concat(":").concat(accessRoleAuthority.getAction())).distinct().collect(Collectors.toList());
gaeaUser.setLoginName(loginName); gaeaUser.setLoginName(loginName);
gaeaUser.setRealName(accessUser.getRealName()); gaeaUser.setRealName(accessUser.getRealName());
gaeaUser.setToken(token); gaeaUser.setToken(token);

@ -13,7 +13,7 @@ import lombok.Data;
* @author Raod * @author Raod
* @date 2021-04-12 14:52:21.761 * @date 2021-04-12 14:52:21.761
**/ **/
@TableName(value="gaea_report_dashboard") @TableName(keepGlobalPrefix=true, value="gaea_report_dashboard")
@Data @Data
public class ReportDashboard extends GaeaBaseEntity { public class ReportDashboard extends GaeaBaseEntity {
@ApiModelProperty(value = "报表编码") @ApiModelProperty(value = "报表编码")

@ -11,7 +11,7 @@ import lombok.Data;
* @author Raod * @author Raod
* @date 2021-04-12 15:12:43.724 * @date 2021-04-12 15:12:43.724
**/ **/
@TableName(value="gaea_report_dashboard_widget") @TableName(keepGlobalPrefix=true, value="gaea_report_dashboard_widget")
@Data @Data
public class ReportDashboardWidget extends GaeaBaseEntity { public class ReportDashboardWidget extends GaeaBaseEntity {
@ApiModelProperty(value = "报表编码") @ApiModelProperty(value = "报表编码")

@ -13,7 +13,7 @@ import lombok.Data;
* @author Raod * @author Raod
* @date 2021-03-18 12:11:31.150755900 * @date 2021-03-18 12:11:31.150755900
**/ **/
@TableName(value="gaea_report_data_set") @TableName(keepGlobalPrefix=true, value="gaea_report_data_set")
@Data @Data
public class DataSet extends GaeaBaseEntity { public class DataSet extends GaeaBaseEntity {
@ApiModelProperty(value = "数据集编码") @ApiModelProperty(value = "数据集编码")

@ -11,7 +11,7 @@ import lombok.Data;
* @author Raod * @author Raod
* @date 2021-03-18 12:12:33.108033200 * @date 2021-03-18 12:12:33.108033200
**/ **/
@TableName(value="gaea_report_data_set_param") @TableName(keepGlobalPrefix=true, value="gaea_report_data_set_param")
@Data @Data
public class DataSetParam extends GaeaBaseEntity { public class DataSetParam extends GaeaBaseEntity {
@ApiModelProperty(value = "数据集编码") @ApiModelProperty(value = "数据集编码")

@ -11,7 +11,7 @@ import lombok.Data;
* @author Raod * @author Raod
* @date 2021-03-18 12:13:15.591309400 * @date 2021-03-18 12:13:15.591309400
**/ **/
@TableName(value="gaea_report_data_set_transform") @TableName(keepGlobalPrefix=true, value="gaea_report_data_set_transform")
@Data @Data
public class DataSetTransform extends GaeaBaseEntity { public class DataSetTransform extends GaeaBaseEntity {
@ApiModelProperty(value = "数据集编码") @ApiModelProperty(value = "数据集编码")

@ -13,7 +13,7 @@ import lombok.Data;
* @author Raod * @author Raod
* @date 2021-03-18 12:09:57.728203200 * @date 2021-03-18 12:09:57.728203200
**/ **/
@TableName(value="gaea_report_data_source") @TableName(keepGlobalPrefix=true, value="gaea_report_data_source")
@Data @Data
public class DataSource extends GaeaBaseEntity { public class DataSource extends GaeaBaseEntity {
@ApiModelProperty(value = "数据源编码") @ApiModelProperty(value = "数据源编码")

@ -33,11 +33,9 @@ import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.sql.Connection; import java.sql.*;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -243,7 +241,9 @@ public class DataSourceServiceImpl implements DataSourceService {
columns.forEach(t -> { columns.forEach(t -> {
try { try {
Object value = rs.getObject(t); Object value = rs.getObject(t);
jo.put(t, value); //数据类型转换
Object result = dealResult(value);
jo.put(t, result);
} catch (SQLException throwable) { } catch (SQLException throwable) {
log.error("error",throwable); log.error("error",throwable);
throw BusinessExceptionBuilder.build(ResponseCode.EXECUTE_SQL_ERROR, throwable.getMessage()); throw BusinessExceptionBuilder.build(ResponseCode.EXECUTE_SQL_ERROR, throwable.getMessage());
@ -267,6 +267,26 @@ public class DataSourceServiceImpl implements DataSourceService {
} }
} }
/**
* sql
* (through reference chain: java.util.HashMap["pageData"]->java.util.ArrayList[0]->java.util.HashMap["UPDATE_TIME"]->oracle.sql.TIMESTAMP["stream"])
* @param result
* @return
* @throws SQLException
*/
private Object dealResult(Object result) throws SQLException {
if (null == result) {
return result;
}
String type = result.getClass().getName();
if ("oracle.sql.TIMESTAMP".equals(type)) {
//oracle.sql.TIMESTAMP处理逻辑
return new Date((Long) JSONObject.toJSON(result));
}
return result;
}
/** /**
* http * http
* *

@ -13,7 +13,7 @@ import java.io.Serializable;
* @author lr * @author lr
* @since 2021-02-23 10:01:02 * @since 2021-02-23 10:01:02
*/ */
@TableName("gaea_dict") @TableName(keepGlobalPrefix=true, value = "gaea_dict")
public class GaeaDict extends GaeaBaseEntity implements Serializable { public class GaeaDict extends GaeaBaseEntity implements Serializable {
/** /**
* *

@ -15,7 +15,7 @@ import java.io.Serializable;
* @author lirui * @author lirui
* @since 2021-03-09 15:52:41 * @since 2021-03-09 15:52:41
*/ */
@TableName("gaea_dict_item") @TableName(keepGlobalPrefix=true,value = "gaea_dict_item")
@UnionUniqueCode(group = BusinessConstant.DICT_ITEM_EXIST_GROUP, code = ResponseCode.DICT_ITEM_REPEAT) @UnionUniqueCode(group = BusinessConstant.DICT_ITEM_EXIST_GROUP, code = ResponseCode.DICT_ITEM_REPEAT)
public class GaeaDictItem extends GaeaBaseEntity implements Serializable { public class GaeaDictItem extends GaeaBaseEntity implements Serializable {

@ -13,7 +13,7 @@ import java.io.Serializable;
* @author peiyanni * @author peiyanni
* @since 2021-02-18 14:48:20 * @since 2021-02-18 14:48:20
*/ */
@TableName("gaea_file") @TableName(keepGlobalPrefix=true, value = "gaea_file")
@Data @Data
public class GaeaFile extends GaeaBaseEntity implements Serializable { public class GaeaFile extends GaeaBaseEntity implements Serializable {

@ -13,7 +13,7 @@ import lombok.Data;
* @author chenkening * @author chenkening
* @date 2021/3/26 10:20 * @date 2021/3/26 10:20
*/ */
@TableName(value="gaea_report") @TableName(keepGlobalPrefix=true, value="gaea_report")
@Data @Data
public class Report extends GaeaBaseEntity { public class Report extends GaeaBaseEntity {

@ -53,4 +53,9 @@ public class ReportShareDto extends GaeaBaseDTO implements Serializable {
@ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG") @ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG")
private Integer deleteFlag; private Integer deleteFlag;
/** 分享码 */
private String sharePassword;
private boolean sharePasswordFlag = false;
} }

@ -1,18 +1,18 @@
package com.anjiplus.template.gaea.business.modules.reportshare.dao.entity; package com.anjiplus.template.gaea.business.modules.reportshare.dao.entity;
import lombok.Data;
import io.swagger.annotations.ApiModelProperty;
import com.anji.plus.gaea.curd.entity.GaeaBaseEntity; import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import javax.validation.constraints.*; import lombok.Data;
import java.util.Date; import java.util.Date;
/** /**
* @description entity * @description entity
* @author Raod * @author Raod
* @date 2021-08-18 13:37:26.663 * @date 2021-08-18 13:37:26.663
**/ **/
@TableName(value="gaea_report_share") @TableName(keepGlobalPrefix=true, value="gaea_report_share")
@Data @Data
public class ReportShare extends GaeaBaseEntity { public class ReportShare extends GaeaBaseEntity {
/** 分享编码系统生成默认UUID */ /** 分享编码系统生成默认UUID */
@ -39,5 +39,12 @@ public class ReportShare extends GaeaBaseEntity {
/** 0--未删除 1--已删除 DIC_NAME=DELETE_FLAG */ /** 0--未删除 1--已删除 DIC_NAME=DELETE_FLAG */
private Integer deleteFlag; private Integer deleteFlag;
/** 分享码 */
@TableField(exist = false)
private String sharePassword;
@TableField(exist = false)
private boolean sharePasswordFlag;
} }

@ -13,9 +13,11 @@ import com.anjiplus.template.gaea.business.modules.reportshare.dao.entity.Report
import com.anjiplus.template.gaea.business.modules.reportshare.service.ReportShareService; import com.anjiplus.template.gaea.business.modules.reportshare.service.ReportShareService;
import com.anjiplus.template.gaea.business.util.DateUtil; import com.anjiplus.template.gaea.business.util.DateUtil;
import com.anjiplus.template.gaea.business.util.JwtUtil; import com.anjiplus.template.gaea.business.util.JwtUtil;
import com.anjiplus.template.gaea.business.util.MD5Util;
import com.anjiplus.template.gaea.business.util.UuidUtil; import com.anjiplus.template.gaea.business.util.UuidUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -51,12 +53,18 @@ public class ReportShareServiceImpl implements ReportShareService {
@Override @Override
public ReportShareDto insertShare(ReportShareDto dto) { public ReportShareDto insertShare(ReportShareDto dto) {
//设置分享码
if (dto.isSharePasswordFlag()) {
dto.setSharePassword(UuidUtil.getRandomPwd(4));
}
ReportShareDto reportShareDto = new ReportShareDto(); ReportShareDto reportShareDto = new ReportShareDto();
ReportShare entity = new ReportShare(); ReportShare entity = new ReportShare();
BeanUtils.copyProperties(dto, entity); BeanUtils.copyProperties(dto, entity);
insert(entity); insert(entity);
//将分享链接返回 //将分享链接返回
reportShareDto.setShareUrl(entity.getShareUrl()); reportShareDto.setShareUrl(entity.getShareUrl());
reportShareDto.setSharePassword(dto.getSharePassword());
return reportShareDto; return reportShareDto;
} }
@ -69,6 +77,12 @@ public class ReportShareServiceImpl implements ReportShareService {
if (null == reportShare) { if (null == reportShare) {
throw BusinessExceptionBuilder.build(ResponseCode.REPORT_SHARE_LINK_INVALID); throw BusinessExceptionBuilder.build(ResponseCode.REPORT_SHARE_LINK_INVALID);
} }
//解析jwt token获取密码
String password = JwtUtil.getPassword(reportShare.getShareToken());
if (StringUtils.isNotBlank(password)) {
//md5加密返回
reportShare.setSharePassword(MD5Util.encrypt(password));
}
return reportShare; return reportShare;
} }
@ -101,7 +115,8 @@ public class ReportShareServiceImpl implements ReportShareService {
} else { } else {
entity.setShareUrl(entity.getShareUrl() + SHARE_FLAG + shareCode); entity.setShareUrl(entity.getShareUrl() + SHARE_FLAG + shareCode);
} }
entity.setShareValidTime(DateUtil.getFutureDateTmdHms(entity.getShareValidType())); entity.setShareValidTime(DateUtil.getFutureDateTmdHms(entity.getShareValidType()));
entity.setShareToken(JwtUtil.createToken(entity.getReportCode(), shareCode, entity.getShareValidTime())); entity.setShareToken(JwtUtil.createToken(entity.getReportCode(), shareCode, entity.getSharePassword(), entity.getShareValidTime()));
} }
} }

@ -7,6 +7,7 @@ import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim; import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.lang3.StringUtils;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
@ -19,11 +20,16 @@ public class JwtUtil {
private static final String JWT_SECRET = "aj-report"; private static final String JWT_SECRET = "aj-report";
public static String createToken(String reportCode, String shareCode, Date expires) { public static String createToken(String reportCode, String shareCode, Date expires) {
return createToken(reportCode, shareCode, null, expires);
}
public static String createToken(String reportCode, String shareCode, String password, Date expires) {
String token = JWT.create() String token = JWT.create()
.withIssuedAt(new Date()) .withIssuedAt(new Date())
.withExpiresAt(expires) .withExpiresAt(expires)
.withClaim("reportCode", reportCode) .withClaim("reportCode", reportCode)
.withClaim("shareCode", shareCode) .withClaim("shareCode", shareCode)
.withClaim("sharePassword", password)
.sign(Algorithm.HMAC256(JWT_SECRET)); .sign(Algorithm.HMAC256(JWT_SECRET));
return token; return token;
} }
@ -55,4 +61,15 @@ public class JwtUtil {
return claim.asString(); return claim.asString();
} }
public static String getPassword(String token) {
Claim claim = getClaim(token).get("sharePassword");
if (null == claim) {
return null;
}
if (StringUtils.isNotBlank(claim.asString())) {
return claim.asString();
}
return null;
}
} }

@ -1,5 +1,6 @@
package com.anjiplus.template.gaea.business.util; package com.anjiplus.template.gaea.business.util;
import java.security.SecureRandom;
import java.util.UUID; import java.util.UUID;
/** /**
@ -31,6 +32,24 @@ public class UuidUtil {
} }
/**
*
* @param num
* @return
*/
public static String getRandomPwd(int num) {
StringBuilder builder = new StringBuilder();
// 因为已经把 4 种字符放进list了所以 i 取值从 4开始
// 产生随机数用于随机调用生成字符的函数
for (int i = 0; i < num; i++) {
SecureRandom random = new SecureRandom();
int funNum = random.nextInt(chars.length);
builder.append(chars[funNum]);
}
return builder.toString().toLowerCase();
}
public static String generateUuid() { public static String generateUuid() {
return UUID.randomUUID().toString().replace("-", ""); return UUID.randomUUID().toString().replace("-", "");
@ -38,7 +57,9 @@ public class UuidUtil {
public static void main(String[] args) { public static void main(String[] args) {
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
System.out.println(generateShortUuid()); // System.out.println(generateShortUuid());
System.out.println(getRandomPwd(4));
} }
} }
} }

@ -37,6 +37,7 @@ spring:
breakAfterAcquireFailure: true # 数据库服务宕机自动重连机制 breakAfterAcquireFailure: true # 数据库服务宕机自动重连机制
timeBetweenConnectErrorMillis: 300000 # 连接出错后重试时间间隔 timeBetweenConnectErrorMillis: 300000 # 连接出错后重试时间间隔
flyway: flyway:
enabled: true #是否开启flyway默认true.
baseline-on-migrate: true baseline-on-migrate: true
#数据库连接配置 #数据库连接配置
url: ${spring.datasource.url} url: ${spring.datasource.url}
@ -48,7 +49,7 @@ spring:
mybatis-plus: mybatis-plus:
configuration: configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql打印
call-setters-on-nulls: true call-setters-on-nulls: true
mapperLocations: mapperLocations:
- classpath*:/mapper/**/*.xml - classpath*:/mapper/**/*.xml

@ -30,3 +30,17 @@ export function validatAlphabets(str) {
const reg = /^[A-Za-z]+$/ const reg = /^[A-Za-z]+$/
return reg.test(str) return reg.test(str)
} }
/*验证内容是否英文数字以及下划线*/
export function validateEngOrNum(rule, value, callback) {
const reg =/^[_a-zA-Z0-9]+$/;
if(value==''||value==undefined||value==null){
callback();
} else {
if (!reg.test(value)){
callback(new Error('英文字母、数字或下划线'));
} else {
callback();
}
}
}

@ -6,6 +6,18 @@
!--> !-->
<template> <template>
<div> <div>
<el-dialog
title="请输入分享码"
:visible.sync="dialogVisible"
width="30%"
:close-on-click-modal="false"
:before-close="handleClose">
<el-input v-model="password" placeholder="请输入分享码"></el-input>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="checkPassword()"> </el-button>
</span>
</el-dialog>
</div> </div>
</template> </template>
@ -18,7 +30,11 @@ export default {
}, },
data() { data() {
return { return {
password: '',
sharePassword: '',
dialogVisible: false,
reportCode: '',
shareToken: ''
}; };
}, },
@ -33,18 +49,46 @@ export default {
const {code, data} = await reportShareDetailByCode(shareCode) const {code, data} = await reportShareDetailByCode(shareCode)
if (code != '200') return if (code != '200') return
setShareToken(data.shareToken) console.log(data)
//shareToken this.reportCode = data.reportCode
// this.sharePassword = data.sharePassword
this.shareToken = data.shareToken
if (this.sharePassword) {
console.log(this.sharePassword)
this.dialogVisible = true
}else {
this.pushAj()
}
},
checkPassword(){
const md5 = require('js-md5')
const inputPassword = md5(this.password);
console.log(this.password +'--------------'+inputPassword + "--------" + this.sharePassword)
if (inputPassword == this.sharePassword) {
this.pushAj()
}else {
this.$message.error('分享码输入不正确')
}
},
pushAj(){
setShareToken(this.shareToken)
this.$router.push({ this.$router.push({
path: '/bigscreen/viewer', path: '/bigscreen/viewer',
query: { query: {
reportCode: data.reportCode reportCode: this.reportCode
}, },
}) })
}, },
handleClose(done) {
this.$confirm('确认关闭?')
.then(_ => {
done();
})
.catch(_ => {});
}
} }
}; };
</script> </script>

@ -44,6 +44,7 @@
import { testConnection, reportDataSourceDetail, reportDataSourceAdd, reportDataSourceUpdate } from '@/api/reportDataSource' import { testConnection, reportDataSourceDetail, reportDataSourceAdd, reportDataSourceUpdate } from '@/api/reportDataSource'
import { getDictList } from '@/api/dict-data' // import { getDictList } from '@/api/dict-data' //
import Dictionary from '@/components/Dictionary/index' import Dictionary from '@/components/Dictionary/index'
import {validateEngOrNum} from "@/utils/validate";
export default { export default {
name: 'Support', name: 'Support',
components: { Dictionary }, components: { Dictionary },
@ -97,6 +98,7 @@ export default {
], ],
sourceCode: [ sourceCode: [
{ required: true, message: '数据集编码必填', trigger: 'blur' }, { required: true, message: '数据集编码必填', trigger: 'blur' },
{ validator: validateEngOrNum, trigger: 'blur' },
], ],
sourceName: [ sourceName: [
{ required: true, message: '数据源名称必选', trigger: 'blur' }, { required: true, message: '数据源名称必选', trigger: 'blur' },

@ -11,19 +11,40 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="10">
<el-col :xs="24" :sm="20" :md="6" :lg="6" :xl="6">
<el-form-item label="分享码" prop="sharePasswordFlag">
<el-switch
v-model="dialogForm.sharePasswordFlag">
</el-switch>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<el-button type="primary" plain @click="createShare"></el-button> <el-button type="primary" plain @click="createShare"></el-button>
</div> </div>
<div v-else> <div v-else>
<el-row :gutter="10"> <el-form ref="userForm" :model="dialogForm" :rules="rules" size="small" label-width="100px">
<el-col :xs="24" :sm="20" :md="20" :lg="20" :xl="16"> <el-row :gutter="10">
<el-input v-model="reportShareUrl" :disabled="true"/> <el-col :xs="24" :sm="20" :md="20" :lg="20" :xl="16">
</el-col> <el-form-item label="链接" prop="reportShareUrl">
</el-row> <el-input v-model="reportShareUrl" :disabled="true"/>
<el-row :gutter="10"> </el-form-item>
<el-button type="primary" plain @click="copyShare"></el-button> </el-col>
</el-row>
<el-row :gutter="10" v-if="dialogForm.sharePassword != ''">
<el-col :xs="24" :sm="20" :md="6" :lg="6" :xl="6">
<el-form-item label="分享码" prop="sharePassword">
<el-input v-model="dialogForm.sharePassword" :disabled="true"/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10">
<el-button v-if="dialogForm.sharePassword == ''" type="primary" plain @click="copyShare"></el-button>
<el-button v-if="dialogForm.sharePassword != ''" type="primary" plain @click="copyShare"></el-button>
</el-row> </el-row>
</el-form>
</div> </div>
<div slot="footer" style="text-align: center"> <div slot="footer" style="text-align: center">
@ -71,6 +92,8 @@ export default {
reportCode: '', reportCode: '',
shareUrl: '', shareUrl: '',
shareCode: '', shareCode: '',
sharePassword: '',
sharePasswordFlag: false,
}, },
shareLinkFlag1: true, shareLinkFlag1: true,
rules: { rules: {
@ -103,24 +126,33 @@ export default {
if (code != '200') return if (code != '200') return
this.shareValidTypeOptions = data this.shareValidTypeOptions = data
this.dialogForm.shareValidType = this.shareValidTypeOptions[0].id this.dialogForm.shareValidType = this.shareValidTypeOptions[0].id
this.dialogForm.sharePasswordFlag = false
this.dialogForm.sharePassword = ''
}, },
async createShare() { async createShare() {
this.dialogForm.reportCode = this.reportCode this.dialogForm.reportCode = this.reportCode
this.dialogForm.shareUrl = window.location.href this.dialogForm.shareUrl = window.location.href
console.log(this.dialogForm) // console.log(this.dialogForm)
const {code, data} = await reportShareAdd(this.dialogForm) const {code, data} = await reportShareAdd(this.dialogForm)
if (code != '200') return if (code != '200') return
console.log(data) // console.log(data)
this.shareLinkFlag1 = false this.shareLinkFlag1 = false
this.$message({ this.$message({
message: '创建链接成功!', message: '创建链接成功!',
type: 'success', type: 'success',
}) })
this.reportShareUrl = data.shareUrl this.reportShareUrl = data.shareUrl
this.dialogForm.sharePassword = data.sharePassword
}, },
copyShare(){ copyShare(){
this.copyToClip(this.reportShareUrl) let content = ''
if (this.dialogForm.sharePassword == '') {
content = 'AJ-Report分享链接' + this.reportShareUrl
}else {
content = 'AJ-Report分享链接' + this.reportShareUrl + ' 分享码:' + this.dialogForm.sharePassword;
}
this.copyToClip(content)
this.$message({ this.$message({
message: '复制链接成功!', message: '复制链接成功!',
type: 'success', type: 'success',

@ -46,6 +46,7 @@ import {
reportDetail reportDetail
} from "@/api/reportmanage"; } from "@/api/reportmanage";
import Share from "@/views/report/report/components/share"; import Share from "@/views/report/report/components/share";
import {validateEngOrNum} from "@/utils/validate";
export default { export default {
name: "Report", name: "Report",
components: { components: {
@ -131,7 +132,8 @@ export default {
editField: "reportCode", editField: "reportCode",
inputType: "input", inputType: "input",
rules: [ rules: [
{ min: 1, max: 100, message: "不超过100个字符", trigger: "blur" } { min: 1, max: 100, message: "不超过100个字符", trigger: "blur" },
{ validator: validateEngOrNum, trigger: 'blur' },
], ],
disabled: "disableOnEdit" disabled: "disableOnEdit"
}, },

@ -1,8 +1,10 @@
<template> <template>
<el-dialog <el-dialog
:title="caseResultTitle" :title="caseResultTitle"
:close-on-click-modal="false"
:visible.sync="visib" :visible.sync="visib"
width="70%" width="70%"
:before-close="closeDialog"
> >
<vue-json-editor <vue-json-editor
v-model="caseResultContent" v-model="caseResultContent"

@ -208,6 +208,7 @@
<el-dialog <el-dialog
:title="dialogTitle" :title="dialogTitle"
:visible.sync="dialogSwitchVisible" :visible.sync="dialogSwitchVisible"
:close-on-click-modal="false"
width="60%" width="60%"
min-height="400px" min-height="400px"
append-to-body append-to-body
@ -345,6 +346,7 @@
<el-dialog <el-dialog
:title="title" :title="title"
:visible.sync="dialogPermissionVisible" :visible.sync="dialogPermissionVisible"
:close-on-click-modal="false"
width="60%" width="60%"
> >
<div class="codemirror"> <div class="codemirror">
@ -383,6 +385,7 @@ import "codemirror/lib/codemirror.css"; // 核心样式
import "codemirror/theme/cobalt.css"; // options import "codemirror/theme/cobalt.css"; // options
import vueJsonEditor from "vue-json-editor"; import vueJsonEditor from "vue-json-editor";
import MonacoEditor from "./MonacoEditor.vue"; import MonacoEditor from "./MonacoEditor.vue";
import {validateEngOrNum} from "@/utils/validate";
export default { export default {
name: "Support", name: "Support",
components: { Dictionary, codemirror, vueJsonEditor, MonacoEditor }, components: { Dictionary, codemirror, vueJsonEditor, MonacoEditor },
@ -469,7 +472,8 @@ export default {
{ required: true, message: "数据集名称必填", trigger: "blur" } { required: true, message: "数据集名称必填", trigger: "blur" }
], ],
setCode: [ setCode: [
{ required: true, message: "数据集编码必填", trigger: "blur" } { required: true, message: "数据集编码必填", trigger: "blur" },
{ validator: validateEngOrNum, trigger: 'blur' },
], ],
sourceCode: [ sourceCode: [
{ required: true, message: "数据源必选", trigger: "change" } { required: true, message: "数据源必选", trigger: "change" }

Loading…
Cancel
Save