Commit ca3ae0e4 by fengshuonan

升级企业版

parent 858e99ad
# Guns最新企业版(单体版)
\ No newline at end of file
# Guns企业版
\ No newline at end of file
目前只有单体增强企业版(1599)才有oracle,sql server,pgsql的数据库支持,其他版本不提供!
Guns默认用mysql作为主要数据源!
目前只有单体增强企业版(1599)才有oracle,sql server,pgsql的数据库支持,其他版本不提供!
目前只有单体增强企业版(1599)才有oracle,sql server,pgsql的数据库支持,其他版本不提供!
目前只有单体增强企业版(1599)才有oracle,sql server,pgsql的数据库支持,其他版本不提供!
\ No newline at end of file
Guns默认用mysql作为主要数据源!
其他数据库会定期适配!
oracle最近适配日期:2019年11月28日
sql server最近适配日期:2019年11月28日
pgsql最近适配日期:2019年11月28日
如果是mysql数据库:
1.先执行guns_mysql.sql
2.再执行guns_mysql_activiti.sql
如果是其他数据库:
1.先运行guns_xxx.sql
2.工作流的数据库初始化,从ActivitiConfig类中打开这两行代码
config.setDatabaseType(DATABASE_TYPE_XXXXX);
config.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
guns_mysql_api.sql这个用在单体前后端分离的项目上!
\ No newline at end of file
......@@ -24,9 +24,12 @@ public enum AuthExceptionEnum implements AbstractBaseExceptionEnum {
VALID_CODE_ERROR(1406, "验证码错误"),
NO_PERMISSION(1500, "没有权限访问资源"),
//用在PermissonException
NO_PERMISSION(1500, "登录已过期,请重新登录"),
SESSION_TIMEOUT(1501, "登录会话超时");
NO_PAGE_ERROR(1502, "请求接口不存在或用户未登录"),
LOGIN_TIMEOUT(409, "登录超时,请重新登录!");
AuthExceptionEnum(int code, String message) {
this.code = code;
......
......@@ -65,7 +65,7 @@ public class JwtPayLoad {
JwtPayLoad jwtPayLoad = new JwtPayLoad();
Object userId = map.get("userId");
if (userId instanceof Integer) {
if (userId instanceof Long) {
jwtPayLoad.setUserId(Long.valueOf(map.get("userId").toString()));
}
......
......@@ -17,11 +17,13 @@ package cn.stylefeng.guns.base.auth.model;
import cn.stylefeng.roses.core.util.ToolUtil;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.io.Serializable;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 当前登录用户信息
......@@ -105,12 +107,11 @@ public class LoginUser implements UserDetails, Serializable {
private String tenantDataSourceName;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
ArrayList<GrantedAuthority> grantedAuthorities = new ArrayList<>();
public List<MyRole> getAuthorities() {
ArrayList<MyRole> grantedAuthorities = new ArrayList<>();
if (ToolUtil.isNotEmpty(this.roleNames)) {
for (String roleName : this.roleNames) {
GrantedAuthority grantedAuthority = (GrantedAuthority) () -> roleName;
grantedAuthorities.add(grantedAuthority);
grantedAuthorities.add(new MyRole(roleName));
}
}
return grantedAuthorities;
......
package cn.stylefeng.guns.base.auth.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
@Data
@AllArgsConstructor
public class MyRole implements GrantedAuthority {
private String roleName;
@Override
public String getAuthority() {
return roleName;
}
}
\ No newline at end of file
package cn.stylefeng.guns.email.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import cn.stylefeng.guns.email.provider.MailServiceProvider;
/**
* 邮件服务的配置
*
* @author fengshuonan
* @Date 2018/7/6 下午3:24
*/
@Configuration
public class ServiceAutoConfiguration {
@Bean
public MailServiceProvider mailServiceProvider() {
return new MailServiceProvider();
}
}
\ No newline at end of file
package cn.stylefeng.guns.email.core.enums;
import cn.stylefeng.roses.kernel.model.exception.AbstractBaseExceptionEnum;
/**
* 邮件发送失败的异常枚举
*
* @author stylefeng
* @Date 2018年07月08日18:39:47
*/
public enum MailSendResultEnum implements AbstractBaseExceptionEnum {
MAIL_SEND_ERROR(500, "邮件发送失败");
MailSendResultEnum(int code, String message) {
this.code = code;
this.message = message;
}
private Integer code;
private String message;
@Override
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
package cn.stylefeng.guns.email.core.exception;
/**
* 邮件发送异常
*
* @author fengshuonan
* @date 2018-07-06-下午3:00
*/
public class MailException extends RuntimeException {
private String code;
private String errorMessage;
public MailException(String code, String errorMessage) {
super(errorMessage);
this.code = code;
this.errorMessage = errorMessage;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
package cn.stylefeng.guns.email.core.mail.service;
import cn.stylefeng.guns.email.core.enums.MailSendResultEnum;
import cn.stylefeng.guns.email.core.mail.MailManager;
import cn.stylefeng.guns.email.core.model.SendMailParam;
import cn.stylefeng.roses.kernel.model.exception.RequestEmptyException;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import cn.stylefeng.roses.kernel.model.util.ValidateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
/**
* java默认的邮件发送方式实现
*
* @author fengshuonan
* @date 2018-07-08-下午3:34
*/
@Service
@Slf4j
public class JavaMailManager implements MailManager {
@Autowired
private JavaMailSender javaMailSender;
@Value("${mail.from}")
private String from;
@Override
public void sendMail(SendMailParam sendMailParam) {
//校验发送邮件的参数
assertSendMailParams(sendMailParam);
log.info("参数校验成功。。。。");
//spring发送邮件
try {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
mimeMessageHelper.setFrom(from);
mimeMessageHelper.setTo(sendMailParam.getTo());
mimeMessageHelper.setSubject(sendMailParam.getTitle());
mimeMessageHelper.setText(sendMailParam.getContent(), true);
javaMailSender.send(mimeMessage);
} catch (MessagingException e) {
log.error("发送邮件异常", e);
throw new ServiceException(MailSendResultEnum.MAIL_SEND_ERROR);
}
}
/**
* 校验发送邮件的请求参数
*
* @author fengshuonan
* @Date 2018/7/8 下午6:41
*/
private void assertSendMailParams(SendMailParam sendMailParam) {
if (sendMailParam == null ||
ValidateUtil.isOneEmpty(
sendMailParam.getTo(), sendMailParam.getTitle(), sendMailParam.getContent())) {
throw new RequestEmptyException();
}
}
}
package cn.stylefeng.guns.email.provider;
import cn.stylefeng.guns.email.core.model.SendMailParam;
/**
* 邮件发送的api
*
* @author fengshuonan
* @date 2018-07-08-下午3:47
*/
public interface MailServiceApi {
/**
* 发送邮件
*
* @author fengshuonan
* @Date 2018/7/8 下午6:28
*/
void sendMail(SendMailParam sendMailParam);
}
package cn.stylefeng.guns.email.provider;
import cn.stylefeng.guns.email.core.mail.MailManager;
import cn.stylefeng.guns.email.core.model.SendMailParam;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* 短信通知接口
*
* @author stylefeng
* @Date 2018/7/5 21:05
*/
public class MailServiceProvider implements MailServiceApi {
private static Logger logger = LoggerFactory.getLogger(MailServiceProvider.class);
@Autowired
private MailManager mailManager;
@Override
public void sendMail(SendMailParam sendMailParam) {
logger.info("email调用入参:" + JSONObject.toJSON(sendMailParam).toString());
mailManager.sendMail(sendMailParam);
}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.stylefeng.guns.email.config.ServiceAutoConfiguration
\ No newline at end of file
package cn.stylefeng.guns.sms.config;
import cn.stylefeng.guns.sms.core.db.SmsInfoInitizlizer;
import cn.stylefeng.guns.sms.core.sms.SmsManager;
import cn.stylefeng.guns.sms.core.sms.service.AliyunSmsManager;
import cn.stylefeng.guns.sms.modular.provider.SmsServiceProvider;
import cn.stylefeng.guns.sms.modular.service.SmsInfoService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 短信服务的配置
*
* @author fengshuonan
* @Date 2018/7/6 下午3:24
*/
@Configuration
public class ServiceAutoConfiguration {
@Bean
public SmsServiceProvider smsServiceProvider() {
return new SmsServiceProvider();
}
@Bean
public SmsInfoService smsInfoService() {
return new SmsInfoService();
}
@Bean
public SmsManager smsManager() {
return new AliyunSmsManager();
}
@Bean
public SmsInfoInitizlizer smsInfoInitizlizer() {
return new SmsInfoInitizlizer();
}
}
\ No newline at end of file
package cn.stylefeng.guns.sms.config;
import cn.stylefeng.guns.sms.core.cache.impl.MapSignManager;
import cn.stylefeng.guns.sms.core.sms.service.AliyunSmsManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* aliyun短信发送的配置
*
* @author fengshuonan
* @Date 2018/7/6 下午3:24
*/
@Configuration
public class SmsAutoConfiguration {
/**
* 短信发送管理器
*
* @author fengshuonan
* @Date 2018/9/21 上午10:07
*/
@Bean
public AliyunSmsManager aliyunSmsManager() {
return new AliyunSmsManager();
}
/**
* 缓存的管理
*
* @author fengshuonan
* @Date 2018/9/21 上午10:59
*/
@Bean
public MapSignManager mapSignManager() {
return new MapSignManager();
}
}
\ No newline at end of file
package cn.stylefeng.guns.sms.core.cache;
/**
* 多个签名的缓存管理
*
* @author fengshuonan
* @date 2018-09-21-上午10:47
*/
public interface MultiSignManager {
/**
* 获取签名
*
* @param phone 电话
* @param signName 发送短信用的签名,是一个以逗号隔开的字符串
* @author fengshuonan
* @Date 2018/9/21 上午10:51
*/
String getSign(String phone, String signName);
}
package cn.stylefeng.guns.sms.core.cache.impl;
import cn.stylefeng.guns.sms.core.cache.MultiSignManager;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 使用map缓存的实现
*
* @author fengshuonan
* @date 2018-09-21-上午10:49
*/
@Slf4j
public class MapSignManager implements MultiSignManager {
private static final Long EXPIRED_TIME = 86400L;
private Map<String, String> cacheMap = new ConcurrentHashMap<>();
@Override
public String getSign(String phone, String signName) {
clearMap();
String[] signNames = signName.split(",");
//获取上次发送的时候用的哪个签名,这次换一个
Object lastSignName = cacheMap.get(phone);
if (lastSignName == null) {
cacheMap.put(phone, signNames[0]);
log.info("发送短信,签名为:" + signNames[0] + ",电话为:" + phone);
return signNames[0];
} else {
for (String name : signNames) {
if (!name.equals(lastSignName)) {
cacheMap.put(phone, name);
log.info("发送短信,签名为:" + name + ",电话为:" + phone);
return name;
}
}
cacheMap.put(phone, signNames[0]);
log.info("发送短信,签名为:" + signNames[0] + ",电话为:" + phone);
return signNames[0];
}
}
/**
* 每隔一段时间清除下map
*
* @author fengshuonan
* @Date 2018/9/21 上午10:57
*/
private void clearMap() {
if (cacheMap.size() >= 1000) {
cacheMap.clear();
}
}
}
package cn.stylefeng.guns.sms.core.db;
import cn.stylefeng.guns.sms.modular.entity.SmsInfo;
import cn.stylefeng.roses.core.db.DbInitializer;
/**
* 短信发送表的初始化程序
*
* @author fengshuonan
* @date 2018-07-30-上午9:29
*/
public class SmsInfoInitizlizer extends DbInitializer {
@Override
public String getTableInitSql() {
return "CREATE TABLE `sms_info` (\n" +
" `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',\n" +
" `PHONE_NUMBERS` varchar(200) COLLATE utf8_bin NOT NULL COMMENT '手机号',\n" +
" `VALIDATE_CODE` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '短信验证码',\n" +
" `TEMPLATE_CODE` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '短信模板ID',\n" +
" `BIZID` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '回执ID,可根据该ID查询具体的发送状态',\n" +
" `STATUS` smallint(3) NOT NULL COMMENT '0=未发送,1=发送成功,2=发送失败,3=失效',\n" +
" `SOURCE` smallint(3) NOT NULL COMMENT '0=app,1=pc,2=其它',\n" +
" `INVALID_TIME` timestamp NULL DEFAULT NULL COMMENT '失效时间',\n" +
" `MODIFY_TIME` timestamp NULL DEFAULT NULL COMMENT '修改时间',\n" +
" `CREATE_TIME` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n" +
" PRIMARY KEY (`ID`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='短信信息发送表'";
}
@Override
public String getTableName() {
return "sms_info";
}
@Override
public Class<?> getEntityClass() {
return SmsInfo.class;
}
}
package cn.stylefeng.guns.sms.core.enums;
/**
* 消息类型
*
* @author stylefeng
* @Date 2018年5月6日 12:30:48
*/
public enum MessageType {
SMS(1, "验证类消息"),
MESSAGE(2, "纯发送消息");
private Integer code;
private String desc;
MessageType(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
package cn.stylefeng.guns.sms.core.enums;
/**
* core模块的异常集合
*
* @author stylefeng
* @Date 2018/1/4 22:40
*/
public enum SmsResultEnum {
INIT_SMS_CLIENT_ERROR("SMS_CLIENT_INIT_ERROR", "初始化sms客户端错误,accessKey错误"),
PARAM_NULL("NULL", "请求参数为空"),
OK("OK", "请求成功"),
RAM_PERMISSION_DENY("isp.RAM_PERMISSION_DENY", "RAM权限DENY"),
PRODUCT_UNSUBSCRIBE("isv.PRODUCT_UNSUBSCRIBE", "产品未开通"),
ACCOUNT_NOT_EXISTS("isv.ACCOUNT_NOT_EXISTS", "账户不存在"),
ACCOUNT_ABNORMAL("isv.ACCOUNT_ABNORMAL", "账户异常"),
SMS_TEMPLATE_ILLEGAL("isv.SMS_TEMPLATE_ILLEGAL", "短信模板不合法"),
SMS_SIGNATURE_ILLEGAL("isv.SMS_SIGNATURE_ILLEGAL", "短信签名不合法"),
INVALID_PARAMETERS("isv.INVALID_PARAMETERS", "参数异常"),
SYSTEM_ERROR("isp.SYSTEM_ERROR", "系统错误"),
MOBILE_NUMBER_ILLEGAL("isv.MOBILE_NUMBER_ILLEGAL", "非法手机号"),
MOBILE_COUNT_OVER_LIMIT("isv.MOBILE_COUNT_OVER_LIMIT", "手机号码数量超过限制"),
TEMPLATE_MISSING_PARAMETERS("isv.TEMPLATE_MISSING_PARAMETERS", "模板缺少变量"),
BUSINESS_LIMIT_CONTROL("isv.BUSINESS_LIMIT_CONTROL", "发送短信过于频繁,请稍后再试"),
INVALID_JSON_PARAM("isv.INVALID_JSON_PARAM", "JSON参数不合法,只接受字符串值"),
BLACK_KEY_CONTROL_LIMIT("isv.BLACK_KEY_CONTROL_LIMIT", "黑名单管控"),
PARAM_LENGTH_LIMIT("isv.PARAM_LENGTH_LIMIT", "参数超出长度限制"),
PARAM_NOT_SUPPORT_URL("isv.PARAM_NOT_SUPPORT_URL", "不支持URL"),
AMOUNT_NOT_ENOUGH("isv.AMOUNT_NOT_ENOUGH", "账户余额不足");
SmsResultEnum(String code, String message) {
this.code = code;
this.message = message;
}
private String code;
private String message;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
package cn.stylefeng.guns.sms.core.enums;
/**
* 短信发送业务枚举
*
* @author stylefeng
* @Date 2018年5月6日 12:30:48
*/
public enum SmsSendSource {
WEB(0),
PC(1),
OTHER(2);
private Integer code;
SmsSendSource(Integer code) {
this.code = code;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public static SmsSendSource toEnum(Integer type) {
if (type == null) {
return null;
} else {
for (SmsSendSource item : SmsSendSource.values()) {
if (item.getCode().equals(type)) {
return item;
}
}
return null;
}
}
}
package cn.stylefeng.guns.sms.core.enums;
/**
* 短信发送状态枚举
*
* @author stylefeng
* @Date 2018年5月6日 12:30:48
*/
public enum SmsSendStatus {
WAITING(0, "未发送"),
SUCCESS(1, "发送成功"),
INVALID(3, "失效"),
FAILED(2, "发送失败");
private Integer code;
private String desc;
SmsSendStatus(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
package cn.stylefeng.guns.sms.core.enums;
/**
* 短信验证结果
*
* @author stylefeng
* @Date 2018年5月6日 12:30:48
*/
public enum SmsVerifyResult {
SUCCESS(10, "验证成功"),
ERROR(20, "验证码错误"),
EXPIRED(30, "验证码超时"),
TIMES_UP(40, "超过验证次数");
private Integer code;
private String desc;
SmsVerifyResult(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
package cn.stylefeng.guns.sms.core.exception;
/**
* 短信发送异常
*
* @author fengshuonan
* @date 2018-07-06-下午3:00
*/
public class SmsException extends RuntimeException {
private String code;
private String errorMessage;
public SmsException(String code, String errorMessage) {
super(errorMessage);
this.code = code;
this.errorMessage = errorMessage;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
package cn.stylefeng.guns.sms.core.sms;
import cn.stylefeng.guns.sms.modular.model.SmsSendRecord;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 短信发送服务
*
* @author fengshuonan
* @date 2018-07-06-下午2:14
*/
public interface SmsManager {
/**
* 发送短信
*
* @param phoneNumber 电话号码
* @param templateCode 模板号码
* @param params 模板里参数的集合
* @author fengshuonan
* @Date 2018/7/6 下午2:32
*/
void sendSms(String phoneNumber, String templateCode, Map<String, Object> params);
/**
* 获取某个手机号已发送短信列表
*
* @param phoneNumber 手机号码
* @param sendDate 发送日期
* @param pageNo 分页(第几页)不传递返回第一页,默认分页大小50
* @author fengshuonan
* @Date 2018/7/6 下午3:54
*/
List<SmsSendRecord> getAlreadySendList(String phoneNumber, Date sendDate, Integer pageNo);
}
package cn.stylefeng.guns.sms.modular.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 短信信息表
* </p>
*
* @author fengshuonan
* @since 2018-07-05
*/
@TableName("sms_info")
public class SmsInfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "ID", type = IdType.AUTO)
private Integer id;
/**
* 手机号
*/
@TableField("PHONE_NUMBERS")
private String phoneNumbers;
/**
* 短信验证码
*/
@TableField("VALIDATE_CODE")
private String validateCode;
/**
* 短信模板ID
*/
@TableField("TEMPLATE_CODE")
private String templateCode;
/**
* 回执ID,可根据该ID查询具体的发送状态
*/
@TableField("BIZID")
private String bizid;
/**
* 0=未发送,1=发送成功,2=发送失败
*/
@TableField("STATUS")
private Integer status;
/**
* 0=app,1=pc,2=其它
*/
@TableField("SOURCE")
private Integer source;
/**
* 失效时间
*/
@TableField("INVALID_TIME")
private Date invalidTime;
/**
* 修改时间
*/
@TableField("MODIFY_TIME")
private Date modifyTime;
/**
* 创建时间
*/
@TableField("CREATE_TIME")
private Date createTime;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getPhoneNumbers() {
return phoneNumbers;
}
public void setPhoneNumbers(String phoneNumbers) {
this.phoneNumbers = phoneNumbers;
}
public String getValidateCode() {
return validateCode;
}
public void setValidateCode(String validateCode) {
this.validateCode = validateCode;
}
public String getTemplateCode() {
return templateCode;
}
public void setTemplateCode(String templateCode) {
this.templateCode = templateCode;
}
public String getBizid() {
return bizid;
}
public void setBizid(String bizid) {
this.bizid = bizid;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getSource() {
return source;
}
public void setSource(Integer source) {
this.source = source;
}
public Date getInvalidTime() {
return invalidTime;
}
public void setInvalidTime(Date invalidTime) {
this.invalidTime = invalidTime;
}
public Date getModifyTime() {
return modifyTime;
}
public void setModifyTime(Date modifyTime) {
this.modifyTime = modifyTime;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "TcSmsInfo{" +
"id=" + id +
", phoneNumbers=" + phoneNumbers +
", validateCode=" + validateCode +
", templateCode=" + templateCode +
", bizid=" + bizid +
", status=" + status +
", source=" + source +
", invalidTime=" + invalidTime +
", modifyTime=" + modifyTime +
", createTime=" + createTime +
"}";
}
}
package cn.stylefeng.guns.sms.modular.mapper;
import cn.stylefeng.guns.sms.modular.entity.SmsInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 短信信息表 Mapper 接口
* </p>
*
* @author fengshuonan
* @since 2018-07-05
*/
public interface SmsInfoMapper extends BaseMapper<SmsInfo> {
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.stylefeng.guns.sms.modular.mapper.SmsInfoMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.stylefeng.guns.sms.modular.entity.SmsInfo">
<id column="ID" property="id"/>
<result column="PHONE_NUMBERS" property="phoneNumbers"/>
<result column="VALIDATE_CODE" property="validateCode"/>
<result column="TEMPLATE_CODE" property="templateCode"/>
<result column="BIZID" property="bizid"/>
<result column="STATUS" property="status"/>
<result column="SOURCE" property="source"/>
<result column="INVALID_TIME" property="invalidTime"/>
<result column="MODIFY_TIME" property="modifyTime"/>
<result column="CREATE_TIME" property="createTime"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
ID as id, PHONE_NUMBERS AS phoneNumbers, VALIDATE_CODE AS validateCode, TEMPLATE_CODE AS templateCode, BIZID as bizid, STATUS as status, SOURCE as source, INVALID_TIME AS invalidTime, MODIFY_TIME AS modifyTime, CREATE_TIME AS createTime
</sql>
</mapper>
package cn.stylefeng.guns.sms.modular.model;
import cn.stylefeng.guns.sms.core.enums.MessageType;
import cn.stylefeng.guns.sms.core.enums.SmsSendSource;
import lombok.Data;
import java.util.Map;
/**
* 发送短信的参数
*
* @author fengshuonan
* @date 2018-07-05 21:19
*/
@Data
public class SendMessageParam {
/**
* 手机号
*/
private String phoneNumbers;
/**
* 模板号
*/
private String templateCode;
/**
* 模板中的参数
*/
private Map<String, Object> params;
/**
* sms发送源
*/
private SmsSendSource smsSendSource = SmsSendSource.PC;
/**
* 消息类型,1=验证码,2=消息,默认不传为验证码
*/
private MessageType messageType = MessageType.SMS;
}
package cn.stylefeng.guns.sms.modular.model;
import lombok.Data;
/**
* 消息发送记录
*
* @author fengshuonan
* @date 2018-07-06-下午4:07
*/
@Data
public class SmsSendRecord {
/**
* 手机号码
*/
private String phoneNum;
/**
* 发送状态 1:等待回执,2:发送失败,3:发送成功
*/
private Long sendStatus;
/**
* 运营商短信错误码
*/
private String errCode;
/**
* 模板ID
*/
private String templateCode;
/**
* 短信内容
*/
private String content;
/**
* 发送时间
*/
private String sendDate;
/**
* 接收时间
*/
private String receiveDate;
/**
* 外部流水扩展字段
*/
private String outId;
}
package cn.stylefeng.guns.sms.modular.provider;
import cn.stylefeng.guns.sms.core.enums.SmsSendStatus;
import cn.stylefeng.guns.sms.core.enums.SmsVerifyResult;
import cn.stylefeng.guns.sms.modular.model.SendMessageParam;
import cn.stylefeng.guns.sms.modular.model.VerifySMSParam;
/**
* 短信通知接口
*
* @author stylefeng
* @Date 2018/7/5 21:05
*/
public interface SmsServiceApi {
/**
* 发送短信
*
* @author fengshuonan
* @Date 2018/7/6 下午4:32
*/
Boolean sendShortMessage(SendMessageParam sendMessageParam);
/**
* 验证短信
*
* @author fengshuonan
* @Date 2018/7/6 下午4:30
*/
SmsVerifyResult verifyShortMessage(VerifySMSParam verifySMSParam);
/**
* <pre>
* 查看短信发送状态
*
* 0=未发送,1=发送成功,2=发送失败
* </pre>
*
* @author fengshuonan
* @Date 2018/7/6 下午4:32
*/
SmsSendStatus getMessageSendStatus(Integer smsId);
}
package cn.stylefeng.guns.sms.modular.provider;
import cn.hutool.core.util.RandomUtil;
import cn.stylefeng.guns.sms.core.enums.MessageType;
import cn.stylefeng.guns.sms.core.enums.SmsSendStatus;
import cn.stylefeng.guns.sms.core.enums.SmsVerifyResult;
import cn.stylefeng.guns.sms.core.sms.SmsManager;
import cn.stylefeng.guns.sms.modular.model.SendMessageParam;
import cn.stylefeng.guns.sms.modular.model.VerifySMSParam;
import cn.stylefeng.guns.sms.modular.service.SmsInfoService;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.Map;
/**
* 短信通知接口
*
* @author stylefeng
* @Date 2018/7/5 21:05
*/
@Slf4j
public class SmsServiceProvider implements SmsServiceApi {
@Autowired
private SmsManager smsManager;
@Autowired
private SmsInfoService smsInfoService;
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean sendShortMessage(SendMessageParam sendMessageParam) {
Map<String, Object> params = sendMessageParam.getParams();
log.info("发送短信Provider接口,参数为:" + JSON.toJSONString(sendMessageParam));
//如果是纯消息发送
if (MessageType.MESSAGE.equals(sendMessageParam.getMessageType())) {
smsManager.sendSms(sendMessageParam.getPhoneNumbers(), sendMessageParam.getTemplateCode(), params);
log.info("发送短信Provider接口--message,params的map具体为:" + JSON.toJSONString(params));
} else {
//初始化短信发送参数
String validateCode = null;
//如果传的参数中没有code,就初始化一个code放到参数map里
if (params != null && params.get("code") != null) {
validateCode = params.get("code").toString();
} else {
validateCode = RandomUtil.randomNumbers(6);
if (params == null) {
params = new HashMap<>();
}
params.put("code", validateCode);
}
log.info("发送短信Provider接口,params的map具体为:" + JSON.toJSONString(params));
log.info("发送短信Provider接口,验证码为:" + validateCode);
//存储短信到数据库
Integer keyId = smsInfoService.saveSmsInfo(sendMessageParam, validateCode);
log.info("开始发送短信:发送的电话号码= " + sendMessageParam.getPhoneNumbers() + ",发送的模板号=" + sendMessageParam.getTemplateCode() + ",发送的参数是:" + JSON.toJSONString(params));
//发送短信
smsManager.sendSms(sendMessageParam.getPhoneNumbers(), sendMessageParam.getTemplateCode(), params);
//更新短信发送状态
smsInfoService.updateSmsInfo(keyId, SmsSendStatus.SUCCESS);
}
return true;
}
@Override
public SmsVerifyResult verifyShortMessage(VerifySMSParam verifySMSParam) {
log.info("验证短信Provider接口,参数为:" + JSON.toJSONString(verifySMSParam));
SmsVerifyResult smsVerifyResult = smsInfoService.validateSmsInfo(verifySMSParam);
log.info("验证短信Provider接口,响应结果为:" + JSON.toJSONString(smsVerifyResult));
return smsVerifyResult;
//return SmsVerifyResult.SUCCESS;
}
@Override
public SmsSendStatus getMessageSendStatus(Integer smsId) {
return null;
}
}
package cn.stylefeng.guns.sms.modular.service;
import cn.stylefeng.guns.base.sms.AliyunSmsProperties;
import cn.stylefeng.guns.sms.core.enums.SmsResultEnum;
import cn.stylefeng.guns.sms.core.enums.SmsSendStatus;
import cn.stylefeng.guns.sms.core.enums.SmsVerifyResult;
import cn.stylefeng.guns.sms.core.exception.SmsException;
import cn.stylefeng.guns.sms.modular.entity.SmsInfo;
import cn.stylefeng.guns.sms.modular.mapper.SmsInfoMapper;
import cn.stylefeng.guns.sms.modular.model.SendMessageParam;
import cn.stylefeng.guns.sms.modular.model.VerifySMSParam;
import cn.stylefeng.roses.kernel.model.util.ValidateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
/**
* <p>
* 短信信息表 服务实现类
* </p>
*
* @author fengshuonan
* @since 2018-07-05
*/
@Slf4j
public class SmsInfoService extends ServiceImpl<SmsInfoMapper, SmsInfo> {
@Autowired
private AliyunSmsProperties aliyunSmsProperties;
/**
* 存储短信验证信息
*
* @author fengshuonan
* @Date 2018/7/6 下午4:47
*/
public Integer saveSmsInfo(SendMessageParam sendMessageParam, String validateCode) {
if (ValidateUtil.isOneEmpty(sendMessageParam.getPhoneNumbers(), validateCode, sendMessageParam.getTemplateCode())) {
log.error("存储短信到数据库失败!有参数为空!");
throw new SmsException(SmsResultEnum.PARAM_NULL.getCode(), SmsResultEnum.PARAM_NULL.getMessage());
}
//当前时间
Date nowDate = new Date();
//短信失效时间
long invalidateTime = nowDate.getTime() + aliyunSmsProperties.getInvalidateMinutes() * 60 * 1000;
Date invalidate = new Date(invalidateTime);
SmsInfo smsInfo = new SmsInfo();
smsInfo.setCreateTime(nowDate);
smsInfo.setInvalidTime(invalidate);
smsInfo.setPhoneNumbers(sendMessageParam.getPhoneNumbers());
smsInfo.setStatus(SmsSendStatus.WAITING.getCode());
smsInfo.setSource(sendMessageParam.getSmsSendSource().getCode());
smsInfo.setTemplateCode(sendMessageParam.getTemplateCode());
smsInfo.setValidateCode(validateCode);
this.save(smsInfo);
log.info("发送短信,存储短信到数据库,数据为:" + JSON.toJSONString(smsInfo));
return smsInfo.getId();
}
/**
* 更新短息发送状态
*
* @author fengshuonan
* @Date 2018/7/6 下午5:12
*/
public void updateSmsInfo(Integer keyId, SmsSendStatus smsSendStatus) {
SmsInfo smsInfo = this.getById(keyId);
smsInfo.setStatus(smsSendStatus.getCode());
this.updateById(smsInfo);
}
/**
* 校验验证码是否正确
*
* @author fengshuonan
* @Date 2018/7/6 下午5:16
*/
@Transactional(rollbackFor = Exception.class)
public SmsVerifyResult validateSmsInfo(VerifySMSParam verifySMSParam) {
//校验请求是否为空
if (ValidateUtil.isOneEmpty(verifySMSParam.getPhoneNumbers(), verifySMSParam.getCode(), verifySMSParam.getTemplateCode())) {
log.error("校验短信是否正确失败!有参数为空!");
throw new SmsException(SmsResultEnum.PARAM_NULL.getCode(), SmsResultEnum.PARAM_NULL.getMessage());
}
//查询有没有这条记录
QueryWrapper<SmsInfo> wrapper = new QueryWrapper<>();
wrapper.eq("phone_numbers", verifySMSParam.getPhoneNumbers())
.and(f -> f.eq("source", verifySMSParam.getSmsSendSource().getCode()))
.and(f -> f.eq("template_code", verifySMSParam.getTemplateCode()));
wrapper.orderByDesc("create_time");
List<SmsInfo> smsInfos = this.list(wrapper);
log.info("验证短信Provider接口,查询到sms记录:" + JSON.toJSONString(smsInfos));
//如果找不到记录,提示验证失败
if (smsInfos == null || smsInfos.isEmpty()) {
log.info("验证短信Provider接口,找不到验证码记录,响应验证失败!");
return SmsVerifyResult.ERROR;
} else {
//获取最近发送的第一条
SmsInfo smsInfo = smsInfos.get(0);
//先判断状态是不是失效的状态
if (SmsSendStatus.INVALID.getCode().equals(smsInfo.getStatus())) {
log.info("验证短信Provider接口,短信状态是失效,响应验证失败!");
return SmsVerifyResult.ERROR;
}
//如果验证码和传过来的不一致
if (!verifySMSParam.getCode().equals(smsInfo.getValidateCode())) {
log.info("验证短信Provider接口,验证手机号和验证码不一致,响应验证失败!");
return SmsVerifyResult.ERROR;
}
//判断是否超时
Date invalidTime = smsInfo.getInvalidTime();
if (invalidTime == null || new Date().after(invalidTime)) {
log.info("验证短信Provider接口,验证码超时,响应验证失败!");
return SmsVerifyResult.EXPIRED;
}
//验证成功把短信设置成失效
smsInfo.setStatus(SmsSendStatus.INVALID.getCode());
this.updateById(smsInfo);
log.info("验证短信Provider接口,验证码验证成功!");
return SmsVerifyResult.SUCCESS;
}
}
}
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.json;
class JSON {
/**
* Returns the input if it is a JSON-permissible value; throws otherwise.
*/
static double checkDouble(double d) throws JSONException {
if (Double.isInfinite(d) || Double.isNaN(d)) {
throw new JSONException("Forbidden numeric value: " + d);
}
return d;
}
static Boolean toBoolean(Object value) {
if (value instanceof Boolean) {
return (Boolean) value;
} else if (value instanceof String) {
String stringValue = (String) value;
if ("true".equalsIgnoreCase(stringValue)) {
return true;
} else if ("false".equalsIgnoreCase(stringValue)) {
return false;
}
}
return null;
}
static Double toDouble(Object value) {
if (value instanceof Double) {
return (Double) value;
} else if (value instanceof Number) {
return ((Number) value).doubleValue();
} else if (value instanceof String) {
try {
return Double.valueOf((String) value);
} catch (NumberFormatException ignored) {
}
}
return null;
}
static Integer toInteger(Object value) {
if (value instanceof Integer) {
return (Integer) value;
} else if (value instanceof Number) {
return ((Number) value).intValue();
} else if (value instanceof String) {
try {
return (int) Double.parseDouble((String) value);
} catch (NumberFormatException ignored) {
}
}
return null;
}
static Long toLong(Object value) {
if (value instanceof Long) {
return (Long) value;
} else if (value instanceof Number) {
return ((Number) value).longValue();
} else if (value instanceof String) {
try {
return (long) Double.parseDouble((String) value);
} catch (NumberFormatException ignored) {
}
}
return null;
}
static String toString(Object value) {
if (value instanceof String) {
return (String) value;
} else if (value != null) {
return String.valueOf(value);
}
return null;
}
public static JSONException typeMismatch(Object indexOrName, Object actual,
String requiredType) throws JSONException {
if (actual == null) {
throw new JSONException("Value at " + indexOrName + " is null.");
} else {
throw new JSONException("Value " + actual + " at " + indexOrName
+ " of type " + actual.getClass().getName()
+ " cannot be converted to " + requiredType);
}
}
public static JSONException typeMismatch(Object actual, String requiredType)
throws JSONException {
if (actual == null) {
throw new JSONException("Value is null.");
} else {
throw new JSONException("Value " + actual
+ " of type " + actual.getClass().getName()
+ " cannot be converted to " + requiredType);
}
}
}
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.json;
// Note: this class was written without inspecting the non-free org.json sourcecode.
/**
* Thrown to indicate a problem with the JSON API. Such problems include:
* <ul>
* <li>Attempts to parse or construct malformed documents
* <li>Use of null as a name
* <li>Use of numeric types not available to JSON, such as {@link
* Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
* <li>Lookups using an out of range index or nonexistent name
* <li>Type mismatches on lookups
* </ul>
*
* <p>Although this is a checked exception, it is rarely recoverable. Most
* callers should simply wrap this exception in an unchecked exception and
* rethrow:
* <pre> public JSONArray toJSONObject() {
* try {
* JSONObject result = new JSONObject();
* ...
* } catch (JSONException e) {
* throw new RuntimeException(e);
* }
* }</pre>
*/
public class JSONException extends Exception {
public JSONException(String s) {
super(s);
}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.stylefeng.guns.sms.config.ServiceAutoConfiguration,\
cn.stylefeng.guns.sms.config.SmsAutoConfiguration
\ No newline at end of file
......@@ -22,12 +22,28 @@
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-core</artifactId>
</dependency>
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-validator</artifactId>
</dependency>
<!--数据库驱动,可根据自己需要自行删减-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!--spring boot依赖-->
<dependency>
......
......@@ -18,16 +18,16 @@ public class AddDatabaseInfoSql extends AbstractSql {
@Override
protected String sqlServer() {
return "";
return "INSERT INTO [database_info] ([db_id], [db_name], [jdbc_driver], [user_name], [password], [jdbc_url], [remarks], [create_time]) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
}
@Override
protected String pgSql() {
return "";
return "INSERT INTO database_info(db_id, db_name, jdbc_driver, user_name, password, jdbc_url, remarks, create_time) VALUES (?, ?, ?, ?, ?, ?, ?, to_timestamp(?,'YYYY-MM-DD HH24:MI:SS'))";
}
@Override
protected String oracle() {
return "";
return "INSERT INTO database_info VALUES (?, ?, ?, ?, ?, ?, ?, to_date(?, 'yyyy-mm-dd hh24:mi:ss'))";
}
}
......@@ -18,16 +18,16 @@ public class DatabaseListSql extends AbstractSql {
@Override
protected String sqlServer() {
return "";
return "select db_name,jdbc_driver,jdbc_url,user_name,password from database_info";
}
@Override
protected String pgSql() {
return "";
return "select db_name,jdbc_driver,jdbc_url,user_name,password from database_info";
}
@Override
protected String oracle() {
return "";
return "select db_name,jdbc_driver,jdbc_url,user_name,password from database_info";
}
}
......@@ -18,16 +18,16 @@ public class DeleteDatabaseInfoSql extends AbstractSql {
@Override
protected String sqlServer() {
return "";
return "DELETE from database_info where db_name = ?";
}
@Override
protected String pgSql() {
return "";
return "DELETE from database_info where db_name = ?";
}
@Override
protected String oracle() {
return "";
return "DELETE from database_info where db_name = ?";
}
}
......@@ -18,16 +18,32 @@ public class TableFieldListSql extends AbstractSql {
@Override
protected String sqlServer() {
return "";
return "SELECT A.name as columnName,\n" +
" CONVERT(varchar(200), isnull(G.[value], '')) as columnComment\n" +
" FROM syscolumns A\n" +
" Left Join systypes B On A.xusertype= B.xusertype\n" +
" Inner Join sysobjects D On A.id= D.id\n" +
" and D.xtype= 'U'\n" +
" and D.name<> 'dtproperties'\n" +
" Left Join syscomments E on A.cdefault= E.id\n" +
" Left Join sys.extended_properties G on A.id= G.major_id\n" +
" and A.colid= G.minor_id\n" +
" Left Join sys.extended_properties F On D.id= F.major_id\n" +
" and F.minor_id= 0\n" +
" where d.name= ? \n" +
" Order By A.id,\n" +
" A.colorder";
}
@Override
protected String pgSql() {
return "";
return "SELECT a.attname as \"columnName\" , col_description(a.attrelid,a.attnum) as \"columnComment\"\n" +
"FROM pg_class as c,pg_attribute as a " +
"where c.relname = ? and a.attrelid = c.oid and a.attnum>0";
}
@Override
protected String oracle() {
return "";
return "select column_name as columnName, comments as columnComment from user_col_comments where Table_Name= ?";
}
}
......@@ -18,16 +18,35 @@ public class TableListSql extends AbstractSql {
@Override
protected String sqlServer() {
return "";
return "SELECT DISTINCT\n" +
"d.name as tableName,\n" +
"CONVERT(varchar(200), f.value) as tableComment\n" +
"FROM\n" +
"syscolumns a\n" +
"LEFT JOIN systypes b ON a.xusertype= b.xusertype\n" +
"INNER JOIN sysobjects d ON a.id= d.id\n" +
"AND d.xtype= 'U'\n" +
"AND d.name<> 'dtproperties'\n" +
"LEFT JOIN syscomments e ON a.cdefault= e.id\n" +
"LEFT JOIN sys.extended_properties g ON a.id= G.major_id\n" +
"AND a.colid= g.minor_id\n" +
"LEFT JOIN sys.extended_properties f ON d.id= f.major_id\n" +
"AND f.minor_id= 0";
}
@Override
protected String pgSql() {
return "";
return "select " +
"relname as \"tableName\"," +
"cast(obj_description(relfilenode,'pg_class') as varchar) as \"tableComment\" " +
"from pg_class c \n" +
"where relkind = 'r' and relname not like 'pg_%' and relname not like 'sql_%' order by relname";
}
@Override
protected String oracle() {
return "";
return "select ut.table_name as tableName, co.comments as tableComment from user_tables ut\n" +
"left join user_tab_comments co on ut.table_name = co.table_name\n" +
"where tablespace_name is not null and user= ?";
}
}
......@@ -21,6 +21,7 @@ public class DataSourceInitException extends ServiceException {
INIT_DATA_SOURCE_ERROR(500, "初始化数据源异常"),
DELETE_TENANT_ERROR(500, "不能删除租户数据源"),
REPEAT_ERROR(500, "数据源已存在,请更换名称!"),
INIT_DATASOURCE_ERROR(500, "数据源连接错误,请检查连接配置!"),
NAME_REPEAT_ERROR(500, "当前上下文中已存在该名称,请重启项目或更换名称!"),
QUERY_DATASOURCE_INFO_ERROR(500, "查询数据库中数据源信息错误");
......
package cn.stylefeng.guns.sys.modular.db.factory;
package cn.stylefeng.guns.base.db.factory;
import cn.stylefeng.guns.sys.modular.db.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.base.db.model.params.DatabaseInfoParam;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
/**
......
package cn.stylefeng.guns.email.core.model;
package cn.stylefeng.guns.base.db.model;
import lombok.Data;
/**
* 发送邮件的请求参数
* 字段详情
*
* @author fengshuonan
* @date 2018-07-05 21:19
* @date 2020-01-19-5:40 下午
*/
@Data
public class SendMailParam {
public class TableFieldInfo {
/**
* 发送给某人的邮箱
* 字段名称(和数据库中的字段名称一致,可能为带下划线的)
*/
private String to;
private String columnName;
/**
* 邮件标题
* 驼峰命名法的名称
*/
private String title;
private String camelFieldName;
/**
* 邮件内容(经过base64编码后的)
* 字段注释
*/
private String content;
private String columnComment;
}
package cn.stylefeng.guns.sys.modular.db.model.params;
package cn.stylefeng.guns.base.db.model.params;
import cn.stylefeng.roses.kernel.model.validator.BaseValidatingParam;
import lombok.Data;
......
package cn.stylefeng.guns.sys.modular.db.service;
package cn.stylefeng.guns.base.db.service;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.base.db.entity.DatabaseInfo;
import cn.stylefeng.guns.sys.modular.db.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.sys.modular.db.model.result.DatabaseInfoResult;
import cn.stylefeng.guns.base.db.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.base.db.model.result.DatabaseInfoResult;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
......
package cn.stylefeng.guns.base.db.util;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.guns.base.db.dao.sqls.CreateDatabaseSql;
import cn.stylefeng.guns.base.db.dao.sqls.TableFieldListSql;
import cn.stylefeng.guns.base.db.dao.sqls.TableListSql;
import cn.stylefeng.guns.base.db.entity.DatabaseInfo;
import cn.stylefeng.guns.base.db.exception.DataSourceInitException;
import cn.stylefeng.guns.base.db.model.TableFieldInfo;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
......@@ -74,8 +76,8 @@ public class DbUtil {
* @author fengshuonan
* @Date 2019-05-04 20:31
*/
public static List<Map<String, Object>> getTableFields(DatabaseInfo dbInfo, String tableName) {
ArrayList<Map<String, Object>> fieldList = new ArrayList<>();
public static List<TableFieldInfo> getTableFields(DatabaseInfo dbInfo, String tableName) {
ArrayList<TableFieldInfo> fieldList = new ArrayList<>();
try {
Class.forName(dbInfo.getJdbcDriver());
Connection conn = DriverManager.getConnection(
......@@ -99,12 +101,13 @@ public class DbUtil {
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
HashMap<String, Object> map = new HashMap<>();
TableFieldInfo tableFieldInfo = new TableFieldInfo();
String columnName = resultSet.getString("columnName");
String columnComment = resultSet.getString("columnComment");
map.put("columnName", columnName);
map.put("columnComment", columnComment);
fieldList.add(map);
tableFieldInfo.setColumnName(columnName);
tableFieldInfo.setColumnComment(columnComment);
tableFieldInfo.setCamelFieldName(StrUtil.toCamelCase(columnName));
fieldList.add(tableFieldInfo);
}
return fieldList;
} catch (Exception ex) {
......
package cn.stylefeng.guns.base.i18n.context;
import cn.stylefeng.guns.base.i18n.dict.TranslationDict;
import cn.stylefeng.guns.base.i18n.enums.TranslationEnum;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 翻译字典的容器
*
* @author fengshuonan
* @Date 2019-06-20 13:37
*/
@Slf4j
public class TranslationContext {
/**
* 所有翻译字典
*/
private static Map<TranslationEnum, Map<String, String>> TRAN_DICT_CONTAINER = new ConcurrentHashMap<>();
/**
* 初始化所有字典
*
* @author fengshuonan
* @Date 2019/10/18 10:29
*/
public static void init(List<TranslationDict> list) {
//根据语种数量,创建多个map
for (TranslationEnum type : TranslationEnum.values()) {
HashMap<String, String> typeMap = new HashMap<>();
TRAN_DICT_CONTAINER.put(type, typeMap);
}
//整理数据库中的字典
for (TranslationDict translationDict : list) {
TranslationEnum translationLanguages = translationDict.getTranslationLanguages();
TRAN_DICT_CONTAINER.get(translationLanguages).put(translationDict.getTranCode(), translationDict.getTranValue());
}
}
/**
* 通过语种获取一套翻译字典
*
* @author fengshuonan
* @Date 2019/10/18 10:41
*/
public static Map<String, String> getTranslationByLanguage(TranslationEnum translationLanguages) {
return TRAN_DICT_CONTAINER.get(translationLanguages);
}
}
package cn.stylefeng.guns.base.i18n.context;
import cn.stylefeng.guns.base.i18n.enums.TranslationEnum;
import cn.stylefeng.roses.core.util.HttpContext;
import cn.stylefeng.roses.core.util.ToolUtil;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* 带有用户信息的翻译字典的上下文
*
* @author fengshuonan
* @Date 2019-06-20 13:37
*/
@Slf4j
public class UserTranslationContext {
private static final String TRAN_COOKIE_NAME = "guns-tran";
private static final Integer EXP_SECONDES = 7 * 24 * 3600;
/**
* 获取当前用户选择的语种
*
* @author fengshuonan
* @Date 2019/10/18 11:06
*/
public static void setUserCurrentTrans(TranslationEnum translationEnum) {
Cookie languageCookie = new Cookie(TRAN_COOKIE_NAME, String.valueOf(translationEnum.getCode()));
languageCookie.setMaxAge(EXP_SECONDES);
languageCookie.setHttpOnly(true);
languageCookie.setPath("/");
HttpServletResponse response = HttpContext.getResponse();
response.addCookie(languageCookie);
}
/**
* 获取当前用户选择的语种
*
* @author fengshuonan
* @Date 2019/10/18 11:06
*/
public static TranslationEnum getUserCurrentTrans() {
Cookie[] cookies = HttpContext.getRequest().getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (TRAN_COOKIE_NAME.equals(cookie.getName())) {
String value = cookie.getValue();
if (ToolUtil.isNotEmpty(value)) {
try {
return TranslationEnum.valueOf(Integer.valueOf(value));
} catch (Exception e) {
//非法输入,直接返回中文
return TranslationEnum.CHINESE;
}
}
}
}
}
//cookie没值,返回中文
return TranslationEnum.CHINESE;
}
/**
* 根据当前登陆用户选择的语言,翻译成指定编码对应语言的值
*
* @author fengshuonan
* @Date 2019/10/18 10:41
*/
public static String get(String code) {
TranslationEnum translationEnum = getUserCurrentTrans();
Map<String, String> translationByLanguage = TranslationContext.getTranslationByLanguage(translationEnum);
return translationByLanguage.get(code);
}
/**
* 根据当前登陆用户选择的语言,翻译成指定编码对应语言的值
* <p>
* 若查找不到code对应的值,则以第二个参数为准
*
* @author fengshuonan
* @Date 2019/10/18 10:41
*/
public static String get(String code, String defaultName) {
TranslationEnum translationEnum = getUserCurrentTrans();
Map<String, String> translationByLanguage = TranslationContext.getTranslationByLanguage(translationEnum);
if (translationByLanguage == null || ToolUtil.isEmpty(translationByLanguage.get(code))) {
return defaultName;
} else {
return translationByLanguage.get(code);
}
}
}
package cn.stylefeng.guns.base.i18n.dict;
import cn.stylefeng.guns.base.i18n.enums.TranslationEnum;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 多语言表
* </p>
*
* @author stylefeng
* @since 2019-10-17
*/
@Data
public class TranslationDict implements Serializable {
/**
* 编码
*/
private String tranCode;
/**
* 多语言条例名称
*/
private String tranName;
/**
* 1:中文 2:英语
*/
private TranslationEnum translationLanguages;
/**
* 翻译的值
*/
private String tranValue;
}
package cn.stylefeng.guns.base.i18n.entity;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 多语言表
* </p>
*
* @author stylefeng
* @since 2019-10-17
*/
@TableName("sys_translation")
public class Translation implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "tran_id", type = IdType.ID_WORKER)
private Long tranId;
/**
* 编码
*/
@TableField("tran_code")
private String tranCode;
/**
* 多语言条例名称
*/
@TableField("tran_name")
private String tranName;
/**
* 1:中文 2:英语
*/
@TableField("languages")
private Integer languages;
/**
* 翻译的值
*/
@TableField("tran_value")
private String tranValue;
/**
* 创建时间
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
private Date createTime;
/**
* 创建人
*/
@TableField(value = "create_user", fill = FieldFill.INSERT)
private Long createUser;
/**
* 更新时间
*/
@TableField(value = "update_time", fill = FieldFill.UPDATE)
private Date updateTime;
/**
* 更新人
*/
@TableField(value = "update_user", fill = FieldFill.UPDATE)
private Long updateUser;
public Long getTranId() {
return tranId;
}
public void setTranId(Long tranId) {
this.tranId = tranId;
}
public String getTranCode() {
return tranCode;
}
public void setTranCode(String tranCode) {
this.tranCode = tranCode;
}
public String getTranName() {
return tranName;
}
public void setTranName(String tranName) {
this.tranName = tranName;
}
public Integer getLanguages() {
return languages;
}
public void setLanguages(Integer languages) {
this.languages = languages;
}
public String getTranValue() {
return tranValue;
}
public void setTranValue(String tranValue) {
this.tranValue = tranValue;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Long getCreateUser() {
return createUser;
}
public void setCreateUser(Long createUser) {
this.createUser = createUser;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Long getUpdateUser() {
return updateUser;
}
public void setUpdateUser(Long updateUser) {
this.updateUser = updateUser;
}
@Override
public String toString() {
return "Translation{" +
"tranId=" + tranId +
", tranCode=" + tranCode +
", tranName=" + tranName +
", languages=" + languages +
", tranValue=" + tranValue +
", createTime=" + createTime +
", createUser=" + createUser +
", updateTime=" + updateTime +
", updateUser=" + updateUser +
"}";
}
}
package cn.stylefeng.guns.base.i18n.enums;
import lombok.Getter;
/**
* 默认的翻译字段枚举
*
* @author fengshuonan
* @Date 2020/3/18 13:24
*/
@Getter
public enum DefaultDicts {
MENU_CHANGE_PASSWORD_1("MENU_CHANGE_PASSWORD", TranslationEnum.CHINESE, "修改密码"),
MENU_CHANGE_PASSWORD_2("MENU_CHANGE_PASSWORD", TranslationEnum.ENGLISH, "change password"),
FIELD_ACCOUNT_1("FIELD_ACCOUNT", TranslationEnum.CHINESE, "账号"),
FIELD_ACCOUNT_2("FIELD_ACCOUNT", TranslationEnum.ENGLISH, "account"),
FIELD_NAME_1("FIELD_NAME", TranslationEnum.CHINESE, "名称"),
FIELD_NAME_2("FIELD_NAME", TranslationEnum.ENGLISH, "name"),
FIELD_POST_1("FIELD_POST", TranslationEnum.CHINESE, "职位"),
FIELD_POST_2("FIELD_POST", TranslationEnum.ENGLISH, "post"),
FIELD_PHONE_1("FIELD_PHONE", TranslationEnum.CHINESE, "电话"),
FIELD_PHONE_2("FIELD_PHONE", TranslationEnum.ENGLISH, "phone"),
FIELD_CREATE_TIME_1("FIELD_CREATE_TIME", TranslationEnum.CHINESE, "创建时间"),
FIELD_CREATE_TIME_2("FIELD_CREATE_TIME", TranslationEnum.ENGLISH, "create time"),
FIELD_STATUS_1("FIELD_STATUS", TranslationEnum.CHINESE, "状态"),
FIELD_STATUS_2("FIELD_STATUS", TranslationEnum.ENGLISH, "status"),
FIELD_OPERATION_1("FIELD_OPERATION", TranslationEnum.CHINESE, "操作"),
FIELD_OPERATION_2("FIELD_OPERATION", TranslationEnum.ENGLISH, "operation"),
TITLE_ADD_USER_1("FIELD_NAME", TranslationEnum.CHINESE, "添加用户"),
TITLE_ADD_USER_2("FIELD_NAME", TranslationEnum.ENGLISH, "add user"),
TITLE_EDIT_USER_1("TITLE_EDIT_USER", TranslationEnum.CHINESE, "编辑用户"),
TITLE_EDIT_USER_2("TITLE_EDIT_USER", TranslationEnum.ENGLISH, "edit user"),
TITLE_ROLE_ASSIGN_1("TITLE_ROLE_ASSIGN", TranslationEnum.CHINESE, "角色分配"),
TITLE_ROLE_ASSIGN_2("TITLE_ROLE_ASSIGN", TranslationEnum.ENGLISH, "role assign"),
FIELD_DEPT_1("FIELD_DEPT", TranslationEnum.CHINESE, "部门"),
FIELD_DEPT_2("FIELD_DEPT", TranslationEnum.ENGLISH, "dept");
/**
* 编码
*/
private String tranCode;
/**
* 1:中文 2:英语
*/
private TranslationEnum translationLanguages;
/**
* 翻译的值
*/
private String tranValue;
DefaultDicts(String tranCode, TranslationEnum translationLanguages, String tranValue) {
this.tranCode = tranCode;
this.translationLanguages = translationLanguages;
this.tranValue = tranValue;
}
}
package cn.stylefeng.guns.base.i18n.enums;
import lombok.Getter;
import java.util.ArrayList;
import java.util.List;
/**
* 翻译的语种
*
* @author fengshuonan
* @Date 2019/10/18 10:03
*/
@Getter
public enum TranslationEnum {
/**
* 中文
*/
CHINESE(1, "中文"),
/**
* 英文
*/
ENGLISH(2, "English");
Integer code;
String description;
TranslationEnum(Integer code, String description) {
this.code = code;
this.description = description;
}
/**
* 获取所有的type(返回code编码集合)
*
* @author fengshuonan
* @Date 2019/10/18 10:13
*/
public static List<String> types() {
ArrayList<String> integers = new ArrayList<>();
for (TranslationEnum value : TranslationEnum.values()) {
integers.add(value.name());
}
return integers;
}
/**
* 通过code值获取枚举
*
* @author fengshuonan
* @Date 2019/10/18 10:33
*/
public static TranslationEnum valueOf(Integer value) {
if (value == null) {
return null;
} else {
for (TranslationEnum translationLanguages : TranslationEnum.values()) {
if (translationLanguages.getCode().equals(value)) {
return translationLanguages;
}
}
return null;
}
}
}
package cn.stylefeng.guns.base.i18n.enums;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* 语言描述
*
* @author fengshuonan
* @Date 2019/10/18 10:03
*/
@Data
@AllArgsConstructor
public class TranslationItem {
Integer code;
String description;
}
package cn.stylefeng.guns.base.i18n.init;
import cn.stylefeng.guns.base.i18n.context.TranslationContext;
import cn.stylefeng.guns.base.i18n.dict.TranslationDict;
import cn.stylefeng.guns.base.i18n.entity.Translation;
import cn.stylefeng.guns.base.i18n.enums.DefaultDicts;
import cn.stylefeng.guns.base.i18n.enums.TranslationEnum;
import cn.stylefeng.guns.base.i18n.service.TranslationService;
import cn.stylefeng.roses.core.util.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 参数配置 服务类
* </p>
*
* @author stylefeng
* @since 2019-06-20
*/
@Component
@Slf4j
public class TranslationInit implements CommandLineRunner {
@Override
public void run(String... args) {
try {
//从数据库加载字典
initFromTable();
} catch (Exception e) {
log.warn("从数据库初始化字典失败,读取默认字典!");
//加载默认的一些字典
initDefaultDicts();
}
}
/**
* 从数据库加载字典
*
* @author fengshuonan
* @Date 2020/3/18 12:59
*/
private void initFromTable() {
ArrayList<TranslationDict> translationDicts = new ArrayList<>();
//从数据库读取字典
TranslationService translationService = SpringContextHolder.getBean(TranslationService.class);
List<Translation> list = translationService.list();
if (list != null) {
for (Translation translation : list) {
TranslationDict translationDict = new TranslationDict();
translationDict.setTranCode(translation.getTranCode());
translationDict.setTranName(translation.getTranName());
translationDict.setTranslationLanguages(TranslationEnum.valueOf(translation.getLanguages()));
translationDict.setTranValue(translation.getTranValue());
translationDicts.add(translationDict);
}
TranslationContext.init(translationDicts);
log.info("初始化所有的翻译字典" + list.size() + "条!");
}
}
/**
* 初始化默认系统字典
*
* @author fengshuonan
* @Date 2020/3/18 12:58
*/
private void initDefaultDicts() {
ArrayList<TranslationDict> translationDicts = new ArrayList<>();
DefaultDicts[] values = DefaultDicts.values();
for (DefaultDicts value : values) {
TranslationDict translationDict = new TranslationDict();
translationDict.setTranCode(value.getTranCode());
translationDict.setTranslationLanguages(value.getTranslationLanguages());
translationDict.setTranValue(value.getTranValue());
translationDicts.add(translationDict);
}
TranslationContext.init(translationDicts);
log.info("初始化所有的翻译字典" + translationDicts.size() + "条!");
}
}
package cn.stylefeng.guns.base.i18n.model.params;
import cn.stylefeng.roses.kernel.model.validator.BaseValidatingParam;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 多语言表
* </p>
*
* @author stylefeng
* @since 2019-10-17
*/
@Data
public class TranslationParam implements Serializable, BaseValidatingParam {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
private Long tranId;
/**
* 编码
*/
private String tranCode;
/**
* 多语言条例名称
*/
private String tranName;
/**
* 1:中文 2:英语
*/
private Integer languages;
/**
* 翻译的值
*/
private String tranValue;
/**
* 创建时间
*/
private Date createTime;
/**
* 创建人
*/
private Long createUser;
/**
* 更新时间
*/
private Date updateTime;
/**
* 更新人
*/
private Long updateUser;
@Override
public String checkParam() {
return null;
}
}
package cn.stylefeng.guns.base.i18n.model.result;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 多语言表
* </p>
*
* @author stylefeng
* @since 2019-10-17
*/
@Data
public class TranslationResult implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
private Long tranId;
/**
* 编码
*/
private String tranCode;
/**
* 多语言条例名称
*/
private String tranName;
/**
* 1:中文 2:英语
*/
private Integer languages;
/**
* 翻译的值
*/
private String tranValue;
/**
* 创建时间
*/
private Date createTime;
/**
* 创建人
*/
private Long createUser;
/**
* 更新时间
*/
private Date updateTime;
/**
* 更新人
*/
private Long updateUser;
}
package cn.stylefeng.guns.base.i18n.service;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.base.i18n.entity.Translation;
import cn.stylefeng.guns.base.i18n.model.params.TranslationParam;
import cn.stylefeng.guns.base.i18n.model.result.TranslationResult;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* 多语言表 服务类
* </p>
*
* @author stylefeng
* @since 2019-10-17
*/
public interface TranslationService extends IService<Translation> {
/**
* 新增
*
* @author stylefeng
* @Date 2019-10-17
*/
void add(TranslationParam param);
/**
* 删除
*
* @author stylefeng
* @Date 2019-10-17
*/
void delete(TranslationParam param);
/**
* 更新
*
* @author stylefeng
* @Date 2019-10-17
*/
void update(TranslationParam param);
/**
* 查询单条数据,Specification模式
*
* @author stylefeng
* @Date 2019-10-17
*/
TranslationResult findBySpec(TranslationParam param);
/**
* 查询列表,Specification模式
*
* @author stylefeng
* @Date 2019-10-17
*/
List<TranslationResult> findListBySpec(TranslationParam param);
/**
* 查询分页数据,Specification模式
*
* @author stylefeng
* @Date 2019-10-17
*/
LayuiPageInfo findPageBySpec(TranslationParam param);
}
package cn.stylefeng.guns.sys.modular.third.model.params;
package cn.stylefeng.guns.base.oauth2.model.params;
import lombok.Data;
import cn.stylefeng.roses.kernel.model.validator.BaseValidatingParam;
import java.util.Date;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* <p>
......
package cn.stylefeng.guns.sys.modular.third.model.result;
package cn.stylefeng.guns.base.oauth2.model.result;
import lombok.Data;
import java.util.Date;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* <p>
......
package cn.stylefeng.guns.sys.modular.third.service;
package cn.stylefeng.guns.base.oauth2.service;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.sys.modular.third.entity.OauthUserInfo;
import cn.stylefeng.guns.sys.modular.third.model.params.OauthUserInfoParam;
import cn.stylefeng.guns.sys.modular.third.model.result.OauthUserInfoResult;
import cn.stylefeng.guns.base.oauth2.entity.OauthUserInfo;
import cn.stylefeng.guns.base.oauth2.model.params.OauthUserInfoParam;
import cn.stylefeng.guns.base.oauth2.model.result.OauthUserInfoResult;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
......
package cn.stylefeng.guns.base.tenant.consts;
/**
* 租户的常量
*
* @author fengshuonan
* @date 2019-06-18-16:24
*/
public interface TenantConstants {
/**
* 租户数据源标识前缀
*/
String TENANT_DB_PREFIX = "guns_tenant_db_";
}
package cn.stylefeng.guns.base.tenant.context;
/**
* 租户编码的临时存放
*
* @author fengshuonan
* @date 2019-06-19-14:08
*/
public class DataBaseNameHolder {
private static ThreadLocal<String> threadLocal = new ThreadLocal<>();
public static void put(String value) {
threadLocal.set(value);
}
public static String get() {
return threadLocal.get();
}
public static void remove() {
threadLocal.remove();
}
}
package cn.stylefeng.guns.base.tenant.context;
/**
* 租户编码的临时存放
*
* @author fengshuonan
* @date 2019-06-19-14:08
*/
public class TenantCodeHolder {
private static ThreadLocal<String> threadLocal = new ThreadLocal<>();
public static void put(String value) {
threadLocal.set(value);
}
public static String get() {
return threadLocal.get();
}
public static void remove() {
threadLocal.remove();
}
}
package cn.stylefeng.guns.base.tenant.entity;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 租户表
* </p>
*
* @author stylefeng
* @since 2019-06-16
*/
@TableName("tenant_info")
public class TenantInfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "tenant_id", type = IdType.ID_WORKER)
private Long tenantId;
/**
* 租户名称
*/
@TableField("name")
private String name;
/**
* 租户的编码
*/
@TableField("code")
private String code;
/**
* 关联的数据库名称
*/
@TableField("db_name")
private String dbName;
/**
* 创建时间
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
private Date createTime;
/**
* 创建人
*/
@TableField(value = "create_user", fill = FieldFill.INSERT)
private Long createUser;
/**
* 更新时间
*/
@TableField(value = "update_time", fill = FieldFill.UPDATE)
private Date updateTime;
/**
* 更新人
*/
@TableField(value = "update_user", fill = FieldFill.UPDATE)
private Long updateUser;
public Long getTenantId() {
return tenantId;
}
public void setTenantId(Long tenantId) {
this.tenantId = tenantId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Long getCreateUser() {
return createUser;
}
public void setCreateUser(Long createUser) {
this.createUser = createUser;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Long getUpdateUser() {
return updateUser;
}
public void setUpdateUser(Long updateUser) {
this.updateUser = updateUser;
}
@Override
public String toString() {
return "TenantInfo{" +
"tenantId=" + tenantId +
", name=" + name +
", code=" + code +
", dbName=" + dbName +
", createTime=" + createTime +
", createUser=" + createUser +
", updateTime=" + updateTime +
", updateUser=" + updateUser +
"}";
}
}
package cn.stylefeng.guns.base.tenant.model.params;
import cn.stylefeng.roses.kernel.model.validator.BaseValidatingParam;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 租户表
* </p>
*
* @author stylefeng
* @since 2019-06-16
*/
@Data
public class TenantInfoParam implements Serializable, BaseValidatingParam {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
private Long tenantId;
/**
* 租户名称
*/
private String name;
/**
* 租户的编码
*/
private String code;
/**
* 租户管理员账号
*/
private String adminUsername;
/**
* 租户管理员密码
*/
private String adminPassword;
@Override
public String checkParam() {
return null;
}
}
package cn.stylefeng.guns.base.tenant.model.result;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 租户表
* </p>
*
* @author stylefeng
* @since 2019-06-16
*/
@Data
public class TenantInfoResult implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
private Long tenantId;
/**
* 租户名称
*/
private String name;
/**
* 租户的编码
*/
private String code;
/**
* 关联的数据库名称
*/
private String dbName;
/**
* 创建时间
*/
private Date createTime;
/**
* 创建人
*/
private Long createUser;
/**
* 更新时间
*/
private Date updateTime;
/**
* 更新人
*/
private Long updateUser;
}
package cn.stylefeng.guns.base.tenant.service;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.base.tenant.entity.TenantInfo;
import cn.stylefeng.guns.base.tenant.model.params.TenantInfoParam;
import cn.stylefeng.guns.base.tenant.model.result.TenantInfoResult;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* 租户表 服务类
* </p>
*
* @author stylefeng
* @since 2019-06-16
*/
public interface TenantInfoService extends IService<TenantInfo> {
/**
* 新增
*
* @author stylefeng
* @Date 2019-06-16
*/
void add(TenantInfoParam param);
/**
* 删除
*
* @author stylefeng
* @Date 2019-06-16
*/
void delete(TenantInfoParam param);
/**
* 更新
*
* @author stylefeng
* @Date 2019-06-16
*/
void update(TenantInfoParam param);
/**
* 查询单条数据,Specification模式
*
* @author stylefeng
* @Date 2019-06-16
*/
TenantInfoResult findBySpec(TenantInfoParam param);
/**
* 查询列表,Specification模式
*
* @author stylefeng
* @Date 2019-06-16
*/
List<TenantInfoResult> findListBySpec(TenantInfoParam param);
/**
* 查询分页数据,Specification模式
*
* @author stylefeng
* @Date 2019-06-16
*/
LayuiPageInfo findPageBySpec(TenantInfoParam param);
/**
* 获取租户信息,通过code
*
* @author fengshuonan
* @Date 2019-06-19 14:17
*/
TenantInfo getByCode(String code);
}
......@@ -11,7 +11,7 @@
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>guns-base-sms</artifactId>
<artifactId>guns-dbctn</artifactId>
<packaging>jar</packaging>
......@@ -20,22 +20,10 @@
<!--基础组件-->
<dependency>
<groupId>cn.stylefeng</groupId>
<artifactId>guns-base</artifactId>
<artifactId>guns-sys</artifactId>
<version>1.0.0</version>
</dependency>
<!--短信发送的sdk-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>3.7.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
<build>
......
package cn.stylefeng.guns.sys.modular.db.controller;
package cn.stylefeng.guns.db.controller;
import cn.stylefeng.guns.base.db.entity.DatabaseInfo;
import cn.stylefeng.guns.base.db.util.DbUtil;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.sys.modular.db.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.sys.modular.db.service.DatabaseInfoService;
import cn.stylefeng.guns.base.db.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.base.db.service.DatabaseInfoService;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.roses.kernel.model.response.ResponseData;
......
package cn.stylefeng.guns.sys.modular.db.mapper;
package cn.stylefeng.guns.db.mapper;
import cn.stylefeng.guns.base.db.entity.DatabaseInfo;
import cn.stylefeng.guns.sys.modular.db.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.sys.modular.db.model.result.DatabaseInfoResult;
import cn.stylefeng.guns.base.db.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.base.db.model.result.DatabaseInfoResult;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.stylefeng.guns.sys.modular.db.mapper.DatabaseInfoMapper">
<mapper namespace="cn.stylefeng.guns.db.mapper.DatabaseInfoMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.stylefeng.guns.base.db.entity.DatabaseInfo">
......@@ -19,7 +19,7 @@
db_id AS "dbId", db_name AS "dbName", jdbc_driver AS "jdbcDriver", user_name AS "userName", '***' AS "password", jdbc_url AS "jdbcUrl", remarks AS "remarks", create_time AS "createTime"
</sql>
<select id="customList" resultType="cn.stylefeng.guns.sys.modular.db.model.result.DatabaseInfoResult" parameterType="cn.stylefeng.guns.sys.modular.db.model.params.DatabaseInfoParam">
<select id="customList" resultType="cn.stylefeng.guns.base.db.model.result.DatabaseInfoResult" parameterType="cn.stylefeng.guns.base.db.model.params.DatabaseInfoParam">
select
<include refid="Base_Column_List"/>
from database_info where 1 = 1
......@@ -28,7 +28,7 @@
</if>
</select>
<select id="customMapList" resultType="map" parameterType="cn.stylefeng.guns.sys.modular.db.model.params.DatabaseInfoParam">
<select id="customMapList" resultType="map" parameterType="cn.stylefeng.guns.base.db.model.params.DatabaseInfoParam">
select
<include refid="Base_Column_List"/>
from database_info where 1 = 1
......@@ -37,7 +37,7 @@
</if>
</select>
<select id="customPageList" resultType="cn.stylefeng.guns.sys.modular.db.model.result.DatabaseInfoResult" parameterType="cn.stylefeng.guns.sys.modular.db.model.params.DatabaseInfoParam">
<select id="customPageList" resultType="cn.stylefeng.guns.base.db.model.result.DatabaseInfoResult" parameterType="cn.stylefeng.guns.base.db.model.params.DatabaseInfoParam">
select
<include refid="Base_Column_List"/>
from database_info where 1 = 1
......@@ -46,7 +46,25 @@
</if>
</select>
<select id="customPageMapList" resultType="map" parameterType="cn.stylefeng.guns.sys.modular.db.model.params.DatabaseInfoParam">
<select id="customPageList" resultType="cn.stylefeng.guns.base.db.model.result.DatabaseInfoResult" parameterType="cn.stylefeng.guns.base.db.model.params.DatabaseInfoParam" databaseId="pgsql">
select
<include refid="Base_Column_List"/>
from database_info where 1 = 1
<if test="paramCondition.dbName != null and paramCondition.dbName != ''">
and db_name like '%' || #{paramCondition.dbName} || '%'
</if>
</select>
<select id="customPageList" resultType="cn.stylefeng.guns.base.db.model.result.DatabaseInfoResult" parameterType="cn.stylefeng.guns.base.db.model.params.DatabaseInfoParam" databaseId="oracle">
select
<include refid="Base_Column_List"/>
from database_info where 1 = 1
<if test="paramCondition.dbName != null and paramCondition.dbName != ''">
and db_name like '%' || #{paramCondition.dbName} || '%'
</if>
</select>
<select id="customPageMapList" resultType="map" parameterType="cn.stylefeng.guns.base.db.model.params.DatabaseInfoParam">
select
<include refid="Base_Column_List"/>
from database_info where 1 = 1
......
package cn.stylefeng.guns.sys.modular.db.service.impl;
package cn.stylefeng.guns.db.service;
import cn.stylefeng.guns.base.db.context.SqlSessionFactoryContext;
import cn.stylefeng.guns.base.db.entity.DatabaseInfo;
import cn.stylefeng.guns.base.db.exception.DataSourceInitException;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.sys.modular.db.mapper.DatabaseInfoMapper;
import cn.stylefeng.guns.sys.modular.db.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.sys.modular.db.model.result.DatabaseInfoResult;
import cn.stylefeng.guns.sys.modular.db.service.DatabaseInfoService;
import cn.stylefeng.guns.db.mapper.DatabaseInfoMapper;
import cn.stylefeng.guns.base.db.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.base.db.model.result.DatabaseInfoResult;
import cn.stylefeng.guns.base.db.service.DatabaseInfoService;
import cn.stylefeng.guns.base.tenant.consts.TenantConstants;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
......@@ -19,6 +20,9 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
/**
......@@ -36,6 +40,24 @@ public class DatabaseInfoServiceImpl extends ServiceImpl<DatabaseInfoMapper, Dat
@Transactional(rollbackFor = Exception.class)
public void add(DatabaseInfoParam param) {
//判断数据库连接是否可用
Connection conn = null;
try {
Class.forName(param.getJdbcDriver());
conn = DriverManager.getConnection(
param.getJdbcUrl(), param.getUserName(), param.getPassword());
} catch (Exception e) {
throw new DataSourceInitException(DataSourceInitException.ExEnum.INIT_DATASOURCE_ERROR);
}finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//判断dbName是否重复
String dbName = param.getDbName();
List<DatabaseInfo> db_name = this.list(new QueryWrapper<DatabaseInfo>().eq("db_name", dbName));
......@@ -59,6 +81,13 @@ public class DatabaseInfoServiceImpl extends ServiceImpl<DatabaseInfoMapper, Dat
@Override
public void delete(DatabaseInfoParam param) {
//如果是租户数据库不能删除
DatabaseInfo databaseInfo = this.getById(param.getDbId());
if (databaseInfo.getDbName().startsWith(TenantConstants.TENANT_DB_PREFIX)) {
throw new DataSourceInitException(DataSourceInitException.ExEnum.DELETE_TENANT_ERROR);
}
this.removeById(getKey(param));
}
......
layui.use(['table', 'admin', 'ax'], function () {
var $ = layui.$;
var table = layui.table;
var $ax = layui.ax;
var admin = layui.admin;
/**
* 数据库信息表管理
*/
var DatabaseInfo = {
tableId: "databaseInfoTable"
};
/**
* 初始化表格的列
*/
DatabaseInfo.initColumn = function () {
return [[
{type: 'checkbox'},
{field: 'dbId', hide: true, title: '主键id'},
{field: 'dbName', align: "center", sort: true, title: '数据库名称'},
{field: 'jdbcDriver', align: "center", sort: true, title: '驱动类型', minWidth: 182},
{field: 'userName', align: "center", sort: true, title: '账号'},
{field: 'password', align: "center", sort: true, title: '密码'},
{field: 'jdbcUrl', align: "center", sort: true, title: 'jdbc的url'},
{field: 'remarks', align: "center", sort: true, title: '备注'},
{field: 'createTime', align: "center", sort: true, title: '创建时间', minWidth: 160},
{align: 'center', toolbar: '#tableBar', title: '操作'}
]];
};
/**
* 点击查询按钮
*/
DatabaseInfo.search = function () {
var queryData = {};
queryData['condition'] = $("#condition").val();
table.reload(DatabaseInfo.tableId, {
where: queryData, page: {curr: 1}
});
};
/**
* 弹出添加对话框
*/
DatabaseInfo.openAddDlg = function () {
window.location.href = Feng.ctxPath + '/databaseInfo/add';
};
/**
* 导出excel按钮
*/
DatabaseInfo.exportExcel = function () {
var checkRows = table.checkStatus(DatabaseInfo.tableId);
if (checkRows.data.length === 0) {
Feng.error("请选择要导出的数据");
} else {
table.exportFile(tableResult.config.id, checkRows.data, 'xls');
}
};
/**
* 点击删除
*
* @param data 点击按钮时候的行数据
*/
DatabaseInfo.onDeleteItem = function (data) {
var operation = function () {
var ajax = new $ax(Feng.ctxPath + "/databaseInfo/delete", function (data) {
Feng.success("删除成功!");
table.reload(DatabaseInfo.tableId);
}, function (data) {
Feng.error("删除失败!" + data.responseJSON.message + "!");
});
ajax.set("dbId", data.dbId);
ajax.start();
};
Feng.confirm("是否删除?", operation);
};
// 渲染表格
var tableResult = table.render({
elem: '#' + DatabaseInfo.tableId,
url: Feng.ctxPath + '/databaseInfo/list',
page: true,
height: "full-158",
cellMinWidth: 100,
cols: DatabaseInfo.initColumn()
});
// 搜索按钮点击事件
$('#btnSearch').click(function () {
DatabaseInfo.search();
});
// 添加按钮点击事件
$('#btnAdd').click(function () {
DatabaseInfo.openAddDlg();
});
// 导出excel
$('#btnExp').click(function () {
DatabaseInfo.exportExcel();
});
// 工具条点击事件
table.on('tool(' + DatabaseInfo.tableId + ')', function (obj) {
var data = obj.data;
var layEvent = obj.event;
if (layEvent === 'edit') {
DatabaseInfo.openEditDlg(data);
} else if (layEvent === 'delete') {
DatabaseInfo.onDeleteItem(data);
}
});
});
/**
* 添加或者修改页面
*/
var DatabaseInfoInfoDlg = {
data: {
dbName: "",
jdbcDriver: "",
userName: "",
password: "",
jdbcUrl: "",
remarks: "",
createTime: ""
}
};
layui.use(['form', 'admin', 'ax'], function () {
var $ = layui.jquery;
var $ax = layui.ax;
var form = layui.form;
var admin = layui.admin;
//让当前iframe弹层高度适应
admin.iframeAuto();
//表单提交事件
form.on('submit(btnSubmit)', function (data) {
var ajax = new $ax(Feng.ctxPath + "/databaseInfo/addItem", function (data) {
Feng.success("添加成功!");
window.location.href = Feng.ctxPath + '/databaseInfo'
}, function (data) {
Feng.error("添加失败!" + data.responseJSON.message)
});
ajax.set(data.field);
ajax.start();
return false;
});
//返回按钮
$("#backupPage").click(function () {
window.location.href = Feng.ctxPath + '/databaseInfo'
});
});
\ No newline at end of file
@layout("/common/_container.html",{js:["/assets/modular/databaseInfo/databaseInfo.js"]}){
<div class="layui-body-header">
<span class="layui-body-header-title">数据库信息表管理</span>
</div>
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-sm12 layui-col-md12 layui-col-lg12">
<div class="layui-card">
<div class="layui-card-body">
<div class="layui-form toolbar">
<div class="layui-form-item">
<div class="layui-inline">
<input id="condition" class="layui-input" type="text" placeholder="名称"/>
</div>
<div class="layui-inline">
<button id="btnSearch" class="layui-btn icon-btn"><i class="layui-icon">&#xe615;</i>搜索</button>
<button id="btnAdd" class="layui-btn icon-btn"><i class="layui-icon">&#xe654;</i>添加</button>
<button id="btnExp" class="layui-btn icon-btn"><i class="layui-icon">&#xe67d;</i>导出</button>
</div>
</div>
</div>
<table class="layui-table" id="databaseInfoTable" lay-filter="databaseInfoTable"></table>
</div>
</div>
</div>
</div>
</div>
<script type="text/html" id="tableBar">
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delete">删除</a>
</script>
@}
\ No newline at end of file
@layout("/common/_container.html",{js:["/assets/modular/databaseInfo/databaseInfo_add.js"]}){
<div class="layui-body-header">
<span class="layui-body-header-title">添加</span>
</div>
<div class="layui-fluid " style="">
<div class="layui-card">
<div class="layui-card-body">
<form id="databaseInfoForm" lay-filter="databaseInfoForm" class="layui-form model-form" style="max-width: 700px;margin: 40px auto;">
<input name="dbId" type="hidden"/>
<div class="layui-form-item">
<label class="layui-form-label">数据库名称<span style="color: red;">*</span></label>
<div class="layui-input-block">
<input id="dbName" name="dbName" placeholder="数据库名称" type="text" class="layui-input" lay-verify="required" required autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">JDBC驱动<span style="color: red;">*</span></label>
<div class="layui-input-block">
<select name="jdbcDriver">
<option value="com.mysql.cj.jdbc.Driver">Mysql</option>
<option value="oracle.jdbc.OracleDriver">Oracle</option>
<option value="net.sourceforge.jtds.jdbc.Driver">Sql Server</option>
<option value="org.postgresql.Driver">Postgre Sql</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">JDBC账号<span style="color: red;">*</span></label>
<div class="layui-input-block">
<input id="userName" name="userName" placeholder="账号" type="text" class="layui-input" lay-verify="required" required autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">JDBC密码<span style="color: red;">*</span></label>
<div class="layui-input-block">
<input id="password" name="password" placeholder="密码" type="text" class="layui-input" lay-verify="required" required autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">JDBC URL<span style="color: red;">*</span></label>
<div class="layui-input-block">
<input id="jdbcUrl" name="jdbcUrl" placeholder="jdbc的url" type="text" class="layui-input" lay-verify="required" required autocomplete="off"/>
</div>
<div class="layui-form-mid layui-word-aux" style="margin-left: 120px;">参考:<br/>
oracle:jdbc:oracle:thin:\@127.0.0.1:1521:ORCLCDB<br/>
sql server:jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=guns<br/>
pg sql:jdbc:postgresql://127.0.0.1:5432/guns<br/>
mysql:jdbc:mysql://127.0.0.1:3306/guns?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注</label>
<div class="layui-input-block">
<input id="remarks" name="remarks" placeholder="备注" type="text" class="layui-input" autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-filter="btnSubmit" lay-submit>&emsp;提交&emsp;</button>
<button class="layui-btn layui-btn-primary" type="button" id="backupPage">&emsp;返回&emsp;</button>
</div>
</div>
</form>
</div>
</div>
</div>
@}
\ No newline at end of file
......@@ -11,7 +11,7 @@
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>guns-base-email</artifactId>
<artifactId>guns-excel</artifactId>
<packaging>jar</packaging>
......@@ -20,13 +20,13 @@
<!--基础组件-->
<dependency>
<groupId>cn.stylefeng</groupId>
<artifactId>guns-base</artifactId>
<artifactId>guns-sys</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-excel</artifactId>
</dependency>
</dependencies>
......@@ -34,5 +34,4 @@
<build>
<finalName>${project.artifactId}</finalName>
</build>
</project>
package cn.stylefeng.guns.excel.consts;
/**
* excel模块使用的常量
*
* @author fengshuonan
* @Date 2020/3/18 21:19
*/
public class ExcelConstants {
/**
* excel模板保存的path
*/
public static final String EXCEL_FILE_TEMPLATE_PATH = "/uploadFiles/excelExportTemplate/";
}
package cn.stylefeng.guns.excel.controller;
import cn.stylefeng.guns.base.consts.ConstantsContext;
import cn.stylefeng.guns.excel.entity.ExcelExportDeploy;
import cn.stylefeng.guns.excel.service.ExcelExportDeployService;
import cn.stylefeng.guns.excel.view.JxlsExcelView;
import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.roses.groovy.util.GroovyUtil;
import cn.stylefeng.roses.kernel.model.response.ErrorResponseData;
import cn.stylefeng.roses.kernel.model.response.ResponseData;
import cn.stylefeng.roses.kernel.model.response.SuccessResponseData;
import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* Excel的导出配置
*
* @author fengshuonan
* @Date 2019/12/31 22:09
*/
@Controller
@RequestMapping("/excelExport")
public class ExcelExportController {
@Resource
private ExcelExportDeployService excelExportDeployService;
/**
* 查看数据格式
*
* @param nid 导出模板的唯一标识
* @author fengshuonan
* @Date 2019/12/31 22:12
*/
@ResponseBody
@RequestMapping(value = "/show/{nid}")
public ResponseData showExport(@PathVariable("nid") String nid, HttpServletRequest request) {
ExcelExportDeploy excelExportDeployParam = new ExcelExportDeploy();
excelExportDeployParam.setNid(nid);
ExcelExportDeploy excelExportDeploy = excelExportDeployService.findBySpec(excelExportDeployParam);
//执行groovy脚本中的类的方法
if (excelExportDeploy != null) {
String groovyText = excelExportDeploy.getDataSource();
Object result = GroovyUtil.executeClassMethod(groovyText, "run", new Class[]{HttpServletRequest.class}, new Object[]{request});
return new SuccessResponseData(result);
} else {
return new ErrorResponseData("模版未定义");
}
}
/**
* 导出链接
*
* @author fengshuonan
* @Date 2019/12/31 22:12
*/
@RequestMapping(value = "/export/{nid}")
public ModelAndView export(@PathVariable("nid") String nid, HttpServletRequest request) {
ExcelExportDeploy excelExportDeployParam = new ExcelExportDeploy();
excelExportDeployParam.setNid(nid);
ExcelExportDeploy excelExportDeploy = excelExportDeployService.findBySpec(excelExportDeployParam);
//执行groovy脚本中的类的方法
if (excelExportDeploy != null) {
String groovyText = excelExportDeploy.getDataSource();
Object result = GroovyUtil.executeClassMethod(groovyText, "run", new Class[]{HttpServletRequest.class}, new Object[]{request});
if (result != null) {
Map<String, Object> resultMap = ToolUtil.toMap(result);
//文件输出目录
String path = ConstantsContext.getFileUploadPath() + excelExportDeploy.getTemplate();
//构造响应文件的标题
String title = ToolUtil.stringReplaceBuild(excelExportDeploy.getTitle(), resultMap);
//输出文件格式解析
String type = excelExportDeploy.getTemplate().contains(".xlsx") ? ".xlsx" : ".xls";
return new ModelAndView(new JxlsExcelView(path, title, type), resultMap);
} else {
ModelAndView mav = new ModelAndView(new FastJsonJsonView());
mav.addObject(new ErrorResponseData("脚本执行结果为空"));
return mav;
}
} else {
ModelAndView mav = new ModelAndView(new FastJsonJsonView());
mav.addObject(new ErrorResponseData("模板未定义"));
return mav;
}
}
}
package cn.stylefeng.guns.excel.controller;
import cn.stylefeng.guns.base.consts.ConstantsContext;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.sys.core.util.FileDownload;
import cn.stylefeng.guns.excel.entity.ExcelExportDeploy;
import cn.stylefeng.guns.excel.model.params.ExcelExportDeployParam;
import cn.stylefeng.guns.excel.service.ExcelExportDeployService;
import cn.stylefeng.guns.sys.modular.system.entity.FileInfo;
import cn.stylefeng.guns.sys.modular.system.model.UploadResult;
import cn.stylefeng.guns.sys.modular.system.service.FileInfoService;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.kernel.model.response.ResponseData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import static cn.stylefeng.guns.excel.consts.ExcelConstants.EXCEL_FILE_TEMPLATE_PATH;
/**
* excel导出配置控制器
*
* @author York
* @Date 2019-11-26 16:52:02
*/
@Controller
@RequestMapping("/excelExportDeploy")
public class ExcelExportDeployController extends BaseController {
private String PREFIX = "/modular/excel";
@Autowired
private FileInfoService fileInfoService;
@Autowired
private ExcelExportDeployService excelExportDeployService;
/**
* 跳转到主页面
*
* @author York
* @Date 2019-11-26
*/
@RequestMapping("")
public String index() {
return PREFIX + "/excelExportDeploy.html";
}
/**
* 新增页面
*
* @author York
* @Date 2019-11-26
*/
@RequestMapping("/add")
public String add() {
return PREFIX + "/excelExportDeploy_add.html";
}
/**
* 编辑页面
*
* @author York
* @Date 2019-11-26
*/
@RequestMapping("/edit")
public String edit() {
return PREFIX + "/excelExportDeploy_edit.html";
}
/**
* 新增接口
*
* @author York
* @Date 2019-11-26
*/
@RequestMapping("/addItem")
@ResponseBody
public ResponseData addItem(ExcelExportDeployParam excelExportDeployParam) {
this.excelExportDeployService.add(excelExportDeployParam);
return ResponseData.success();
}
/**
* 编辑接口
*
* @author York
* @Date 2019-11-26
*/
@RequestMapping("/editItem")
@ResponseBody
public ResponseData editItem(ExcelExportDeployParam excelExportDeployParam) {
this.excelExportDeployService.update(excelExportDeployParam);
return ResponseData.success();
}
/**
* 删除接口
*
* @author York
* @Date 2019-11-26
*/
@RequestMapping("/delete")
@ResponseBody
public ResponseData delete(ExcelExportDeployParam excelExportDeployParam) {
this.excelExportDeployService.delete(excelExportDeployParam);
return ResponseData.success();
}
/**
* 上传模版文件
*
* @return
*/
@RequestMapping("/uploadTemplate")
@ResponseBody
public ResponseData uploadTemplate(@RequestPart("file") MultipartFile file) {
try {
if (file == null) {
return ResponseData.error("请选择要上传的模版文件");
}
//上传路径设置
String fileSavePath = ConstantsContext.getFileUploadPath();
fileSavePath = fileSavePath + EXCEL_FILE_TEMPLATE_PATH;
UploadResult uploadResult = fileInfoService.uploadFile(file, fileSavePath);
if (!uploadResult.getOriginalFilename().contains(".xls")) {
return ResponseData.error("上传的模版文件必须为2003版的excel文件");
}
return ResponseData.success(EXCEL_FILE_TEMPLATE_PATH + uploadResult.getFinalName());
} catch (Exception e) {
e.printStackTrace();
return ResponseData.error(e.getMessage());
}
}
/**
* 下载模板文件
*
* @author fengshuonan
* @Date 2019-2-23 10:48:29
*/
@RequestMapping(path = "/download/{fileFinalName}")
public void download(@PathVariable String fileFinalName, HttpServletResponse httpServletResponse) {
//上传路径设置
String fileSavePath = ConstantsContext.getFileUploadPath();
fileSavePath = fileSavePath + EXCEL_FILE_TEMPLATE_PATH;
//查找文件信息
FileInfo fileInfo = fileInfoService.getByFinalName(fileFinalName);
try {
FileDownload.fileDownload(httpServletResponse, fileSavePath + fileFinalName, fileInfo.getFileName());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 查看详情接口
*
* @author York
* @Date 2019-11-26
*/
@RequestMapping("/detail")
@ResponseBody
public ResponseData detail(ExcelExportDeployParam excelExportDeployParam) {
ExcelExportDeploy detail = this.excelExportDeployService.getById(excelExportDeployParam.getId());
return ResponseData.success(detail);
}
/**
* 查询列表
*
* @author York
* @Date 2019-11-26
*/
@ResponseBody
@RequestMapping("/list")
public LayuiPageInfo list(ExcelExportDeployParam excelExportDeployParam) {
return this.excelExportDeployService.findPageBySpec(excelExportDeployParam);
}
}
package cn.stylefeng.guns.excel.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
/**
* <p>
* excel导出配置
* </p>
*
* @author York
* @since 2019-11-26
*/
@TableName("excel_export_deploy")
public class ExcelExportDeploy implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* excel导出配置名称
*/
@TableField("name")
private String name;
/**
* 文件名称
*/
@TableField("title")
private String title;
/**
* 唯一标识
*/
@TableField("nid")
private String nid;
/**
* 模版路径
*/
@TableField("template")
private String template;
/**
* 数据源
*/
@TableField("data_source")
private String dataSource;
/**
* 0开启1关闭
*/
@TableField("status")
private Integer status;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getNid() {
return nid;
}
public void setNid(String nid) {
this.nid = nid;
}
public String getTemplate() {
return template;
}
public void setTemplate(String template) {
this.template = template;
}
public String getDataSource() {
return dataSource;
}
public void setDataSource(String dataSource) {
this.dataSource = dataSource;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Override
public String toString() {
return "ExcelExportDeploy{" + "id=" + id + ", name=" + name + ", title=" + title + ", nid=" + nid
+ ", template=" + template + ", dataSource=" + dataSource + ", status=" + status + "}";
}
}
package cn.stylefeng.guns.excel.mapper;
import cn.stylefeng.guns.excel.entity.ExcelExportDeploy;
import cn.stylefeng.guns.excel.model.params.ExcelExportDeployParam;
import cn.stylefeng.guns.excel.model.result.ExcelExportDeployResult;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* <p>
* excel导出配置 Mapper 接口
* </p>
*
* @author York
* @since 2019-11-26
*/
public interface ExcelExportDeployMapper extends BaseMapper<ExcelExportDeploy> {
/**
* 获取列表
*
* @author York
* @Date 2019-11-26
*/
List<ExcelExportDeployResult> customList(@Param("paramCondition") ExcelExportDeployParam paramCondition);
/**
* 获取map列表
*
* @author York
* @Date 2019-11-26
*/
List<Map<String, Object>> customMapList(@Param("paramCondition") ExcelExportDeployParam paramCondition);
/**
* 获取分页实体列表
*
* @author York
* @Date 2019-11-26
*/
Page<ExcelExportDeployResult> customPageList(@Param("page") Page page, @Param("paramCondition") ExcelExportDeployParam paramCondition);
/**
* 获取分页map列表
*
* @author York
* @Date 2019-11-26
*/
Page<Map<String, Object>> customPageMapList(@Param("page") Page page, @Param("paramCondition") ExcelExportDeployParam paramCondition);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.stylefeng.guns.excel.mapper.ExcelExportDeployMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.stylefeng.guns.excel.entity.ExcelExportDeploy">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="title" property="title"/>
<result column="nid" property="nid"/>
<result column="template" property="template"/>
<result column="data_source" property="dataSource"/>
<result column="status" property="status"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id AS "id", name AS "name", title AS "title", nid AS "nid", template AS "template", data_source AS "dataSource", status AS "status"
</sql>
<select id="customList" resultType="cn.stylefeng.guns.excel.model.result.ExcelExportDeployResult" parameterType="cn.stylefeng.guns.excel.model.params.ExcelExportDeployParam">
select
<include refid="Base_Column_List"/>
from excel_export_deploy where 1 = 1
<if test="paramCondition.id != null and paramCondition.id != ''">
and id like CONCAT('%',#{paramCondition.id},'%')
</if>
<if test="paramCondition.nid != null and paramCondition.nid != ''">
and nid like CONCAT('%',#{paramCondition.nid},'%')
</if>
<if test="paramCondition.status != null and paramCondition.status != ''">
and status like CONCAT('%',#{paramCondition.status},'%')
</if>
</select>
<select id="customMapList" resultType="map" parameterType="cn.stylefeng.guns.excel.model.params.ExcelExportDeployParam">
select
<include refid="Base_Column_List"/>
from excel_export_deploy where 1 = 1
<if test="paramCondition.id != null and paramCondition.id != ''">
and id like CONCAT('%',#{paramCondition.id},'%')
</if>
<if test="paramCondition.nid != null and paramCondition.nid != ''">
and nid like CONCAT('%',#{paramCondition.nid},'%')
</if>
<if test="paramCondition.status != null and paramCondition.status != ''">
and status like CONCAT('%',#{paramCondition.status},'%')
</if>
</select>
<select id="customPageList" resultType="cn.stylefeng.guns.excel.model.result.ExcelExportDeployResult" parameterType="cn.stylefeng.guns.excel.model.params.ExcelExportDeployParam">
select
<include refid="Base_Column_List"/>
from excel_export_deploy where 1 = 1
<if test="paramCondition.id != null and paramCondition.id != ''">
and id like CONCAT('%',#{paramCondition.id},'%')
</if>
<if test="paramCondition.nid != null and paramCondition.nid != ''">
and nid like CONCAT('%',#{paramCondition.nid},'%')
</if>
<if test="paramCondition.status != null and paramCondition.status != ''">
and status like CONCAT('%',#{paramCondition.status},'%')
</if>
</select>
<select id="customPageMapList" resultType="map" parameterType="cn.stylefeng.guns.excel.model.params.ExcelExportDeployParam">
select
<include refid="Base_Column_List"/>
from excel_export_deploy where 1 = 1
<if test="paramCondition.id != null and paramCondition.id != ''">
and id like CONCAT('%',#{paramCondition.id},'%')
</if>
<if test="paramCondition.nid != null and paramCondition.nid != ''">
and nid like CONCAT('%',#{paramCondition.nid},'%')
</if>
<if test="paramCondition.status != null and paramCondition.status != ''">
and status like CONCAT('%',#{paramCondition.status},'%')
</if>
</select>
</mapper>
package cn.stylefeng.guns.excel.model.params;
import cn.stylefeng.roses.kernel.model.validator.BaseValidatingParam;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* excel导出配置
* </p>
*
* @author York
* @since 2019-11-26
*/
@Data
public class ExcelExportDeployParam implements Serializable, BaseValidatingParam {
private static final long serialVersionUID = 1L;
private Integer id;
/**
* excel导出配置名称
*/
private String name;
/**
* 文件名称
*/
private String title;
/**
* 唯一标识
*/
private String nid;
/**
* 模版路径
*/
private String template;
/**
* 数据源
*/
private String dataSource;
/**
* 0开启1关闭
*/
private Integer status;
@Override
public String checkParam() {
return null;
}
}
package cn.stylefeng.guns.excel.model.result;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* excel导出配置
* </p>
*
* @author York
* @since 2019-11-26
*/
@Data
public class ExcelExportDeployResult implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
/**
* excel导出配置名称
*/
private String name;
/**
* 文件名称
*/
private String title;
/**
* 唯一标识
*/
private String nid;
/**
* 模版路径
*/
private String template;
/**
* 数据源
*/
private String dataSource;
/**
* 0开启1关闭
*/
private Integer status;
public String getStatusName() {
if (status == null) {
return null;
}
switch (status) {
case 0:
return "开启";
case 1:
return "关闭";
default:
return "未定义";
}
}
}
package cn.stylefeng.guns.excel.service;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.excel.entity.ExcelExportDeploy;
import cn.stylefeng.guns.excel.model.params.ExcelExportDeployParam;
import cn.stylefeng.guns.excel.model.result.ExcelExportDeployResult;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* excel导出配置 服务类
* </p>
*
* @author York
* @since 2019-11-26
*/
public interface ExcelExportDeployService extends IService<ExcelExportDeploy> {
/**
* 新增
*
* @author York
* @Date 2019-11-26
*/
void add(ExcelExportDeployParam param);
/**
* 删除
*
* @author York
* @Date 2019-11-26
*/
void delete(ExcelExportDeployParam param);
/**
* 更新
*
* @author York
* @Date 2019-11-26
*/
void update(ExcelExportDeployParam param);
/**
* 查询单条数据
*
* @author York
* @Date 2019-11-26
*/
public ExcelExportDeploy findBySpec(ExcelExportDeploy param);
/**
* 查询列表,Specification模式
*
* @author York
* @Date 2019-11-26
*/
List<ExcelExportDeployResult> findListBySpec(ExcelExportDeployParam param);
/**
* 查询分页数据,Specification模式
*
* @author York
* @Date 2019-11-26
*/
LayuiPageInfo findPageBySpec(ExcelExportDeployParam param);
}
package cn.stylefeng.guns.excel.service.impl;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.excel.entity.ExcelExportDeploy;
import cn.stylefeng.guns.excel.mapper.ExcelExportDeployMapper;
import cn.stylefeng.guns.excel.model.params.ExcelExportDeployParam;
import cn.stylefeng.guns.excel.model.result.ExcelExportDeployResult;
import cn.stylefeng.guns.excel.service.ExcelExportDeployService;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.io.Serializable;
import java.util.List;
/**
* <p>
* excel导出配置 服务实现类
* </p>
*
* @author York
* @since 2019-11-26
*/
@Service
public class ExcelExportDeployServiceImpl extends ServiceImpl<ExcelExportDeployMapper, ExcelExportDeploy> implements ExcelExportDeployService {
@Override
public void add(ExcelExportDeployParam param) {
ExcelExportDeploy entity = getEntity(param);
this.save(entity);
}
@Override
public void delete(ExcelExportDeployParam param) {
this.removeById(getKey(param));
}
@Override
public void update(ExcelExportDeployParam param) {
ExcelExportDeploy oldEntity = getOldEntity(param);
ExcelExportDeploy newEntity = getEntity(param);
ToolUtil.copyProperties(newEntity, oldEntity);
this.updateById(newEntity);
}
@Override
public ExcelExportDeploy findBySpec(ExcelExportDeploy param) {
QueryWrapper<ExcelExportDeploy> queryWrapper = new QueryWrapper<>();
queryWrapper.setEntity(param);
return baseMapper.selectOne(queryWrapper);
}
@Override
public List<ExcelExportDeployResult> findListBySpec(ExcelExportDeployParam param) {
return null;
}
@Override
public LayuiPageInfo findPageBySpec(ExcelExportDeployParam param) {
Page<ExcelExportDeployResult> pageContext = getPageContext();
IPage<ExcelExportDeployResult> page = this.baseMapper.customPageList(pageContext, param);
return LayuiPageFactory.createPageInfo(page);
}
private Serializable getKey(ExcelExportDeployParam param) {
return param.getId();
}
private Page<ExcelExportDeployResult> getPageContext() {
return LayuiPageFactory.defaultPage();
}
private ExcelExportDeploy getOldEntity(ExcelExportDeployParam param) {
return this.getById(getKey(param));
}
private ExcelExportDeploy getEntity(ExcelExportDeployParam param) {
ExcelExportDeploy entity = new ExcelExportDeploy();
ToolUtil.copyProperties(param, entity);
return entity;
}
}
layui.use(['table', 'admin', 'ax', 'func'], function () {
var $ = layui.$;
var table = layui.table;
var $ax = layui.ax;
var admin = layui.admin;
var func = layui.func;
/**
* excel导出配置管理
*/
var ExcelExportDeploy = {
tableId: "excelExportDeployTable"
};
/**
* 初始化表格的列
*/
ExcelExportDeploy.initColumn = function () {
return [[
{field: 'id', hide: true, title: ''},
{field: 'name', sort: true, title: 'excel导出配置名称'},
{field: 'title', sort: true, title: '文件名称'},
{field: 'nid', sort: true, title: '唯一标识'},
{templet: '#template', sort: true, title: '模版文件'},
{templet: '#showUrl', sort: true, title: '数据查询'},
{templet: '#exportUrl', sort: true, title: '导出链接'},
{field: 'statusName', sort: true, title: '状态'},
{align: 'center', toolbar: '#tableBar', title: '操作'}
]];
};
/**
* 点击查询按钮
*/
ExcelExportDeploy.search = function () {
var queryData = {};
queryData['condition'] = $("#condition").val();
table.reload(ExcelExportDeploy.tableId, {
where: queryData, page: {curr: 1}
});
};
/**
* 弹出添加对话框
*/
ExcelExportDeploy.openAddDlg = function () {
func.open({
title: '添加excel导出配置',
content: Feng.ctxPath + '/excelExportDeploy/add',
tableId: ExcelExportDeploy.tableId
});
};
/**
* 点击编辑
*
* @param data 点击按钮时候的行数据
*/
ExcelExportDeploy.openEditDlg = function (data) {
func.open({
title: '修改excel导出配置',
content: Feng.ctxPath + '/excelExportDeploy/edit?id=' + data.id,
tableId: ExcelExportDeploy.tableId
});
};
/**
* 导出excel按钮
*/
ExcelExportDeploy.exportExcel = function () {
var checkRows = table.checkStatus(ExcelExportDeploy.tableId);
if (checkRows.data.length === 0) {
Feng.error("请选择要导出的数据");
} else {
table.exportFile(tableResult.config.id, checkRows.data, 'xls');
}
};
/**
* 点击删除
*
* @param data 点击按钮时候的行数据
*/
ExcelExportDeploy.onDeleteItem = function (data) {
var operation = function () {
var ajax = new $ax(Feng.ctxPath + "/excelExportDeploy/delete", function (data) {
Feng.success("删除成功!");
table.reload(ExcelExportDeploy.tableId);
}, function (data) {
Feng.error("删除失败!" + data.responseJSON.message + "!");
});
ajax.set("id", data.id);
ajax.start();
};
Feng.confirm("是否删除?", operation);
};
// 渲染表格
var tableResult = table.render({
elem: '#' + ExcelExportDeploy.tableId,
url: Feng.ctxPath + '/excelExportDeploy/list',
page: true,
height: "full-158",
cellMinWidth: 100,
cols: ExcelExportDeploy.initColumn()
});
// 搜索按钮点击事件
$('#btnSearch').click(function () {
ExcelExportDeploy.search();
});
// 添加按钮点击事件
$('#btnAdd').click(function () {
ExcelExportDeploy.openAddDlg();
});
// 导出excel
$('#btnExp').click(function () {
ExcelExportDeploy.exportExcel();
});
// 工具条点击事件
table.on('tool(' + ExcelExportDeploy.tableId + ')', function (obj) {
var data = obj.data;
var layEvent = obj.event;
if (layEvent === 'edit') {
ExcelExportDeploy.openEditDlg(data);
} else if (layEvent === 'delete') {
ExcelExportDeploy.onDeleteItem(data);
}
});
});
/**
* 添加或者修改页面
*/
var ExcelExportDeployInfoDlg = {
data : {
name : "",
title : "",
nid : "",
template : "",
dataSource : "",
status : ""
}
};
layui.use([ 'form', 'admin', 'ax', 'upload' ], function() {
var $ = layui.jquery;
var $ax = layui.ax;
var form = layui.form;
var admin = layui.admin;
var upload = layui.upload;
// 执行上传实例
var uploadInst = upload.render({
elem : '#templateUplod', // 绑定元素
url : 'uploadTemplate', // 上传接口
accept : 'file', // 只允许上传图片
acceptMime : 'file/xls', // 只筛选图片
done : function(res) {
// 上传完毕回调
if (res.code == 200) {
$("#template").val(res.data);
Feng.success("上传成功!");
$("#src").text(res.data);
$("#templateUplod").text("重新上传");
} else {
Feng.error("上传失败!" + res.message)
}
},
error : function() {
// 请求异常回调
Feng.error("上传失败!")
}
});
// 表单提交事件
form.on('submit(btnSubmit)', function(data) {
var ajax = new $ax(Feng.ctxPath + "/excelExportDeploy/addItem",
function(data) {
Feng.success("添加成功!");
// 传给上个页面,刷新table用
admin.putTempData('formOk', true);
// 关掉对话框
admin.closeThisDialog();
}, function(data) {
Feng.error("添加失败!" + data.responseJSON.message)
});
ajax.set(data.field);
ajax.start();
return false;
});
});
\ No newline at end of file
/**
* 详情对话框
*/
var ExcelExportDeployInfoDlg = {
data: {
name: "",
title: "",
nid: "",
template: "",
dataSource: "",
status: ""
}
};
layui.use(['form', 'admin', 'ax', 'upload'], function () {
var $ = layui.jquery;
var $ax = layui.ax;
var form = layui.form;
var admin = layui.admin;
var upload = layui.upload;
// 执行上传实例
var uploadInst = upload.render({
elem : '#templateUplod', // 绑定元素
url : 'uploadTemplate', // 上传接口
accept : 'file', // 只允许上传图片
acceptMime : 'file/xls', // 只筛选图片
done : function(res) {
// 上传完毕回调
if (res.code == 200) {
$("#template").val(res.data);
Feng.success("上传成功!");
$("#src").text(res.data);
$("#templateUplod").text("重新上传");
} else {
Feng.error("上传失败!" + res.message)
}
},
error : function() {
// 请求异常回调
Feng.error("上传失败!")
}
});
//获取详情信息,填充表单
var ajax = new $ax(Feng.ctxPath + "/excelExportDeploy/detail?id=" + Feng.getUrlParam("id"));
var result = ajax.start();
form.val('excelExportDeployForm', result.data);
$("#src").text(result.data.template);
//表单提交事件
form.on('submit(btnSubmit)', function (data) {
var ajax = new $ax(Feng.ctxPath + "/excelExportDeploy/editItem", function (data) {
Feng.success("更新成功!");
//传给上个页面,刷新table用
admin.putTempData('formOk', true);
//关掉对话框
admin.closeThisDialog();
}, function (data) {
Feng.error("更新失败!" + data.responseJSON.message)
});
ajax.set(data.field);
ajax.start();
return false;
});
});
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment