微信扫描登录

[复制链接]
发表于 2014-2-2 21:55:19 | 显示全部楼层 |阅读模式
用户通过扫描网页提供的二维码实现登陆信息获取
- H0 [: L7 q- Y
  1. <?php
    7 h' v& T4 r+ C% t8 ?1 U( c6 T, D
  2. /**
    8 W+ \7 r; M& s( H4 Z& E
  3. *  微信公众平台PHP-SDK
    ! \+ G- P$ K9 ^, k6 W: Q8 m
  4. *  Wechatauth为非官方微信登陆API
    : o/ l) M  e" J0 e1 E* h
  5. *  用户通过扫描网页提供的二维码实现登陆信息获取, o1 J$ O+ A7 w: m4 |( u9 b
  6. *  主要实现如下功能:
    5 u: x9 y9 M& _! z
  7. *  get_login_code() 获取登陆授权码, 通过授权码才能获取二维码
    * G3 Y7 r% u) W/ T# Y6 r" d
  8. *  get_code_image($code='') 将上面获取的授权码转换为图片二维码
    7 w" t: K+ p9 m) q4 z# }# ^
  9. *  verify_code() 鉴定是否登陆成功,返回200为最终授权成功.4 k- ]4 N% s8 i, d% C1 q' e
  10. *  get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息
    # f. S( ]  z" A
  11. *  sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息) O# p4 f, s  }  i$ Y' E
  12. *  get_avatar($url) 获取用户头像图片数据9 k& V2 o6 K; u/ I1 D; J
  13. *  @author dodge <dodgepudding@gmail.com>
    + K) e9 j+ Z6 @* N, u6 I9 f! a
  14. *  @link https://github.com/dodgepudding/wechat-php-sdk
    $ a1 a4 m5 e- \; b  d& o2 r* `
  15. *  @version 1.12 Y9 u# {8 h3 a/ c) u& h
  16. *  
    : l% A8 D- U; r
  17. */
    . f; H. g* o* J7 f  k) j' w, i
  18. include "snoopy.class.php";  X, s6 E! b* Z; q; K' l
  19. class Wechatauth$ z. @4 |" e% f" ^) q  }
  20. {' B. _) q5 Q% @' {
  21.         private $cookie;' |6 D6 o1 r* E5 J
  22.         private $_cookiename;0 k$ }7 t5 e1 A+ c
  23.         private $_cookieexpired = 3600;
    # c$ \# Q9 r* v
  24.         private $_account = 'test';) r! z! A* L% a& N
  25.         private $_datapath = './data/cookie_';0 y9 d, U4 U( j! J! o
  26.         private $debug;
    ( f4 i0 [- F0 I( A, }+ e, x
  27.         private $_logcallback;
    5 \4 N: S: A1 N( b" d5 s3 e  E9 W
  28.         public $login_user; //当前登陆用户, 调用get_login_info后获取3 l3 e- K# F- G: W% F8 ~8 i
  29.         
    " o; _* _, x0 G- }/ |. l" Y
  30.         public function __construct($options)& p) m1 c6 @9 r# ~: D& L
  31.         {
    " b) ~0 h5 D8 ]6 H  ?2 B( s
  32.                 $this->_account = isset($options['account'])?$options['account']:'';
    / F8 s; V3 y  R4 |2 B* k
  33.                 $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
    $ {- S' r  M" D4 g; |. [
  34.                 $this->debug = isset($options['debug'])?$options['debug']:false;0 Q+ }1 M+ E5 C0 G+ y$ {6 }
  35.                 $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
    * W* R) J: E* V9 J& R+ a, A9 F/ h
  36.                 $this->_cookiename = $this->_datapath.$this->_account;
    , P. ^9 I0 {: U( U
  37.                 $this->getCookie($this->_cookiename);
    ! R3 s* d/ H9 K2 p5 w
  38.         }% M: a$ I# S; V0 C/ O7 s! ~
  39.         /**
      F0 @2 s( k& h9 Y9 k
  40.          * 把cookie写入缓存* R% ~$ f+ u. G9 ]  H
  41.          * @param  string $filename 缓存文件名: {0 s' v  X4 a4 ~' J" {" u! R. o  J
  42.          * @param  string $content  文件内容" ^; s0 L! \: `/ Y) a2 p0 g
  43.          * @return bool
    % v7 j2 n1 N0 P5 p0 J  A. \5 A
  44.          */! P; [7 P7 w6 g+ M9 K
  45.         public function saveCookie($filename,$content){
    * u/ w; O: K+ G# k' V
  46.                 return file_put_contents($filename,$content);
    " ~9 H% n6 X8 Q1 \5 l3 Y6 O) D
  47.         }
    6 V9 M  e5 I7 U! `" [3 r
  48. / ]5 U, F0 y- T# [6 L
  49.         /**/ g* J$ R: y, }  s% ?( s. J3 X' V
  50.          * 读取cookie缓存内容% ?+ W8 _: r+ F) A; G) ~& R
  51.          * @param  string $filename 缓存文件名) n9 H1 j' ~: |4 H4 _/ S6 f
  52.          * @return string cookie
    " t5 r  z$ I) v) ]
  53.          */9 h/ f4 q% p" {$ E( B
  54.         public function getCookie($filename){
    + A  n1 ?+ G1 U
  55.                 if (file_exists($filename)) {
    4 {- n) @7 q8 z+ t: k! F
  56.                         $mtime = filemtime($filename);
    2 q$ m: k& q8 `8 e% M$ Z" S3 q4 x
  57.                         if ($mtime<time()-$this->_cookieexpired) return false;8 M( R( [$ ~5 ?+ A0 P) J- P, S
  58.                         $data = file_get_contents($filename);
    4 ?, G2 T) Z2 p( E4 X$ Y
  59.                         if ($data) $this->cookie = $data;
    9 m) r( k) t1 d% C) A, G+ s/ ]
  60.                 }
    6 f" P  Q6 N8 }% o4 b+ S
  61.                 return $this->cookie;7 D2 H) Z" S  o# Z
  62.         }
    ) c- H: Q" l4 \+ }
  63.         9 t" g  y9 }6 }5 a7 J
  64.         /*
    7 w. K$ R! i5 Z
  65.          * 删除cookie
    . p$ C, w! h; L& [5 j5 G' X
  66.          *// {7 C! b" ]! C% s
  67.         public function deleteCookie($filename) {
    / T' e! ~5 a9 O1 ^: I3 k, p
  68.                 $this->cookie = '';0 E  {7 F. m* H7 L) `1 ?$ t# T3 a
  69.                 @unlink($filename);
    6 v0 _7 u( |$ C# w8 H6 f
  70.                 return true;  A9 @. d+ e5 |
  71.         }
    ( V) b" d+ h0 ~/ y+ U
  72.         
    2 B1 H% B' h& v) T
  73.         private function log($log){
    2 {) a# k0 V: H1 `+ Z5 x! m8 D$ ^7 b
  74.                 if ($this->debug && function_exists($this->_logcallback)) {
    * Y8 O/ W2 @5 [; k) m! E( k
  75.                         if (is_array($log)) $log = print_r($log,true);
    7 B! N; {3 h7 ?
  76.                         return call_user_func($this->_logcallback,$log);
    5 B( J( l, h  \8 I
  77.                 }7 U: u1 a- e0 B; \
  78.         }
    / `! k# I, E) E# r- D
  79.         6 ?2 m4 b3 S; a
  80.         /**
    6 r( ~* w9 m8 x3 z5 r0 H6 C! {6 R
  81.          * 获取登陆二维码对应的授权码
    , ]7 M' t: ?- v5 `
  82.          */6 p/ F  d" {( W+ A( p, S
  83.         public function get_login_code(){" Q/ C$ ]2 _- E! x$ _
  84.                 if ($this->_logincode) return $this->_logincode;, k# f8 y: Y+ o; ~/ q
  85.                 $t = time().strval(mt_rand(100,999));( U* C& d9 A: ]% \* |  `* y0 X( h
  86.                 $codeurl = 'https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_='.$t;
    0 f7 v6 g' T  |+ ?6 O
  87.                 $send_snoopy = new Snoopy;
    1 U6 k$ L0 b, N0 h# ^1 h
  88.                 $send_snoopy->fetch($codeurl);
    8 `: {& Z- P. u6 B. p0 Z0 D# U4 r
  89.                 $result = $send_snoopy->results;0 w" C# l5 h  n; t+ b! M
  90.                 if ($result) {/ d, A  P! {( i. i
  91.                         preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);
    9 F! Q1 @* b+ D, g9 W  D
  92.                         if(count($matches)>1) {
    , U0 h  }& h" A' \' x
  93.                                 $this->_logincode = $matches[1];
    + z8 Z8 p. O6 |' y. ^  c
  94.                                 $_SESSION['login_step'] = 0;3 V  y3 Q7 M" j5 N, c' ?8 c& G
  95.                                 return $this->_logincode;
    : D& T, o7 A3 V
  96.                         }) j* }5 x$ q2 Q8 J6 X
  97.                 }) W8 ~# @% {0 u1 D. |6 S9 b
  98.                 return $result;7 F" k8 \# n9 x1 }' U% t* Q
  99.         }
    5 U) k+ w$ f' C  `

  100. 0 G  M& S/ m' f2 Q9 c- n
  101.         /**
    ( V# D4 l4 ~+ Q$ }; R
  102.          * 通过授权码获取对应的二维码图片地址, q4 D3 ?$ M/ m' R
  103.          * @param string $code
    $ R$ V0 P, I" R
  104.          * @return string image url) ]% j$ M8 B* H) O
  105.          */7 o1 X* o* S3 `9 ^
  106.         public function get_code_image($code=''){
      S1 h8 o* o1 Y  |" @
  107.                 if ($code=='') $code = $this->_logincode;
    ) b$ e3 u& j- h1 O) Q6 p6 q- J
  108.                 if (!$code) return false;
    # b; |0 `& l' z) U& t
  109.                 return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';& D: ]3 k; T- R5 h5 Q
  110.         }
    3 x$ x+ Y* n9 ^: e) H
  111.         0 R2 J* c. L$ v3 j+ ^6 Y6 b
  112.         /**
    / n* C: p) A" {( j$ M6 p2 B
  113.          * 设置二维码对应的授权码
    ' o# }2 c# D- _; }" f+ }6 S
  114.          * @param string $code
    ! J" ~$ E" @3 Y$ t
  115.          * @return class $this
    * M' ]- V/ \7 ?* i/ q1 L. s% X$ ~
  116.          */; u& F- b& g* A) n7 x; J8 F: L
  117.         public  function set_login_code($code) {
    4 |* B' \* `" K4 J$ w
  118.                 $this->_logincode = $code;
    + O  {. k8 g2 g1 u
  119.                 return $this;* t, M4 T6 t( b8 H" L* c! _, A
  120.         }
    7 V1 c6 I3 n/ c+ B0 g/ W. ?
  121.         
    2 ?7 c" }. O2 m: ?' c. h9 k  G
  122.         /**/ v4 f8 A- _2 ?( U0 D
  123.          * 二维码登陆验证# w3 ~4 l1 \" F( Q! ^5 Q$ Z
  124.          *
    5 A4 m( {6 a0 Y8 L7 {7 F
  125.          * @return status:
    7 z8 v2 a  e6 y) ?5 w
  126.          * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired5 c1 M+ {# }; \0 S/ S
  127.          * 201: just scaned but not confirm6 x! Q8 ~* x0 J" }- g7 q' c
  128.          * 200: confirm then you can get user info
      Y& H! q7 h* M; l
  129.          */" c7 \9 H: D. I# Y" w
  130.         public function verify_code() {9 `5 k  J, i7 B7 t2 U! i7 c
  131.                 if (!$this->_logincode) return false;
    & a3 O& p1 k; ]: Z8 P1 t
  132.                 $t = time().strval(mt_rand(100,999));5 w% M7 [! p  g. w6 @) u
  133. 3 T% Q/ y! ^  q7 |2 G! x
  134.                         $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;% p7 l- g+ i5 \6 G/ T- G
  135.                         $send_snoopy = new Snoopy;
    / d$ F7 m5 o1 n9 s* B5 z
  136.                         $send_snoopy->referer = "https://wx.qq.com/";1 Z. @- I' M: K3 Q: t; D
  137.                         $send_snoopy->fetch($url);/ B+ c6 x  r5 s; d
  138.                         $result = $send_snoopy->results;& S4 _# t  l" ^: a. X1 l2 }* t
  139.                         $this->log('step1:'.$result);, }6 B5 g" D, f
  140.                         if ($result) {8 o  ^% r( v) g: b: S9 c% ~
  141.                                 preg_match("/window\.code=(\d+)/",$result,$matches);3 l! [8 ^4 S! b+ {! Q
  142.                                 if(count($matches)>1) {
    $ ?6 m1 u1 Z6 e! `! g
  143.                                         $status = intval($matches[1]);( O. E# K# r4 V) C8 Q7 t8 O
  144.                                         if ($status==201) $_SESSION['login_step'] = 1;
    7 C7 G# [1 a& J0 h: m  B  A  P
  145.                                         if ($status==200) {  l( i' T* d7 m& j) ?" o3 o" ~
  146.                                                 preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);. W# I% N  I8 Z4 B) t" J8 b
  147.                                                 $this->log('step2:'.print_r($matches,true));
    ) ~0 k1 n4 K0 a0 q
  148.                                                 if (count($matches)>1) {
    1 J/ B9 C  `! {- C8 o
  149.                                                         $ticket = $matches[1];
    ' F# N6 k8 ?, I
  150.                                                         $scan = $matches[2];" @) y+ g, ^4 q9 i6 m
  151.                                                         $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';' K. Y5 f+ s: R3 U
  152.                                                         $send_snoopy = new Snoopy;
    " T. ?* q  G7 A1 p1 N: W
  153.                                                         $send_snoopy->referer = "https://wx.qq.com/";
    % X$ s: e* n" o0 @
  154.                                                         $send_snoopy->fetch($loginurl);2 q' `6 T2 e% o/ y
  155.                                                         $this->log('step3:'.print_r($send_snoopy->headers,true));% h. X7 A& U- W2 o$ K
  156.                                                         foreach ($send_snoopy->headers as $key => $value) {
    6 `! d( a* T' H* V* }
  157.                                                                 $value = trim($value);& {# j) j1 u3 m" I
  158.                                                                 if(strpos($value,'Set-Cookie: ') !== false){
    & \- M) t$ h, H! {! |: V+ o/ {
  159.                                                                         $tmp = str_replace("Set-Cookie: ","",$value);
    - L# D$ a1 Q: B$ c
  160.                                                                         $tmp = str_replace("Path=/","",$tmp);1 X, F2 a' P1 {* r4 [  P
  161.                                                                         $tmp = str_replace("Domain=.qq.com; ","",$tmp);# F; I1 i" W+ V$ q  r, W
  162.                                                                         $cookie.=$tmp;' R4 \$ f: i* a- n" R6 Z- k
  163.                                                                 }
    $ v) n7 z$ M9 c9 K+ Y
  164.                                                         }
    3 Y$ A4 r; X& @  z. c1 o. Q
  165.                                                         $cookie .="Domain=.qq.com;";5 f( l5 g6 R* x2 d2 a' K0 b! N6 f
  166.                                                         $this->cookie = $cookie;
    / X* Q: j; f0 ~! i( S' e
  167.                                                         $this->saveCookie($this->_cookiename,$this->cookie);
    * n4 p2 a6 Q( T7 s5 b  `( y  c& U
  168.                                                 }* g, u+ Y* J# `6 R& j
  169.                                         }
    1 G7 U$ Y7 |/ J6 S
  170.                                         return $status;
    4 H9 {6 Y1 `5 t. H
  171.                                 }4 _' L$ N# a4 ~' K
  172.                         }$ O- |5 J, Z. C9 |) [+ L
  173.                 return false;" i& k( Y8 J$ v# h. F
  174.         }
    9 f! X8 Y/ b/ e0 _# \* c
  175.         
    & K  {" {& L. B4 i+ N
  176.         /**
    + U1 l$ r3 ^) J, D0 _
  177.          * 获取登陆的cookie
      L) I( \# T0 g5 z+ U- J" N" r
  178.          *6 M" r& D7 O" J0 i* p+ L" O/ L/ o1 |
  179.          * @param bool $is_array 是否以数值方式返回,默认否,返回字符串  s: `) q; T% N  q6 ]# Z
  180.          * @return string|array3 @( q, R1 \  c- N9 y4 M
  181.          */; [  z1 x) \, C& l
  182.         public function get_login_cookie($is_array = false){, f1 P( G! P5 F% Q
  183.                 if (!$is_array)        return $this->cookie;
    & Z% z$ j8 g1 W$ G! m
  184.                 $c_arr = explode(';',$this->cookie);/ C( F0 C4 j: H1 i0 o
  185.                 $cookie = array();
    4 L* Q9 m6 V+ r& A2 z$ y2 V
  186.                 foreach($c_arr as $item) {
    1 u" |, o0 q6 c5 |* _
  187.                         $kitem = explode('=',trim($item));
    . I! d, P1 M1 m" u% V6 r/ A" b7 {9 @
  188.                         if (count($kitem)>1) {) k: M  Z! Q5 \& g% O+ f
  189.                                 $key = trim($kitem[0]);
    # m' q; D6 }2 v0 i
  190.                                 $val = trim($kitem[1]);
    / y8 y5 T1 C- u
  191.                                 if (!empty($val)) $cookie[$key] = $val;
    4 w+ F5 A2 w  [% e0 m" J" C( _
  192.                         }' Q" Z% z% f  D7 u. _$ w' n2 m
  193.                 }, x# V% I+ c/ v2 x) R& G
  194.                 return $cookie;
    + V. A0 b* Q, U! U# G# _
  195.         }8 N+ I5 m; @$ B) ?
  196.         + M5 Z) c- [; z- h
  197.         /**9 R6 B# c' W! ]# Y( |: N
  198.          *          授权登陆后获取用户登陆信息
    8 s4 D3 ^' m+ Y/ W9 |9 |
  199.          */
      q( ~) R: R  i% M- Q
  200.         public function get_login_info(){, \, M+ e0 f7 S. K% y& }
  201.                 if (!$this->cookie) return false;
    7 z. _- ^) L4 O! v+ z
  202.                 $t = time().strval(mt_rand(100,999));
    , m% n: ]3 D* ]' A& K1 v% a0 l
  203.                 $send_snoopy = new Snoopy; 2 t6 Y# @$ X' S( L
  204.                 $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;
    ) G5 g! ?' _  W  R7 e; h6 x
  205.                 $send_snoopy->rawheaders['Cookie']= $this->cookie;
    + S" T7 A$ t% f/ A- s* Q4 V5 j
  206.                 $send_snoopy->referer = "https://wx.qq.com/";9 y9 ~' Y0 I% Z5 {) z
  207.                 $send_snoopy->submit($submit,array());
      J' N3 J2 U4 V) ?
  208.                 $this->log('login_info:'.$send_snoopy->results);* X) t1 v( A" d4 h/ v+ [! q
  209.                 $result = json_decode($send_snoopy->results,true);1 i6 x) A6 B: m& [- w
  210.                 if ($result['BaseResponse']['Ret']<0) return false;
    8 U/ M1 q' g$ m. v7 [  S! ?4 a4 k
  211.                 $this->_login_user = $result['User'];
    , |3 u9 w+ R3 Q4 n4 Y1 ?
  212.                 return $result;
    1 K6 i( f% c* Q6 q3 `: ?, q8 x9 T
  213.         }
    $ y  u4 x+ {; K6 R. `, }
  214.         4 [& B) v6 o  }, i/ P, s! \, d
  215.         /**! A' y- z$ L6 j7 t, Z6 Y
  216.          *  获取头像. ?' U9 @- S  m- U
  217.          *  @param string $url 传入从用户信息接口获取到的头像地址; ]5 q+ X* ^% \- b7 V& e* e
  218.          */
    , H' j# H: I) W( i8 B
  219.         public function get_avatar($url) {
    / q! C4 I7 }9 j1 h9 y3 A$ q6 r! G
  220.                 if (!$this->cookie) return false;: Q0 I1 b3 A6 j# P2 _+ y
  221.                 if (strpos($url, 'http')===false) {
    9 T; |# s$ D0 M/ s" V* Z
  222.                         $url = 'http://wx.qq.com'.$url;9 {" [& I" p, `" H, n" G
  223.                 }
    ) G! X, b6 V) p% I# P( ^
  224.                 $send_snoopy = new Snoopy;
      j, u4 L! D- k3 b% H  L- ?
  225.                 $send_snoopy->rawheaders['Cookie']= $this->cookie;
    - r* j2 ~! [1 j3 o+ p1 b  O+ ?% d
  226.                 $send_snoopy->referer = "https://wx.qq.com/";
    ! J7 S9 P* X# B$ w- s; _8 d
  227.                 $send_snoopy->fetch($url);  J/ Y/ |& ~9 L: J  p! ?2 r
  228.                 $result = $send_snoopy->results;
    # x, S2 {% M  e. t" M( X7 e6 p- N
  229.                 if ($result) 9 O  w$ d8 M8 a4 r5 b
  230.                         return $result;. G( I( m( \6 a7 e
  231.                 else
    6 u; ?6 v$ \% ^" h# E
  232.                         return false;& r, @- l# K5 p, m9 ~
  233.         }
      ]- {; y  _$ @
  234.         3 s" H5 J# j+ y7 P! p; a
  235.         /**
    / ~$ R& q6 u* s
  236.          * 登出当前登陆用户2 c* q1 [' G* M% I/ e, }
  237.          */6 D" i7 {9 l! I. ^
  238.         public function logout(){
    & F  h2 U9 i3 ]1 I- V
  239.                 if (!$this->cookie) return false;
    + m& e$ ]* h, C0 ]
  240.                 preg_match("/wxuin=(\w+);/",$this->cookie,$matches);6 q& D3 R9 I4 C: F/ c/ D
  241.                 if (count($matches)>1) $uid = $matches[1];; o  G3 V6 ~1 S# v8 M+ [" t$ R
  242.                 preg_match("/wxsid=(\w+);/",$this->cookie,$matches);8 M/ _; w) a' s! a. e! P6 r8 p
  243.                 if (count($matches)>1) $sid = $matches[1];
    . S! W. w& Q' |0 Y: s! n
  244.                 $this->log('logout: uid='.$uid.';sid='.$sid);
    $ z( r* p0 s% g/ g$ Z
  245.                 $send_snoopy = new Snoopy; 2 u( h: S7 W0 U
  246.                 $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
    / m& C: I0 Y6 @
  247.                 $send_snoopy->rawheaders['Cookie']= $this->cookie;
    9 O, k8 l! k" S6 N' x: W9 f& H9 q
  248.                 $send_snoopy->referer = "https://wx.qq.com/";  _. O! b) l" \' U
  249.                 $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));' s# e% W4 _$ a6 \1 e
  250.                 $this->deleteCookie($this->_cookiename);
    - D$ s. d" ?2 w4 p* Y* |  U' Z
  251.                 return true;
    0 r0 L; ?+ v( q2 T
  252.         }$ p7 J, |+ m# h( v5 _1 M
  253. }
复制代码
- y/ Y) @. m, d/ D, [8 n




上一篇:[Discuz插件] Discuz!微信登录插件配置前提
下一篇:Emacs逆袭:开发微信公众平台小游戏
回复

使用道具 举报

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

快速回复 返回顶部 返回列表