diff --git a/ruoyi-vue-pro-master/yudao-framework/yudao-common/pom.xml b/ruoyi-vue-pro-master/yudao-framework/yudao-common/pom.xml index f364df7..cb960d5 100644 --- a/ruoyi-vue-pro-master/yudao-framework/yudao-common/pom.xml +++ b/ruoyi-vue-pro-master/yudao-framework/yudao-common/pom.xml @@ -144,6 +144,26 @@ spring-boot-starter-test test + + + + com.google.zxing + + core + + 3.4.1 + + + + + + com.google.zxing + + javase + + 3.4.1 + + diff --git a/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/Base64Util.java b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/Base64Util.java new file mode 100644 index 0000000..f4eaab2 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/Base64Util.java @@ -0,0 +1,107 @@ +package cn.iocoder.yudao.framework.common.util.qccode; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.util.Base64; + +/** + * 编码工具 + * + * Created by FSQ + * CopyRight https://www.huamar.com + */ +public class Base64Util { + + private static final Logger logger = LoggerFactory.getLogger(Base64Util.class); + + public Base64Util() { + // empty + } + + public static byte[] baseEncode(byte[] bytes) { + return Base64.getEncoder().encode(bytes); + } + + public static String baseEncode(String s) { + try { + byte[] e = s.getBytes("UTF-8"); + return Base64.getEncoder().encodeToString(e); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static byte[] baseDecode(byte[] bytes) { + return Base64.getDecoder().decode(bytes); + } + + public static String baseDecode(String s) { + try { + byte[] e = Base64.getDecoder().decode(s); + return new String(e, "UTF-8"); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static byte[] urlEncode(byte[] bytes) { + return Base64.getUrlEncoder().encode(bytes); + } + + public static String urlEncode(String s) { + try { + byte[] e = s.getBytes("UTF-8"); + return Base64.getUrlEncoder().encodeToString(e); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static byte[] urlDecode(byte[] bytes) { + return Base64.getUrlDecoder().decode(bytes); + } + + public static String urlDecode(String s) { + byte[] result = Base64.getUrlDecoder().decode(s); + + try { + return new String(result, "UTF-8"); + } catch (UnsupportedEncodingException var3) { + logger.error(var3.getMessage(), var3); + return null; + } + } + + public static byte[] mimeEncode(byte[] bytes) { + return Base64.getMimeEncoder().encode(bytes); + } + + public static String mimeEncode(String s) { + try { + byte[] e = s.getBytes("UTF-8"); + return Base64.getMimeEncoder().encodeToString(e); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static byte[] mimeDecode(byte[] bytes) { + return Base64.getMimeDecoder().decode(bytes); + } + + public static String mimeDecode(String s) { + try { + byte[] e = Base64.getMimeDecoder().decode(s); + return new String(e, "UTF-8"); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } +} diff --git a/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/QRCodeUtil.java b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/QRCodeUtil.java index b5960a0..d3d6b0a 100644 --- a/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/QRCodeUtil.java +++ b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/QRCodeUtil.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.framework.common.util.qccode; import cn.hutool.core.util.StrUtil; -import com.google.zxing.client.j2se.BufferedImageLuminanceSource; +import cn.hutool.extra.qrcode.BufferedImageLuminanceSource; +import com.google.zxing.*; + import com.google.zxing.common.BitMatrix; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.QRCodeReader; @@ -109,6 +111,12 @@ public class QRCodeUtil { result = reader.decode(bitmap, hints); } catch (ReaderException e) { logger.error(e.getMessage(), e); + } catch (ChecksumException e) { + throw new RuntimeException(e); + } catch (NotFoundException e) { + throw new RuntimeException(e); + } catch (FormatException e) { + throw new RuntimeException(e); } logger.info(result.getText()); } diff --git a/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/vo/QRCodeConfig.java b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/vo/QRCodeConfig.java index 32a2337..b6d59d7 100644 --- a/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/vo/QRCodeConfig.java +++ b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/vo/QRCodeConfig.java @@ -12,20 +12,20 @@ import lombok.ToString; @ToString(callSuper = true) public class QRCodeConfig { // 二维码内容 - @Schema(description = "二维码内容", requiredMode = Schema.RequiredMode.REQUIRED,defaultValue = "我是二维码的内容") + @Schema(description = "二维码内容",defaultValue = "我是二维码的内容") private String content; // 二维码的宽度 - @Schema(description = "二维码的宽度", requiredMode = Schema.RequiredMode.REQUIRED,defaultValue = "800") - private int width; + @Schema(description = "二维码的宽度",defaultValue = "800") + private int width=800; // 二维码的高度 - @Schema(description = "二维码的高度", requiredMode = Schema.RequiredMode.REQUIRED,defaultValue = "800") - private int height; + @Schema(description = "二维码的高度",defaultValue = "800") + private int height=800; // 二维码的图片格式,如"png", "jpg"等 - @Schema(description = "二维码的高度", requiredMode = Schema.RequiredMode.REQUIRED,defaultValue = "png") - private String imageFormat; + @Schema(description = "二维码的高度",defaultValue = "png,jpg") + private String imageFormat="jpg"; // 附加资源或相关信息(具体含义根据项目需求定义) /*private String resource;*/ diff --git a/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/pom.xml b/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/pom.xml index f2840cf..5b15541 100644 --- a/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/pom.xml +++ b/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/pom.xml @@ -124,6 +124,12 @@ org.apache.tika tika-core + + cn.iocoder.boot + yudao-module-system-biz + 2.1.0-jdk8-snapshot + compile + diff --git a/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/app/file/AppFileController.java b/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/app/file/AppFileController.java index edc857c..c633ccc 100644 --- a/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/app/file/AppFileController.java +++ b/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/app/file/AppFileController.java @@ -1,13 +1,18 @@ package cn.iocoder.yudao.module.infra.controller.app.file; +import cn.hutool.core.codec.Base64; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.lang.UUID; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.qccode.Base64Util; import cn.iocoder.yudao.framework.common.util.qccode.QRCodeUtil; import cn.iocoder.yudao.framework.common.util.qccode.vo.QRCodeConfig; import cn.iocoder.yudao.module.infra.controller.app.file.vo.AppFileUploadReqVO; import cn.iocoder.yudao.module.infra.service.file.FileService; +import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO; +import cn.iocoder.yudao.module.system.service.dict.DictDataService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; @@ -22,8 +27,10 @@ import javax.annotation.Resource; import javax.validation.Valid; import java.io.*; +import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "用户 App - 文件存储") @RestController @@ -35,6 +42,9 @@ public class AppFileController { @Resource private FileService fileService; + @Resource + private DictDataService dictDataService; + @PostMapping("/upload") @Operation(summary = "上传文件") public CommonResult uploadFile(AppFileUploadReqVO uploadReqVO) throws Exception { @@ -43,7 +53,7 @@ public class AppFileController { return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream()))); } - @GetMapping("/qrCode") + @RequestMapping("/qrCode") @Operation(summary = "生成二维码") public CommonResult qrCode(@Valid QRCodeConfig qrCodeConfig) { try { @@ -73,4 +83,45 @@ public class AppFileController { return success(""); } + @RequestMapping("/qrCode64") + @Operation(summary = "生成二维码64") + public CommonResult qrCode64(@Valid String type) { + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + // 假设QRCodeUtil.createQrCode是一个正确实现的方法,用于生成二维码并写入到ByteArrayOutputStream中 + QRCodeConfig qrCodeConfig = new QRCodeConfig(); + QRCodeUtil.createQrCode(out, getString(type), qrCodeConfig.getWidth(), qrCodeConfig.getHeight(), qrCodeConfig.getImageFormat(), ""); // 使用PNG格式,不是JPG + // 创建文件,使用PNG扩展名,因为QR码是以PNG格式生成的 + String h5QrCode = new String(Base64Util.baseEncode(out.toByteArray()), "UTF-8"); + out.close(); // 关闭ByteArrayOutputStream,虽然在这个上下文中它会在方法结束时自动关闭 + return success(h5QrCode); + } catch (IOException e) { + e.printStackTrace(); // 适当的错误处理应该替换这一行,例如记录日志或向用户显示错误消息 + } + + return success(null); + } + + @RequestMapping("/qrCode64Url") + @Operation(summary = "生成Url") + public CommonResult qrCode64Url(@Valid String type) { + + // 创建文件,使用PNG扩展名,因为QR码是以PNG格式生成的 + return success( getString(type)); + + } + + private String getString(String type) { + String replace=null; + List list = dictDataService.getDictDataList( + CommonStatusEnum.ENABLE.getStatus(), "xcxscewm_type"); + Long loginUserId = getLoginUserId(); + for (DictDataDO dictDataDO : list) { + if (dictDataDO.getValue().equals(type)) { + replace = dictDataDO.getRemark().replace("{bindUserId}", loginUserId.toString()); + } + } + return replace; + } + } diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java index c6b77de..74439f9 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java @@ -92,7 +92,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { } // 情况二:修改推广员 - //validateCanBindUser(brokerageUser, bindUserId); + validateCanBindUser(brokerageUser, bindUserId); brokerageUserMapper.updateById(fillBindUserData(bindUserId, new BrokerageUserDO().setId(id))); } diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java index 0e6fb58..8bb801c 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java @@ -28,6 +28,8 @@ import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants; import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO; +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper; import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -66,6 +68,10 @@ public class MemberAuthServiceImpl implements MemberAuthService { @Resource private BrokerageUserService brokerageUserService; + + @Resource + private BrokerageUserMapper brokerageUserMapper; + @Override public AppAuthLoginRespVO login(AppAuthLoginReqVO reqVO) { // 使用手机 + 密码,进行登录。 @@ -74,8 +80,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { // 如果 socialType 非空,说明需要绑定社交用户 String openid = null; if (reqVO.getSocialType() != null) { - openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), - reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); + openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); } // 创建 Token 令牌,记录登录日志 @@ -102,8 +107,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { // 如果 socialType 非空,说明需要绑定社交用户 String openid = null; if (reqVO.getSocialType() != null) { - openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), - reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); + openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); } // 创建 Token 令牌,记录登录日志 @@ -114,8 +118,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { @Transactional public AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO) { // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 - SocialUserRespDTO socialUser = socialUserApi.getSocialUserByCode(UserTypeEnum.MEMBER.getValue(), reqVO.getType(), - reqVO.getCode(), reqVO.getState()); + SocialUserRespDTO socialUser = socialUserApi.getSocialUserByCode(UserTypeEnum.MEMBER.getValue(), reqVO.getType(), reqVO.getCode(), reqVO.getState()); if (socialUser == null) { throw exception(AUTH_SOCIAL_USER_NOT_FOUND); } @@ -124,11 +127,10 @@ public class MemberAuthServiceImpl implements MemberAuthService { MemberUserDO user; if (socialUser.getUserId() != null) { user = userService.getUser(socialUser.getUserId()); - // 情况二:未绑定,注册用户 + 绑定用户 + // 情况二:未绑定,注册用户 + 绑定用户 } else { user = userService.createUser(socialUser.getNickname(), socialUser.getAvatar(), getClientIP(), getTerminal()); - socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), - reqVO.getType(), reqVO.getCode(), reqVO.getState())); + socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), reqVO.getType(), reqVO.getCode(), reqVO.getState())); } if (user == null) { throw exception(USER_NOT_EXISTS); @@ -141,38 +143,35 @@ public class MemberAuthServiceImpl implements MemberAuthService { @Override public AppAuthLoginRespVO weixinMiniAppLogin(AppAuthWeixinMiniAppLoginReqVO reqVO) { // 获得对应的手机号信息 - SocialWxPhoneNumberInfoRespDTO phoneNumberInfo = socialClientApi.getWxMaPhoneNumberInfo( - UserTypeEnum.MEMBER.getValue(), reqVO.getPhoneCode()); + SocialWxPhoneNumberInfoRespDTO phoneNumberInfo = socialClientApi.getWxMaPhoneNumberInfo(UserTypeEnum.MEMBER.getValue(), reqVO.getPhoneCode()); Assert.notNull(phoneNumberInfo, "获得手机信息失败,结果为空"); // 获得获得注册用户 - MemberUserDO user = userService.createUserIfAbsent(phoneNumberInfo.getPurePhoneNumber(), - getClientIP(), TerminalEnum.WECHAT_MINI_PROGRAM.getTerminal()); + MemberUserDO user = userService.createUserIfAbsent(phoneNumberInfo.getPurePhoneNumber(), getClientIP(), TerminalEnum.WECHAT_MINI_PROGRAM.getTerminal()); Assert.notNull(user, "获取用户失败,结果为空"); // 绑定社交用户 - String openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), - SocialTypeEnum.WECHAT_MINI_APP.getType(), reqVO.getLoginCode(), reqVO.getState())); + String openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), SocialTypeEnum.WECHAT_MINI_APP.getType(), reqVO.getLoginCode(), reqVO.getState())); - if( ObjectUtil.isNotEmpty(reqVO.getBindUserId())){ - brokerageUserService.bindBrokerageUser(user.getId(), reqVO.getBindUserId()); + BrokerageUserDO brokerageUserDO = brokerageUserMapper.selectById(user.getId()); - }else { - brokerageUserService.bindBrokerageUser(user.getId(), 0L); - } + if (ObjectUtil.isEmpty(brokerageUserDO) && ObjectUtil.isNotEmpty(reqVO.getBindUserId())) { + brokerageUserService.bindBrokerageUser(user.getId(), reqVO.getBindUserId()); + } else { + if (ObjectUtil.isEmpty(brokerageUserDO)) { + brokerageUserService.bindBrokerageUser(user.getId(), 0L); + } + } //绑定分销用户 // 创建 Token 令牌,记录登录日志 return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, openid); } - private AppAuthLoginRespVO createTokenAfterLoginSuccess(MemberUserDO user, String mobile, - LoginLogTypeEnum logType, String openid) { + private AppAuthLoginRespVO createTokenAfterLoginSuccess(MemberUserDO user, String mobile, LoginLogTypeEnum logType, String openid) { // 插入登陆日志 createLoginLog(user.getId(), mobile, logType, LoginResultEnum.SUCCESS); // 创建 Token 令牌 - OAuth2AccessTokenRespDTO accessTokenRespDTO = oauth2TokenApi.createAccessToken(new OAuth2AccessTokenCreateReqDTO() - .setUserId(user.getId()).setUserType(getUserType().getValue()) - .setClientId(OAuth2ClientConstants.CLIENT_ID_DEFAULT)); + OAuth2AccessTokenRespDTO accessTokenRespDTO = oauth2TokenApi.createAccessToken(new OAuth2AccessTokenCreateReqDTO().setUserId(user.getId()).setUserType(getUserType().getValue()).setClientId(OAuth2ClientConstants.CLIENT_ID_DEFAULT)); // 构建返回结果 return AuthConvert.INSTANCE.convert(accessTokenRespDTO, openid); } @@ -265,8 +264,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { @Override public AppAuthLoginRespVO refreshToken(String refreshToken) { - OAuth2AccessTokenRespDTO accessTokenDO = oauth2TokenApi.refreshAccessToken(refreshToken, - OAuth2ClientConstants.CLIENT_ID_DEFAULT); + OAuth2AccessTokenRespDTO accessTokenDO = oauth2TokenApi.refreshAccessToken(refreshToken, OAuth2ClientConstants.CLIENT_ID_DEFAULT); return AuthConvert.INSTANCE.convert(accessTokenDO, null); }