ryp vor 3 Wochen
Ursprung
Commit
bb40d5cd8d
3 geänderte Dateien mit 225 neuen und 221 gelöschten Zeilen
  1. 198 182
      app/controllers/index.php
  2. 27 17
      app/libs/uoj-html-lib.php
  3. 0 22
      app/views/page-footer.php

+ 198 - 182
app/controllers/index.php

@@ -3,19 +3,9 @@ $blogs = DB::selectAll("select blogs.id, title, poster, post_time from important
 $activateusers = DB::selectAll("select submitter, count(*) as cnt from submissions where datediff(now(), submit_time) <= 30 group by submitter order by cnt desc limit 12;");
 $topusers = DB::selectAll("select u.username, u.rating, u.rating_rd, u.rating_vol, u.motto, u.qq, count(*) cnt from user_info u inner join contests_registrants c on u.username = c.username inner join contests s on s.id = c.contest_id where datediff(now(), s.start_time) <= 180 group by c.username having cnt >= 3 order by rating desc, username asc limit 12;");
 $hotusers = DB::selectAll("select username, rating, rating_rd, rating_vol, qq, motto from user_info order by rating_vol desc, username asc limit 12;");
-$topblogs = DB::selectAll("select id from blogs order by zan desc limit 10;");
+$topblogs = DB::selectAll("select id from blogs order by zan desc limit 20;");
 $songs_data = htmlspecialchars(json_encode(DB::selectAll("select * from songs;")), ENT_QUOTES, 'UTF-8');
 
-// 服务器数据看板
-$today_submit_num = DB::selectCount("select count(*) from submissions where date(submit_time) = date(now())");
-$today_ac_num = DB::selectCount("select count(*) from submissions where date(submit_time) = date(now()) and score = 100");
-$month_submit_num = DB::selectCount("select count(*) from submissions where year(submit_time) = year(now()) and month(submit_time) = month(now())");
-$month_ac_num = DB::selectCount("select count(*) from submissions where year(submit_time) = year(now()) and month(submit_time) = month(now()) and score = 100");
-$total_submit_num = DB::selectCount("select count(*) from submissions");
-$total_ac_num = DB::selectCount("select count(*) from submissions where score = 100");
-$total_problem_num = DB::selectCount("select count(*) from problems where is_hidden = 0");
-$total_user_num = DB::selectCount("select count(*) from user_info");
-
 // 最近比赛:未结束的按开始时间升序取,不足 5 场时补最近结束的
 $recent_contests = array();
 $result = DB::selectAll("select * from contests where status != 'finished' order by start_time asc, id asc limit 5");
@@ -35,21 +25,11 @@ if (count($recent_contests) < 5) {
 <?php echoUOJPageHeader(UOJConfig::$data['profile']['oj-name-short']) ?>
 <div id="songs-data" data-songs='<?php echo $songs_data; ?>'></div>
 
-<div class="row shadow my-4 wyoj-topcard">
+<div class="row my-4 wyoj-topcard">
 	<div class="card-body">
 		<div class="row">
-<!--			<div class="col-xs-6 col-sm-4 col-md-3">
-				<img class="media-object img-thumbnail" src="/images/logo.png" alt="Logo" />
-			</div>-->
 			<div class="col-sm-12 col-md-9">
 				<table class="table table-sm">
-<!--					<thead>
-						<tr>
-							<th style="width:60%"><?= UOJLocale::get('announcements') ?></th>
-							<th style="width:20%"></th>
-							<th style="width:20%"></th>
-						</tr>
-					</thead>-->
 				  	<tbody>
 					<?php $now_cnt = 0; ?>
 					<?php foreach ($blogs as $blog): ?>
@@ -86,9 +66,6 @@ if (count($recent_contests) < 5) {
 				</table>
 			</div>
 			<div class="col-xs-6 col-sm-4 col-md-3">
-
-
-    
 	<div class="card" style="max-width:300px; width:100%; border-radius:0; ">
         <div class="image-frame" style="aspect-ratio:1/1; position:relative;">
             <img id="photo" src="" alt="" style="width:100%; height:100%; object-fit:cover; display:block; cursor:pointer; -webkit-tap-highlight-color:transparent;">
@@ -204,168 +181,207 @@ if (count($recent_contests) < 5) {
         })();
     </script>
 </div>
-
-
-
 		</div>
 	</div>
 </div>
+<?php
+// ---- 日期 ----
+$todayTs   = time();
+$dayNum    = (int)date('j', $todayTs);
+$monthNum  = (int)date('n', $todayTs);
+$wday      = (int)date('w', $todayTs);
+$monthCN   = ['一','二','三','四','五','六','七','八','九','十','十一','十二'];
+$weekCN    = ['日','一','二','三','四','五','六'];
+$monthText = $monthCN[$monthNum - 1] . '月';
+$weekText  = '星期' . $weekCN[$wday];
 
-<div class="row shadow my-4 wyoj-topcard">
-	<div class="col-lg-6 p-4">
-		<h3>服务器数据</h3>
-		<div class="row">
-			<div class="col-6 col-lg-3 mb-3">
-				<div class="card h-100 p-3 text-center stat-card">
-					<div class="stat-icon"><span class="glyphicon glyphicon-flash"></span></div>
-					<div class="stat-num"><?= $today_submit_num ?></div>
-					<div class="stat-label">今日提交</div>
-				</div>
-			</div>
-			<div class="col-6 col-lg-3 mb-3">
-				<div class="card h-100 p-3 text-center stat-card">
-					<div class="stat-icon"><span class="glyphicon glyphicon-ok"></span></div>
-					<div class="stat-num"><?= $today_ac_num ?></div>
-					<div class="stat-label">今日通过</div>
-				</div>
-			</div>
-			<div class="col-6 col-lg-3 mb-3">
-				<div class="card h-100 p-3 text-center stat-card">
-					<div class="stat-icon"><span class="glyphicon glyphicon-send"></span></div>
-					<div class="stat-num"><?= $month_submit_num ?></div>
-					<div class="stat-label">本月提交</div>
-				</div>
-			</div>
-			<div class="col-6 col-lg-3 mb-3">
-				<div class="card h-100 p-3 text-center stat-card">
-					<div class="stat-icon"><span class="glyphicon glyphicon-check"></span></div>
-					<div class="stat-num"><?= $month_ac_num ?></div>
-					<div class="stat-label">本月通过</div>
-				</div>
-			</div>
-			<div class="col-6 col-lg-3 mb-3">
-				<div class="card h-100 p-3 text-center stat-card">
-					<div class="stat-icon"><span class="glyphicon glyphicon-tasks"></span></div>
-					<div class="stat-num"><?= $total_submit_num ?></div>
-					<div class="stat-label">总提交</div>
-				</div>
-			</div>
-			<div class="col-6 col-lg-3 mb-3">
-				<div class="card h-100 p-3 text-center stat-card">
-					<div class="stat-icon"><span class="glyphicon glyphicon-star"></span></div>
-					<div class="stat-num"><?= $total_ac_num ?></div>
-					<div class="stat-label">总通过</div>
-				</div>
-			</div>
-			<div class="col-6 col-lg-3 mb-3">
-				<div class="card h-100 p-3 text-center stat-card">
-					<div class="stat-icon"><span class="glyphicon glyphicon-list-alt"></span></div>
-					<div class="stat-num"><?= $total_problem_num ?></div>
-					<div class="stat-label">题目总数</div>
-				</div>
-			</div>
-			<div class="col-6 col-lg-3 mb-3">
-				<div class="card h-100 p-3 text-center stat-card">
-					<div class="stat-icon"><span class="glyphicon glyphicon-user"></span></div>
-					<div class="stat-num"><?= $total_user_num ?></div>
-					<div class="stat-label">注册用户</div>
-				</div>
-			</div>
-		</div>
-	</div>
-	<div class="col-lg-6 p-4">
-		<h3>最近比赛</h3>
-		<?php if (empty($recent_contests)): ?>
-		<p class="text-muted">暂无比赛</p>
-		<?php else: ?>
-		<table class="table contest-table">
-			<tbody>
-			<?php foreach ($recent_contests as $contest): ?>
-				<tr>
-					<td class="contest-name">
-						<a href="<?= HTML::url('/contest/' . $contest['id']) ?>"><?= $contest['name'] ?></a>
-						<?php if ($contest['cur_progress'] == CONTEST_NOT_STARTED): ?>
-						<span class="badge badge-info">即将开始</span>
-						<span class="contest-countdown" id="recent-contest-countdown-<?= $contest['id'] ?>"></span>
-						<?php elseif ($contest['cur_progress'] == CONTEST_IN_PROGRESS): ?>
-						<span class="badge badge-success">进行中</span>
-						<?php elseif ($contest['cur_progress'] == CONTEST_PENDING_FINAL_TEST): ?>
-						<span class="badge badge-warning">等待出分</span>
-						<?php elseif ($contest['cur_progress'] == CONTEST_TESTING): ?>
-						<span class="badge badge-warning">最终评测中</span>
-						<?php else: ?>
-						<span class="badge badge-secondary">已结束</span>
-						<?php endif ?>
-					</td>
-					<td class="contest-info"><?= $contest['start_time_str'] ?></td>
-					<td class="contest-info"><?= round($contest['last_min'] / 60, 2) ?>h</td>
-				</tr>
-			<?php endforeach ?>
-			</tbody>
-		</table>
-		<?php endif ?>
-	</div>
-</div>
-<script type="text/javascript">
-<?php foreach ($recent_contests as $contest): ?>
-<?php if ($contest['cur_progress'] == CONTEST_NOT_STARTED): ?>
-$('#recent-contest-countdown-<?= $contest['id'] ?>').countdown(<?= $contest['start_time']->getTimestamp() - UOJTime::$time_now->getTimestamp() ?>);
-<?php endif ?>
-<?php endforeach ?>
-</script>
-<div class="row shadow my-4 wyoj-topcard">
-	<div class="col-12 p-4">
-		<h3>活跃排行榜</h3>
-	</div>
-	<?php foreach($activateusers as $username): ?>
-		<?php $user = queryUser($username['submitter']); ?>
-		<div class="col-md-3 mb-4">
-			<div class="card h-100 p-3 text-center">
-				<img class="uoj-avatar mx-auto mb-2" src=<?= "https://q.qlogo.cn/g?b=qq&nk=" . $user['qq'] . "&s=100" ?> alt="...">
-				<span class="mb-2"><?= getUserLink($user['username']) ?></span>
-				<span class="text-center text-bottom"><?= $user['motto'] ?></span>
-			</div>
-		</div>
-	<?php endforeach ?>
-</div>
-<div class="row shadow my-4 wyoj-topcard">
-	<div class="col-12 p-4">
-		<h3>比赛排行榜(180天内三场及以上比赛)</h3>
-		<a href="/ranklist">全部排名</a>
-	</div>
-	<?php foreach($topusers as $user): ?>
-		<div class="col-md-3 mb-4">
-			<div class="card h-100 p-3 text-center">
-				<img class="uoj-avatar mx-auto mb-2" src=<?= "https://q.qlogo.cn/g?b=qq&nk=" . $user['qq'] . "&s=100" ?> alt="...">
-				<span class="mb-2"><?= getUserLink($user['username']) ?></span>
-				<strong style="color: red" class="mb-2"><?= $user['rating'] ?> (±<?= round($user['rating_rd']) * 2 ?>)</strong>
-				<span class="text-center text-bottom"><?= $user['motto'] ?></span>
-			</div>
-		</div>
-	<?php endforeach ?>
-</div>
-<div class="row shadow my-4 wyoj-topcard">
-	<div class="col-12 p-4">
-		<h3>黑马 / 爆冷榜</h3>
-	</div>
-	<?php foreach($hotusers as $user): ?>
-		<div class="col-md-3 mb-4">
-			<div class="card h-100 p-3 text-center">
-				<img class="uoj-avatar mx-auto mb-2" src=<?= "https://q.qlogo.cn/g?b=qq&nk=" . $user['qq'] . "&s=100" ?> alt="...">
-				<span class="mb-2"><?= getUserLink($user['username']) ?></span>
-				<strong style="color: red" class="mb-2">Vol <?= round(1000 * $user['rating_vol']) / 1000 ?>, <?= $user['rating'] ?> (±<?= round($user['rating_rd']) * 2 ?>)</strong>
-				<span class="text-center text-bottom"><?= $user['motto'] ?></span>
-			</div>
+// ---- NOIP 倒计时 ----
+$noipTs        = strtotime('2026-11-28');
+$todayMidnight = strtotime(date('Y-m-d', $todayTs));
+$daysLeft      = (int)floor(($noipTs - $todayMidnight) / 86400);
+?>
+
+<?php
+$todayTs   = time();
+$dayNum    = (int)date('j', $todayTs);
+$monthNum  = (int)date('n', $todayTs);
+$wday      = (int)date('w', $todayTs);
+$monthCN   = ['一','二','三','四','五','六','七','八','九','十','十一','十二'];
+$weekCN    = ['日','一','二','三','四','五','六'];
+
+$bigMonths = [1,3,5,7,8,10,12];
+if ($monthNum == 2) {
+	$sizeChar = '平';           // 闰年可改成 '闰'
+} elseif (in_array($monthNum, $bigMonths)) {
+	$sizeChar = '大';
+} else {
+	$sizeChar = '小';
+}
+$monthText = $monthCN[$monthNum - 1] . '月' . $sizeChar;
+$weekText  = '星期' . $weekCN[$wday];
+
+$todayMidnight = strtotime(date('Y-m-d', $todayTs));
+$noipTs        = strtotime('2026-11-28');
+$daysLeft      = max(0, (int)floor(($noipTs - $todayMidnight) / 86400));
+$csj1Ts        = strtotime('2026-09-19');
+$csp1daysLeft  = max(0, (int)floor(($csp1Ts - $todayMidnight) / 86400));
+$csp2Ts        = strtotime('2026-10-31');
+$csp2daysLeft  = max(0, (int)floor(($csp2Ts - $todayMidnight) / 86400));
+?>
+
+<div class="row my-4">
+    <!-- ============ 左列:日程 + 博客 ============ -->
+    <div class="col-12 col-lg-9">
+
+        <!-- 黑色日期卡片 -->
+        <div class="mb-4"
+             style="background:#000;color:#fff;padding:2rem 1.5rem;border-radius:0;">
+            <div class="d-flex justify-content-center align-items-center">
+                <div style="writing-mode:vertical-rl;font-size:1.5rem;font-weight:bold;letter-spacing:0.3em;line-height:1;">
+                    <?= $monthText ?>
+                </div>
+                <div class="mx-4" style="font-size:5rem;font-weight:600;line-height:1;">
+                    <?= $dayNum ?>
+                </div>
+                <div style="writing-mode:vertical-rl;font-size:1.5rem;font-weight:bold;letter-spacing:0.3em;line-height:1;">
+                    <?= $weekText ?>
+                </div>
+            </div>
+            <div class="text-center mt-4" style="font-size:1rem;letter-spacing:0.05em;">
+                <?php if ($daysLeft > 0): ?>
+                    距 <strong>NOIP2026</strong> 还有 <strong><?= $daysLeft ?></strong> 天
+                <?php elseif ($daysLeft === 0): ?>
+                    <strong>NOIP2026</strong> 就是今天
+                <?php else: ?>
+                    <strong>NOIP2026</strong> 已结束
+		<?php endif; ?>
+		<br/>
+                <?php if ($csp1daysLeft > 0): ?>
+                    距 <strong>CSP-J/S 2026 第一轮</strong> 还有 <strong><?= $csp1daysLeft ?></strong> 天
+                <?php elseif ($csp1daysLeft === 0): ?>
+                    <strong>CSP-J/S 2026 第一轮</strong> 就是今天
+                <?php else: ?>
+                    <strong>CSP-J/S 2026 第一轮</strong> 已结束
+                <?php endif; ?>
+		<br/>
+                <?php if ($csp2daysLeft > 0): ?>
+                    距 <strong>CSP-J/S 2026 第二轮</strong> 还有 <strong><?= $csp2daysLeft ?></strong> 天
+                <?php elseif ($csp2daysLeft === 0): ?>
+                    <strong>CSP-J/S 2026 第二轮</strong> 就是今天!
+                <?php else: ?>
+                    <strong>CSP-J/S 2026 第二轮</strong> 已结束
+                <?php endif; ?>
 		</div>
-	<?php endforeach ?>
-</div>
-<div class="row shadow my-4 wyoj-topcard">
-	<div class="col-12 p-4">
-		<h3>博客广场</h3>
-	</div>
+        </div>
+
+        <!-- 博客列表 -->
+        <div class="row">
+            <?php foreach ($topblogs as $blog): ?>
+                <?= echoBlogCard(queryBlog($blog['id'])) ?>
+            <?php endforeach ?>
+        </div>
 
-	<?php 
-		foreach ($topblogs as $id) echo echoBlogCard(queryBlog($id['id']));
-	?>
+    </div>
+
+    <!-- ============ 右列:排行榜 ============ -->
+    <div class="col-12 col-lg-3">
+
+        <!-- 活跃 -->
+        <div class="card shadow-sm border-0 mb-3">
+            <div class="card-body p-3">
+                <h6 class="font-weight-bold mb-3">活跃排行榜</h6>
+                <?php foreach ($activateusers as $username): ?>
+                    <?php $user = queryUser($username['submitter']); ?>
+                    <div class="d-flex align-items-start border-bottom pb-2 mb-2">
+                        <img class="uoj-avatar rounded-circle flex-shrink-0 mr-2"
+                             style="width:36px;height:36px;object-fit:cover;"
+                             src="https://q.qlogo.cn/g?b=qq&nk=<?= $user['qq'] ?>&s=100" alt="...">
+                        <div class="flex-grow-1" style="min-width:0;">
+                            <div class="text-truncate font-weight-bold" style="font-size:0.9rem;">
+                                <?= getUserLink($user['username']) ?>
+                            </div>
+                            <div class="text-truncate" style="font-size:0.8rem;">
+                                <?= $user['motto'] ?>
+                            </div>
+                        </div>
+                    </div>
+                <?php endforeach ?>
+            </div>
+        </div>
+
+        <!-- 比赛 -->
+        <div class="card shadow-sm border-0 mb-3">
+            <div class="card-body p-3">
+                <h6 class="font-weight-bold mb-1">比赛排行榜</h6>
+                <div class="mb-3" style="font-size:0.75rem;">
+                    <span class="text-muted">180 天内三场及以上</span>
+                    <a href="/ranklist" class="ml-1">全部排名</a>
+                </div>
+                <?php foreach ($topusers as $user): ?>
+                    <div class="d-flex align-items-start border-bottom pb-2 mb-2">
+                        <img class="uoj-avatar rounded-circle flex-shrink-0 mr-2"
+                             style="width:36px;height:36px;object-fit:cover;"
+                             src="https://q.qlogo.cn/g?b=qq&nk=<?= $user['qq'] ?>&s=100" alt="...">
+                        <div class="flex-grow-1" style="min-width:0;">
+                            <div class="d-flex justify-content-between align-items-baseline">
+                                <span class="text-truncate font-weight-bold" style="font-size:0.9rem;">
+                                    <?= getUserLink($user['username']) ?>
+                                </span>
+                                <strong class="text-danger ml-1 flex-shrink-0" style="font-size:0.75rem;">
+                                    <?= $user['rating'] ?> <small>(±<?= round($user['rating_rd']) * 2 ?>)</small>
+                                </strong>
+                            </div>
+                            <div class="text-truncate" style="font-size:0.8rem;">
+                                <?= $user['motto'] ?>
+                            </div>
+                        </div>
+                    </div>
+                <?php endforeach ?>
+            </div>
+        </div>
+
+        <!-- 黑马 -->
+        <div class="card shadow-sm border-0 mb-3">
+            <div class="card-body p-3">
+                <h6 class="font-weight-bold mb-3">黑马 / 爆冷榜</h6>
+                <?php foreach ($hotusers as $user): ?>
+                    <div class="d-flex align-items-start border-bottom pb-2 mb-2">
+                        <img class="uoj-avatar rounded-circle flex-shrink-0 mr-2"
+                             style="width:36px;height:36px;object-fit:cover;"
+                             src="https://q.qlogo.cn/g?b=qq&nk=<?= $user['qq'] ?>&s=100" alt="...">
+                        <div class="flex-grow-1" style="min-width:0;">
+                            <div class="d-flex justify-content-between align-items-baseline">
+                                <span class="text-truncate font-weight-bold" style="font-size:0.9rem;">
+                                    <?= getUserLink($user['username']) ?>
+                                </span>
+                                <strong class="text-danger ml-1 flex-shrink-0" style="font-size:0.75rem;">
+                                    Vol <?= round(1000 * $user['rating_vol']) / 1000 ?>
+                                </strong>
+                            </div>
+                            <div class="text-truncate" style="font-size:0.8rem;">
+                                <?= $user['motto'] ?>
+                            </div>
+                        </div>
+                    </div>
+                <?php endforeach ?>
+            </div>
+        </div>
+
+    </div>
 </div>
+
+<!-- 博客卡片悬停效果 -->
+<style>
+.wyoj-blog-card {
+    transition: box-shadow .2s ease;
+}
+.wyoj-blog-card:hover {
+    box-shadow: 0 4px 14px rgba(0,0,0,.10) !important;
+}
+.wyoj-blog-card .wyoj-blog-title {
+    font-size: 1.05rem;
+    line-height: 1.5;
+}
+</style>
+
 <?php echoUOJPageFooter() ?>

+ 27 - 17
app/libs/uoj-html-lib.php

@@ -1217,32 +1217,42 @@ function echoBlogCard($blog) {
 	$bloghref = "/blogs/" . $blog['id'];
 	$blogtitle = $blog['title'];
 	$poster = queryUser($blog['poster']);
-	$blogpreview = getBlogPreview($blog['content']);
 	$userlink = getUserLink($blog['poster']);
 	$posttime = $blog['post_time'];
 	$usermotto = $poster['motto'];
 	$zanblock = getClickZanBlock('B', $blog['id'], $blog['zan']);
+	$avatar = "https://q.qlogo.cn/g?b=qq&nk=" . $poster['qq'] . "&s=100";
+
+	error_log($blog);
+	error_log($poster);
+	error_log($poster['qq']);
+	error_log("FACK");
 
 	return <<<EOF
-	<div class="col-12 mb-4">
-		<div class="card d-flex p-3 shadow mx-4">
-			<div class="align-items-start">
-				<a href="$bloghref"><h5>$blogtitle</h5></a>
-				<p>$blogpreview</p>
-			</div>
-			<div class="d-flex align-items-end justify-content-between">
-				<div>
-					<span class="mb-2">$userlink</span>
-					<span class="text-muted">$posttime</span>
-					<span class="ml-4">$usermotto</span>
-				</div>
-				$zanblock
-			</div>
-		</div>
-	</div>
+        <div class="col-12 mb-3">
+                <div class="card wyoj-blog-card border-0 shadow-sm">
+                        <div class="card-body p-3">
+                                <a href="$bloghref" class="text-decoration-none text-dark">
+                                        <h5 class="mb-3 wyoj-blog-title">$blogtitle</h5>
+                                </a>
+                                <div class="d-flex align-items-center justify-content-between">
+                                        <div class="d-flex align-items-center" style="min-width:0;">
+                                                <img class="uoj-avatar rounded-circle flex-shrink-0 mr-2"
+                                                     style="width:28px;height:28px;object-fit:cover;"
+                                                     src="$avatar" alt="...">
+                                                <span class="text-truncate">$userlink</span>
+                                                <span class="text-muted ml-2 text-nowrap" style="font-size:0.85rem;">$posttime</span>
+                                                <span class="ml-3 text-truncate" style="font-size:1rem;">$usermotto</span>
+                                        </div>
+                                        <div class="flex-shrink-0 ml-2">$zanblock</div>
+                                </div>
+                        </div>
+                </div>
+        </div>
 EOF;
 }
 
+
 function echoRecommendProblem($pid, $link, $name, $descr) {
 	return <<<EOF
 	<div class="col-md-3 mb-4">

+ 0 - 22
app/views/page-footer.php

@@ -25,27 +25,5 @@
 			<?php endif ?>
 		</div>
 		</div>
-
-<!--
-<script 
-  data-host-id="1" 
-  data-auto-reg="true" 
-  data-login-token="" 
-  data-title="" 
-  data-logo="" 
-  data-theme-color="#1fe1f9" 
-  data-close-width="48" 
-  data-close-height="48" 
-  data-open-width="380" 
-  data-open-height="680" 
-  data-welcome="请在这里留言" 
-  data-popup-title="需要联系管理员?" 
-  data-popup-subtitle="快来这里联系我们" 
-  data-popup-image="" 
-  data-popup-closable="true" 
-  src="https://x.ryp.org.cn/widget.js" 
-  async 
-></script>-->
-		<!-- /container -->
 	</body>
 </html>