diff --git a/back/main.py b/back/main.py
index 62b58e9..d7db77e 100644
--- a/back/main.py
+++ b/back/main.py
@@ -53,23 +53,35 @@ class Submission(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
content = db.Column(db.Text, nullable=False)
identity_token = db.Column(db.String(36), nullable=True)
- status = db.Column(db.String(20), default='Pending')
+ status = db.Column(db.String(20), default='Pending', index=True)
created_at = db.Column(db.DateTime, default=now_time)
updated_at = db.Column(db.DateTime, default=now_time, onupdate=now_time)
upvotes = db.Column(db.Integer, default=0)
downvotes = db.Column(db.Integer, default=0)
comments = db.relationship('Comment', backref='submission', lazy=True, cascade='all, delete-orphan')
+ hashtags = db.relationship(
+ 'Hashtag',
+ primaryjoin="and_(Hashtag.type==0, Hashtag.target_id==Submission.id)",
+ cascade='all, delete-orphan',
+ lazy=True
+ )
class Comment(db.Model):
__tablename__ = 'comments'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
- submission_id = db.Column(db.Integer, db.ForeignKey('submissions.id'), nullable=False)
+ submission_id = db.Column(db.Integer, db.ForeignKey('submissions.id'), nullable=False, index=True)
nickname = db.Column(db.String(50), default='匿名用户')
content = db.Column(db.Text, nullable=False)
identity_token = db.Column(db.String(36), nullable=True)
created_at = db.Column(db.DateTime, default=now_time)
parent_comment_id = db.Column(db.Integer, db.ForeignKey('comments.id'), nullable=True)
+ hashtags = db.relationship(
+ 'Hashtag',
+ primaryjoin="and_(Hashtag.type==1, Hashtag.target_id==Comment.id)",
+ cascade='all, delete-orphan',
+ lazy=True
+ )
class Report(db.Model):
__tablename__ = 'reports'
@@ -711,10 +723,38 @@ def get_post_info():
@app.route('/api/hot_topics', methods=['GET'])
def get_hot_topics():
try:
+ submission_tags = db.session.query(
+ Hashtag.name.label('name')
+ ).join(
+ Submission,
+ db.and_(Hashtag.type == 0, Hashtag.target_id == Submission.id)
+ ).filter(
+ Submission.status == 'Pass'
+ )
+
+ comment_tags = db.session.query(
+ Hashtag.name.label('name')
+ ).join(
+ Comment,
+ db.and_(Hashtag.type == 1, Hashtag.target_id == Comment.id)
+ ).join(
+ Submission,
+ Comment.submission_id == Submission.id
+ ).filter(
+ Submission.status == 'Pass'
+ )
+
+ union_subq = submission_tags.union_all(comment_tags).subquery()
+
rows = db.session.query(
- Hashtag.name,
- db.func.count(Hashtag.name).label('count')
- ).group_by(Hashtag.name).order_by(db.func.count(Hashtag.name).desc()).limit(3).all()
+ union_subq.c.name,
+ db.func.count(union_subq.c.name).label('count')
+ ).group_by(
+ union_subq.c.name
+ ).order_by(
+ db.func.count(union_subq.c.name).desc(),
+ union_subq.c.name.asc()
+ ).limit(3).all()
data = [{"name": name, "count": int(count)} for name, count in rows]
return jsonify({"code": 1000, "data": {"list": data}})
diff --git a/front/src/components/CommentSection.tsx b/front/src/components/CommentSection.tsx
index a424a54..9abb8c3 100644
--- a/front/src/components/CommentSection.tsx
+++ b/front/src/components/CommentSection.tsx
@@ -261,10 +261,14 @@ useEffect(() => {
const diffHours = Math.floor(diffMs / 3600000);
const sameDay = now.toDateString() === date.toDateString();
if (sameDay) return `${diffHours}小时前`;
- const diffDays = Math.floor(diffMs / 86400000);
- const diffMonths = Math.floor(diffDays / 30);
- if (diffMonths >= 1 && diffMonths < 12) return `${diffMonths}个月前`;
- if (diffDays >= 1 && diffMonths < 1) return `${diffDays}天前`;
+ const todayMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();
+ const dateMidnight = new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
+ const diffDays = Math.max(1, Math.floor((todayMidnight - dateMidnight) / 86400000));
+ if (diffDays < 30) return `${diffDays}天前`;
+ let diffMonths = (now.getFullYear() * 12 + now.getMonth()) - (date.getFullYear() * 12 + date.getMonth());
+ if (now.getDate() < date.getDate()) diffMonths -= 1;
+ if (diffMonths < 1) diffMonths = 1;
+ if (diffMonths < 12) return `${diffMonths}个月前`;
const yyyy = date.getFullYear();
const mm = String(date.getMonth() + 1).padStart(2, '0');
const dd = String(date.getDate()).padStart(2, '0');
@@ -293,13 +297,12 @@ useEffect(() => {
a: ({ node, ...props }) => {
const href = props.href;
if (href && typeof href === 'string' && href.startsWith('/tag/#')) {
- const hash = href.slice('/tag/'.length);
return (
{
e.preventDefault();
- navigate({ pathname: '/tag', hash });
+ navigate(href);
}}
/>
);
diff --git a/front/src/components/PostCard.tsx b/front/src/components/PostCard.tsx
index e79ad1f..4e53e12 100644
--- a/front/src/components/PostCard.tsx
+++ b/front/src/components/PostCard.tsx
@@ -252,10 +252,14 @@ const PostCard = ({
const diffHours = Math.floor(diffMs / 3600000);
const sameDay = now.toDateString() === date.toDateString();
if (sameDay) return `${diffHours}小时前`;
- const diffDays = Math.floor(diffMs / 86400000);
- const diffMonths = Math.floor(diffDays / 30);
- if (diffMonths >= 1 && diffMonths < 12) return `${diffMonths}个月前`;
- if (diffDays >= 1 && diffMonths < 1) return `${diffDays}天前`;
+ const todayMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();
+ const dateMidnight = new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
+ const diffDays = Math.max(1, Math.floor((todayMidnight - dateMidnight) / 86400000));
+ if (diffDays < 30) return `${diffDays}天前`;
+ let diffMonths = (now.getFullYear() * 12 + now.getMonth()) - (date.getFullYear() * 12 + date.getMonth());
+ if (now.getDate() < date.getDate()) diffMonths -= 1;
+ if (diffMonths < 1) diffMonths = 1;
+ if (diffMonths < 12) return `${diffMonths}个月前`;
const yyyy = date.getFullYear();
const mm = String(date.getMonth() + 1).padStart(2, '0');
const dd = String(date.getDate()).padStart(2, '0');
@@ -275,13 +279,12 @@ const PostCard = ({
a: ({ node, ...props }) => {
const href = props.href;
if (href && typeof href === 'string' && href.startsWith('/tag/#')) {
- const hash = href.slice('/tag/'.length);
return (
{
e.preventDefault();
- navigate({ pathname: '/tag', hash });
+ navigate(href);
}}
/>
);