package com.moral.api.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moral.api.config.Interceptor.UserHelper;
import com.moral.api.entity.*;
import com.moral.api.mapper.*;
import com.moral.api.pojo.bo.UserBO;
import com.moral.api.pojo.enums.AllocationApproveEnum;
import com.moral.api.pojo.enums.FileTableEnum;
import com.moral.api.pojo.enums.StateEnum;
import com.moral.api.pojo.enums.SysDictTypeEnum;
import com.moral.api.pojo.vo.file.FileVo;
import com.moral.api.pojo.vo.user.QxUser;
import com.moral.api.service.FileTableService;
import com.moral.api.service.ResponsibilityUnitService;
import com.moral.api.service.UserService;
import com.moral.api.utils.OperationLogUtils;
import com.moral.api.utils.StringUtils;
import com.moral.api.utils.WechatUtils;
import com.moral.api.vo.WxMssVo;
import com.moral.constant.Constants;
import com.moral.constant.ResponseCodeEnum;
import com.moral.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;
/**
*
* 用户表 服务实现类
*
*
* @author moral
* @since 2021-03-09
*/
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private MenuMapper menuMapper;
@Autowired
private UserGroupMapper userGroupMapper;
@Autowired
private UserLogMapper userLogMapper;
@Autowired
private FileTableService fileTableService;
@Autowired
private OperationLogUtils operationLogUtils;
@Autowired
private ResponsibilityUnitMapper responsibilityUnitMapper;
@Autowired
private ResponsibilityUnitService responsibilityUnitService;
@Value("${AES.KEY}")
private String AESKey;
@Override
public UserBO selectUserInfo(Map parameters) {
return userMapper.selectUserInfo(parameters);
}
/**
* 小程序登陆
* @param parameters
* @return
*/
@Override
@Transactional
public Map loginSmallRoutine(Map parameters) {
UserBO userBo = selectUserInfo(parameters);
String openId = parameters.get("openId").toString();
Map result = new HashMap<>();
//校验账户
if (userBo == null) {
result.put("code", ResponseCodeEnum.ACCOUNT_NOT_EXIST.getCode());
result.put("msg", ResponseCodeEnum.ACCOUNT_NOT_EXIST.getMsg());
return result;
}
//校验是否删除
if (Constants.DELETE.equals(userBo.getIsDelete())) {
result.put("code", ResponseCodeEnum.ACCOUNT_IS_DELETE.getCode());
result.put("msg", ResponseCodeEnum.ACCOUNT_IS_DELETE.getMsg());
return result;
}
ResponsibilityUnit responsibilityUnit = responsibilityUnitMapper.selectById(userBo.getUnitId());
List list = responsibilityUnitMapper.selectCodeList(SysDictTypeEnum.SYS_DEVICE.value, userBo.getId());
result.put("userName", userBo.getUserName());
result.put("unitId",userBo.getUnitId());
result.put("userId", userBo.getId());
result.put("account", userBo.getAccount());
List listFile = fileTableService.list(userBo.getId(), FileTableEnum.APP_ALLOCATION.value);
result.put("file", CollectionUtils.isNotEmpty(listFile)?listFile.get(0):new FileVo());
result.put("unName",Objects.nonNull(responsibilityUnit)&&Objects.nonNull(responsibilityUnit.getUnitName())?responsibilityUnit.getUnitName():"管理员登陆");
result.put("device",ObjectUtils.isEmpty(list)? StateEnum.NOT_EFFECTIVE.value :StateEnum.TAKE_EFFECT.value);
String userIdStr = new StringBuffer("00").append(userBo.getId().toString()).toString();
String tokenResult = TokenUtils.getTokenById(userIdStr);
//封装用户信息
Map userInfo = new LinkedHashMap<>();
userInfo.put("userId", userBo.getId());
userInfo.put("account", userBo.getAccount());
userInfo.put("userName", userBo.getUserName());
userInfo.put("email", userBo.getEmail());
userInfo.put("mobile", userBo.getMobile());
userInfo.put("unitId",userBo.getUnitId());
userInfo.put("unName",Objects.nonNull(responsibilityUnit)&&Objects.nonNull(responsibilityUnit.getAreaName())?responsibilityUnit.getAreaName():"未选择责任单位");
userInfo.put("wechat", userBo.getWechat());
userInfo.put("expireTime", DateUtils.dateToDateString(userBo.getExpireTime()));
userInfo.put("isAdmin", userBo.getIsAdmin());
userInfo.put("organizationId",userBo.getOrganizationId());
userInfo.put("openid", openId);
if(StringUtils.isNotEmpty(tokenResult)){
result.put("token", tokenResult);
result.put("code", ResponseCodeEnum.SUCCESS.getCode());
result.put("msg", ResponseCodeEnum.SUCCESS.getMsg());
sysLog("登陆了用户:" + userBo.getAccount()+" ;openId:"+openId,userBo);
//添加openId到user表中
User user = userMapper.selectById(userBo.getId());
user.setOpenId(openId);
userMapper.updateById(user);
TokenUtils.getRefreshTokenApp(tokenResult,userInfo);
return result;
}
try {
//生成token,并存入redis
String token = TokenUtils.getTokenApp(new StringBuffer("00").append(userBo.getId().toString()).toString(),userInfo);
result.put("token", token);
} catch (Exception e) {
log.error("token生成异常:" + e.getMessage());
result.put("code", ResponseCodeEnum.TOKEN_CREATE_ERROR.getCode());
result.put("msg", ResponseCodeEnum.TOKEN_CREATE_ERROR.getMsg());
return result;
}
sysLog("登陆了用户:" + userBo.getAccount()+";openId:"+openId,userBo);
//添加openId到user表中
User user = userMapper.selectById(userBo.getId());
user.setOpenId(openId);
userMapper.updateById(user);
return result;
}
@Override
public Map wxLogin(String code) {
Map result = new HashMap<>();
// 用户非敏感信息:rawData
// 签名:signature
// JSONObject rawDataJson = JSON.parseObject(rawData);
// 1.接收小程序发送的code
// 2.开发者服务器 登录凭证校验接口 appi + appsecret + code
JSONObject SessionKeyOpenId = WechatUtils.getSessionKeyOrOpenId(code);
// 3.接收微信接口服务 获取返回的参数
String openid = SessionKeyOpenId.getString("openid");
// String sessionKey = SessionKeyOpenId.getString("session_key");
// 4.校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
// String signature2 = DigestUtils.sha1Hex(rawData + sessionKey);
// if (!signature.equals(signature2)) {
// return ResultMessage.ok().message("签名校验失败");
// return ResultMessage.ok("签名校验失败");
// throw new BusinessException("签名校验失败");
// }
// 5.根据返回的User实体类,判断用户是否是新用户,是的话,将用户信息存到数据库;
LambdaQueryWrapper lqw = Wrappers.lambdaQuery();
lqw.eq(User::getOpenId, openid);
User user = userMapper.selectOne(lqw);
if (user == null) {
result.put("code", ResponseCodeEnum.USER_NOT_EXIST.getCode());
result.put("msg", ResponseCodeEnum.USER_NOT_EXIST.getMsg());
result.put("openId",openid);
return result;
// 用户信息入库
// String nickName = rawDataJson.getString("nickName");
// String avatarUrl = rawDataJson.getString("avatarUrl");
}
String userIdStr = new StringBuffer("00").append(user.getId().toString()).toString();
String tokenResult = TokenUtils.getTokenById(userIdStr);
result.put("userName", user.getUserName());
result.put("unitId",user.getUnitId());
List listFile = fileTableService.list(user.getId(), FileTableEnum.APP_ALLOCATION.value);
result.put("file", CollectionUtils.isNotEmpty(listFile)?listFile.get(0):new FileVo());
result.put("userId", user.getId());
result.put("account", user.getAccount());
ResponsibilityUnit responsibilityUnit = responsibilityUnitMapper.selectById(user.getUnitId());
//设备秒级权限
List list = responsibilityUnitMapper.selectCodeList(SysDictTypeEnum.SYS_DEVICE.value, user.getId());
//手持设备秒级权限
List handList = responsibilityUnitMapper.selectCodeList(SysDictTypeEnum.SYS_HAND_DEVICE.value, user.getId());
result.put("device",ObjectUtils.isEmpty(list)? StateEnum.NOT_EFFECTIVE.value : StateEnum.TAKE_EFFECT.value);
result.put("handDevice",ObjectUtils.isEmpty(handList)? StateEnum.NOT_EFFECTIVE.value : StateEnum.TAKE_EFFECT.value);
result.put("unName",Objects.nonNull(responsibilityUnit)&&Objects.nonNull(responsibilityUnit.getUnitName())?responsibilityUnit.getUnitName():"管理员登陆");
result.put("openId",openid);
Map userInfo = new LinkedHashMap<>();
userInfo.put("userId", user.getId());
userInfo.put("account", user.getAccount());
userInfo.put("userName", user.getUserName());
userInfo.put("email", user.getEmail());
userInfo.put("mobile", user.getMobile());
userInfo.put("unitId",user.getUnitId());
userInfo.put("organizationId",user.getOrganizationId());
userInfo.put("wechat", user.getWechat());
userInfo.put("expireTime", DateUtils.dateToDateString(user.getExpireTime()));
userInfo.put("isAdmin", user.getIsAdmin());
if(StringUtils.isNotEmpty(tokenResult)){
result.put("token", tokenResult);
result.put("code", ResponseCodeEnum.SUCCESS.getCode());
result.put("msg", ResponseCodeEnum.SUCCESS.getMsg());
sysLog("登陆了用户:" + user.getAccount()+" ;openId:"+openid,user);
TokenUtils.getRefreshTokenApp(tokenResult,userInfo);
return result;
}
try {
//生成token,并存入redis
String token = TokenUtils.getTokenApp(new StringBuffer("00").append(user.getId().toString()).toString(),userInfo);
result.put("token", token);
} catch (Exception e) {
log.error("token生成异常:" + e.getMessage());
result.put("code", ResponseCodeEnum.TOKEN_CREATE_ERROR.getCode());
result.put("msg", ResponseCodeEnum.TOKEN_CREATE_ERROR.getMsg());
return result;
}
result.put("code", ResponseCodeEnum.SUCCESS.getCode());
result.put("msg", ResponseCodeEnum.SUCCESS.getMsg());
sysLog("登陆了用户:" + user.getAccount()+" ;openId:"+openid,user);
return result;
}
@Override
public boolean updateUserId(Integer userId) {
User user = userMapper.selectById(userId);
user.setOpenId("0");
userMapper.updateById(user);
sysLog(userId+"退出了小程序",user);
return true;
}
/**
* 小程序推送
* @param appAllocationPushUserCond
*/
@Override
@Async("asyncPoolTaskExecutor")
public void pushOneUser(Allocation appAllocationPushUserCond) {
QxUser currentUser = UserHelper.getCurrentUser();
ResponsibilityUnit responsibilityUnit = responsibilityUnitMapper.selectById(appAllocationPushUserCond.getUnitId());
Integer areaCode = responsibilityUnit.getAreaCode();
List responsibilityUnits = responsibilityUnitService.selectAreaUnit(areaCode.toString().length()>6?responsibilityUnit.getParentCode():responsibilityUnit.getAreaCode());
//获取unitid
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getIsDelete,Constants.NOT_DELETE);
Integer state = appAllocationPushUserCond.getState();
if (state==20){
wrapper.eq(User::getUnitId,appAllocationPushUserCond.getUnitId());
}else {
wrapper.eq(User::getUnitId,ObjectUtils.isEmpty(responsibilityUnits)?0:responsibilityUnits.get(0).getUnitId());
}
List users = userMapper.selectList(wrapper);
if (ObjectUtils.isEmpty(users)){
return;
}
String dateString = DateUtils.dateToDateString(appAllocationPushUserCond.getEscalationTime(),"MM月dd日");
//这里简单起见我们每次都获取最新的access_token(时间开发中,应该在access_token快过期时再重新获取)
//小程序订阅
String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + WechatUtils.getAccessToken();
//发送消息
for (User user : users) {
if (user.getId().equals(currentUser.getUserId())){
continue;
}
RestTemplate restTemplate = new RestTemplate();
//拼接推送的模版
WxMssVo wxMssVo = new WxMssVo();
wxMssVo.setTouser(user.getOpenId());//用户的openid(要发送给那个用户,通常这里应该动态传进来的)
wxMssVo.setTemplate_id("YNqUZ1MgMvwY3G-NENVbcmIBR5dUotSdnwcz96CWrho");//订阅消息模板id
wxMssVo.setLang("zh_CN");
wxMssVo.setMiniprogramState("formal");
wxMssVo.setPage("pages/index/index");
Map m = new HashMap<>();
HashMap map1 = new HashMap<>();
HashMap map2 = new HashMap<>();
HashMap map3 = new HashMap<>();
HashMap map4 = new HashMap<>();
map1.put("value",responsibilityUnit.getUnitName()+dateString+"的交办单");
map2.put("value",appAllocationPushUserCond.getAllocationNum());
map3.put("value",state==30? AllocationApproveEnum.IN_APPROVAL.name:AllocationApproveEnum.UNDER_RECTIFICATION.name);
map4.put("value",DateUtils.dateToDateString(new Date(),"yyyy年MM月dd日"));
m.put("thing18", map1);
m.put("character_string1", map2);
m.put("thing2", map3);
m.put("date4", map4);
wxMssVo.setData(JSON.toJSON(m));
ResponseEntity responseEntity =
restTemplate.postForEntity(url, wxMssVo, String.class);
String body = responseEntity.getBody();
log.info("信息:"+body+"账号:"+user.getAccount()+"openID"+user.getOpenId());
}
}
private void sysLog(String cont,User user){
//日志
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
UserLog userLog = new UserLog();
userLog.setType(Constants.LOGIN_OPERTATE_APP);
userLog.setIp(WebUtils.getIpAddr(request));
userLog.setOperateId(user.getId());
userLog.setOrganizationId(user.getOrganizationId());
userLog.setContent(cont);
userLogMapper.insert(userLog);
}
@Override
public Map login(Map parameters) {
UserBO userBo = selectUserInfo(parameters);
Map result = new HashMap<>();
//校验账户
if (userBo == null) {
result.put("code", ResponseCodeEnum.ACCOUNT_NOT_EXIST.getCode());
result.put("msg", ResponseCodeEnum.ACCOUNT_NOT_EXIST.getMsg());
return result;
}
//校验密码
String password = parameters.get("password").toString();
//密码解密
password = AESUtils.decrypt(password, AESKey);
if (!MD5Utils.saltMD5Verify(password, userBo.getPassword())) {
result.put("code", ResponseCodeEnum.PASSWORD_INVALID.getCode());
result.put("msg", ResponseCodeEnum.PASSWORD_INVALID.getMsg());
return result;
}
//校验是否删除
if (Constants.DELETE.equals(userBo.getIsDelete())) {
result.put("code", ResponseCodeEnum.ACCOUNT_IS_DELETE.getCode());
result.put("msg", ResponseCodeEnum.ACCOUNT_IS_DELETE.getMsg());
return result;
}
//校验是否过期
if (userBo.getExpireTime() != null && userBo.getExpireTime().getTime() < System.currentTimeMillis()) {
result.put("code", ResponseCodeEnum.ACCOUNT_IS_EXPIRE.getCode());
result.put("msg", ResponseCodeEnum.ACCOUNT_IS_EXPIRE.getMsg());
return result;
}
//封装用户信息
Map userInfo = new LinkedHashMap<>();
ResponsibilityUnit responsibilityUnit = responsibilityUnitMapper.selectById(userBo.getUnitId());
//用户信息
userInfo.put("userId", userBo.getId());
userInfo.put("account", userBo.getAccount());
userInfo.put("userName", userBo.getUserName());
userInfo.put("email", userBo.getEmail());
userInfo.put("mobile", userBo.getMobile());
userInfo.put("unitId",userBo.getUnitId());
userInfo.put("unName",Objects.nonNull(responsibilityUnit)&&Objects.nonNull(responsibilityUnit.getAreaName())?responsibilityUnit.getAreaName():"未选择责任单位");
userInfo.put("wechat", userBo.getWechat());
userInfo.put("expireTime", DateUtils.dateToDateString(userBo.getExpireTime()));
userInfo.put("isAdmin", userBo.getIsAdmin());
//用户组织信息
Organization organization = userBo.getOrganization();
Map orgInfo = new LinkedHashMap<>();
orgInfo.put("id", userBo.getOrganizationId());
orgInfo.put("name", organization.getName());
orgInfo.put("locationLevelCode", organization.getLocationLevelCode());
orgInfo.put("expireTime", DateUtils.dateToDateString(organization.getExpireTime()));
userInfo.put("organization", orgInfo);
//用户组信息
Group group = userBo.getGroup();
Map groupMap = new LinkedHashMap<>();
userInfo.put("group", groupMap);
if (group != null) {
groupMap.put("id", group.getId());
groupMap.put("groupName", group.getGroupName());
userInfo.put("group", groupMap);
}
Map map = new HashMap<>();
map.put("userId", userBo.getId());
//用户菜单信息
userInfo.putAll(getMenus(map));
try {
//生成token,并存入redis
String token = TokenUtils.getToken(userBo.getId().toString(), userInfo);
result.put("token", token);
} catch (Exception e) {
log.error("token生成异常:" + e.getMessage());
result.put("code", ResponseCodeEnum.TOKEN_CREATE_ERROR.getCode());
result.put("msg", ResponseCodeEnum.TOKEN_CREATE_ERROR.getMsg());
return result;
}
//日志
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
UserLog userLog = new UserLog();
userLog.setType(Constants.LOGIN_OPERTATE_TYPE);
userLog.setIp(WebUtils.getIpAddr(request));
userLog.setOperateId(userBo.getId());
userLog.setOrganizationId(userBo.getOrganizationId());
userLog.setContent("登陆了用户:" + userBo.getAccount());
userLogMapper.insert(userLog);
return result;
}
@Override
public Map getCurrentUserInfo() {
Map userInfo = (Map) TokenUtils.getUserInfo();
return userInfo;
}
@Override
public Map getMenus(Map parameters) {
List