From dd0630ad454e41dc510ff5d9465a7cab7ea5e77a Mon Sep 17 00:00:00 2001 From: Vinjor Date: Tue, 24 Sep 2024 18:35:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E8=87=AA=E5=8A=A8=E7=99=BB?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dl-module-base/pom.xml | 5 + .../iocoder/yudao/common/BaseConstants.java | 10 +- .../cn/iocoder/yudao/common/WechatCommon.java | 27 +++ .../module/app/customer/CustomerAPI.java | 67 ++++++ .../controller/WechatLoginController.java | 40 ++++ .../app/wechat/service/WechatService.java | 17 ++ .../service/impl/WechatServiceImpl.java | 91 +++++++ .../admin/CustomerMainController.java | 21 -- .../custom/service/CustomerMainService.java | 3 +- .../service/impl/CustomerMainServiceImpl.java | 30 ++- .../custom/vo/CustomerMainSaveReqVO.java | 4 +- .../cn/iocoder/yudao/util/NetWorkHelper.java | 222 ++++++++++++++++++ .../iocoder/yudao/util/WeChatLoginUtil.java | 39 +++ .../YudaoWebSecurityConfigurerAdapter.java | 1 + .../module/system/api/user/AdminUserApi.java | 18 ++ .../system/api/user/dto/AdminUserRespDTO.java | 4 + .../module/system/api/user/dto/UserDTO.java | 4 + .../system/api/user/AdminUserApiImpl.java | 28 +++ .../system/dal/mysql/dept/DeptMapper.java | 3 + .../dal/mysql/user/AdminUserMapper.java | 2 + .../system/service/auth/AdminAuthService.java | 10 + .../service/auth/AdminAuthServiceImpl.java | 15 ++ .../system/service/dept/DeptServiceImpl.java | 4 +- .../oauth2/OAuth2TokenServiceImpl.java | 1 + .../system/service/user/AdminUserService.java | 18 ++ .../service/user/AdminUserServiceImpl.java | 32 +++ .../src/main/resources/mapper/DeptMapper.xml | 10 + .../main/resources/mapper/SysUserMapper.xml | 5 +- .../src/main/resources/application-local.yaml | 10 +- .../src/main/resources/application.yaml | 2 + 30 files changed, 705 insertions(+), 38 deletions(-) create mode 100644 dl-module-base/src/main/java/cn/iocoder/yudao/common/WechatCommon.java create mode 100644 dl-module-base/src/main/java/cn/iocoder/yudao/module/app/customer/CustomerAPI.java create mode 100644 dl-module-base/src/main/java/cn/iocoder/yudao/module/app/wechat/controller/WechatLoginController.java create mode 100644 dl-module-base/src/main/java/cn/iocoder/yudao/module/app/wechat/service/WechatService.java create mode 100644 dl-module-base/src/main/java/cn/iocoder/yudao/module/app/wechat/service/impl/WechatServiceImpl.java create mode 100644 dl-module-base/src/main/java/cn/iocoder/yudao/util/NetWorkHelper.java create mode 100644 dl-module-base/src/main/java/cn/iocoder/yudao/util/WeChatLoginUtil.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/DeptMapper.xml diff --git a/dl-module-base/pom.xml b/dl-module-base/pom.xml index 49b21e0f..f373003a 100644 --- a/dl-module-base/pom.xml +++ b/dl-module-base/pom.xml @@ -15,6 +15,11 @@ 点亮业务基础库 + + cn.iocoder.boot + yudao-module-system-biz + ${revision} + cn.iocoder.boot yudao-module-system-api diff --git a/dl-module-base/src/main/java/cn/iocoder/yudao/common/BaseConstants.java b/dl-module-base/src/main/java/cn/iocoder/yudao/common/BaseConstants.java index 60b04b6b..763140e8 100644 --- a/dl-module-base/src/main/java/cn/iocoder/yudao/common/BaseConstants.java +++ b/dl-module-base/src/main/java/cn/iocoder/yudao/common/BaseConstants.java @@ -9,6 +9,10 @@ public class BaseConstants { public static final String CUS_TYPE_CORP_ATTN = "04"; /**政企客户*/ public static final String CUS_TYPE_CORP = "03"; + /**私人客户*/ + public static final String CUS_TYPE_PRIVATE = "01"; + /**代办客户*/ + public static final String CUS_TYPE_AGENT = "02"; /**客户标识*/ public static final String CUS_SIGN_CUSTOMER = "customer"; /**车辆标识*/ @@ -23,8 +27,12 @@ public class BaseConstants { public static final String SIGN_UPDATE = "update"; /**默认密码*/ public static final String PASSWORD_DEFAULT = "123456"; - /**租户下部门名称*/ + /**租户下部门名称--政企客户*/ public static final String DEPT_NAME_CORP_NAME = "政企客户"; + /**租户下部门名称--私人客户*/ + public static final String DEPT_NAME_PRIVATE_NAME = "私人客户"; + /**租户下部门名称--代办客户*/ + public static final String DEPT_NAME_AGENT_NAME = "代办客户"; /**私家车*/ public static final String CAR_CATEGORY_PRIVATE = "01"; /**货车*/ diff --git a/dl-module-base/src/main/java/cn/iocoder/yudao/common/WechatCommon.java b/dl-module-base/src/main/java/cn/iocoder/yudao/common/WechatCommon.java new file mode 100644 index 00000000..dcdf51c0 --- /dev/null +++ b/dl-module-base/src/main/java/cn/iocoder/yudao/common/WechatCommon.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.common; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class WechatCommon { + /** + * 微信公众号APPID + */ + @Value(value = "${wx.mp.app-id}") + public String APP_ID; + /** + * 微信公众号秘钥 + */ + @Value(value = "${wx.mp.secret}") + public String APP_SECRET; + + /** + * 获取网页的token,后续还有+"&code=&grant_type=authorization_code" + **/ + public String getTokeUrl(){ + String appId = APP_ID; + String appSecret = APP_SECRET; + return "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appSecret; + } +} diff --git a/dl-module-base/src/main/java/cn/iocoder/yudao/module/app/customer/CustomerAPI.java b/dl-module-base/src/main/java/cn/iocoder/yudao/module/app/customer/CustomerAPI.java new file mode 100644 index 00000000..ac651765 --- /dev/null +++ b/dl-module-base/src/main/java/cn/iocoder/yudao/module/app/customer/CustomerAPI.java @@ -0,0 +1,67 @@ +package cn.iocoder.yudao.module.app.customer; + +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.custom.service.CustomerMainService; +import cn.iocoder.yudao.module.custom.vo.CustomerMainSaveReqVO; +import cn.iocoder.yudao.module.system.api.user.dto.UserDTO; +import cn.iocoder.yudao.module.system.service.auth.AdminAuthService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +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 org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +import static cn.iocoder.yudao.common.BaseConstants.SIGN_CREATE; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +/** + * 客户管理 + * + * @author : http://www.chiner.pro + * @date : 2024-7-31 + */ +@RestController +@RequestMapping("/base/custom-app") +@Tag(name = "客户管理-小程序端接口") +@Validated +public class CustomerAPI { + @Resource + private CustomerMainService customerMainService; + @Resource + private AdminAuthService loginService; + + /** + * 新增客户 + * + * @param saveReqVO 保存客户信息扩展实体 + * @return cn.iocoder.yudao.framework.common.pojo.CommonResult + * @author PQZ + * @date 15:42 2024/8/1 + **/ + @PostMapping("/register") + @Operation(summary = "客户自行注册") + public CommonResult createCustomerMain(@Valid @RequestBody CustomerMainSaveReqVO saveReqVO, HttpServletRequest request) { + //客户类型,统一为私人客户 + saveReqVO.setTypeCode("01"); + //客户来源,统一为04-维修 + saveReqVO.setDataFrom("04"); + //注册方式,统一为自主创建 + saveReqVO.setInviterType("01"); + try { + UserDTO userDTO = customerMainService.saveCustomer(saveReqVO,SIGN_CREATE); + //注册并登录 + return success(loginService.wxLoginByUserId(userDTO.getId(),userDTO.getUsername())); + }catch (ServiceException e){ + return error(e); + } + } +} diff --git a/dl-module-base/src/main/java/cn/iocoder/yudao/module/app/wechat/controller/WechatLoginController.java b/dl-module-base/src/main/java/cn/iocoder/yudao/module/app/wechat/controller/WechatLoginController.java new file mode 100644 index 00000000..26535eaf --- /dev/null +++ b/dl-module-base/src/main/java/cn/iocoder/yudao/module/app/wechat/controller/WechatLoginController.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.app.wechat.controller; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.app.wechat.service.WechatService; +import cn.iocoder.yudao.module.system.service.auth.AdminAuthService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 微信登录控制层 + * + */ +@RestController +@RequestMapping("/userClient/weChat") +@Tag(name = "微信登录") +@Validated +public class WechatLoginController { + @Autowired + private WechatService wechatService; + + /** + * 微信获取openId + * @author vinjor-M + * @date 9:53 2024/8/2 + * @param code 请求参数 + **/ + @GetMapping("/wechatLogin") + @Operation(summary = "微信获取openId") + public CommonResult createCompany(String code) { + return wechatService.loginByOpenId(code); + } + +} \ No newline at end of file diff --git a/dl-module-base/src/main/java/cn/iocoder/yudao/module/app/wechat/service/WechatService.java b/dl-module-base/src/main/java/cn/iocoder/yudao/module/app/wechat/service/WechatService.java new file mode 100644 index 00000000..d08add78 --- /dev/null +++ b/dl-module-base/src/main/java/cn/iocoder/yudao/module/app/wechat/service/WechatService.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.app.wechat.service; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; + +/** + * @author vinjor-m + * @description 微信模块服务层 + **/ +public interface WechatService { + /** + * 微信自动登录 + * @author vinjor-M + * @date 23:53 2024/9/23 + * @param map 参数 + **/ + CommonResult loginByOpenId(String code); +} diff --git a/dl-module-base/src/main/java/cn/iocoder/yudao/module/app/wechat/service/impl/WechatServiceImpl.java b/dl-module-base/src/main/java/cn/iocoder/yudao/module/app/wechat/service/impl/WechatServiceImpl.java new file mode 100644 index 00000000..3cc6460a --- /dev/null +++ b/dl-module-base/src/main/java/cn/iocoder/yudao/module/app/wechat/service/impl/WechatServiceImpl.java @@ -0,0 +1,91 @@ +package cn.iocoder.yudao.module.app.wechat.service.impl; + +import cn.hutool.json.JSONObject; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.app.wechat.service.WechatService; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginReqVO; +import cn.iocoder.yudao.module.system.service.auth.AdminAuthService; +import cn.iocoder.yudao.util.WeChatLoginUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.LOCKED; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +/** + * @Author vinjor-m + * @Description 微信模块服务层 + **/ +@Service +public class WechatServiceImpl implements WechatService { + @Autowired + private WeChatLoginUtil weChatLoginUtil; + @Autowired + private AdminUserApi adminUserApi; + @Resource + private AdminAuthService loginService; + /** + * 微信自动登录 + * + * @param code 参数 + * @return java.lang.String + * @author vinjor-M + * @date 23:53 2024/9/23 + **/ + @Override + public CommonResult loginByOpenId(String code) { + try { + //当前登录用户的openId + Map authMap = getWeChatOpenId(code); + String openId = authMap.getOrDefault("openId",null); + //默认租户180,查是否有user表数据 + AdminUserRespDTO userRespDTO = adminUserApi.getUserByOpenId(openId,null); + if(null==userRespDTO){ + //未找到用户,去注册 + return CommonResult.success(openId); + }else{ + //找到用户,登录并返回 + return success(loginService.wxLoginByUserId(userRespDTO.getId(),userRespDTO.getUsername())); + } + }catch (Exception e){ + e.printStackTrace(); + return CommonResult.error(LOCKED.getCode(),e.getMessage()); + } + } + + /** + * 获取openId + * @author vinjor-M + * @date 23:56 2024/9/23 + * @param code (静默/非静默)授权拿到的code + * @return java.util.Map + **/ + private Map getWeChatOpenId(String code) throws Exception { + Map rtnMap = new HashMap<>(2); + try { + //code为空为没有获取到code + if (StringUtils.isNotBlank(code)) { + JSONObject tokenJson = weChatLoginUtil.getTokenJson(code); + //获取到tokenJson后,解析tokenJson获取其openId + if (null != tokenJson && tokenJson.containsKey("openid")) { + rtnMap.put("openId",tokenJson.getStr("openid")); + rtnMap.put("token",tokenJson.getStr("access_token")); + }else{ + throw new Exception("code过期"); + } + }else{ + throw new Exception("没有code"); + } + return rtnMap; + } catch (Exception e) { + throw new Exception(e.getMessage()); + } + } +} diff --git a/dl-module-base/src/main/java/cn/iocoder/yudao/module/custom/controller/admin/CustomerMainController.java b/dl-module-base/src/main/java/cn/iocoder/yudao/module/custom/controller/admin/CustomerMainController.java index 9cfdc8b9..a55afc83 100644 --- a/dl-module-base/src/main/java/cn/iocoder/yudao/module/custom/controller/admin/CustomerMainController.java +++ b/dl-module-base/src/main/java/cn/iocoder/yudao/module/custom/controller/admin/CustomerMainController.java @@ -180,26 +180,5 @@ public class CustomerMainController { return success(true); } - /** - * 小程序客户注册 - * cusName,phoneNumber,birthday,sex,inviter - */ - @PostMapping("/addUniUser") - public CommonResult addUniUser(@Valid @RequestBody CustomerMainSaveReqVO saveReqVO) { - if(!saveReqVO.getCode().isEmpty()){ - String code = saveReqVO.getCode(); - JSONObject jsonObj = new JSONObject(); - String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=" - +code+"&grant_type=authorization_code"; - String response = HttpRequest.get(url).execute().body(); - JSONObject json = JSONUtil.parseObj(response); - if (json.containsKey("access_token") && json.containsKey("openid")) { - String accessToken = json.getStr("access_token"); - String openid = json.getStr("openid"); - } - - } - return null; - } } \ No newline at end of file diff --git a/dl-module-base/src/main/java/cn/iocoder/yudao/module/custom/service/CustomerMainService.java b/dl-module-base/src/main/java/cn/iocoder/yudao/module/custom/service/CustomerMainService.java index 0280ebff..f90b9c95 100644 --- a/dl-module-base/src/main/java/cn/iocoder/yudao/module/custom/service/CustomerMainService.java +++ b/dl-module-base/src/main/java/cn/iocoder/yudao/module/custom/service/CustomerMainService.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.custom.entity.CustomerMain; import cn.iocoder.yudao.module.custom.vo.CustomerMainPageReqVO; import cn.iocoder.yudao.module.custom.vo.CustomerMainRespVO; import cn.iocoder.yudao.module.custom.vo.CustomerMainSaveReqVO; +import cn.iocoder.yudao.module.system.api.user.dto.UserDTO; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; @@ -38,7 +39,7 @@ public interface CustomerMainService extends IService { * @author PQZ * @date 15:46 2024/8/1 **/ - void saveCustomer(CustomerMainSaveReqVO saveReqVO, String sign); + UserDTO saveCustomer(CustomerMainSaveReqVO saveReqVO, String sign); /** * 根据客户id查询客户信息 diff --git a/dl-module-base/src/main/java/cn/iocoder/yudao/module/custom/service/impl/CustomerMainServiceImpl.java b/dl-module-base/src/main/java/cn/iocoder/yudao/module/custom/service/impl/CustomerMainServiceImpl.java index e2ae719d..0f417167 100644 --- a/dl-module-base/src/main/java/cn/iocoder/yudao/module/custom/service/impl/CustomerMainServiceImpl.java +++ b/dl-module-base/src/main/java/cn/iocoder/yudao/module/custom/service/impl/CustomerMainServiceImpl.java @@ -31,6 +31,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.lang3.StringUtils; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -98,12 +99,12 @@ public class CustomerMainServiceImpl extends ServiceImpl labelList; /** - * Code + * 微信openId */ - private String Code; + private String openId; } \ No newline at end of file diff --git a/dl-module-base/src/main/java/cn/iocoder/yudao/util/NetWorkHelper.java b/dl-module-base/src/main/java/cn/iocoder/yudao/util/NetWorkHelper.java new file mode 100644 index 00000000..e5720b8d --- /dev/null +++ b/dl-module-base/src/main/java/cn/iocoder/yudao/util/NetWorkHelper.java @@ -0,0 +1,222 @@ +package cn.iocoder.yudao.util; + +import javax.net.ssl.*; +import java.io.*; +import java.net.URL; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + + +public class NetWorkHelper { + + public String getHttpsResponse(String hsUrl, String requestMethod) { + URL url; + InputStream is = null; + String resultData = ""; + try { + url = new URL(hsUrl); + HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); + TrustManager[] tm = {xtm}; + + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(null, tm, null); + + con.setSSLSocketFactory(ctx.getSocketFactory()); + con.setHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String arg0, SSLSession arg1) { + return true; + } + }); + + + con.setDoInput(true); //允许输入流,即允许下载 + + //在android中必须将此项设置为false + con.setDoOutput(false); //允许输出流,即允许上传 + con.setUseCaches(false); //不使用缓冲 + if(null!=requestMethod && !requestMethod.equals("")) { + con.setRequestMethod(requestMethod); //使用指定的方式 + } + else{ + con.setRequestMethod("GET"); //使用get请求 + } + is = con.getInputStream(); //获取输入流,此时才真正建立链接 + InputStreamReader isr = new InputStreamReader(is); + BufferedReader bufferReader = new BufferedReader(isr); + String inputLine = ""; + while ((inputLine = bufferReader.readLine()) != null) { + resultData += inputLine + "\n"; + } + + Certificate[] certs = con.getServerCertificates(); + + int certNum = 1; + + for (Certificate cert : certs) { + X509Certificate xcert = (X509Certificate) cert; + } + + } catch (Exception e) { + e.printStackTrace(); + } + return resultData; + } + + + /** + * 下载文件 + * @param hsUrl + * @return + */ + public String DownLoadHttpsFile(String hsUrl, String fileName, String path) { + URL url; + InputStream is = null; + String filePath = path+fileName; + try { + url = new URL(hsUrl); + HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); + TrustManager[] tm = {xtm}; + + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(null, tm, null); + + con.setSSLSocketFactory(ctx.getSocketFactory()); + con.setHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String arg0, SSLSession arg1) { + return true; + } + }); + + + con.setDoInput(true); //允许输入流,即允许下载 + + //在android中必须将此项设置为false + con.setDoOutput(false); //允许输出流,即允许上传 + con.setUseCaches(false); //不使用缓冲 + con.setRequestMethod("GET"); //使用get请求 + is = con.getInputStream(); //获取输入流,此时才真正建立链接 + + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len = 0; + while( (len=is.read(buffer)) != -1 ){ + outStream.write(buffer, 0, len); + } + is.close(); + byte[] fileBytes = outStream.toByteArray(); + + File file = new File(filePath); + FileOutputStream fops = new FileOutputStream(file); + fops.write(fileBytes); + fops.flush(); + fops.close(); + /* Certificate[] certs = con.getServerCertificates(); + for (Certificate cert : certs) { + X509Certificate xcert = (X509Certificate) cert; + }*/ + + } catch (Exception e) { + e.printStackTrace(); + } + return filePath; + } + + /** + * HTTPS协议的POST请求 + * @param hsUrl 请求地址 + * @param json 请求数据 + * @return + */ + public String PostHttpsResponse(String hsUrl, String json) { + URL url; + InputStream is = null; + String resultData = ""; + try { + url = new URL(hsUrl); + HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); + TrustManager[] tm = {xtm}; + + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(null, tm, null); + + con.setSSLSocketFactory(ctx.getSocketFactory()); + con.setHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String arg0, SSLSession arg1) { + return true; + } + }); + + + con.setDoInput(true); //允许输入流,即允许下载 + + //在android中必须将此项设置为false + con.setDoOutput(true); //允许输出流,即允许上传 + con.setUseCaches(false); //不使用缓冲 + con.setRequestMethod("POST"); //使用get请求 + + //表单数据 + if (null != json) { + OutputStream outputStream = con.getOutputStream(); + outputStream.write(json.getBytes("UTF-8")); + outputStream.close(); + } + + + is = con.getInputStream(); //获取输入流,此时才真正建立链接 + InputStreamReader isr = new InputStreamReader(is); + BufferedReader bufferReader = new BufferedReader(isr); + String inputLine = ""; + while ((inputLine = bufferReader.readLine()) != null) { + resultData += inputLine + "\n"; + } + /* log(con.getResponseCode()); + log(con.getCipherSuite()); + log("");*/ + Certificate[] certs = con.getServerCertificates(); + + int certNum = 1; + + for (Certificate cert : certs) { + X509Certificate xcert = (X509Certificate) cert; + /*log("Cert No. " + certNum++); + log(xcert.getType()); + log(xcert.getPublicKey().getAlgorithm()); + log(xcert.getIssuerDN()); + log(xcert.getIssuerDN()); + log(xcert.getNotAfter()); + log(xcert.getNotBefore()); + log("");*/ + } + + } catch (Exception e) { + e.printStackTrace(); + } + return resultData; + } + + X509TrustManager xtm = new X509TrustManager() { + @Override + public X509Certificate[] getAcceptedIssuers() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void checkServerTrusted(X509Certificate[] arg0, String arg1) + throws CertificateException { + // TODO Auto-generated method stub + + } + + @Override + public void checkClientTrusted(X509Certificate[] arg0, String arg1) + throws CertificateException { + // TODO Auto-generated method stub + + } + }; +} diff --git a/dl-module-base/src/main/java/cn/iocoder/yudao/util/WeChatLoginUtil.java b/dl-module-base/src/main/java/cn/iocoder/yudao/util/WeChatLoginUtil.java new file mode 100644 index 00000000..87c14400 --- /dev/null +++ b/dl-module-base/src/main/java/cn/iocoder/yudao/util/WeChatLoginUtil.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.util; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import cn.iocoder.yudao.common.WechatCommon; +import org.checkerframework.checker.units.qual.A; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import java.util.Map; + + +/** + * @Author vinjor-m + * @Description 微信模块工具类 + **/ +@Component +public class WeChatLoginUtil { + @Autowired + private WechatCommon wechatCommon; + + /** + * @param code 授权后拿到的code + * @return net.sf.json.JSONObject + * ---modify history--- + * Modify By Date Description + * @Author PQZ + * @Description 获取网页的token + * @Date 17:12 2021/1/26 + **/ + public JSONObject getTokenJson(String code) { + //请求获取网页的token + String url = wechatCommon.getTokeUrl() + "&code=" + code + "&grant_type=authorization_code"; + NetWorkHelper helper = new NetWorkHelper(); + String response = helper.getHttpsResponse(url, ""); + return JSONUtil.parseObj(response); + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java index beb47d3a..547aa114 100644 --- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java +++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java @@ -146,6 +146,7 @@ public class YudaoWebSecurityConfigurerAdapter { // 微信支付接口 .antMatchers("/admin-api/notify/**").permitAll() .antMatchers("/userClient/pay/**").permitAll() + .antMatchers("/userClient/weChat/**").permitAll() .antMatchers("/admin-api/websocket/**").permitAll() // 小程序首页 .antMatchers("/admin-api/system/notice/listWx","/admin-api/system/swiper/listWx","/admin-api/system/shopconfig/listWx").permitAll() diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java index 0a29eaf6..bb12285e 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java @@ -41,6 +41,16 @@ public interface AdminUserApi { */ AdminUserRespDTO getUser(Long id); + /** + * 根据openid和租户id查询用户 + * @author vinjor-M + * @date 11:29 2024/9/24 + * @param openId 微信id + * @param tenantId 租户id,可能为null + * @return cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO + **/ + AdminUserRespDTO getUserByOpenId(String openId,String tenantId); + /** * 通过用户 登录账户 查询用户 * @@ -137,5 +147,13 @@ public interface AdminUserApi { */ AdminUserRespDTO getUserByMobile(String mobile); + /** + * 设置用户openId + * @author vinjor-M + * @date 15:45 2024/9/24 + * @param userId 用户id + * @param openId 微信id + **/ + void setOpenId(Long userId,String openId); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserRespDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserRespDTO.java index 39233952..8066577c 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserRespDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserRespDTO.java @@ -18,6 +18,10 @@ public class AdminUserRespDTO { * 用户ID */ private Long id; + /** + * 用户登录账号 + */ + private String username; /** * 用户昵称 */ diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/UserDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/UserDTO.java index e49a6193..72414253 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/UserDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/UserDTO.java @@ -47,5 +47,9 @@ public class UserDTO { * 用户性别 **/ private String sex; + /** + * 用户openId + **/ + private String openId; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java index caea71ec..a7bf43c0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java @@ -64,6 +64,21 @@ public class AdminUserApiImpl implements AdminUserApi { return BeanUtils.toBean(user, AdminUserRespDTO.class); } + /** + * 根据openid和租户id查询用户 + * + * @param openId 微信id + * @param tenantId 租户id,可能为null + * @return cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO + * @author vinjor-M + * @date 11:29 2024/9/24 + **/ + @Override + public AdminUserRespDTO getUserByOpenId(String openId, String tenantId) { + AdminUserDO user = userService.selectUserByOpenId(openId,tenantId); + return BeanUtils.toBean(user, AdminUserRespDTO.class); + } + /** * 通过用户 登录账户 查询用户 * @@ -153,4 +168,17 @@ public class AdminUserApiImpl implements AdminUserApi { return BeanUtils.toBean(user, AdminUserRespDTO.class); } + /** + * 设置用户openId + * + * @param userId 用户id + * @param openId 微信id + * @author vinjor-M + * @date 15:45 2024/9/24 + **/ + @Override + public void setOpenId(Long userId, String openId) { + userService.setOpenId(userId, openId); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java index 2aa68e32..d0fe80e7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; import java.util.Collection; import java.util.List; @@ -41,4 +42,6 @@ public interface DeptMapper extends BaseMapperX { default DeptDO selectTenantDeptTop(Long parentId, Long tenantId) { return selectOne(DeptDO::getParentId, parentId, DeptDO::getTenantId, tenantId); } + + List selectDeptByName(@Param("name")String name); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java index a7311bf0..8108a7ed 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java @@ -57,4 +57,6 @@ public interface AdminUserMapper extends BaseMapperX { AdminUserDO selectUserByPhone(String phone); AdminUserDO getUserByMobileWithoutTenant(String phoneNumber); + + int updateSetOpenId(@Param("userId")Long userId,@Param("openId")String openId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthService.java index e6498cc1..29ca03e1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthService.java @@ -75,4 +75,14 @@ public interface AdminAuthService { AuthLoginRespVO wxLoginRescue(String decryptResult, String openId, Long inviteId); AuthLoginRespVO wxLoginJc(String decryptResult, String openId, Long inviteId); + + /** + * 根据用户id自动登录 + * @author vinjor-M + * @date 12:17 2024/9/24 + * @param userId 用户id + * @param userName 用户名称 + * @return cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginRespVO + **/ + AuthLoginRespVO wxLoginByUserId(Long userId,String userName); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java index 6b8a1a53..ac6f73de 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java @@ -439,4 +439,19 @@ public class AdminAuthServiceImpl implements AdminAuthService { // 生成token return createTokenAfterLoginSuccess(wxUser.getId(), wxUser.getUsername(), LoginLogTypeEnum.LOGIN_SOCIAL); } + + /** + * 根据用户id自动登录 + * + * @param userId 用户id + * @param userName 用户名称 + * @return cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginRespVO + * @author vinjor-M + * @date 12:17 2024/9/24 + **/ + @Override + public AuthLoginRespVO wxLoginByUserId(Long userId, String userName) { + // 生成token + return createTokenAfterLoginSuccess(userId, userName, LoginLogTypeEnum.LOGIN_USERNAME); + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java index b894a796..736e12e2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptSaveReqV import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper; import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -244,7 +245,8 @@ public class DeptServiceImpl implements DeptService { **/ @Override public DeptDO selectDeptByName(String name) { - return deptMapper.selectByDeptName(name); + List list = deptMapper.selectDeptByName(name); + return list.size()>0?list.get(0):new DeptDO(); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java index 3853347c..7c947cc0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java @@ -20,6 +20,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2AccessTokenMapper; import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2RefreshTokenMapper; import cn.iocoder.yudao.module.system.dal.redis.oauth2.OAuth2AccessTokenRedisDAO; import cn.iocoder.yudao.module.system.service.user.AdminUserService; +import org.apache.commons.lang3.StringUtils; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java index ec78e30f..73e370f8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java @@ -219,4 +219,22 @@ public interface AdminUserService { AdminUserDO selectUserByPhone(String phone); AdminUserDO getUserByMobileWithoutTenant(String phoneNumber); + + /** + * 根据openid和租户id查询用户 + * @author vinjor-M + * @date 11:29 2024/9/24 + * @param openId 微信id + * @param tenantId 租户id,可能为null + **/ + AdminUserDO selectUserByOpenId(String openId,String tenantId); + /** + * 设置用户openId + * + * @param userId 用户id + * @param openId 微信id + * @author vinjor-M + * @date 15:45 2024/9/24 + **/ + void setOpenId(Long userId,String openId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index 529c16a7..15ade9ba 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java @@ -28,6 +28,7 @@ import cn.iocoder.yudao.module.system.service.dept.DeptService; import cn.iocoder.yudao.module.system.service.dept.PostService; import cn.iocoder.yudao.module.system.service.permission.PermissionService; import cn.iocoder.yudao.module.system.service.tenant.TenantService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.google.common.annotations.VisibleForTesting; import com.mzt.logapi.context.LogRecordContext; import com.mzt.logapi.service.impl.DiffParseFunction; @@ -530,6 +531,37 @@ public class AdminUserServiceImpl implements AdminUserService { return userMapper.getUserByMobileWithoutTenant(phoneNumber); } + /** + * 根据openid和租户id查询用户 + * + * @param openId 微信id + * @param tenantId 租户id,可能为null + * @author vinjor-M + * @date 11:29 2024/9/24 + **/ + @Override + public AdminUserDO selectUserByOpenId(String openId, String tenantId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(AdminUserDO::getOpenId,openId); + if(StringUtils.isNotEmpty(tenantId)){ + queryWrapper.eq(AdminUserDO::getTenantId,tenantId); + } + return userMapper.selectOne(queryWrapper); + } + + /** + * 设置用户openId + * + * @param userId 用户id + * @param openId 微信id + * @author vinjor-M + * @date 15:45 2024/9/24 + **/ + @Override + public void setOpenId(Long userId, String openId) { + userMapper.updateSetOpenId(userId,openId); + } + /** * 对密码进行加密 * diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/DeptMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/DeptMapper.xml new file mode 100644 index 00000000..2b6b70c9 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/DeptMapper.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/SysUserMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/SysUserMapper.xml index ed069135..9bc0a9cb 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/SysUserMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/SysUserMapper.xml @@ -3,8 +3,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> + + UPDATE system_users SET open_id = #{openId} WHERE id = #{userId} + - SELECT distinct su.* FROM diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index c42fd801..b29532e3 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -185,12 +185,10 @@ debug: false --- #################### 微信公众号、小程序相关配置 #################### wx: mp: # 公众号配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档 -# app-id: wx041349c6f39b268b # 测试号(牛希尧提供的) -# secret: 5abee519483bc9f8cb37ce280e814bd0 - app-id: wx5b23ba7a5589ecbb # 测试号(自己的) - secret: 2a7b3b20c537e52e74afd395eb85f61f -# app-id: wxa69ab825b163be19 # 测试号(Kongdy 提供的) -# secret: bd4f9fab889591b62aeac0d7b8d8b4a0 +# app-id: wx8653afe16dffec37 # 蓝安 +# secret: ab94673dd0cca78abd0a453d0aac9f98 + app-id: wxb1f71e5e0c5f9ee7 # 点亮 + secret: 2e9864a6b224feb6fba4ab73b70212cd # 存储配置,解决 AccessToken 的跨节点的共享 config-storage: type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index cee7bbe6..6fc8e49d 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -223,6 +223,7 @@ yudao: - /admin-api/system/config/configKey/** - /websocket/** - /userClient/pay/** + - /userClient/weChat/** - /admin-api/websocket/** - /admin-api/rescue/wxLoginRescue - /admin-api/rescue/wxLoginJc @@ -281,6 +282,7 @@ yudao: - /admin-api/system/tenant/getListByWebsite - /admin-api/websocket/** - /userClient/pay/** + - /userClient/weChat/** ignore-tables: - system_tenant - system_tenant_package