最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java如何優(yōu)雅的實(shí)現(xiàn)微信登錄注冊

 更新時(shí)間:2022年02月21日 11:12:52   作者:Anyin  
這篇文章主要給大家介紹了關(guān)于Java如何優(yōu)雅的實(shí)現(xiàn)微信登錄注冊的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

引言

今天我們來聊一聊微信登錄注冊遇到的一些事兒。

在我們的業(yè)務(wù)系統(tǒng)中,一個(gè)用戶在系統(tǒng)中肯定會(huì)有一個(gè)唯一標(biāo)識(shí),并且這個(gè)唯一標(biāo)識(shí)一般是從系統(tǒng)外部獲取的,而不是系統(tǒng)自動(dòng)生成的,例如:手機(jī)號或者身份證。

我們在微信的場景下(微信公眾號H5或者小程序),對于用戶的唯一標(biāo)識(shí)一般都是手機(jī)號或者openid。在正常情況下,我們遇到的都是一個(gè)用戶只有一個(gè)微信號,一個(gè)微信號綁定了一個(gè)手機(jī)號,所以我們就認(rèn)為三者的關(guān)系如下:

但是,理想很豐滿,現(xiàn)實(shí)很骨感,我們遇到的情況肯定不會(huì)如此的簡單。

問題分析

當(dāng)一個(gè)系統(tǒng)運(yùn)行的足夠久,用戶量足夠多,那么你總會(huì)遇到各種奇奇怪怪的問題。

在上一節(jié),我們知道正常情況遇到的場景會(huì)比較簡單,用戶、微信號、手機(jī)號三者是1:1:1的關(guān)系,也就說三者可以等價(jià),我用其中一個(gè)信息,總是可以查詢出另外兩個(gè)的信息,例如:我可以用手機(jī)號,查詢出用戶ID和微信openid。

所以,根據(jù)以上思路,我們很容易設(shè)計(jì)出用戶表:cus_info ,基本表結(jié)構(gòu)如下:

用戶ID微信openid用戶手機(jī)號邏輯刪除其他字段
idopenidmobiledel_flg...

但是當(dāng)遇到以下2個(gè)場景的時(shí)候,這個(gè)表結(jié)構(gòu)設(shè)計(jì)就無法滿足需求了。

一個(gè)用戶2個(gè)微信號有些用戶是擁有兩個(gè)微信號,并且綁定同一個(gè)手機(jī)號(這個(gè)邏輯可以通過微信換綁手機(jī)號實(shí)現(xiàn))。

在這個(gè)場景下,一旦用戶換了個(gè)微信號登錄進(jìn)入系統(tǒng)的時(shí)候,根據(jù)微信openid進(jìn)行登錄,因?yàn)楸頂?shù)據(jù)找不到該openid,則走注冊流程;在注冊的時(shí)候,又根據(jù)手機(jī)號查詢用戶信息,發(fā)現(xiàn)用戶已經(jīng)存在,返回登錄流程,最終造成邏輯死循環(huán)。

一個(gè)用戶2個(gè)手機(jī)號另外還有一些用戶擁有2個(gè)手機(jī)號,并且綁定同一個(gè)手機(jī)號(這個(gè)邏輯在用戶授權(quán)手機(jī)號的時(shí)候添加另外一個(gè)手機(jī)號實(shí)現(xiàn))。

在這個(gè)場景下,第一次用戶使用手機(jī)號A注冊并登錄,我們在后端綁定了手機(jī)號A和對應(yīng)的微信openid;第二次用戶使用手機(jī)號B注冊并登錄,這時(shí)候數(shù)據(jù)庫會(huì)有2條記錄,不同手機(jī)號相同的openid。這樣子會(huì)導(dǎo)致在某些場景下(例如支付回調(diào)),根據(jù)openid獲取用戶信息的時(shí)候,找到2個(gè)用戶,從而導(dǎo)致業(yè)務(wù)異常。

解決思路

以上2個(gè)問題,在不同的業(yè)務(wù)場景下,不同的人會(huì)有不同的解法。有以手機(jī)號作為用戶的唯一標(biāo)識(shí),有以微信openid作為用戶唯一標(biāo)識(shí)。在這里,我們提供以手機(jī)號作為用戶唯一標(biāo)識(shí)的解法。

在這里,我們認(rèn)為一個(gè)手機(jī)號就是一個(gè)用戶,一個(gè)用戶會(huì)有多個(gè)微信號。關(guān)系如下:

一個(gè)用戶2個(gè)微信號針對該問題,我們在登錄注冊的時(shí)候,會(huì)通過邏輯控制,保證一個(gè)手機(jī)號只能找到一個(gè)微信openid。處理方式如下:

  • 根據(jù)當(dāng)前的手機(jī)號查詢到所有的微信openid,做邏輯刪除處理
  • 根據(jù)當(dāng)前的openid查詢到所有的手機(jī)號,做邏輯刪除處理
  • 根據(jù)當(dāng)前手機(jī)號和openid查詢是否存在記錄,如果不存在則新增,如果存在則邏輯刪除標(biāo)識(shí)重置為正常。

一個(gè)用戶2個(gè)手機(jī)號針對該問題,我們在業(yè)務(wù)上做處理。因?yàn)槲覀冋J(rèn)為了一個(gè)手機(jī)號就是一個(gè)用戶,如果一個(gè)用戶擁有兩個(gè)手機(jī)號,那么在我們系統(tǒng)上我們認(rèn)為是兩個(gè)用戶,他們的數(shù)據(jù)是相互獨(dú)立的。

另外在這個(gè)場景下,我們還需要提供一個(gè)手機(jī)號換綁的功能。這樣當(dāng)用戶有2個(gè)手機(jī)號,也能給實(shí)現(xiàn)切換的需求。

方案實(shí)現(xiàn)

以上,相關(guān)解決思路我們有了。那么接下來就是設(shè)計(jì)和編碼。

根據(jù)以上,我們會(huì)設(shè)計(jì)如下2張表結(jié)構(gòu):

cus_info 用戶信息表

用戶ID用戶手機(jī)號邏輯刪除其他字段
idmobiledel_flg...

cus_wx_info 用戶和微信關(guān)聯(lián)表

ID用戶手機(jī)號微信appId微信openid開放平臺(tái)unionid邏輯刪除其他字段
idmobileapp_idopenidunioniddel_flg...

這里多添加了一個(gè)app_id的字段和unionid的字段,是用于當(dāng)我們的業(yè)務(wù)涉及到多個(gè)入口,例如微信公眾號H5入口和微信小程序。

不同的用戶在微信公眾號H5和微信小程序產(chǎn)生的openid可能一樣也可能不一樣,所以我們需要通過app_id來區(qū)分

同時(shí)為了關(guān)聯(lián)在微信公眾號H5和微信小程序的用戶,我們會(huì)把微信公眾號和微信小程序綁定到同一個(gè)開放平臺(tái),這個(gè)時(shí)候會(huì)產(chǎn)生一個(gè)unionid,通過該標(biāo)識(shí)即可以找到微信公眾號的用戶,也可以找到微信小程序的用戶。

接著我們實(shí)現(xiàn)一個(gè)注冊方法。

@Service
public class CsInfoServiceImpl implements CsInfoService {
    @Autowired
    private CsInfoRepository csInfoRepository;

    @Autowired
    private CsWxInfoRepository csWxInfoRepository;

    @Autowired
    private CsInfoConvert csInfoConvert;
    
    @Override
    @Transactional(rollbackFor = Throwable.class, timeout = 60)
    public CsWxInfoDTO register(CsInfoRegisterDTO param) {
        // 根據(jù)手機(jī)號查詢用戶信息
        CsInfo info = csInfoRepository.infoByMobile(param.getMobile());
        Long id = info == null ? 0 : info.getId();
        // 如果用戶不存在,則創(chuàng)建
        if(id == 0){
            id = csInfoRepository.create(param.getMobile(), param.getRegisterSource().getCode());
        }
        // 邏輯刪除當(dāng)前手機(jī)號綁定的openid
        // 邏輯刪除當(dāng)前openid綁定的手機(jī)號
        csWxInfoRepository.handleOpenidMobileUnique(param.getMobile(), param.getOpenid(), param.getAppId());
        
        // 保證當(dāng)前手機(jī)號和openid在系統(tǒng)中1:1的關(guān)系
        CsWxInfo wxInfo = csWxInfoRepository.infoByMobileOpenid(param.getMobile(), param.getOpenid(), param.getAppId());
        if(wxInfo == null){
            wxInfo = new CsWxInfo();
            wxInfo.setAppId(param.getAppId());
            wxInfo.setMobile(param.getMobile());
            wxInfo.setOpenid(param.getOpenid());
            wxInfo.setUnionid(param.getUnionid());
            wxInfo.setAvatarUrl(param.getAvatarUrl());
            wxInfo.setNickName(param.getNickName());
            csWxInfoRepository.save(wxInfo);
        }else{
            CsWxInfo model = new CsWxInfo();
            model.setId(wxInfo.getId());
            model.setDelFlg(Integer.valueOf(DelFlgEnum.NORMAL.getCode()));
            csWxInfoRepository.updateById(model);
        }

        CsWxInfoDTO result = csInfoConvert.getCsWxInfoDTO(wxInfo);
        result.setInfoId(id);
        return result;
    }
}  

其中handleOpenidMobileUnique方法對應(yīng)的SQL處理如下:

    <update id="loginDelByOpenIdExcludeMobile">
        update cs_wx_info set del_flg = 0 ,update_time = now()
        <where>
            del_flg = 1
            <if test="appId != null">
                and app_id = #{appId}
            </if>
            <if test="openid != null and openid != ''">
                and openid = #{openid}
            </if>
            <if test="mobile != null and mobile != ''">
                and mobile != #{mobile}
            </if>
        </where>
    </update>

    <update id="loginDelByMobileExcludeOpenid">
        update cs_wx_info set del_flg = 0 ,update_time = now()
        <where>
            del_flg = 1
            <if test="appId != null">
                and app_id = #{appId}
            </if>
            <if test="mobile != null and mobile != ''">
                and mobile = #{mobile}
            </if>
            <if test="openid != null and openid != ''">
                and openid != #{openid}
            </if>
        </where>
    </update>

最后

至此,關(guān)于微信登錄注冊遇到的一些小問題,我們找到了一個(gè)相對比較好解決方案,你還不快實(shí)踐到你自己項(xiàng)目上去?

相關(guān)源碼地址:Anyin Cloud

到此這篇關(guān)于Java如何優(yōu)雅的實(shí)現(xiàn)微信登錄注冊的文章就介紹到這了,更多相關(guān)Java微信登錄注冊內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java9中接口的私有方法詳解

    Java9中接口的私有方法詳解

    印象中Java?接口就沒有論述私有方法這回事。既然?Java?9?添加了這項(xiàng)特性,那么,應(yīng)該就有它的用途,我們一起來看看?Java?9?中的接口的私有方法是什么樣的吧
    2023-04-04
  • 詳解Java線程池如何實(shí)現(xiàn)優(yōu)雅退出

    詳解Java線程池如何實(shí)現(xiàn)優(yōu)雅退出

    這篇文章我們將從源碼角度深度解析線程池是如何優(yōu)雅的退出程序的,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)java線程池有一定幫助,需要的可以參考一下
    2022-07-07
  • php上傳文件分類實(shí)例代碼

    php上傳文件分類實(shí)例代碼

    這篇文章主要介紹了php上傳文件分類實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-02-02
  • Java equals 方法與hashcode 方法的深入解析

    Java equals 方法與hashcode 方法的深入解析

    面試時(shí)經(jīng)常會(huì)問起字符串比較相關(guān)的問題,比如:字符串比較時(shí)用的什么方法,內(nèi)部實(shí)現(xiàn)如何?hashcode的作用,以及重寫equal方法,為什么要重寫hashcode方法?以下就為大家解答,需要的朋友可以參考下
    2013-07-07
  • SpringBoot 下的 Static 文件夾打包成前端資源的示例代碼

    SpringBoot 下的 Static 文件夾打包成前端資源的示例代碼

    這篇文章主要介紹了SpringBoot 下的 Static 文件夾如何打包成前端資源,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • java?IP歸屬地功能實(shí)現(xiàn)詳解

    java?IP歸屬地功能實(shí)現(xiàn)詳解

    前一陣子抖音和微博開始陸續(xù)上了IP歸屬地的功能,引起了眾多熱議,有大批在國外的老鐵們開始"原形畢露",被定位到國內(nèi)來,那么IP歸屬到底是怎么實(shí)現(xiàn)的呢?那么網(wǎng)紅們的歸屬地到底對不對呢
    2022-07-07
  • Java時(shí)區(qū)轉(zhuǎn)換實(shí)例代碼解析

    Java時(shí)區(qū)轉(zhuǎn)換實(shí)例代碼解析

    這篇文章主要介紹了Java時(shí)區(qū)轉(zhuǎn)換實(shí)例代碼解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • RabbitMQ 實(shí)現(xiàn)延遲隊(duì)列的兩種方式詳解

    RabbitMQ 實(shí)現(xiàn)延遲隊(duì)列的兩種方式詳解

    很多場景下我們都需要延遲隊(duì)列。這篇文章主要以RabbitMQ為例來和大家聊一聊延遲隊(duì)列的玩法。文中的代碼具有一定的學(xué)習(xí)價(jià)值,感興趣的同學(xué)可以了解一下
    2021-12-12
  • mybatis配置獲取自增主鍵的操作方法

    mybatis配置獲取自增主鍵的操作方法

    當(dāng)需要?jiǎng)倓偛迦霐?shù)據(jù)庫的數(shù)據(jù)對應(yīng)的新增主鍵時(shí),通過配置xml文件,使數(shù)據(jù)庫返回新增主鍵id,并把主鍵id與類參數(shù)對應(yīng),本文給大家介紹了mybatis配置獲取自增主鍵的操作方法,需要的朋友可以參考下
    2024-05-05
  • 詳解Java線程池如何統(tǒng)計(jì)線程空閑時(shí)間

    詳解Java線程池如何統(tǒng)計(jì)線程空閑時(shí)間

    這篇文章主要和大家分享一個(gè)面試題:Java線程池是怎么統(tǒng)計(jì)線程空閑時(shí)間?文中的示例代碼講解詳細(xì),對我們掌握J(rèn)ava有一定幫助,需要的可以參考一下
    2022-11-11

最新評論

嘉黎县| 泗阳县| 长沙市| 孟连| 伊春市| 奉化市| 阿尔山市| 巨野县| 雷山县| 宕昌县| 乌鲁木齐县| 大连市| 民乐县| 枝江市| 深泽县| 阿瓦提县| 出国| 曲水县| 海安县| 游戏| 荣昌县| 潜江市| 柏乡县| 合山市| 辽中县| 从化市| 台中市| 团风县| 柏乡县| 朝阳县| 茂名市| 犍为县| 龙井市| 兴海县| 灵璧县| 辉县市| 怀集县| 施秉县| 克山县| 静安区| 牙克石市|