Unify success codes and update upload deps
This commit is contained in:
@@ -10,3 +10,5 @@
|
|||||||
rate limit功能
|
rate limit功能
|
||||||
|
|
||||||
rss功能
|
rss功能
|
||||||
|
|
||||||
|
完成开发后记得Debug=False
|
||||||
|
|||||||
45
back/main.py
45
back/main.py
@@ -8,6 +8,8 @@ import os
|
|||||||
import uuid
|
import uuid
|
||||||
import json
|
import json
|
||||||
import filetype
|
import filetype
|
||||||
|
from PIL import Image
|
||||||
|
from PIL import UnidentifiedImageError
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
@@ -212,6 +214,23 @@ def save_hashtags(tag_type, target_id, hashtopic):
|
|||||||
)
|
)
|
||||||
db.session.add(new_tag)
|
db.session.add(new_tag)
|
||||||
|
|
||||||
|
def mime_allowed(mime, rules):
|
||||||
|
if not rules:
|
||||||
|
return True
|
||||||
|
if not mime:
|
||||||
|
return False
|
||||||
|
mime = mime.lower()
|
||||||
|
for rule in rules:
|
||||||
|
rule = str(rule).strip().lower()
|
||||||
|
if not rule:
|
||||||
|
continue
|
||||||
|
if rule == 'image/*':
|
||||||
|
if mime.startswith('image/'):
|
||||||
|
return True
|
||||||
|
if mime == rule:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
# --- 用户普通api端点 ---
|
# --- 用户普通api端点 ---
|
||||||
@app.route('/api/settings', methods=['GET'])
|
@app.route('/api/settings', methods=['GET'])
|
||||||
def get_settings():
|
def get_settings():
|
||||||
@@ -244,7 +263,7 @@ def get_about():
|
|||||||
"data": settings.about
|
"data": settings.about
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
# about在初始化时不会被设置,避免管理面板报错,返回默认文本
|
# about在初始化时不会被设置,避免报错,返回默认文本
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"code": 1000,
|
"code": 1000,
|
||||||
"data": "# 默认关于页面\n关于页面未设置,请前往管理面板操作。"
|
"data": "# 默认关于页面\n关于页面未设置,请前往管理面板操作。"
|
||||||
@@ -354,7 +373,7 @@ def submit_post():
|
|||||||
save_hashtags(0, new_post.id, hashtopic)
|
save_hashtags(0, new_post.id, hashtopic)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
code = 1002 if new_post.status == 'Pending' else 1001
|
code = 1002 if new_post.status == 'Pending' else 1000
|
||||||
return jsonify({"code": code, "data": {"id": new_post.id}})
|
return jsonify({"code": code, "data": {"id": new_post.id}})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
@@ -409,7 +428,7 @@ def submit_comment():
|
|||||||
save_hashtags(1, new_comment.id, hashtopic)
|
save_hashtags(1, new_comment.id, hashtopic)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return jsonify({"code": 1001, "data": {"id": new_comment.id}})
|
return jsonify({"code": 1000, "data": {"id": new_comment.id}})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
return jsonify({"code": 2003, "data": f"评论失败: {str(e)}"})
|
return jsonify({"code": 2003, "data": f"评论失败: {str(e)}"})
|
||||||
@@ -448,7 +467,7 @@ def submit_report():
|
|||||||
db.session.add(report)
|
db.session.add(report)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return jsonify({"code": 1001, "data": {"id": report.id}})
|
return jsonify({"code": 1000, "data": {"id": report.id}})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({"code": 2003, "data": f"投诉失败: {str(e)}"})
|
return jsonify({"code": 2003, "data": f"投诉失败: {str(e)}"})
|
||||||
|
|
||||||
@@ -499,15 +518,27 @@ def upload_pic():
|
|||||||
if FILE_SIZE_LIMIT_MB is not None:
|
if FILE_SIZE_LIMIT_MB is not None:
|
||||||
limit_bytes = float(FILE_SIZE_LIMIT_MB) * 1024 * 1024
|
limit_bytes = float(FILE_SIZE_LIMIT_MB) * 1024 * 1024
|
||||||
if file_length > limit_bytes:
|
if file_length > limit_bytes:
|
||||||
return jsonify({"code": 2006, "data": "上传的图片超出限制大小"})
|
return jsonify({"code": 2006, "data": f"上传的图片超出{FILE_SIZE_LIMIT_MB}MB限制大小"})
|
||||||
|
|
||||||
ext = os.path.splitext(file.filename)[1].lstrip('.').lower()
|
ext = os.path.splitext(file.filename)[1].lstrip('.').lower()
|
||||||
kind = filetype.guess(file.read(5120))
|
kind = filetype.guess(file.read(5120))
|
||||||
file.seek(0)
|
file.seek(0)
|
||||||
detected_mime = kind.mime if kind else None
|
detected_mime = kind.mime if kind else None
|
||||||
if not detected_mime or (FILE_FORMATS and detected_mime.lower() not in FILE_FORMATS):
|
if not detected_mime or not mime_allowed(detected_mime, FILE_FORMATS):
|
||||||
return jsonify({"code": 2007, "data": "上传的文件类型不支持"})
|
return jsonify({"code": 2007, "data": "上传的文件类型不支持"})
|
||||||
|
|
||||||
|
try:
|
||||||
|
file.seek(0)
|
||||||
|
img = Image.open(file)
|
||||||
|
img.verify()
|
||||||
|
file.seek(0)
|
||||||
|
except (UnidentifiedImageError, OSError):
|
||||||
|
file.seek(0)
|
||||||
|
return jsonify({"code": 2008, "data": "上传的文件损坏"})
|
||||||
|
except Exception:
|
||||||
|
file.seek(0)
|
||||||
|
return jsonify({"code": 2008, "data": "上传的文件损坏"})
|
||||||
|
|
||||||
if not ext and kind:
|
if not ext and kind:
|
||||||
ext = kind.extension
|
ext = kind.extension
|
||||||
filename = f"{uuid.uuid4().hex}.{ext}" if ext else uuid.uuid4().hex
|
filename = f"{uuid.uuid4().hex}.{ext}" if ext else uuid.uuid4().hex
|
||||||
@@ -519,7 +550,7 @@ def upload_pic():
|
|||||||
db.session.add(ImgFile(path=filename, name=name, identity_token=identity_token))
|
db.session.add(ImgFile(path=filename, name=name, identity_token=identity_token))
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return jsonify({"code": 1001, "data": f"/api/files/{filename}"})
|
return jsonify({"code": 1000, "data": f"/api/files/{filename}"})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({"code": 2003, "data": str(e)})
|
return jsonify({"code": 2003, "data": str(e)})
|
||||||
|
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ Flask>=3.0.3
|
|||||||
Flask-CORS>=4.0.1
|
Flask-CORS>=4.0.1
|
||||||
Flask-SQLAlchemy>=3.1.1
|
Flask-SQLAlchemy>=3.1.1
|
||||||
filetype>=1.2.0
|
filetype>=1.2.0
|
||||||
|
Pillow>=10.0.0
|
||||||
|
|||||||
@@ -28,18 +28,17 @@
|
|||||||
|
|
||||||
| Code | 含义 |
|
| Code | 含义 |
|
||||||
| ---- | ---------------------------------------------------- |
|
| ---- | ---------------------------------------------------- |
|
||||||
| 1000 | 正常。适用于大多数成功的GET请求的返回。 |
|
| 1000 | 正常。适用于大多数成功的请求的返回。 |
|
||||||
| 1001 | 正常。适用于大多数成功的POST请求的返回。 |
|
|
||||||
| 1002 | 正常。提交内容需要等待审核。 |
|
| 1002 | 正常。提交内容需要等待审核。 |
|
||||||
| 2000 | 失败。请求方式错误,例如缺少指定参数。 |
|
| 2000 | 失败。请求格式错误,例如缺少指定参数。 |
|
||||||
| 2001 | 失败。未初始化。不应该在成功初始化后继续使用该code。 |
|
| 2001 | 失败。未初始化。不应该在成功初始化后继续使用该code。 |
|
||||||
| 2002 | 失败。数据不存在。 |
|
| 2002 | 失败。数据不存在。 |
|
||||||
| 2003 | 失败。服务器内部错误。 |
|
| 2003 | 失败。服务器内部错误。表示未预期的服务端异常,不应频繁出现。 |
|
||||||
| 2004 | 失败。试图使用不存在的Identity。 |
|
| 2004 | 失败。试图使用不存在的Identity。 |
|
||||||
| 2005 | 失败。提交内容包含违禁词。 |
|
| 2005 | 失败。提交内容包含违禁词。 |
|
||||||
| 2006 | 失败。上传的图片超出限制大小。 |
|
| 2006 | 失败。上传的图片超出限制大小。 |
|
||||||
| 2007 | 失败。上传的文件类型不支持。 |
|
| 2007 | 失败。上传的图片类型不支持。 |
|
||||||
| 404 | api端点不存在。 |
|
| 2008 | 失败。上传的图片损坏。 |
|
||||||
| | |
|
| | |
|
||||||
| | |
|
| | |
|
||||||
| | |
|
| | |
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ export const postComment = async (commentData: PostCommentRequest): Promise<Post
|
|||||||
|
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
handlePostApiCode(json);
|
handlePostApiCode(json);
|
||||||
if (json.code === 1001 && json.data?.id !== undefined) {
|
if (json.code === 1000 && json.data?.id !== undefined) {
|
||||||
return { id: Number(json.data.id) };
|
return { id: Number(json.data.id) };
|
||||||
}
|
}
|
||||||
if (json.code === 2005) {
|
if (json.code === 2005) {
|
||||||
@@ -466,7 +466,7 @@ export const reportPost = async (reportData: { id: number; title: string; conten
|
|||||||
}
|
}
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
handlePostApiCode(json);
|
handlePostApiCode(json);
|
||||||
if (json.code === 1001 && json.data?.id !== undefined) {
|
if (json.code === 1000 && json.data?.id !== undefined) {
|
||||||
return { id: Number(json.data.id) };
|
return { id: Number(json.data.id) };
|
||||||
}
|
}
|
||||||
throw new Error(json.data || 'Report failed');
|
throw new Error(json.data || 'Report failed');
|
||||||
@@ -493,12 +493,15 @@ export const uploadImage = async (file: File): Promise<string> => {
|
|||||||
}
|
}
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
handlePostApiCode(json);
|
handlePostApiCode(json);
|
||||||
if (json.code === 1001 && typeof json.data === 'string') {
|
if (json.code === 1000 && typeof json.data === 'string') {
|
||||||
return json.data;
|
return json.data;
|
||||||
}
|
}
|
||||||
if (json.code === 2006) {
|
if (json.code === 2006) {
|
||||||
throw new Error('UPLOAD_TOO_LARGE');
|
throw new Error('UPLOAD_TOO_LARGE');
|
||||||
}
|
}
|
||||||
|
if (json.code === 2008) {
|
||||||
|
throw new Error('CORRUPTED_IMAGE');
|
||||||
|
}
|
||||||
if (json.code === 2007) {
|
if (json.code === 2007) {
|
||||||
throw new Error('UNSUPPORTED_FORMAT');
|
throw new Error('UNSUPPORTED_FORMAT');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ const CreatePost: React.FC = () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await createPost(value);
|
const response = await createPost(value);
|
||||||
if (response.code === 1001 || response.code === 1002) {
|
if (response.code === 1000 || response.code === 1002) {
|
||||||
// 清除草稿
|
// 清除草稿
|
||||||
saveDraft('');
|
saveDraft('');
|
||||||
setValue('');
|
setValue('');
|
||||||
@@ -318,6 +318,13 @@ const CreatePost: React.FC = () => {
|
|||||||
</Toast>,
|
</Toast>,
|
||||||
{ intent: 'error' }
|
{ intent: 'error' }
|
||||||
);
|
);
|
||||||
|
} else if (msg.includes('CORRUPTED_IMAGE')) {
|
||||||
|
dispatchToast(
|
||||||
|
<Toast>
|
||||||
|
<ToastTitle>上传的文件损坏</ToastTitle>
|
||||||
|
</Toast>,
|
||||||
|
{ intent: 'error' }
|
||||||
|
);
|
||||||
} else if (msg.includes('UNSUPPORTED_FORMAT')) {
|
} else if (msg.includes('UNSUPPORTED_FORMAT')) {
|
||||||
dispatchToast(
|
dispatchToast(
|
||||||
<Toast>
|
<Toast>
|
||||||
|
|||||||
Reference in New Issue
Block a user