Sfoglia il codice sorgente

[update] message:1.小程序登录整合(50%)

kelei 6 mesi fa
parent
commit
cafaf7065d

+ 5 - 1
admin/pom.xml

@@ -35,11 +35,15 @@
         </dependency>
 
         <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
             <groupId>com.aliyun.oss</groupId>
             <artifactId>aliyun-sdk-oss</artifactId>
             <version>3.12.0</version>
         </dependency>
-
     </dependencies>
 
     <build>

+ 19 - 0
admin/src/main/java/com/flyer/foster/consts/WechatConst.java

@@ -0,0 +1,19 @@
+package com.flyer.foster.consts;
+
+/**
+ * 小程序常量
+ *
+ * @author kelei
+ * @since 2024/5/11/14:28
+ */
+public interface WechatConst {
+    /**
+     * 小程序ID
+     */
+    String APP_ID = "wx628f62793fdf5251";
+
+    /**
+     * 小程序秘钥
+     */
+    String APP_SECRET = "590f35a04adc9672618bbff4d6aa3468";
+}

+ 12 - 0
admin/src/main/java/com/flyer/foster/controller/AppUserController.java

@@ -1,6 +1,12 @@
 package com.flyer.foster.controller;
 
 import cn.dev33.satoken.annotation.SaCheckLogin;
+import com.flyer.foster.dto.AppUserQueryDTO;
+import com.flyer.foster.service.IAppUserService;
+import com.flyer.util.R;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -14,5 +20,11 @@ import org.springframework.web.bind.annotation.RestController;
 @RestController
 @RequestMapping("/app-user")
 public class AppUserController {
+    @Autowired
+    private IAppUserService iAppUserService;
 
+    @RequestMapping("/login")
+    public R login(@RequestBody AppUserQueryDTO dto, @RequestHeader("appId") String appId) {
+        return R.ok().result(iAppUserService.login(dto, appId));
+    }
 }

+ 14 - 0
admin/src/main/java/com/flyer/foster/dto/AppUserQueryDTO.java

@@ -0,0 +1,14 @@
+package com.flyer.foster.dto;
+
+import lombok.Data;
+
+/**
+ * AppUserQueryDTO
+ *
+ * @author kelei
+ * @since 2024/5/11/14:15
+ */
+@Data
+public class AppUserQueryDTO {
+    private String code;
+}

+ 14 - 0
admin/src/main/java/com/flyer/foster/dto/AppUserRespDTO.java

@@ -0,0 +1,14 @@
+package com.flyer.foster.dto;
+
+import lombok.Data;
+
+/**
+ * AppUserQueryDTO
+ *
+ * @author kelei
+ * @since 2024/5/11/14:15
+ */
+@Data
+public class AppUserRespDTO {
+
+}

+ 5 - 0
admin/src/main/java/com/flyer/foster/entity/AppUser.java

@@ -33,6 +33,11 @@ public class AppUser implements Serializable {
     @TableId(value = "id", type = IdType.AUTO)
     private Integer id;
 
+    /**
+     * 最新进入果园id
+     */
+    private Integer gardenId;
+
     private String unionId;
 
     /**

+ 38 - 0
admin/src/main/java/com/flyer/foster/pojo/Code2SessionResp.java

@@ -0,0 +1,38 @@
+package com.flyer.foster.pojo;
+
+import lombok.Data;
+
+/**
+ * 调用微信code2Session接口返回对象
+ * 官方文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html
+ *
+ * @author kelei
+ * @since 2024/5/11/14:58
+ */
+@Data
+public class Code2SessionResp {
+    /**
+     * 会话密钥
+     */
+    private String session_key;
+
+    /**
+     * 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台账号下会返回
+     */
+    private String unionid;
+
+    /**
+     * 错误信息
+     */
+    private String errmsg;
+
+    /**
+     * 用户唯一标识
+     */
+    private String openid;
+
+    /**
+     * 错误码
+     */
+    private Integer errcode;
+}

+ 3 - 0
admin/src/main/java/com/flyer/foster/service/IAppUserService.java

@@ -1,5 +1,7 @@
 package com.flyer.foster.service;
 
+import com.flyer.foster.dto.AppUserQueryDTO;
+import com.flyer.foster.dto.AppUserRespDTO;
 import com.flyer.foster.entity.AppUser;
 import com.baomidou.mybatisplus.extension.service.IService;
 
@@ -13,4 +15,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IAppUserService extends IService<AppUser> {
 
+    AppUserRespDTO login(AppUserQueryDTO dto, String appId);
 }

+ 17 - 0
admin/src/main/java/com/flyer/foster/service/impl/AppUserServiceImpl.java

@@ -1,11 +1,19 @@
 package com.flyer.foster.service.impl;
 
+import com.flyer.foster.consts.WechatConst;
+import com.flyer.foster.dto.AppUserQueryDTO;
+import com.flyer.foster.dto.AppUserRespDTO;
 import com.flyer.foster.entity.AppUser;
 import com.flyer.foster.mapper.IAppUserMapper;
+import com.flyer.foster.pojo.Code2SessionResp;
 import com.flyer.foster.service.IAppUserService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.flyer.foster.util.WeChatApiUtil;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Map;
+
 /**
  * <p>
  * 小程序用户 服务实现类
@@ -16,5 +24,14 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class AppUserServiceImpl extends ServiceImpl<IAppUserMapper, AppUser> implements IAppUserService {
+    @Autowired
+    private WeChatApiUtil weChatApiUtil;
+
+    @Override
+    public AppUserRespDTO login(AppUserQueryDTO dto, String appId) {
+        // 查找用户信息
+        Code2SessionResp code2Session = weChatApiUtil.getCode2Session(dto.getCode(), appId, WechatConst.APP_SECRET);
 
+        return null;
+    }
 }

+ 104 - 0
admin/src/main/java/com/flyer/foster/util/WeChatApiUtil.java

@@ -0,0 +1,104 @@
+package com.flyer.foster.util;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.flyer.exception.BusinessException;
+import com.flyer.foster.pojo.Code2SessionResp;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.PostConstruct;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 微信小程序api工具类
+ */
+@Component
+@Slf4j
+public class WeChatApiUtil {
+    @Autowired
+    private RestTemplate restTemplate;
+
+    @PostConstruct
+    public void initRestTemplate() {
+        // 解决调用微信服务返回信息无法反序列化
+//        restTemplate.getMessageConverters().add(new WxMappingJackson2HttpMessageConverter());
+    }
+
+    /**
+     * 根据code(临时调用凭证),请求微信api获取用户unionid
+     *
+     * @param code      前端调用微信登录接口生成的临时凭证
+     * @param appId     微信小程序的appId
+     * @param appSecret 小程序appId对应的秘钥
+     */
+    public Code2SessionResp getCode2Session(String code, String appId, String appSecret) {
+        String url = "https://api.weixin.qq.com/sns/jscode2session?appid={appid}&secret={secret}&js_code={code}&grant_type={authorization_code}";
+        HashMap<String, String> map = new HashMap<>();
+        map.put("appid", appId);
+        map.put("secret", appSecret);
+        map.put("code", code);
+        map.put("authorization_code", "authorization_code");
+        Code2SessionResp resp = new Code2SessionResp();
+        try {
+            resp = restTemplate.getForObject(url, Code2SessionResp.class, map);
+        } catch (RestClientException e) {
+            throw new BusinessException("调用微信服务错误");
+        }
+        return resp;
+    }
+
+    /**
+     * 获取微信调用凭证
+     *
+     * @return
+     */
+    public String getAccessToken(String appId, String secret) {
+        String accessToken = null;
+        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type={grantType}&appid={appId}&secret={secret}";
+        HashMap<String, String> map = new HashMap<>();
+        map.put("grantType", "client_credential");
+        map.put("appId", appId);
+        map.put("secret", secret);
+
+        JSONObject res;
+        try {
+            res = restTemplate.getForObject(url, JSONObject.class, map);
+            if (res != null) {
+                accessToken = String.valueOf(res.get("access_token"));
+            }
+        } catch (RestClientException e) {
+            throw new BusinessException("调用微信服务错误");
+        }
+
+        return accessToken;
+    }
+
+    public String getPhoneNumber(String appId, String appSecret, String code) {
+        String accessToken = this.getAccessToken(appId, appSecret);
+        String tel = "";
+        String url = StrUtil.format("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={}", accessToken);
+        try {
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            HashMap<String, String> bodyParams = new HashMap<>();
+            bodyParams.put("code", code);
+            // 用HttpEntity封装整个请求报文
+            HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(bodyParams, headers);
+            JSONObject res = restTemplate.postForObject(url, httpEntity, JSONObject.class);
+            if (res != null) {
+                tel = res.getJSONObject("phone_info").getString("phoneNumber");
+            }
+        } catch (RestClientException e) {
+            throw new BusinessException("调用微信服务错误");
+        }
+        return tel;
+    }
+}

+ 20 - 1
admin/src/main/resources/application-dev.yml

@@ -1,10 +1,29 @@
 spring:
+#  datasource:
+#    type: com.zaxxer.hikari.HikariDataSource
+#    driver-class-name: com.mysql.cj.jdbc.Driver
+#    url: jdbc:mysql://106.53.222.208:3306/foster?serverTimezone=GMT%2B8&characterEncoding=utf-8
+#    username: foster
+#    password: tKLGm42dSzaaNJPK
   datasource:
-    type: com.zaxxer.hikari.HikariDataSource
+    type: com.alibaba.druid.pool.DruidDataSource
     driver-class-name: com.mysql.cj.jdbc.Driver
     url: jdbc:mysql://106.53.222.208:3306/foster?serverTimezone=GMT%2B8&characterEncoding=utf-8
     username: foster
     password: tKLGm42dSzaaNJPK
+    druid:
+      initial-size: 5
+      min-idle: 5
+      max-active: 20
+      max-wait: 30000
+      time-between-eviction-runs-millis: 60000
+      min-evictable-idle-time-millis: 300000
+      validation-query: SELECT 1 FROM DUAL
+      test-while-idle: true
+      test-on-borrow: false
+      test-on-return: false
+      pool-prepared-statements: true
+      max-pool-prepared-statement-per-connection-size: 20
   redis:
     database: 1
     host: 106.53.222.208

+ 4 - 1
admin/src/main/resources/mysql/ddl/init-table.sql

@@ -289,4 +289,7 @@ alter table tb_poster_lib
 
 alter table tb_whisper
     add column start_time varchar(10) comment '开始时间' after content,
-    add column end_time   varchar(10) comment '结束时间' after start_time;
+    add column end_time   varchar(10) comment '结束时间' after start_time;
+
+alter table tb_app_user
+    add column garden_id int default 0 comment '最新进入果园id' after id;

+ 7 - 0
pom.xml

@@ -34,6 +34,7 @@
         <hutool.pinyin.version>2.0.3.RELEASE</hutool.pinyin.version>
         <satoken.version>1.37.0</satoken.version>
         <easyexcel.version>3.1.1</easyexcel.version>
+        <druid.version>1.2.6</druid.version>
     </properties>
 
     <dependencyManagement>
@@ -106,6 +107,12 @@
                 <artifactId>easyexcel</artifactId>
                 <version>${easyexcel.version}</version>
             </dependency>
+
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>druid-spring-boot-starter</artifactId>
+                <version>${druid.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 </project>