diff --git a/biliapi/pom.xml b/biliapi/pom.xml
new file mode 100644
index 0000000..6c77166
--- /dev/null
+++ b/biliapi/pom.xml
@@ -0,0 +1,26 @@
+
+
+ 4.0.0
+
+ com.yutou
+ bilibili
+ 0.0.1-SNAPSHOT
+
+
+ biliapi
+
+
+ 21
+ 21
+ UTF-8
+
+
+
+ io.reactivex.rxjava3
+ rxjava
+ 3.1.8
+
+
+
\ No newline at end of file
diff --git a/biliapi/src/main/java/com/yutou/bili/api/LoginApi.java b/biliapi/src/main/java/com/yutou/bili/api/LoginApi.java
new file mode 100644
index 0000000..54ecfa2
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/api/LoginApi.java
@@ -0,0 +1,18 @@
+package com.yutou.bili.api;
+
+import com.yutou.bili.bean.login.LoginInfoBean;
+import com.yutou.bili.bean.login.QRCodeGenerateBean;
+import com.yutou.okhttp.HttpBody;
+import retrofit2.Call;
+import retrofit2.http.GET;
+import retrofit2.http.Query;
+
+public interface LoginApi {
+ @GET("/x/passport-login/web/qrcode/generate")
+ Call> getQRCodeGenerate();
+
+ @GET("/x/passport-login/web/qrcode/poll")
+ Call> loginQRCode(@Query("qrcode_key") String qrcode_key);
+
+
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/api/UserApi.java b/biliapi/src/main/java/com/yutou/bili/api/UserApi.java
new file mode 100644
index 0000000..20440e4
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/api/UserApi.java
@@ -0,0 +1,11 @@
+package com.yutou.bili.api;
+
+import com.yutou.bili.bean.login.UserInfoBean;
+import com.yutou.okhttp.HttpBody;
+import retrofit2.Call;
+import retrofit2.http.GET;
+
+public interface UserApi {
+ @GET("/x/web-interface/nav")
+ Call> getUserInfo();
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/login/LoginCookie.java b/biliapi/src/main/java/com/yutou/bili/bean/login/LoginCookie.java
new file mode 100644
index 0000000..1b9b436
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/login/LoginCookie.java
@@ -0,0 +1,34 @@
+package com.yutou.bili.bean.login;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.google.gson.annotations.SerializedName;
+import com.yutou.databases.AbsDatabasesBean;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class LoginCookie extends AbsDatabasesBean {
+ @JSONField(name = "SESSDATA")
+ String sessdta;
+ @JSONField(name = "Path")
+ String path;
+ @JSONField(name = "DedeUserID")
+ String dedeUserID;
+ @JSONField(name = "DedeUserID__ckMd5")
+ String dedeUserIDCkMd5;
+ @JSONField(name = "bili_jct")
+ String biliJct;
+ @JSONField(name = "Expires")
+ String expires;
+ @JSONField(name = "Domain")
+ String domain;
+ @JSONField(name = "sid")
+ String sid;
+ @JSONField(name = "gourl")
+ String gourl;
+
+ public LoginCookie() {
+ setTableName("login_cookie");
+ }
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/login/LoginInfoBean.java b/biliapi/src/main/java/com/yutou/bili/bean/login/LoginInfoBean.java
new file mode 100644
index 0000000..c66de42
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/login/LoginInfoBean.java
@@ -0,0 +1,17 @@
+package com.yutou.bili.bean.login;
+
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class LoginInfoBean extends BaseBean {
+ private String url;
+ private String refresh_token;
+ private long timestamp;
+ private int code;
+ private String message;
+
+
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/login/QRCodeGenerateBean.java b/biliapi/src/main/java/com/yutou/bili/bean/login/QRCodeGenerateBean.java
new file mode 100644
index 0000000..02fa07f
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/login/QRCodeGenerateBean.java
@@ -0,0 +1,15 @@
+package com.yutou.bili.bean.login;
+
+
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class QRCodeGenerateBean extends BaseBean {
+
+ private String url;
+ private String qrcode_key;
+
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/login/UserInfoBean.java b/biliapi/src/main/java/com/yutou/bili/bean/login/UserInfoBean.java
new file mode 100644
index 0000000..72482a8
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/login/UserInfoBean.java
@@ -0,0 +1,288 @@
+package com.yutou.bili.bean.login;
+
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.google.gson.annotations.SerializedName;
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class UserInfoBean extends BaseBean {
+
+ @JSONField(name = "isLogin")
+ private boolean isLogin;
+
+ @JSONField(name = "email_verified")
+ private int emailVerified;
+
+ @JSONField(name = "face")
+ private String face;
+
+ @JSONField(name = "face_nft")
+ private int faceNft;
+
+ @JSONField(name = "face_nft_type")
+ private int faceNftType;
+
+ @JSONField(name = "level_info")
+ private LevelInfo levelInfo;
+
+ @JSONField(name = "mid")
+ private long mid;
+
+ @JSONField(name = "mobile_verified")
+ private int mobileVerified;
+
+ @JSONField(name = "money")
+ private double money;
+
+ @JSONField(name = "moral")
+ private int moral;
+
+ @JSONField(name = "official")
+ private Official official;
+
+ @JSONField(name = "officialVerify")
+ private OfficialVerify officialVerify;
+
+ @JSONField(name = "pendant")
+ private Pendant pendant;
+
+ @JSONField(name = "scores")
+ private int scores;
+
+ @JSONField(name = "uname")
+ private String uname;
+
+ @JSONField(name = "vipDueDate")
+ private Date vipDueDate;
+
+ @JSONField(name = "vipStatus")
+ private int vipStatus;
+
+ @JSONField(name = "vipType")
+ private int vipType;
+
+ @JSONField(name = "vip_pay_type")
+ private int vipPayType;
+
+ @JSONField(name = "vip_theme_type")
+ private int vipThemeType;
+
+ @JSONField(name = "vip_label")
+ private VipLabel vipLabel;
+
+ @JSONField(name = "vip_avatar_subscript")
+ private int vipAvatarSubscript;
+
+ @JSONField(name = "vip_nickname_color")
+ private String vipNicknameColor;
+
+ @JSONField(name = "vip")
+ private Vip vip;
+
+ @JSONField(name = "wallet")
+ private Wallet wallet;
+
+ @JSONField(name = "has_shop")
+ private boolean hasShop;
+
+ @JSONField(name = "shop_url")
+ private String shopUrl;
+
+ @JSONField(name = "allowance_count")
+ private int allowanceCount;
+
+ @JSONField(name = "answer_status")
+ private int answerStatus;
+
+ @JSONField(name = "is_senior_member")
+ private boolean isSeniorMember;
+
+ @JSONField(name = "wbi_img")
+ private WbiImg wbiImg;
+
+ @JSONField(name = "is_jury")
+ private boolean isJury;
+
+ // 省略了getters和setters
+
+ // level_info的内部数据结构
+ @Data
+ public static class LevelInfo {
+ @JSONField(name = "current_level")
+ private int currentLevel;
+
+ @JSONField(name = "current_min")
+ private int currentMin;
+
+ @JSONField(name = "current_exp")
+ private int currentExp;
+
+ @JSONField(name = "next_exp")
+ private String nextExp;
+
+ // getters and setters
+ }
+
+ // official的结构
+ @Data
+ public static class Official {
+ @JSONField(name = "role")
+ private int role;
+
+ @JSONField(name = "title")
+ private String title;
+
+ @JSONField(name = "desc")
+ private String desc;
+
+ @JSONField(name = "type")
+ private int type;
+
+ // getters and setters
+ }
+
+ // officialVerify的结构
+ @Data
+ public static class OfficialVerify {
+ @JSONField(name = "type")
+ private int type;
+
+ @JSONField(name = "desc")
+ private String desc;
+
+ // getters and setters
+ }
+
+ // pendant的结构
+ @Data
+ public static class Pendant {
+ @JSONField(name = "pid")
+ private int pid;
+
+ @JSONField(name = "name")
+ private String name;
+
+ @JSONField(name = "image")
+ private String image;
+
+ @JSONField(name = "expire")
+ private int expire;
+
+ @JSONField(name = "image_enhance")
+ private String imageEnhance;
+
+ @JSONField(name = "image_enhance_frame")
+ private String imageEnhanceFrame;
+
+ @JSONField(name = "n_pid")
+ private int nPid;
+
+ // getters and setters
+ }
+
+ // vipLabel的结构
+ @Data
+ public static class VipLabel {
+ @JSONField(name = "path")
+ private String path;
+
+ @JSONField(name = "text")
+ private String text;
+
+ @JSONField(name = "label_theme")
+ private String labelTheme;
+
+ @JSONField(name = "text_color")
+ private String textColor;
+
+ @JSONField(name = "bg_style")
+ private String bgStyle;
+
+ @JSONField(name = "bg_color")
+ private String bgColor;
+
+ @JSONField(name = "border_color")
+ private String borderColor;
+
+ @JSONField(name = "use_img_label")
+ private boolean useImgLabel;
+
+ @JSONField(name = "img_label_uri_hans")
+ private String imgLabelUriHans;
+
+ @JSONField(name = "img_label_uri_hant")
+ private String imgLabelUriHant;
+
+ @JSONField(name = "img_label_uri_hans_static")
+ private String imgLabelUriHansStatic;
+
+ @JSONField(name = "img_label_uri_hant_static")
+ private String imgLabelUriHantStatic;
+
+ // getters and setters
+ }
+
+ // vip的结构,和vipLabel类似
+ @Data
+ public static class Vip {
+ @JSONField(name = "type")
+ private int type;
+
+ @JSONField(name = "status")
+ private int status;
+
+ @JSONField(name = "due_date")
+ private Date dueDate;
+
+ @JSONField(name = "vip_pay_type")
+ private int vipPayType;
+
+ @JSONField(name = "theme_type")
+ private int themeType;
+
+ @JSONField(name = "label")
+ private VipLabel label;
+
+ @JSONField(name = "avatar_subscript")
+ private int avatarSubscript;
+
+ @JSONField(name = "nickname_color")
+ private String nicknameColor;
+ // getters and setters
+ }
+
+ // wallet的结构
+ @Data
+ public static class Wallet {
+ @JSONField(name = "mid")
+ private long mid;
+
+ @JSONField(name = "bcoin_balance")
+ private int bcoinBalance;
+
+ @JSONField(name = "coupon_balance")
+ private int couponBalance;
+
+ @JSONField(name = "coupon_due_time")
+ private int couponDueTime;
+ // getters and setters
+ }
+
+ // WbiImg的结构
+ @Data
+ public static class WbiImg {
+ @JSONField(name = "img_url")
+ private String imgUrl;
+
+ @JSONField(name = "sub_url")
+ private String subUrl;
+
+ // getters and setters
+ }
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/databases/BiliBiliLoginDatabase.java b/biliapi/src/main/java/com/yutou/bili/databases/BiliBiliLoginDatabase.java
new file mode 100644
index 0000000..983c0df
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/databases/BiliBiliLoginDatabase.java
@@ -0,0 +1,49 @@
+package com.yutou.bili.databases;
+
+import com.yutou.bili.bean.login.LoginCookie;
+import com.yutou.databases.SQLiteManager;
+
+import java.util.List;
+
+public class BiliBiliLoginDatabase extends SQLiteManager {
+ LoginCookie cookie;
+ private static BiliBiliLoginDatabase instance;
+
+ private BiliBiliLoginDatabase(Class tClass) {
+ try {
+ cookie = new LoginCookie();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ init();
+ }
+
+ public static BiliBiliLoginDatabase getInstance() {
+ if (instance == null) {
+ instance = new BiliBiliLoginDatabase(LoginCookie.class);
+ }
+ return instance;
+ }
+
+
+ public BiliBiliLoginDatabase initData(LoginCookie cookie) {
+ this.cookie = cookie;
+ for (BuildSqlTable table : build.getTable()) {
+ cookie.setTableName(table.getName());
+ add(cookie);
+ }
+ return this;
+ }
+
+ public List get() {
+ return super.get(cookie.getTableName(), LoginCookie.class);
+ }
+
+ @Override
+ protected LoginCookie getDataBean() {
+ return new LoginCookie();
+ }
+}
+/**
+ *
+ */
\ No newline at end of file
diff --git a/biliapi/src/main/java/com/yutou/bili/net/BiliLoginNetApiManager.java b/biliapi/src/main/java/com/yutou/bili/net/BiliLoginNetApiManager.java
new file mode 100644
index 0000000..dbc8b90
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/net/BiliLoginNetApiManager.java
@@ -0,0 +1,118 @@
+package com.yutou.bili.net;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.yutou.bili.api.LoginApi;
+import com.yutou.bili.bean.login.LoginCookie;
+import com.yutou.bili.bean.login.LoginInfoBean;
+import com.yutou.bili.bean.login.QRCodeGenerateBean;
+import com.yutou.bili.databases.BiliBiliLoginDatabase;
+import com.yutou.databases.AbsDatabasesBean;
+import com.yutou.okhttp.HttpBody;
+import com.yutou.okhttp.HttpCallback;
+import com.yutou.okhttp.api.BaseApi;
+import okhttp3.Headers;
+import org.springframework.util.StringUtils;
+import retrofit2.Response;
+
+import java.io.IOException;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class BiliLoginNetApiManager extends BaseApi {
+ public static final int LOGIN_QRCODE = 100;
+ public static final int LOGIN_SUCCESS = 101;
+
+ private static BiliLoginNetApiManager instance;
+ LoginApi loginApi;
+
+ private BiliLoginNetApiManager() {
+ super("https://passport.bilibili.com");
+ loginApi = createApi(LoginApi.class);
+ }
+
+ public static BiliLoginNetApiManager getInstance() {
+ if (instance == null) {
+ instance = new BiliLoginNetApiManager();
+ }
+ return instance;
+ }
+
+ public void login(HttpCallback callback) {
+ List cookie = BiliBiliLoginDatabase.getInstance().get();
+ if (!cookie.isEmpty()) {
+ callback.onResponse(null, LOGIN_SUCCESS, null, cookie.get(0), null);
+ return;
+ }
+ loginApi.getQRCodeGenerate().enqueue(new HttpCallback() {
+ @Override
+ public void onResponse(Headers headers, int code, String status, QRCodeGenerateBean response, String rawResponse) {
+ String oauthKey = response.getQrcode_key();
+ String url = response.getUrl();
+ String bd = "gourl=https%3A%2F%2Fpassport.bilibili.com%2Fajax%2FminiLogin%2Fredirect&oauthKey=" + oauthKey;
+ callback.onResponse(headers, LOGIN_QRCODE, null, null, url);
+ new Thread(() -> waitLogin(oauthKey, callback)).start();
+ }
+
+ @Override
+ public void onFailure(Throwable throwable) {
+
+ }
+ });
+ }
+
+ private void waitLogin(String oauthKey, HttpCallback callback) {
+ long time = System.currentTimeMillis();
+ new Timer().schedule(new TimerTask() {
+ @Override
+ public void run() {
+ String bd = "gourl=https%3A%2F%2Fpassport.bilibili.com%2Fajax%2FminiLogin%2Fredirect&oauthKey=" + oauthKey;
+ if ((System.currentTimeMillis() - time) > 5 * 60 * 1000) {
+ cancel();
+ return;
+ }
+
+ try {
+ Response> response = loginApi.loginQRCode(oauthKey).execute();
+ Headers headers = response.headers();
+ HttpBody httpBody = response.body();
+ if (httpBody.getData().getCode() == 0) {
+ JSONObject ck = new JSONObject();
+ List list = headers.values("set-cookie");
+ for (String cookie : list) {
+ String[] split = cookie.split(";");
+ for (String string : split) {
+ if (!ck.containsKey(string) && !StringUtils.isEmpty(string) && string.contains("=")) {
+ String key = string.split("=")[0].trim();
+ String value = string.split("=")[1].trim();
+ if (key.contains("Expires")) {
+ SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMMM yyyy HH:mm:ss z", Locale.ENGLISH);
+ sdf.setTimeZone(TimeZone.getDefault());
+ Date date = sdf.parse(value, new ParsePosition(0));
+ value = String.valueOf(date.getTime() / 1000);
+ }
+ ck.put(key, value);
+ }
+ }
+ }
+ if (!list.isEmpty()) {
+ ck.put("gourl", bd);
+ LoginCookie cookie = JSONObject.parseObject(ck.toString(), LoginCookie.class);
+ cancel();
+ callback.onResponse(headers, LOGIN_SUCCESS, "ok", cookie, ck.toString());
+
+ } else {
+ callback.onFailure(new RuntimeException("cookie为空"));
+ cancel();
+ }
+ }
+ } catch (IOException e) {
+ cancel();
+ throw new RuntimeException(e);
+ }
+
+ }
+ }, 1000, 3000);
+ }
+
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/net/BiliUserNetApiManager.java b/biliapi/src/main/java/com/yutou/bili/net/BiliUserNetApiManager.java
new file mode 100644
index 0000000..c4a9688
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/net/BiliUserNetApiManager.java
@@ -0,0 +1,47 @@
+package com.yutou.bili.net;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.yutou.bili.api.UserApi;
+import com.yutou.bili.bean.login.LoginCookie;
+import com.yutou.bili.databases.BiliBiliLoginDatabase;
+import com.yutou.inter.IHttpApiCheckCallback;
+import com.yutou.okhttp.api.BaseApi;
+
+import java.util.HashMap;
+import java.util.List;
+
+public class BiliUserNetApiManager extends BaseApi {
+ public static final int LOGIN_LOGOUT = 1;
+
+ public static BiliUserNetApiManager manager;
+
+ private BiliUserNetApiManager() {
+ super("https://api.bilibili.com");
+ }
+
+ public static BiliUserNetApiManager getInstance() {
+ if (manager == null) {
+ manager = new BiliUserNetApiManager();
+ }
+ return manager;
+ }
+
+ public void getUserApi(IHttpApiCheckCallback callback) {
+ List list = BiliBiliLoginDatabase.getInstance().get();
+ if (!list.isEmpty()) {
+ HashMap headers = new HashMap<>();
+ LoginCookie cookie = list.get(0);
+ JSONObject json = JSONObject.parseObject(JSONObject.toJSONString(cookie));
+ StringBuilder ck=new StringBuilder();
+ for (String key : json.keySet()) {
+ ck.append(key).append("=").append(json.getString(key)).append("; ");
+ }
+ headers.put("Cookie", ck.toString());
+ setHeaders(headers);
+ callback.onSuccess(createApi(UserApi.class));
+ } else {
+ callback.onError(LOGIN_LOGOUT, "未登录");
+ }
+ }
+
+}
diff --git a/common/pom.xml b/common/pom.xml
new file mode 100644
index 0000000..6b8bcf9
--- /dev/null
+++ b/common/pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+ com.yutou
+ bilibili
+ 0.0.1-SNAPSHOT
+
+
+ common
+
+
+ 21
+ 21
+ UTF-8
+
+
+
+
+ com.squareup.okhttp3
+ okhttp
+ 4.12.0
+
+
+
+
+ com.squareup.retrofit2
+ retrofit
+ 2.11.0
+
+
+
\ No newline at end of file
diff --git a/common/src/main/java/com/yutou/databases/AbsDatabasesBean.java b/common/src/main/java/com/yutou/databases/AbsDatabasesBean.java
new file mode 100644
index 0000000..fcf5cdb
--- /dev/null
+++ b/common/src/main/java/com/yutou/databases/AbsDatabasesBean.java
@@ -0,0 +1,17 @@
+package com.yutou.databases;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONWriter;
+import lombok.Data;
+
+@Data
+public class AbsDatabasesBean {
+ String tableName;
+
+
+ public JSONObject toJson() {
+ JSONObject json = JSONObject.parseObject(JSONObject.toJSONString(this, JSONWriter.Feature.WriteMapNullValue));
+ json.remove("tableName");
+ return json;
+ }
+}
diff --git a/common/src/main/java/com/yutou/databases/SQLiteManager.java b/common/src/main/java/com/yutou/databases/SQLiteManager.java
new file mode 100644
index 0000000..11f9e7f
--- /dev/null
+++ b/common/src/main/java/com/yutou/databases/SQLiteManager.java
@@ -0,0 +1,302 @@
+package com.yutou.databases;
+
+
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.utils.Log;
+import lombok.Data;
+import lombok.Getter;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public abstract class SQLiteManager {
+ protected Connection conn;
+ private String url = "jdbc:sqlite:";
+ private File sql;
+ @Getter
+ public BuildSql build;
+
+ public void init() {
+ AbsDatabasesBean data = getDataBean();
+ List items = new ArrayList<>();
+ Field[] fields = data.getClass().getDeclaredFields();
+ for (Field field : fields) {
+ String name = field.getAnnotation(JSONField.class).name();
+ if (name.equals("tableName")) continue;
+ String type = BuildSqlItem.TYPE_STRING;
+ if (field.getType() == int.class) {
+ type = BuildSqlItem.TYPE_INT;
+ } else if (field.getType() == String.class) {
+ type = BuildSqlItem.TYPE_STRING;
+ } else if (field.getType() == Date.class) {
+ type = BuildSqlItem.TYPE_TIME;
+ }
+ items.add(BuildSqlItem.create().setName(name).setType(type).setNull(true).setKey(false));
+ }
+ BuildSql sql = BuildSql.create()
+ .setFileName("bilibili_login.db")
+ .setTable(BuildSqlTable.create().setName(data.getTableName()).setItem(items));
+ build(sql);
+ }
+
+
+ public void startBatch() {
+ try {
+ conn.setAutoCommit(false);
+ } catch (SQLException e) {
+ Log.e(e);
+ }
+ }
+
+ public void closeBatch() {
+ try {
+ conn.setAutoCommit(true);
+ } catch (SQLException e) {
+ Log.e(e);
+ }
+ }
+
+ public void close() {
+ try {
+ conn.close();
+ } catch (SQLException throwables) {
+ throwables.printStackTrace();
+ }
+ }
+
+ public void commit() {
+ try {
+ conn.commit();
+ } catch (SQLException e) {
+ Log.e(e);
+ }
+ }
+
+ public void add(T t) {
+ try {
+ Statement statement = conn.createStatement();
+ StringBuilder sb = new StringBuilder();
+ StringBuilder value = new StringBuilder();
+ sb.append("INSERT INTO `").append(t.getTableName()).append("` ");
+ sb.append("(");
+ value.append("(");
+ for (String key : t.toJson().keySet()) {
+ sb.append("`").append(key).append("`,");
+ value.append("'").append(t.toJson().get(key)).append("',");
+ }
+ sb.deleteCharAt(sb.length() - 1);
+ value.deleteCharAt(value.length() - 1);
+ value.append(")");
+ sb.append(") VALUES ");
+ sb.append(value);
+ statement.executeUpdate(sb.toString());
+ statement.close();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public List get(String table, Class tClass) {
+ List list = new ArrayList<>();
+ try {
+ Statement statement = conn.createStatement();
+ String sql = "SELECT * FROM `" + table + "`";
+ ResultSet resultSet = statement.executeQuery(sql);
+ while (resultSet.next()) {
+ JSONObject json = new JSONObject();
+ for (int i = 0; i < resultSet.getMetaData().getColumnCount(); i++) {
+ String name = resultSet.getMetaData().getColumnName(i + 1);
+ json.put(name, resultSet.getObject(name));
+ }
+ list.add(json.to(tClass));
+ }
+ resultSet.close();
+ statement.closeOnCompletion();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return list;
+ }
+
+
+ private void createSql(BuildSql build) {
+ try {
+ sql.mkdirs();
+ sql.delete();
+ conn = DriverManager.getConnection(url + sql.getAbsolutePath());
+ } catch (Exception e) {
+ Log.e(e);
+ }
+ startBatch();
+ for (BuildSqlTable table : build.getTable()) {
+ Log.i("创建表:" + table.getName());
+ createSqlOfTable(table);
+ }
+ closeBatch();
+ }
+
+ private void createSqlOfTable(BuildSqlTable table) {
+ String tableName = table.getName();
+ try {
+ Statement statement = conn.createStatement();
+ List items = table.getItem();
+ StringBuilder sql = new StringBuilder();
+ sql.append("CREATE TABLE `")
+ .append(tableName)
+ .append("` (");
+ for (BuildSqlItem item : items) {
+ StringBuilder builder = new StringBuilder();
+ String type = switch (item.getType()) {
+ case "int" -> " INTEGER ";
+ case "TIME" -> " NUMERIC ";
+ default -> " TEXT ";
+ };
+ builder.append("`")
+ .append(item.getName())
+ .append("`")
+ .append(type)
+ .append(item.isNull() ? "" : " NOT NULL ")
+ .append(item.isKey() ? " PRIMARY KEY AUTOINCREMENT " : "")
+ .append(",");
+ sql.append(builder.toString());
+ }
+ sql.append(");");
+ System.out.println("创建表 > " + sql.toString());
+ statement.execute(sql.toString().replace(",);", ");"));
+ statement.closeOnCompletion();
+ } catch (Exception e) {
+ Log.e(e);
+ }
+ }
+
+ protected void build(BuildSql buildSql) {
+ try {
+ this.build = buildSql;
+ Class.forName("org.sqlite.JDBC");
+ sql = new File("databases" + File.separator + buildSql.getFileName());
+ if (!sql.exists()) {
+ createSql(buildSql);
+ } else {
+ conn = DriverManager.getConnection(url + sql.getAbsolutePath());
+ }
+ } catch (Exception e) {
+ Log.e(e);
+ }
+ }
+
+ public boolean setDB(String fileName) {
+ try {
+ Class.forName("org.sqlite.JDBC");
+ sql = new File("db" + File.separator + fileName);
+ if (sql.exists()) {
+ if (conn != null && !conn.isClosed()) {
+ conn.close();
+ }
+ conn = DriverManager.getConnection(url + sql.getAbsolutePath());
+ return true;
+ }
+ } catch (Exception e) {
+ Log.e(e);
+ }
+ return false;
+ }
+
+
+ protected abstract AbsDatabasesBean getDataBean();
+
+ public static void main(String[] args) {
+
+ }
+
+ @Data
+ public static class BuildSql {
+ String fileName;
+ List table;
+
+ public static BuildSql create() {
+ return new BuildSql();
+ }
+
+ public BuildSql setFileName(String fileName) {
+ this.fileName = fileName;
+ return this;
+ }
+
+ public BuildSql setTable(List table) {
+ this.table = table;
+ return this;
+ }
+
+ public BuildSql setTable(BuildSqlTable... table) {
+ this.table = List.of(table);
+ return this;
+ }
+ }
+
+ @Data
+ public static class BuildSqlTable {
+ String name;
+ List item;
+
+ public static BuildSqlTable create() {
+ return new BuildSqlTable();
+ }
+
+ public BuildSqlTable setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public BuildSqlTable setItem(List item) {
+ this.item = item;
+ return this;
+ }
+
+ public BuildSqlTable setItem(BuildSqlItem... item) {
+ this.item = List.of(item);
+ return this;
+ }
+ }
+
+ @Data
+ public static class BuildSqlItem {
+ public static final String TYPE_INT = "init";
+ public static final String TYPE_STRING = "String";
+ public static final String TYPE_TIME = "TIME";
+
+
+ String name;
+ String type;
+ boolean isNull;
+ boolean isKey;
+
+ public static BuildSqlItem create() {
+ return new BuildSqlItem();
+ }
+
+ public BuildSqlItem setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public BuildSqlItem setType(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public BuildSqlItem setNull(boolean aNull) {
+ isNull = aNull;
+ return this;
+ }
+
+ public BuildSqlItem setKey(boolean key) {
+ isKey = key;
+ return this;
+ }
+ }
+}
diff --git a/common/src/main/java/com/yutou/inter/IHttpApiCheckCallback.java b/common/src/main/java/com/yutou/inter/IHttpApiCheckCallback.java
new file mode 100644
index 0000000..17a7588
--- /dev/null
+++ b/common/src/main/java/com/yutou/inter/IHttpApiCheckCallback.java
@@ -0,0 +1,7 @@
+package com.yutou.inter;
+
+public interface IHttpApiCheckCallback {
+ void onSuccess(T api);
+
+ void onError(int code, String error);
+}
diff --git a/common/src/main/java/com/yutou/okhttp/BaseBean.java b/common/src/main/java/com/yutou/okhttp/BaseBean.java
new file mode 100644
index 0000000..ffca9c9
--- /dev/null
+++ b/common/src/main/java/com/yutou/okhttp/BaseBean.java
@@ -0,0 +1,6 @@
+package com.yutou.okhttp;
+
+import java.io.Serializable;
+
+public class BaseBean implements Serializable {
+}
diff --git a/common/src/main/java/com/yutou/okhttp/GetRequestParams.java b/common/src/main/java/com/yutou/okhttp/GetRequestParams.java
new file mode 100644
index 0000000..c574f91
--- /dev/null
+++ b/common/src/main/java/com/yutou/okhttp/GetRequestParams.java
@@ -0,0 +1,32 @@
+package com.yutou.okhttp;
+
+
+import okhttp3.Headers;
+import okhttp3.HttpUrl;
+import okhttp3.Request;
+
+import java.util.HashMap;
+
+public class GetRequestParams implements IRequestParam {
+ /**
+ * 构建Request
+ *
+ * @param request
+ * @return
+ */
+ @Override
+ public Request getRequest(HashMap headerMap, HashMap map, Request request) {
+ Headers.Builder headerBuild = request.headers().newBuilder();
+ if (!headerMap.isEmpty()) {
+ for (String key : headerMap.keySet()) {
+ headerBuild.add(key, headerMap.get(key));
+ }
+ }
+ //添加公共参数
+ HttpUrl.Builder builder = request.url().newBuilder();
+ for (String key : map.keySet()) {
+ builder.addQueryParameter(key, String.valueOf(map.get(key)));
+ }
+ return request.newBuilder().url(builder.build()).headers(headerBuild.build()).build();
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/com/yutou/okhttp/HttpBody.java b/common/src/main/java/com/yutou/okhttp/HttpBody.java
new file mode 100644
index 0000000..7d8588e
--- /dev/null
+++ b/common/src/main/java/com/yutou/okhttp/HttpBody.java
@@ -0,0 +1,14 @@
+package com.yutou.okhttp;
+
+import lombok.Data;
+
+@Data
+public class HttpBody {
+ private String msg;
+ private String status;
+ private int code;
+ private int retcode;
+ private T data;
+ private String src;
+
+}
\ No newline at end of file
diff --git a/common/src/main/java/com/yutou/okhttp/HttpCallback.java b/common/src/main/java/com/yutou/okhttp/HttpCallback.java
new file mode 100644
index 0000000..147a502
--- /dev/null
+++ b/common/src/main/java/com/yutou/okhttp/HttpCallback.java
@@ -0,0 +1,35 @@
+package com.yutou.okhttp;
+
+import okhttp3.Headers;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public abstract class HttpCallback implements Callback> {
+
+ public abstract void onResponse(Headers headers,int code, String status, T response, String rawResponse);
+
+ public abstract void onFailure(Throwable throwable);
+
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ if (response.body() != null) {
+ onResponse(
+ response.headers(),
+ response.body().getRetcode(),
+ response.body().getStatus(),
+ response.body().getData(),
+ response.body().getSrc()
+ );
+ } else {
+ onFailure(new NullPointerException("response body is null"));
+ }
+ call.cancel();
+ }
+
+ @Override
+ public void onFailure(Call> call, Throwable throwable) {
+ onFailure(throwable);
+ call.cancel();
+ }
+}
diff --git a/common/src/main/java/com/yutou/okhttp/HttpLoggingInterceptor.java b/common/src/main/java/com/yutou/okhttp/HttpLoggingInterceptor.java
new file mode 100644
index 0000000..ac6e501
--- /dev/null
+++ b/common/src/main/java/com/yutou/okhttp/HttpLoggingInterceptor.java
@@ -0,0 +1,209 @@
+package com.yutou.okhttp;
+
+
+import com.yutou.utils.Log;
+import okhttp3.*;
+import okhttp3.internal.http.HttpHeaders;
+import okio.Buffer;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
+
+public class HttpLoggingInterceptor implements Interceptor {
+ private static final String TAG = "HttpLogging";
+
+ private static final Charset UTF8 = Charset.forName("UTF-8");
+
+ private volatile Level printLevel = Level.NONE;
+ private java.util.logging.Level colorLevel;
+ private Logger logger;
+
+ private static boolean prLog;
+
+ public static void setLog(boolean log) {
+ prLog = log;
+ }
+
+ public enum Level {
+ NONE, //不打印log
+ BASIC, //只打印 请求首行 和 响应首行
+ HEADERS, //打印请求和响应的所有 Header
+ BODY //所有数据全部打印
+ }
+
+ public HttpLoggingInterceptor(String tag) {
+ logger = Logger.getLogger(tag);
+ colorLevel = java.util.logging.Level.INFO;
+ }
+
+ public void setPrintLevel(Level level) {
+ if (printLevel == null)
+ throw new NullPointerException("printLevel == null. Use Level.NONE instead.");
+ printLevel = level;
+ }
+
+ public void setColorLevel(java.util.logging.Level level) {
+ colorLevel = level;
+ }
+
+ private void log(String message) {
+ //logger.log(colorLevel, message);
+ if (prLog) {
+ Log.i(TAG, message);
+ }
+ //Log.e(TAG,message);
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+ if (request.body() != null && request.body().contentLength() == 0) {
+ request = chain.call().request();
+ }
+ if (printLevel == Level.NONE) {
+ return chain.proceed(request);
+ }
+
+ //请求日志拦截
+ logForRequest(request, chain.connection());
+
+ //执行请求,计算请求时间
+ long startNs = System.nanoTime();
+ Response response;
+ try {
+ response = chain.proceed(request);
+ } catch (Exception e) {
+ log("<-- HTTP FAILED: " + e);
+ throw e;
+ }
+ long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
+
+ //响应日志拦截
+ return logForResponse(response, tookMs);
+ }
+
+ private void logForRequest(Request request, Connection connection) throws IOException {
+ boolean logBody = (printLevel == Level.BODY);
+ boolean logHeaders = (printLevel == Level.BODY || printLevel == Level.HEADERS);
+ RequestBody requestBody = request.body();
+ boolean hasRequestBody = requestBody != null;
+ Protocol protocol = connection != null ? connection.protocol() : Protocol.HTTP_1_1;
+
+ try {
+ String requestStartMessage = "--> " + request.method() + ' ' + request.url() + ' ' + protocol;
+ log(requestStartMessage);
+
+ if (logHeaders) {
+ if (hasRequestBody) {
+ // Request body headers are only present when installed as a network interceptor. Force
+ // them to be included (when available) so there values are known.
+ if (requestBody.contentType() != null) {
+ log("\tContent-Type: " + requestBody.contentType());
+ }
+ if (requestBody.contentLength() != -1) {
+ log("\tContent-Length: " + requestBody.contentLength());
+ }
+ }
+ Headers headers = request.headers();
+ for (int i = 0, count = headers.size(); i < count; i++) {
+ String name = headers.name(i);
+ // Skip headers from the request body as they are explicitly logged above.
+ if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
+ log("\t" + name + ": " + headers.value(i));
+ }
+ }
+
+ log(" ");
+ if (logBody && hasRequestBody) {
+ if (isPlaintext(requestBody.contentType())) {
+ bodyToString(request);
+ } else {
+ log("\tbody: maybe [binary body], omitted!");
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.log(java.util.logging.Level.WARNING, e.getMessage(), e);
+ } finally {
+ log("--> END " + request.method());
+ }
+ }
+
+ private Response logForResponse(Response response, long tookMs) {
+ Response.Builder builder = response.newBuilder();
+ Response clone = builder.build();
+ ResponseBody responseBody = clone.body();
+ boolean logBody = (printLevel == Level.BODY);
+ boolean logHeaders = (printLevel == Level.BODY || printLevel == Level.HEADERS);
+
+ try {
+ log("<-- " + clone.code() + ' ' + clone.message() + ' ' + clone.request().url() + " (" + tookMs + "ms)");
+ if (logHeaders) {
+ Headers headers = clone.headers();
+ for (int i = 0, count = headers.size(); i < count; i++) {
+ log("\t" + headers.name(i) + ": " + headers.value(i));
+ }
+ log(" ");
+ if (logBody && HttpHeaders.hasBody(clone)) {
+ if (responseBody == null) return response;
+
+ if (isPlaintext(responseBody.contentType())) {
+ byte[] bytes = responseBody.byteStream().readAllBytes();
+ MediaType contentType = responseBody.contentType();
+ String body = new String(bytes, getCharset(contentType));
+ log("\tbody:" + body);
+ responseBody = ResponseBody.create(responseBody.contentType(), bytes);
+ return response.newBuilder().body(responseBody).build();
+ } else {
+ log("\tbody: maybe [binary body], omitted!");
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.log(java.util.logging.Level.WARNING, e.getMessage(), e);
+ } finally {
+ log("<-- END HTTP");
+ }
+ return response;
+ }
+
+ private static Charset getCharset(MediaType contentType) {
+ Charset charset = contentType != null ? contentType.charset(UTF8) : UTF8;
+ if (charset == null) charset = UTF8;
+ return charset;
+ }
+
+ /**
+ * Returns true if the body in question probably contains human readable text. Uses a small sample
+ * of code points to detect unicode control characters commonly used in binary file signatures.
+ */
+ private static boolean isPlaintext(MediaType mediaType) {
+ if (mediaType == null) return false;
+ if (mediaType.type() != null && mediaType.type().equals("text")) {
+ return true;
+ }
+ String subtype = mediaType.subtype();
+ if (subtype != null) {
+ subtype = subtype.toLowerCase();
+ if (subtype.contains("x-www-form-urlencoded") || subtype.contains("json") || subtype.contains("xml") || subtype.contains("html")) //
+ return true;
+ }
+ return false;
+ }
+
+ private void bodyToString(Request request) {
+ try {
+ Request copy = request.newBuilder().build();
+ RequestBody body = copy.body();
+ if (body == null) return;
+ Buffer buffer = new Buffer();
+ body.writeTo(buffer);
+ Charset charset = getCharset(body.contentType());
+ log("\tbody:" + buffer.readString(charset));
+ } catch (Exception e) {
+ logger.log(java.util.logging.Level.WARNING, e.getMessage(), e);
+ }
+ }
+}
diff --git a/common/src/main/java/com/yutou/okhttp/IRequestParam.java b/common/src/main/java/com/yutou/okhttp/IRequestParam.java
new file mode 100644
index 0000000..c1ac1e5
--- /dev/null
+++ b/common/src/main/java/com/yutou/okhttp/IRequestParam.java
@@ -0,0 +1,9 @@
+package com.yutou.okhttp;
+
+import okhttp3.Request;
+
+import java.util.HashMap;
+
+public interface IRequestParam {
+ Request getRequest(HashMap header, HashMap map, Request request);
+}
\ No newline at end of file
diff --git a/common/src/main/java/com/yutou/okhttp/ParamsContext.java b/common/src/main/java/com/yutou/okhttp/ParamsContext.java
new file mode 100644
index 0000000..b54f919
--- /dev/null
+++ b/common/src/main/java/com/yutou/okhttp/ParamsContext.java
@@ -0,0 +1,43 @@
+package com.yutou.okhttp;
+
+import okhttp3.Request;
+
+import java.util.HashMap;
+
+public class ParamsContext {
+ private IRequestParam iRequestParam;
+ private Request request;
+ private HashMap map;
+ private HashMap headerMap;
+
+ public ParamsContext(HashMap map, Request request) {
+ if (map == null) {
+ map = new HashMap<>();
+ }
+ this.map = map;
+ this.request = request;
+ this.headerMap = new HashMap<>();
+ }
+
+ public ParamsContext(HashMap headerMap, HashMap map, Request request) {
+ if (map == null) {
+ map = new HashMap<>();
+ }
+ this.map = map;
+ this.request = request;
+ this.headerMap = headerMap;
+ }
+
+ public Request getInRequest() {
+ switch (request.method()) {
+ case "GET":
+ iRequestParam = new GetRequestParams();
+ break;
+ case "POST":
+ iRequestParam = new PostRequestParams();
+ break;
+ }
+ headerMap.remove("tableName");
+ return iRequestParam.getRequest(headerMap, map, request);
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/com/yutou/okhttp/PostRequestParams.java b/common/src/main/java/com/yutou/okhttp/PostRequestParams.java
new file mode 100644
index 0000000..6145eaa
--- /dev/null
+++ b/common/src/main/java/com/yutou/okhttp/PostRequestParams.java
@@ -0,0 +1,73 @@
+package com.yutou.okhttp;
+
+
+import com.alibaba.fastjson2.JSONObject;
+import okhttp3.*;
+
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class PostRequestParams implements IRequestParam {
+ @Override
+ public Request getRequest(HashMap headerMap, HashMap map, Request request) {
+ Headers.Builder headerBuilder = request.headers().newBuilder();
+ if (!headerMap.isEmpty()) {
+ for (String key : headerMap.keySet()) {
+ headerBuilder.add(key, headerMap.get(key));
+ }
+ }
+ if (request.body() instanceof FormBody) {
+ FormBody.Builder bodyBuilder = new FormBody.Builder();
+ FormBody formBody = (FormBody) request.body();
+ for (int i = 0; i < formBody.size(); i++) {
+ bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i));
+ }
+ for (String key : map.keySet()) {
+ bodyBuilder.addEncoded(key, String.valueOf(map.get(key)));
+ }
+ formBody = bodyBuilder.build();
+ request = request.newBuilder().headers(headerBuilder.build()).post(formBody).build();
+ } else if (request.body() != null) {
+ RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), toUrlParams(map));
+ request = request.newBuilder()
+ .headers(headerBuilder.build())
+ .post(request.body())
+ .post(requestBody).build();
+ }
+ return request;
+ }
+
+ public static String toUrlParams(JSONObject json) {
+ StringBuilder string = new StringBuilder();
+ Set keys = json.keySet();
+ for (String key : keys) {
+ try {
+ string.append("&").append(key).append("=").append(URLEncoder.encode(json.getString(key), "UTF-8"));
+ } catch (Exception e) {
+ e.printStackTrace();
+ try {
+ string.append("&").append(URLEncoder.encode(key, "UTF-8")).append("=");
+ // string += "&" + key + "=";
+ } catch (Exception e1) {
+ string.append("&").append(key).append("=");
+ }
+ }
+ }
+
+ string = new StringBuilder(string.substring(1, string.length()).replaceAll(" ", ""));
+ return string.toString();
+ }
+
+ public static String toUrlParams(Map map) {
+ if (map.isEmpty()) {
+ return "";
+ }
+ StringBuilder builder = new StringBuilder();
+ for (String key : map.keySet()) {
+ builder.append(key).append("=").append(map.get(key)).append("&");
+ }
+ return builder.substring(0, builder.length() - 1);
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/com/yutou/okhttp/api/BaseApi.java b/common/src/main/java/com/yutou/okhttp/api/BaseApi.java
new file mode 100644
index 0000000..8fb2f7e
--- /dev/null
+++ b/common/src/main/java/com/yutou/okhttp/api/BaseApi.java
@@ -0,0 +1,107 @@
+package com.yutou.okhttp.api;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.internal.bind.DateTypeAdapter;
+import com.yutou.okhttp.HttpLoggingInterceptor;
+import com.yutou.okhttp.ParamsContext;
+import com.yutou.okhttp.converter.JsonCallAdapter;
+import com.yutou.okhttp.converter.JsonConverterFactory;
+import okhttp3.Interceptor;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import retrofit2.CallAdapter;
+import retrofit2.Converter;
+import retrofit2.Retrofit;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+
+public class BaseApi {
+ private String URL;
+ private HashMap params;
+ private HashMap headers;
+
+ public BaseApi(String URL) {
+ this.URL = URL;
+ }
+
+ public BaseApi setURL(String URL) {
+ this.URL = URL;
+ return this;
+ }
+
+ public BaseApi setHeaders(HashMap headers) {
+ this.headers = headers;
+ return this;
+ }
+
+ public BaseApi setParams(HashMap params) {
+ this.params = params;
+ return this;
+ }
+
+ /**
+ * 创建一个接口方法
+ *
+ * @param okHttpClient okhttp客户端
+ * @param converterFactory 处理工厂类
+ * @param callAdapterFactory 请求适配器工厂
+ * @param baseUrl 基础地质
+ * @param service 接口
+ * @param 接口泛型
+ * @return 接口
+ */
+ public T create(OkHttpClient okHttpClient, Converter.Factory converterFactory, CallAdapter.Factory callAdapterFactory, String baseUrl, Class service) {
+ Retrofit.Builder builder = new Retrofit.Builder()
+ //基础url
+ .baseUrl(baseUrl)
+ //客户端OKHttp
+ .client(okHttpClient);
+ //添加转换工厂
+ if (null != converterFactory) {
+ builder.addConverterFactory(converterFactory);
+ }
+ //添加请求工厂
+ if (null != callAdapterFactory) {
+ builder.addCallAdapterFactory(callAdapterFactory);
+ }
+ //创建retrofit对象
+ Retrofit retrofit = builder.build();
+
+ //返回创建的api
+ return retrofit.create(service);
+ }
+
+ public T createApi(Class apiClass) {
+ Gson gson = new GsonBuilder()
+ .registerTypeAdapter(Date.class, new DateTypeAdapter())
+ .create();
+ HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("http");
+ loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);
+ OkHttpClient.Builder builder = new OkHttpClient()
+ .newBuilder()
+ .addInterceptor(initQuery())
+ .addInterceptor(loggingInterceptor);
+
+ return create(builder.build(),
+ JsonConverterFactory.create(gson),
+ JsonCallAdapter.create(),
+ URL,
+ apiClass);
+ }
+ public Interceptor initQuery() {
+ Interceptor addQueryParameterInterceptor = new Interceptor() {
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+ //配置公共参数
+ request = new ParamsContext(headers,params,request).getInRequest();
+ return chain.proceed(request);
+ }
+ };
+ return addQueryParameterInterceptor;
+ }
+}
diff --git a/common/src/main/java/com/yutou/okhttp/converter/JsonCallAdapter.java b/common/src/main/java/com/yutou/okhttp/converter/JsonCallAdapter.java
new file mode 100644
index 0000000..8fe0ff9
--- /dev/null
+++ b/common/src/main/java/com/yutou/okhttp/converter/JsonCallAdapter.java
@@ -0,0 +1,19 @@
+package com.yutou.okhttp.converter;
+
+import org.jetbrains.annotations.Nullable;
+import retrofit2.CallAdapter;
+import retrofit2.Retrofit;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+public class JsonCallAdapter extends CallAdapter.Factory{
+ public static JsonCallAdapter create(){
+ return new JsonCallAdapter();
+ }
+ @Nullable
+ @Override
+ public CallAdapter, ?> get(Type type, Annotation[] annotations, Retrofit retrofit) {
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/com/yutou/okhttp/converter/JsonConverterFactory.java b/common/src/main/java/com/yutou/okhttp/converter/JsonConverterFactory.java
new file mode 100644
index 0000000..c2d3a58
--- /dev/null
+++ b/common/src/main/java/com/yutou/okhttp/converter/JsonConverterFactory.java
@@ -0,0 +1,40 @@
+package com.yutou.okhttp.converter;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.reflect.TypeToken;
+import okhttp3.RequestBody;
+import okhttp3.ResponseBody;
+import org.jetbrains.annotations.Nullable;
+import retrofit2.Converter;
+import retrofit2.Retrofit;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+public class JsonConverterFactory extends Converter.Factory {
+ Gson gson;
+ public static JsonConverterFactory create(Gson gson) {
+ return new JsonConverterFactory(gson);
+ }
+
+ private JsonConverterFactory(Gson gson) {
+ this.gson = gson;
+ }
+
+ @Nullable
+ @Override
+ public Converter, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
+ // return super.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
+ TypeAdapter> adapter = gson.getAdapter(TypeToken.get(type));
+ return new JsonRequestBodyConverter<>(gson,adapter);
+ }
+
+ @Nullable
+ @Override
+ public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
+ // return super.responseBodyConverter(type, annotations, retrofit);
+ TypeAdapter> adapter = gson.getAdapter(TypeToken.get(type));
+ return new JsonResponseBodyConverter<>(gson,adapter,type);
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/com/yutou/okhttp/converter/JsonRequestBodyConverter.java b/common/src/main/java/com/yutou/okhttp/converter/JsonRequestBodyConverter.java
new file mode 100644
index 0000000..6c7df58
--- /dev/null
+++ b/common/src/main/java/com/yutou/okhttp/converter/JsonRequestBodyConverter.java
@@ -0,0 +1,36 @@
+package com.yutou.okhttp.converter;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonWriter;
+import okhttp3.MediaType;
+import okhttp3.RequestBody;
+import okio.Buffer;
+import org.jetbrains.annotations.Nullable;
+import retrofit2.Converter;
+
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+
+public class JsonRequestBodyConverter implements Converter {
+ Gson gson;
+ TypeAdapter adapter;
+ public JsonRequestBodyConverter(Gson gson, TypeAdapter adapter) {
+ this.gson=gson;
+ this.adapter=adapter;
+ }
+
+ @Nullable
+ @Override
+ public RequestBody convert(T value) throws IOException {
+ Buffer buffer = new Buffer();
+ Writer writer = new OutputStreamWriter(buffer.outputStream(), StandardCharsets.UTF_8);
+ JsonWriter jsonWriter = gson.newJsonWriter(writer);
+ adapter.write(jsonWriter, value);
+ jsonWriter.close();
+ byte[] bytes = buffer.readByteArray();
+ return RequestBody.create(MediaType.parse("application/json; charset=UTF-8"),bytes );
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/com/yutou/okhttp/converter/JsonResponseBodyConverter.java b/common/src/main/java/com/yutou/okhttp/converter/JsonResponseBodyConverter.java
new file mode 100644
index 0000000..69c06d1
--- /dev/null
+++ b/common/src/main/java/com/yutou/okhttp/converter/JsonResponseBodyConverter.java
@@ -0,0 +1,45 @@
+package com.yutou.okhttp.converter;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.JSONWriter;
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.yutou.okhttp.HttpBody;
+import okhttp3.ResponseBody;
+import org.jetbrains.annotations.Nullable;
+import retrofit2.Converter;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+public class JsonResponseBodyConverter implements Converter {
+ Gson gson;
+ TypeAdapter> adapter;
+ Type type;
+
+ public JsonResponseBodyConverter(Gson gson, TypeAdapter> adapter, Type type) {
+ this.gson = gson;
+ this.adapter = adapter;
+ this.type = type;
+ }
+
+ @Nullable
+ @Override
+ public T convert(ResponseBody responseBody) throws IOException {
+ String string = new String(responseBody.bytes());
+ responseBody.close();
+ HttpBody body;
+ try {
+ body = JSONObject.parseObject(string, type, JSONReader.Feature.FieldBased);
+ body.setSrc(string);
+ return (T) body;
+ } catch (Exception e) {
+ e.printStackTrace();
+ body = new HttpBody();
+ body.setSrc(string);
+ }
+ return (T) body;
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/yutou/bilibili/Tools/AppTools.java b/common/src/main/java/com/yutou/utils/AppTools.java
similarity index 95%
rename from src/main/java/com/yutou/bilibili/Tools/AppTools.java
rename to common/src/main/java/com/yutou/utils/AppTools.java
index 5d705f9..1f44dfd 100644
--- a/src/main/java/com/yutou/bilibili/Tools/AppTools.java
+++ b/common/src/main/java/com/yutou/utils/AppTools.java
@@ -1,15 +1,16 @@
-package com.yutou.bilibili.Tools;
+package com.yutou.utils;
+import jakarta.servlet.http.Cookie;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.xml.bind.DatatypeConverter;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.xml.bind.DatatypeConverter;
+
import java.io.*;
import java.net.URLEncoder;
import java.security.MessageDigest;
@@ -26,7 +27,7 @@ public class AppTools {
writer.close();
return true;
} catch (IOException e) {
- com.yutou.bilibili.Tools.Log.e(e);
+ Log.e(e);
return false;
}
}
@@ -166,7 +167,7 @@ public class AppTools {
public static String deleteCookie(HttpServletRequest request, HttpServletResponse response, String key) {
for (Cookie cookie : request.getCookies()) {
if (cookie.getName().equals(key)) {
- com.yutou.bilibili.Tools.Log.i("删除key=" + key);
+ Log.i("删除key=" + key);
cookie.setMaxAge(0);
cookie.setPath("/");
cookie.setValue(null);
@@ -249,7 +250,7 @@ public class AppTools {
digest.update(data.getBytes());
return DatatypeConverter.printHexBinary(digest.digest());
} catch (Exception e) {
- com.yutou.bilibili.Tools.Log.e(e);
+ Log.e(e);
}
return "";
}
@@ -278,7 +279,7 @@ public class AppTools {
}else{
if(srcFileName.equals("Activity.smali")){
- com.yutou.bilibili.Tools.Log.i("文件夹已存在:"+destFileName);
+ Log.i("文件夹已存在:"+destFileName);
}
}
@@ -302,10 +303,10 @@ public class AppTools {
in.close();
return true;
} catch (FileNotFoundException e) {
- com.yutou.bilibili.Tools.Log.e(e);
+ Log.e(e);
return false;
} catch (IOException e) {
- com.yutou.bilibili.Tools.Log.e(e);
+ Log.e(e);
return false;
}
}
diff --git a/common/src/main/java/com/yutou/utils/Base64Tools.java b/common/src/main/java/com/yutou/utils/Base64Tools.java
new file mode 100644
index 0000000..4b9cafd
--- /dev/null
+++ b/common/src/main/java/com/yutou/utils/Base64Tools.java
@@ -0,0 +1,34 @@
+package com.yutou.utils;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Base64;
+
+public class Base64Tools {
+ public static String encode(String str) {
+ return Base64.getEncoder().encodeToString(str.getBytes());
+ }
+
+ public static String decode(String str) {
+ return new String(Base64.getDecoder().decode(str));
+ }
+
+ public static String encode(byte[] bytes) {
+ return Base64.getEncoder().encodeToString(bytes);
+ }
+
+ public static String encode(File file) {
+ try {
+ byte[] fileContent = Files.readAllBytes(Paths.get(file.getAbsolutePath()));
+ return encode(fileContent);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static void main(String[] args) {
+ }
+}
diff --git a/src/main/java/com/yutou/bilibili/Tools/ConfigTools.java b/common/src/main/java/com/yutou/utils/ConfigTools.java
similarity index 91%
rename from src/main/java/com/yutou/bilibili/Tools/ConfigTools.java
rename to common/src/main/java/com/yutou/utils/ConfigTools.java
index 66befd4..4bbb231 100644
--- a/src/main/java/com/yutou/bilibili/Tools/ConfigTools.java
+++ b/common/src/main/java/com/yutou/utils/ConfigTools.java
@@ -1,6 +1,7 @@
-package com.yutou.bilibili.Tools;
+package com.yutou.utils;
-import com.alibaba.fastjson.JSONObject;
+
+import com.alibaba.fastjson2.JSONObject;
import java.io.*;
@@ -11,6 +12,10 @@ public class ConfigTools {
public static final String CONFIG="config.json";
public static final String DATA="data.json";
public static final String SQLITE="sqlite.json";
+
+ public static final String NAPCAT_URL = "napcat.url";
+ public static final String QQ = "qq_bot";
+
static {
try {
File file=new File(CONFIG);
@@ -23,7 +28,7 @@ public class ConfigTools {
}
file=null;
}catch (Exception e){
- com.yutou.bilibili.Tools.Log.e(e);
+ Log.e(e);
}
}
@@ -68,7 +73,7 @@ public class ConfigTools {
writer.close();
return true;
} catch (IOException e) {
- com.yutou.bilibili.Tools.Log.e(e);
+ Log.e(e);
return false;
}
}
@@ -84,7 +89,7 @@ public class ConfigTools {
return str.toString();
} catch (Exception e) {
Log.i("error = "+file.getAbsolutePath());
- com.yutou.bilibili.Tools.Log.e(e);
+ Log.e(e);
}
return null;
}
diff --git a/src/main/java/com/yutou/bilibili/Tools/Log.java b/common/src/main/java/com/yutou/utils/Log.java
similarity index 90%
rename from src/main/java/com/yutou/bilibili/Tools/Log.java
rename to common/src/main/java/com/yutou/utils/Log.java
index 57d8adf..6fe4ce1 100644
--- a/src/main/java/com/yutou/bilibili/Tools/Log.java
+++ b/common/src/main/java/com/yutou/utils/Log.java
@@ -1,4 +1,4 @@
-package com.yutou.bilibili.Tools;
+package com.yutou.utils;
import java.io.File;
@@ -13,8 +13,9 @@ public class Log {
public static void i(String tag, Object log) {
i('[' + tag + ']' + log);
}
+
public static void i(Object log) {
- if (!((boolean) ConfigTools.load(ConfigTools.CONFIG, "logout"))) {
+ if (!((boolean) ConfigTools.load(ConfigTools.CONFIG, "logcat"))) {
return;
}
System.out.printf("[%s]%s%n",
@@ -25,7 +26,7 @@ public class Log {
}
public static void e(Exception e) {
- if (!((boolean) ConfigTools.load(ConfigTools.CONFIG, "logout"))) {
+ if (!ConfigTools.load(ConfigTools.CONFIG, "logcat", Boolean.class)){
return;
}
i(e.getMessage());
@@ -34,7 +35,7 @@ public class Log {
public static void i(String timer, int roomId, Object log) {
String logFlag = RedisTools.get("live-log", 1);
- if (logFlag!=null&&logFlag.startsWith("true")) {
+ if (logFlag != null && logFlag.startsWith("true")) {
if (logFlag.contains("|")) {
if (log.toString().contains(logFlag.split("\\|")[1])) {
getLogger("[" + timer.replace(":", "_") + "]" + roomId).log(Level.INFO, log.toString());
diff --git a/src/main/java/com/yutou/bilibili/Tools/RedisTools.java b/common/src/main/java/com/yutou/utils/RedisTools.java
similarity index 69%
rename from src/main/java/com/yutou/bilibili/Tools/RedisTools.java
rename to common/src/main/java/com/yutou/utils/RedisTools.java
index 29ae94d..1ff6853 100644
--- a/src/main/java/com/yutou/bilibili/Tools/RedisTools.java
+++ b/common/src/main/java/com/yutou/utils/RedisTools.java
@@ -1,21 +1,19 @@
-package com.yutou.bilibili.Tools;
+package com.yutou.utils;
-import com.alibaba.fastjson.JSONObject;
-import com.yutou.bilibili.QQBot.QQBotManager;
+import com.alibaba.fastjson2.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;
-import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.util.Properties;
import java.util.Set;
public class RedisTools {
+ public static final int QQBOT_USER = 3;
private static boolean isNotInstallRedis = false;
private static String host;
private static int port;
@@ -51,8 +49,8 @@ public class RedisTools {
return true;
}
- public static boolean set(String key, String value) {
- return set(0, key, value);
+ public static boolean set(Object key, String value) {
+ return set(0, key.toString(), value);
}
public static boolean set(String key, String value, int timeout) {
@@ -91,12 +89,12 @@ public class RedisTools {
return value;
}
- public static String get(String key) {
- return get(key, 0);
+ public static String get(Object key) {
+ return get(key.toString(), 0);
}
- public static boolean remove(String key) {
- return remove(key,0);
+ public static boolean remove(Object key) {
+ return remove(key.toString(),0);
}
public static void removeLoginState(String uid) {
@@ -117,12 +115,12 @@ public class RedisTools {
return tmp;
}
- public static boolean exists(String key, String value) {
+ public static boolean exists(Object key, String value) {
if (isNotInstallRedis) {
return false;
}
Jedis jedis = getRedis();
- boolean flag = value.equals(jedis.get(key));
+ boolean flag = value.equals(jedis.get(key.toString()));
jedis.close();
return flag;
}
@@ -183,53 +181,7 @@ public class RedisTools {
private static boolean init = false;
- public static void initRedisPoolSub() {
- if (init)
- return;
- init = true;
- Log.i("初始化订阅");
- new Thread(new Runnable() {
- @Override
- public void run() {
- Jedis jedis = getPoolRedis();
- if (jedis != null)
- jedis.psubscribe(new Consumer(), "*");
- }
- }).start();
- }
-
- protected static class Consumer extends JedisPubSub {
- @Override
- public void onPMessage(String pattern, String channel, String message) {
- super.onPMessage(pattern, channel, message);
- Log.i("onPMessage: channel=" + channel + " msg=" + message + " pattern=" + pattern);
- switch (channel) {
- case "bot":
- bot(message);
- break;
- }
- }
-
- @Override
- public void onMessage(String channel, String message) {
- super.onMessage(channel, message);
- Log.i("onMessage: channel=" + channel + " msg=" + message);
- }
-
-
-
-
- public static void bot(String value) {
- switch (value) {
- case "getip":
- JSONObject json = JSONObject.parseObject(HttpTools.get("https://api.asilu.com/ip/"));
- String ip = json.getString("ip");
- QQBotManager.getInstance().sendMessage("服务器IP:\n" + ip);
- break;
- }
- }
- }
public static void main(String[] args) {
RedisTools.pullMsg("msg", "abc");
}
diff --git a/pom.xml b/pom.xml
index 73ced4c..f30b6c2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,16 +5,22 @@
org.springframework.boot
spring-boot-starter-parent
- 2.4.3
+ 3.3.0
com.yutou
bilibili
0.0.1-SNAPSHOT
+ pom
bilibili
Demo project for Spring Boot
+
+ biliapi
+ qqbot
+ common
+
- 1.8
+ 21
1.6.10
@@ -26,9 +32,9 @@
org.springframework.boot
spring-boot-starter-web-services
-
- mysql
- mysql-connector-java
+
+ com.mysql
+ mysql-connector-j
runtime
@@ -52,9 +58,9 @@
spring-boot-starter-websocket
- com.alibaba
- fastjson
- 1.2.80
+ com.alibaba.fastjson2
+ fastjson2
+ 2.0.22
org.xerial
@@ -64,18 +70,13 @@
org.projectlombok
lombok
- 1.18.22
+ annotationProcessor
org.java-websocket
Java-WebSocket
1.5.2
-
- mysql
- mysql-connector-java
- runtime
-
org.mybatis.spring.boot
mybatis-spring-boot-starter
@@ -103,27 +104,25 @@
4.1.2
-
- net.mamoe
- mirai-core-jvm
- 2.10.0
-
-
- org.jetbrains.kotlinx
- kotlinx-coroutines-jdk8
- 1.6.0-native-mt
-
-
- org.jetbrains.kotlinx
- kotlinx-coroutines-core-jvm
- 1.6.0-native-mt
-
redis.clients
jedis
4.2.0
+
+ com.yutou
+ common
+ 0.0.1-SNAPSHOT
+ compile
+
+
+ com.yutou
+ qqbot
+ 0.0.1-SNAPSHOT
+ compile
+
+
@@ -190,6 +189,14 @@
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 7
+ 7
+
+
diff --git a/qqbot/pom.xml b/qqbot/pom.xml
new file mode 100644
index 0000000..4c474c1
--- /dev/null
+++ b/qqbot/pom.xml
@@ -0,0 +1,29 @@
+
+
+ 4.0.0
+
+ com.yutou
+ bilibili
+ 0.0.1-SNAPSHOT
+
+
+ qqbot
+
+
+ 21
+ 21
+ UTF-8
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/qqbot/src/main/java/com/yutou/napcat/NapCatQQ.java b/qqbot/src/main/java/com/yutou/napcat/NapCatQQ.java
new file mode 100644
index 0000000..f1cf592
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/NapCatQQ.java
@@ -0,0 +1,57 @@
+package com.yutou.napcat;
+
+import com.yutou.napcat.handle.MessageHandleBuild;
+import com.yutou.napcat.handle.Text;
+import com.yutou.napcat.http.NapCatApi;
+import com.yutou.napcat.model.SendMessageResponse;
+import com.yutou.okhttp.HttpCallback;
+import okhttp3.Headers;
+
+import java.io.File;
+
+public class NapCatQQ {
+
+
+ private NapCatQQ() {
+
+ }
+
+ public static void main(String[] args) {
+ /* List> list = new ArrayList<>();
+ list.add(new Text("1", false));
+ list.add(new Text("2", false));
+ list.add(new Text("3"));
+ list.add(new Text("4", false));
+ list.add(new At(583819556L));
+ list.add(new Text("5"));
+ QQBotManager.getInstance().sendMessage(false, 891655174L, list);*/
+ NapCatApi.setLog(false);
+ File file = new File("C:\\Users\\58381\\Downloads\\0074TT8Yly1hp5mqidwqeg30g20f27wh.gif");
+ NapCatApi.getMessageApi().sendPrivateMsg(
+ MessageHandleBuild.create()
+ .setQQNumber(583819556L)
+ //.add(new Image(file))
+ .add(new Text("abc"))
+ .build()
+ ).enqueue(new HttpCallback() {
+ @Override
+ public void onResponse(Headers headers, int code, String status, SendMessageResponse response, String rawResponse) {
+ System.out.println("code = " + code + ", status = " + status + ", response = " + response + ", rawResponse = " + rawResponse);
+ }
+
+ @Override
+ public void onFailure(Throwable throwable) {
+ throwable.printStackTrace();
+ }
+ });
+ }
+ /**
+ * 私聊
+ {"self_id":240828363,"user_id":583819556,"time":1714472684,"message_id":376,"real_id":376,"message_type":"private","sender":{"user_id":583819556,"nickname":"魔芋","card":""},"raw_message":"123","font":14,"sub_type":"friend","message":[{"data":{"text":"123"},"type":"text"}],"message_format":"array","post_type":"message"}
+ */
+
+ /**
+ * 群聊
+ * {"self_id":240828363,"user_id":583819556,"time":1714472695,"message_id":377,"real_id":377,"message_type":"group","sender":{"user_id":583819556,"nickname":"魔芋","card":"","role":"owner"},"raw_message":"222","font":14,"sub_type":"normal","message":[{"data":{"text":"222"},"type":"text"}],"message_format":"array","post_type":"message","group_id":891655174}
+ */
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/QQDatabase.java b/qqbot/src/main/java/com/yutou/napcat/QQDatabase.java
new file mode 100644
index 0000000..46e5e7d
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/QQDatabase.java
@@ -0,0 +1,54 @@
+package com.yutou.napcat;
+
+import com.yutou.napcat.model.FriendBean;
+import com.yutou.napcat.model.GroupBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class QQDatabase {
+ private static Map data = new HashMap<>();
+
+ @Getter
+ @Setter
+ private static FriendBean me;
+
+ public static void addUser(Long qq, FriendBean bean) {
+ data.put(qq, bean);
+ }
+
+ public static void addGroup(Long qq, GroupBean bean) {
+ data.put(qq, bean);
+ }
+
+ public static boolean checkFriend(Long qq) {
+ if (data.containsKey(qq)) {
+ return data.get(qq) instanceof FriendBean;
+ }
+ return false;
+ }
+
+ public static boolean checkGroup(Long qq) {
+ if (data.containsKey(qq)) {
+ return data.get(qq) instanceof GroupBean;
+ }
+ return false;
+ }
+
+ public static List getGroups() {
+ List numbers = new ArrayList<>();
+ for (Long qq : data.keySet()) {
+ if (data.get(qq) instanceof GroupBean) {
+ {
+ numbers.add((GroupBean) data.get(qq));
+ }
+ }
+ }
+ return numbers;
+ }
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/QQNumberManager.java b/qqbot/src/main/java/com/yutou/napcat/QQNumberManager.java
new file mode 100644
index 0000000..7799209
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/QQNumberManager.java
@@ -0,0 +1,145 @@
+package com.yutou.napcat;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.yutou.utils.RedisTools;
+import redis.clients.jedis.Jedis;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+public class QQNumberManager {
+ private static QQNumberManager manager;
+ private QQNumberManager(){
+
+ }
+
+ public static QQNumberManager getManager() {
+ if(manager==null) {
+ manager=new QQNumberManager();
+ }
+ return manager;
+ }
+ public void addNumber(Long qq,boolean isGroup){
+ if(RedisTools.exists(qq,null)){
+ return;
+ }
+ JSONObject json=new JSONObject();
+ json.put("group",isGroup);
+ json.put("power",new JSONArray());
+ json.put("model",new JSONArray());
+ RedisTools.set(qq,json.toJSONString());
+ }
+ public List getNumber(){
+ List list =new ArrayList<>();
+ Jedis jedis=RedisTools.getRedis();
+ jedis.select(RedisTools.QQBOT_USER);
+ Set set=jedis.keys("*");
+ for (String s : set) {
+ try {
+ list.add(Long.parseLong(s));
+ }catch (Exception ignored){
+
+ }
+ }
+ jedis.close();
+ return list;
+ }
+ public boolean addPower(Long qq, String power){
+ if(RedisTools.exists(qq,null)){
+ JSONObject json=JSON.parseObject(RedisTools.get(qq));
+ JSONArray array=json.getJSONArray("power");
+ array.add(power);
+ json.put("power",array);
+ return RedisTools.set(qq,json.toJSONString());
+ }
+ return false;
+ }
+ public List getPower(Long qq){
+ List list=new ArrayList<>();
+ if(RedisTools.exists(qq,null)){
+ JSONObject json=JSON.parseObject(RedisTools.get(qq));
+ JSONArray array=json.getJSONArray("power");
+ for (Object power : array) {
+ list.add((String) power);
+ }
+ return list;
+ }
+ return list;
+ }
+ public List getUseModel(long qq) {
+ List list=new ArrayList<>();
+ if(RedisTools.exists(qq,null)){
+ JSONObject json=JSON.parseObject(RedisTools.get(qq));
+ JSONArray array=json.getJSONArray("model");
+ for (Object power : array) {
+ list.add((String) power);
+ }
+ return list;
+ }
+ return list;
+ }
+ public boolean delPower(Long qq, String power){
+ if(RedisTools.exists(qq,null)){
+ JSONObject json=JSON.parseObject(RedisTools.get(qq));
+ JSONArray array=json.getJSONArray("power");
+ array.remove(power);
+ json.put("power",array);
+ return RedisTools.set(qq,json.toJSONString());
+ }
+ return false;
+ }
+ public boolean addUseModel(Long qq,Class> modelClass){
+ if(RedisTools.exists(qq,null)){
+ JSONObject json=JSON.parseObject(RedisTools.get(qq));
+ JSONArray array=json.getJSONArray("model");
+ array.add(modelClass.getName());
+ json.put("model",array);
+ return RedisTools.set(qq,json.toJSONString());
+ }
+ return false;
+ }
+ public boolean delUseModel(Long qq,Class> modelClass){
+ if(RedisTools.exists(qq,null)){
+ JSONObject json=JSON.parseObject(RedisTools.get(qq));
+ JSONArray array=json.getJSONArray("model");
+ array.remove(modelClass.getName());
+ json.put("model",array);
+ return RedisTools.set(qq,json.toJSONString());
+ }
+ return false;
+ }
+ public boolean isExistsPower(Long qq, String... power){
+ //1
+ if(RedisTools.exists(qq,null)){
+ JSONObject json=JSON.parseObject(RedisTools.get(qq));
+ JSONArray array=json.getJSONArray("power");
+ for (String key : power) {
+ if(!array.contains(key)){
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+ public boolean isGroup(Long qq){
+ if(RedisTools.exists(qq,null)){
+ JSONObject json= JSON.parseObject(RedisTools.get(qq));
+ return json.getBooleanValue("group");
+ }
+ return false;
+ }
+ public boolean isUseModel(Long qq,Class> modelClass){
+ if(RedisTools.exists(qq,null)){
+ JSONObject json=JSON.parseObject(RedisTools.get(qq));
+ JSONArray array=json.getJSONArray("model");
+ return array.contains(modelClass.getName());
+ }
+ return false;
+ }
+
+
+}
\ No newline at end of file
diff --git a/qqbot/src/main/java/com/yutou/napcat/enums/MessageEnum.java b/qqbot/src/main/java/com/yutou/napcat/enums/MessageEnum.java
new file mode 100644
index 0000000..9a93a93
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/enums/MessageEnum.java
@@ -0,0 +1,29 @@
+package com.yutou.napcat.enums;
+
+public enum MessageEnum {
+ TEXT("text"),
+ IMAGE("image"),
+ AT("at"),
+ REPLY("reply"),
+ JSON("json");
+
+ String type;
+
+ MessageEnum(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public static MessageEnum of(String type) {
+ for (MessageEnum messageEnum : MessageEnum.values()) {
+ if (messageEnum.getType().equals(type)) {
+ return messageEnum;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/enums/RecordFormatEnum.java b/qqbot/src/main/java/com/yutou/napcat/enums/RecordFormatEnum.java
new file mode 100644
index 0000000..052fb0c
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/enums/RecordFormatEnum.java
@@ -0,0 +1,28 @@
+package com.yutou.napcat.enums;
+
+public enum RecordFormatEnum {
+ MP3("mp3"),
+ AMR("amr"),
+ WMA("wma"),
+ M4A("m4a"),
+ SPX("spx"),
+ OGG("ogg"),
+ WAV("wav"),
+ FLAC("flac");
+
+
+ private final String format;
+
+ RecordFormatEnum(String format) {
+ this.format = format;
+ }
+
+ public String getFormat() {
+ return format;
+ }
+
+ @Override
+ public String toString() {
+ return format;
+ }
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/event/GroupMessageEvent.java b/qqbot/src/main/java/com/yutou/napcat/event/GroupMessageEvent.java
new file mode 100644
index 0000000..0d4a9b6
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/event/GroupMessageEvent.java
@@ -0,0 +1,12 @@
+package com.yutou.napcat.event;
+
+import com.yutou.napcat.model.GroupFrom;
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class GroupMessageEvent extends MessageEvent {
+ private GroupFrom group;
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/event/MessageEvent.java b/qqbot/src/main/java/com/yutou/napcat/event/MessageEvent.java
new file mode 100644
index 0000000..977db2b
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/event/MessageEvent.java
@@ -0,0 +1,183 @@
+package com.yutou.napcat.event;
+
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.napcat.QQDatabase;
+import com.yutou.napcat.enums.MessageEnum;
+import com.yutou.napcat.handle.*;
+import com.yutou.napcat.model.SourceFrom;
+import lombok.Data;
+import lombok.val;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class MessageEvent {
+
+ @JSONField(name = "self_id")
+ private Long selfId;
+
+ @JSONField(name = "user_id")
+ private Long userId;
+
+ @JSONField(name = "time")
+ private Long time;
+
+ @JSONField(name = "message_id")
+ private Integer messageId;
+
+ @JSONField(name = "real_id")
+ private Integer realId;
+
+ @JSONField(name = "message_type")
+ private String messageType;
+
+ @JSONField(name = "sender")
+ private SourceFrom source;
+
+ @JSONField(name = "raw_message")
+ private String rawMessage;
+
+ @JSONField(name = "font")
+ private Integer font;
+
+ @JSONField(name = "sub_type")
+ private String subType;
+
+ @JSONField(name = "message")
+ private List> message;
+
+ @JSONField(name = "message_format")
+ private String messageFormat;
+
+ @JSONField(name = "post_type")
+ private String postType;
+
+ @JSONField(name = "group_id")
+ private Long groupId;
+
+
+ public static MessageEvent parseHandleHttp(String jsonString) {
+
+ return parseHandle(JSONObject.parseObject(jsonString).getJSONObject("data").toString());
+ }
+
+ public static MessageEvent parseHandle(String jsonString) {
+ JSONObject json = JSONObject.parseObject(jsonString);
+
+ JSONArray array = json.getJSONArray("message");
+ List> messageList = new ArrayList<>();
+ for (Object o : array) {
+ JSONObject _json = (JSONObject) o;
+ Type classType = null;
+ MessageEnum _type = MessageEnum.of(_json.getString("type"));
+ classType = switch (_type) {
+ case TEXT -> Text.TextInfo.class;
+ case IMAGE -> Image.ImageInfo.class;
+ case AT -> At.AtData.class;
+ case JSON -> OtherHandle.OtherInfo.class;
+ case REPLY -> Reply.ReplyInfo.class;
+ default -> classType;
+ };
+ BaseHandle> handle = new BaseHandle<>(_type.getType());
+ if (_type == MessageEnum.JSON) {
+ handle.setData(JSONObject.parseObject(((JSONObject) o).getJSONObject("data").getString("data"), classType));
+ } else {
+ handle.setData(JSONObject.parseObject(((JSONObject) o).getJSONObject("data").toString(), classType));
+ }
+ messageList.add(handle);
+ }
+
+
+ SourceFrom sender = new SourceFrom();
+ sender.setUserId(json.getJSONObject("sender").getLong("user_id"));
+ sender.setNickname(json.getJSONObject("sender").getString("nickname"));
+ sender.setCard(json.getJSONObject("sender").getString("card"));
+
+ MessageEvent event = new MessageEvent();
+ event.setSelfId(json.getLong("self_id"));
+ event.setUserId(json.getLong("user_id"));
+ event.setTime(json.getLong("time"));
+ event.setMessageId(json.getInteger("message_id"));
+ event.setRealId(json.getInteger("real_id"));
+ event.setMessageType(json.getString("message_type"));
+ event.setSource(sender);
+ event.setRawMessage(json.getString("raw_message"));
+ event.setFont(json.getInteger("font"));
+ event.setSubType(json.getString("sub_type"));
+ event.setMessageFormat(json.getString("message_format"));
+ event.setPostType(json.getString("post_type"));
+ event.setGroupId(json.getLong("group_id"));
+ event.setMessage(messageList);
+ return event;
+ }
+
+ public boolean hasType(MessageEnum messageEnum) {
+ for (BaseHandle> handle : message) {
+ if (MessageEnum.of(handle.getType()) == messageEnum) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public List findAllType(Class t) {
+ List tmp = new ArrayList<>();
+ try {
+ T newed = t.getDeclaredConstructor().newInstance();
+ for (BaseHandle> baseHandle : message) {
+ if (baseHandle.getType().equals(newed.getType())) {
+ newed.setData(baseHandle.getData());
+ tmp.add(newed);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return tmp;
+ }
+
+ public T findType(Class tClass) {
+ List list = findAllType(tClass);
+ if (list == null || list.isEmpty()) {
+ return null;
+ }
+ return list.get(0);
+ }
+
+
+ public boolean isAtMe() {
+ if (!hasType(MessageEnum.AT)) {
+ return false;
+ }
+ List list = findAllType(At.class);
+ for (At handle : list) {
+ if (handle.getData().getQq() == QQDatabase.getMe().getUserId()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public String getTextMessage() {
+ val texts = findAllType(Text.class);
+ StringBuilder sb = new StringBuilder();
+ for (Text text : texts) {
+ sb.append(text);
+ }
+ return sb.toString().trim();
+ }
+
+ public boolean isUser() {
+ return "private".equals(messageType);
+ }
+
+ public boolean isGroup() {
+ return "group".equals(messageType);
+ }
+
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/handle/At.java b/qqbot/src/main/java/com/yutou/napcat/handle/At.java
new file mode 100644
index 0000000..866f6fb
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/handle/At.java
@@ -0,0 +1,32 @@
+package com.yutou.napcat.handle;
+
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+
+public class At extends BaseHandle {
+ public At() {
+ super("at");
+ }
+
+ public At(Long userId) {
+ super("at");
+ data = new AtData(userId);
+ }
+
+ @Override
+ public String toString() {
+ if (data == null) {
+ return null;
+ }
+ return String.format("[CQ:at,qq=%d]", data.qq);
+ }
+
+ @Data
+ public class AtData extends BaseBean {
+ private Long qq;
+
+ public AtData(Long qq) {
+ this.qq = qq;
+ }
+ }
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/handle/BaseHandle.java b/qqbot/src/main/java/com/yutou/napcat/handle/BaseHandle.java
new file mode 100644
index 0000000..376a6a5
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/handle/BaseHandle.java
@@ -0,0 +1,22 @@
+package com.yutou.napcat.handle;
+
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+
+@Data
+public class BaseHandle extends BaseBean {
+ protected String type;
+ protected T data;
+ protected String src;
+
+ public BaseHandle(String type) {
+ this.type = type;
+ }
+
+
+ public BaseHandle(String type, Object obj) {
+ super();
+ this.type = type;
+ this.data= (T) obj;
+ }
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/handle/Image.java b/qqbot/src/main/java/com/yutou/napcat/handle/Image.java
new file mode 100644
index 0000000..ab035bf
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/handle/Image.java
@@ -0,0 +1,35 @@
+package com.yutou.napcat.handle;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.utils.Base64Tools;
+import lombok.Data;
+
+import java.io.File;
+
+public class Image extends BaseHandle {
+
+ public Image() {
+ super("image");
+ }
+
+ public Image(String imageUrl) {
+ super("image");
+ data = new ImageInfo(imageUrl);
+ }
+ public Image(File imageFile){
+ super("image");
+ data=new ImageInfo("base64://"+ Base64Tools.encode(imageFile));
+ }
+
+ @Data
+ public static class ImageInfo {
+ String file;
+ String url;
+ @JSONField(name = "file_size")
+ String fileSize;
+
+ public ImageInfo(String file) {
+ this.file = file;
+ }
+ }
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/handle/MessageHandleBuild.java b/qqbot/src/main/java/com/yutou/napcat/handle/MessageHandleBuild.java
new file mode 100644
index 0000000..9486daa
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/handle/MessageHandleBuild.java
@@ -0,0 +1,53 @@
+package com.yutou.napcat.handle;
+
+import com.alibaba.fastjson2.JSONObject;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MessageHandleBuild {
+ private List> msgList = new ArrayList<>();
+ private long qq;
+ private boolean autoEscape;
+ private boolean isGroup;
+
+ public static MessageHandleBuild create() {
+ return new MessageHandleBuild();
+ }
+
+ private MessageHandleBuild() {
+ msgList = new ArrayList<>();
+ }
+
+ public MessageHandleBuild setQQNumber(long qq) {
+ this.qq = qq;
+ return this;
+ }
+
+ public MessageHandleBuild setAutoEscape(boolean autoEscape) {
+ this.autoEscape = autoEscape;
+ return this;
+ }
+
+ public MessageHandleBuild add(BaseHandle> msg) {
+ msgList.add(msg);
+ return this;
+ }
+
+ public MessageHandleBuild setGroup(boolean group) {
+ isGroup = group;
+ return this;
+ }
+
+ public JSONObject build() {
+ JSONObject json=new JSONObject();
+ if(isGroup){
+ json.put("group_id", qq);
+ }else {
+ json.put("user_id", qq);
+ }
+ json.put("auto_escape", autoEscape);
+ json.put("message", msgList);
+ return json;
+ }
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/handle/OtherHandle.java b/qqbot/src/main/java/com/yutou/napcat/handle/OtherHandle.java
new file mode 100644
index 0000000..800c8b6
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/handle/OtherHandle.java
@@ -0,0 +1,19 @@
+package com.yutou.napcat.handle;
+
+import com.yutou.napcat.model.AppShareBean;
+import lombok.Data;
+
+public class OtherHandle extends BaseHandle{
+
+ public OtherHandle() {
+ super("json");
+ data= new OtherInfo();
+ }
+
+
+ @Data
+ public static class OtherInfo extends AppShareBean{
+
+
+ }
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/handle/QuoteReply.java b/qqbot/src/main/java/com/yutou/napcat/handle/QuoteReply.java
new file mode 100644
index 0000000..cab5cad
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/handle/QuoteReply.java
@@ -0,0 +1,14 @@
+package com.yutou.napcat.handle;
+
+public class QuoteReply {
+ private final String messageId;
+
+ public QuoteReply(String messageId) {
+ this.messageId = messageId;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("[CQ:reply,id=%s]",messageId);
+ }
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/handle/Record.java b/qqbot/src/main/java/com/yutou/napcat/handle/Record.java
new file mode 100644
index 0000000..bec8dfd
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/handle/Record.java
@@ -0,0 +1,38 @@
+package com.yutou.napcat.handle;
+
+import com.yutou.utils.ConfigTools;
+import lombok.Data;
+
+public class Record extends BaseHandle {
+
+ public Record() {
+ super("record");
+ }
+
+ public Record(String file) {
+ super("record");
+ data = new RecordInfo(file);
+ }
+
+ public Record(String file, boolean proxy) {
+ super("record");
+ data = new RecordInfo(file);
+ data.proxy = proxy ? "1" : "0";
+ }
+
+
+ @Data
+ public static class RecordInfo {
+ String file;
+ int magic;
+ String url;
+ String cache;
+ String proxy;
+ String timeout;
+
+ public RecordInfo(String file) {
+ this.file = file;
+ }
+
+ }
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/handle/Reply.java b/qqbot/src/main/java/com/yutou/napcat/handle/Reply.java
new file mode 100644
index 0000000..76aaedc
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/handle/Reply.java
@@ -0,0 +1,24 @@
+package com.yutou.napcat.handle;
+
+import lombok.Data;
+
+public class Reply extends BaseHandle {
+
+ public Reply() {
+ super("reply");
+ }
+
+ public Reply(long id) {
+ super("reply");
+ data = new ReplyInfo(id);
+ }
+
+ @Data
+ public static class ReplyInfo {
+ private long id;
+
+ public ReplyInfo(long id) {
+ this.id = id;
+ }
+ }
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/handle/Text.java b/qqbot/src/main/java/com/yutou/napcat/handle/Text.java
new file mode 100644
index 0000000..db82d5c
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/handle/Text.java
@@ -0,0 +1,51 @@
+package com.yutou.napcat.handle;
+
+import lombok.Data;
+
+public class Text extends BaseHandle {
+
+ public Text() {
+ super("text");
+ }
+
+ public Text(String text) {
+ super("text");
+ data = new TextInfo(text + "\n");
+ }
+
+ public Text(String text, boolean isNewLine) {
+ super("text");
+ if (isNewLine) {
+ data = new TextInfo(text + "\n");
+ } else {
+ data = new TextInfo(text);
+ }
+ }
+
+ public Text(boolean isNewLine, String... text) {
+ super("text");
+ StringBuilder sb = new StringBuilder();
+ for (String s : text) {
+ sb.append(s);
+ }
+ if (isNewLine) {
+ data = new TextInfo(sb + "\n");
+ } else {
+ data = new TextInfo(sb.toString());
+ }
+ }
+
+ @Override
+ public String toString() {
+ return data.text.trim();
+ }
+
+ @Data
+ public static class TextInfo {
+ String text;
+
+ public TextInfo(String text) {
+ this.text = text.trim();
+ }
+ }
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/http/FriendApi.java b/qqbot/src/main/java/com/yutou/napcat/http/FriendApi.java
new file mode 100644
index 0000000..324da72
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/http/FriendApi.java
@@ -0,0 +1,14 @@
+package com.yutou.napcat.http;
+
+import com.yutou.napcat.model.FriendBean;
+import com.yutou.okhttp.HttpBody;
+import retrofit2.Call;
+import retrofit2.http.POST;
+
+import java.util.List;
+
+public interface FriendApi {
+ @POST("/get_friend_list")
+ Call>> getFriendList(
+ );
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/http/GroupApi.java b/qqbot/src/main/java/com/yutou/napcat/http/GroupApi.java
new file mode 100644
index 0000000..1901c9c
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/http/GroupApi.java
@@ -0,0 +1,70 @@
+package com.yutou.napcat.http;
+
+import com.yutou.napcat.model.GroupBean;
+import com.yutou.napcat.model.GroupUserBean;
+import com.yutou.okhttp.BaseBean;
+import com.yutou.okhttp.HttpBody;
+import retrofit2.Call;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.POST;
+
+import java.util.List;
+
+public interface GroupApi {
+ /**
+ * 禁言
+ * @param group 群号
+ * @param user 用户
+ * @param duration 禁言时长,单位秒
+ *
+ */
+ @FormUrlEncoded
+ @POST("/set_group_ban")
+ Call> groupBan(
+ @Field("group_id") long group,
+ @Field("user_id") long user,
+ @Field("duration") long duration
+ );
+
+ /**
+ * 禁言群组全体成员
+ * @param group 群号
+ */
+ @FormUrlEncoded
+ @POST("/set_group_whole_ban")
+ Call> groupBanAll(
+ @Field("group_id") long group
+ );
+
+ /**
+ * 获取群组列表
+ */
+ @POST("/get_group_list")
+ Call>> getGroupList(
+ );
+
+ /**
+ * 获取群组信息
+ */
+ @POST("/get_group_info")
+ Call> getGroupInfo(
+ );
+
+ /**
+ * 获取群组成员信息
+ */
+ @POST("/get_group_member_info")
+ Call> getGroupUserInfo(
+ );
+
+ /**
+ * 获取群组成员列表
+ * @param group 群号
+ */
+ @FormUrlEncoded
+ @POST("/get_group_member_list")
+ Call> getGroupUserList(
+ @Field("group_id") long group
+ );
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/http/MessageAPI.java b/qqbot/src/main/java/com/yutou/napcat/http/MessageAPI.java
new file mode 100644
index 0000000..2986cc1
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/http/MessageAPI.java
@@ -0,0 +1,50 @@
+package com.yutou.napcat.http;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.yutou.napcat.model.MessageBean;
+import com.yutou.napcat.model.SendMessageResponse;
+import com.yutou.okhttp.BaseBean;
+import com.yutou.okhttp.HttpBody;
+import retrofit2.Call;
+import retrofit2.http.Body;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.POST;
+
+public interface MessageAPI {
+ /**
+ * 发送私聊消息
+ * @param message {@link com.yutou.napcat.handle.MessageHandleBuild}
+ * @return 消息id
+ */
+ @POST("/send_private_msg")
+ Call> sendPrivateMsg(
+ @Body
+ JSONObject message);
+ /**
+ * 发送群聊消息
+ * @param message 消息内容
+ * @return 消息id
+ */
+ @POST("/send_group_msg")
+ Call> sendGroupMsg(
+ @Body
+ JSONObject message
+ );
+
+ /**
+ * 撤回消息
+ * @param messageId 消息id
+ */
+ @FormUrlEncoded
+ @POST("/delete_msg")
+ Call> delMsg(
+ @Field("message_id") long messageId
+ );
+
+ @FormUrlEncoded
+ @POST("/get_msg")
+ Call> getMessage(
+ @Field("message_id") long messageId
+ );
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/http/NapCatApi.java b/qqbot/src/main/java/com/yutou/napcat/http/NapCatApi.java
new file mode 100644
index 0000000..85287de
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/http/NapCatApi.java
@@ -0,0 +1,33 @@
+package com.yutou.napcat.http;
+
+import com.yutou.okhttp.HttpLoggingInterceptor;
+import com.yutou.okhttp.api.BaseApi;
+import com.yutou.utils.ConfigTools;
+
+public class NapCatApi extends BaseApi {
+ private static final String URL;
+ static {
+ URL= ConfigTools.load(ConfigTools.CONFIG,ConfigTools.NAPCAT_URL,String.class);
+ }
+
+ public NapCatApi() {
+ super(URL);
+ }
+
+ public static void setLog(boolean log){
+ HttpLoggingInterceptor.setLog(log);
+ }
+
+ public static MessageAPI getMessageApi(){
+ return new NapCatApi().setURL(URL).createApi(MessageAPI.class);
+ }
+ public static UtilsApi getUtilsApi(){
+ return new NapCatApi().setURL(URL).createApi(UtilsApi.class);
+ }
+ public static GroupApi getGroupApi(){
+ return new NapCatApi().setURL(URL).createApi(GroupApi.class);
+ }
+ public static FriendApi getFriendApi(){
+ return new NapCatApi().setURL(URL).createApi(FriendApi.class);
+ }
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/http/UtilsApi.java b/qqbot/src/main/java/com/yutou/napcat/http/UtilsApi.java
new file mode 100644
index 0000000..63a0ab7
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/http/UtilsApi.java
@@ -0,0 +1,80 @@
+package com.yutou.napcat.http;
+
+import com.yutou.napcat.model.*;
+import com.yutou.okhttp.BaseBean;
+import com.yutou.okhttp.HttpBody;
+import retrofit2.Call;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.POST;
+
+public interface UtilsApi {
+ /**
+ * 获取语音
+ *
+ * @param fileId 收到的语音文件名(消息段的 file 参数),如 0B38145AA44505000B38145AA4450500.silk
+ * @param format 要转换到的格式,目前支持 mp3、amr、wma、m4a、spx、ogg、wav、flac {@link com.yutou.napcat.enums.RecordFormatEnum}
+ * @return 转换后的语音文件路径
+ */
+ @FormUrlEncoded
+ @POST("/get_record")
+ Call> getMessageRecord(
+ @Field("file") String fileId,
+ @Field("out_format") String format
+ );
+
+ /**
+ * 获取图片
+ *
+ * @param fileId 收到的图片文件名(消息段的 file 参数)
+ * @return 下载后的图片文件路径
+ */
+ @FormUrlEncoded
+ @POST("/get_image")
+ Call> getMessageImage(
+ @Field("file") String fileId
+ );
+
+ /**
+ * 检查是否可以发送图片
+ */
+ @POST("/can_send_image")
+ Call> checkSendImage(
+ );
+
+ /**
+ * 检查是否可以发送语音
+ */
+ @POST("/can_send_record")
+ Call> checkSendRecord(
+ );
+
+ /**
+ * 获取机器人状态
+ */
+ @POST("/get_status")
+ Call> checkQQBotStatus(
+ );
+
+ /**
+ * 获取机器人版本信息
+ */
+ @POST("/get_version_info")
+ Call> checkQQBotVersion(
+ );
+
+ /**
+ * 清理缓存
+ */
+ @POST("/clean_cache")
+ Call> cleanCache(
+ );
+
+ /**
+ * 获取登录信息
+ */
+ @POST("/get_login_info")
+ Call> getLoginInfo(
+ );
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/AppShareBean.java b/qqbot/src/main/java/com/yutou/napcat/model/AppShareBean.java
new file mode 100644
index 0000000..b6da655
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/AppShareBean.java
@@ -0,0 +1,139 @@
+package com.yutou.napcat.model;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+
+import java.util.Map;
+
+@Data
+
+public class AppShareBean extends BaseBean {
+
+ @JSONField(name = "ver")
+ private String version;
+
+ @JSONField(name = "prompt")
+ private String prompt;
+
+ @JSONField(name = "config")
+ private Config config;
+
+ @JSONField(name = "needShareCallBack")
+ private boolean needShareCallBack;
+
+ @JSONField(name = "app")
+ private String app;
+
+ @JSONField(name = "view")
+ private String view;
+
+ @JSONField(name = "meta")
+ private Meta meta;
+
+ // getters and setters...
+
+ // Inner classes
+
+ @Data
+ public static class Config {
+ @JSONField(name = "type")
+ private String type;
+
+ @JSONField(name = "width")
+ private int width;
+
+ @JSONField(name = "height")
+ private int height;
+
+ @JSONField(name = "forward")
+ private int forward;
+
+ @JSONField(name = "autoSize")
+ private int autoSize;
+
+ @JSONField(name = "ctime")
+ private long ctime;
+
+ @JSONField(name = "token")
+ private String token;
+
+ // getters and setters...
+ }
+
+ @Data
+ public static class Meta {
+ @JSONField(name = "detail_1")
+ private Detail detail1;
+
+ // If there can be multiple "detail_X" entries, you might need a Map
+ // @JSONField(name = "detail_X")
+ // private Map details;
+
+ // getters and setters...
+ }
+
+ @Data
+ public static class Detail {
+ @JSONField(name = "appid")
+ private String appid;
+
+ @JSONField(name = "appType")
+ private int appType;
+
+ @JSONField(name = "title")
+ private String title;
+
+ @JSONField(name = "desc")
+ private String desc;
+
+ @JSONField(name = "icon")
+ private String icon;
+
+ @JSONField(name = "preview")
+ private String preview;
+
+ @JSONField(name = "url")
+ private String url;
+
+ @JSONField(name = "scene")
+ private int scene;
+
+ @JSONField(name = "host")
+ private Host host;
+
+ @JSONField(name = "shareTemplateId")
+ private String shareTemplateId;
+
+ // Since "shareTemplateData" is an empty object, it can be left as a Map or a specific class
+ // if you know the structure of the data that might be there
+ @JSONField(name = "shareTemplateData")
+ private Map shareTemplateData;
+
+ @JSONField(name = "qqdocurl")
+ private String qqdocurl;
+
+ @JSONField(name = "showLittleTail")
+ private String showLittleTail;
+
+ @JSONField(name = "gamePoints")
+ private String gamePoints;
+
+ @JSONField(name = "gamePointsUrl")
+ private String gamePointsUrl;
+
+ // getters and setters...
+ }
+
+ @Data
+ public static class Host {
+ @JSONField(name = "uin")
+ private long uin;
+
+ @JSONField(name = "nick")
+ private String nick;
+
+ // getters and setters...
+ }
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/CheckSendImageBean.java b/qqbot/src/main/java/com/yutou/napcat/model/CheckSendImageBean.java
new file mode 100644
index 0000000..fe7823d
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/CheckSendImageBean.java
@@ -0,0 +1,12 @@
+package com.yutou.napcat.model;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+
+@Data
+public class CheckSendImageBean extends BaseBean {
+ @JSONField(name = "yes")
+ private boolean yes;
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/CheckSendRecordBean.java b/qqbot/src/main/java/com/yutou/napcat/model/CheckSendRecordBean.java
new file mode 100644
index 0000000..89b16ef
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/CheckSendRecordBean.java
@@ -0,0 +1,12 @@
+package com.yutou.napcat.model;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+
+@Data
+public class CheckSendRecordBean extends BaseBean {
+ @JSONField(name = "yes")
+ private boolean yes;
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/FriendBean.java b/qqbot/src/main/java/com/yutou/napcat/model/FriendBean.java
new file mode 100644
index 0000000..db53c52
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/FriendBean.java
@@ -0,0 +1,15 @@
+package com.yutou.napcat.model;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+
+@Data
+public class FriendBean extends BaseBean {
+ @JSONField(name = "user_id")
+ private long userId;//qq号
+ @JSONField(name = "nickname")
+ private String nickName;//昵称
+ @JSONField(name = "remark")
+ private String remark;//备注
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/GroupBean.java b/qqbot/src/main/java/com/yutou/napcat/model/GroupBean.java
new file mode 100644
index 0000000..1d7c9ab
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/GroupBean.java
@@ -0,0 +1,18 @@
+package com.yutou.napcat.model;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+
+@Data
+public class GroupBean extends BaseBean {
+ @JSONField(name = "group_id")
+ private long groupId;
+ @JSONField(name = "group_name")
+ private String groupName;
+ @JSONField(name = "member_count")
+ private int userCount;
+ @JSONField(name = "max_member_count")
+ private int userMaxCount;
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/GroupFrom.java b/qqbot/src/main/java/com/yutou/napcat/model/GroupFrom.java
new file mode 100644
index 0000000..1b3b278
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/GroupFrom.java
@@ -0,0 +1,8 @@
+package com.yutou.napcat.model;
+
+import lombok.Data;
+
+@Data
+public class GroupFrom {
+ private long id;
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/GroupUserBean.java b/qqbot/src/main/java/com/yutou/napcat/model/GroupUserBean.java
new file mode 100644
index 0000000..9e20250
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/GroupUserBean.java
@@ -0,0 +1,69 @@
+package com.yutou.napcat.model;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+
+@Data
+public class GroupUserBean extends BaseBean {
+ // 群号
+ @JSONField(name = "group_id")
+ private long groupId;
+
+ // QQ号
+ @JSONField(name = "user_id")
+ private long userId;
+
+ // 昵称
+ @JSONField(name = "nickname")
+ private String nickname;
+
+ // 群名片/备注
+ @JSONField(name = "card")
+ private String card;
+
+ // 性别,male 或 female 或 unknown
+ @JSONField(name = "sex")
+ private String sex;
+
+ // 年龄
+ @JSONField(name = "age")
+ private int age;
+
+ // 地区
+ @JSONField(name = "area")
+ private String area;
+
+ // 加群时间戳
+ @JSONField(name = "join_time")
+ private int joinTime;
+
+ // 最后发言时间戳
+ @JSONField(name = "last_sent_time")
+ private int lastSentTime;
+
+ // 成员等级
+ @JSONField(name = "level")
+ private String level;
+
+ // 角色,owner 或 admin 或 member
+ @JSONField(name = "role")
+ private String role;
+
+ // 是否不良记录成员
+ @JSONField(name = "unfriendly")
+ private boolean unfriendly;
+
+ // 专属头衔
+ @JSONField(name = "title")
+ private String title;
+
+ // 专属头衔过期时间戳
+ @JSONField(name = "title_expire_time")
+ private int titleExpireTime;
+
+ // 是否允许修改群名片
+ @JSONField(name = "card_changeable")
+ private boolean cardChangeable;
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/Message.java b/qqbot/src/main/java/com/yutou/napcat/model/Message.java
new file mode 100644
index 0000000..962a07d
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/Message.java
@@ -0,0 +1,23 @@
+package com.yutou.napcat.model;
+
+import lombok.Data;
+
+@Data
+public class Message {
+ private String message;
+ private String srcMessage;
+ private String id;
+ public Message(String message, String srcMessage) {
+ this.message = message;
+ this.srcMessage = srcMessage;
+ }
+
+ public String serializeToMiraiCode(){
+ return srcMessage;
+ }
+
+ public String contentToString(){
+ return message;
+ }
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/MessageBean.java b/qqbot/src/main/java/com/yutou/napcat/model/MessageBean.java
new file mode 100644
index 0000000..df79626
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/MessageBean.java
@@ -0,0 +1,45 @@
+package com.yutou.napcat.model;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+
+/**
+ * 消息
+ * @see 文档
+ */
+@Data
+public class MessageBean extends BaseBean {
+ /**
+ *发送时间
+ */
+ @JSONField(name = "time")
+ private long time;
+ /**
+ * 消息类型,同 消息事件
+ */
+ @JSONField(name = "message_type")
+ private String type;
+ /**
+ * 消息 ID
+ */
+ @JSONField(name = "message_id")
+ private int messageId;
+ /**
+ * 消息真实 ID
+ */
+ @JSONField(name = "real_id")
+ private int realId;
+ /**
+ * 发送人信息,同 消息事件
+ */
+ @JSONField(name = "sender")
+ private SenderBean sender;
+ /**
+ * 消息内容
+ */
+ @JSONField(name = "message")
+ private String message;
+
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/QQBotStatusBean.java b/qqbot/src/main/java/com/yutou/napcat/model/QQBotStatusBean.java
new file mode 100644
index 0000000..24b0498
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/QQBotStatusBean.java
@@ -0,0 +1,13 @@
+package com.yutou.napcat.model;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+
+@Data
+public class QQBotStatusBean extends BaseBean {
+ @JSONField(name = "online")
+ private String online;//当前 QQ 在线,null 表示无法查询到在线状态
+ @JSONField(name = "good")
+ private String good;//状态符合预期,意味着各模块正常运行、功能正常,且 QQ 在线
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/QQBotVersionBean.java b/qqbot/src/main/java/com/yutou/napcat/model/QQBotVersionBean.java
new file mode 100644
index 0000000..9ba668e
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/QQBotVersionBean.java
@@ -0,0 +1,17 @@
+package com.yutou.napcat.model;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.Data;
+
+@Data
+public class QQBotVersionBean {
+ @JSONField(name = "app_name")
+ private String appName;//应用标识,如 mirai-native
+
+ @JSONField(name = "app_version")
+ private String appVersion;//应用版本,如 1.2.3
+
+ @JSONField(name = "protocol_version")
+ private String protocolVersion;//OneBot 标准版本,如 v11
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/SendMessageRequest.java b/qqbot/src/main/java/com/yutou/napcat/model/SendMessageRequest.java
new file mode 100644
index 0000000..feb73c7
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/SendMessageRequest.java
@@ -0,0 +1,21 @@
+package com.yutou.napcat.model;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.google.gson.annotations.SerializedName;
+import com.yutou.napcat.handle.BaseHandle;
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class SendMessageRequest extends BaseBean {
+ @JSONField(name = "user_id")
+ private long userId;
+ @JSONField
+ List> message;
+ @SerializedName("auto_escape")
+ private boolean notCQCode;
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/SendMessageResponse.java b/qqbot/src/main/java/com/yutou/napcat/model/SendMessageResponse.java
new file mode 100644
index 0000000..c8b0df3
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/SendMessageResponse.java
@@ -0,0 +1,16 @@
+package com.yutou.napcat.model;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class SendMessageResponse extends BaseBean {
+ @JSONField( name = "message_id")
+ private int id;
+
+ private String e;
+
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/SenderBean.java b/qqbot/src/main/java/com/yutou/napcat/model/SenderBean.java
new file mode 100644
index 0000000..ffc1596
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/SenderBean.java
@@ -0,0 +1,24 @@
+package com.yutou.napcat.model;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+
+/**
+ * 发送人结构体
+ *
+ */
+@Data
+public class SenderBean extends BaseBean {
+ @JSONField(name = "user_id")
+ private long userId;
+ @JSONField(name = "nickname")
+ private String nickName;
+ /**
+ * male 或 female 或 unknown
+ */
+ @JSONField(name = "sex")
+ private String sex;
+ @JSONField(name = "age")
+ private int age;
+}
diff --git a/qqbot/src/main/java/com/yutou/napcat/model/SourceFrom.java b/qqbot/src/main/java/com/yutou/napcat/model/SourceFrom.java
new file mode 100644
index 0000000..0dc3553
--- /dev/null
+++ b/qqbot/src/main/java/com/yutou/napcat/model/SourceFrom.java
@@ -0,0 +1,17 @@
+package com.yutou.napcat.model;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.Data;
+
+@Data
+public class SourceFrom {
+ @JSONField(name = "user_id")
+ private long userId;
+ private String nickname;
+ private String card;
+ private String role;
+
+ public Long getFromId() {
+ return userId;
+ }
+}
diff --git a/src/main/java/com/yutou/bilibili/BiliBili/Controllers/BiliUserController.java b/src/main/java/com/yutou/bilibili/BiliBili/Controllers/BiliUserController.java
deleted file mode 100644
index c31c033..0000000
--- a/src/main/java/com/yutou/bilibili/BiliBili/Controllers/BiliUserController.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package com.yutou.bilibili.BiliBili.Controllers;
-
-import com.alibaba.fastjson.JSONObject;
-import com.yutou.bilibili.BiliBili.LiveUtils;
-import com.yutou.bilibili.Tools.AppTools;
-import org.springframework.stereotype.Controller;
-import org.springframework.util.StringUtils;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
-
-import java.io.File;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-
-@Controller
-@RequestMapping("/bili/")
-public class BiliUserController {
- @ResponseBody
- @RequestMapping("/login/get/test.do")
- public JSONObject testLogin(){
- JSONObject json=new JSONObject();
- if(StringUtils.isEmpty(AppTools.readFile(new File("cookies.json")))){
- json.put("code",-1);
- json.put("msg","未登录");
- }else{
- JSONObject login= LiveUtils.getUserLoginInfo();
- JSONObject data=new JSONObject();
- json.put("code",login.getInteger("code"));
- data.put("uname",login.getJSONObject("data").getString("uname"));
- data.put("icon",login.getJSONObject("data").getString("face"));
- json.put("data",data);
- }
- return json;
- }
- @ResponseBody
- @RequestMapping("/login/set/login.do")
- public JSONObject login(){
- JSONObject login=LiveUtils.http_get("https://passport.bilibili.com/qrcode/getLoginUrl");
- JSONObject json=new JSONObject();
- json.put("code",login.getInteger("code"));
- json.put("url",login.getJSONObject("data").getString("url"));
- new Thread(new Runnable() {
- @Override
- public void run() {
- waitLogin(login.getJSONObject("data").getString("oauthKey"));
- }
- }).start();
- return json;
- }
- public void waitLogin(String oauthKey){
- long time=System.currentTimeMillis();
- String bd="gourl=https%3A%2F%2Fpassport.bilibili.com%2Fajax%2FminiLogin%2Fredirect&oauthKey="+oauthKey;
- new Timer().schedule(new TimerTask() {
- @Override
- public void run() {
- if((System.currentTimeMillis()-time)>5*60*1000){
- cancel();
- return;
- }
- JSONObject json=LiveUtils.http_post("https://passport.bilibili.com/qrcode/getLoginInfo",bd);
- if(json.containsKey("code")&&json.getInteger("code")==0){
- String _url=json.getJSONObject("data").getString("url");
- Map map=AppTools.getUrlParams(_url);
- JSONObject tmp=LiveUtils.http_post(_url,"");
- JSONObject cookie=new JSONObject();
- for (String key : map.keySet()) {
- cookie.put(key,map.get(key));
- }
- String sid=tmp.getString("cookie");
- sid=sid.split("sid=")[1];
- sid=sid.split(";")[0];
- cookie.put("sid",sid);
- cookie.put("Domain",".bilibili.com");
- AppTools.saveFile(new File("cookies.json"),cookie.toJSONString());
- cancel();
- }
- }
- },0,3000);
-
- }
-}
diff --git a/src/main/java/com/yutou/bilibili/BiliBili/Controllers/BiliVideoController.java b/src/main/java/com/yutou/bilibili/BiliBili/Controllers/BiliVideoController.java
deleted file mode 100644
index 7955bb4..0000000
--- a/src/main/java/com/yutou/bilibili/BiliBili/Controllers/BiliVideoController.java
+++ /dev/null
@@ -1,149 +0,0 @@
-package com.yutou.bilibili.BiliBili.Controllers;
-
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import com.yutou.bilibili.BiliBili.LiveUtils;
-import com.yutou.bilibili.BiliBili.Services.IBiliBiliLiveService;
-import com.yutou.bilibili.BiliBili.Tools.BiliTools;
-import com.yutou.bilibili.Services.ISystemConfigService;
-import com.yutou.bilibili.Services.IUserService;
-import com.yutou.bilibili.Tools.*;
-import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliUpInfo;
-import com.yutou.bilibili.mybatis.model.UUser;
-import org.springframework.core.io.FileSystemResource;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.util.StringUtils;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
-
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
-import java.io.File;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-@Controller
-public class BiliVideoController {
- @Resource
- IUserService service;
- @Resource
- IBiliBiliLiveService liveService;
- @Resource
- ISystemConfigService configService;
-
- @ResponseBody
- @RequestMapping("/bili/video/get/list.do")
- public JSONObject videoList(HttpServletRequest request) {
- JSONObject json = new JSONObject();
- String token = AppTools.getLoginToken(request);
- UUser user = service.getUserToToken(token);
- if (user == null) {
- json.put("code", -1);
- json.put("msg", "未登录");
- json.put("data", new JSONObject());
- return json;
- }
- if (ServiceTools.getInstance().auth(request, user.getUser(), "/bili/video/get/")) {
- File file = new File(ConfigTools.load(ConfigTools.CONFIG,"liveSavePath",String.class));
- Log.i(file.getAbsolutePath());
- if (!file.exists() || Objects.requireNonNull(file.listFiles()).length == 0) {
- json.put("code", 0);
- json.put("msg", "文件夹为空");
- json.put("data", new JSONObject());
- } else {
- List list = AppTools.scanFilePath(file.getAbsolutePath()+File.separator+"live");
- JSONArray array = new JSONArray();
- for (File f : list) {
- if(!f.getName().endsWith(".mp4")){
- continue;
- }
- JSONObject item = new JSONObject();
- String _time = f.getName().split(" ")[0].substring(1);
- File mpeg = new File("ffmpeg_out" + File.separator + _time + File.separator + f.getName());
- if (mpeg.exists()) {
- f = mpeg;
- item.put("ffmpeg", true);
- } else {
- item.put("ffmpeg", false);
- }
- String date = f.getName().split(" ")[0].substring(1);
- String time = f.getName().split(" ")[1].split("\\]")[0];
- String roomid = f.getName().split("\\]")[1].replace(".mp4", "").replace("_ffmpeg", "").trim();
-
- BilibiliUpInfo info = liveService.queryUpToRoomId(Integer.parseInt(roomid));
- long size = f.length();
- String _size;
- if (size < 1024) {
- _size = size + "B";
- } else if (size < 1048576) {
- _size = (size / 1024) + "KB";
- } else if (size < 1073741824) {
- _size = (size / 1048576) + "MB";
- } else {
- _size = (size / 1073741824) + "GB";
- }
-
- item.put("fileName", f.getName());
- item.put("fileSize", _size);
- item.put("date", date);
- item.put("time", time);
- item.put("name", info == null ? roomid : info.getName());
- array.add(item);
- }
- json.put("code", 0);
- json.put("msg", "ok");
- json.put("data", array);
- }
- } else {
- json.put("code", -2);
- json.put("msg", "未授权");
- json.put("data", new JSONObject());
- }
- return json;
- }
-
- @RequestMapping("/bili/video/download/get.do")
- public ResponseEntity download(String fileName) {
- String time = fileName.split(" ")[0].substring(1);
- File file = new File("ffmpeg_out" + File.separator + time + File.separator + fileName);
- if (!file.exists()) {
- file = new File(ConfigTools.load(ConfigTools.CONFIG,"liveSavePath",String.class)+File.separator+"live" + File.separator + time + File.separator + fileName);
- }
- Log.i(file.getAbsolutePath());
- return AppTools.getFile(file);
- }
- @ResponseBody
- @RequestMapping("/bili/video/set/ffmpeg.do")
- public JSONObject ffmpegOut(String fileName) throws UnsupportedEncodingException {
- fileName= URLDecoder.decode(fileName,"UTF-8");
- JSONObject json=new JSONObject();
- json.put("code",0);
- json.put("msg","ok");
- String time = fileName.split(" ")[0].substring(1);
- File file = new File("live" + File.separator + time + File.separator + fileName);
- System.out.println("file "+file.getAbsolutePath()+" "+file.exists());
- String ffmpeg=configService.getConfig(Config.SYSTEM_VIDEO_FFMPEG);
- if(StringUtils.isEmpty(ffmpeg)||!new File(ffmpeg).exists()){
- json.put("msg","FFmpeg未设置,请联系管理员");
- return json;
- }
- int i= FFmpegUtils.add(configService.getConfig(Config.SYSTEM_VIDEO_FFMPEG),file,new File("ffmpeg_out"+File.separator+time));
- json.put("model",i);
- switch (i){
- case 0:
- json.put("msg","已添加到后台转码");
- break;
- case 1:
- json.put("msg","已经转码,无须二次转码");
- break;
- case 2:
- json.put("msg","正在转码");
- break;
- }
- return json;
- }
-}
diff --git a/src/main/java/com/yutou/bilibili/BiliBili/Controllers/OverviewController.java b/src/main/java/com/yutou/bilibili/BiliBili/Controllers/OverviewController.java
deleted file mode 100644
index 694a6b3..0000000
--- a/src/main/java/com/yutou/bilibili/BiliBili/Controllers/OverviewController.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package com.yutou.bilibili.BiliBili.Controllers;
-
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import com.yutou.bilibili.BiliBili.Datas.LiveData;
-import com.yutou.bilibili.BiliBili.Services.IBiliBiliLiveService;
-import com.yutou.bilibili.Tools.AppTools;
-import com.yutou.bilibili.Tools.ExcelUtils;
-import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliLiveData;
-import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliLiveInfo;
-import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliUpInfo;
-import org.springframework.core.io.FileSystemResource;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
-
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
-import java.io.File;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-@Controller
-public class OverviewController {
- @Resource
- IBiliBiliLiveService manager;
-
- @RequestMapping("/overview/get/query.do")
- @ResponseBody
- public JSONObject queryOverview(Date startTime, Date endTime, BilibiliUpInfo upData) {
- JSONObject json = new JSONObject();
- JSONObject data = new JSONObject();
- //BiliBiliLiveDatabasesManager manager = BiliBiliLiveDatabasesManager.getInstance();
- data.put("giftCount", manager.queryGiftSize(upData.getRoomid(), -1, startTime, endTime));
- data.put("giftUserCount", manager.queryGiftUserToDistinct(upData, startTime, endTime, new String[]{
- LiveData.SEND_GIFT
- , LiveData.COMBO_SEND
- , LiveData.GUARD_BUY}));
- data.put("price", manager.queryPriceSize(upData.getRoomid(), startTime, endTime));
- long h = (endTime.getTime() - startTime.getTime()) % (1000 * 24 * 60 * 60) / (1000 * 60 * 60);
- com.yutou.bilibili.Tools.Log.i("相差:" + h + "小时");
- try {
- data.put("hprice", data.getInteger("price") / h);
- } catch (Exception e) {
- data.put("hprice", 0);
- }
-
-
- JSONArray array=new JSONArray();
- List infos=manager.queryLiveInfo(upData,startTime,endTime);
- int maxUser=0;
- for (BilibiliLiveInfo info : infos) {
- com.yutou.bilibili.Tools.Log.i(info);
- maxUser+=info.getUserindex()+info.getVipuserindex();
- JSONObject item=new JSONObject();
- String nowTime = new SimpleDateFormat("HH").format(info.getSubtime());
- item.put("time",nowTime);
- item.put("popular",info.getPopular());
- item.put("user",info.getUserindex()+info.getVipuserindex());
- array.add(item);
- }
- try {
- Map map = manager.queryUserGiftCount(upData, startTime, endTime);
- int huserGift = 0;
- for (String s : map.keySet()) {
- huserGift += map.get(s);
- }
- data.put("userGift", huserGift / maxUser);
- } catch (Exception e) {
- data.put("userGift", 0);
- }
- data.put("map",array);
- json.put("data",data);
- json.put("code",0);
- return json;
- }
-
- @ResponseBody
- @RequestMapping("/overview/get/down.do")
- public JSONObject downExcel(Date startTime, Date endTime, BilibiliUpInfo upData){
- final String fileName=System.currentTimeMillis()+".xlsx";
- new Thread(new Runnable() {
- @Override
- public void run() {
- ExcelUtils.getInstance(upData.getRoomid(),startTime,endTime,fileName);
- }
- }).start();
- JSONObject json=new JSONObject();
- json.put("code",0);
- json.put("data",fileName);
- return json;
-
- }
-
- @RequestMapping("/overview/get/download.do")
- public ResponseEntity downloadExcel(HttpServletRequest request, String fname){
- File file=new File("excel"+File.separator+fname);
- if(file.exists()) {
- return AppTools.getFile(file);
- }else{
- return null;
- }
- }
-}
diff --git a/src/main/java/com/yutou/bilibili/BiliBili/Controllers/RealTimeDataController.java b/src/main/java/com/yutou/bilibili/BiliBili/Controllers/RealTimeDataController.java
deleted file mode 100644
index bcf69d0..0000000
--- a/src/main/java/com/yutou/bilibili/BiliBili/Controllers/RealTimeDataController.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package com.yutou.bilibili.BiliBili.Controllers;
-
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import com.yutou.bilibili.BiliBili.Datas.LiveData;
-import com.yutou.bilibili.BiliBili.Live;
-import com.yutou.bilibili.BiliBili.LiveUtils;
-import com.yutou.bilibili.BiliBili.Services.IBiliBiliLiveService;
-import com.yutou.bilibili.Tools.AppTools;
-import com.yutou.bilibili.Tools.Log;
-import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliLiveData;
-import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliLiveInfo;
-import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliUpInfo;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
-
-import javax.annotation.Resource;
-import java.math.BigDecimal;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-@Controller
-@RequestMapping("/realTimeData/")
-public class RealTimeDataController {
- @Resource
- IBiliBiliLiveService service;
- @ResponseBody
- @RequestMapping("get/query.do")
- public JSONObject queryToDayLiveData(int roomid,Date startTime,Date endTime){
- JSONObject json = new JSONObject();
- BilibiliUpInfo info = new BilibiliUpInfo();
- info.setRoomid(roomid);
- Live live = LiveUtils.liveContains(info);
- if(startTime==null){
- startTime=AppTools.getToDayStartTime();
- }
- if(endTime==null){
- endTime=AppTools.getToDayNowTime();
- }
- int userCount = service.queryLiveData(info.getRoomid(), startTime, endTime, new String[]{LiveData.INTERACT_WORD}).size();
- int vipCount = service.queryLiveData(info.getRoomid(), startTime, endTime, new String[]{LiveData.ENTRY_EFFECT}).size();
- JSONObject data = new JSONObject();
- data.put("roomid", roomid);
- data.put("popular",live==null?0:live.getInfo().getPopular());
- data.put("userLength", userCount);
- data.put("vipLength", vipCount);
-
- JSONArray price = new JSONArray();
- //改写这个sql可以按时段统计数据
- List