package com.xy.service; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.yitter.idgen.YitIdHelper; import com.google.common.base.Throwables; import com.xy.annotation.Lock; import com.xy.collections.list.JArrayList; import com.xy.collections.list.JList; import com.xy.config.WeChatOfficialConfig; import com.xy.config.WebMqttConfig; import com.xy.device.EnumDeviceQrCode; import com.xy.device.EnumDeviceType; import com.xy.dto.MercDeviceQrConfigDto; import com.xy.dto.SysWorkUser.AddDto; import com.xy.dto.SysWorkUser.DelDto; import com.xy.dto.SysWorkUser.UpdateDto; import com.xy.dto.UserInfoDto; import com.xy.dto.WxServiceMsgDto; import com.xy.entity.UserInfo; import com.xy.error.CommRuntimeException; import com.xy.mapper.UserInfoMapper; import com.xy.utils.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.mp.api.WxMpMessageHandler; import me.chanjar.weixin.mp.api.WxMpMessageRouter; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import java.util.List; import java.util.Map; import java.util.Objects; import static com.xy.utils.Beans.copy; import static com.xy.utils.PlusBeans.toIPage; import static com.xy.utils.PlusBeans.toPageBean; /** *

* 用户表 服务实现类 *

* * @author lijin * @since 2023-01-12 */ @Slf4j @Service @AllArgsConstructor @Api(tags = "用户表") public class UserInfoServiceImpl extends ServiceImpl implements UserInfoService { private SysWorkUserService sysWorkUserService; private WebMqttConfig webMqttConfig; private WxMpService wxService; private WeChatOfficialConfig weChatOfficialConfig; @Override @ApiOperation("集合查询") public R> list(UserInfoDto.SelectListDto selectList) { List userIds = selectList.getUserIds(); UserInfoDto.Vo userVo = selectList.getUserVo(); LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); if (userVo != null) { lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(selectList.getUserVo(), UserInfo.class).build(); } lambdaQueryWrapper.in(CollUtil.isNotEmpty(userIds), UserInfo::getUserId, userIds); List list = list(lambdaQueryWrapper); return R.ok(copy(UserInfoDto.Vo.class, list)); } @Override @ApiOperation("对象查询") public R obj(UserInfoDto.Vo vo) { LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(vo, UserInfo.class).build(); List list = list(lambdaQueryWrapper); if (Emptys.check(list)) { return R.ok(copy(UserInfoDto.Vo.class, list.get(0))); } return R.ok(); } @PostMapping("page") @ApiOperation("分页查询") public R> page(@RequestBody UserInfoDto.Page page) { PageBean pageBean = page.getPage(); LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(page, UserInfo.class) .like(UserInfo::getTel, page.getTel()) .like(UserInfo::getMail, page.getMail()) .like(UserInfo::getUnionid, page.getUnionid()) .ge(UserInfo::getCreateTime, page.getBeginCreateTime()) .le(UserInfo::getCreateTime, page.getEndCreateTime()) .build() .eq(!AuthorizeUtils.authByData(page.getSysId()), UserInfo::getCreateUser, AuthorizeUtils.getLoginId(Long.class)) .orderByDesc(!Emptys.check(pageBean.getOrders()), UserInfo::getCreateTime); IPage iPage = page(toIPage(pageBean), lambdaQueryWrapper); return R.ok(toPageBean(UserInfoDto.Vo.class, iPage)); } @Override @ApiOperation("添加") @Lock(value = "save.tel", prefix = "user_save_") public R save(UserInfoDto.Save save) { //添加权限用户 AddDto addDto = copy(AddDto.class, save) .setEmail(save.getMail()) .setPhone(save.getTel()) .setRoleIds(save.getRoleIds()) .setAccount(save.getAccount()); R register = sysWorkUserService.register(addDto); if (register.getCode() != R.Enum.SUCCESS.getCode()) { return R.fail(register.getMsg()); } Long authorizeUserId = register.getData(); //添加用户 Long loginId = AuthorizeUtils.getLoginId(Long.class); UserInfo saveInfo = copy(UserInfo.class, save) .createUserTime(loginId) .setUserId(YitIdHelper.nextId()) .setAuthorizeUserId(authorizeUserId) .createUserTime(loginId); save(saveInfo); return R.ok(copy(UserInfoDto.Vo.class, saveInfo)); } @Override @ApiOperation("修改") @Lock(value = "update.userId", prefix = "user_update_") public R update(UserInfoDto.Update update) { log.info("权限用户信息修改请求:{}", JSONUtil.toJsonPrettyStr(update)); UserInfo byId = getById(update.getUserId()); String account = update.getAccount(); if (StrUtil.isNotEmpty(update.getTel())) { if (!update.getTel().equals(byId.getTel())) { long count = count(new LambdaQueryWrapper().eq(UserInfo::getTel, update.getTel())); if (count > 0) { return R.fail("手机已存在"); } } } if (StrUtil.isNotEmpty(update.getMail())) { if (!byId.getMail().equals(update.getMail())) { long count = count(new LambdaQueryWrapper().eq(UserInfo::getMail, update.getMail())); if (count > 0) { return R.fail("邮箱已存在"); } } } UserInfo updateInfo = copy(UserInfo.class, update) .updateUserTime(AuthorizeUtils.getLoginId(Long.class)); UserInfo u = getById(update.getUserId()); //修改权限用户 if (Emptys.check(update.getTel()) || Emptys.check(update.getMail()) || Emptys.check(update.getStatus()) || Emptys.check(update.getPassword())) { UpdateDto updateDto = new UpdateDto() .setId(u.getAuthorizeUserId()) .setAccount(account) .setPhone(update.getTel()) .setEmail(update.getMail()) .setPassword(update.getPassword()) .setStatus(update.getStatus()) .setRoleIds(update.getRoleIds()); log.info("权限用户信息修改:{}", JSONUtil.toJsonPrettyStr(updateDto)); sysWorkUserService.update(updateDto); } //修改用户 updateById(updateInfo); return R.ok(); } @ApiOperation("删除用户") @Override public R del(@RequestBody @Validated UserInfoDto.DelDto dto) { //sys_work_user 权限用户表 R r = sysWorkUserService.del(copy(DelDto.class, dto)); if (R.Enum.SUCCESS.getCode() != r.getCode()) { return R.fail(r.getMsg()); } //user_info 用户表 return R.ok(removeBatchByIds(dto.getId())); } @PostMapping("webUserMqtt") @ApiOperation("获取用户mqtt信息") public R webUserMqtt(@RequestBody @Validated UserInfoDto.WebUserMqtt webUserMqtt) { Long loginId = AuthorizeUtils.getLoginId(Long.class); Integer type = webUserMqtt.getType(); UserInfoDto.WebUserMqttVo webUserMqttVo = new UserInfoDto.WebUserMqttVo() .setUsername(webMqttConfig.getUsername()) .setPassword(webMqttConfig.getPassword()); WebMqttConfig.Protocol protocol = webMqttConfig.getProtocol(); WebMqttConfig.Topic topic = webMqttConfig.getTopic(); if (type == 1) { webUserMqttVo.setUrl(protocol.getPcUrl() + webMqttConfig.getIp()) .setPort(webMqttConfig.getWsPort()) .setClientTopic(topic.getPrefix() + topic.getPcManagePrefix() + loginId); } else if (type == 2) { webUserMqttVo.setUrl(protocol.getWxsUrl() + webMqttConfig.getIp()) .setPort(webMqttConfig.getWssPort()) .setClientTopic(topic.getPrefix() + topic.getWxCPrefix() + loginId); } else if (type == 3) { webUserMqttVo.setUrl(protocol.getAlisUrl() + webMqttConfig.getIp()) .setPort(webMqttConfig.getWssPort()) .setClientTopic(topic.getPrefix() + topic.getAlisCPrefix() + loginId); } return R.ok(webUserMqttVo); } @ApiOperation("修改微信信息") @Override public R updateByWechat(UserInfoDto.UpdateByWechat dto) { updateById(copy(UserInfo.class, dto)); return R.ok(); } @ApiOperation("修改支付宝信息") @Override public R updateByAli(UserInfoDto.UpdateByAli dto) { updateById(copy(UserInfo.class, dto)); return R.ok(); } @SneakyThrows @PostMapping("wxQrCode") @ApiOperation("获取微信服务号二维码-扫码关注公众号并绑定") public R getQrCode(@RequestBody @Validated UserInfoDto.WxQrCode wxQrCode) { WxMpService wxMpService = weChatOfficialConfig.getWxMpService(); if (wxMpService == null) { throw new CommRuntimeException("获取微信公众号配置信息失败!"); } //指定用户 String userId = wxQrCode.getUserId(); if (StrUtil.isEmpty(userId)) { //当前登录用户 userId = AuthorizeUtils.getLoginId(String.class); } WxMpQrCodeTicket ticket = wxService.getQrcodeService().qrCodeCreateTmpTicket(userId, 2592000); String tk = ticket.getTicket(); String url = wxService.getQrcodeService().qrCodePictureUrl(tk); JList contents = new JArrayList<>(); contents.set(url); JList text = new JArrayList<>(); text.set("使用微信[扫一扫]关注"); List base64s = QRCodeUtils.create(contents, 400, 400, "back1.png", text).base64(); UserInfoDto.WxQrCodeVO vo = new UserInfoDto.WxQrCodeVO(); log.info("获取微信服务号二维码 usrId:{},tk:{}", userId, tk); return R.ok(vo.setImgList(base64s).setTicket(tk)); } private WxMpMessageRouter wxMpMessageRouter; @Autowired private Map wxMpMessageHandlers; /** * 接收微信的事件消息 * https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html * * @return */ @RequestMapping(value = "/receipt", produces = {"application/xml; charset=UTF-8"}) @ApiOperation("接收微信的事件消息") public String receiptMessage(@RequestBody(required = false) WxServiceMsgDto wxServiceMsgDto, HttpServletRequest request) { WxMpService wxMpService = weChatOfficialConfig.getWxMpService(); if (wxMpService == null) { throw new CommRuntimeException("获取微信公众号配置信息失败!"); } String echoStr = request.getParameter(WeChatOfficialConfig.ECHO_STR); // echoStr!=null,说明只是微信调试的请求 if (CharSequenceUtil.isNotBlank(echoStr)) { return echoStr; } String signature = request.getParameter(WeChatOfficialConfig.SIGNATURE); String nonce = request.getParameter(WeChatOfficialConfig.NONCE); String timestamp = request.getParameter(WeChatOfficialConfig.TIMESTAMP); if (!wxService.checkSignature(timestamp, nonce, signature)) { throw new CommRuntimeException("接收微信的事件消息,验签异常!"); } log.info("接收微信的事件消息:{}", wxServiceMsgDto); //处理带参数请求 if (null != wxServiceMsgDto && !StrUtil.isEmpty(wxServiceMsgDto.getMsgType()) && !StrUtil.isEmpty(wxServiceMsgDto.getEvent()) && !StrUtil.isEmpty(wxServiceMsgDto.getEventKey()) && !wxServiceMsgDto.getEventKey().equals("null") && (wxServiceMsgDto.getEventKey().equals("subscribe") || wxServiceMsgDto.getEvent().equals("SCAN")) ) { //关注 if (wxServiceMsgDto.getEvent().equals("subscribe")) { log.info("关注: " + wxServiceMsgDto.getFromUserName()); setCacheTicket("1", wxServiceMsgDto.getFromUserName()); if (wxServiceMsgDto.getEventKey().contains("FenXiangMa")) { log.info("优惠券领取"); } } //扫码 if (wxServiceMsgDto.getEvent().equals("SCAN")) { log.info("扫码: " + wxServiceMsgDto.getFromUserName()); if (wxServiceMsgDto.getEventKey().contains("YaoQingMa")) { log.info("新用户邀请"); } } log.info("参数: " + wxServiceMsgDto.getEventKey()); } return ""; // // String encryptType = CharSequenceUtil.isBlank(request.getParameter(WeChatOfficialConfig.ENCRYPT_TYPE)) ? WeChatOfficialConfig.RAW : request.getParameter(WeChatOfficialConfig.ENCRYPT_TYPE); // if (WeChatOfficialConfig.RAW.equals(encryptType)) { // WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream()); // log.info("raw inMessage:{}", JSON.toJSONString(inMessage)); // WxMpXmlOutMessage outMessage = weChatOfficialConfig.getWxMpMessageRouter().route(inMessage); // return outMessage.toXml(); // } else if (WeChatOfficialConfig.AES.equals(encryptType)) { // String msgSignature = request.getParameter(WeChatOfficialConfig.MSG_SIGNATURE); // WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), weChatOfficialConfig.getConfig(), timestamp, nonce, msgSignature); // log.info("aes inMessage:{}", JSON.toJSONString(inMessage)); // WxMpXmlOutMessage outMessage = weChatOfficialConfig.getWxMpMessageRouter().route(inMessage); // return outMessage.toEncryptedXml(weChatOfficialConfig.getConfig()); // } // return "ok"; } /** * 缓存ticket * * @param tk * @param openId */ public static void setCacheTicket(String tk, String openId) { RedisService redisService = SpringBeanUtils.getBean(RedisService.class); redisService.set("wechat:scan:ticket:" + tk, openId, 3600);//1h } /** * 获取tk * * @param tk * @return {@link String} */ public static String getCacheTicket(String tk) { RedisService redisService = SpringBeanUtils.getBean(RedisService.class); return redisService.get("wechat:scan:ticket:" + tk); } /** * 刪除ticket * * @param tk */ public static void delCacheTicket(String tk) { RedisService redisService = SpringBeanUtils.getBean(RedisService.class); redisService.remove("wechat:scan:ticket:" + tk); } }