20260123最后备份
This commit is contained in:
62
back/main.py
62
back/main.py
@@ -92,18 +92,16 @@ def load_config():
|
||||
NEED_AUDIT = settings.need_audit
|
||||
except Exception as e:
|
||||
print(f"Warning: Failed to load settings: {e}")
|
||||
|
||||
def load_deny_words():
|
||||
global DENY_WORDS_CACHE
|
||||
with app.app_context():
|
||||
try:
|
||||
words = db.session.query(DenyWord.word).all()
|
||||
# words 是 list of tuples [('word1',), ('word2',)]
|
||||
DENY_WORDS_CACHE = [w[0] for w in words]
|
||||
print(f"Loaded {len(DENY_WORDS_CACHE)} deny words.")
|
||||
except Exception as e:
|
||||
print(f"Warning: Failed to load deny words: {e}")
|
||||
|
||||
global DENY_WORDS_CACHE
|
||||
with app.app_context():
|
||||
try:
|
||||
words = db.session.query(DenyWord.word).all()
|
||||
# words 是 list of tuples [('word1',), ('word2',)]
|
||||
DENY_WORDS_CACHE = [w[0] for w in words]
|
||||
print(f"Loaded {len(DENY_WORDS_CACHE)} deny words.")
|
||||
except Exception as e:
|
||||
print(f"Warning: Failed to load deny words: {e}")
|
||||
|
||||
# --- 用户普通api端点 ---
|
||||
@app.route('/api/settings', methods=['GET'])
|
||||
def get_settings():
|
||||
@@ -367,6 +365,45 @@ def get_statics():
|
||||
except Exception as e:
|
||||
return jsonify({"code": 2003, "data": str(e)})
|
||||
|
||||
@app.route('/api/10_info', methods=['GET'])
|
||||
def get_10_info():
|
||||
try:
|
||||
page = request.args.get("page", 1, type=int)
|
||||
if page < 1:
|
||||
page = 1
|
||||
|
||||
per_page = 10
|
||||
# 相比v1的优化:使用数据库层面的过滤和分页,避免一次性加载所有数据
|
||||
pagination = Submission.query.filter_by(status='Pass')\
|
||||
.order_by(Submission.id.desc())\
|
||||
.paginate(page=page, per_page=per_page, error_out=False)
|
||||
|
||||
page_posts = pagination.items
|
||||
|
||||
data = []
|
||||
for s in page_posts:
|
||||
data.append({
|
||||
"id": s.id,
|
||||
"content": s.content,
|
||||
"upvotes": s.upvotes,
|
||||
"downvotes": s.downvotes,
|
||||
"created_at": s.created_at.isoformat() if s.created_at else None,
|
||||
"comment_count": len(s.comments),
|
||||
"total_pages": pagination.total,
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
"code": 1000,
|
||||
"data": data
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({"code": 2003, "data": str(e)})
|
||||
|
||||
# --- 菜单 ---
|
||||
@app.route('/get/teapot', methods=['GET'])
|
||||
def return_418():
|
||||
abort(418)
|
||||
|
||||
# --- 用户的管理api端点 ---
|
||||
# TODO: 用户管理端点
|
||||
|
||||
@@ -377,5 +414,4 @@ def get_statics():
|
||||
if __name__ == '__main__':
|
||||
init_db()
|
||||
load_config()
|
||||
load_deny_words()
|
||||
app.run(debug=True, port=5000)
|
||||
|
||||
81
front/src/pages/NotFound.tsx
Normal file
81
front/src/pages/NotFound.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
// 复用 v1 的 NotFound 组件
|
||||
|
||||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { makeStyles, tokens, Card, CardHeader, CardPreview, Text, Button, Title1, Subtitle1 } from '@fluentui/react-components';
|
||||
import { ArrowLeft24Regular, Home24Regular } from '@fluentui/react-icons';
|
||||
|
||||
const useStyles = makeStyles({
|
||||
page: {
|
||||
minHeight: '100vh',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: tokens.colorNeutralBackground3,
|
||||
padding: tokens.spacingHorizontalXL,
|
||||
},
|
||||
card: {
|
||||
width: 'min(720px, 92vw)',
|
||||
borderRadius: tokens.borderRadiusLarge,
|
||||
overflow: 'hidden',
|
||||
boxShadow: tokens.shadow8,
|
||||
},
|
||||
header: {
|
||||
paddingLeft: tokens.spacingHorizontalXL,
|
||||
paddingRight: tokens.spacingHorizontalXL,
|
||||
paddingTop: tokens.spacingVerticalM,
|
||||
paddingBottom: tokens.spacingVerticalM,
|
||||
},
|
||||
preview: {
|
||||
height: '140px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
background: `linear-gradient(135deg, ${tokens.colorBrandBackground} 0%, ${tokens.colorBrandBackground2} 50%, ${tokens.colorPaletteBlueBackground2} 100%)`,
|
||||
color: tokens.colorNeutralForegroundOnBrand,
|
||||
},
|
||||
content: {
|
||||
paddingLeft: tokens.spacingHorizontalXL,
|
||||
paddingRight: tokens.spacingHorizontalXL,
|
||||
paddingTop: tokens.spacingVerticalL,
|
||||
paddingBottom: tokens.spacingVerticalL,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: tokens.spacingVerticalM,
|
||||
},
|
||||
actions: {
|
||||
display: 'flex',
|
||||
gap: tokens.spacingHorizontalM,
|
||||
marginTop: tokens.spacingVerticalL,
|
||||
},
|
||||
});
|
||||
|
||||
const NotFound: React.FC = () => {
|
||||
const styles = useStyles();
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div className={styles.page}>
|
||||
<Card className={styles.card}>
|
||||
<CardHeader className={styles.header} header={<Title1 style={{ margin: 0 }}>😕 404 Not Found</Title1>} />
|
||||
<CardPreview>
|
||||
<div className={styles.preview} />
|
||||
</CardPreview>
|
||||
<div className={styles.content}>
|
||||
<Subtitle1>Oh no, 页面不见了喵😭</Subtitle1>
|
||||
<Text>看看是不是链接打错了呀?点击下方按钮继续浏览哦</Text>
|
||||
<div className={styles.actions}>
|
||||
<Button appearance="primary" icon={<ArrowLeft24Regular />} onClick={() => navigate(-1)}>
|
||||
返回上一页
|
||||
</Button>
|
||||
<Button appearance="secondary" icon={<Home24Regular />} onClick={() => navigate('/') }>
|
||||
返回首页
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NotFound;
|
||||
Reference in New Issue
Block a user