diff --git a/login-wechat/pom.xml b/login-wechat/pom.xml new file mode 100644 index 00000000..9759351d --- /dev/null +++ b/login-wechat/pom.xml @@ -0,0 +1,22 @@ + + + + wg-basic + ink.wgink + 1.0-SNAPSHOT + + 4.0.0 + + login-wechat + + + + ink.wgink + login-base + 1.0-SNAPSHOT + + + + \ No newline at end of file diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/config/properties/MiniAppProperties.java b/login-wechat/src/main/java/ink/wgink/login/wechat/config/properties/MiniAppProperties.java new file mode 100644 index 00000000..70b33072 --- /dev/null +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/config/properties/MiniAppProperties.java @@ -0,0 +1,93 @@ +package ink.wgink.login.wechat.config.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: WechatMiniProgramProperties + * @Description: 微信小程序 + * @Author: WangGeng + * @Date: 2020/5/9 15:50 + * @Version: 1.0 + **/ +@Configuration +@ConfigurationProperties(prefix = "open-platform.wechat.mini-app") +public class MiniAppProperties { + + private Boolean active; + private String authorizeUrl; + private String bindUserUrl; + private String grantType; + private String appKey; + private String appSecret; + + public Boolean getActive() { + return active; + } + + public void setActive(Boolean active) { + this.active = active; + } + + public String getAuthorizeUrl() { + return authorizeUrl == null ? "" : authorizeUrl; + } + + public void setAuthorizeUrl(String authorizeUrl) { + this.authorizeUrl = authorizeUrl; + } + + public String getBindUserUrl() { + return bindUserUrl == null ? "" : bindUserUrl; + } + + public void setBindUserUrl(String bindUserUrl) { + this.bindUserUrl = bindUserUrl; + } + + public String getGrantType() { + return grantType == null ? "" : grantType; + } + + public void setGrantType(String grantType) { + this.grantType = grantType; + } + + public String getAppKey() { + return appKey == null ? "" : appKey; + } + + public void setAppKey(String appKey) { + this.appKey = appKey; + } + + public String getAppSecret() { + return appSecret == null ? "" : appSecret; + } + + public void setAppSecret(String appSecret) { + this.appSecret = appSecret; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"active\":") + .append(active); + sb.append(",\"authorizeUrl\":\"") + .append(authorizeUrl).append('\"'); + sb.append(",\"bindUserUrl\":\"") + .append(bindUserUrl).append('\"'); + sb.append(",\"grantType\":\"") + .append(grantType).append('\"'); + sb.append(",\"appKey\":\"") + .append(appKey).append('\"'); + sb.append(",\"appSecret\":\"") + .append(appSecret).append('\"'); + sb.append('}'); + return sb.toString(); + } +} diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/controller/api/sign/MiniAppSignController.java b/login-wechat/src/main/java/ink/wgink/login/wechat/controller/api/sign/MiniAppSignController.java new file mode 100644 index 00000000..4328d5d3 --- /dev/null +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/controller/api/sign/MiniAppSignController.java @@ -0,0 +1,39 @@ +package ink.wgink.login.wechat.controller.api.sign; + +import ink.wgink.annotation.CheckRequestBodyAnnotation; +import ink.wgink.interfaces.consts.ISystemConstant; +import ink.wgink.login.wechat.pojo.vos.sign.MiniAppLoginVO; +import ink.wgink.login.wechat.service.sign.IMiniAppSignService; +import ink.wgink.pojo.result.SuccessResultData; +import io.swagger.annotations.Api; +import org.springframework.beans.factory.annotation.Autowired; +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; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: MiniSignWechatController + * @Description: 小程序登录 + * @Author: wanggeng + * @Date: 2021/4/8 5:08 下午 + * @Version: 1.0 + */ +@Api(tags = ISystemConstant.API_TAGS_WECHAT_MINI_APP_PREFIX + "小程序登录") +@RestController +@RequestMapping(ISystemConstant.WECHAT_MINI_APP_PREFIX + "/sign") +public class MiniAppSignController { + + @Autowired + private IMiniAppSignService miniAppSignService; + + @PostMapping("default") + @CheckRequestBodyAnnotation + public SuccessResultData defaultSign(@RequestBody MiniAppLoginVO miniAppLoginVO) throws Exception { + return new SuccessResultData<>(miniAppSignService.defaultSign(miniAppLoginVO)); + } + +} diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/dao/user/IMiniAppUserDao.java b/login-wechat/src/main/java/ink/wgink/login/wechat/dao/user/IMiniAppUserDao.java new file mode 100644 index 00000000..482f49fd --- /dev/null +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/dao/user/IMiniAppUserDao.java @@ -0,0 +1,47 @@ +package ink.wgink.login.wechat.dao.user; + +import ink.wgink.exceptions.SaveException; +import ink.wgink.exceptions.SearchException; +import ink.wgink.exceptions.UpdateException; +import ink.wgink.login.wechat.pojo.pos.user.MiniAppUserPO; +import org.springframework.stereotype.Repository; + +import java.util.Map; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: IMiniAppUserDao + * @Description: 小程序用户 + * @Author: wanggeng + * @Date: 2021/4/8 5:39 下午 + * @Version: 1.0 + */ +@Repository +public interface IMiniAppUserDao { + + /** + * 建表 + * + * @throws UpdateException + */ + void createTable() throws UpdateException; + + /** + * 新增 + * + * @param params + * @throws SaveException + */ + void save(Map params) throws SaveException; + + /** + * 详情 + * + * @param params + * @return + * @throws SearchException + */ + MiniAppUserPO getPO(Map params) throws SearchException; +} diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/bos/user/MiniAppUserInfoBO.java b/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/bos/user/MiniAppUserInfoBO.java new file mode 100644 index 00000000..59a45ec1 --- /dev/null +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/bos/user/MiniAppUserInfoBO.java @@ -0,0 +1,88 @@ +package ink.wgink.login.wechat.pojo.bos.user; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: WechatMiniAppUserInfo + * @Description: 微信小程序用户信息 + * @Author: WangGeng + * @Date: 2020/5/9 18:29 + * @Version: 1.0 + **/ +public class MiniAppUserInfoBO { + + private String openid; + private String session_key; + private String unionid; + private Integer errcode; + private String errmsg; + private long updateTime; + + public String getOpenid() { + return openid == null ? "" : openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public String getSession_key() { + return session_key == null ? "" : session_key; + } + + public void setSession_key(String session_key) { + this.session_key = session_key; + } + + public String getUnionid() { + return unionid == null ? "" : unionid; + } + + public void setUnionid(String unionid) { + this.unionid = unionid; + } + + public Integer getErrcode() { + return errcode; + } + + public void setErrcode(Integer errcode) { + this.errcode = errcode; + } + + public String getErrmsg() { + return errmsg == null ? "" : errmsg; + } + + public void setErrmsg(String errmsg) { + this.errmsg = errmsg; + } + + public long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(long updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"openid\":\"") + .append(openid).append('\"'); + sb.append(",\"session_key\":\"") + .append(session_key).append('\"'); + sb.append(",\"unionid\":\"") + .append(unionid).append('\"'); + sb.append(",\"errcode\":") + .append(errcode); + sb.append(",\"errmsg\":\"") + .append(errmsg).append('\"'); + sb.append(",\"updateTime\":") + .append(updateTime); + sb.append('}'); + return sb.toString(); + } +} diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/pos/user/MiniAppUserPO.java b/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/pos/user/MiniAppUserPO.java new file mode 100644 index 00000000..b51ce344 --- /dev/null +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/pos/user/MiniAppUserPO.java @@ -0,0 +1,63 @@ +package ink.wgink.login.wechat.pojo.pos.user; + +import java.io.Serializable; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: MiniAppUserPO + * @Description: 小程序用户 + * @Author: wanggeng + * @Date: 2021/4/8 5:49 下午 + * @Version: 1.0 + */ +public class MiniAppUserPO implements Serializable { + + private static final long serialVersionUID = -8186629510739913926L; + private String appId; + private String openId; + private String userId; + private Integer isInitAccount; + private String gmtCreate; + + public String getAppId() { + return appId == null ? "" : appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getOpenId() { + return openId == null ? "" : openId; + } + + public void setOpenId(String openId) { + this.openId = openId; + } + + public String getUserId() { + return userId == null ? "" : userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public Integer getIsInitAccount() { + return isInitAccount == null ? 0 : isInitAccount; + } + + public void setIsInitAccount(Integer isInitAccount) { + this.isInitAccount = isInitAccount; + } + + public String getGmtCreate() { + return gmtCreate == null ? "" : gmtCreate; + } + + public void setGmtCreate(String gmtCreate) { + this.gmtCreate = gmtCreate; + } +} diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/vos/sign/MiniAppLoginVO.java b/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/vos/sign/MiniAppLoginVO.java new file mode 100644 index 00000000..a50122ed --- /dev/null +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/pojo/vos/sign/MiniAppLoginVO.java @@ -0,0 +1,40 @@ +package ink.wgink.login.wechat.pojo.vos.sign; + +import ink.wgink.annotation.CheckEmptyAnnotation; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: WechatMiniProgramLoginVO + * @Description: 小程序登录VO + * @Author: WangGeng + * @Date: 2020/5/9 18:12 + * @Version: 1.0 + **/ +@ApiModel +public class MiniAppLoginVO { + + @ApiModelProperty(name = "jsCode", value = "临时code") + @CheckEmptyAnnotation(name = "jsCode") + private String jsCode; + + public String getJsCode() { + return jsCode == null ? "" : jsCode; + } + + public void setJsCode(String jsCode) { + this.jsCode = jsCode; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"jsCode\":\"") + .append(jsCode).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 new file mode 100644 index 00000000..e8e88a2f --- /dev/null +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/service/sign/IMiniAppSignService.java @@ -0,0 +1,28 @@ +package ink.wgink.login.wechat.service.sign; + +import ink.wgink.login.wechat.pojo.vos.sign.MiniAppLoginVO; +import ink.wgink.pojo.result.SuccessResultData; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: IMiniAppSignService + * @Description: 小程序登录 + * @Author: wanggeng + * @Date: 2021/4/8 5:14 下午 + * @Version: 1.0 + */ +public interface IMiniAppSignService { + + String WECHAT_RANDOM_USER_PREFIX = "WX_"; + + /** + * 默认登录 + * + * @param miniAppLoginVO + * @return + * @throws Exception + */ + String defaultSign(MiniAppLoginVO miniAppLoginVO) throws Exception; +} 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 new file mode 100644 index 00000000..465f76e3 --- /dev/null +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/service/sign/impl/MiniAppSignServiceImpl.java @@ -0,0 +1,82 @@ +package ink.wgink.login.wechat.service.sign.impl; + +import com.alibaba.fastjson.JSONObject; +import ink.wgink.exceptions.PropertiesException; +import ink.wgink.exceptions.SearchException; +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.config.properties.MiniAppProperties; +import ink.wgink.login.wechat.pojo.bos.user.MiniAppUserInfoBO; +import ink.wgink.login.wechat.pojo.vos.sign.MiniAppLoginVO; +import ink.wgink.login.wechat.service.sign.IMiniAppSignService; +import ink.wgink.login.wechat.service.user.IMiniAppUserService; +import ink.wgink.service.user.pojo.pos.UserPO; +import ink.wgink.service.user.service.IUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: MiniAppSignServiceImpl + * @Description: 小程序登录 + * @Author: wanggeng + * @Date: 2021/4/8 5:14 下午 + * @Version: 1.0 + */ +@Service +public class MiniAppSignServiceImpl extends BaseAppSignService implements IMiniAppSignService { + + @Autowired + private MiniAppProperties miniAppProperties; + @Autowired + private IMiniAppUserService miniAppUserService; + @Autowired + private IUserService userService; + + @Override + public String defaultSign(MiniAppLoginVO miniAppLoginVO) throws Exception { + if (miniAppLoginVO == null) { + throw new PropertiesException("未有相关配置"); + } + if (miniAppProperties.getActive() == null || !miniAppProperties.getActive()) { + throw new PropertiesException("未激活小程序配置"); + } + Map params = new HashMap<>(2); + params.put("appid", miniAppProperties.getAppKey()); + params.put("secret", miniAppProperties.getAppSecret()); + params.put("js_code", miniAppLoginVO.getJsCode()); + params.put("grant_type", miniAppProperties.getGrantType()); + + StringBuilder url = new StringBuilder(miniAppProperties.getAuthorizeUrl()); + url.append("?appid={appid}&secret={secret}&js_code={js_code}&grant_type={grant_type}"); + RestTemplate restTemplate = new RestTemplate(); + + String resultJson = restTemplate.getForObject(url.toString(), String.class, params); + MiniAppUserInfoBO miniAppUserInfoBO = JSONObject.parseObject(resultJson, MiniAppUserInfoBO.class); + if (miniAppUserInfoBO == null) { + throw new WechatUserInfoException("获取微信用户信息失败"); + } + if (miniAppUserInfoBO.getErrcode() != null && miniAppUserInfoBO.getErrcode() != 0) { + throw new WechatAccessTokenForUserException(String.format("获取用户信息失败,错误码:%s,错误信息:%s", miniAppUserInfoBO.getErrcode(), miniAppUserInfoBO.getErrmsg())); + } + LOG.debug("绑定用户"); + String userId = miniAppUserService.createAndReturnUserId(miniAppProperties.getAppKey(), miniAppUserInfoBO.getOpenid()); + UserPO userPO = userService.getPO(userId); + if (userPO == null) { + throw new SearchException("用户不存在"); + } + String isRandomUsername = ISystemConstant.IS_FALSE_INT; + if (userPO.getUserUsername().startsWith(IMiniAppSignService.WECHAT_RANDOM_USER_PREFIX)) { + isRandomUsername = ISystemConstant.IS_TRUE_INT; + } + return getToken(userPO) + "_" + isRandomUsername; + } +} diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/service/user/IMiniAppUserService.java b/login-wechat/src/main/java/ink/wgink/login/wechat/service/user/IMiniAppUserService.java new file mode 100644 index 00000000..0ae2f047 --- /dev/null +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/service/user/IMiniAppUserService.java @@ -0,0 +1,54 @@ +package ink.wgink.login.wechat.service.user; + +import ink.wgink.login.wechat.pojo.pos.user.MiniAppUserPO; + +import java.util.Map; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: IMiniAppUserService + * @Description: 小程序用户 + * @Author: wanggeng + * @Date: 2021/4/8 5:37 下午 + * @Version: 1.0 + */ +public interface IMiniAppUserService { + + /** + * 创建用户并返回用户ID,已经存在的不操作 + * + * @param appKey + * @param openId + * @return + * @throws Exception + */ + String createAndReturnUserId(String appKey, String openId) throws Exception; + + /** + * 详情 + * + * @param params + * @return + */ + MiniAppUserPO getPO(Map params); + + /** + * 详情 + * + * @param userId + * @return + */ + MiniAppUserPO getPO(String userId); + + /** + * 详情 + * + * @param appId + * @param openId + * @return + */ + MiniAppUserPO getPO(String appId, String openId); + +} diff --git a/login-wechat/src/main/java/ink/wgink/login/wechat/service/user/impl/MiniAppUserServiceImpl.java b/login-wechat/src/main/java/ink/wgink/login/wechat/service/user/impl/MiniAppUserServiceImpl.java new file mode 100644 index 00000000..0ce1d0d1 --- /dev/null +++ b/login-wechat/src/main/java/ink/wgink/login/wechat/service/user/impl/MiniAppUserServiceImpl.java @@ -0,0 +1,83 @@ +package ink.wgink.login.wechat.service.user.impl; + +import ink.wgink.common.base.DefaultBaseService; +import ink.wgink.login.wechat.dao.user.IMiniAppUserDao; +import ink.wgink.login.wechat.pojo.pos.user.MiniAppUserPO; +import ink.wgink.login.wechat.service.sign.IMiniAppSignService; +import ink.wgink.login.wechat.service.user.IMiniAppUserService; +import ink.wgink.service.user.pojo.pos.UserPO; +import ink.wgink.service.user.pojo.vos.UserVO; +import ink.wgink.service.user.service.IUserService; +import ink.wgink.util.date.DateUtil; +import ink.wgink.util.map.HashMapUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: MiniAppUserServiceImpl + * @Description: 小程序用户 + * @Author: wanggeng + * @Date: 2021/4/8 5:38 下午 + * @Version: 1.0 + */ +@Service +public class MiniAppUserServiceImpl extends DefaultBaseService implements IMiniAppUserService { + + @Value("${user.default-password:888888}") + private String defaultPassword; + @Autowired + private IMiniAppUserDao miniAppUserDao; + @Autowired + private IUserService userService; + + @Override + public String createAndReturnUserId(String appKey, String openId) { + MiniAppUserPO miniAppUserPO = getPO(appKey, openId); + if (miniAppUserPO != null) { + LOG.debug("已经绑定小程序用户"); + return miniAppUserPO.getUserId(); + } + UserVO userVO = new UserVO(); + userVO.setUserUsername(IMiniAppSignService.WECHAT_RANDOM_USER_PREFIX + openId); + userVO.setUserName("微信" + openId.substring(0, 6)); + userVO.setUserPassword(defaultPassword); + userVO.setUserState(0); + userVO.setUserType(2); + String userId = userService.saveAndReturnId(userVO, true); + + Map params = getHashMap(6); + params.put("appId", appKey); + params.put("openId", openId); + params.put("userId", userId); + params.put("isInitAccount", 1); + params.put("gmtCreate", DateUtil.getTime()); + miniAppUserDao.save(params); + return userId; + } + + @Override + public MiniAppUserPO getPO(Map params) { + return miniAppUserDao.getPO(params); + } + + @Override + public MiniAppUserPO getPO(String userId) { + Map params = getHashMap(2); + params.put("userId", userId); + return getPO(params); + } + + @Override + public MiniAppUserPO getPO(String appId, String openId) { + Map params = getHashMap(4); + params.put("appId", appId); + params.put("openId", openId); + return getPO(params); + } +} diff --git a/login-wechat/src/main/resources/mybatis/mapper/miniapp-user-mapper.xml b/login-wechat/src/main/resources/mybatis/mapper/miniapp-user-mapper.xml new file mode 100644 index 00000000..4654a15c --- /dev/null +++ b/login-wechat/src/main/resources/mybatis/mapper/miniapp-user-mapper.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + CREATE TABLE `wechat_mini_app_user` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `app_id` varchar(255) DEFAULT NULL COMMENT 'appid', + `open_id` varchar(255) DEFAULT NULL COMMENT 'openid', + `user_id` varchar(255) DEFAULT NULL COMMENT '用户ID', + `is_init_account` int(1) DEFAULT '0' COMMENT '是否初始化账户', + `gmt_create` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `app_id` (`app_id`) USING BTREE, + KEY `open_id` (`open_id`) USING BTREE, + KEY `user_id` (`user_id`) USING BTREE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='小程序用户'; + + + + + INSERT INTO wechat_mini_app_user( + app_id, + open_id, + user_id, + is_init_account, + gmt_create + ) VALUES( + #{appId}, + #{openId}, + #{userId}, + #{isInitAccount}, + #{gmtCreate} + ) + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index eea0ffde..778b913e 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,7 @@ service-position login-base login-app + login-wechat pom