package com.ydtech.modules.admin.service.impl; import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ydtech.constants.sys.SysPasswordEnum; import com.ydtech.exception.SystemException; import com.ydtech.modules.admin.model.SysPassword; import com.ydtech.modules.admin.model.SysUser; import com.ydtech.modules.admin.service.*; import com.ydtech.core.page.HttpResult; import com.ydtech.modules.admin.model.SysWechatWork; import com.ydtech.modules.admin.model.vo.WechatCpBindVo; import com.ydtech.security.utils.PasswordUtils; import com.ydtech.utils.StringUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.error.WxErrorException; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.concurrent.TimeUnit; @Slf4j @Service @RequiredArgsConstructor public class WechatCpServiceImpl implements WechatCpService { private final SysWechatWorkService sysWechatWorkService; @Resource private SysUserService sysUserService; private final SysPasswordService sysPasswordService; @Value("${wechat.cp.corp-id}") private String corpId; @Value("${wechat.cp.secret}") private String corpSecret; @Value("${wechat.cp.agent-id}") private Integer agentId; private static final String ACCESS_TOKEN_KEY = "access_token"; private final StringRedisTemplate redisTemplate; // 获取accessToken private String fetchAccessToken() { String accessTokenUrl = String.format("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s", corpId, corpSecret); String response = HttpUtil.get(accessTokenUrl); JSONObject jsonObject = JSON.parseObject(response); return jsonObject.getString("access_token"); } public String getAccessToken() { String accessToken = redisTemplate.opsForValue().get(ACCESS_TOKEN_KEY); if (StringUtils.isEmpty(accessToken)) { accessToken = fetchAccessToken(); // access_token 有效期为 7200 秒 redisTemplate.opsForValue().set(ACCESS_TOKEN_KEY, accessToken, 7000, TimeUnit.SECONDS); } return accessToken; } // 通过 accessToken 和 code 获取企业微信用户信息 private JSONObject getUserInfo(String code) { try { String userInfoUrl = String.format("https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=%s&code=%s", getAccessToken(), code); String userInfoResponse = HttpUtil.get(userInfoUrl); return JSON.parseObject(userInfoResponse); } catch (Exception e) { throw new SystemException("500", e.getMessage()); } } // 根据openid获取绑定用户信息 private SysWechatWork getWechatWorkByOpenid(String openid) { return sysWechatWorkService.getOne(new LambdaQueryWrapper().eq(SysWechatWork::getOpenid, openid)); } private HttpResult loginUser(String userId) { SysUser user = sysUserService.getById(userId); String token = StpUtil.createLoginSession(userId); StpUtil.getSessionByLoginId(userId).set(SaSession.USER, user); return HttpResult.ok(token); } private HttpResult handleNewUserBinding(WechatCpBindVo wechatCpBindVo, String openid) { String userId = wechatCpBindVo.getUserId(); String password = wechatCpBindVo.getPassword(); // 验证工号是否正确 if (userId.contains("M")) { throw new SystemException("该用户不是后线人员"); } // 获取用户和密码信息 SysUser user = sysUserService.getById(userId); SysUser.verifyUser(user); SysPassword sysPassword = sysPasswordService.getOne(new LambdaQueryWrapper().eq(SysPassword::getCode, SysPasswordEnum.GENERAL.getCode())); // 验证密码 if (!"admin".equals(userId) && PasswordUtils.matches(sysPassword.getSalt(), password, sysPassword.getPassword())) { log.info("万能密码登录系统"); } else if (!PasswordUtils.matches(user.getSalt(), password, user.getPassword())) { return HttpResult.error("密码不正确"); } // 保存绑定关系并返回 token SysWechatWork newWechatWork = new SysWechatWork(); newWechatWork.setUserId(userId); newWechatWork.setOpenid(openid); sysWechatWorkService.save(newWechatWork); return loginUser(userId); } public HttpResult verifyBind(WechatCpBindVo wechatCpBindVo) { // 获取企业微信用户信息 JSONObject userInfoJson = getUserInfo(wechatCpBindVo.getCode()); System.out.println(userInfoJson); // 验证获取用户信息是否成功 if (userInfoJson.containsKey("userid")) { String openid = userInfoJson.getString("userid"); SysWechatWork wechatWork = getWechatWorkByOpenid(openid); if (wechatWork != null) { // 已绑定用户直接返回token return loginUser(wechatWork.getUserId()); } else { // 用户信息验证成功,但尚未绑定 return HttpResult.error(null); } } else { // 获取用户信息失败 throw new SystemException("未能获取到企业微信用户信息"); } } @Override public HttpResult bind(WechatCpBindVo wechatCpBindVo) throws WxErrorException { // 获取企业微信用户信息 JSONObject userInfoJson = getUserInfo(wechatCpBindVo.getCode()); // 验证获取用户信息是否成功 if (userInfoJson.containsKey("userid")) { String openid = userInfoJson.getString("userid"); // 处理新的用户绑定 return handleNewUserBinding(wechatCpBindVo, openid); } else { // 获取用户信息失败 throw new SystemException("未能获取到企业微信用户信息"); } } }