diff --git a/basic-properties/src/main/java/ink/wgink/properties/wechat/miniapp/MiniAppProperties.java b/basic-properties/src/main/java/ink/wgink/properties/wechat/miniapp/MiniappProperties.java similarity index 98% rename from basic-properties/src/main/java/ink/wgink/properties/wechat/miniapp/MiniAppProperties.java rename to basic-properties/src/main/java/ink/wgink/properties/wechat/miniapp/MiniappProperties.java index a6ac6902..8750fe5e 100644 --- a/basic-properties/src/main/java/ink/wgink/properties/wechat/miniapp/MiniAppProperties.java +++ b/basic-properties/src/main/java/ink/wgink/properties/wechat/miniapp/MiniappProperties.java @@ -15,7 +15,7 @@ import org.springframework.context.annotation.Configuration; **/ @Configuration @ConfigurationProperties(prefix = "open-platform.wechat.mini-app") -public class MiniAppProperties { +public class MiniappProperties { private Boolean active; private String authorizeUrl; diff --git a/login-base/src/main/java/ink/wgink/login/base/security/WebSecurityConfig.java b/login-base/src/main/java/ink/wgink/login/base/security/WebSecurityConfig.java index be9c6bac..0f82ba6b 100644 --- a/login-base/src/main/java/ink/wgink/login/base/security/WebSecurityConfig.java +++ b/login-base/src/main/java/ink/wgink/login/base/security/WebSecurityConfig.java @@ -62,7 +62,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { "/approute/**", "/wechat/**", "/wechat/route/**", - "/wechat/miniapp/**", + "/wechat-miniapp/**", "/route/file/**", "/api/sms/getverificationcode/*", "/api/user/getsignintype/**") diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/controller/app/MiniappAppController.java b/login-wechat/src/main/java/ink/wgink/login/wechat/controller/app/MiniappAppController.java index 261fe53f..755844da 100644 --- a/login-wechat/src/main/java/ink/wgink/login/wechat/controller/app/MiniappAppController.java +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/controller/app/MiniappAppController.java @@ -2,8 +2,8 @@ package ink.wgink.login.wechat.controller.app; import ink.wgink.annotation.CheckRequestBodyAnnotation; import ink.wgink.interfaces.consts.ISystemConstant; +import ink.wgink.login.wechat.pojo.vos.update.MiniappUpdatePhoneVO; import ink.wgink.login.wechat.service.sign.IMiniappSignService; -import ink.wgink.module.wechat.pojo.vos.miniapp.MiniappUpdatePhoneVO; import ink.wgink.pojo.result.ErrorResult; import ink.wgink.pojo.result.SuccessResultData; import io.swagger.annotations.*; diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/controller/wechat/sign/SignMiniappController.java b/login-wechat/src/main/java/ink/wgink/login/wechat/controller/wechat/sign/SignMiniappController.java index 36dafecd..5a7f3d53 100644 --- a/login-wechat/src/main/java/ink/wgink/login/wechat/controller/wechat/sign/SignMiniappController.java +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/controller/wechat/sign/SignMiniappController.java @@ -7,7 +7,7 @@ import ink.wgink.login.wechat.pojo.vos.sign.MiniappLoginVO; import ink.wgink.login.wechat.service.sign.IMiniappSignService; import ink.wgink.pojo.result.ErrorResult; import ink.wgink.pojo.result.SuccessResultData; -import ink.wgink.properties.wechat.miniapp.MiniAppProperties; +import ink.wgink.properties.wechat.miniapp.MiniappProperties; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; @@ -34,7 +34,7 @@ import org.springframework.web.bind.annotation.RestController; public class SignMiniappController { @Autowired - private MiniAppProperties miniAppProperties; + private MiniappProperties miniAppProperties; @Autowired private IMiniappSignService miniAppSignService; diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/bos/miniapp/MiniappPhoneDataBO.java b/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/bos/miniapp/MiniappPhoneDataBO.java new file mode 100644 index 00000000..1da763fd --- /dev/null +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/bos/miniapp/MiniappPhoneDataBO.java @@ -0,0 +1,81 @@ +package ink.wgink.login.wechat.pojo.bos.miniapp; + +/** + * @ClassName: MiniappPhoneBO + * @Description: 小程序手机号 + * @Author: wanggeng + * @Date: 2021/8/3 10:46 上午 + * @Version: 1.0 + */ +public class MiniappPhoneDataBO { + + private String phoneNumber; + private String purePhoneNumber; + private String countryCode; + private WaterMark watermark; + + public String getPhoneNumber() { + return phoneNumber == null ? "" : phoneNumber.trim(); + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getPurePhoneNumber() { + return purePhoneNumber == null ? "" : purePhoneNumber.trim(); + } + + public void setPurePhoneNumber(String purePhoneNumber) { + this.purePhoneNumber = purePhoneNumber; + } + + public String getCountryCode() { + return countryCode == null ? "" : countryCode.trim(); + } + + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + + public WaterMark getWatermark() { + return watermark; + } + + public void setWatermark(WaterMark watermark) { + this.watermark = watermark; + } + + public static class WaterMark { + private String appid; + private Long timestamp; + + public String getAppid() { + return appid == null ? "" : appid.trim(); + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public Long getTimestamp() { + return timestamp; + } + + public void setTimestamp(Long timestamp) { + this.timestamp = timestamp; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"appid\":\"") + .append(appid).append('\"'); + sb.append(",\"timestamp\":") + .append(timestamp); + sb.append('}'); + return sb.toString(); + } + } + +} diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/vos/update/MiniappUpdatePhoneVO.java b/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/vos/update/MiniappUpdatePhoneVO.java new file mode 100644 index 00000000..2baa292d --- /dev/null +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/vos/update/MiniappUpdatePhoneVO.java @@ -0,0 +1,50 @@ +package ink.wgink.login.wechat.pojo.vos.update; + +import ink.wgink.annotation.CheckEmptyAnnotation; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * @ClassName: MiniAppUpdatePhoneVO + * @Description: 小程序更新手机 + * @Author: wanggeng + * @Date: 2021/8/2 5:20 下午 + * @Version: 1.0 + */ +@ApiModel +public class MiniappUpdatePhoneVO { + + @ApiModelProperty(name = "encryptedData", value = "加密数据") + @CheckEmptyAnnotation(name = "加密数据") + private String encryptedData; + @ApiModelProperty(name = "iv", value = "向量") + @CheckEmptyAnnotation(name = "iv") + private String iv; + + public String getEncryptedData() { + return encryptedData == null ? "" : encryptedData.trim(); + } + + public void setEncryptedData(String encryptedData) { + this.encryptedData = encryptedData; + } + + public String getIv() { + return iv == null ? "" : iv.trim(); + } + + public void setIv(String iv) { + this.iv = iv; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"encryptedData\":\"") + .append(encryptedData).append('\"'); + sb.append(",\"iv\":\"") + .append(iv).append('\"'); + sb.append('}'); + return sb.toString(); + } +} diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/vos/update/UpdatePhoneVO.java b/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/vos/update/UpdatePhoneVO.java deleted file mode 100644 index dfb05e17..00000000 --- a/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/vos/update/UpdatePhoneVO.java +++ /dev/null @@ -1,37 +0,0 @@ -package ink.wgink.login.wechat.pojo.vos.update; - -import ink.wgink.annotation.CheckEmptyAnnotation; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - -/** - * @ClassName: MiniAppUpdatePhoneVO - * @Description: 小程序更新手机 - * @Author: wanggeng - * @Date: 2021/8/2 5:20 下午 - * @Version: 1.0 - */ -@ApiModel -public class UpdatePhoneVO { - - @ApiModelProperty(name = "phone", value = "手机号") - @CheckEmptyAnnotation(name = "手机号", regex = "phone") - private String phone; - - public String getPhone() { - return phone == null ? "" : phone.trim(); - } - - public void setPhone(String phone) { - this.phone = phone; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("{"); - sb.append("\"phone\":\"") - .append(phone).append('\"'); - sb.append('}'); - return sb.toString(); - } -} diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/service/sign/IMiniappSignService.java b/login-wechat/src/main/java/ink/wgink/login/wechat/service/sign/IMiniappSignService.java index 6d1c17a0..5165b295 100644 --- a/login-wechat/src/main/java/ink/wgink/login/wechat/service/sign/IMiniappSignService.java +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/service/sign/IMiniappSignService.java @@ -1,7 +1,7 @@ package ink.wgink.login.wechat.service.sign; import ink.wgink.login.wechat.pojo.vos.sign.MiniappLoginVO; -import ink.wgink.module.wechat.pojo.vos.miniapp.MiniappUpdatePhoneVO; +import ink.wgink.login.wechat.pojo.vos.update.MiniappUpdatePhoneVO; import java.io.UnsupportedEncodingException; diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/service/sign/impl/MiniappSignServiceImpl.java b/login-wechat/src/main/java/ink/wgink/login/wechat/service/sign/impl/MiniappSignServiceImpl.java index 82d41a36..c22f320f 100644 --- a/login-wechat/src/main/java/ink/wgink/login/wechat/service/sign/impl/MiniappSignServiceImpl.java +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/service/sign/impl/MiniappSignServiceImpl.java @@ -7,16 +7,20 @@ import ink.wgink.exceptions.WechatAccessTokenForUserException; import ink.wgink.exceptions.WechatUserInfoException; import ink.wgink.interfaces.consts.ISystemConstant; import ink.wgink.login.base.service.BaseAppSignService; +import ink.wgink.login.wechat.pojo.bos.miniapp.MiniappPhoneDataBO; import ink.wgink.login.wechat.pojo.vos.sign.MiniappLoginVO; +import ink.wgink.login.wechat.pojo.vos.update.MiniappUpdatePhoneVO; import ink.wgink.login.wechat.service.sign.IMiniappSignService; -import ink.wgink.module.wechat.pojo.bos.miniapp.MiniAppUserInfoBO; +import ink.wgink.module.wechat.manager.MiniappManager; +import ink.wgink.module.wechat.pojo.bos.miniapp.MiniappUserInfoBO; import ink.wgink.module.wechat.pojo.pos.miniapp.MiniappUserPO; -import ink.wgink.module.wechat.pojo.vos.miniapp.MiniappUpdatePhoneVO; import ink.wgink.module.wechat.service.miniapp.IMiniappUserService; -import ink.wgink.properties.wechat.miniapp.MiniAppProperties; +import ink.wgink.properties.wechat.miniapp.MiniappProperties; import ink.wgink.service.user.pojo.pos.UserPO; import ink.wgink.service.user.pojo.vos.UpdateUsernameVO; import ink.wgink.service.user.service.IUserService; +import ink.wgink.util.AesUtil; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -41,7 +45,7 @@ import java.util.Map; public class MiniappSignServiceImpl extends BaseAppSignService implements IMiniappSignService { @Autowired - private MiniAppProperties miniappProperties; + private MiniappProperties miniappProperties; @Autowired private IMiniappUserService miniappUserService; @Autowired @@ -63,7 +67,7 @@ public class MiniappSignServiceImpl extends BaseAppSignService implements IMinia RestTemplate restTemplate = new RestTemplate(); String resultJson = restTemplate.getForObject(url.toString(), String.class, params); - MiniAppUserInfoBO miniAppUserInfoBO = JSONObject.parseObject(resultJson, MiniAppUserInfoBO.class); + MiniappUserInfoBO miniAppUserInfoBO = JSONObject.parseObject(resultJson, MiniappUserInfoBO.class); if (miniAppUserInfoBO == null) { throw new WechatUserInfoException("获取微信用户信息失败"); } @@ -76,17 +80,22 @@ public class MiniappSignServiceImpl extends BaseAppSignService implements IMinia if (userPO == null) { throw new SearchException("用户不存在"); } + String token = getMiniappToken(userPO); + // 加入管理队列 + MiniappManager.getInstance().addUser(token.substring(0, token.length() - 2), miniAppUserInfoBO); return getMiniappToken(userPO); } @Override public String updatePhone(String token, MiniappUpdatePhoneVO miniappUpdatePhoneVO) throws UnsupportedEncodingException { + MiniappPhoneDataBO miniappPhoneData = getMiniappPhoneData(token, miniappUpdatePhoneVO); String userId = getAppTokenUser(token).getId(); UserPO userPO = userService.getPO(userId); if (userPO == null) { throw new SearchException("非系统用户,请刷新小程序"); } - UserPO userPOByUsername = userService.getPOByUsername(miniappUpdatePhoneVO.getPhone()); + String phone = miniappPhoneData.getPhoneNumber(); + UserPO userPOByUsername = userService.getPOByUsername(phone); if (userPOByUsername != null) { LOG.debug("手机号存在"); // 不是当前用户,抛异常 @@ -103,17 +112,36 @@ public class MiniappSignServiceImpl extends BaseAppSignService implements IMinia } LOG.debug("手机不存在,更新用户名"); UpdateUsernameVO updateUsernameVO = new UpdateUsernameVO(); - updateUsernameVO.setUsername(miniappUpdatePhoneVO.getPhone()); + updateUsernameVO.setUsername(phone); updateUsernameVO.setUpdateReason("微信用户手动更新"); userService.updateUsername(userId, updateUsernameVO); LOG.debug("返回token"); UserPO newUserPO = new UserPO(); BeanUtils.copyProperties(userPO, newUserPO); - newUserPO.setUserUsername(miniappUpdatePhoneVO.getPhone()); + newUserPO.setUserUsername(phone); miniappUserService.updateIsInitAccount(userId, 0); return getMiniappToken(userPO); } + /** + * 解密获得手机号 + * + * @param token + * @param miniappUpdatePhoneVO + * @return + */ + private MiniappPhoneDataBO getMiniappPhoneData(String token, MiniappUpdatePhoneVO miniappUpdatePhoneVO) { + MiniappUserInfoBO miniappUserInfoBO = MiniappManager.getInstance().get(token); + if (miniappUserInfoBO == null) { + throw new SearchException("会话不存在,请重新打开小程序"); + } + byte[] encryptedBytes = Base64.decodeBase64(miniappUpdatePhoneVO.getEncryptedData()); + byte[] keyBytes = Base64.decodeBase64(miniappUserInfoBO.getSession_key()); + byte[] ivBytes = Base64.decodeBase64(miniappUpdatePhoneVO.getIv()); + byte[] userInfoBytes = AesUtil.aesCommonDecoderDetail(keyBytes, encryptedBytes, ivBytes, AesUtil.PKCS_7); + return JSONObject.parseObject(userInfoBytes, MiniappPhoneDataBO.class); + } + /** * 获得小程序token * diff --git a/module-wechat/src/main/java/ink/wgink/module/wechat/manager/MiniappManager.java b/module-wechat/src/main/java/ink/wgink/module/wechat/manager/MiniappManager.java new file mode 100644 index 00000000..b06eb6d3 --- /dev/null +++ b/module-wechat/src/main/java/ink/wgink/module/wechat/manager/MiniappManager.java @@ -0,0 +1,82 @@ +package ink.wgink.module.wechat.manager; + +import ink.wgink.module.wechat.pojo.bos.miniapp.MiniappUserInfoBO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: WechatMiniAppManager + * @Description: 微信小程序管理 + * @Author: WangGeng + * @Date: 2020/5/9 18:05 + * @Version: 1.0 + **/ +public class MiniappManager { + + private static final Logger LOG = LoggerFactory.getLogger(MiniappManager.class); + private static MiniappManager miniAppManager = WechatMiniAppManagerBuilder.MINI_APP_MANAGER; + // 超时分钟 + private final int TIME_OUT_SECOND = 120 * 60; + + private MiniappManager() { + } + + private Map users = new ConcurrentHashMap<>(); + + public static MiniappManager getInstance() { + return miniAppManager; + } + + /** + * 添加用户 + * + * @param token + * @param miniappUserInfoBO + */ + public void addUser(String token, MiniappUserInfoBO miniappUserInfoBO) { + miniappUserInfoBO.setUpdateTime(System.currentTimeMillis()); + users.put(token, miniappUserInfoBO); + } + + /** + * 获取小程序应用 + * + * @param token + * @return + */ + public MiniappUserInfoBO get(String token) { + return users.get(token); + } + + /** + * 删除超时用户 + */ + public void removeTimeout() { + LOG.debug("delete timeout wechat mini app user start"); + long startTime = System.currentTimeMillis(); + List tokenList = new ArrayList<>(); + for (Map.Entry kv : users.entrySet()) { + // 超时 + if ((startTime - kv.getValue().getUpdateTime()) / 1000 > TIME_OUT_SECOND) { + tokenList.add(kv.getKey()); + } + } + for (String token : tokenList) { + users.remove(token); + } + long endTime = System.currentTimeMillis(); + LOG.debug("delete timeout wechat mini app user end, delete count: {}, useTime: {}ms", tokenList.size(), endTime - startTime); + } + + private static class WechatMiniAppManagerBuilder { + public static final MiniappManager MINI_APP_MANAGER = new MiniappManager(); + } +} diff --git a/module-wechat/src/main/java/ink/wgink/module/wechat/pojo/bos/miniapp/MiniAppUserInfoBO.java b/module-wechat/src/main/java/ink/wgink/module/wechat/pojo/bos/miniapp/MiniappUserInfoBO.java similarity index 98% rename from module-wechat/src/main/java/ink/wgink/module/wechat/pojo/bos/miniapp/MiniAppUserInfoBO.java rename to module-wechat/src/main/java/ink/wgink/module/wechat/pojo/bos/miniapp/MiniappUserInfoBO.java index 5199b11d..1472c078 100644 --- a/module-wechat/src/main/java/ink/wgink/module/wechat/pojo/bos/miniapp/MiniAppUserInfoBO.java +++ b/module-wechat/src/main/java/ink/wgink/module/wechat/pojo/bos/miniapp/MiniappUserInfoBO.java @@ -10,7 +10,7 @@ package ink.wgink.module.wechat.pojo.bos.miniapp; * @Date: 2020/5/9 18:29 * @Version: 1.0 **/ -public class MiniAppUserInfoBO { +public class MiniappUserInfoBO { private String openid; private String session_key; diff --git a/module-wechat/src/main/java/ink/wgink/module/wechat/pojo/vos/miniapp/MiniappUpdatePhoneVO.java b/module-wechat/src/main/java/ink/wgink/module/wechat/pojo/vos/miniapp/MiniappUpdatePhoneVO.java deleted file mode 100644 index cf5b7e66..00000000 --- a/module-wechat/src/main/java/ink/wgink/module/wechat/pojo/vos/miniapp/MiniappUpdatePhoneVO.java +++ /dev/null @@ -1,37 +0,0 @@ -package ink.wgink.module.wechat.pojo.vos.miniapp; - -import ink.wgink.annotation.CheckEmptyAnnotation; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - -/** - * @ClassName: MiniAppUpdatePhoneVO - * @Description: 小程序更新手机 - * @Author: wanggeng - * @Date: 2021/8/2 5:20 下午 - * @Version: 1.0 - */ -@ApiModel -public class MiniappUpdatePhoneVO { - - @ApiModelProperty(name = "phone", value = "手机号") - @CheckEmptyAnnotation(name = "手机号", regex = "phone") - private String phone; - - public String getPhone() { - return phone == null ? "" : phone.trim(); - } - - public void setPhone(String phone) { - this.phone = phone; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("{"); - sb.append("\"phone\":\"") - .append(phone).append('\"'); - sb.append('}'); - return sb.toString(); - } -} diff --git a/module-wechat/src/main/java/ink/wgink/module/wechat/startup/WechatStartUp.java b/module-wechat/src/main/java/ink/wgink/module/wechat/startup/WechatStartUp.java index d3a12c61..28fcfeff 100644 --- a/module-wechat/src/main/java/ink/wgink/module/wechat/startup/WechatStartUp.java +++ b/module-wechat/src/main/java/ink/wgink/module/wechat/startup/WechatStartUp.java @@ -1,9 +1,8 @@ package ink.wgink.module.wechat.startup; -import ink.wgink.module.wechat.dao.miniapp.IMiniAppUserDao; -import ink.wgink.module.wechat.dao.official.account.IOfficialAccountUserDao; +import ink.wgink.module.wechat.manager.MiniappManager; import ink.wgink.module.wechat.manager.OfficialAccountAccessTokenManager; -import ink.wgink.properties.wechat.miniapp.MiniAppProperties; +import ink.wgink.properties.wechat.miniapp.MiniappProperties; import ink.wgink.properties.wechat.official.account.OfficialAccountProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,17 +26,15 @@ import org.springframework.stereotype.Component; public class WechatStartUp implements ApplicationRunner { private static final Logger LOG = LoggerFactory.getLogger(WechatStartUp.class); @Autowired - private MiniAppProperties miniAppProperties; + private MiniappProperties miniAppProperties; @Autowired private OfficialAccountProperties officialAccountProperties; - @Autowired - private IMiniAppUserDao miniAppUserDao; - @Autowired - private IOfficialAccountUserDao officialAccountUserDao; @Override public void run(ApplicationArguments args) throws Exception { - new Thread(() -> refreshOfficialAccountAccessToken()).start(); + new Thread(() -> { + refreshOfficialAccountAccessToken(); + }).start(); } @Scheduled(cron = "0 0/5 * * * ?") @@ -48,4 +45,15 @@ public class WechatStartUp implements ApplicationRunner { OfficialAccountAccessTokenManager.getInstance().refreshAccessToken(officialAccountProperties); } + /** + * 删除小程序超时用户,每10分钟执行一次 + */ + @Scheduled(cron = "0 0/10 * * * ?") + public void removeTimeoutMiniAppUser() { + if (!miniAppProperties.getActive()) { + return; + } + MiniappManager.getInstance().removeTimeout(); + } + } diff --git a/module-wechat/src/main/resources/mybatis/mapper/miniapp-user-mapper.xml b/module-wechat/src/main/resources/mybatis/mapper/miniapp-user-mapper.xml index c74db02d..0657c255 100644 --- a/module-wechat/src/main/resources/mybatis/mapper/miniapp-user-mapper.xml +++ b/module-wechat/src/main/resources/mybatis/mapper/miniapp-user-mapper.xml @@ -31,7 +31,7 @@ - + INSERT INTO wechat_mini_app_user( app_id, open_id, @@ -48,7 +48,7 @@ - + UPDATE wechat_mini_app_user SET @@ -61,7 +61,7 @@ - + UPDATE wechat_mini_app_user SET @@ -110,7 +110,7 @@ app_id = #{appId} - + AND open_id = #{openId} @@ -121,6 +121,4 @@ - - \ No newline at end of file