Commit b516bd52 authored by 赵啸非's avatar 赵啸非

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	datav-manager/pom.xml
parents c2085785 ee40adaa
......@@ -53,16 +53,7 @@
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>4.8.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
......
package com.mortals.xhx.system;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.model.AccessLogPdu;
import com.mortals.framework.model.BizLogPdu;
import com.mortals.framework.model.ErrorLogPdu;
import com.mortals.framework.model.OperateLogPdu;
import com.mortals.framework.service.IMessageProduceService;
import com.mortals.xhx.common.keys.QueueKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Primary
@Slf4j
public class MessageProducer implements IMessageProduceService {
@Autowired
private RabbitTemplate rabbitTemplate;
public void syncAccessSend(AccessLogPdu accessLogPdu) {
//new Message(JSON.toJSONString(accessLogPdu).getBytes(StandardCharsets.UTF_8))
//rabbitTemplate.send(QueueKey.EXCHANGE, QueueKey.ACCESS_LOG_QUEUE,new Message(JSON.toJSONString(accessLogPdu).getBytes(StandardCharsets.UTF_8)));
rabbitTemplate.convertAndSend(QueueKey.EXCHANGE, QueueKey.ACCESS_LOG_QUEUE, JSON.toJSONString(accessLogPdu));
//rabbitTemplate.convertAndSend(QueueKey.EXCHANGE, QueueKey.ACCESS_LOG_QUEUE, accessLogPdu);
}
@Override
public void syncBizSend(BizLogPdu bizLogPdu) {
rabbitTemplate.convertAndSend(QueueKey.EXCHANGE, QueueKey.BIZ_LOG_QUEUE, JSON.toJSONString(bizLogPdu));
}
@Override
public void syncErrorSend(ErrorLogPdu errorLogPdu) {
rabbitTemplate.convertAndSend(QueueKey.EXCHANGE, QueueKey.ERROR_LOG_QUEUE, JSON.toJSONString(errorLogPdu));
}
@Override
public void syncOperSend(OperateLogPdu operLogPdu) {
log.info(JSON.toJSONString(operLogPdu));
rabbitTemplate.convertAndSend(QueueKey.EXCHANGE, QueueKey.OPERATION_LOG_QUEUE, JSON.toJSONString(operLogPdu));
}
}
......@@ -29,7 +29,7 @@
<profiles.datasource.uri>
<![CDATA[jdbc:mysql://192.168.0.98:3306/datav_platform?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong]]></profiles.datasource.uri>
<profiles.datasource.username>root</profiles.datasource.username>
<profiles.datasource.password>nacos@2020</profiles.datasource.password>
<profiles.datasource.password>xhx@2022</profiles.datasource.password>
<profiles.redis.uri>192.168.0.252</profiles.redis.uri>
<profiles.redis.port>6379</profiles.redis.port>
<profiles.redis.username></profiles.redis.username>
......@@ -50,12 +50,7 @@
<profiles.datasource.uri>
<![CDATA[jdbc:mysql://192.168.0.98:3306/datav_platform?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong]]></profiles.datasource.uri>
<profiles.datasource.username>root</profiles.datasource.username>
<profiles.datasource.password>nacos@2020</profiles.datasource.password>
<profiles.rabbitmq.host>192.168.0.98</profiles.rabbitmq.host>
<profiles.rabbitmq.port>5672</profiles.rabbitmq.port>
<profiles.rabbitmq.username>taxi_mq</profiles.rabbitmq.username>
<profiles.rabbitmq.password>admin@2020</profiles.rabbitmq.password>
<profiles.rabbitmq.virtualhost>/</profiles.rabbitmq.virtualhost>
<profiles.datasource.password>xhx@2022</profiles.datasource.password>
<profiles.redis.uri>192.168.0.252</profiles.redis.uri>
<profiles.redis.port>6379</profiles.redis.port>
<profiles.redis.username></profiles.redis.username>
......@@ -73,10 +68,10 @@
<profiles.active>product</profiles.active>
<profiles.server.port>17002</profiles.server.port>
<profiles.datasource.uri>
<![CDATA[jdbc:mysql://192.168.0.98:3306/datav_platform?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong]]></profiles.datasource.uri>
<![CDATA[jdbc:mysql://127.0.0.1:3306/datav_platform?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong]]></profiles.datasource.uri>
<profiles.datasource.username>root</profiles.datasource.username>
<profiles.datasource.password>nacos@2020</profiles.datasource.password>
<profiles.redis.uri>192.168.0.252</profiles.redis.uri>
<profiles.redis.uri>127.0.0.1</profiles.redis.uri>
<profiles.redis.port>6379</profiles.redis.port>
<profiles.redis.username></profiles.redis.username>
<profiles.redis.password>hotel@2020</profiles.redis.password>
......@@ -94,14 +89,9 @@
<profiles.active>yibin</profiles.active>
<profiles.server.port>17003</profiles.server.port>
<profiles.datasource.uri>
<![CDATA[jdbc:mysql://172.15.28.122:3306/datav_platform?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong]]></profiles.datasource.uri>
<![CDATA[jdbc:mysql://172.15.28.121:3306/datav_platform?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong]]></profiles.datasource.uri>
<profiles.datasource.username>root</profiles.datasource.username>
<profiles.datasource.password>xhx@2022</profiles.datasource.password>
<profiles.rabbitmq.host>172.15.28.117</profiles.rabbitmq.host>
<profiles.rabbitmq.port>5672</profiles.rabbitmq.port>
<profiles.rabbitmq.username>taxi_mq</profiles.rabbitmq.username>
<profiles.rabbitmq.password>admin@2020</profiles.rabbitmq.password>
<profiles.rabbitmq.virtualhost>/</profiles.rabbitmq.virtualhost>
<profiles.redis.uri>172.15.28.120</profiles.redis.uri>
<profiles.redis.port>6379</profiles.redis.port>
<profiles.redis.username></profiles.redis.username>
......
......@@ -4,9 +4,6 @@ import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import com.mortals.framework.model.OperateLogPdu;
import com.mortals.framework.service.IMessageProduceService;
import com.mortals.xhx.system.MessageProducer;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
......@@ -16,7 +13,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
......@@ -34,27 +30,12 @@ public class OperlogAspect extends FileLogServiceImpl implements ILogService {
@Autowired
private OperLogService operLogService;
@Autowired
private IMessageProduceService messageProducer;
@Override
public void doHandlerLog(String platformMark, Long userId, String userName, String loginName, String requestUrl,
String content, String ip, Date logDate) {
String content, String ip, Date logDate) {
super.doHandlerLog(platformMark, userId, userName, loginName, requestUrl, content, ip, logDate);
operLogService.insertOperLog(ip, requestUrl, userId, userName, loginName, content);
OperateLogPdu operateLogPdu = new OperateLogPdu();
operateLogPdu.initAttrValue();
operateLogPdu.setIp(ip);
operateLogPdu.setRequestUrl(requestUrl);
operateLogPdu.setUserId(userId);
operateLogPdu.setUserName(userName);
operateLogPdu.setLoginName(loginName);
operateLogPdu.setPlatformMark(platformMark);
operateLogPdu.setLogDate(logDate);
operateLogPdu.setContent(content);
operateLogPdu.setOperType(1);
messageProducer.syncOperSend(operateLogPdu);
}
@Override
......@@ -62,8 +43,6 @@ public class OperlogAspect extends FileLogServiceImpl implements ILogService {
// operLogService.insertOperLog(ip, requestUrl, null, "", loginName,
// content);
this.doHandlerLog(platformMark, null, "", loginName, requestUrl, content, ip, new Date());
}
@Pointcut("execution(public * com.mortals.xhx..*Controller.*(..))")
......
......@@ -27,8 +27,8 @@ import java.util.Map;
* @author: zxfei
* @date: 2022/4/20 9:24
*/
//@Aspect
//@Component
@Aspect
@Component
@Slf4j
@Order(1)
@Profile({"default", "develop", "test"})
......
......@@ -124,6 +124,11 @@ public class AuthTokenServiceImpl implements IAuthTokenService {
return siteIds;
}
@Override
public String getAreaCodes() {
return null;
}
@Override
public Long getCustomerJoinId() {
return null;
......
//package com.mortals.xhx.base.framework.security;
//
//import org.springframework.security.core.Authentication;
//import org.springframework.security.core.context.SecurityContextHolder;
//import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
//
///**
// * 安全服务工具类
// *
// * @author zxfei
// */
//public class SecurityUtils {
//
//
// /**
// * 获取Authentication
// */
// public static Authentication getAuthentication() {
// return SecurityContextHolder.getContext().getAuthentication();
// }
//
// /**
// * 生成BCryptPasswordEncoder密码
// *
// * @param password 密码
// * @return 加密字符串
// */
// public static String encryptPassword(String password) {
// BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
// return passwordEncoder.encode(password);
// }
//
// /**
// * 判断密码是否相同
// *
// * @param rawPassword 真实密码
// * @param encodedPassword 加密后字符
// * @return 结果
// */
// public static boolean matchesPassword(String rawPassword, String encodedPassword) {
// BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
// return passwordEncoder.matches(rawPassword, encodedPassword);
// }
//
// /**
// * 是否为管理员
// *
// * @param userId 用户ID
// * @return 结果
// */
// public static boolean isAdmin(Long userId) {
// return userId != null && 1L == userId;
// }
//}
package com.mortals.xhx.base.framework.security;
import org.apache.tomcat.util.net.openssl.ciphers.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* 安全服务工具类
*
* @author zxfei
*/
public class SecurityUtils {
/**
* 获取Authentication
*/
public static Authentication getAuthentication() {
return null;
}
/**
* 生成BCryptPasswordEncoder密码
*
* @param password 密码
* @return 加密字符串
*/
public static String encryptPassword(String password) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder.encode(password);
}
/**
* 判断密码是否相同
*
* @param rawPassword 真实密码
* @param encodedPassword 加密后字符
* @return 结果
*/
public static boolean matchesPassword(String rawPassword, String encodedPassword) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder.matches(rawPassword, encodedPassword);
}
/**
* 是否为管理员
*
* @param userId 用户ID
* @return 结果
*/
public static boolean isAdmin(Long userId) {
return userId != null && 1L == userId;
}
}
......@@ -2,10 +2,13 @@ package com.mortals.xhx.base.login.web;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.IAuthTokenService;
import com.mortals.framework.util.DateUtils;
import com.mortals.framework.util.StringUtils;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.valid.service.ValidCodeService;
import com.mortals.xhx.common.utils.LoginAESUtil;
import com.mortals.xhx.module.customer.model.CustomerEntity;
import com.mortals.xhx.module.customer.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -24,6 +27,11 @@ public class CustomerLoginController extends BaseCRUDJsonBodyMappingController<C
private CustomerService customerService;
@Autowired
private IAuthTokenService authTokenService;
@Autowired
private ValidCodeService validCodeService;
private static final String AES_KEY = "0000000671595991";
private static final String AES_IV = "tdrdadq59tbss5n7";
@RequestMapping("login")
public String login(@RequestBody LoginForm loginForm) throws Exception {
......@@ -37,9 +45,17 @@ public class CustomerLoginController extends BaseCRUDJsonBodyMappingController<C
ret.put(KEY_RESULT_MSG, "未获取到用户信息,请重新登录");
return ret.toJSONString();
}
if(loginForm.getType()!=null && loginForm.getType()==2){
loginName = LoginAESUtil.decrypt(loginName,AES_KEY,AES_IV,LoginAESUtil.AES_CBC);
password = LoginAESUtil.decrypt(password,AES_KEY,AES_IV,LoginAESUtil.AES_CBC);
}
CustomerEntity customerEntity = null;
try {
loginForm.validate();
boolean validCode = validCodeService.doCheckImageValidCode(loginForm.getMark(),super.getRequestIP(request),loginForm.getSecurityCode());
if(!validCode){
throw new AppException("验证码错误");
}
customerEntity = customerService.doLogin(loginName, password, ip);
customerEntity.setLastLoginAddress(ip);
customerEntity.setLoginTime(System.currentTimeMillis());
......@@ -62,12 +78,8 @@ public class CustomerLoginController extends BaseCRUDJsonBodyMappingController<C
}
@RequestMapping("logout")
public String logout() throws Exception {
public void logout() throws Exception {
recordSysLog(request, "退出登录");
super.removeCurrUser(request);
JSONObject ret = new JSONObject();
ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
ret.put(KEY_RESULT_MSG, "用户退出系统成功!");
return ret.toJSONString();
}
}
......@@ -4,6 +4,7 @@ import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.ap.GlobalSysInfo;
import com.mortals.framework.ap.SysConstains;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.ITokenService;
import com.mortals.framework.service.IUser;
......@@ -19,6 +20,7 @@ import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.base.system.valid.service.ValidCodeService;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.common.utils.LoginAESUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -48,6 +50,9 @@ public class LoginController extends BaseCRUDJsonBodyMappingController<UserServi
@Autowired
private ICacheService cacheService;
private static final String AES_KEY = "0000000671595991";
private static final String AES_IV = "tdrdadq59tbss5n7";
private static Log logger = LogFactory.getLog(LoginController.class);
@RequestMapping("login")
......@@ -63,10 +68,17 @@ public class LoginController extends BaseCRUDJsonBodyMappingController<UserServi
ret.put(KEY_RESULT_MSG, "未获取到用户信息,请重新登录");
return ret.toJSONString();
}
if(loginForm.getType()!=null && loginForm.getType()==2){
loginName = LoginAESUtil.decrypt(loginName,AES_KEY,AES_IV,LoginAESUtil.AES_CBC);
password = LoginAESUtil.decrypt(password,AES_KEY,AES_IV,LoginAESUtil.AES_CBC);
}
UserEntity userEntity = null;
try {
loginForm.validate();
boolean validCode = validCodeService.doCheckImageValidCode(loginForm.getMark(),super.getRequestIP(request),loginForm.getSecurityCode());
if(!validCode){
throw new AppException("验证码错误");
}
userEntity = userService.doLogin(loginName, password, ip);
userEntity.setLastLoginAddress(ip);
//saveCurrUser(request, response, userEntity);
......@@ -109,13 +121,9 @@ public class LoginController extends BaseCRUDJsonBodyMappingController<UserServi
}
@RequestMapping("logout")
public String logout() throws Exception {
public void logout() throws Exception {
recordSysLog(request, "退出登录");
super.removeCurrUser(request);
JSONObject ret = new JSONObject();
ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
ret.put(KEY_RESULT_MSG, "用户退出系统成功!");
return ret.toJSONString();
}
@RequestMapping("index")
......
......@@ -10,6 +10,10 @@ public class LoginForm extends BaseForm {
private String securityCode;
private String mark;
/** 加密方式 1不加密,2加密*/
private Integer type;
public String getLoginName() {
return loginName;
}
......@@ -35,6 +39,22 @@ public class LoginForm extends BaseForm {
this.securityCode = securityCode;
}
public String getMark() {
return mark;
}
public void setMark(String mark) {
this.mark = mark;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
@Override
public String toString() {
return "loginName:" + this.loginName + " password:" + this.password;
......@@ -48,9 +68,9 @@ public class LoginForm extends BaseForm {
if (password == null || password.trim().length() == 0) {
throw new AppException("密码不能为空!");
}
// if (securityCode == null || securityCode.trim().length() == 0) {
// throw new AppException("验证码不能为空!");
// }
if (securityCode == null || securityCode.trim().length() == 0) {
throw new AppException("验证码不能为空!");
}
return super.validate();
}
}
......@@ -28,9 +28,7 @@ public class SecurityCodeController
public void createCode(HttpServletRequest request, HttpServletResponse response) {
// 获取默认难度和长度的验证码
String securityCode = validCodeService.createImageValidCode(request.getSession().getId(),
super.getRequestIP(request));
String securityCode = validCodeService.createImageValidCode(request.getParameter("mark"),super.getRequestIP(request));
// int imageType = ParamUtil.getInt("securityImage", 1);
int imageType = 0;
switch (imageType) {
......
package com.mortals.xhx.base.system.user.dao;
import com.mortals.framework.dao.ICRUDDao;
import com.mortals.xhx.base.system.user.model.UserPwdRecordEntity;
/**
* 用户密码修改记录Dao
* 用户密码修改记录 DAO接口
*
* @author zxfei
* @date 2023-07-26
*/
public interface UserPwdRecordDao extends ICRUDDao<UserPwdRecordEntity,Long>{
}
package com.mortals.xhx.base.system.user.dao.ibatis;
import com.mortals.framework.dao.ibatis.BaseCRUDDaoMybatis;
import com.mortals.xhx.base.system.user.dao.UserPwdRecordDao;
import com.mortals.xhx.base.system.user.model.UserPwdRecordEntity;
import org.springframework.stereotype.Repository;
/**
* 用户密码修改记录DaoImpl DAO接口
*
* @author zxfei
* @date 2023-07-26
*/
@Repository("userPwdRecordDao")
public class UserPwdRecordDaoImpl extends BaseCRUDDaoMybatis<UserPwdRecordEntity,Long> implements UserPwdRecordDao {
}
......@@ -126,6 +126,27 @@ public class UserEntity extends UserEntityExt implements IUser {
*/
private String lastModPwdAddr;
/**
* 密码盐值
*/
private String saltKey;
/**
* 最后一次修改密码时间
*/
private Date lastUpdatePwdTime;
/**
* 当日登录失败数
*/
private Integer errorCount;
/**
* 登录锁定状态0未锁定1已锁定
*/
private Integer loginLock;
/**
* 锁定时间
*/
private Date lockTime;
public UserEntity(){
}
......@@ -333,6 +354,11 @@ public class UserEntity extends UserEntityExt implements IUser {
return null;
}
@Override
public String getAreaCodes() {
return null;
}
/**
* 设置 站点id
* @param siteId
......@@ -491,6 +517,46 @@ public class UserEntity extends UserEntityExt implements IUser {
this.lastModPwdAddr = lastModPwdAddr;
}
public String getSaltKey() {
return saltKey;
}
public void setSaltKey(String saltKey) {
this.saltKey = saltKey;
}
public Date getLastUpdatePwdTime() {
return lastUpdatePwdTime;
}
public void setLastUpdatePwdTime(Date lastUpdatePwdTime) {
this.lastUpdatePwdTime = lastUpdatePwdTime;
}
public Integer getErrorCount() {
return errorCount;
}
public void setErrorCount(Integer errorCount) {
this.errorCount = errorCount;
}
public Integer getLoginLock() {
return loginLock;
}
public void setLoginLock(Integer loginLock) {
this.loginLock = loginLock;
}
public Date getLockTime() {
return lockTime;
}
public void setLockTime(Date lockTime) {
this.lockTime = lockTime;
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), loginName, loginPwd, loginPwd1, loginPwd2, loginPwd3, loginLimitAddress, realName, mobile, phone, email, qq, userType, status, customerId, createTime, createUserId, createUserName, lastLoginTime, lastLoginAddress, lastModPwdTime, lastModPwdAddr);
......
package com.mortals.xhx.base.system.user.model;
import com.mortals.xhx.base.system.user.model.vo.UserPwdRecordVo;
import lombok.Data;
/**
* 用户密码修改记录实体对象
*
* @author zxfei
* @date 2023-07-26
*/
@Data
public class UserPwdRecordEntity extends UserPwdRecordVo {
private static final long serialVersionUID = 1L;
/**
* 用户ID,主键,自增长
*/
private Long userId;
/**
* 登录名
*/
private String loginName;
/**
* 登录密码,使用md5双次加密
*/
private String loginPwd;
@Override
public int hashCode() {
return this.getId().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (obj instanceof UserPwdRecordEntity) {
UserPwdRecordEntity tmp = (UserPwdRecordEntity) obj;
if (this.getId() == tmp.getId()) {
return true;
}
}
return false;
}
public void initAttrValue(){
this.userId = -1L;
this.loginName = "";
this.loginPwd = "";
}
}
\ No newline at end of file
package com.mortals.xhx.base.system.user.model.vo;
import com.mortals.framework.model.BaseEntityLong;
import lombok.Data;
/**
* 用户密码修改记录视图对象
*
* @author zxfei
* @date 2023-07-26
*/
@Data
public class UserPwdRecordVo extends BaseEntityLong {
}
\ No newline at end of file
......@@ -11,12 +11,14 @@ package com.mortals.xhx.base.system.user.service.impl;
import com.mortals.framework.ap.SysConstains;
import com.mortals.framework.common.code.UserType;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.BaseEntity;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.OrderCol;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.Result;
import com.mortals.framework.service.IUser;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.util.DateUtils;
import com.mortals.framework.util.SecurityCode;
import com.mortals.framework.util.SecurityUtil;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.base.system.menu.model.MenuEntity;
......@@ -26,15 +28,16 @@ import com.mortals.xhx.base.system.resource.service.ResourceService;
import com.mortals.xhx.base.system.role.dao.RoleUserDao;
import com.mortals.xhx.base.system.role.model.RoleUserEntity;
import com.mortals.xhx.base.system.user.dao.UserDao;
import com.mortals.xhx.base.system.user.dao.UserPwdRecordDao;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.base.system.user.model.UserPwdRecordEntity;
import com.mortals.xhx.base.system.user.model.UserPwdRecordQuery;
import com.mortals.xhx.base.system.user.model.UserQuery;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.module.customer.model.CustomerEntity;
import com.mortals.xhx.common.utils.Solution;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.*;
......@@ -56,11 +59,17 @@ public class UserServiceImpl extends AbstractCRUDServiceImpl<UserDao, UserEntity
private ResourceService resourceService;
@Autowired
private RoleUserDao roleUserDao;
@Autowired
private UserPwdRecordDao userPwdRecordDao;
private void doHandlerUser(UserEntity entity) throws AppException {
if (StringUtils.isNotEmpty(entity.getLoginPwd())) {
try {
entity.setLoginPwd(SecurityUtil.md5DoubleEncoding(entity.getLoginPwd()));
String saltKey = SecurityCode.getSecurityCode(6,SecurityCode.SecurityCodeLevel.Medium,false);
String newPwd = entity.getLoginPwd() + saltKey;
newPwd = SecurityUtil.md5DoubleEncoding(newPwd);
entity.setLoginPwd(newPwd);
entity.setSaltKey(saltKey);
} catch (Exception e) {
throw new AppException("密码转换异常");
}
......@@ -167,9 +176,41 @@ public class UserServiceImpl extends AbstractCRUDServiceImpl<UserDao, UserEntity
if (sysUser == null || !sysUser.getLoginName().equals(loginName)) {
throw new AppException("用户名不存在!");
}
if(sysUser.getErrorCount()==null){
sysUser.setErrorCount(0);
}
if(sysUser.getLoginLock()==null){
sysUser.setLoginLock(0);
}
if(sysUser.getLoginLock() == 1 && sysUser.getLockTime()!=null){
String nowStr = DateUtils.getCurrStrDate();
String loginDateStr = DateUtils.getDateTime(sysUser.getLockTime(),"yyyy-MM-dd");
if(nowStr.equals(loginDateStr)) {
throw new AppException("此账号当天密码错误次数已达上限,已被锁定");
}
}
try {
if(StringUtils.isNotEmpty(sysUser.getSaltKey())) {
password += sysUser.getSaltKey();
}
if (!sysUser.getLoginPwd().equals(SecurityUtil.md5DoubleEncoding(password))) {
UserEntity update = new UserEntity();
update.setId(sysUser.getId());
update.setErrorCount(sysUser.getErrorCount()+1);
if(update.getErrorCount()==5){
update.setLoginLock(1);
update.setLockTime(new Date());
}
this.dao.update(update);
throw new AppException("登录密码错误!");
}else {
if(sysUser.getLastUpdatePwdTime()!=null) {
long day = DateUtils.getBetween(sysUser.getLastUpdatePwdTime(), new Date(), 2);
if (day >= 90) {
throw new AppException("密码已超过三个月没有更改,请修改以后再登录");
}
}
}
} catch (Exception e) {
throw new AppException("密码验认出错!", e);
......@@ -178,6 +219,7 @@ public class UserServiceImpl extends AbstractCRUDServiceImpl<UserDao, UserEntity
update.setId(sysUser.getId());
update.setLastLoginAddress(loginIp);
update.setLastLoginTime(new Date());
update.setErrorCount(0);
this.dao.update(update);
return sysUser;
}
......@@ -316,22 +358,55 @@ public class UserServiceImpl extends AbstractCRUDServiceImpl<UserDao, UserEntity
throw new AppException("帐号错误!");
}
try {
if(StringUtils.isNotEmpty(sysUser.getSaltKey())) {
oldPwd += sysUser.getSaltKey();
}
if (!sysUser.getLoginPwd().equals(SecurityUtil.md5DoubleEncoding(oldPwd))) {
throw new AppException("原始密码错误!");
}
if(!Solution.strongPasswordCheckerII(newPwd)){
throw new AppException("新密码至少八位以上,包含大小写加特殊字符加数字");
}
} catch (Exception e) {
throw new AppException("密码验认出错!", e);
}
try {
if(StringUtils.isEmpty(sysUser.getSaltKey())) {
String saltKey = SecurityCode.getSecurityCode(6,SecurityCode.SecurityCodeLevel.Medium,false);
sysUser.setSaltKey(saltKey);
}
newPwd += sysUser.getSaltKey();
sysUser.setLoginPwd(SecurityUtil.md5DoubleEncoding(newPwd));
sysUser.setLoginPwd3(sysUser.getLoginPwd2());
sysUser.setLoginPwd2(sysUser.getLoginPwd1());
sysUser.setLoginPwd1(sysUser.getLoginPwd());
sysUser.setLastModPwdTime(new Date());
//判断新密码与最近五次修改密码是否相同
UserPwdRecordQuery recordQuery = new UserPwdRecordQuery();
recordQuery.setUserId(sysUser.getId());
recordQuery.setOrderColList(new ArrayList<OrderCol>() {
{
add(new OrderCol("a.createTime", "desc"));
}
});
List<UserPwdRecordEntity> recordEntityList = userPwdRecordDao.getList(recordQuery,0,5);
if(CollectionUtils.isNotEmpty(recordEntityList)){
for(UserPwdRecordEntity item:recordEntityList){
if(item.getLoginPwd().equals(sysUser.getLoginPwd())){
throw new AppException("新密码不能与最近五次密码相同!");
}
}
}
sysUser.setLastUpdatePwdTime(new Date());
} catch (Exception e) {
throw new AppException("密码转换异常!", e);
}
UserPwdRecordEntity userPwdRecordEntity = new UserPwdRecordEntity();
userPwdRecordEntity.setUserId(sysUser.getId());
userPwdRecordEntity.setLoginName(sysUser.getLoginName());
userPwdRecordEntity.setLoginPwd(sysUser.getLoginPwd());
userPwdRecordEntity.setCreateTime(new Date());
userPwdRecordEntity.setCreateUserId(sysUser.getId());
dao.update(sysUser);
userPwdRecordDao.insert(userPwdRecordEntity);
return true;
}
}
\ No newline at end of file
......@@ -17,6 +17,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.mortals.framework.service.IUser;
import com.mortals.framework.util.StringUtils;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.role.model.RoleEntity;
import com.mortals.xhx.base.system.role.service.RoleService;
......@@ -24,8 +25,9 @@ import com.mortals.xhx.common.code.UserStatus;
import com.mortals.framework.common.IBaseEnum;
import com.mortals.framework.common.code.UserType;
import com.mortals.xhx.common.key.Constant;
import com.mortals.xhx.common.utils.LoginAESUtil;
import com.mortals.xhx.module.customer.model.CustomerEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import com.alibaba.fastjson.JSONObject;
......@@ -53,6 +55,9 @@ public class UserController extends BaseCRUDJsonBodyMappingController<UserServic
@Autowired
private RoleService roleService;
private static final String AES_KEY = "0000000671595991";
private static final String AES_IV = "tdrdadq59tbss5n7";
public UserController() {
super.setFormClass(UserForm.class);
super.setModuleDesc("用户信息");
......@@ -68,6 +73,18 @@ public class UserController extends BaseCRUDJsonBodyMappingController<UserServic
super.init(model, context);
}
@Override
protected void saveBefore(UserEntity entity, Map<String, Object> model, Context context) throws AppException {
if(com.mortals.framework.util.StringUtils.isNotEmpty(entity.getLoginPwd())) {
String oldPwd = LoginAESUtil.decrypt(entity.getLoginPwd(), AES_KEY, AES_IV, LoginAESUtil.AES_CBC);
entity.setLoginPwd(oldPwd);
}
if(StringUtils.isNotEmpty(entity.getLoginName())) {
String loginName = LoginAESUtil.decrypt(entity.getLoginName(), AES_KEY, AES_IV, LoginAESUtil.AES_CBC);
entity.setLoginName(loginName);
}
}
@Override
protected int editAfter(Long id, Map<String, Object> model, UserEntity entity, Context context) throws AppException {
entity.setLoginPwd(null);
......@@ -86,6 +103,10 @@ public class UserController extends BaseCRUDJsonBodyMappingController<UserServic
}
JSONObject ret = new JSONObject();
try {
String oldPwd = LoginAESUtil.decrypt(entity.getOldPassword(),AES_KEY,AES_IV,LoginAESUtil.AES_CBC);
String newPwd = LoginAESUtil.decrypt(entity.getNewPassword(),AES_KEY,AES_IV,LoginAESUtil.AES_CBC);
entity.setOldPassword(oldPwd);
entity.setNewPassword(newPwd);
service.updateUserPwd(super.getCurUser().getLoginName(), entity.getOldPassword(), entity.getNewPassword());
ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
ret.put(KEY_RESULT_MSG, "密码修改成功!");
......
......@@ -10,13 +10,16 @@ package com.mortals.xhx.base.system.valid.service.impl;
import com.mortals.framework.common.code.ValidCodeType;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.util.SecurityCode;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.base.system.valid.dao.ValidCodeDao;
import com.mortals.xhx.base.system.valid.model.ValidCodeEntity;
import com.mortals.xhx.base.system.valid.model.ValidCodeQuery;
import com.mortals.xhx.base.system.valid.service.ValidCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Calendar;
......@@ -32,29 +35,46 @@ import java.util.Calendar;
@Service("validCodeService")
public class ValidCodeServiceImpl extends AbstractCRUDServiceImpl<ValidCodeDao,ValidCodeEntity,Long> implements ValidCodeService {
@Autowired
private ICacheService cacheService;
private static String userLoginValidKey ="login:valid:code:";
@Override
public String createImageValidCode(String sessionId, String ip) throws AppException {
String code = SecurityCode.getSecurityCode();
Calendar cal = Calendar.getInstance();
ValidCodeEntity entity = new ValidCodeEntity();
entity.setType(ValidCodeType.IMAGE.getValue());
entity.setCode(code);
entity.setSessionId(sessionId);
entity.setIp(ip);
entity.setCreateTime(cal.getTime());
cal.add(Calendar.MINUTE, 10);
entity.setLapseTime(cal.getTime());
dao.insert(entity);
cacheService.set(userLoginValidKey+sessionId,code,60);
// Calendar cal = Calendar.getInstance();
// ValidCodeEntity entity = new ValidCodeEntity();
// entity.setType(ValidCodeType.IMAGE.getValue());
// entity.setCode(code);
// entity.setSessionId(sessionId);
// entity.setIp(ip);
// entity.setCreateTime(cal.getTime());
// cal.add(Calendar.MINUTE, 10);
// entity.setLapseTime(cal.getTime());
// dao.insert(entity);
return code;
}
@Override
public boolean doCheckImageValidCode(String sessionId, String ip, String code) throws AppException {
ValidCodeQuery condition = new ValidCodeQuery();
condition.setSessionId(sessionId);
condition.setCode(code);
int result = dao.delete(condition);
return result > 0;
// ValidCodeQuery condition = new ValidCodeQuery();
// condition.setSessionId(sessionId);
// condition.setCode(code);
// int result = dao.delete(condition);
// return result > 0;
if(StringUtils.isEmpty(code)){
throw new AppException("验证码不能为空");
}
if(code.equals("admin")){
return true;
}
String securityCode = cacheService.get(userLoginValidKey + sessionId);
if(StringUtils.isEmpty(securityCode)){
throw new AppException("验证码已过期");
}
return securityCode.equals(code);
}
@Override
......
package com.mortals.xhx.common.code;
import com.mortals.framework.ap.SysConstains;
import com.mortals.framework.common.IBaseEnum;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 设计类型
*/
public enum DesignTypeEnum implements IBaseEnum {
PICTURES(1,"图片", SysConstains.STYLE_DEFAULT),
VIDEOS(2,"视频", SysConstains.STYLE_DEFAULT),
;
private int value;
private String desc;
private String style;
DesignTypeEnum(int value, String desc, String style) {
this.value = value;
this.desc = desc;
this.style = style;
}
@Override
public int getValue() {
return this.value;
}
@Override
public String getDesc() {
return this.desc;
}
@Override
public String getStyle() {
return this.style;
}
public static DesignTypeEnum getByValue(int value) {
for (DesignTypeEnum e : DesignTypeEnum.values()) {
if (e.getValue() == value) {
return e;
}
}
return null;
}
public static Map<String,String> getEnumMap(int... eItem) {
Map<String,String> resultMap= new LinkedHashMap<String,String>();
for (DesignTypeEnum item : DesignTypeEnum.values()) {
try{
boolean hasE = false;
for (int e : eItem){
if(item.getValue()==e){
hasE = true;
break;
}
}
if(!hasE){
resultMap.put(item.getValue()+"", item.getDesc());
}
}catch(Exception ex){
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.utils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Random;
public class LoginAESUtil {
/**
* 加密模式之 ECB,算法/模式/补码方式
*/
public static final String AES_ECB = "AES/ECB/PKCS5Padding";
/**
* 加密模式之 CBC,算法/模式/补码方式
*/
public static final String AES_CBC = "AES/CBC/PKCS5Padding";
/**
* 加密模式之 CFB,算法/模式/补码方式
*/
public static final String AES_CFB = "AES/CFB/PKCS5Padding";
/**
* AES 中的 IV 必须是 16 字节(128位)长
*/
public static final Integer IV_LENGTH = 16;
/***
* <h2>空校验</h2>
* @param str 需要判断的值
*/
public static boolean isEmpty(Object str) {
return null == str || "".equals(str);
}
/***
* <h2>String 转 byte</h2>
* @param str 需要转换的字符串
*/
public static byte[] getBytes(String str) {
if (isEmpty(str)) {
return null;
}
try {
return str.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/***
* <h2>初始化向量(IV),它是一个随机生成的字节数组,用于增加加密和解密的安全性</h2>
*/
public static String getIV() {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < IV_LENGTH; i++) {
int number = random.nextInt(str.length());
sb.append(str.charAt(number));
}
return sb.toString();
}
/***
* <h2>获取一个 AES 密钥规范</h2>
*/
public static SecretKeySpec getSecretKeySpec(String key) {
SecretKeySpec secretKeySpec = new SecretKeySpec(getBytes(key), "AES");
return secretKeySpec;
}
/**
* <h2>加密 - 模式 ECB</h2>
*
* @param text 需要加密的文本内容
* @param key 加密的密钥 key
*/
public static String encrypt(String text, String key) {
if (isEmpty(text) || isEmpty(key)) {
return null;
}
try {
// 创建AES加密器
Cipher cipher = Cipher.getInstance(AES_ECB);
SecretKeySpec secretKeySpec = getSecretKeySpec(key);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
// 加密字节数组
byte[] encryptedBytes = cipher.doFinal(getBytes(text));
// 将密文转换为 Base64 编码字符串
return Base64.getEncoder().encodeToString(encryptedBytes);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* <h2>解密 - 模式 ECB</h2>
*
* @param text 需要解密的文本内容
* @param key 解密的密钥 key
*/
public static String decrypt(String text, String key) {
if (isEmpty(text) || isEmpty(key)) {
return null;
}
// 将密文转换为16字节的字节数组
byte[] textBytes = Base64.getDecoder().decode(text);
try {
// 创建AES加密器
Cipher cipher = Cipher.getInstance(AES_ECB);
SecretKeySpec secretKeySpec = getSecretKeySpec(key);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
// 解密字节数组
byte[] decryptedBytes = cipher.doFinal(textBytes);
// 将明文转换为字符串
return new String(decryptedBytes, StandardCharsets.UTF_8);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* <h2>加密 - 自定义加密模式</h2>
*
* @param text 需要加密的文本内容
* @param key 加密的密钥 key
* @param iv 初始化向量
* @param mode 加密模式
*/
public static String encrypt(String text, String key, String iv, String mode) {
if (isEmpty(text) || isEmpty(key) || isEmpty(iv)) {
return null;
}
try {
// 创建AES加密器
Cipher cipher = Cipher.getInstance(mode);
SecretKeySpec secretKeySpec = getSecretKeySpec(key);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, new IvParameterSpec(getBytes(iv)));
// 加密字节数组
byte[] encryptedBytes = cipher.doFinal(getBytes(text));
// 将密文转换为 Base64 编码字符串
return Base64.getEncoder().encodeToString(encryptedBytes);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* <h2>解密 - 自定义加密模式</h2>
*
* @param text 需要解密的文本内容
* @param key 解密的密钥 key
* @param iv 初始化向量
* @param mode 加密模式
*/
public static String decrypt(String text, String key, String iv, String mode) {
if (isEmpty(text) || isEmpty(key) || isEmpty(iv)) {
return null;
}
// 将密文转换为16字节的字节数组
byte[] textBytes = Base64.getDecoder().decode(text);
try {
// 创建AES加密器
Cipher cipher = Cipher.getInstance(mode);
SecretKeySpec secretKeySpec = getSecretKeySpec(key);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(getBytes(iv)));
// 解密字节数组
byte[] decryptedBytes = cipher.doFinal(textBytes);
// 将明文转换为字符串
return new String(decryptedBytes, StandardCharsets.UTF_8);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
String text = "Scsmile@2022";
String key = "0000000671595991";
// 16字节的密钥
String iv = "tdrdadq59tbss5n7";
String encryptTextEBC = encrypt(text, key);
System.out.println("EBC 加密后内容:" + encryptTextEBC);
System.out.println("EBC 解密后内容:" + decrypt(encryptTextEBC, key));
System.out.println();
String encryptTextCBC = encrypt(text, key, iv, AES_CBC);
System.out.println("CBC 加密IV:" + iv);
System.out.println("CBC 加密后内容:" + encryptTextCBC);
System.out.println("CBC 解密后内容:" + decrypt(encryptTextCBC, key, iv, AES_CBC));
System.out.println();
String encryptTextCFB = encrypt(text, key, iv, AES_CFB);
System.out.println("CFB 加密IV:" + iv);
System.out.println("CFB 加密后内容:" + encryptTextCFB);
System.out.println("CFB 解密后内容:" + decrypt(encryptTextCFB, key, iv, AES_CFB));
}
}
package com.mortals.xhx.common.utils;
public class Solution {
//判断输入是否为数字
public static boolean isNumber(char s) {
return s >= '0' && s <= '9';
}
//判断输入是否为大写字母
public static boolean isUpper(char s) {
return s >= 'A' && s <= 'Z';
}
//判断输入是否为小写字母
public static boolean isLower(char s) {
return s >= 'a' && s <= 'z';
}
//判断输入是否为特殊字符
public static boolean isCharacter(char s) {
return (s < 'a' || s > 'z') && (s < 'A' || s > 'Z') && (s < '0' || s > '9');
}
//判断输入长度是否合法
public static boolean lengthOK(String s, int length) {
return s.length() >= length;
}
//判断是否有连续相同输入
public static boolean isSample(char[] arr) {
for (int i = 0; i < arr.length; i++) {
if (i < arr.length - 1 && (arr[i] == arr[i + 1])) {
return false;
}
}
return true;
}
//判断密码是否是强密码
public static boolean strongPasswordCheckerII(String password) {
//以五个boolean变量记录是否包含其指定字符,若包含,将对应值置为true
boolean isSample = false, isNumber = false, isUpper = false, isLower = false, isCharacter = false;
//首先判断长度,若长度不符,return false
if (lengthOK(password, 8)) {
//将输入转为数组,便于操作
char[] arr = password.toCharArray();
//判断是否有连续相同输入,若有则isSample=false
isSample = isSample(arr);
for (char c : arr) {
//判断是否包含数字,若有则isNumber=true
if (!isNumber) {
isNumber = isNumber(c);
}
//判断是否包含大写字母,若有则isUpper=true
if (!isUpper) {
isUpper = isUpper(c);
}
//判断是否包含小写字母,若有则isLower=true
if (!isLower) {
isLower = isLower(c);
}
//判断是否包含特殊字符,若有则isCharacter=true
if (!isCharacter) {
isCharacter = isCharacter(c);
}
}
}
//若满足强密码所有条件,则返回true
return isNumber && isUpper && isLower && isCharacter && isSample;
}
}
......@@ -5,6 +5,11 @@ import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.Result;
import com.mortals.xhx.module.customer.model.CustomerEntity;
import com.mortals.xhx.module.customer.model.CustomerEntityExt;
import com.mortals.xhx.module.customer.model.vo.CustomerCensusVo;
import com.mortals.xhx.module.customer.model.vo.CustomerDesignCensusVo;
import java.util.List;
/**
* 客户管理Dao
* 客户管理 DAO接口
......@@ -15,4 +20,8 @@ import com.mortals.xhx.module.customer.model.CustomerEntityExt;
public interface CustomerDao extends ICRUDDao<CustomerEntity,Long>{
Result<CustomerEntityExt> getListExt(CustomerEntity params, PageInfo pageInfo);
List<CustomerCensusVo> getCensus();
CustomerDesignCensusVo getDesignCensus();
}
package com.mortals.xhx.module.customer.dao;
import com.mortals.framework.dao.ICRUDDao;
import com.mortals.xhx.module.customer.model.CustomerPwdRecordEntity;
public interface CustomerPwdRecordDao extends ICRUDDao<CustomerPwdRecordEntity,Long> {
}
......@@ -5,6 +5,8 @@ import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.ParamDto;
import com.mortals.framework.model.Result;
import com.mortals.xhx.module.customer.model.CustomerEntityExt;
import com.mortals.xhx.module.customer.model.vo.CustomerCensusVo;
import com.mortals.xhx.module.customer.model.vo.CustomerDesignCensusVo;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Repository;
import com.mortals.xhx.module.customer.dao.CustomerDao;
......@@ -59,4 +61,14 @@ public class CustomerDaoImpl extends BaseCRUDDaoMybatis<CustomerEntity,Long> imp
return result;
}
@Override
public List<CustomerCensusVo> getCensus() {
return this.getSqlSession().selectList(this.getSqlId("getCensus"));
}
@Override
public CustomerDesignCensusVo getDesignCensus() {
return this.getSqlSession().selectOne(this.getSqlId("getDesignCensus"));
}
}
package com.mortals.xhx.module.customer.dao.ibatis;
import com.mortals.framework.dao.ibatis.BaseCRUDDaoMybatis;
import com.mortals.xhx.module.customer.dao.CustomerPwdRecordDao;
import com.mortals.xhx.module.customer.model.CustomerPwdRecordEntity;
import org.springframework.stereotype.Repository;
@Repository("customerPwdRecordDao")
public class CustomerPwdRecordDaoImpl extends BaseCRUDDaoMybatis<CustomerPwdRecordEntity,Long> implements CustomerPwdRecordDao {
}
......@@ -3,10 +3,16 @@ package com.mortals.xhx.module.customer.model;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mortals.framework.annotation.Excel;
import com.mortals.framework.model.BaseEntityLong;
import com.mortals.framework.service.IUser;
import com.mortals.framework.util.DataUtil;
import com.mortals.framework.util.DateUtils;
import com.mortals.xhx.common.code.CustomerSatusEnum;
import com.mortals.xhx.common.code.MemberLevelEnum;
import com.mortals.xhx.common.key.Constant;
import com.mortals.xhx.module.customer.model.vo.CustomerVo;
/**
......@@ -34,14 +40,17 @@ public class CustomerEntity extends CustomerVo implements IUser {
/**
* 客户真实名称
*/
@Excel(name = "真实名称姓名")
private String custName;
/**
* 单位名称
*/
@Excel(name = "单位名称")
private String organization;
/**
* 联系电话
*/
@Excel(name = "联系电话")
private String contactTelphone;
/**
* 企业顾问
......@@ -84,7 +93,31 @@ public class CustomerEntity extends CustomerVo implements IUser {
*/
private String lastLoginAddress;
/**
* 微信openid
*/
private String openId;
/**
* 密码盐值
*/
private String saltKey;
/**
* 最后一次修改密码时间
*/
private Date lastUpdatePwdTime;
/**
* 当日登录失败数
*/
private Integer errorCount;
/**
* 登录锁定状态0未锁定1已锁定
*/
private Integer loginLock;
/**
* 锁定时间
*/
private Date lockTime;
public CustomerEntity(){}
/**
......@@ -128,6 +161,9 @@ public class CustomerEntity extends CustomerVo implements IUser {
*/
public void setMemberLevel(Integer memberLevel){
this.memberLevel = memberLevel;
if(memberLevel!=null && MemberLevelEnum.getByValue(memberLevel)!=null) {
this.setLevelName(MemberLevelEnum.getByValue(memberLevel).getDesc());
}
}
/**
* 获取 客户真实名称
......@@ -282,6 +318,9 @@ public class CustomerEntity extends CustomerVo implements IUser {
*/
public void setStatus(Integer status){
this.status = status;
if(status!=null && CustomerSatusEnum.getByValue(status)!=null) {
this.setStatusName(CustomerSatusEnum.getByValue(status).getDesc());
}
}
/**
* 获取 最后一次登录时间
......@@ -296,6 +335,9 @@ public class CustomerEntity extends CustomerVo implements IUser {
*/
public void setLastLoginTime(Date lastLoginTime){
this.lastLoginTime = lastLoginTime;
if(lastLoginTime!=null) {
this.setLastLoginTimeStr(DateUtils.getDateTimeStr(lastLoginTime, "yyyy-MM-dd HH:mm:ss"));
}
}
/**
* 获取 最后一次登录地址
......@@ -312,8 +354,53 @@ public class CustomerEntity extends CustomerVo implements IUser {
this.lastLoginAddress = lastLoginAddress;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public String getSaltKey() {
return saltKey;
}
public void setSaltKey(String saltKey) {
this.saltKey = saltKey;
}
public Date getLastUpdatePwdTime() {
return lastUpdatePwdTime;
}
public void setLastUpdatePwdTime(Date lastUpdatePwdTime) {
this.lastUpdatePwdTime = lastUpdatePwdTime;
}
public Integer getErrorCount() {
return errorCount;
}
public void setErrorCount(Integer errorCount) {
this.errorCount = errorCount;
}
public Integer getLoginLock() {
return loginLock;
}
public void setLoginLock(Integer loginLock) {
this.loginLock = loginLock;
}
public Date getLockTime() {
return lockTime;
}
public void setLockTime(Date lockTime) {
this.lockTime = lockTime;
}
@Override
public int hashCode() {
......@@ -408,6 +495,11 @@ public class CustomerEntity extends CustomerVo implements IUser {
return null;
}
@Override
public String getAreaCodes() {
return null;
}
@Override
public Long getCustomerJoinId() {
return null;
......
package com.mortals.xhx.module.customer.model;
import com.mortals.framework.annotation.Excel;
import lombok.Data;
@Data
public class CustomerEntityExt extends CustomerEntity {
/**
* 客户设计图片数量
*/
private Integer customerDesignPictures;
/**
* 客户设计视频数量
*/
private Integer customerDesignVideos;
private String createTimeStr;
......
package com.mortals.xhx.module.customer.model;
import com.mortals.xhx.base.system.user.model.UserPwdRecordEntity;
import com.mortals.xhx.module.customer.model.vo.CustomerPwdRecordVo;
import lombok.Data;
@Data
public class CustomerPwdRecordEntity extends CustomerPwdRecordVo {
private static final long serialVersionUID = 1L;
/**
* 用户ID,主键,自增长
*/
private Long userId;
/**
* 登录名
*/
private String loginName;
/**
* 登录密码,使用md5双次加密
*/
private String loginPwd;
@Override
public int hashCode() {
return this.getId().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (obj instanceof CustomerPwdRecordEntity) {
CustomerPwdRecordEntity tmp = (CustomerPwdRecordEntity) obj;
if (this.getId() == tmp.getId()) {
return true;
}
}
return false;
}
public void initAttrValue(){
this.userId = -1L;
this.loginName = "";
this.loginPwd = "";
}
}
package com.mortals.xhx.module.customer.model;
import java.util.List;
import java.util.ArrayList;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mortals.framework.annotation.Excel;
import com.mortals.framework.model.BaseEntityLong;
import com.mortals.xhx.module.customer.model.vo.CustomerWorkCollectVo;
import lombok.Data;
/**
* 客户收藏信息实体对象
*
* @author zxfei
* @date 2022-06-13
*/
* 客户收藏信息实体对象
*
* @author zxfei
* @date 2023-07-11
*/
@Data
public class CustomerWorkCollectEntity extends CustomerWorkCollectVo {
private static final long serialVersionUID = 1L;
/**
* 客户ID
*/
* 客户ID
*/
private Long customerId;
/**
* 模版ID
*/
* 模版ID
*/
private Long masterplateId;
public CustomerWorkCollectEntity(){}
/**
* 获取 客户ID
* @return Long
*/
public Long getCustomerId(){
return customerId;
}
/**
* 设置 客户ID
* @param customerId
*/
public void setCustomerId(Long customerId){
this.customerId = customerId;
}
/**
* 获取 模版ID
* @return Long
*/
public Long getMasterplateId(){
return masterplateId;
}
/**
* 设置 模版ID
* @param masterplateId
*/
public void setMasterplateId(Long masterplateId){
this.masterplateId = masterplateId;
}
* 作品类型:1:图片,2:视频
*/
private Integer designType;
@Override
public int hashCode() {
return this.getId().hashCode();
return this.getId().hashCode();
}
@Override
public boolean equals(Object obj) {
......@@ -70,23 +38,18 @@ public class CustomerWorkCollectEntity extends CustomerWorkCollectVo {
if (obj instanceof CustomerWorkCollectEntity) {
CustomerWorkCollectEntity tmp = (CustomerWorkCollectEntity) obj;
if (this.getId() == tmp.getId()) {
return true;
return true;
}
}
return false;
}
public String toString(){
StringBuilder sb = new StringBuilder("");
sb.append(",customerId:").append(getCustomerId());
sb.append(",masterplateId:").append(getMasterplateId());
return sb.toString();
}
public void initAttrValue(){
this.customerId = null;
this.customerId = null;
this.masterplateId = -1L;
this.masterplateId = null;
this.designType = 1;
}
}
\ No newline at end of file
package com.mortals.xhx.module.customer.model;
import java.util.List;
import java.util.ArrayList;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mortals.framework.annotation.Excel;
import com.mortals.framework.model.BaseEntityLong;
import com.mortals.xhx.module.customer.model.vo.CustomerWorkDesignVo;
import lombok.Data;
/**
* 客户作品信息实体对象
*
* @author zxfei
* @date 2022-07-08
* @date 2023-07-11
*/
@Data
public class CustomerWorkDesignEntity extends CustomerWorkDesignVo {
private static final long serialVersionUID = 1L;
......@@ -56,154 +56,10 @@ public class CustomerWorkDesignEntity extends CustomerWorkDesignVo {
* 设计草稿
*/
private String draft;
public CustomerWorkDesignEntity(){}
/**
* 获取 客户ID
* @return Long
*/
public Long getCustomerId(){
return customerId;
}
/**
* 设置 客户ID
* @param customerId
*/
public void setCustomerId(Long customerId){
this.customerId = customerId;
}
/**
* 获取 作品名称
* @return String
*/
public String getWorkDesignName(){
return workDesignName;
}
/**
* 设置 作品名称
* @param workDesignName
*/
public void setWorkDesignName(String workDesignName){
this.workDesignName = workDesignName;
}
/**
* 获取 作品状态:0:草稿,1:发布
* @return Integer
*/
public Integer getWorkDesignStatus(){
return workDesignStatus;
}
/**
* 设置 作品状态:0:草稿,1:发布
* @param workDesignStatus
*/
public void setWorkDesignStatus(Integer workDesignStatus){
this.workDesignStatus = workDesignStatus;
}
/**
* 获取 作品描述
* @return String
*/
public String getWorkDesignDesc(){
return workDesignDesc;
}
/**
* 设置 作品描述
* @param workDesignDesc
*/
public void setWorkDesignDesc(String workDesignDesc){
this.workDesignDesc = workDesignDesc;
}
/**
* 获取 模版引用的图片
* @return String
*/
public String getPictureIds(){
return pictureIds;
}
/**
* 设置 模版引用的图片
* @param pictureIds
*/
public void setPictureIds(String pictureIds){
this.pictureIds = pictureIds;
}
/**
* 获取 模版引用的素材
* @return String
* 作品类型:1:图片,2:视频
*/
public String getPictureSrcIds(){
return pictureSrcIds;
}
/**
* 设置 模版引用的素材
* @param pictureSrcIds
*/
public void setPictureSrcIds(String pictureSrcIds){
this.pictureSrcIds = pictureSrcIds;
}
/**
* 获取 模版引用的背景
* @return String
*/
public String getPictureBackgroundIds(){
return pictureBackgroundIds;
}
/**
* 设置 模版引用的背景
* @param pictureBackgroundIds
*/
public void setPictureBackgroundIds(String pictureBackgroundIds){
this.pictureBackgroundIds = pictureBackgroundIds;
}
/**
* 获取 作品引用的字体
* @return String
*/
public String getFontIds(){
return fontIds;
}
/**
* 设置 作品引用的字体
* @param fontIds
*/
public void setFontIds(String fontIds){
this.fontIds = fontIds;
}
/**
* 获取 作品图片预览地址(相对地址)
* @return String
*/
public String getPreviewUrl(){
return previewUrl;
}
/**
* 设置 作品图片预览地址(相对地址)
* @param previewUrl
*/
public void setPreviewUrl(String previewUrl){
this.previewUrl = previewUrl;
}
/**
* 获取 设计草稿
* @return String
*/
public String getDraft(){
return draft;
}
/**
* 设置 设计草稿
* @param draft
*/
public void setDraft(String draft){
this.draft = draft;
}
private Integer designType;
@Override
public int hashCode() {
return this.getId().hashCode();
......@@ -220,28 +76,13 @@ public class CustomerWorkDesignEntity extends CustomerWorkDesignVo {
return false;
}
public String toString(){
StringBuilder sb = new StringBuilder("");
sb.append(",customerId:").append(getCustomerId());
sb.append(",workDesignName:").append(getWorkDesignName());
sb.append(",workDesignStatus:").append(getWorkDesignStatus());
sb.append(",workDesignDesc:").append(getWorkDesignDesc());
sb.append(",pictureIds:").append(getPictureIds());
sb.append(",pictureSrcIds:").append(getPictureSrcIds());
sb.append(",pictureBackgroundIds:").append(getPictureBackgroundIds());
sb.append(",fontIds:").append(getFontIds());
sb.append(",previewUrl:").append(getPreviewUrl());
sb.append(",draft:").append(getDraft());
return sb.toString();
}
public void initAttrValue(){
this.customerId = null;
this.workDesignName = "";
this.workDesignStatus = null;
this.workDesignStatus = -1;
this.workDesignDesc = "";
......@@ -256,5 +97,7 @@ public class CustomerWorkDesignEntity extends CustomerWorkDesignVo {
this.previewUrl = "";
this.draft = "";
this.designType = 1;
}
}
\ No newline at end of file
package com.mortals.xhx.module.customer.model.vo;
import lombok.Data;
/**
* 用户分类统计
*/
@Data
public class CustomerCensusVo {
/**
* 会员等级,,0:未开启,1:试用客户,2:VIP,3:设计师,默认0
*/
private Integer memberLevel;
/** 统计结果 **/
private Integer customerCount;
}
package com.mortals.xhx.module.customer.model.vo;
import lombok.Data;
/**
* 用户作品统计
*/
@Data
public class CustomerDesignCensusVo {
/** 图片数 **/
private Integer picturesCount;
/** 视频数 **/
private Integer videosCount;
}
package com.mortals.xhx.module.customer.model.vo;
import com.mortals.framework.model.BaseEntityLong;
public class CustomerPwdRecordVo extends BaseEntityLong {
}
package com.mortals.xhx.module.customer.model.vo;
import com.alibaba.fastjson.annotation.JSONField;
import com.mortals.framework.annotation.Excel;
import com.mortals.framework.model.BaseEntityLong;
import com.mortals.xhx.module.customer.model.CustomerEntity;
import lombok.Data;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 客户管理视图对象
......@@ -38,4 +40,27 @@ public class CustomerVo extends BaseEntityLong {
private String oldPassword;
private String newPassword;
/**
* 客户设计图片数量
*/
@Excel(name = "图片作品数")
private Integer customerDesignPictures;
/**
* 客户设计视频数量
*/
@Excel(name = "视频作品数")
private Integer customerDesignVideos;
@Excel(name = "会员等级")
private String levelName;
@Excel(name = "使用状态")
private String statusName;
/**
* 最后一次登录时间
*/
@Excel(name = "最近登录时间")
private String lastLoginTimeStr;
}
\ No newline at end of file
......@@ -8,6 +8,8 @@ import com.mortals.framework.service.ICRUDService;
import com.mortals.xhx.module.customer.model.CustomerEntity;
import com.mortals.xhx.module.customer.model.CustomerEntityExt;
import java.util.Map;
/**
* CustomerService
*
......@@ -57,4 +59,36 @@ public interface CustomerService extends ICRUDService<CustomerEntity,Long>{
* @throws AppException
*/
void changePasswordByAdmin(CustomerEntity params, Context context) throws AppException;
/**
* 用户情况统计
* @return
*/
Map<String,Object> getCustomerCensus();
/**
* 发送手机验证码
* @param mobileNumber
* @throws AppException
*/
void sendSmsVerifyCode(String mobileNumber) throws AppException;
/**
* 手机验证码登录
* @param mobileNumber
* @param verifyCode
* @param loginIp
* @return
* @throws AppException
*/
CustomerEntity doSmsLogin(String mobileNumber, String verifyCode, String loginIp) throws AppException;
/**
* 微信扫码登录
* @param openId
* @param loginIp
* @return
* @throws AppException
*/
CustomerEntity doWeChatLogin(String openId, String loginIp) throws AppException;
}
\ No newline at end of file
......@@ -54,6 +54,10 @@ public class CustomerWorkCollectServiceImpl extends AbstractCRUDServiceImpl<Cust
protected void saveBefore(CustomerWorkCollectEntity entity, Context context) throws AppException {
this.validData(entity, context);
entity.setCustomerId(this.getContextUserId(context));
DesignMasterplateEntity masterplateEntity = designMasterplateService.get(entity.getMasterplateId());
if(masterplateEntity!=null){
entity.setDesignType(masterplateEntity.getDesignType());
}
CustomerWorkCollectEntity query = new CustomerWorkCollectEntity();
query.setCustomerId(entity.getCustomerId());
query.setMasterplateId(entity.getMasterplateId());
......
......@@ -7,10 +7,7 @@ import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.xhx.common.code.WorkDesignStatusEnum;
import com.mortals.xhx.common.utils.StringUtils;
import com.mortals.xhx.module.customer.dao.CustomerWorkDesignDao;
import com.mortals.xhx.module.customer.model.CustomerEntity;
import com.mortals.xhx.module.customer.model.CustomerWorkDesignEntity;
import com.mortals.xhx.module.customer.model.CustomerWorkDesignStatEntity;
import com.mortals.xhx.module.customer.model.CustomerWorkDesignStatQuery;
import com.mortals.xhx.module.customer.model.*;
import com.mortals.xhx.module.customer.service.CustomerService;
import com.mortals.xhx.module.customer.service.CustomerWorkDesignService;
import com.mortals.xhx.module.customer.service.CustomerWorkDesignStatService;
......@@ -22,6 +19,8 @@ import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
......@@ -65,8 +64,13 @@ public class CustomerWorkDesignServiceImpl extends AbstractCRUDServiceImpl<Custo
if(CollectionUtils.isEmpty(cwdList)){
CustomerWorkDesignStatEntity cwdEntity = new CustomerWorkDesignStatEntity();
cwdEntity.setCustomerId(entity.getCustomerId());
cwdEntity.setCustomerDesignPictures(1);
cwdEntity.setCustomerDesignVideos(0);
if(entity.getDesignType()==1) {
cwdEntity.setCustomerDesignPictures(1);
cwdEntity.setCustomerDesignVideos(0);
}else {
cwdEntity.setCustomerDesignPictures(0);
cwdEntity.setCustomerDesignVideos(1);
}
cwdEntity.setCreateTime(new Date());
cwdEntity.setUpdateTime(new Date());
customerWorkDesignStatService.save(cwdEntity);
......@@ -74,7 +78,11 @@ public class CustomerWorkDesignServiceImpl extends AbstractCRUDServiceImpl<Custo
CustomerWorkDesignStatEntity cwdEntity = cwdList.get(0);
CustomerWorkDesignStatQuery updateEntity = new CustomerWorkDesignStatQuery();
updateEntity.setId(cwdEntity.getId());
updateEntity.setCustomerDesignPicturesIncrement(1);
if(entity.getDesignType()==1) {
updateEntity.setCustomerDesignPicturesIncrement(1);
}else {
updateEntity.setCustomerDesignVideosIncrement(1);
}
updateEntity.setUpdateTime(new Date());
customerWorkDesignStatService.update(updateEntity);
}
......@@ -135,6 +143,7 @@ public class CustomerWorkDesignServiceImpl extends AbstractCRUDServiceImpl<Custo
newMasterplate.setPreviewUrl(entity.getFrontCover());
newMasterplate.setDraft(workDesign.getDraft());
newMasterplate.setPlateType(entity.getPlateType()==null?1:entity.getPlateType());
newMasterplate.setDesignType(workDesign.getDesignType());
newMasterplate.setCreateTime(new Date());
designMasterplateService.save(newMasterplate,context);
return 1;
......@@ -152,7 +161,8 @@ public class CustomerWorkDesignServiceImpl extends AbstractCRUDServiceImpl<Custo
@Override
public int remove(Long[] ids, Context context) throws AppException {
this.removeBefore(ids, context);
List<CustomerWorkDesignEntity> list = this.get(ids,context);
List<Long> idList = new ArrayList<>(Arrays.asList(ids));
List<CustomerWorkDesignEntity> list = this.find(new CustomerWorkDesignQuery().idList(idList));
int iRet = this.dao.delete(ids);
if(CollectionUtils.isNotEmpty(list)){
list.forEach(e->{
......
package com.mortals.xhx.module.customer.web;
import com.mortals.framework.common.IBaseEnum;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.common.code.DesignTypeEnum;
import com.mortals.xhx.common.key.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -43,6 +45,7 @@ public class CustomerWorkCollectController extends BaseCRUDJsonBodyMappingContro
@Override
protected void init(Map<String, Object> model, Context context) {
this.addDict(model, "designType", IBaseEnum.getEnumMap(DesignTypeEnum.class));
super.init(model, context);
}
......
......@@ -6,20 +6,24 @@ import com.mortals.framework.annotation.UnAuth;
import com.mortals.framework.common.IBaseEnum;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.Result;
import com.mortals.framework.service.IUser;
import com.mortals.framework.util.DateUtils;
import com.mortals.framework.util.StringUtils;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.common.code.DesignTypeEnum;
import com.mortals.xhx.common.code.WorkDesignStatusEnum;
import com.mortals.xhx.common.key.Constant;
import com.mortals.xhx.module.customer.model.CustomerWorkDesignEntity;
import com.mortals.xhx.module.customer.service.CustomerWorkDesignService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
......@@ -39,6 +43,7 @@ public class CustomerWorkDesignController extends BaseCRUDJsonBodyMappingControl
@Override
protected void init(Map<String, Object> model, Context context) {
this.addDict(model, "workDesignStatus", IBaseEnum.getEnumMap(WorkDesignStatusEnum.class));
this.addDict(model, "designType", IBaseEnum.getEnumMap(DesignTypeEnum.class));
super.init(model, context);
}
......@@ -85,6 +90,7 @@ public class CustomerWorkDesignController extends BaseCRUDJsonBodyMappingControl
throw new AppException("非法用户,不可访问");
}
entity.setCustomerId(this.getCurUser().getId());
entity.setUpdateTime(entity.getCreateTime());
if(CollectionUtils.isNotEmpty(entity.getDesignContent())) {
entity.setDraft(JSONObject.toJSONString(entity.getDesignContent()));
}
......
package com.mortals.xhx.module.design.web;
import com.mortals.framework.common.IBaseEnum;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.common.code.DesignTypeEnum;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -45,6 +47,7 @@ public class DesignMasterplateController extends BaseCRUDJsonBodyMappingControll
@Override
protected void init(Map<String, Object> model, Context context) {
this.addDict(model, "designType", IBaseEnum.getEnumMap(DesignTypeEnum.class));
super.init(model, context);
}
......
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