| package doumeemes.service.system.impl; | 
|   | 
| import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | 
| import com.alibaba.fastjson.JSONObject; | 
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | 
| import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; | 
| import doumeemes.biz.system.SystemDictDataBiz; | 
| import doumeemes.config.shiro.ShiroToken; | 
| import doumeemes.core.constants.ResponseStatus; | 
| import doumeemes.core.exception.BusinessException; | 
| import doumeemes.core.model.LoginUserInfo; | 
| import doumeemes.core.utils.Constants; | 
| import doumeemes.core.utils.HttpsUtil; | 
| import doumeemes.core.utils.Utils; | 
| import doumeemes.core.utils.WxMiniConfig; | 
| import doumeemes.dao.business.model.Company; | 
| import doumeemes.dao.business.model.CompanyUser; | 
| import doumeemes.dao.business.model.Department; | 
| import doumeemes.dao.ext.CompanyExtMapper; | 
| import doumeemes.dao.ext.CompanyUserExtMapper; | 
| import doumeemes.dao.ext.DepartmentExtMapper; | 
| import doumeemes.dao.ext.dto.WxLoginDTO; | 
| import doumeemes.dao.ext.dto.WxLoginOutDTO; | 
| import doumeemes.dao.ext.vo.WxLoginVO; | 
| import doumeemes.dao.system.SystemUserMapper; | 
| import doumeemes.dao.system.dto.LoginDTO; | 
| import doumeemes.dao.system.model.SystemLoginLog; | 
| import doumeemes.dao.system.model.SystemUser; | 
| import doumeemes.service.system.SystemLoginLogService; | 
| import doumeemes.service.system.WxLoginService; | 
| import lombok.extern.slf4j.Slf4j; | 
| import me.chanjar.weixin.common.error.WxErrorException; | 
| import org.apache.commons.lang3.StringUtils; | 
| import org.apache.shiro.SecurityUtils; | 
| import org.apache.shiro.authc.AuthenticationException; | 
| import org.apache.shiro.subject.Subject; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.beans.factory.annotation.Value; | 
| import org.springframework.stereotype.Service; | 
|   | 
| import javax.servlet.http.HttpServletRequest; | 
| import java.util.Date; | 
| import java.util.Objects; | 
|   | 
| /** | 
|  * Created by IntelliJ IDEA. | 
|  * | 
|  * @Author : Rk | 
|  * @create 2023/8/11 10:14 | 
|  */ | 
| @Slf4j | 
| @Service | 
| public class WxLoginServiceImpl implements WxLoginService { | 
|   | 
|     @Autowired | 
|     private SystemDictDataBiz systemDictDataBiz; | 
|   | 
|     @Value("${project.version}") | 
|     private String systemVersion; | 
|   | 
|     @Autowired | 
|     private CompanyUserExtMapper companyUserExtMapper; | 
|     @Autowired | 
|     private SystemUserMapper systemUserMapper; | 
|     @Autowired | 
|     private DepartmentExtMapper departmentExtMapper; | 
|   | 
|     @Autowired | 
|     private SystemLoginLogService systemLoginLogService; | 
|     @Autowired | 
|     private CompanyExtMapper companyExtMapper; | 
|   | 
|   | 
|     /** | 
|      * 微信公众号获取TOKEN地址 | 
|      */ | 
|     public static final String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code"; | 
|   | 
|     /** | 
|      * 微信公众号获取USERINFO信息地址 | 
|      */ | 
|     public static final String GET_USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN"; | 
|   | 
|     public static final String  url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN"; | 
|   | 
|     /** | 
|      * 注:公众号-设置与开发-基本设置,必须【已绑定的微信开放平台账号】 | 
|      * @param code | 
|      * @param request | 
|      * @return | 
|      */ | 
|     @Override | 
|     public WxLoginVO wxLogin(String code, HttpServletRequest request) { | 
|         String appId = systemDictDataBiz.queryByCode(Constants.WX_CONFIG,Constants.APPID).getCode(); | 
|         String appSecret = systemDictDataBiz.queryByCode(Constants.WX_CONFIG,Constants.APPSECRET).getCode(); | 
|         String getTokenUrl = GET_ACCESS_TOKEN_URL.replace("CODE", code).replace("APPID", appId).replace("SECRET", appSecret); | 
|         JSONObject tokenJson = JSONObject.parseObject(HttpsUtil.get(getTokenUrl,true)); | 
|         String openId = tokenJson.getString("openid"); | 
|         //注:公众号-设置与开发-基本设置,必须【已绑定的微信开放平台账号】 | 
|         String unionId = tokenJson.getString("unionid"); | 
|         return  loginByUnionIdAndReturn(unionId,Constants.OPENID_WX+openId,request); | 
|     } | 
|   | 
|   | 
|     @Override | 
|     public WxLoginVO wxProgramLogin(String code, HttpServletRequest request) { | 
|         try { | 
|             WxMaJscode2SessionResult session =   WxMiniConfig.wxMaService.getUserService().getSessionInfo(code); | 
|             String unionid = session.getUnionid(); | 
|             String openId = session.getOpenid(); | 
|             return  loginByUnionIdAndReturn(unionid,Constants.OPENID_MINI+openId,request); | 
|         } catch (WxErrorException e) { | 
|             e.printStackTrace(); | 
|         } | 
|         throw new BusinessException(ResponseStatus.SERVER_ERROR.getCode(),"微信授权失败,请联系管理员"); | 
|   | 
|   | 
|   | 
|     } | 
|     private WxLoginVO loginByUnionIdAndReturn(String unionid,String openId,HttpServletRequest request) { | 
|         WxLoginVO wxLoginVO = new WxLoginVO(); | 
|         wxLoginVO.setOpenid(openId); | 
|         wxLoginVO.setUnionid(unionid); | 
|         CompanyUser companyUser = companyUserExtMapper.selectOne(new QueryWrapper<CompanyUser>().lambda() | 
|                 .eq(CompanyUser::getUnionid,wxLoginVO.getUnionid()) | 
|                 .eq(CompanyUser::getDeleted,Constants.ZERO) | 
|                 .last(" limit 1 ")); | 
| //        CompanyUser companyUser = companyUserExtMapper.selectOne(new QueryWrapper<CompanyUser>().eq("openid",openId).last(" limit 1 ")); | 
|         if(Objects.isNull(companyUser)){ | 
|             wxLoginVO.setLoginStatus(Constants.ONE); | 
|             return wxLoginVO; | 
|         } | 
|         Department department = departmentExtMapper.selectById(companyUser.getRootDepartId()); | 
|         if(Objects.isNull(department)){ | 
|             throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"未查询到绑定部门信息"); | 
|         } | 
|         Company company = companyExtMapper.selectById(department.getCompanyId()); | 
|         if(Objects.isNull(company)||company.getStatus().equals(Constants.ZERO)){ | 
|             wxLoginVO.setLoginStatus(Constants.ONE); | 
|             return wxLoginVO; | 
|         } | 
|         SystemUser systemUser = systemUserMapper.selectById(companyUser.getUserId()); | 
|         //查询用户数据 | 
|         LoginDTO dto = new LoginDTO(); | 
|         dto.setCompanyId(department.getCompanyId()); | 
|         dto.setUsername(systemUser.getUsername()); | 
|         SystemLoginLog loginLog = new SystemLoginLog(); | 
|         loginLog.setLoginUsername(dto.getUsername()); | 
|         loginLog.setLoginTime(new Date()); | 
|         loginLog.setSystemVersion(systemVersion); | 
|         loginLog.setIp(Utils.User_Client.getIP(request)); | 
|         loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp())); | 
|         loginLog.setPlatform(Utils.User_Client.getPlatform(request)); | 
|         loginLog.setClientInfo(Utils.User_Client.getBrowser(request)); | 
|         loginLog.setOsInfo(Utils.User_Client.getOS(request)); | 
|         loginLog.setServerIp(Utils.Server.getIP()); | 
|         // 校验用户名和密码 | 
|         Subject subject = SecurityUtils.getSubject(); | 
|         ShiroToken token = new ShiroToken(dto.getCompanyId(),dto.getUsername(), null,false,true); | 
|         try { | 
|             subject.login(token); | 
|             LoginUserInfo loginUser = ((LoginUserInfo)subject.getPrincipal()); | 
|             loginLog.setUserId(loginUser.getId()); | 
|             loginLog.setCompanyId(loginUser.getCompany()!=null?loginUser.getCompany().getId():null); | 
|             loginLog.setCompanyUserId(loginUser.getCompanyUser()!=null?loginUser.getCompanyUser().getId():null); | 
|             loginLog.setSuccess(Boolean.TRUE); | 
|             systemLoginLogService.create(loginLog); | 
|             String session = (String)subject.getSession().getId(); | 
|             wxLoginVO.setLoginStatus(Constants.ZERO); | 
|             wxLoginVO.setSession(session); | 
|             return wxLoginVO; | 
|         }catch (BusinessException e) { | 
|             wxLoginVO.setLoginStatus(Constants.ONE); | 
|             return wxLoginVO; | 
|         }catch (AuthenticationException e) { | 
|             BusinessException ee = null; | 
|             loginLog.setSuccess(Boolean.FALSE); | 
|             if(e.getCause()!=null && e.getCause() instanceof  BusinessException){ | 
|                 ee =   (BusinessException)e.getCause(); | 
|                 loginLog.setReason(ee.getMessage().length() > 200 ? (ee.getMessage().substring(0, 190) + "...") : ee.getMessage()); | 
|                 log.error(ee.getMessage(), e); | 
|             }else{ | 
|                 log.error(ResponseStatus.ACCOUNT_INCORRECT.getMessage(), e); | 
|                 loginLog.setReason(e.getMessage().length() > 200 ? (e.getMessage().substring(0, 190) + "...") : e.getMessage()); | 
|                 ee = new BusinessException(ResponseStatus.ACCOUNT_INCORRECT); | 
|             } | 
|             systemLoginLogService.create(loginLog); | 
|             throw  ee; | 
|         } | 
|     } | 
|   | 
|   | 
|   | 
|   | 
|     @Override | 
|     public String wxLoginByPassword(WxLoginDTO dto, HttpServletRequest request) { | 
|         SystemLoginLog loginLog = new SystemLoginLog(); | 
|         loginLog.setLoginUsername(dto.getUsername()); | 
|         loginLog.setLoginTime(new Date()); | 
|         loginLog.setSystemVersion(systemVersion); | 
|         loginLog.setIp(Utils.User_Client.getIP(request)); | 
|         loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp())); | 
|         loginLog.setPlatform(Utils.User_Client.getPlatform(request)); | 
|         loginLog.setClientInfo(Utils.User_Client.getBrowser(request)); | 
|         loginLog.setOsInfo(Utils.User_Client.getOS(request)); | 
|         loginLog.setServerIp(Utils.Server.getIP()); | 
|         // 校验用户名和密码 | 
|         Subject subject = SecurityUtils.getSubject(); | 
|         ShiroToken token = new ShiroToken(dto.getCompanyId(),dto.getUsername(), dto.getPassword(),false,false); | 
|         try { | 
|             subject.login(token); | 
|             LoginUserInfo loginUser = ((LoginUserInfo)subject.getPrincipal()); | 
|             loginLog.setUserId(loginUser.getId()); | 
|             loginLog.setCompanyId(loginUser.getCompany()!=null?loginUser.getCompany().getId():null); | 
|             loginLog.setCompanyUserId(loginUser.getCompanyUser()!=null?loginUser.getCompanyUser().getId():null); | 
|             loginLog.setSuccess(Boolean.TRUE); | 
|             systemLoginLogService.create(loginLog); | 
|             //登录携带微信openid信息 | 
|             if(StringUtils.isNotBlank(dto.getOpenid())){ | 
|                 CompanyUser companyUser = companyUserExtMapper.selectById(loginLog.getCompanyUserId()); | 
|                 if(StringUtils.isBlank(companyUser.getOpenid())||!companyUser.getOpenid().equals(dto.getOpenid())){ | 
|                     //1、绑定微信openid到companyUser表信息 | 
|                     companyUser.setOpenid(dto.getOpenid()); | 
|                     companyUser.setUnionid(dto.getUnionid()); | 
|                     companyUserExtMapper.updateById(companyUser); | 
|                     //2、清空同用户其余companyUser表openid与 unionid | 
|                     companyUserExtMapper.update(null,new UpdateWrapper<CompanyUser>() | 
|                             .ne("ID",companyUser.getId()).set("UNIONID","").set("OPENID","") | 
|                             .eq("USER_ID",companyUser.getUserId()) | 
|                     ); | 
|                 } | 
|             } | 
|             return (String)subject.getSession().getId(); | 
|         }catch (AuthenticationException e) { | 
|             BusinessException ee = null; | 
|             loginLog.setSuccess(Boolean.FALSE); | 
|             if(e.getCause()!=null && e.getCause() instanceof  BusinessException){ | 
|                 ee =   (BusinessException)e.getCause(); | 
|                 loginLog.setReason(ee.getMessage().length() > 200 ? (ee.getMessage().substring(0, 190) + "...") : ee.getMessage()); | 
|                 log.error(ee.getMessage(), e); | 
|             }else{ | 
|                 log.error(ResponseStatus.ACCOUNT_INCORRECT.getMessage(), e); | 
|                 loginLog.setReason(e.getMessage().length() > 200 ? (e.getMessage().substring(0, 190) + "...") : e.getMessage()); | 
|                 ee = new BusinessException(ResponseStatus.ACCOUNT_INCORRECT); | 
|             } | 
|             systemLoginLogService.create(loginLog); | 
|             throw  ee; | 
|         } | 
|     } | 
|   | 
|     @Override | 
|     public void wxLoginOut(WxLoginOutDTO wxLoginOutDTO) { | 
|         if(!Objects.isNull(wxLoginOutDTO)&&!Objects.isNull(wxLoginOutDTO.getCompanyUserId())){ | 
|             companyUserExtMapper.update(null,new UpdateWrapper<CompanyUser>() | 
|                     .set("UNIONID","").set("OPENID","") | 
|                     .eq("id",wxLoginOutDTO.getCompanyUserId()) | 
|             ); | 
|         } | 
|     } | 
|   | 
| } |