UDN-企业互联网技术人气社区

板块导航

浏览  : 1949
回复  : 2

[原生js] java开发微信分享到朋友圈功能

[复制链接]
西北的风的头像 楼主
发表于 2017-1-17 16:25:56 | 显示全部楼层 |阅读模式
  这篇文章主要为大家详细介绍了java开发微信发送给朋友和分享到朋友圈功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  微信分享功能开发
  
  用了一天时间,把微信发送给朋友和分享到朋友圈功能开发出来,在这里给大家分享一下,避免大家走弯路。
  
  一、服务器端程序
  1. package com.wiimedia.controller;


  2. import java.io.IOException;
  3. import java.security.MessageDigest;
  4. import java.security.NoSuchAlgorithmException;
  5. import java.text.ParseException;
  6. import java.text.SimpleDateFormat;
  7. import java.util.Arrays;
  8. import java.util.Date;

  9. import javax.servlet.http.HttpServletRequest;
  10. import javax.servlet.http.HttpServletResponse;

  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.stereotype.Controller;
  13. import org.springframework.web.bind.annotation.RequestMapping;

  14. import com.google.gson.Gson;
  15. import com.wiimedia.model.Ticket;
  16. import com.wiimedia.service.ArticleSolrService;
  17. import com.wiimedia.service.TicketRepository;
  18. import com.wiimedia.service.TicketRepositorySolr;
  19. import com.wiimedia.utils.GetRandomStr;
  20. import com.wiimedia.utils.SignatureBean;
  21. import com.wiimedia.utils.weixin.WeixinUtil;
  22. /**
  23. *
  24. *
  25. *<p>Project:mryl_phone_v2</p>
  26. *
  27. *<p>Package:com.wiimedia.controller</p>
  28. *
  29. *<p>Description:微信分享Controller</p>
  30. *
  31. *<p>Company:Wiimedia</p>
  32. *
  33. *@Athor:SongJia
  34. *
  35. *@Date:2016-7-15 上午09:34:10
  36. *
  37. */

  38. @Controller
  39. @RequestMapping("/WeixinshareController/API/Inteface")
  40. public class WeixinshareController {
  41. @Autowired
  42. private TicketRepositorySolr ticketRepositorySolr;

  43. @RequestMapping("/getSignature")
  44. public String getSignature( HttpServletRequest request,
  45.    HttpServletResponse response) throws IOException, ParseException{
  46.   //获取签名页面链接
  47.   String url = request.getParameter("url");
  48.   SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  49.   //从数据库中获取标签,并检查标签是否过期
  50.   Ticket oldticket = ticketRepositorySolr.getTicketById("20160114wiimediamrylsong1152");
  51.   if(oldticket==null){//第一次访问,标签不存在。
  52.    executeTicket(response,"1",url,format);
  53.    return null;
  54.   }else{//标签存在,判断标签是否超时
  55.    String oldAcquiretime = oldticket.getAcquiretime();
  56.    long difference=format.parse(format.format(new Date())).getTime()-format.parse(oldAcquiretime).getTime();
  57.    if(difference>7100000){//标签超时,重新到微信服务器请求标签超时时间为7200秒(7200000毫秒)
  58.     executeTicket(response,"2",url,format);
  59.     return null;
  60.    }else{//标签未超时
  61.     /**
  62.      * 注意事项           
  63.      * 1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
  64.      * 2.签名用的url必须是调用JS接口页面的完整URL。      
  65.      * 3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。
  66.      *
  67.      ****根据第1点要求   signature 配置的时候很容易出错,需要把生成 Ticket的 noncestr和 timestamp传给客户端***
  68.      */
  69.     String signature = signature(oldticket.getTicket(),oldticket.getTimestamp(),oldticket.getNoncestr(),url);
  70.     SignatureBean signatureBean = new SignatureBean();
  71.     signatureBean.setNoncestr(oldticket.getNoncestr());
  72.     signatureBean.setSignature(signature);
  73.     signatureBean.setTimestamp(oldticket.getTimestamp());
  74.     signatureBean.setUrl(url);
  75.     response.setContentType("text/html;charset=UTF-8");
  76.     response.getWriter().print(new Gson().toJson(signatureBean));
  77.     return null;
  78.    }
  79.   }


  80. }
  81. /**
  82.   *
  83.   *<p>Project:mryl_phone_v2</p>
  84.   *
  85.   *<p>:mryl_phone_v2</p>
  86.   *
  87.   *<p>Description:更新和获取ticket的方法,因为用的solr所以更新和新增是一样的ID无则添加,有责更新</p>
  88.   *
  89.   *<p>Company:Wiimedia</p>
  90.   *
  91.   *@Athor:SongJia
  92.   *
  93.   *@Date:2016-7-15 上午09:45:00
  94.   *
  95.   */
  96. public void executeTicket(HttpServletResponse response,String flag,String url,SimpleDateFormat format) throws IOException{

  97.   //获取签名随即字符串
  98.   GetRandomStr randomStr = new GetRandomStr();
  99.   String noncestr = randomStr.getRandomString(15);
  100.   //获取签名时间戳
  101.   String timestamp = Long.toString(System.currentTimeMillis());
  102.   //请求accessToken
  103.   String accessTokenUrl ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=您的APPID&secret=您的密匙";
  104.   String tokenJson = WeixinUtil.httpRequest(accessTokenUrl, "GET", null);
  105.   Gson gson = new Gson();
  106.   ShareAccess_Token token = gson.fromJson(tokenJson, ShareAccess_Token.class);
  107.   String to= token.getAccess_token();
  108.   //获取标签
  109.   String urlTicket ="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+to+"&type=jsapi";
  110.   String ticketJson = WeixinUtil.httpRequest(urlTicket, "GET", null);
  111.   Ticket ticket = gson.fromJson(ticketJson, Ticket.class);
  112.   String t = ticket.getTicket();
  113.   //String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
  114.   //我的Ticket ID是写死的
  115.   String acquiretime = format.format(new Date());
  116.   ticket.setTid("20160114wiimediamrylsong1152");
  117.   ticket.setAcquiretime(acquiretime);
  118.   ticket.setTimestamp(timestamp);
  119.   ticket.setNoncestr(noncestr);
  120.   //因为用的SOLR所以更新和添加的方法是一样的,可以根据自己具体需求进行修改,本文不再贴出代码.
  121.   if(flag.equals("2")){
  122.    ticketRepositorySolr.addTicketToSolr(ticket);
  123.   }else{
  124.    ticketRepositorySolr.addTicketToSolr(ticket);
  125.   }
  126.   /**
  127.    * 注意事项           
  128.    * 1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
  129.    * 2.签名用的url必须是调用JS接口页面的完整URL。      
  130.    * 3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。
  131.    *
  132.    *根据第1点要求   signature 配置的时候很容易出错,需要把生成 Ticket的 noncestr和 timestamp传给客户端*
  133.    */
  134.   String signature = signature(t,timestamp,noncestr,url);
  135.   SignatureBean signatureBean = new SignatureBean();
  136.   signatureBean.setNoncestr(noncestr);
  137.   signatureBean.setSignature(signature);
  138.   signatureBean.setTimestamp(timestamp);
  139.   signatureBean.setUrl(url);
  140.   response.setContentType("text/html;charset=UTF-8");
  141.   response.getWriter().print(new Gson().toJson(signatureBean));
  142. }

  143. /**
  144.   *
  145.   *<p>Project:mryl_phone_v2</p>
  146.   *
  147.   *<p>:mryl_phone_v2</p>
  148.   *
  149.   *<p>Description:根据标签,时间戳,密匙,URL进行签名</p>
  150.   *
  151.   *<p>Company:Wiimedia</p>
  152.   *
  153.   *@Athor:SongJia
  154.   *
  155.   *@Date:2016-7-15 上午09:37:13
  156.   *
  157.   */
  158. private String signature(String jsapi_ticket, String timestamp, String noncestr, String url) {
  159.   jsapi_ticket = "jsapi_ticket=" + jsapi_ticket;
  160.   timestamp = "timestamp=" + timestamp;
  161.   noncestr = "noncestr=" + noncestr;
  162.   url = "url=" + url;
  163.   String[] arr = new String[] { jsapi_ticket, timestamp, noncestr, url };
  164.   // 将token、timestamp、nonce,url参数进行字典序排序
  165.   Arrays.sort(arr);
  166.   StringBuilder content = new StringBuilder();
  167.   for (int i = 0; i < arr.length; i++) {
  168.    content.append(arr[i]);
  169.    if (i != arr.length - 1) {
  170.     content.append("&");
  171.    }
  172.   }
  173.   MessageDigest md = null;
  174.   String tmpStr = null;

  175.   try {
  176.    md = MessageDigest.getInstance("SHA-1");
  177.    // 将三个参数字符串拼接成一个字符串进行sha1加密
  178.    byte[] digest = md.digest(content.toString().getBytes());
  179.    tmpStr = byteToStr(digest);
  180.   } catch (NoSuchAlgorithmException e) {
  181.    e.printStackTrace();
  182.   }

  183.   content = null;
  184.   return tmpStr;
  185. }
  186. /**
  187.   * 将字节转换为十六进制字符串
  188.   *
  189.   * @param mByte
  190.   * @return
  191.   */
  192. private static String byteToHexStr(byte mByte) {

  193.   char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  194.   char[] tempArr = new char[2];
  195.   tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
  196.   tempArr[1] = Digit[mByte & 0X0F];

  197.   String s = new String(tempArr);
  198.   return s;
  199. }
  200. /**
  201.   * 将字节数组转换为十六进制字符串
  202.   *
  203.   * @param byteArray
  204.   * @return
  205.   */
  206. private static String byteToStr(byte[] byteArray) {
  207.   String strDigest = "";
  208.   for (int i = 0; i < byteArray.length; i++) {
  209.    strDigest += byteToHexStr(byteArray[i]);
  210.   }
  211.   return strDigest;
  212. }


  213. class ShareAccess_Token{
  214.   private String access_token;
  215.   private String expires_in;
  216.   public String getAccess_token() {
  217.    return access_token;
  218.   }
  219.   public void setAccess_token(String accessToken) {
  220.    access_token = accessToken;
  221.   }
  222.   public String getExpires_in() {
  223.    return expires_in;
  224.   }
  225.   public void setExpires_in(String expiresIn) {
  226.    expires_in = expiresIn;
  227.   }

  228. }
  229. }
复制代码

  二、客户端代码.
  1. <script type="text/JavaScript">
  2.    var url = window.location.href;
  3.    var articleId = "";
  4.    var shareTitle="明日医疗资讯";
  5.    var shareImgUrl="";
  6.    var userinfo = localStorage.getItem("_userinfo");
  7.    var timestamp;
  8.    var noncestr;
  9.    var signature;
  10.    //获取签名
  11.     $.ajax({
  12.       type: "GET",
  13.       url: "WeixinshareController/Api/Inteface/getSignature",
  14.       //data:{timestamp:timestamp,noncestr:noncestr,url:url},
  15.       data:{url:url},
  16.       success: function(data){
  17.         var objData=JSON.parse(data);
  18.         timestamp=objData.timestamp;
  19.         noncestr=objData.noncestr;
  20.         signature=objData.signature;
  21.          console.log(objData);
  22.          wxShare();
  23.       }
  24.      });
  25.    function wxShare(){
  26.    wx.config({
  27.     debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  28.     appId: '您的appid', // 和获取Ticke的必须一样------必填,公众号的唯一标识
  29.     timestamp:timestamp, // 必填,生成签名的时间戳
  30.     nonceStr: noncestr, // 必填,生成签名的随机串
  31.     signature: signature,// 必填,签名,见附录1
  32.     jsApiList: [
  33.     'onMenuShareAppMessage'
  34.     ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
  35.    });
  36.    }
  37.    wx.ready(function(){
  38.      //config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,
  39.      //config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关
  40.      //接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。

  41.     //----------“分享给朋友”
  42.     wx.onMenuShareAppMessage({
  43.      title: "明日医疗资讯", // 分享标题
  44.      desc: shareTitle, // 分享描述
  45.      link: url, // 分享链接
  46.      imgUrl: shareImgUrl, // 分享图标
  47.      type: '', // 分享类型,music、video或link,不填默认为link
  48.      dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
  49.      success: function () {
  50.       // 用户确认分享后执行的回调函数、
  51.      },
  52.      cancel: function () {
  53.       // 用户取消分享后执行的回调函数
  54.      }
  55.     });
  56.     //------------"分享到朋友圈"
  57.     wx.onMenuShareTimeline({
  58.      title: '明日医疗资讯', // 分享标题
  59.      link: '', // 分享链接
  60.      imgUrl: shareImgUrl, // 分享图标
  61.      success: function () {
  62.       // 用户确认分享后执行的回调函数
  63.      },
  64.      cancel: function () {
  65.       // 用户取消分享后执行的回调函数
  66.      }
  67.     });
  68.     //-------------分享到QQ
  69.     wx.onMenuShareQQ({
  70.      title: '明日医疗资讯', // 分享标题
  71.      desc: shareTitle, // 分享描述
  72.      link: '', // 分享链接
  73.      imgUrl: shareImgUrl, // 分享图标
  74.      success: function () {
  75.       // 用户确认分享后执行的回调函数
  76.      },
  77.      cancel: function () {
  78.       // 用户取消分享后执行的回调函数
  79.      }
  80.     });
  81.     //-------------分享到QQ空间
  82.     wx.onMenuShareQZone({
  83.      title: '明日医疗资讯', // 分享标题
  84.      desc: shareTitle, // 分享描述
  85.      link: '', // 分享链接
  86.      imgUrl: shareImgUrl, // 分享图标
  87.      success: function () {
  88.       // 用户确认分享后执行的回调函数
  89.      },
  90.      cancel: function () {
  91.       // 用户取消分享后执行的回调函数
  92.      }
  93.     });

  94.    });
复制代码

  三、服务器需要的工具类和Model
  
  ① Ticket
  1. package com.wiimedia.model;


  2. public class Ticket{
  3. private String tid;
  4. private String ticket;
  5. private String errcode;
  6. private String errmsg;
  7. private String expires_in;
  8. private String acquiretime;
  9. private String noncestr;
  10. private String timestamp;

  11. public Ticket(String tid, String ticket, String errcode, String errmsg,
  12.    String expiresIn, String acquiretime, String noncestr,
  13.    String timestamp) {
  14.   super();
  15.   this.tid = tid;
  16.   this.ticket = ticket;
  17.   this.errcode = errcode;
  18.   this.errmsg = errmsg;
  19.   expires_in = expiresIn;
  20.   this.acquiretime = acquiretime;
  21.   this.noncestr = noncestr;
  22.   this.timestamp = timestamp;
  23. }
  24. public String getTid() {
  25.   return tid;
  26. }
  27. public void setTid(String tid) {
  28.   this.tid = tid;
  29. }
  30. public String getTicket() {
  31.   return ticket;
  32. }
  33. public void setTicket(String ticket) {
  34.   this.ticket = ticket;
  35. }
  36. public String getErrcode() {
  37.   return errcode;
  38. }
  39. public void setErrcode(String errcode) {
  40.   this.errcode = errcode;
  41. }
  42. public String getErrmsg() {
  43.   return errmsg;
  44. }
  45. public void setErrmsg(String errmsg) {
  46.   this.errmsg = errmsg;
  47. }
  48. public String getExpires_in() {
  49.   return expires_in;
  50. }
  51. public void setExpires_in(String expiresIn) {
  52.   expires_in = expiresIn;
  53. }
  54. public String getAcquiretime() {
  55.   return acquiretime;
  56. }
  57. public void setAcquiretime(String acquiretime) {
  58.   this.acquiretime = acquiretime;
  59. }
  60. public String getNoncestr() {
  61.   return noncestr;
  62. }
  63. public void setNoncestr(String noncestr) {
  64.   this.noncestr = noncestr;
  65. }
  66. public String getTimestamp() {
  67.   return timestamp;
  68. }
  69. public void setTimestamp(String timestamp) {
  70.   this.timestamp = timestamp;
  71. }


  72. }
复制代码

  ② 添加到数据库的业务根据自己需要进行实现.
  
  ③ GetRandomStr
  1. package com.wiimedia.utils;

  2. import java.util.Random;

  3. public class GetRandomStr {
  4. /**
  5.   *
  6.   *<p>Project:mryl_phone_v2</p>
  7.   *
  8.   *<p>:mryl_phone_v2</p>
  9.   *
  10.   *<p>Description:生成随即字符串 </p>
  11.   *
  12.   *<p>Company:Wiimedia</p>
  13.   *
  14.   *@Athor:SongJia
  15.   *
  16.   *@Date:2016-7-14 上午11:14:46
  17.   *
  18.   */
  19. public String getRandomString(int length) {
  20.   String base = "abcdefghijklmnopqrstuvwxyz0123456789";
  21.   Random random = new Random();
  22.   StringBuffer sb = new StringBuffer();
  23.   for (int i = 0; i < length; i++) {
  24.    int number = random.nextInt(base.length());
  25.    sb.append(base.charAt(number));
  26.   }
  27.   return sb.toString();
  28.   }
  29. }
复制代码

  ④ SignatureBean
  1. package com.wiimedia.utils;

  2. public class SignatureBean {
  3. private String noncestr;
  4. private String url;
  5. private String timestamp;
  6. private String signature;
  7. public String getNoncestr() {
  8.   return noncestr;
  9. }
  10. public void setNoncestr(String noncestr) {
  11.   this.noncestr = noncestr;
  12. }
  13. public String getUrl() {
  14.   return url;
  15. }
  16. public void setUrl(String url) {
  17.   this.url = url;
  18. }
  19. public String getTimestamp() {
  20.   return timestamp;
  21. }
  22. public void setTimestamp(String timestamp) {
  23.   this.timestamp = timestamp;
  24. }
  25. public String getSignature() {
  26.   return signature;
  27. }
  28. public void setSignature(String signature) {
  29.   this.signature = signature;
  30. }

  31. }
复制代码

  ⑤ WeixinUtil
  1. package com.wiimedia.utils.weixin;
  2. import java.io.BufferedReader;
  3. import java.io.InputStream;
  4. import java.io.InputStreamReader;
  5. import java.io.OutputStream;
  6. import java.net.ConnectException;
  7. import java.net.URL;

  8. import javax.net.ssl.HttpsURLConnection;
  9. import javax.net.ssl.SSLContext;
  10. import javax.net.ssl.SSLSocketFactory;
  11. import javax.net.ssl.TrustManager;

  12. /**
  13.   *
  14.   *<p>Project:mryl_phone_v2</p>
  15.   *
  16.   *<p>:mryl_phone_v2</p>
  17.   *
  18.   *<p>Description:公众平台接口工具类</p>
  19.   *
  20.   *<p>Company:Wiimedia</p>
  21.   *
  22.   *@Athor:SongJia
  23.   *
  24.   *@Date:2016-7-15 上午09:37:13
  25.   *
  26.   */
  27. public class WeixinUtil {

  28. /**
  29.   * 发起https请求并获取结果
  30.   *
  31.   * @param requestUrl 请求地址
  32.   * @param requestMethod 请求方式(GET、POST)
  33.   * @param outputStr 提交的数据
  34.   * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
  35.   */
  36. public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {

  37.   StringBuffer buffer = new StringBuffer();
  38.   try {
  39.    // 创建SSLContext对象,并使用我们指定的信任管理器初始化
  40.    TrustManager[] tm = { new MyX509TrustManager() };
  41.    SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
  42.    sslContext.init(null, tm, new java.security.SecureRandom());
  43.    // 从上述SSLContext对象中得到SSLSocketFactory对象
  44.    SSLSocketFactory ssf = sslContext.getSocketFactory();

  45.    URL url = new URL(requestUrl);
  46.    HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
  47.    httpUrlConn.setSSLSocketFactory(ssf);

  48.    httpUrlConn.setDoOutput(true);
  49.    httpUrlConn.setDoInput(true);
  50.    httpUrlConn.setUseCaches(false);
  51.    // 设置请求方式(GET/POST)
  52.    httpUrlConn.setRequestMethod(requestMethod);

  53.    if ("GET".equalsIgnoreCase(requestMethod))
  54.     httpUrlConn.connect();

  55.    // 当有数据需要提交时
  56.    if (null != outputStr) {
  57.     OutputStream outputStream = httpUrlConn.getOutputStream();
  58.     // 注意编码格式,防止中文乱码
  59.     outputStream.write(outputStr.getBytes("UTF-8"));
  60.     outputStream.close();
  61.    }

  62.    // 将返回的输入流转换成字符串
  63.    InputStream inputStream = httpUrlConn.getInputStream();
  64.    InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
  65.    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

  66.    String str = null;
  67.    while ((str = bufferedReader.readLine()) != null) {
  68.     buffer.append(str);
  69.    }
  70.    bufferedReader.close();
  71.    inputStreamReader.close();
  72.    // 释放资源
  73.    inputStream.close();
  74.    inputStream = null;
  75.    httpUrlConn.disconnect();
  76.    return buffer.toString();
  77.   } catch (ConnectException ce) {
  78.    ce.printStackTrace();
  79.   } catch (Exception e) {
  80.    e.printStackTrace();
  81.   }
  82.   return "";
  83. }
  84. }
复制代码

  四、至此,分享功能已经开发完成,但是,在生成signature的时候会遇到很多问题,这里提供一些wx.config失败的排错方法。
  
  ① 确认自己的生成的signature是否正确
  
  在微信提供的http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign进行校验
  
  ② wx.config中使用的noncestr, timestamp与用以签名中的对应noncestr, timestamp是否一致一致…如上面(一.服务器代码)
  
  (有可能因为JS页面加载顺序问题,服务器生成的signature,noncestr,timestamp在wx.config中没有获取到)。
  
  ③ 确认url是页面完整的url,包括GET参数部分
  
  需要去掉#后面的部分
  
  ④ config 中的 appid 与用来获取 jsapi_ticket 的 appid 是否一致
  
  ⑤ 报错{errmsg:config:ok}是debug的正常返回把调试模式关掉就OK
  
  wx.config debug: false,
  
  以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

相关帖子

发表于 2017-1-17 16:26:32 | 显示全部楼层
LZ敢整点更有创意的不?兄弟们等着围观捏~
使用道具 举报

回复

发表于 2017-1-20 02:36:06 来自手机 | 显示全部楼层
无论是不是沙发都得回复下
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部