国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot——短信發(fā)送、手機(jī)驗(yàn)證碼登錄

這篇具有很好參考價(jià)值的文章主要介紹了SpringBoot——短信發(fā)送、手機(jī)驗(yàn)證碼登錄。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

一、短信發(fā)送

1.1 阿里云短信服務(wù)

1.1.1 設(shè)置短信簽名

1.1.2 模板管理

1.1.3 設(shè)置AccessKey

1.2 短信發(fā)送——代碼開發(fā)

1.2.1 導(dǎo)入maven坐標(biāo)

1.2.2 調(diào)用API

1.2? 手機(jī)驗(yàn)證碼登錄

1.2.1 用戶數(shù)據(jù)庫(kù)表

1.2.2? 修改過濾器

1.2.3? ?隨機(jī)生成驗(yàn)證碼的工具類

1.2.4?手機(jī)驗(yàn)證碼登錄-- 發(fā)送驗(yàn)證碼

1.2.5?手機(jī)驗(yàn)證碼登錄-- 驗(yàn)證驗(yàn)證碼


一、短信發(fā)送

1.1 阿里云短信服務(wù)

短信服務(wù)_企業(yè)短信營(yíng)銷推廣_驗(yàn)證碼通知-阿里云

也可以在下面這個(gè)地方查看短信服務(wù)?

SpringBoot——短信發(fā)送、手機(jī)驗(yàn)證碼登錄

1.1.1 設(shè)置短信簽名

短信簽名就是短信發(fā)送者的署名,表示發(fā)送方的身份

1.1.2 模板管理

SpringBoot——短信發(fā)送、手機(jī)驗(yàn)證碼登錄

?申請(qǐng)下來(lái)之后可以點(diǎn)擊詳情進(jìn)行查看

? ? ?其中模板CODE是自動(dòng)生成的,不用管,重點(diǎn)是模板的內(nèi)容

SpringBoot——短信發(fā)送、手機(jī)驗(yàn)證碼登錄

1.1.3 設(shè)置AccessKey

SpringBoot——短信發(fā)送、手機(jī)驗(yàn)證碼登錄

?SpringBoot——短信發(fā)送、手機(jī)驗(yàn)證碼登錄

創(chuàng)建新的用戶

SpringBoot——短信發(fā)送、手機(jī)驗(yàn)證碼登錄

勾選上之后,我們?cè)诰幊檀a中就能使用

SpringBoot——短信發(fā)送、手機(jī)驗(yàn)證碼登錄

?

當(dāng)我們創(chuàng)建用戶成功后,就生成了一對(duì)AccessKey,即AccessKey ID(用戶名) 與AccessKey Secret(密碼)

很多人在這里的時(shí)候不小心沒截圖或者沒保存就關(guān)了,丟失了AccessKey,但是不要緊,還可以再次創(chuàng)建

還有就是如果別人知道了我們的AccessKey,那別人使用的時(shí)候會(huì)就花我們的錢。我們也可以把泄露的AccessKey禁用

SpringBoot——短信發(fā)送、手機(jī)驗(yàn)證碼登錄

之后再新增授權(quán)。這次授權(quán)的意思就是僅僅授予有關(guān)短信服務(wù)的,即是我們泄露了,別人也只能操作短信服務(wù),對(duì)我們的影響很小。

SpringBoot——短信發(fā)送、手機(jī)驗(yàn)證碼登錄

1.2 短信發(fā)送——代碼開發(fā)

參照官方文檔即可

新手指引_短信服務(wù)-阿里云幫助中心

1.2.1 導(dǎo)入maven坐標(biāo)

        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.5.16</version>
        </dependency>

        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
            <version>2.1.0</version>
        </dependency>

1.2.2 調(diào)用API


/**
 * 短信發(fā)送工具類
 */
public class SMSUtils {

	/**
	 * 發(fā)送短信
	 * @param signName 簽名
	 * @param templateCode 模板
	 * @param phoneNumbers 手機(jī)號(hào)
	 * @param param 參數(shù)
	 */
	public static void sendMessage(String signName, String templateCode,String phoneNumbers,String param){
		DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "LTAI5tHRxs2FeCu5JcJTGbm2", "v0H4PaJpXSwNr6XChtlVYAgmQWgKRA");

		IAcsClient client = new DefaultAcsClient(profile);

		SendSmsRequest request = new SendSmsRequest();

		request.setSysRegionId("cn-hangzhou");
//	    要發(fā)送給那個(gè)人的電話號(hào)碼
		request.setPhoneNumbers(phoneNumbers);
//      我們?cè)诎⒗镌圃O(shè)置的簽名
		request.setSignName(signName);
//	    我們?cè)诎⒗镌圃O(shè)置的模板
		request.setTemplateCode(templateCode);
//	    在設(shè)置模板的時(shí)候有一個(gè)占位符
		request.setTemplateParam("{\"code\":\""+param+"\"}");

//		request.setPhoneNumbers("1368846****");//接收短信的手機(jī)號(hào)碼
//		request.setSignName("阿里云");//短信簽名名稱
//		request.setTemplateCode("SMS_20933****");//短信模板CODE
//		request.setTemplateParam("張三");//短信模板變量對(duì)應(yīng)的實(shí)際值

		try {
			SendSmsResponse response = client.getAcsResponse(request);
			System.out.println("短信發(fā)送成功");
		}catch (ClientException e) {
			e.printStackTrace();
		}
	}

}

1.2? 手機(jī)驗(yàn)證碼登錄

  • 方便、快捷、無(wú)需注冊(cè)、直接登陸
  • 使用短信驗(yàn)證碼作為登錄憑證,無(wú)序記憶密碼
  • 安全

登錄流程:? 輸入手機(jī)號(hào)? ->? 獲取驗(yàn)證碼? ->? 輸入驗(yàn)證碼? ->? 點(diǎn)擊登錄? ->? 登陸成功

注意: 通過手機(jī)驗(yàn)證碼登錄,手機(jī)號(hào)是區(qū)分不同用戶的標(biāo)識(shí)

1.2.1 用戶數(shù)據(jù)庫(kù)表

因?yàn)槭峭ㄟ^手機(jī)和驗(yàn)證碼登錄的,所以沒有用戶名和密碼字段

SpringBoot——短信發(fā)送、手機(jī)驗(yàn)證碼登錄

1.2.2? 修改過濾器

?在寫代碼之前記得要在過濾器中定義不需要處理的請(qǐng)求路徑/user/sendMsg和/user/login

?然后訪問路徑:?http://localhost:8080/front/page/login.html


/**
 * 檢查用戶是否已經(jīng)完成登錄
 * 過濾器與攔截器的區(qū)別:Filter對(duì)所有訪問進(jìn)行增強(qiáng)(在Tomcat服務(wù)器進(jìn)行配置),Interceptor僅針對(duì)SpringMVC的訪問進(jìn)行增強(qiáng)
 */
@Slf4j
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")  //urlPatterns指定攔截哪些路徑
public class LoginCheckFilter implements Filter {

    //  此對(duì)象的作用:路徑匹配器,  匹配路徑時(shí)支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//      servletRequest向下強(qiáng)制類型轉(zhuǎn)換
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;


        //1. 獲取本次請(qǐng)求的URI( URI:請(qǐng)求的資源路徑)
        String requestURI = request.getRequestURI();

        log.info("攔截到請(qǐng)求:{}", request.getRequestURI());
        // 定義不用處理的請(qǐng)求路徑
        String[] urls = new String[]{
                "/employee/login",
                "/employee/logout",
                "/backend/**",
                "/front/**",
                "/common/**",
                "/user/sendMsg",
                "/user/login"
        };

        //2. 判斷本次請(qǐng)求是否需要處理(因?yàn)橛行┱?qǐng)求并不需要用戶登錄)
        boolean check = check(requestURI, urls);

        //3.如果不需要處理,則直接放行
        if (check) {
            log.info("本次請(qǐng)求{}不需要處理", request.getRequestURI());
            filterChain.doFilter(request, response);
            return;
        }

        //4-1.判斷登錄狀態(tài),如果已登錄,則直接放行.從session中獲取用戶,如果獲取到說明已經(jīng)登錄
        if (request.getSession().getAttribute("employee") != null) {
            log.info("用戶已登錄,用戶id為{}", request.getSession().getAttribute("employee"));

            Long empId = (Long) request.getSession().getAttribute("employee");
            BaseContext.setCurrentId(empId);

            filterChain.doFilter(request, response);
            return;
        }

        //4-2.判斷登錄狀態(tài),如果已登錄,則直接放行.從session中獲取用戶,如果獲取到說明已經(jīng)登錄
        if (request.getSession().getAttribute("user") != null) {
            log.info("用戶已登錄,用戶id為{}", request.getSession().getAttribute("user"));

            Long userId = (Long) request.getSession().getAttribute("user");
            BaseContext.setCurrentId(userId);

            filterChain.doFilter(request, response);
            return;
        }

        //5.如果未登錄則返回未登錄結(jié)果
        log.info("資源路徑路徑:{},用戶未登錄{}", request.getRequestURI(), request.getSession().getAttribute("employee"));
//           通過輸出流的方式向客戶端響應(yīng)數(shù)據(jù)   (為什么要返回這個(gè)NOTLOGIN?  因?yàn)榍岸诵枰@個(gè)來(lái)進(jìn)行判定是否登錄)
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
//        filterChain.doFilter(request, response);  加上這個(gè)就無(wú)法實(shí)現(xiàn)

    }

    /**
     * 檢查本次請(qǐng)求是否需要放行
     *
     * @param requestURI 請(qǐng)求的資源路徑
     * @param urls       放過的路徑
     * @return true 放行
     */
    public boolean check(String requestURI, String[] urls) {
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            if (match) {
//           放行
                return true;
            }
        }
        return false;
    }
}

1.2.3? ?隨機(jī)生成驗(yàn)證碼的工具類

/**
 * 隨機(jī)生成驗(yàn)證碼工具類
 */
public class ValidateCodeUtils {
    /**
     * 隨機(jī)生成驗(yàn)證碼
     * @param length 長(zhǎng)度為4位或者6位
     * @return
     */
    public static Integer generateValidateCode(int length){
        Integer code =null;

//      長(zhǎng)度為4
        if(length == 4){
            code = new Random().nextInt(9999);//生成隨機(jī)數(shù),最大為9999
            if(code < 1000){
                code = code + 1000;//保證隨機(jī)數(shù)為4位數(shù)字
            }

//      長(zhǎng)度為6
        }else if(length == 6){
            code = new Random().nextInt(999999);//生成隨機(jī)數(shù),最大為999999
            if(code < 100000){
                code = code + 100000;//保證隨機(jī)數(shù)為6位數(shù)字
            }
//       其他情況
        }else{
            throw new RuntimeException("只能生成4位或6位數(shù)字驗(yàn)證碼");
        }
        return code;
    }

    /**
     * 隨機(jī)生成指定長(zhǎng)度字符串驗(yàn)證碼
     * @param length 長(zhǎng)度
     * @return
     */
    public static String generateValidateCode4String(int length){
        Random rdm = new Random();
        String hash1 = Integer.toHexString(rdm.nextInt());
        String capstr = hash1.substring(0, length);
        return capstr;
    }
}

1.2.4?手機(jī)驗(yàn)證碼登錄-- 發(fā)送驗(yàn)證碼

兩次ajax請(qǐng)求:

? ?1. 登錄頁(yè)面輸入手機(jī)號(hào),點(diǎn)擊【獲取驗(yàn)證碼】按鈕,頁(yè)面發(fā)送ajax請(qǐng)求,在服務(wù)端調(diào)用短信服務(wù)API給指定手機(jī)號(hào)發(fā)送驗(yàn)證碼短信

? ?2. 在登錄頁(yè)面輸入驗(yàn)證碼,點(diǎn)擊【登錄】按鈕,發(fā)送ajax請(qǐng)求,在服務(wù)端處理登錄請(qǐng)求文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-421301.html

    @PostMapping("/sendMsg")
    public R<String> sendMsg(@RequestBody User user, HttpSession session){
//      1.獲取手機(jī)號(hào)
        String phone = user.getPhone();

        if(StringUtils.isEmpty(phone)){
            return R.error("短信發(fā)送失敗");
        }
//      2.隨機(jī)生成四位驗(yàn)證碼
        String code = ValidateCodeUtils.generateValidateCode(4).toString();

//      3.調(diào)用阿里云提供的短信服務(wù)
        SMSUtils.sendMessage("張靖奇","",phone,code);

//      4.需要將生成的驗(yàn)證碼保存到session中
         session.setAttribute(phone,code);

        return R.success("驗(yàn)證碼短信發(fā)送成功");
    }

1.2.5?手機(jī)驗(yàn)證碼登錄-- 驗(yàn)證驗(yàn)證碼

    //  其實(shí)傳過來(lái)的phone:xxxx,code:xxx 也可以用map集合接收
    @PostMapping("/login")
    public R<User> login(@RequestBody Map map, HttpSession session) {
        log.info(map.toString());

//      1. 獲取手機(jī)號(hào)
        String phone = map.get("phone").toString();

//      2. 獲取驗(yàn)證碼
        String code = map.get("code").toString();

//      3. 從Session中獲取保存的驗(yàn)證碼
        Object codeInSession = session.getAttribute(phone);

//      4. 進(jìn)行驗(yàn)證碼比對(duì)(頁(yè)面提交的驗(yàn)證碼和Session中保存的驗(yàn)證碼比對(duì))
        if (codeInSession != null && codeInSession.equals(code)) {
//          5.對(duì)比成功,說明登錄成功

            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getPhone,phone);
            User user = userService.getOne(queryWrapper);
            if (user==null){
//          6. 如果新用戶,自動(dòng)注冊(cè)
                user = new User();
                user.setPhone(phone);
                user.setStatus(1);
               userService.save(user);
            }
            session.setAttribute("user",user.getId());
            return R.success(user);
        }

        return R.error("登錄失敗");
    }

到了這里,關(guān)于SpringBoot——短信發(fā)送、手機(jī)驗(yàn)證碼登錄的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 騰訊云短信服務(wù)實(shí)現(xiàn) Java 發(fā)送手機(jī)驗(yàn)證碼(SpringBoot+Redis 實(shí)現(xiàn))

    騰訊云短信服務(wù)實(shí)現(xiàn) Java 發(fā)送手機(jī)驗(yàn)證碼(SpringBoot+Redis 實(shí)現(xiàn))

    前置:需要騰訊云的賬號(hào),后期授權(quán)需要,不需要買云服務(wù)器,有需要的可以購(gòu)買短信套餐(幾塊錢) 搜索框輸入短信,可以買一個(gè)短信套餐包,便宜不貴,進(jìn)入短信服務(wù)的控制臺(tái) 發(fā)送短信有頻率限制,企業(yè)用戶可以修改設(shè)置 之后我們需要對(duì)短信內(nèi)容進(jìn)行設(shè)置 ?? ??類型有網(wǎng)站

    2024年02月09日
    瀏覽(25)
  • 引入短信服務(wù)發(fā)送手機(jī)驗(yàn)證碼進(jìn)行安全校驗(yàn)

    引入短信服務(wù)發(fā)送手機(jī)驗(yàn)證碼進(jìn)行安全校驗(yàn)

    其他方案=引入QQ郵箱發(fā)送驗(yàn)證碼進(jìn)行安全校驗(yàn) 相對(duì)短信驗(yàn)證碼,操作更簡(jiǎn)單而且免費(fèi) 最近想給自己的項(xiàng)目在注冊(cè)時(shí)加點(diǎn)安全校驗(yàn),準(zhǔn)備使用免費(fèi)的郵箱驗(yàn)證來(lái)著,在上一篇引入QQ郵箱進(jìn)行安全校驗(yàn)時(shí),看有朋友說阿里云會(huì)送一些短信服務(wù)免費(fèi)額度,于是去官網(wǎng)一看,果然送了

    2024年02月04日
    瀏覽(20)
  • 如何通過騰訊云短信實(shí)現(xiàn)發(fā)送驗(yàn)證碼并校驗(yàn)驗(yàn)證碼以實(shí)現(xiàn)登錄功能

    驗(yàn)證碼相關(guān)的10種技術(shù) 圖像處理技術(shù):生成、識(shí)別、驗(yàn)證驗(yàn)證碼的圖像。 機(jī)器學(xué)習(xí)技術(shù):讓計(jì)算機(jī)自動(dòng)學(xué)習(xí)并識(shí)別驗(yàn)證碼。 文字識(shí)別技術(shù):將圖像中的文字轉(zhuǎn)換成計(jì)算機(jī)可讀的文本。 模式識(shí)別技術(shù):識(shí)別驗(yàn)證碼中的模式及規(guī)律。 圖像噪聲處理技術(shù):去除圖像中的噪聲干擾。

    2024年02月10日
    瀏覽(17)
  • 【Springboot】| 阿里云發(fā)送短信驗(yàn)證碼,你會(huì)了嗎?

    【Springboot】| 阿里云發(fā)送短信驗(yàn)證碼,你會(huì)了嗎?

    專欄 名字 ??Elasticsearch專欄 es ??spring專欄 spring開發(fā) redis專欄 redis學(xué)習(xí)筆記 ??項(xiàng)目專欄 項(xiàng)目集錦 修bug專欄 bug修理廠 獅子之前發(fā)了一篇《郵箱發(fā)送驗(yàn)證碼,你會(huì)了嗎?》,很快上了熱度榜單,但是那篇文章只是簡(jiǎn)單介紹了如何接收驗(yàn)證碼的流程以及安利了一個(gè)接收驗(yàn)證碼的

    2024年02月08日
    瀏覽(16)
  • 【Redis】2、Redis應(yīng)用之【根據(jù) Session 和 Redis 進(jìn)行登錄校驗(yàn)和發(fā)送短信驗(yàn)證碼】

    【Redis】2、Redis應(yīng)用之【根據(jù) Session 和 Redis 進(jìn)行登錄校驗(yàn)和發(fā)送短信驗(yàn)證碼】

    ?? 文章基于 B 站黑馬程序員視頻教程編寫 ?? 做筆記便于日后復(fù)習(xí) ① 手機(jī)號(hào)格式后端校驗(yàn) 手機(jī)號(hào)校驗(yàn)的正則表達(dá)式 校驗(yàn)工具類: ② 生成短信驗(yàn)證碼 ?? hutool 工具的詳細(xì)使用: https://doc.hutool.cn/pages/index/ ?? 根據(jù) Cookie 中的 JSESSIONID 獲取到 Session ?? 然后從 Session 中獲取到

    2024年02月11日
    瀏覽(29)
  • 前端Vue自定義發(fā)送短信驗(yàn)證碼彈框popup 實(shí)現(xiàn)剩余秒數(shù)計(jì)數(shù) 重發(fā)短信驗(yàn)證碼

    前端Vue自定義發(fā)送短信驗(yàn)證碼彈框popup 實(shí)現(xiàn)剩余秒數(shù)計(jì)數(shù) 重發(fā)短信驗(yàn)證碼

    前端Vue自定義發(fā)送短信驗(yàn)證碼彈框popup 實(shí)現(xiàn)剩余秒數(shù)計(jì)數(shù) 重發(fā)短信驗(yàn)證碼, 閱讀全文下載完整代碼請(qǐng)關(guān)注微信公眾號(hào): 前端組件開發(fā) 效果圖如下: 實(shí)現(xiàn)代碼如下: 使用方法 HTML代碼實(shí)現(xiàn)部分 組件實(shí)現(xiàn)代碼

    2024年02月11日
    瀏覽(18)
  • 最近項(xiàng)目上需要發(fā)送短信整理了一篇文章 SpringBoot整合阿里云發(fā)送短信

    最近項(xiàng)目上需要發(fā)送短信整理了一篇文章 SpringBoot整合阿里云發(fā)送短信

    阿里云短信服務(wù)網(wǎng)址:阿里云登錄 - 歡迎登錄阿里云,安全穩(wěn)定的云計(jì)算服務(wù)平臺(tái) 第一步:申請(qǐng)簽名(一般申請(qǐng)時(shí)長(zhǎng)在1-2小時(shí)之間)特別注意:場(chǎng)景說明不要亂填以免申請(qǐng)不通過 ?第二步:申請(qǐng)短信模板(一般申請(qǐng)時(shí)長(zhǎng)在1-2小時(shí)之間)特別注意:場(chǎng)景說明不要亂填以免申請(qǐng)不

    2024年02月06日
    瀏覽(14)
  • 如何通過python來(lái)給手機(jī)發(fā)送一條短信?

    要通過Python發(fā)送短信到手機(jī),您可以使用不同的短信服務(wù)提供商的API。以下是一個(gè)使用Twilio和Sinch服務(wù)提供商的示例,您可以根據(jù)自己的選擇來(lái)決定使用哪個(gè)。 使用Twilio發(fā)送短信: 首先,注冊(cè)一個(gè)Twilio賬戶并獲取您的賬戶SID、認(rèn)證令牌和Twilio號(hào)碼。 安裝 twilio 包,如果您還沒

    2024年02月12日
    瀏覽(20)
  • 項(xiàng)目7:(aliyun)實(shí)現(xiàn)短信的發(fā)送和驗(yàn)證微服務(wù)和上傳文件刪除文件微服務(wù)

    項(xiàng)目7:(aliyun)實(shí)現(xiàn)短信的發(fā)送和驗(yàn)證微服務(wù)和上傳文件刪除文件微服務(wù)

    ①gulimall-common和service-base放什么? gulimall-common寫全局用的工具包 全局異常處理 全局返回值 工具包(生成隨機(jī)數(shù),校驗(yàn)手機(jī)號(hào)) service-base寫服務(wù)的配置 redis配置類序列化的方式 swagger文檔生成分組 ②生成四位或六位隨機(jī)數(shù) ③校驗(yàn)手機(jī)號(hào)碼正確 ④補(bǔ)充錯(cuò)誤代碼-501阿里云響應(yīng)失

    2023年04月19日
    瀏覽(27)
  • springboot整合阿里大于并結(jié)合mq發(fā)送短信

    在 pom.xml 文件中添加以下依賴: 在 application.properties 文件中添加以下配置: 其中, accessKeyId 和 accessKeySecret 是阿里云控制臺(tái)上的AccessKey, signName 是短信簽名, templateCode 是短信模板ID。 在Spring Boot中,我們可以使用MQ來(lái)異步發(fā)送短信,提高系統(tǒng)的響應(yīng)速度。這里以ActiveMQ為例

    2024年02月08日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包