hints = new HashMap<>();
63 | hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
64 | // 容错级别
65 | hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
66 | // 图像数据转换,使用了矩阵转换
67 | BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix,
68 | heightPix, hints);
69 | int[] pixels = new int[widthPix * heightPix];
70 | // 下面这里按照二维码的算法,逐个生成二维码的图片,
71 | // 两个for循环是图片横列扫描的结果
72 | for (int y = 0; y < heightPix; y++) {
73 | for (int x = 0; x < widthPix; x++) {
74 | if (bitMatrix.get(x, y)) {
75 | pixels[y * widthPix + x] = 0xff000000;
76 | } else {
77 | pixels[y * widthPix + x] = 0xffffffff;
78 | }
79 | }
80 | }
81 | // 生成二维码图片的格式,使用ARGB_8888
82 | Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888);
83 | bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix);
84 | if (logoBm != null) {
85 | bitmap = addLogo(bitmap, logoBm);
86 | }
87 | //必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,内存消耗巨大!
88 | return bitmap;
89 | } catch (WriterException e) {
90 | e.printStackTrace();
91 | }
92 | return null;
93 | }
94 |
95 | /**
96 | * 在二维码中间添加Logo图案
97 | */
98 | private static Bitmap addLogo(Bitmap src, Bitmap logo) {
99 | if (src == null) {
100 | return null;
101 | }
102 | if (logo == null) {
103 | return src;
104 | }
105 | //获取图片的宽高
106 | int srcWidth = src.getWidth();
107 | int srcHeight = src.getHeight();
108 | int logoWidth = logo.getWidth();
109 | int logoHeight = logo.getHeight();
110 | if (srcWidth == 0 || srcHeight == 0) {
111 | return null;
112 | }
113 | if (logoWidth == 0 || logoHeight == 0) {
114 | return src;
115 | }
116 | //logo大小为二维码整体大小的1/5
117 | float scaleFactor = srcWidth * 1.0f / 5 / logoWidth;
118 | Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
119 | try {
120 | Canvas canvas = new Canvas(bitmap);
121 | canvas.drawBitmap(src, 0, 0, null);
122 | canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2);
123 | canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null);
124 | // canvas.save(Canvas.ALL_SAVE_FLAG);
125 | canvas.restore();
126 | } catch (Exception e) {
127 | bitmap = null;
128 | e.getStackTrace();
129 | }
130 | return bitmap;
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/qrcode/view/ViewfinderResultPointCallback.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2009 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package top.naccl.gamebox.qrcode.view;
18 |
19 | import com.google.zxing.ResultPoint;
20 | import com.google.zxing.ResultPointCallback;
21 |
22 | public final class ViewfinderResultPointCallback implements ResultPointCallback {
23 | private final ViewfinderView viewfinderView;
24 |
25 | public ViewfinderResultPointCallback(ViewfinderView viewfinderView) {
26 | this.viewfinderView = viewfinderView;
27 | }
28 |
29 | public void foundPossibleResultPoint(ResultPoint point) {
30 | viewfinderView.addPossibleResultPoint(point);
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/service/ArticleService.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox.service;
2 |
3 | import top.naccl.gamebox.bean.Article;
4 |
5 | public interface ArticleService {
6 | Article getArticle(Long id);
7 |
8 | boolean deleteArticle(Long id);
9 |
10 | boolean saveArticle(Article article);
11 |
12 | boolean updateViews(Article article);
13 |
14 | boolean updateStar(Article article);
15 | }
16 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/service/ImageService.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox.service;
2 |
3 | import top.naccl.gamebox.bean.Image;
4 |
5 | public interface ImageService {
6 | Image getImage(String url);
7 |
8 | boolean saveImage(Image image);
9 | }
10 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/service/UserService.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox.service;
2 |
3 | import top.naccl.gamebox.bean.User;
4 |
5 | public interface UserService {
6 | User getUser();
7 |
8 | boolean saveUser(User user);
9 |
10 | boolean updateUser(User user);
11 |
12 | boolean deleteUser();
13 | }
14 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/service/impl/ArticleServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox.service.impl;
2 |
3 | import android.content.Context;
4 |
5 | import top.naccl.gamebox.bean.Article;
6 | import top.naccl.gamebox.dao.ArticleDao;
7 | import top.naccl.gamebox.service.ArticleService;
8 |
9 | public class ArticleServiceImpl implements ArticleService {
10 | private static final String[] allColumns = new String[]{"_id", "title", "author", "date", "description", "firstPicture", "content", "star", "views"};
11 | ArticleDao articleDao;
12 |
13 | public ArticleServiceImpl(Context context) {
14 | this.articleDao = new ArticleDao(context);
15 | }
16 |
17 | @Override
18 | public Article getArticle(Long id) {
19 | articleDao.open();
20 | Article[] articles = (Article[]) articleDao.queryOneData(allColumns, "_id", String.valueOf(id));
21 | articleDao.close();
22 | if (articles != null && articles.length == 1) {
23 | return articles[0];
24 | }
25 | return null;
26 | }
27 |
28 | @Override
29 | public boolean deleteArticle(Long id) {
30 | articleDao.open();
31 | long res = articleDao.deleteOneData("_id", String.valueOf(id));
32 | articleDao.close();
33 | if (res == -1) {
34 | return false;
35 | }
36 | return true;
37 | }
38 |
39 | @Override
40 | public boolean saveArticle(Article article) {
41 | articleDao.open();
42 | long res = articleDao.insert(allColumns, new String[]{String.valueOf(article.getId()), article.getTitle(), article.getAuthor(), article.getDate(), article.getDescription(), article.getFirstPicture(), article.getContent(), String.valueOf(article.getStar()), String.valueOf(article.getViews())});
43 | articleDao.close();
44 | if (res == -1) {
45 | return false;
46 | }
47 | return true;
48 | }
49 |
50 | @Override
51 | public boolean updateViews(Article article) {
52 | articleDao.open();
53 | long res = articleDao.updateOneData(new String[]{"views"}, new String[]{String.valueOf(article.getViews())}, "_id", String.valueOf(article.getId()));
54 | articleDao.close();
55 | if (res == -1) {
56 | return false;
57 | }
58 | return true;
59 | }
60 |
61 | @Override
62 | public boolean updateStar(Article article) {
63 | articleDao.open();
64 | long res = articleDao.updateOneData(new String[]{"star"}, new String[]{String.valueOf(article.getStar())}, "_id", String.valueOf(article.getId()));
65 | articleDao.close();
66 | if (res == -1) {
67 | return false;
68 | }
69 | return true;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/service/impl/ImageServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox.service.impl;
2 |
3 | import android.content.Context;
4 |
5 | import top.naccl.gamebox.bean.Image;
6 | import top.naccl.gamebox.dao.ImageDao;
7 | import top.naccl.gamebox.service.ImageService;
8 |
9 | public class ImageServiceImpl implements ImageService {
10 | private static final String[] allColumns = new String[]{"url", "base64"};
11 | ImageDao imageDao;
12 |
13 | public ImageServiceImpl(Context context) {
14 | this.imageDao = new ImageDao(context);
15 | }
16 |
17 | @Override
18 | public Image getImage(String url) {
19 | imageDao.open();
20 | Image[] images = (Image[]) imageDao.queryOneData(allColumns, "url", url);
21 | imageDao.close();
22 | if (images != null && images.length == 1) {
23 | return images[0];
24 | }
25 | return null;
26 | }
27 |
28 | @Override
29 | public boolean saveImage(Image image) {
30 | imageDao.open();
31 | long res = imageDao.insert(allColumns, new String[]{image.getUrl(), image.getBase64()});
32 | imageDao.close();
33 | if (res == -1) {
34 | return false;
35 | }
36 | return true;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/service/impl/UserServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox.service.impl;
2 |
3 | import android.content.Context;
4 |
5 | import top.naccl.gamebox.bean.User;
6 | import top.naccl.gamebox.dao.UserDao;
7 | import top.naccl.gamebox.service.UserService;
8 |
9 | public class UserServiceImpl implements UserService {
10 | private static final String[] allColumns = new String[]{"_id", "username", "password", "avatar", "introduction", "sex", "email", "education", "job", "birthday"};
11 | UserDao userDao;
12 |
13 | public UserServiceImpl(Context context) {
14 | this.userDao = new UserDao(context);
15 | }
16 |
17 | private String[] getAllParams(User user) {
18 | return new String[]{String.valueOf(user.getId()), user.getUsername(), user.getPassword(), user.getAvatar(), user.getIntroduction(), user.getSex(), user.getEmail(), user.getEducation(), user.getJob(), user.getBirthday()};
19 | }
20 |
21 | @Override
22 | public User getUser() {
23 | userDao.open();
24 | User[] users = (User[]) userDao.queryAllData(allColumns);
25 | userDao.close();
26 | if (users != null && users.length == 1) {
27 | return users[0];
28 | }
29 | return null;
30 | }
31 |
32 | @Override
33 | public boolean saveUser(User user) {
34 | userDao.open();
35 | long res = userDao.insert(allColumns, getAllParams(user));
36 | userDao.close();
37 | if (res == -1) {
38 | return false;
39 | }
40 | return true;
41 | }
42 |
43 | @Override
44 | public boolean updateUser(User user) {
45 | userDao.open();
46 | //正常情况下,数据库中只存放一条用户记录,直接updateAllData
47 | long res = userDao.updateAllData(allColumns, getAllParams(user));
48 | userDao.close();
49 | if (res == -1) {
50 | return false;
51 | }
52 | return true;
53 | }
54 |
55 | @Override
56 | public boolean deleteUser() {
57 | userDao.open();
58 | long res = userDao.deleteAllData();
59 | userDao.close();
60 | if (res == -1) {
61 | return false;
62 | }
63 | return true;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/util/Base64Utils.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox.util;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.util.Base64;
6 |
7 | import java.io.ByteArrayOutputStream;
8 | import java.io.IOException;
9 |
10 | public class Base64Utils {
11 | public static String bitmapToBase64(Bitmap bitmap) {
12 | String reslut = null;
13 | ByteArrayOutputStream baos = null;
14 | try {
15 | if (bitmap != null) {
16 | baos = new ByteArrayOutputStream();
17 | //压缩只对保存有效果bitmap还是原来的大小,100不压缩
18 | bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);
19 | baos.flush();
20 | baos.close();
21 | byte[] byteArray = baos.toByteArray();
22 | reslut = Base64.encodeToString(byteArray, Base64.DEFAULT);
23 | } else {
24 | return null;
25 | }
26 | } catch (IOException e) {
27 | e.printStackTrace();
28 | } finally {
29 | try {
30 | if (baos != null) {
31 | baos.close();
32 | }
33 | } catch (IOException e) {
34 | e.printStackTrace();
35 | }
36 | }
37 | return reslut;
38 | }
39 |
40 | public static Bitmap base64ToBitmap(String base64String) {
41 | byte[] decode = Base64.decode(base64String, Base64.DEFAULT);
42 | Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length);
43 | return bitmap;
44 | }
45 | }
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/util/BitmapUtil.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox.util;
2 |
3 | import android.content.ContentResolver;
4 | import android.content.Context;
5 | import android.graphics.Bitmap;
6 | import android.graphics.BitmapFactory;
7 | import android.net.Uri;
8 | import android.util.Log;
9 |
10 | import java.io.IOException;
11 | import java.io.InputStream;
12 |
13 | /**
14 | * Bitmap util.
15 | * 从Uri直接读取图片流,避免路径转换的适配问题
16 | */
17 | public class BitmapUtil {
18 | /**
19 | * 读取一个缩放后的图片,限定图片大小,避免OOM
20 | *
21 | * @param uri 图片uri,支持“file://”、“content://”
22 | * @param maxWidth 最大允许宽度
23 | * @param maxHeight 最大允许高度
24 | * @return 返回一个缩放后的Bitmap,失败则返回null
25 | */
26 | public static Bitmap decodeUri(Context context, Uri uri, int maxWidth, int maxHeight) {
27 | BitmapFactory.Options options = new BitmapFactory.Options();
28 | options.inJustDecodeBounds = true; //只读取图片尺寸
29 | readBitmapScale(context, uri, options);
30 |
31 | //计算实际缩放比例
32 | int scale = 1;
33 | for (int i = 0; i < Integer.MAX_VALUE; i++) {
34 | if ((options.outWidth / scale > maxWidth &&
35 | options.outWidth / scale > maxWidth * 1.4) ||
36 | (options.outHeight / scale > maxHeight &&
37 | options.outHeight / scale > maxHeight * 1.4)) {
38 | scale++;
39 | } else {
40 | break;
41 | }
42 | }
43 |
44 | options.inSampleSize = scale;
45 | options.inJustDecodeBounds = false;//读取图片内容
46 | options.inPreferredConfig = Bitmap.Config.RGB_565; //根据情况进行修改
47 | Bitmap bitmap = null;
48 | try {
49 | bitmap = readBitmapData(context, uri, options);
50 | } catch (Throwable e) {
51 | e.printStackTrace();
52 | }
53 | return bitmap;
54 | }
55 |
56 | private static void readBitmapScale(Context context, Uri uri, BitmapFactory.Options options) {
57 | if (uri == null) {
58 | return;
59 | }
60 | String scheme = uri.getScheme();
61 | if (ContentResolver.SCHEME_CONTENT.equals(scheme) ||
62 | ContentResolver.SCHEME_FILE.equals(scheme)) {
63 | InputStream stream = null;
64 | try {
65 | stream = context.getContentResolver().openInputStream(uri);
66 | BitmapFactory.decodeStream(stream, null, options);
67 | } catch (Exception e) {
68 | Log.w("readBitmapScale", "Unable to open content: " + uri, e);
69 | } finally {
70 | if (stream != null) {
71 | try {
72 | stream.close();
73 | } catch (IOException e) {
74 | Log.e("readBitmapScale", "Unable to close content: " + uri, e);
75 | }
76 | }
77 | }
78 | } else if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) {
79 | Log.e("readBitmapScale", "Unable to close content: " + uri);
80 | } else {
81 | Log.e("readBitmapScale", "Unable to close content: " + uri);
82 | }
83 | }
84 |
85 | private static Bitmap readBitmapData(Context context, Uri uri, BitmapFactory.Options options) {
86 | if (uri == null) {
87 | return null;
88 | }
89 | Bitmap bitmap = null;
90 | String scheme = uri.getScheme();
91 | if (ContentResolver.SCHEME_CONTENT.equals(scheme) ||
92 | ContentResolver.SCHEME_FILE.equals(scheme)) {
93 | InputStream stream = null;
94 | try {
95 | stream = context.getContentResolver().openInputStream(uri);
96 | bitmap = BitmapFactory.decodeStream(stream, null, options);
97 | } catch (Exception e) {
98 | Log.e("readBitmapData", "Unable to open content: " + uri, e);
99 | } finally {
100 | if (stream != null) {
101 | try {
102 | stream.close();
103 | } catch (IOException e) {
104 | Log.e("readBitmapData", "Unable to close content: " + uri, e);
105 | }
106 | }
107 | }
108 | } else if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) {
109 | Log.e("readBitmapData", "Unable to close content: " + uri);
110 | } else {
111 | Log.e("readBitmapData", "Unable to close content: " + uri);
112 | }
113 | return bitmap;
114 | }
115 | }
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/util/Constant.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox.util;
2 |
3 | /**
4 | * 常量
5 | */
6 | public class Constant {
7 | // request参数
8 | public static final int REQ_QR_CODE = 11002; // // 打开扫描界面请求码
9 | public static final int REQ_PERM_CAMERA = 11003; // 打开摄像头
10 | public static final int REQ_PERM_EXTERNAL_STORAGE = 11004; // 读写文件
11 |
12 | public static final String INTENT_EXTRA_KEY_QR_SCAN = "qr_scan_result";
13 | }
14 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/util/DBUtils.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox.util;
2 |
3 | import android.content.ContentValues;
4 | import android.content.Context;
5 | import android.database.Cursor;
6 | import android.database.sqlite.SQLiteDatabase;
7 | import android.database.sqlite.SQLiteDatabase.CursorFactory;
8 | import android.database.sqlite.SQLiteException;
9 | import android.database.sqlite.SQLiteOpenHelper;
10 |
11 | public class DBUtils {
12 | private static final String DB_NAME = "gamebox.db";
13 | private static final int DB_VERSION = 1;
14 |
15 | private SQLiteDatabase db;
16 | private DBOpenHelper dbOpenHelper;
17 | private Context context;
18 | private String table;
19 | private String table_create;
20 |
21 | public DBUtils(Context context, String table, String table_create) {
22 | this.context = context;
23 | this.table = table;
24 | this.table_create = table_create;
25 | }
26 |
27 | public void close() {
28 | if (db != null) {
29 | db.close();
30 | db = null;
31 | }
32 | }
33 |
34 | public void open() throws SQLiteException {
35 | dbOpenHelper = new DBOpenHelper(context, DB_NAME, null, DB_VERSION, table, table_create);
36 | try {
37 | db = dbOpenHelper.getWritableDatabase();//执行此方法时,会判断数据库是否存在,如果已存在,就不在调用onCreate方法
38 | } catch (SQLiteException ex) {
39 | db = dbOpenHelper.getReadableDatabase();
40 | }
41 | }
42 |
43 | public long insert(String[] columns, String[] params) {
44 | ContentValues newValues = new ContentValues();
45 | for (int i = 0; i < columns.length; i++) {
46 | newValues.put(columns[i], params[i]);
47 | }
48 | return db.insert(table, null, newValues);
49 | }
50 |
51 | public long updateOneData(String[] columns, String[] params, String selectColumn, String selectParam) {
52 | ContentValues updateValues = new ContentValues();
53 | for (int i = 0; i < columns.length; i++) {
54 | updateValues.put(columns[i], params[i]);
55 | }
56 | return db.update(table, updateValues, selectColumn + "=" + selectParam, null);
57 | }
58 |
59 | public long updateAllData(String[] columns, String[] params) {
60 | ContentValues updateValues = new ContentValues();
61 | for (int i = 0; i < columns.length; i++) {
62 | updateValues.put(columns[i], params[i]);
63 | }
64 | return db.update(table, updateValues, null, null);
65 | }
66 |
67 | public long deleteAllData() {
68 | return db.delete(table, null, null);
69 | }
70 |
71 | public long deleteOneData(String selectColumn, String selectParam) {
72 | return db.delete(table, selectColumn + "=" + selectParam, null);
73 | }
74 |
75 | public Object[] queryAllData(String[] columns) {
76 | Cursor results = db.query(table, columns, null, null, null, null, null);
77 | return ConvertToObject(results);
78 | }
79 |
80 | public Object[] queryOneData(String[] columns, String selectColumn, String selectParam) {
81 | Cursor results = db.query(table, columns, selectColumn + "=" + selectParam,
82 | null, null, null, null);
83 | return ConvertToObject(results);
84 | }
85 |
86 | public Object[] ConvertToObject(Cursor cursor) {
87 | int resultCounts = cursor.getCount();
88 | if (resultCounts == 0 || !cursor.moveToFirst()) {
89 | return null;
90 | }
91 | Object[] objects = new Object[resultCounts];
92 | return objects;
93 | }
94 |
95 | private class DBOpenHelper extends SQLiteOpenHelper {
96 | private String table;
97 | private String table_create;
98 |
99 | public DBOpenHelper(Context context, String name, CursorFactory factory, int version, String table, String table_create) {
100 | super(context, name, factory, version);
101 | this.table = table;
102 | this.table_create = table_create;
103 | }
104 |
105 | @Override
106 | public void onCreate(SQLiteDatabase database) {
107 | database.execSQL("create table user(_id integer primary key autoincrement, username text not null, password text, avatar text, introduction text, sex text, email text, education text, job text, birthday text);");
108 | database.execSQL("create table article(_id integer primary key, title text, author text, date text, description text, firstPicture text, content text, star integer, views integer);");
109 | database.execSQL("create table image(url text not null, base64 text not null);");
110 | }
111 |
112 | @Override
113 | public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
114 | database.execSQL("DROP TABLE IF EXISTS " + table);
115 | onCreate(database);
116 | }
117 | }
118 | }
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/util/MD5Utils.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox.util;
2 |
3 | import java.io.UnsupportedEncodingException;
4 | import java.math.BigInteger;
5 | import java.security.MessageDigest;
6 | import java.security.NoSuchAlgorithmException;
7 |
8 | public class MD5Utils {
9 | public static String getMD5(String str) {
10 | byte[] digest = null;
11 | try {
12 | MessageDigest md5 = MessageDigest.getInstance("md5");
13 | digest = md5.digest(str.getBytes("utf-8"));
14 | } catch (NoSuchAlgorithmException e) {
15 | e.printStackTrace();
16 | } catch (UnsupportedEncodingException e) {
17 | e.printStackTrace();
18 | }
19 | String md5String = new BigInteger(1, digest).toString(16);
20 | return md5String;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/util/OkHttpUtils.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox.util;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | import okhttp3.FormBody;
6 | import okhttp3.OkHttpClient;
7 | import okhttp3.Request;
8 | import okhttp3.RequestBody;
9 |
10 | public class OkHttpUtils {
11 | private static OkHttpClient okHttpClient = new OkHttpClient.Builder()
12 | .connectTimeout(10, TimeUnit.SECONDS)
13 | .readTimeout(10, TimeUnit.SECONDS)
14 | .writeTimeout(10, TimeUnit.SECONDS)
15 | .build();
16 |
17 | public static void getRequest(String url, okhttp3.Callback callback) {
18 | Request request = new Request.Builder()
19 | .url(url)
20 | .get()
21 | .build();
22 | okHttpClient.newCall(request).enqueue(callback);
23 | }
24 |
25 | public static void getRequest(String url, String token, okhttp3.Callback callback) {
26 | Request request = new Request.Builder()
27 | .url(url)
28 | .get()
29 | .addHeader("Authorization", token)
30 | .build();
31 | okHttpClient.newCall(request).enqueue(callback);
32 | }
33 |
34 | public static void postRequest(String url, String token, okhttp3.Callback callback) {
35 | Request request = new Request.Builder()
36 | .url(url)
37 | .post(new FormBody.Builder().build())
38 | .addHeader("Authorization", token)
39 | .build();
40 | okHttpClient.newCall(request).enqueue(callback);
41 | }
42 |
43 | public static void postRequest(String url, RequestBody requestBody, okhttp3.Callback callback) {
44 | Request request = new Request.Builder()
45 | .url(url)
46 | .post(requestBody)
47 | .build();
48 | okHttpClient.newCall(request).enqueue(callback);
49 | }
50 |
51 | public static void postRequest(String url, String token, RequestBody requestBody, okhttp3.Callback callback) {
52 | Request request = new Request.Builder()
53 | .url(url)
54 | .post(requestBody)
55 | .addHeader("Authorization", token)
56 | .build();
57 | okHttpClient.newCall(request).enqueue(callback);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/java/top/naccl/gamebox/util/ToastUtils.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox.util;
2 |
3 | import android.app.Activity;
4 | import android.widget.Toast;
5 |
6 | public class ToastUtils {
7 | public static void showToast(final Activity activity, final String msg) {
8 | activity.runOnUiThread(new Runnable() {
9 | public void run() {
10 | Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show();
11 | }
12 | });
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/abc_ic_menu_moreoverflow_mtrl_alpha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/abc_ic_menu_moreoverflow_mtrl_alpha.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/active_nor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/active_nor.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/arrow_go_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/arrow_go_back.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/arrow_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/arrow_right.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/avatar_login_default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/avatar_login_default.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/avatar_logout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/avatar_logout.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/btn_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/btn_back.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/chuapp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/chuapp.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/community.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/eye.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/eye.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/flash_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/flash_off.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/flash_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/flash_on.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/home.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/ic_search_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/icon_article_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_article_add.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/icon_article_favorite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_article_favorite.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/icon_article_good.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_article_good.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/icon_article_message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_article_message.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/icon_community_find.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_community_find.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/icon_community_game.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_community_game.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/icon_community_nor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_community_nor.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/icon_community_sel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_community_sel.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/icon_home_nor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_home_nor.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/icon_home_sel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_home_sel.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/icon_information_save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_information_save.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/icon_me_nor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_me_nor.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/icon_me_sel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_me_sel.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/me.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/message.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/scan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/scan.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/scrollimg1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/scrollimg1.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/scrollimg2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/scrollimg2.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/setting.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
17 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/shape_add.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
17 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/drawable/textcolor.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/activity_bottom_navigation_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
17 |
18 |
25 |
26 |
33 |
34 |
41 |
42 |
49 |
50 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/activity_favorite.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
20 |
21 |
31 |
32 |
33 |
34 |
38 |
39 |
42 |
43 |
47 |
48 |
51 |
52 |
60 |
61 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
22 |
23 |
36 |
37 |
48 |
49 |
63 |
64 |
74 |
75 |
85 |
86 |
94 |
95 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/activity_register.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
22 |
23 |
36 |
37 |
48 |
49 |
63 |
64 |
74 |
75 |
85 |
86 |
94 |
95 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/activity_scanner.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
13 |
14 |
19 |
20 |
32 |
33 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/comment_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
19 |
20 |
32 |
33 |
42 |
43 |
53 |
54 |
66 |
67 |
79 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/dialog_input_text_msg.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
34 |
35 |
36 |
43 |
44 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/fragment_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
21 |
22 |
23 |
27 |
28 |
31 |
32 |
36 |
37 |
40 |
41 |
49 |
50 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/message_action_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
14 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/recycleview_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
23 |
24 |
25 |
26 |
36 |
37 |
49 |
50 |
60 |
61 |
72 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/recycleview_item_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/scan_action_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
14 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/setting_action_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
14 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/toolbar_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/layout/toolbar_scanner.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
23 |
24 |
32 |
33 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/menu/community.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/menu/information_save.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/menu/nologin_setting.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/menu/scanner_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/menu/setting.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/raw/beep.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/raw/beep.ogg
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/values/attr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #282525
4 | #948484
5 | #3F51B5
6 | #303F9F
7 | #FF4081
8 |
9 |
10 | #60000000
11 | #B0000000
12 | #90FFFFFF
13 | #C0FFFF00
14 | #0F0
15 | #00FF00
16 |
17 |
18 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | GameBox
3 |
4 |
--------------------------------------------------------------------------------
/GameBox/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
26 |
27 |
28 |
39 |
40 |
--------------------------------------------------------------------------------
/GameBox/app/src/test/java/top/naccl/gamebox/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package top.naccl.gamebox;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/GameBox/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath "com.android.tools.build:gradle:4.0.1"
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | google()
18 | jcenter()
19 | }
20 | }
21 |
22 | task clean(type: Delete) {
23 | delete rootProject.buildDir
24 | }
--------------------------------------------------------------------------------
/GameBox/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
--------------------------------------------------------------------------------
/GameBox/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/GameBox/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Nov 07 20:22:29 CST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/GameBox/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/GameBox/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | rootProject.name = "GameBox"
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Features
17 |
18 | 仿[小黑盒](https://www.xiaoheihe.cn/)安卓APP,含后端、含界面原型设计、最新资讯爬虫
19 |
20 | 主要实现功能:
21 |
22 | 1. 爬取[触乐网](http://www.chuapp.com/)最新游戏资讯
23 | 2. 登录注册
24 | 3. jwt 实现登录状态鉴权
25 | 4. 首页文章布局
26 | 5. 上拉加载更多
27 | 6. 文章 HTML 渲染
28 | 7. 文章配图从网络动态获取
29 | 8. 本地 SQLite 缓存查看过的文章和图片资源
30 | 9. 文章点赞收藏
31 | 10. 个人资料修改
32 |
33 |
34 |
35 | ## 后端
36 |
37 | 1. 核心框架:[Spring Boot](https://github.com/spring-projects/spring-boot)
38 | 2. Token 认证:[jjwt](https://github.com/jwtk/jjwt)
39 | 3. 持久层框架:[MyBatis](https://github.com/mybatis/spring-boot-starter)
40 | 4. 分页插件:[PageHelper](https://github.com/pagehelper/Mybatis-PageHelper)
41 | 5. JSON 库:[fastjson](https://github.com/alibaba/fastjson)
42 |
43 |
44 |
45 | ## Android端
46 |
47 | 1. 网络请求框架:[okhttp3](https://github.com/square/okhttp)
48 | 2. JSON 库:[fastjson](https://github.com/alibaba/fastjson)
49 | 3. 下拉刷新、上拉加载:[SmartRefreshLayout](https://github.com/scwang90/SmartRefreshLayout)
50 | 4. 二维码:[zxing](https://github.com/zxing/zxing)
51 | 5. 数据库缓存:[SQLite](https://www.sqlite.org/)
52 |
53 |
54 |
55 | ## Screenshots
56 |
57 |
58 |
59 | 首页 |
60 | 文章1 |
61 |
62 |
63 | 文章2 |
64 | 评论 |
65 |
66 |
67 | 静态页 |
68 | 我的 |
69 |
70 |
71 | 收藏夹 |
72 | 扫描二维码 |
73 |
74 |
75 | 设置 |
76 | 修改资料 |
77 |
78 |
79 | 登录 |
80 | |
81 |
--------------------------------------------------------------------------------
/SpiderForChuApp.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | # Author: Naccl
4 |
5 | import requests
6 | from bs4 import BeautifulSoup
7 | import os
8 | import pymysql
9 | import datetime
10 | import sys
11 |
12 | db = None
13 | cursor = None
14 | # articleID = 287120
15 |
16 | def requests_get(url):
17 | try:
18 | response = requests.get(url, timeout=(3, 3))
19 | if response.status_code == 200:
20 | return response
21 | except Exception as e:
22 | print(e)
23 | for i in range(1,4):
24 | print("请求超时,第%s次重复请求,url=%s" % (i, url))
25 | response = requests.get(url, timeout=(3, 3))
26 | if response.status_code == 200:
27 | return response
28 | return -1
29 |
30 |
31 | def executeSQL(field):
32 | global db
33 | global cursor
34 | sql = '''INSERT INTO article(id, title, author, date, description, first_picture, content, star, views)
35 | VALUES ("%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s")''' % (field[0], field[1], field[2], field[3], field[4], field[5], field[6], 0, 0)
36 | try:
37 | cursor.execute(sql)
38 | db.commit()
39 | result = cursor.fetchall()
40 | print(result)
41 | except Exception as e:
42 | print(e)
43 | db.rollback()
44 |
45 |
46 | def getContent(articleID):
47 | url = "http://www.chuapp.com/article/%s.html" % articleID
48 | try:
49 | r = requests_get(url)
50 | bs = BeautifulSoup(r.text, "lxml")
51 | page = bs.select("body > div.content.single > div > div.the-content") # 获取正文内容
52 |
53 | p = list(page[0])
54 | while "\n" in p: # 去除空行
55 | p.remove("\n")
56 |
57 | content = ""
58 | for i in range(len(p)):
59 | imgTag = p[i].find("img")
60 | if imgTag != None:
61 | imgUrl = imgTag["src"].split("?")[0]
62 | content += "
" % imgUrl
63 | else:
64 | if p[i].text == "\n": # 文本是换行符
65 | content += "<%s>%s>" % (p[i].name, p[i].name)
66 | else:
67 | content += "<%s>%s%s>" % (p[i].name, p[i].text, p[i].name)
68 | return content
69 | except Exception as e:
70 | print(e)
71 | return None
72 |
73 |
74 | def getRecommend(pageNumber, num): # pageNumber:每日聚焦id,num:每日聚焦页面中文章序号
75 | url = "http://www.chuapp.com/category/index/id/daily/p/%s.html" % pageNumber
76 | try:
77 | r = requests_get(url)
78 | bs = BeautifulSoup(r.text, "lxml")
79 |
80 | aTagSelect = "body > div.content.category.fn-clear > div.category-left.fn-left > div > a:nth-child(%s)" % num
81 | titleSelect = "body > div.content.category.fn-clear > div.category-left.fn-left > div > a:nth-child(%s) > dl > dt" % num
82 | authorSelect = "body > div.content.category.fn-clear > div.category-left.fn-left > div > a:nth-child(%s) > dl > dd.fn-clear > span.fn-left > em" % num
83 | dateSelect = "body > div.content.category.fn-clear > div.category-left.fn-left > div > a:nth-child(%s) > dl > dd.fn-clear > span.fn-left" % num
84 | descriptionSelect = "body > div.content.category.fn-clear > div.category-left.fn-left > div > a:nth-child(%s) > dl > dd:nth-child(3)" % num
85 |
86 | aTag = bs.select(aTagSelect)
87 | title = bs.select(titleSelect)
88 | author = bs.select(authorSelect)
89 | date = bs.select(dateSelect)
90 | description = bs.select(descriptionSelect)
91 |
92 | articleID = aTag[0]["href"].split(".")[0][-6:] # 从aTag中获取文章id
93 | firstPictureUrl = aTag[0].find("img")["src"].split("?")[0] # 从aTag中获取firstPictureUrl
94 | dateStr = date[0].text[len(author[0].text):]
95 | if "前" in dateStr:
96 | today = datetime.date.today()
97 | dateStr = "%02d月%02d日" % (today.month, today.day)
98 |
99 | field = [articleID, title[0].text, author[0].text, dateStr, description[0].text, firstPictureUrl]
100 | return field
101 | except Exception as e:
102 | print(e)
103 | return None
104 |
105 |
106 | def start(page):
107 | global db
108 | global cursor
109 | db = pymysql.connect("localhost", "root", "root", "gamebox")
110 | cursor = db.cursor()
111 | getTop(page)
112 | db.close()
113 |
114 |
115 | def getTop(page):
116 | for i in range(1, page + 1):
117 | pageNumber = i
118 | for j in range(1, 11):
119 | field = getRecommend(pageNumber, j)
120 | if field != None:
121 | content = getContent(field[0])
122 | if content != None:
123 | field.append(content)
124 | executeSQL(field)
125 |
126 |
127 | if __name__ == "__main__":
128 | args = sys.argv
129 | if len(args) == 2:
130 | if int(args[1]) > 0:
131 | start(int(args[1]))
132 | else:
133 | print("args error")
134 | else:
135 | print("input a number of page")
136 |
--------------------------------------------------------------------------------
/android-api/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.2.7.RELEASE
9 |
10 |
11 | top.naccl
12 | android-api
13 | 0.0.1
14 | android-api
15 | Android API project for Spring Boot
16 |
17 |
18 | 1.8
19 | 1.8
20 | 1.8
21 | UTF-8
22 | 1.8
23 |
24 |
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-web
29 |
30 |
31 | org.mybatis.spring.boot
32 | mybatis-spring-boot-starter
33 | 2.1.3
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-devtools
39 | runtime
40 | true
41 |
42 |
43 | mysql
44 | mysql-connector-java
45 | runtime
46 |
47 |
48 | org.projectlombok
49 | lombok
50 | true
51 |
52 |
53 | io.jsonwebtoken
54 | jjwt
55 | 0.9.1
56 |
57 |
58 | com.github.pagehelper
59 | pagehelper-spring-boot-starter
60 | 1.2.12
61 |
62 |
63 | com.alibaba
64 | fastjson
65 | 1.2.58
66 |
67 |
68 | org.springframework.boot
69 | spring-boot-starter-test
70 | test
71 |
72 |
73 | org.junit.vintage
74 | junit-vintage-engine
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | org.springframework.boot
84 | spring-boot-maven-plugin
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/AndroidApiApplication.java:
--------------------------------------------------------------------------------
1 | package top.naccl;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class AndroidApiApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(AndroidApiApplication.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/controller/FavoriteController.java:
--------------------------------------------------------------------------------
1 | package top.naccl.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.web.bind.annotation.GetMapping;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.PostMapping;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RestController;
9 | import top.naccl.model.entity.Article;
10 | import top.naccl.model.entity.Favorite;
11 | import top.naccl.model.vo.Result;
12 | import top.naccl.service.ArticleService;
13 | import top.naccl.service.FavoriteService;
14 | import top.naccl.service.UserService;
15 | import top.naccl.util.JwtUtils;
16 |
17 | import javax.servlet.http.HttpServletRequest;
18 | import java.util.ArrayList;
19 | import java.util.HashMap;
20 | import java.util.List;
21 | import java.util.Map;
22 |
23 | /**
24 | * @Description: 收藏夹
25 | * @Author: Naccl
26 | * @Date: 2020-10-16
27 | */
28 |
29 | @RestController
30 | @RequestMapping("/favorite")
31 | public class FavoriteController {
32 | @Autowired
33 | FavoriteService favoriteService;
34 | @Autowired
35 | UserService userService;
36 | @Autowired
37 | ArticleService articleService;
38 |
39 | /**
40 | * 按文章id查询用户是否已收藏,未收藏则添加收藏,已收藏则取消收藏
41 | *
42 | * @param id 文章id
43 | * @param request
44 | * @return
45 | */
46 | @PostMapping("/{id}")
47 | public Result favorite(@PathVariable Long id, HttpServletRequest request) {
48 | String jwt = request.getHeader("Authorization");
49 | if (JwtUtils.judgeTokenIsExist(jwt)) {
50 | try {
51 | String userId = JwtUtils.getUserId(jwt);
52 | Favorite favorite = favoriteService.findByUserIdAndArticleId(Long.valueOf(userId), id);
53 | if (favorite != null) {//已收藏,取消收藏
54 | favoriteService.removeFavorite(favorite);
55 | Map map = new HashMap<>();
56 | map.put("favorite", false);
57 | return Result.ok("已取消收藏", map);
58 | } else {//未收藏,添加收藏
59 | Favorite f = new Favorite();
60 | f.setUserId(Long.valueOf(userId));
61 | f.setArticleId(id);
62 | favoriteService.saveFavorite(f);
63 | Map map = new HashMap<>();
64 | map.put("favorite", true);
65 | return Result.ok("收藏成功", map);
66 | }
67 | } catch (Exception e) {
68 | e.printStackTrace();
69 | return Result.create(403, "Token已失效,请重新登录!");
70 | }
71 | } else {
72 | return Result.create(403, "请登录");
73 | }
74 | }
75 |
76 | /**
77 | * 获取当前用户文章收藏夹列表
78 | *
79 | * @param request
80 | * @return
81 | */
82 | @GetMapping("/list")
83 | public Result userFavorite(HttpServletRequest request) {
84 | String jwt = request.getHeader("Authorization");
85 | if (JwtUtils.judgeTokenIsExist(jwt)) {
86 | try {
87 | String userId = JwtUtils.getUserId(jwt);
88 | List favorites = favoriteService.listFavorite(Long.valueOf(userId));
89 | List articles = new ArrayList<>();
90 | for (Favorite favorite : favorites) {
91 | articles.add(articleService.getFavoriteArticle(favorite.getArticleId()));
92 | }
93 | return Result.ok("请求成功", articles);
94 | } catch (Exception e) {
95 | e.printStackTrace();
96 | return Result.create(403, "Token已失效,请重新登录!");
97 | }
98 | } else {
99 | return Result.create(403, "请登录");
100 | }
101 | }
102 |
103 | /**
104 | * 获取用户收藏文章数
105 | *
106 | * @param request
107 | * @return
108 | */
109 | @GetMapping("/num")
110 | public Result userFavoriteNum(HttpServletRequest request) {
111 | String jwt = request.getHeader("Authorization");
112 | if (JwtUtils.judgeTokenIsExist(jwt)) {
113 | try {
114 | String userId = JwtUtils.getUserId(jwt);
115 | int num = favoriteService.countFavoriteByUserId(Long.valueOf(userId));
116 | return Result.ok("请求成功", num);
117 | } catch (Exception e) {
118 | e.printStackTrace();
119 | return Result.create(403, "Token已失效,请重新登录!");
120 | }
121 | } else {
122 | return Result.create(403, "请登录");
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/controller/LoginController.java:
--------------------------------------------------------------------------------
1 | package top.naccl.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.web.bind.annotation.PostMapping;
5 | import org.springframework.web.bind.annotation.RequestParam;
6 | import org.springframework.web.bind.annotation.RestController;
7 | import top.naccl.model.entity.User;
8 | import top.naccl.model.vo.Result;
9 | import top.naccl.service.UserService;
10 | import top.naccl.util.JwtUtils;
11 | import top.naccl.util.MD5Utils;
12 |
13 | import java.util.HashMap;
14 | import java.util.Map;
15 |
16 | /**
17 | * @Description: 用户登录
18 | * @Author: Naccl
19 | * @Date: 2020-11-05
20 | */
21 | @RestController
22 | public class LoginController {
23 | @Autowired
24 | UserService userService;
25 |
26 | /**
27 | * 用户登录
28 | *
29 | * @param username 用户名
30 | * @param password 密码
31 | * @return
32 | */
33 | @PostMapping("/login")
34 | public Result login(@RequestParam String username, @RequestParam String password) {
35 | User user = userService.checkUserByUsername(username);
36 | if (user == null || !user.getPassword().equals(MD5Utils.getMD5(password))) {
37 | return Result.create(401, "用户名或密码错误!");
38 | }
39 | user.setPassword(null);
40 | String subject = user.getId() + ":" + user.getUsername();
41 | String jwt = JwtUtils.generateToken(subject);
42 | Map map = new HashMap<>();
43 | map.put("user", user);
44 | map.put("token", jwt);
45 | return Result.ok("登录成功", map);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/controller/RegisterController.java:
--------------------------------------------------------------------------------
1 | package top.naccl.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.web.bind.annotation.PostMapping;
5 | import org.springframework.web.bind.annotation.RequestParam;
6 | import org.springframework.web.bind.annotation.RestController;
7 | import top.naccl.model.entity.User;
8 | import top.naccl.model.vo.Result;
9 | import top.naccl.service.UserService;
10 | import top.naccl.util.JwtUtils;
11 | import top.naccl.util.MD5Utils;
12 |
13 | import java.util.HashMap;
14 | import java.util.Map;
15 |
16 | /**
17 | * @Description: 注册
18 | * @Author: Naccl
19 | * @Date: 2020-10-06
20 | */
21 | @RestController
22 | public class RegisterController {
23 | @Autowired
24 | UserService userService;
25 |
26 | /**
27 | * 用户注册
28 | *
29 | * @param username 用户名
30 | * @param password 密码
31 | * @return
32 | */
33 | @PostMapping("/register")
34 | public Result register(@RequestParam String username, @RequestParam String password) {
35 | User user = userService.checkUserByUsername(username);
36 | if (user != null) {
37 | return Result.create(400, "用户名已存在");
38 | }
39 | User u = new User();
40 | u.setUsername(username);
41 | u.setPassword(MD5Utils.getMD5(password));
42 | userService.saveUser(u);
43 |
44 | u.setPassword(null);
45 | String subject = u.getId() + ":" + u.getUsername();
46 | String jwt = JwtUtils.generateToken(subject);
47 | Map map = new HashMap<>();
48 | map.put("user", u);
49 | map.put("token", jwt);
50 | return Result.ok("注册成功", map);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/controller/UserController.java:
--------------------------------------------------------------------------------
1 | package top.naccl.controller;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.web.bind.annotation.PostMapping;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RestController;
9 | import top.naccl.model.entity.User;
10 | import top.naccl.model.vo.Result;
11 | import top.naccl.service.UserService;
12 | import top.naccl.util.JwtUtils;
13 |
14 | import javax.servlet.http.HttpServletRequest;
15 |
16 | /**
17 | * @Description: 用户资料
18 | * @Author: Naccl
19 | * @Date: 2020-10-06
20 | */
21 | @RestController
22 | @RequestMapping("/user")
23 | public class UserController {
24 | @Autowired
25 | UserService userService;
26 | @Autowired
27 | ObjectMapper objectMapper;
28 |
29 | /**
30 | * 更新用户个人资料
31 | *
32 | * @param request
33 | * @return
34 | */
35 | @PostMapping("/update")
36 | public Result updateUser(HttpServletRequest request) {
37 | User user = JSON.parseObject(request.getParameter("user"), User.class);
38 | String jwt = request.getHeader("Authorization");
39 | if (JwtUtils.judgeTokenIsExist(jwt)) {
40 | try {
41 | String userId = JwtUtils.getUserId(jwt);
42 | userService.updateUserById(user, Long.valueOf(userId));
43 | } catch (Exception e) {
44 | e.printStackTrace();
45 | return Result.create(403, "Token已失效,请重新登录!");
46 | }
47 | } else {
48 | return Result.create(403, "请登录");
49 | }
50 | return Result.ok("更新成功");
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/exception/BadRequestException.java:
--------------------------------------------------------------------------------
1 | package top.naccl.exception;
2 |
3 | /**
4 | * @Description: 非法请求异常
5 | * @Author: Naccl
6 | * @Date: 2020-10-16
7 | */
8 | public class BadRequestException extends RuntimeException {
9 | public BadRequestException() {
10 | }
11 |
12 | public BadRequestException(String message) {
13 | super(message);
14 | }
15 |
16 | public BadRequestException(String message, Throwable cause) {
17 | super(message, cause);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/exception/NotFoundException.java:
--------------------------------------------------------------------------------
1 | package top.naccl.exception;
2 |
3 | /**
4 | * @Description: 404异常
5 | * @Author: Naccl
6 | * @Date: 2020-10-16
7 | */
8 | public class NotFoundException extends RuntimeException {
9 | public NotFoundException() {
10 | }
11 |
12 | public NotFoundException(String message) {
13 | super(message);
14 | }
15 |
16 | public NotFoundException(String message, Throwable cause) {
17 | super(message, cause);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/exception/PersistenceException.java:
--------------------------------------------------------------------------------
1 | package top.naccl.exception;
2 |
3 | /**
4 | * @Description: 持久化异常
5 | * @Author: Naccl
6 | * @Date: 2020-10-16
7 | */
8 | public class PersistenceException extends RuntimeException {
9 | public PersistenceException() {
10 | }
11 |
12 | public PersistenceException(String message) {
13 | super(message);
14 | }
15 |
16 | public PersistenceException(String message, Throwable cause) {
17 | super(message, cause);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/handler/ControllerExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package top.naccl.handler;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.web.bind.annotation.ExceptionHandler;
6 | import org.springframework.web.bind.annotation.RestControllerAdvice;
7 | import top.naccl.exception.NotFoundException;
8 | import top.naccl.exception.PersistenceException;
9 | import top.naccl.model.vo.Result;
10 |
11 | import javax.servlet.http.HttpServletRequest;
12 |
13 | /**
14 | * @Description: 对Controller层全局异常处理
15 | * @RestControllerAdvice 捕获异常后,返回json数据类型
16 | * @Author: Naccl
17 | * @Date: 2020-10-16
18 | */
19 | @RestControllerAdvice
20 | public class ControllerExceptionHandler {
21 | private final Logger logger = LoggerFactory.getLogger(this.getClass());
22 |
23 | /**
24 | * 捕获自定义的404异常
25 | *
26 | * @param request 请求
27 | * @param e 自定义抛出的异常信息
28 | * @return
29 | */
30 | @ExceptionHandler(NotFoundException.class)
31 | public Result notFoundExceptionHandler(HttpServletRequest request, NotFoundException e) {
32 | logger.error("Request URL : {}, Exception : {}", request.getRequestURL(), e);
33 | return Result.create(404, e.getMessage());
34 | }
35 |
36 | /**
37 | * 捕获自定义的持久化异常
38 | *
39 | * @param request 请求
40 | * @param e 自定义抛出的异常信息
41 | * @return
42 | */
43 | @ExceptionHandler(PersistenceException.class)
44 | public Result persistenceExceptionHandler(HttpServletRequest request, PersistenceException e) {
45 | logger.error("Request URL : {}, Exception : {}", request.getRequestURL(), e);
46 | return Result.create(500, e.getMessage());
47 | }
48 |
49 | /**
50 | * 捕获其它异常
51 | *
52 | * @param request 请求
53 | * @param e 异常信息
54 | * @return
55 | */
56 | @ExceptionHandler(Exception.class)
57 | public Result exceptionHandler(HttpServletRequest request, Exception e) {
58 | logger.error("Request URL : {}, Exception : {}", request.getRequestURL(), e);
59 | return Result.create(500, "异常错误");
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/mapper/ArticleMapper.java:
--------------------------------------------------------------------------------
1 | package top.naccl.mapper;
2 |
3 | import org.apache.ibatis.annotations.Mapper;
4 | import org.springframework.stereotype.Repository;
5 | import top.naccl.model.entity.Article;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * @Description: 文章持久层接口
11 | * @Author: Naccl
12 | * @Date: 2020-10-16
13 | */
14 | @Mapper
15 | @Repository
16 | public interface ArticleMapper {
17 | List listArticle();
18 |
19 | Article getFavoriteArticle(Long id);
20 |
21 | Article findById(Long id);
22 |
23 | int updateViewsById(Long id);
24 |
25 | int updateStarById(Long id);
26 | }
27 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/mapper/CommentMapper.java:
--------------------------------------------------------------------------------
1 | package top.naccl.mapper;
2 |
3 | import org.apache.ibatis.annotations.Mapper;
4 | import org.springframework.stereotype.Repository;
5 | import top.naccl.model.entity.Comment;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * @Description: 文章评论持久层接口
11 | * @Author: Naccl
12 | * @Date: 2020-11-16
13 | */
14 | @Mapper
15 | @Repository
16 | public interface CommentMapper {
17 | List listComment(Long articleId);
18 |
19 | int saveComment(Comment comment);
20 | }
21 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/mapper/FavoriteMapper.java:
--------------------------------------------------------------------------------
1 | package top.naccl.mapper;
2 |
3 |
4 | import org.apache.ibatis.annotations.Mapper;
5 | import org.springframework.stereotype.Repository;
6 | import top.naccl.model.entity.Favorite;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @Description: 收藏夹持久层接口
12 | * @Author: Naccl
13 | * @Date: 2020-10-16
14 | */
15 | @Mapper
16 | @Repository
17 | public interface FavoriteMapper {
18 | int saveFavorite(Favorite favorite);
19 |
20 | int removeFavorite(Favorite favorite);
21 |
22 | Favorite findByUserIdAndArticleId(Long userId, Long articleId);
23 |
24 | List listFavoriteByUserId(Long userId);
25 |
26 | int countFavoriteByUserId(Long userId);
27 | }
28 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/mapper/UserMapper.java:
--------------------------------------------------------------------------------
1 | package top.naccl.mapper;
2 |
3 | import org.apache.ibatis.annotations.Mapper;
4 | import org.springframework.stereotype.Repository;
5 | import top.naccl.model.entity.User;
6 |
7 | /**
8 | * @Description: 用户持久层接口
9 | * @Author: Naccl
10 | * @Date: 2020-10-16
11 | */
12 | @Mapper
13 | @Repository
14 | public interface UserMapper {
15 | User findByUsername(String username);
16 |
17 | int saveUser(User user);
18 |
19 | int updateUserById(User user, Long id);
20 | }
21 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/model/entity/Article.java:
--------------------------------------------------------------------------------
1 | package top.naccl.model.entity;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | /**
9 | * @Description: 文章实体类
10 | * @Author: Naccl
11 | * @Date: 2020-10-06
12 | */
13 | @NoArgsConstructor
14 | @Getter
15 | @Setter
16 | @ToString
17 | public class Article {
18 | private Long id;
19 | private String title;
20 | private String author;
21 | private String date;
22 | private String description;
23 | private String firstPicture;
24 | private String content;
25 | private Integer star;
26 | private Integer views;
27 | }
28 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/model/entity/Comment.java:
--------------------------------------------------------------------------------
1 | package top.naccl.model.entity;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | import java.util.Date;
9 |
10 | /**
11 | * @Description: 文章评论
12 | * @Author: Naccl
13 | * @Date: 2020-11-16
14 | */
15 | @NoArgsConstructor
16 | @Getter
17 | @Setter
18 | @ToString
19 | public class Comment {
20 | private Long id;
21 | private Long userId;
22 | private Long articleId;
23 | private String content;
24 | private Date createTime;
25 | }
26 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/model/entity/Favorite.java:
--------------------------------------------------------------------------------
1 | package top.naccl.model.entity;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | /**
9 | * @Description: 收藏夹实体类
10 | * @Author: Naccl
11 | * @Date: 2020-10-06
12 | */
13 | @NoArgsConstructor
14 | @Getter
15 | @Setter
16 | @ToString
17 | public class Favorite {
18 | private Long id;
19 | private Long userId;
20 | private Long articleId;
21 | }
22 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/model/entity/User.java:
--------------------------------------------------------------------------------
1 | package top.naccl.model.entity;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | /**
9 | * @Description: 用户实体类
10 | * @Author: Naccl
11 | * @Date: 2020-10-06
12 | */
13 | @NoArgsConstructor
14 | @Getter
15 | @Setter
16 | @ToString
17 | public class User {
18 | private Long id;
19 | private String username;
20 | private String password;
21 | private String avatar;
22 | private String introduction;
23 | private String sex;
24 | private String email;
25 | private String education;
26 | private String job;
27 | private String birthday;
28 | }
29 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/model/vo/Comment.java:
--------------------------------------------------------------------------------
1 | package top.naccl.model.vo;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | import java.util.Date;
9 |
10 | /**
11 | * @Description: 文章评论vo
12 | * @Author: Naccl
13 | * @Date: 2020-11-16
14 | */
15 | @NoArgsConstructor
16 | @Getter
17 | @Setter
18 | @ToString
19 | public class Comment {
20 | private String username;
21 | private String avatar;
22 | private String content;
23 | private Date createTime;
24 | }
25 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/model/vo/Result.java:
--------------------------------------------------------------------------------
1 | package top.naccl.model.vo;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | /**
9 | * @Description: 封装响应结果
10 | * @Author: Naccl
11 | * @Date: 2020-10-06
12 | */
13 | @NoArgsConstructor
14 | @Getter
15 | @Setter
16 | @ToString
17 | public class Result {
18 | private Integer code;
19 | private String msg;
20 | private Object data;
21 |
22 | private Result(Integer code, String msg) {
23 | this.code = code;
24 | this.msg = msg;
25 | this.data = null;
26 | }
27 |
28 | private Result(Integer code, String msg, Object data) {
29 | this.code = code;
30 | this.msg = msg;
31 | this.data = data;
32 | }
33 |
34 | public static Result ok(String msg, Object data) {
35 | return new Result(200, msg, data);
36 | }
37 |
38 | public static Result ok(String msg) {
39 | return new Result(200, msg);
40 | }
41 |
42 | public static Result error(String msg) {
43 | return new Result(500, msg);
44 | }
45 |
46 | public static Result error() {
47 | return new Result(500, "异常错误");
48 | }
49 |
50 | public static Result create(Integer code, String msg, Object data) {
51 | return new Result(code, msg, data);
52 | }
53 |
54 | public static Result create(Integer code, String msg) {
55 | return new Result(code, msg);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/service/ArticleService.java:
--------------------------------------------------------------------------------
1 | package top.naccl.service;
2 |
3 | import top.naccl.model.entity.Article;
4 |
5 | import java.util.List;
6 |
7 | public interface ArticleService {
8 | List listArticle(Integer start);
9 |
10 | Article getFavoriteArticle(Long id);
11 |
12 | Article findById(Long id);
13 |
14 | void updateArticleStarById(Long id);
15 |
16 | void updateArticleViewById(Long id);
17 | }
18 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/service/CommentService.java:
--------------------------------------------------------------------------------
1 | package top.naccl.service;
2 |
3 | import top.naccl.model.entity.Comment;
4 |
5 | import java.util.List;
6 |
7 | public interface CommentService {
8 | List listComment(Long articleId);
9 |
10 | int saveComment(Comment comment);
11 | }
12 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/service/FavoriteService.java:
--------------------------------------------------------------------------------
1 | package top.naccl.service;
2 |
3 | import top.naccl.model.entity.Favorite;
4 |
5 | import java.util.List;
6 |
7 | public interface FavoriteService {
8 | void saveFavorite(Favorite favorite);
9 |
10 | void removeFavorite(Favorite favorite);
11 |
12 | Favorite findByUserIdAndArticleId(Long userId, Long ArticleId);
13 |
14 | List listFavorite(Long userId);
15 |
16 | int countFavoriteByUserId(Long userId);
17 | }
18 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/service/UserService.java:
--------------------------------------------------------------------------------
1 | package top.naccl.service;
2 |
3 | import top.naccl.model.entity.User;
4 |
5 | public interface UserService {
6 | User checkUserByUsername(String username);
7 |
8 | void saveUser(User user);
9 |
10 | void updateUserById(User user, Long id);
11 | }
12 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/service/impl/ArticleServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.naccl.service.impl;
2 |
3 | import com.github.pagehelper.PageHelper;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.stereotype.Service;
6 | import org.springframework.transaction.annotation.Transactional;
7 | import top.naccl.exception.PersistenceException;
8 | import top.naccl.mapper.ArticleMapper;
9 | import top.naccl.model.entity.Article;
10 | import top.naccl.service.ArticleService;
11 |
12 | import java.util.List;
13 |
14 | /**
15 | * @Description: 文章业务层实现
16 | * @Author: Naccl
17 | * @Date: 2020-10-16
18 | */
19 | @Service
20 | public class ArticleServiceImpl implements ArticleService {
21 | @Autowired
22 | ArticleMapper articleMapper;
23 | //每页显示7条资讯简介
24 | private static final Integer pageSize = 7;
25 |
26 | @Override
27 | public List listArticle(Integer pageNum) {
28 | PageHelper.startPage(pageNum, pageSize);
29 | return articleMapper.listArticle();
30 | }
31 |
32 | @Override
33 | public Article getFavoriteArticle(Long id) {
34 | return articleMapper.getFavoriteArticle(id);
35 | }
36 |
37 | @Override
38 | public Article findById(Long id) {
39 | updateArticleViewById(id);
40 | return articleMapper.findById(id);
41 | }
42 |
43 | @Transactional
44 | @Override
45 | public void updateArticleStarById(Long id) {
46 | if (articleMapper.updateStarById(id) != 1) {
47 | throw new PersistenceException("点赞失败");
48 | }
49 | }
50 |
51 | @Transactional
52 | @Override
53 | public void updateArticleViewById(Long id) {
54 | if (articleMapper.updateViewsById(id) != 1) {
55 | throw new PersistenceException("更新失败");
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/service/impl/CommentServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.naccl.service.impl;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.stereotype.Service;
5 | import top.naccl.mapper.CommentMapper;
6 | import top.naccl.model.entity.Comment;
7 | import top.naccl.service.CommentService;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * @Description: 文章评论业务层实现
13 | * @Author: Naccl
14 | * @Date: 2020-11-16
15 | */
16 | @Service
17 | public class CommentServiceImpl implements CommentService {
18 | @Autowired
19 | CommentMapper commentMapper;
20 |
21 | @Override
22 | public List listComment(Long articleId) {
23 | return commentMapper.listComment(articleId);
24 | }
25 |
26 | @Override
27 | public int saveComment(Comment comment) {
28 | return commentMapper.saveComment(comment);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/service/impl/FavoriteServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.naccl.service.impl;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.stereotype.Service;
5 | import org.springframework.transaction.annotation.Transactional;
6 | import top.naccl.exception.PersistenceException;
7 | import top.naccl.mapper.FavoriteMapper;
8 | import top.naccl.model.entity.Favorite;
9 | import top.naccl.service.FavoriteService;
10 |
11 | import java.util.List;
12 |
13 | /**
14 | * @Description: 收藏夹业务层实现
15 | * @Author: Naccl
16 | * @Date: 2020-10-16
17 | */
18 | @Service
19 | public class FavoriteServiceImpl implements FavoriteService {
20 | @Autowired
21 | FavoriteMapper favoriteMapper;
22 |
23 | @Transactional
24 | @Override
25 | public void saveFavorite(Favorite favorite) {
26 | if (favoriteMapper.saveFavorite(favorite) != 1) {
27 | throw new PersistenceException("操作失败");
28 | }
29 | }
30 |
31 | @Transactional
32 | @Override
33 | public void removeFavorite(Favorite favorite) {
34 | if (favoriteMapper.removeFavorite(favorite) != 1) {
35 | throw new PersistenceException("操作失败");
36 | }
37 | }
38 |
39 | @Override
40 | public Favorite findByUserIdAndArticleId(Long userId, Long articleId) {
41 | return favoriteMapper.findByUserIdAndArticleId(userId, articleId);
42 | }
43 |
44 | @Override
45 | public List listFavorite(Long userId) {
46 | return favoriteMapper.listFavoriteByUserId(userId);
47 | }
48 |
49 | @Override
50 | public int countFavoriteByUserId(Long userId) {
51 | return favoriteMapper.countFavoriteByUserId(userId);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/service/impl/UserServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.naccl.service.impl;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.stereotype.Service;
5 | import org.springframework.transaction.annotation.Transactional;
6 | import top.naccl.exception.PersistenceException;
7 | import top.naccl.mapper.UserMapper;
8 | import top.naccl.model.entity.User;
9 | import top.naccl.service.UserService;
10 |
11 | /**
12 | * @Description: 用户业务层实现
13 | * @Author: Naccl
14 | * @Date: 2020-10-16
15 | */
16 | @Service
17 | public class UserServiceImpl implements UserService {
18 | @Autowired
19 | UserMapper userMapper;
20 |
21 | @Override
22 | public User checkUserByUsername(String username) {
23 | return userMapper.findByUsername(username);
24 | }
25 |
26 | @Transactional
27 | @Override
28 | public void saveUser(User user) {
29 | if (userMapper.saveUser(user) != 1) {
30 | throw new PersistenceException("注册失败");
31 | }
32 | }
33 |
34 | @Transactional
35 | @Override
36 | public void updateUserById(User user, Long id) {
37 | if (userMapper.updateUserById(user, id) != 1) {
38 | throw new PersistenceException("更新失败");
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/util/JwtUtils.java:
--------------------------------------------------------------------------------
1 | package top.naccl.util;
2 |
3 | import io.jsonwebtoken.Claims;
4 | import io.jsonwebtoken.Jwts;
5 | import io.jsonwebtoken.SignatureAlgorithm;
6 | import org.springframework.beans.factory.annotation.Value;
7 | import org.springframework.stereotype.Component;
8 |
9 | import java.util.Date;
10 |
11 | /**
12 | * @Description: JWT工具类
13 | * @Author: Naccl
14 | * @Date: 2020-10-16
15 | */
16 | @Component
17 | public class JwtUtils {
18 | private static long expireTime;
19 | private static String secretKey;
20 |
21 | @Value("${token.secretKey}")
22 | public void setSecretKey(String secretKey) {
23 | this.secretKey = secretKey;
24 | }
25 |
26 | @Value("${token.expireTime}")
27 | public void setExpireTime(long expireTime) {
28 | this.expireTime = expireTime;
29 | }
30 |
31 | /**
32 | * 判断token是否存在
33 | *
34 | * @param token
35 | * @return
36 | */
37 | public static boolean judgeTokenIsExist(String token) {
38 | return token != null && !"".equals(token) && !"null".equals(token);
39 | }
40 |
41 | /**
42 | * 生成token
43 | *
44 | * @param subject
45 | * @return
46 | */
47 | public static String generateToken(String subject) {
48 | String jwt = Jwts.builder()
49 | .setSubject(subject)
50 | .setExpiration(new Date(System.currentTimeMillis() + expireTime))
51 | .signWith(SignatureAlgorithm.HS512, secretKey)
52 | .compact();
53 | return jwt;
54 | }
55 |
56 | /**
57 | * 生成自定义过期时间token
58 | *
59 | * @param subject
60 | * @param expireTime
61 | * @return
62 | */
63 | public static String generateToken(String subject, long expireTime) {
64 | String jwt = Jwts.builder()
65 | .setSubject(subject)
66 | .setExpiration(new Date(System.currentTimeMillis() + expireTime))
67 | .signWith(SignatureAlgorithm.HS512, secretKey)
68 | .compact();
69 | return jwt;
70 | }
71 |
72 |
73 | /**
74 | * 获取tokenBody同时校验token是否有效(无效则会抛出异常)
75 | *
76 | * @param token
77 | * @return
78 | */
79 | public static Claims getTokenBody(String token) {
80 | Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token.replace("Bearer", "")).getBody();
81 | return claims;
82 | }
83 |
84 | public static String getUserId(String token) {
85 | String subject = getTokenBody(token).getSubject();
86 | String[] split = subject.split(":");
87 | return split[0];
88 | }
89 |
90 | public static String getUsername(String token) {
91 | String subject = getTokenBody(token).getSubject();
92 | String[] split = subject.split(":");
93 | return split[1];
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/android-api/src/main/java/top/naccl/util/MD5Utils.java:
--------------------------------------------------------------------------------
1 | package top.naccl.util;
2 |
3 | import org.springframework.util.DigestUtils;
4 |
5 | public class MD5Utils {
6 | public static String getMD5(String str) {
7 | return DigestUtils.md5DigestAsHex(str.getBytes());
8 | }
9 |
10 | public static void main(String[] args) {
11 | System.out.println(getMD5("123456"));
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/android-api/src/main/resources/application-dev.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/android-api/src/main/resources/application-dev.properties
--------------------------------------------------------------------------------
/android-api/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.profiles.active=dev
--------------------------------------------------------------------------------
/android-api/src/main/resources/logback-spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | ${FILE_LOG_PATTERN}
10 |
11 |
12 | ${LOG_FILE}-%d{yyyy-MM-dd}-%i.log
13 | 365
14 |
15 | 10MB
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/android-api/src/main/resources/mapper/ArticleMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
13 |
14 |
15 |
18 |
19 |
20 |
21 | update article set views = views+1 where id=#{id}
22 |
23 |
24 |
25 |
26 | update article set star = star+1 where id=#{id}
27 |
28 |
29 |
--------------------------------------------------------------------------------
/android-api/src/main/resources/mapper/CommentMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
16 |
--------------------------------------------------------------------------------
/android-api/src/main/resources/mapper/FavoriteMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | insert into favorite (id,user_id,article_id) values (#{id},#{userId},#{articleId})
7 |
8 |
9 |
10 | delete from favorite where id=#{id}
11 |
12 |
13 |
14 |
17 |
18 |
19 |
22 |
23 |
26 |
27 |
--------------------------------------------------------------------------------
/android-api/src/main/resources/mapper/UserMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 | insert into user (id, username, password, avatar, introduction, sex, email, education, job, birthday)
12 | values (#{id}, #{username}, #{password}, #{avatar}, #{introduction}, #{sex}, #{email}, #{education}, #{job}, #{birthday})
13 |
14 |
15 |
16 |
17 | update user set avatar=#{user.avatar}, introduction=#{user.introduction}, sex=#{user.sex}, email=#{user.email},
18 | education=#{user.education}, job=#{user.job}, birthday=#{user.birthday} where id=#{id}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/android-api/src/test/java/top/naccl/AndroidApiApplicationTests.java:
--------------------------------------------------------------------------------
1 | package top.naccl;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class AndroidApiApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/image/gamebox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/image/gamebox.png
--------------------------------------------------------------------------------
/image/修改资料.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/image/修改资料.png
--------------------------------------------------------------------------------
/image/我的.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/image/我的.png
--------------------------------------------------------------------------------
/image/扫描二维码.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/image/扫描二维码.png
--------------------------------------------------------------------------------
/image/收藏夹.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/image/收藏夹.png
--------------------------------------------------------------------------------
/image/文章1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/image/文章1.png
--------------------------------------------------------------------------------
/image/文章2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/image/文章2.png
--------------------------------------------------------------------------------
/image/登录.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/image/登录.png
--------------------------------------------------------------------------------
/image/设置.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/image/设置.png
--------------------------------------------------------------------------------
/image/评论.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/image/评论.png
--------------------------------------------------------------------------------
/image/静态页.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/image/静态页.png
--------------------------------------------------------------------------------
/image/首页.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/image/首页.png
--------------------------------------------------------------------------------
/原型/GameBox.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/原型/GameBox.zip
--------------------------------------------------------------------------------
/原型/GameBoxSnapshoot.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/原型/GameBoxSnapshoot.zip
--------------------------------------------------------------------------------