package com.qxgmat.service; import com.github.pagehelper.Page; import com.nuliji.tools.AbstractService; import com.nuliji.tools.CipherHelp; import com.nuliji.tools.Tools; import com.nuliji.tools.Transform; import com.nuliji.tools.exception.AuthException; import com.nuliji.tools.exception.ParameterException; import com.nuliji.tools.exception.SystemException; import com.nuliji.tools.mybatis.Example; import com.nuliji.tools.mybatis.NativeJsonHandler; import com.nuliji.tools.third.OauthData; import com.qxgmat.data.constants.enums.status.DirectionStatus; import com.qxgmat.data.constants.enums.user.PrepareExaminationTime; import com.qxgmat.data.dao.UserMapper; import com.qxgmat.data.dao.entity.User; import com.qxgmat.data.dao.entity.UserOrder; import com.qxgmat.data.inline.UserToken; import com.qxgmat.data.relation.UserRelationMapper; import com.qxgmat.data.relation.entity.UserPrepareRelation; import com.qxgmat.help.WechatHelp; import com.qxgmat.service.extend.MessageExtendService; import com.qxgmat.service.extend.OrderFlowService; import com.qxgmat.service.inline.UserCourseService; import com.qxgmat.service.inline.UserMessageService; import com.qxgmat.service.inline.UserOrderService; import org.hibernate.criterion.Order; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.*; /** * Created by GaoJie on 2017/11/1. */ @Service public class UsersService extends AbstractService { final public String PLATORM_WECHAT_NATIVE = "wechatOpenidWechat"; final public String PLATORM_WECHAT_PC = "wechatOpenidPc"; final public String PLATORM_WECHAT = "wechatUnionid"; @Value("${self.secret}") private String secret; private NativeJsonHandler tokenHandler = new NativeJsonHandler(UserToken.class); @Resource private UserMapper userMapper; @Resource private WechatHelp wechatHelp; @Resource private UserRelationMapper userRelationMapper; @Resource private OrderFlowService orderFlowService; @Resource private MessageExtendService messageExtendService; /** * 生成有效期token * @param user * @return */ public String getTokenByUser(User user){ UserToken ut = new UserToken(); ut.setId(user.getId()); Date expire = new Date(new Date().getTime() + 86400); ut.setExpire(expire); String info = tokenHandler.toJson(ut); return CipherHelp.encrypt(info, CipherHelp.DES, secret); } /** * 解析有效期token * @param token * @return */ public User getUserByToken(String token){ // 默认测试token if (token.equals("1234567890")){ return get(1); }else{ String info = CipherHelp.decrypt(token, CipherHelp.DES, secret); UserToken ut = tokenHandler.toObject(info); Date expire = ut.getExpire(); if (expire.before(new Date())){ throw new AuthException("token错误"); } return get(ut.getId()); } } /** * 绑定第三方账号信息 * @param user 当前登录用户 * @param code * @param platform * @return */ @Transactional public User Oauth(User user, String code, String platform, boolean userInfo){ OauthData data; switch(platform){ case "wechat_pc": data = wechatHelp.oauthPc(code, userInfo); break; case "wechat_native": data = wechatHelp.oauthNative(code, userInfo); break; default: throw new ParameterException("第三方平台"+platform+"不支持"); } User openUser = getByOpen(data.getOpenId(), data.getUnionId(), platform); // 获取已关联的账号 if (user != null && user.getId() != null){ // 检验是否已经绑定 if(openUser != null && !openUser.getId().equals(user.getId())){ // // 自动合并账号 // // 更新消息 // userMessageService.mergeUser(openUser.getId(), user.getId()); // // 更新消费记录 // userOrderService.mergeUser(openUser.getId(), user.getId()); // // 更新课程信息 // userCourseService.mergeUser(openUser.getId(), user.getId()); // // 更新服务信息 // userServiceService.mergeUser(openUser.getId(), user.getId()); // // // 更新实名认证 // if (openUser.getRealStatus() > 0){ // user.setRealAddress(openUser.getRealAddress()); // user.setRealIdentity(openUser.getRealIdentity()); // user.setRealName(openUser.getRealName()); // user.setRealPhotoFront(openUser.getRealPhotoFront()); // user.setRealPhotoBack(openUser.getRealPhotoBack()); // user.setRealStatus(openUser.getRealStatus()); // } // // // 删除旧账号 // delete(openUser.getId()); throw new ParameterException("该微信账户已绑定其他手机号,您可直接使用微信登录"); } } User mm = User.builder() .id(openUser != null ? openUser.getId() : null) .build(); // if (openUser ==null || openUser.getAvatar() == null || openUser.getAvatar().isEmpty()) { // mm.setAvatar(data.getAvatar()); // if(openUser != null){ // openUser.setAvatar(data.getAvatar()); // } // } // if (openUser == null || openUser.getNickname() == null|| openUser.getNickname().isEmpty()){ // mm.setNickname(data.getNickName()); // if(openUser != null){ // openUser.setNickname(data.getNickName()); // } // } switch(platform){ case "wechat_pc": mm.setWechatOpenidPc(data.getOpenId()); mm.setWechatUnionid(data.getUnionId()); break; case "wechat_native": mm.setWechatOpenidWechat(data.getOpenId()); mm.setWechatUnionid(data.getUnionId()); mm.setWechatAccessToken(data.getAccessToken()); mm.setWechatRefreshToken(data.getRefreshToken()); mm.setWechatExpireTime(data.getExpiresTime()); break; } if (mm.getId() != null){ // 直接更新数据 edit(mm); return openUser; } return mm; } /** * 通过手机号注册 * @param mobile * @param inviteCode * @param openUser * @return */ @Transactional public User register(String area, String mobile, String inviteCode, String email, User openUser, String registerIp, String[] registerInfo){ boolean n = false; User user = getByMobile(area, mobile); if (user != null){ if (openUser == null) { // 直接手机登录,异常抛出,根据情况忽略 throw new ParameterException("手机号已注册"); }else if(user.getWechatUnionid() != null && !user.getWechatUnionid().equals("")){ // openUser不为空,则用于绑定微信 throw new ParameterException("该手机已绑定其他账号,请更换手机号码"); } user = User.builder().id(user.getId()).build(); if (user.getRegisterIp() == null || user.getRegisterIp().isEmpty()){ user.setRegisterIp(registerIp); user.setRegisterCity(registerInfo != null ? String.join(",",registerInfo) : ""); user.setLatestLoginIp(registerIp); } }else{ // 注册,并且绑定邀请者 user = User.builder().area(area).mobile(mobile).email(email).build(); n = true; if (inviteCode != null && !inviteCode.isEmpty()){ User origin = getByInviteCode(inviteCode); user.setOriginId(origin.getId()); edit(User.builder().id(origin.getId()).inviteNumber(origin.getInviteNumber() + 1).inviteLatestTime(new Date()).build()); // 邀请奖励 orderFlowService.giveInvite(origin); } // 生成邀请码: 10位字符串 user.setInviteCode(Tools.getRandomString(10)); user.setRegisterIp(registerIp); user.setRegisterCity(registerInfo != null ? String.join(",",registerInfo) : ""); user.setLatestLoginIp(registerIp); user.setNickname("qx"+user.getMobile()); } // 绑定第三方登录信息 if (openUser != null){ this.bind(user, openUser); } if (n){ user = add(user); messageExtendService.sendRegister(user); }else{ user = edit(user); } if(user == null) throw new SystemException("注册失败"); return user; } public User bind(User user, User openUser){ // 绑定第三方登录信息 if(openUser.getWechatOpenidPc() != null) user.setWechatOpenidPc(openUser.getWechatOpenidPc()); if(openUser.getWechatOpenidWechat() != null) user.setWechatOpenidWechat(openUser.getWechatOpenidWechat()); if(openUser.getWechatExpireTime() != null) user.setWechatExpireTime(openUser.getWechatExpireTime()); if(openUser.getWechatUnionid() != null) user.setWechatUnionid(openUser.getWechatUnionid()); if(openUser.getWechatAccessToken() != null) user.setWechatAccessToken(openUser.getWechatAccessToken()); if(openUser.getWechatRefreshToken() != null) user.setWechatRefreshToken(openUser.getWechatRefreshToken()); // if(openUser.getNickname() != null) user.setNickname(openUser.getNickname()); // if(openUser.getAvatar() != null) user.setAvatar(openUser.getAvatar()); return user; } // 获取微信快到期账号 public Page listByWechatExpire(int page, int size, Date expire){ Example example = new Example(User.class); example.and( example.createCriteria() .andLessThan("wechatExpireTime", expire) ); return page(()->select(userMapper, example), page, size); } // 通过手机号获取用户 public User getByMobile(String area, String mobile){ User user = User.builder().area(area).mobile(mobile).build(); return one(userMapper, user); } // 通过邮箱获取用户 public User getByEmail(String email){ User user = User.builder().email(email).build(); return one(userMapper, user); } // 通过身份证获取用户 public User getByIdentity(String identity){ User user = User.builder().realIdentity(identity).build(); return one(userMapper, user); } // 通过openid获取用户 public User getByOpen(String openId, String unionId, String platform){ String platformField; String unionField; switch(platform){ case "wechat_pc": platformField = PLATORM_WECHAT_PC; unionField = PLATORM_WECHAT; break; case "wechat_native": platformField = PLATORM_WECHAT_NATIVE; unionField = PLATORM_WECHAT; break; default: throw new ParameterException("第三方平台"+platform+"不支持"); } Example example = new Example(User.class); example.or( example.createCriteria() .andEqualTo(platformField, openId) ); if (unionId != null && !unionId.isEmpty()){ example.or( example.createCriteria() .andEqualTo(unionField, unionId) ); } return one(userMapper, example); } /** * 通过邀请码或者手机好获取邀请人 * @param inviteCode * @return */ public User getByInviteCode(String inviteCode){ User user = new User(); Example example = new Example(User.class); // 查找手机或邀请码 example.and( example.createCriteria() .orEqualTo("invite_code", inviteCode) .orEqualTo("mobile", inviteCode) ); return one(userMapper, example); } /** * 获取备考统计:身份 * @return */ public List statPrepareStatus(){ return userRelationMapper.groupPrepareString("prepare_status"); } /** * 获取备考统计:目标分数 * @return */ public List statPrepareGoal(){ List relations = userRelationMapper.groupPrepareInteger("prepare_goal"); // 按考分分组 List userPrepareRelationList = new ArrayList<>(); Integer[] goalGroup = new Integer[]{600, 650, 700, 750}; for(Integer goal : goalGroup){ UserPrepareRelation real = new UserPrepareRelation(); real.setI(goal); real.setNumber(0); userPrepareRelationList.add(real); } for(UserPrepareRelation relation : relations){ int goal = -1; for(int i = 0; i < goalGroup.length; i++){ // 根据考分判断层级 if (goalGroup[i] > relation.getI()){ // 属于上一层 goal = i - 1; break; } } if (goal > 0){ // 按层级归类 UserPrepareRelation real = userPrepareRelationList.get(goal); real.setNumber(real.getNumber()+relation.getNumber()); } } return userPrepareRelationList; } /** * 获取备考统计:考试时间 * @return */ public List statPrepareExaminationTime(){ return userRelationMapper.groupPrepareString("prepare_examination_time"); } /** * 获取备考统计:出分时间 * @return */ public List statPrepareScoreTime(){ // 直接按不同时间段统计 Example example; List userPrepareRelationList = new ArrayList<>(); Calendar calendar = Calendar.getInstance(); // 一个月内 calendar.setTime(new Date()); calendar.add(Calendar.MONTH, 1); example = new Example(User.class); example.and( example.createCriteria() .andLessThan("prepareScoreTime", calendar.getTime()) ); UserPrepareRelation oneMonth = new UserPrepareRelation(); oneMonth.setS(PrepareExaminationTime.ONE_MONTH.key); oneMonth.setNumber(count(userMapper, example)); userPrepareRelationList.add(oneMonth); // 两个月内 calendar.setTime(new Date()); calendar.add(Calendar.MONTH, 2); example = new Example(User.class); example.and( example.createCriteria() .andLessThan("prepareScoreTime", calendar.getTime()) ); UserPrepareRelation twoMonth = new UserPrepareRelation(); twoMonth.setS(PrepareExaminationTime.TWO_MONTH.key); twoMonth.setNumber(count(userMapper, example) - oneMonth.getNumber()); userPrepareRelationList.add(twoMonth); // 三个月内 calendar.setTime(new Date()); calendar.add(Calendar.MONTH, 3); example = new Example(User.class); example.and( example.createCriteria() .andLessThan("prepareScoreTime", calendar.getTime()) ); UserPrepareRelation threeMonth = new UserPrepareRelation(); threeMonth.setS(PrepareExaminationTime.THREE_MONTH.key); threeMonth.setNumber(count(userMapper, example) - twoMonth.getNumber()); userPrepareRelationList.add(threeMonth); // 半年 calendar.setTime(new Date()); calendar.add(Calendar.MONTH, 6); example = new Example(User.class); example.and( example.createCriteria() .andLessThan("prepareScoreTime", calendar.getTime()) ); UserPrepareRelation sixMonth = new UserPrepareRelation(); sixMonth.setS(PrepareExaminationTime.SIX_MONTH.key); sixMonth.setNumber(count(userMapper, example) - threeMonth.getNumber()); userPrepareRelationList.add(sixMonth); // 一年 calendar.setTime(new Date()); calendar.add(Calendar.MONTH, 12); example = new Example(User.class); example.and( example.createCriteria() .andLessThan("prepareScoreTime", calendar.getTime()) ); UserPrepareRelation oneYear = new UserPrepareRelation(); oneYear.setS(PrepareExaminationTime.ONE_YEAR.key); oneYear.setNumber(count(userMapper, example) - sixMonth.getNumber()); userPrepareRelationList.add(oneYear); // 其他 example = new Example(User.class); example.and( example.createCriteria() // 设置过备考信息的人:mapper中做为基本条件 .andGreaterThan("prepareGoal", 0) .andIsNull("prepareScoreTime") ); UserPrepareRelation other = new UserPrepareRelation(); other.setS(PrepareExaminationTime.OTHER.key); other.setNumber(count(userMapper, example)); userPrepareRelationList.add(other); return userPrepareRelationList; } private Map adminMap = new HashMap(){{ put("", "u"); }}; /** * 获取购买过课程的用户 * @param page * @param pageSize * @param keyword * @param courseId * @return */ public Page listAdminByCourse(int page, int pageSize, String keyword, Integer courseId, String order, DirectionStatus direction){ if(order == null || order.isEmpty()){ order = "id"; } if(adminMap.containsKey(order)){ order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`"; }else{ order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`"; } if (direction == null){ direction = DirectionStatus.DESC; } String finalOrder = order; DirectionStatus finalDirection = direction; Page p = page(()->{ userRelationMapper.listByCourse(keyword, courseId, finalOrder, finalDirection.key); }, page, pageSize); Collection ids = Transform.getIds(p, User.class, "id"); // 获取详细数据 List list = select(ids); Transform.replace(p, list, User.class, "id"); return p; } /** * 获取总用户数 * @return */ public Integer count(){ Example example = new Example(User.class); return count(userMapper, example); } /** * 累加支付金额 * @param userId * @param money */ public void accumulation(Integer userId, BigDecimal money){ userRelationMapper.accumulation(userId, money); } public Page listAdmin(int page, int pageSize, String keyword, Boolean real, Boolean wechat, Boolean prepare, Date startTime, Date endTime, String order, DirectionStatus direction){ Example example = new Example(User.class); if(keyword != null) example.and( example.createCriteria() .orLike("id", "%"+keyword+"%") .orLike("mobile", "%"+keyword+"%") ); if (real != null) example.and( example.createCriteria().andEqualTo("realStatus", real?1:0) ); if (wechat != null) example.and( wechat ? example.createCriteria().andNotEqualTo("wechatUnionid", "") : example.createCriteria().andEqualTo("wechatUnionid", "") ); if (prepare != null) example.and( prepare ? example.createCriteria().andIsNotNull("prepareTime"):example.createCriteria().andIsNull("prepareTime") ); if (startTime != null){ example.and( example.createCriteria().andGreaterThanOrEqualTo("createTime", startTime) ); } if(endTime != null){ example.and( example.createCriteria().andLessThan("createTime", endTime) ); } if(order==null||order.isEmpty()) order = "id"; if (direction != null){ switch(direction){ case ASC: example.orderBy(order).asc(); break; case DESC: default: example.orderBy(order).desc(); } } else { example.orderBy(order).desc(); } return select(userMapper, example, page, pageSize); } public boolean equalsPassword(User user, String password){ return Objects.equals(user.getPassword(), Tools.stringMD5(Tools.stringMD5(password))); } public boolean changePassword(User user, String password){ User updateUser = User.builder().id(user.getId()).password(Tools.stringMD5(Tools.stringMD5(password))).build(); int result = update(userMapper, updateUser); return result > 0; } public User add(User user){ if(user.getPassword() != null) user.setPassword(Tools.stringMD5(user.getPassword())); int result = insert(userMapper, user); user = one(userMapper, user.getId()); if(user == null){ throw new SystemException("用户添加失败"); } return user; } public User edit(User user){ User in = one(userMapper, user.getId()); if(in == null){ throw new ParameterException("用户不存在"); } if(user.getPassword() != null) user.setPassword(Tools.stringMD5(user.getPassword())); int result = update(userMapper, user); return user; } public boolean delete(Number id){ User in = one(userMapper, id); if(in == null){ throw new ParameterException("用户不存在"); } int result = delete(userMapper, id); return result > 0; } public User get(Number id){ User in = one(userMapper, id); if(in == null){ throw new ParameterException("用户不存在"); } return in; } public Page select(int page, int pageSize){return select(userMapper, page, pageSize); } public Page select(Integer[] ids){ return page(()->select(userMapper, ids), 1, ids.length); } public List select(Collection ids){ return select(userMapper, ids); } }