IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> 微信公众号小程序开发公共类 -> 正文阅读

[开发工具]微信公众号小程序开发公共类

签名工具类,?


import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;

import java.security.MessageDigest;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @Author 
 * @Date 2020/7/30
 * @Description: 生成签名
 */
public class PublicWXUtil {

    private PublicWXUtil() {
    }

    private static final String publicappId = "xxxxxx";
    private static final String publicAppSecret = "xxxxxxxx";
    private static final String getAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
    private static final String getAccessToken_grant_type = "client_credential";
    private static final String getTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";


    public static String getAccessToken() {
        Map<String, String> param = new LinkedHashMap<>();
        param.put("appid", publicappId);
        param.put("secret", publicAppSecret);
        param.put("grant_type", getAccessToken_grant_type);
        String response = SendSignHttpsClient.doGet(getAccessTokenUrl, param);
        return JSONObject.parseObject(response).get("access_token").toString();
    }


    public static String getTicket() {
        String token = getAccessToken();
        Map<String, String> param = new LinkedHashMap<>();
        param.put("access_token", token);
        param.put("type", "jsapi");
        String response = SendSignHttpsClient.doGet(getTicketUrl, param);
        return JSONObject.parseObject(response).get("ticket").toString();
    }

    public static String signature(String url) throws Exception {
        Map<String, String> param = new LinkedHashMap<>();
        param.put("jsapi_ticket", getTicket());
        param.put("noncestr", UUID.randomUUID().toString());
        param.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        if (StringUtils.isNotEmpty(url)) {
            param.put("url", url);
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (String key : param.keySet()) {
            stringBuilder.append(key + "=" + param.get(key) + "&");
        }
        String string1 = stringBuilder.toString().substring(0, stringBuilder.toString().length() - 1);
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        //对接后的字符串进行sha1加密
        byte[] digest = md.digest(string1.toString().getBytes());
        return byteToStr(digest).toLowerCase();
    }

    /**
     * 将字节数组转化我16进制字符串
     *
     * @param byteArrays 字符数组
     * @return 字符串
     */
    private static String byteToStr(byte[] byteArrays) {
        String str = "";
        for (int i = 0; i < byteArrays.length; i++) {
            str += byteToHexStr(byteArrays[i]);
        }
        return str;
    }


    /**
     * 将字节转化为十六进制字符串
     *
     * @param myByte 字节
     * @return 字符串
     */
    private static String byteToHexStr(byte myByte) {
        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        char[] tampArr = new char[2];
        tampArr[0] = Digit[(myByte >>> 4) & 0X0F];
        tampArr[1] = Digit[myByte & 0X0F];
        String str = new String(tampArr);
        return str;
    }
}

小程序公共类,

package com.ehousechina.cric.region.product.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ehousechina.cric.region.api.product.common.dto.UnlimitedDto;
import org.apache.commons.codec.binary.Base64;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Author 
 * @Date 2020/7/30
 * @Description: TODO
 */
public class MiniProgramUtil {

    private MiniProgramUtil() {
    }

    public static final String pagepath = "pages/index/index?scene=f:s-";
    public static final String appId = "xxxxx";
    private static final String appSecret = "xxxxxxxx";
    private static final String code2SessionUrl = "https://api.weixin.qq.com/sns/jscode2session";
    private static final String getAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
    private static final String getUnlimitedUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit";
    private static final String code2Session_grant_type = "authorization_code";
    private static final String getAccessToken_grant_type = "client_credential";


    public static JSONObject code2Session(String js_code) {
        Map<String, String> param = new LinkedHashMap<>();
        param.put("appid", appId);
        param.put("secret", appSecret);
        param.put("js_code", js_code);
        param.put("grant_type", code2Session_grant_type);
        String response = SendSignHttpsClient.doGet(code2SessionUrl, param);
        return JSONObject.parseObject(response);
    }

    public static String getAccessToken() {
        Map<String, String> param = new LinkedHashMap<>();
        param.put("appid", appId);
        param.put("secret", appSecret);
        param.put("grant_type", getAccessToken_grant_type);
        String response = SendSignHttpsClient.doGet(getAccessTokenUrl, param);
        return JSONObject.parseObject(response).get("access_token").toString();
    }

    public static String getUnlimited(UnlimitedDto unlimitedDto) {
        Map<String, Object> param = new LinkedHashMap<>();
        param.put("scene", unlimitedDto.getScene());
        param.put("page", unlimitedDto.getPage());
        param.put("width", "280");
        param.put("auto_color", unlimitedDto.getAuto_color());
        param.put("line_color", unlimitedDto.getLine_color());
        unlimitedDto.setIs_hyaline(true);
        param.put("is_hyaline", unlimitedDto.getIs_hyaline());
        byte[] response = SendSignHttpsClient.post(getUnlimitedUrl + "?access_token=" + getAccessToken(), JSON.toJSONString(param));
        return Base64.encodeBase64String(response);
    }


}

微信公众号开发工具类,

package com.ehousechina.cric.region.product.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ehousechina.cric.region.api.product.common.dto.MiniprogramParams;
import com.ehousechina.cric.region.api.product.common.dto.TemplateSendDto;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author 
 * @Date 2020/7/30
 * @Description: TODO
 */
public class PublicWXUtil {

    private PublicWXUtil() {
    }

    private static final String publicappId = "xxxxxxxx";
    private static final String publicAppSecret = "xxxxxx";
    private static final String getAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
    private static final String getAccessToken_grant_type = "client_credential";
    private static final String getPublicUserInfoUrl = "https://api.weixin.qq.com/cgi-bin/user/info";
    private static final String getPublicOpenIdUrl = "https://api.weixin.qq.com/cgi-bin/user/get";
    private static final String templateSendUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send";

    public static String getAccessToken() {
        Map<String, String> param = new LinkedHashMap<>();
        param.put("appid", publicappId);
        param.put("secret", publicAppSecret);
        param.put("grant_type", getAccessToken_grant_type);
        String response = SendSignHttpsClient.doGet(getAccessTokenUrl, param);
        return JSONObject.parseObject(response).get("access_token").toString();
    }

    /**
     * 公众号获取用户基本信息
     *
     * @param openid
     * @return
     */
    public static String getUserInfo(String openid) {
        Map<String, String> param = new LinkedHashMap<>();
        param.put("access_token", getAccessToken());
        param.put("openid", openid);
        param.put("lang", "zh_CN");
        String response = SendSignHttpsClient.doGet(getPublicUserInfoUrl, param);
        return response;
    }

    /**
     * 获取微信公众号关注列表的openid
     *
     * @param next_openid
     * @return
     */
    public static String getPublicOpenId(String next_openid) {
        Map<String, String> param = new LinkedHashMap<>();
        param.put("access_token", getAccessToken());
        param.put("next_openid", next_openid);
        String response = SendSignHttpsClient.doGet(getPublicOpenIdUrl, param);
        return response;
    }

    public static String templateSend(TemplateSendDto templateSendDto) {
        String response = SendSignHttpsClient.doPostJson(templateSendUrl + "?access_token=" + getAccessToken(), JSON.toJSONString(templateSendDto));
        return response;
    }

    public static TemplateSendDto getTemplateSendDto(String sharekey, String passWord, String openid, String templateId, List<String> keywords) {
        TemplateSendDto templateSendDto = new TemplateSendDto();
        MiniprogramParams params = new MiniprogramParams();
        params.setAppid(MiniProgramUtil.appId);
        params.setPagepath(MiniProgramUtil.pagepath + "k:" + sharekey + "-p:" + passWord + "");
        templateSendDto.setMiniprogram(params);
        templateSendDto.setTouser(openid);
        templateSendDto.setTemplate_id(templateId);
        JSONObject dataJson = new JSONObject();

        JSONObject firstParam = new JSONObject();
        firstParam.put("value", keywords.get(0));
        dataJson.put("first", firstParam);

        JSONObject keyword1Param = new JSONObject();
        keyword1Param.put("value", keywords.get(1));
        dataJson.put("keyword2", keyword1Param);

        JSONObject keyword2Param = new JSONObject();
        keyword2Param.put("value", keywords.get(2));
        dataJson.put("keyword2", keyword2Param);

        JSONObject keyword3Param = new JSONObject();
        keyword3Param.put("value", keywords.get(3));
        dataJson.put("keyword3", keyword3Param);

        JSONObject keyword4Param = new JSONObject();
        keyword4Param.put("value", keywords.get(4));
        dataJson.put("keyword4", keyword4Param);

        JSONObject paramRemark = new JSONObject();
        paramRemark.put("value", keywords.get(5));
        dataJson.put("remark", paramRemark);

        templateSendDto.setData(dataJson);
        return templateSendDto;
    }

    public static JSONObject doGetJson(String url) throws Exception, IOException {
        JSONObject jsonObject = null;
        //初始化httpClient
        DefaultHttpClient client = new DefaultHttpClient();
        //用Get方式进行提交
        HttpGet httpGet = new HttpGet(url);
        //发送请求
        HttpResponse response = client.execute(httpGet);
        //获取数据
        HttpEntity entity = response.getEntity();
        //格式转换
        if (entity != null) {
            String result = EntityUtils.toString(entity, "UTF-8");
            jsonObject = JSONObject.parseObject(result);
        }
        //释放链接
        httpGet.releaseConnection();
        return jsonObject;
    }
}

?

?http请求工具类,

package com.ehousechina.cric.region.product.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * 调用的是接口
 */

public class SendSignHttpsClient {


    /**
     * post请求以及参数是json
     *
     * @param url
     * @param jsonParams
     * @return
     */
    public static JSONObject doPostForJson(String url, String jsonParams) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        JSONObject jsonObject = null;
        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().
                setConnectTimeout(180 * 1000).setConnectionRequestTimeout(180 * 1000)
                .setSocketTimeout(180 * 1000).setRedirectsEnabled(true).build();
        httpPost.setConfig(requestConfig);
        httpPost.setHeader("Content-Type", "application/json");
        try {
            httpPost.setEntity(new StringEntity(jsonParams, ContentType.create("application/json", "utf-8")));
            System.out.println("request parameters" + EntityUtils.toString(httpPost.getEntity()));
            System.out.println("httpPost:" + httpPost);
            HttpResponse response = httpClient.execute(httpPost);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                String result = EntityUtils.toString(response.getEntity());
                System.out.println("result:" + result);
                jsonObject = JSONObject.parseObject(result);
                return jsonObject;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return jsonObject;
        }
    }


    public static String doGet(String url, Map<String, String> param) {

        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();

            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);

            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    public static String doGet(String url) {
        return doGet(url, null);
    }

    public static String doPost(String url, Map<String, String> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList,"utf-8");
                httpPost.setEntity(entity);
            }
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        return resultString;
    }

    public static String doPost(String url) {
        return doPost(url, null);
    }

    public static String doPostJson(String url, String json) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        return resultString;
    }

    /* 发送 post请求 用HTTPclient 发送请求*/
    public static byte[] post(String URL, String json) {
        InputStream inputStream = null;
        byte[] data = null;
        // 创建默认的httpClient实例.
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建httppost
        HttpPost httppost = new HttpPost(URL);
        httppost.addHeader("Content-type", "application/json; charset=utf-8");
        httppost.setHeader("Accept", "application/json");
        try {
            StringEntity s = new StringEntity(json, Charset.forName("UTF-8"));
            s.setContentEncoding("UTF-8");
            httppost.setEntity(s);
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                // 获取相应实体
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    inputStream = entity.getContent();
                    data = readInputStream(inputStream);
                }
                return data;
            } finally {
                response.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接,释放资源
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return data;
    }

    /**  将流 保存为数据数组
     * @param inStream
     * @return
     * @throws Exception
     */
    public static byte[] readInputStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        // 创建一个Buffer字符串
        byte[] buffer = new byte[1024];
        // 每次读取的字符串长度,如果为-1,代表全部读取完毕
        int len = 0;
        // 使用一个输入流从buffer里把数据读取出来
        while ((len = inStream.read(buffer)) != -1) {
            // 用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
            outStream.write(buffer, 0, len);
        }
        // 关闭输入流
        inStream.close();
        // 把outStream里的数据写入内存
        return outStream.toByteArray();
    }
}

微信网页授权工具类,

package com.ehousechina.cric.region.core.controller.wx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ehousechina.cric.region.core.util.SendSignHttpsClient;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 微信网页授权公共类
 */
public class SignUtil {

    private static String token = "xxxx";// 与微信公众号上的token一致,是服务器令牌(token),这里写什么。服务器就填什么

    private static final String publicappId = "xxxxx";
    private static final String publicAppSecret = "xxxxx";
    private static final String getAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
    private static final String getAccessToken_grant_type = "authorization_code";

    private static final String refreshTokenUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token";
    private static final String snsapiUserinfoUrl = "https://api.weixin.qq.com/sns/userinfo";
    private static final String fei_shu_url = "xxxxxx";


    /**
     * 校验签名
     *
     * @param signature 签名
     * @param timestamp 时间戳
     * @param nonce     随机数
     * @return 布尔值
     */
    public static boolean checkSignature(String signature, String timestamp, String nonce) {
        String checktext = null;
        if (null != signature) {
            //对ToKen,timestamp,nonce 按字典排序
            String[] paramArr = new String[]{token, timestamp, nonce};
            Arrays.sort(paramArr);
            //将排序后的结果拼成一个字符串
            String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);

            try {
                MessageDigest md = MessageDigest.getInstance("SHA-1");
                //对接后的字符串进行sha1加密
                byte[] digest = md.digest(content.toString().getBytes());
                checktext = byteToStr(digest);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }
        //将加密后的字符串与signature进行对比
        return checktext != null ? checktext.equals(signature.toUpperCase()) : false;
    }

    /**
     * 将字节数组转化我16进制字符串
     *
     * @param byteArrays 字符数组
     * @return 字符串
     */
    private static String byteToStr(byte[] byteArrays) {
        String str = "";
        for (int i = 0; i < byteArrays.length; i++) {
            str += byteToHexStr(byteArrays[i]);
        }
        return str;
    }

    /**
     * 将字节转化为十六进制字符串
     *
     * @param myByte 字节
     * @return 字符串
     */
    private static String byteToHexStr(byte myByte) {
        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        char[] tampArr = new char[2];
        tampArr[0] = Digit[(myByte >>> 4) & 0X0F];
        tampArr[1] = Digit[myByte & 0X0F];
        String str = new String(tampArr);
        return str;
    }

    public static JSONObject getAccessToken(String code) {
        Map<String, String> param = new LinkedHashMap<>();
        param.put("appid", publicappId);
        param.put("secret", publicAppSecret);
        param.put("code", code);
        param.put("grant_type", getAccessToken_grant_type);
        String response = SendSignHttpsClient.doGet(getAccessTokenUrl, param);
        return JSONObject.parseObject(response);
    }

    public static JSONObject refreshToken(String refresh_token) {
        Map<String, String> param = new LinkedHashMap<>();
        param.put("appid", publicappId);
        param.put("grant_type", "refresh_token");
        param.put("refresh_token", refresh_token);
        String response = SendSignHttpsClient.doGet(refreshTokenUrl, param);
        return JSONObject.parseObject(response);
    }

    public static JSONObject snsapiUserinfo(String access_token, String openid) {
        Map<String, String> param = new LinkedHashMap<>();
        param.put("access_token", access_token);
        param.put("openid", openid);
        param.put("lang", "zh_CN");
        String response = SendSignHttpsClient.doGet(snsapiUserinfoUrl, param);
        sendFeiShu(response);
        return JSONObject.parseObject(response);
    }

    private static void sendFeiShu(String response) {
        try {
            Map<String, Object> params = new LinkedHashMap<>();
            Map<String, Object> mapText = new LinkedHashMap<>();
            mapText.put("text", "网页授权拉取用户信息: " + response);
            params.put("msg_type", "text");
            params.put("content", mapText);
            SendSignHttpsClient.doPostForJson(fei_shu_url, JSON.toJSONString(params));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static JSONObject getUserInfo(String code) {
        JSONObject jsonObject = getAccessToken(code);
        String openid = jsonObject.get("openid").toString();
        String access_token = jsonObject.get("access_token").toString();
        return snsapiUserinfo(access_token, openid);
    }
}

?

?

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2021-08-24 15:46:13  更:2021-08-24 15:48:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/22 19:40:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码