This commit is contained in:
2026-06-05 18:45:40 +08:00
7 changed files with 1035 additions and 90 deletions

View File

@@ -222,13 +222,9 @@ a.label:hover {
<!-- 状态 -->
<a class="item <?php if ($url=="status.php") echo "active";?>" href="<?php echo $path_fix?>status.php"><i
class="tasks icon"></i><?php echo $MSG_STATUS?></a>
<!-- AI 聊天 -->
<?php
if(isset($OJ_AI_HTML)&&$OJ_AI_HTML) echo $OJ_AI_HTML;
?>
<!-- 文档 -->
<a class="item <?php if ($url=="docs.php") echo "active";?>"
href="<?php echo $path_fix?>docs.php"><i class="book icon"></i> 文档</a>
<!-- AI聊天 -->
<a class="item <?php if ($url=="llm-chat.php") echo "active";?>"
href="<?php echo $path_fix?>llm-chat.php"><i class="comment icon"></i> AI聊天</a>
<!-- 排名 -->
<a class="desktop-only item <?php if ($url=="ranklist.php") echo "active";?> "
href="<?php echo $path_fix?>ranklist.php"><i class="signal icon"></i> <?php echo $MSG_RANKLIST?></a>
@@ -248,6 +244,9 @@ a.label:hover {
}
?>
<?php if( isset($_GET['cid']) && intval($_GET['cid'])>0 ){
$cid=intval($_GET['cid']);
?>
<a id="" class="item" href="<?php echo $path_fix?>contest.php" ><i class="arrow left icon"></i><?php echo $MSG_CONTEST.$MSG_LIST?></a>
<a id="" class="item active" href="<?php echo $path_fix?>contest.php?cid=<?php echo $cid?>" ><i class="list icon"></i><?php echo $MSG_PROBLEMS.$MSG_LIST?></a>
<a id="" class="item active" href="<?php echo $path_fix?>status.php?cid=<?php echo $cid?>" ><i class="tasks icon"></i><?php echo $MSG_STATUS.$MSG_LIST?></a>
@@ -261,14 +260,11 @@ a.label:hover {
<a id="" class="item active" href="<?php echo $path_fix?>conteststatistics.php?cid=<?php echo $cid?>" ><i class="eye icon"></i><?php echo $MSG_STATISTICS?></a>
<?php } ?>
<?php } ?>
<!-- cppreference菜单最后 -->
<a class="item <?php if ($url=="cppreference.php") echo "active";?>"
href="cppreference.php"><i class="help icon"></i><?php echo $MSG_CPPREFRENCE?></a>
<?php if( isset($_GET['cid']) && intval($_GET['cid'])>0 ){
$cid=intval($_GET['cid']);
?>
<?php echo $sql_news_menu_result_html; ?>
<div class="right menu">
<?php if(isset($_SESSION[$OJ_NAME.'_'.'user_id'])) { ?>

View File

@@ -215,40 +215,104 @@
$('#llm-review-error').hide();
$('#llm-review-result').hide();
$.ajax({
type: 'GET',
url: 'llm-review.php?sid=<?php echo intval($id); ?>',
dataType: 'json',
timeout: 60000,
success: function(data){
btn.removeClass('loading');
$('#llm-review-loading').hide();
if(data.error){
$('#llm-review-error-msg').text(data.error);
$('#llm-review-error').show();
btn.prop('disabled', false);
} else if(data.review){
$('#llm-review-result').show();
var container = document.getElementById('llm-review-content');
// 先以纯文本放入,再用 Vditor 渲染为 Markdown HTML
container.textContent = data.review;
if(typeof HustOJVditor !== 'undefined' && HustOJVditor.renderMarkdownBlocks){
HustOJVditor.renderMarkdownBlocks('#llm-review-content', {
useTextContent: true
});
}
btn.hide();
var fullText = "";
var container = document.getElementById('llm-review-content');
var resultDiv = document.getElementById('llm-review-result');
var reader = null;
var decoder = new TextDecoder();
// 解析 SSE 事件
var sseBuffer = "";
function processSSE(text) {
sseBuffer += text;
var lines = sseBuffer.split('\n');
sseBuffer = lines.pop(); // 保留未完成的行
var currentEvent = "";
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line.indexOf('event: ') === 0) {
currentEvent = line.substring(7);
} else if (line.indexOf('data: ') === 0) {
var dataStr = line.substring(6);
try {
var data = JSON.parse(dataStr);
if (currentEvent === 'chunk') {
fullText += data.text;
container.textContent = fullText;
resultDiv.style.display = 'block';
} else if (currentEvent === 'cached') {
fullText = data.text;
container.textContent = fullText;
resultDiv.style.display = 'block';
} else if (currentEvent === 'done') {
finishReview();
} else if (currentEvent === 'error') {
showError(data.message || '未知错误');
}
} catch(e) {}
currentEvent = "";
}
},
error: function(xhr, status){
btn.removeClass('loading').prop('disabled', false);
$('#llm-review-loading').hide();
var msg = '请求失败';
if(status === 'timeout') msg = '请求超时,请稍后重试';
$('#llm-review-error-msg').text(msg);
$('#llm-review-error').show();
}
});
}
function finishReview() {
btn.removeClass('loading').hide();
document.getElementById('llm-review-loading').style.display = 'none';
resultDiv.style.display = 'block';
// 渲染 Markdown
if (fullText && typeof HustOJVditor !== 'undefined' && HustOJVditor.renderMarkdownBlocks) {
HustOJVditor.renderMarkdownBlocks('#llm-review-content', { useTextContent: true });
}
}
function showError(msg) {
btn.removeClass('loading').prop('disabled', false);
document.getElementById('llm-review-loading').style.display = 'none';
document.getElementById('llm-review-error-msg').textContent = msg;
document.getElementById('llm-review-error').style.display = 'block';
}
if (typeof fetch === 'undefined') {
showError('浏览器不支持,请升级浏览器');
return;
}
fetch('llm-review.php?sid=<?php echo intval($id); ?>')
.then(function(response) {
if (!response.ok) {
return response.text().then(function(text) {
try {
var d = JSON.parse(text);
showError(d.error || '请求失败 (HTTP ' + response.status + ')');
} catch(e) {
showError('请求失败 (HTTP ' + response.status + ')');
}
});
}
reader = response.body.getReader();
function read() {
reader.read().then(function(result) {
if (result.done) {
if (fullText) finishReview();
return;
}
var text = decoder.decode(result.value, { stream: true });
processSSE(text);
read();
}).catch(function(err) {
if (fullText) {
finishReview();
} else {
showError('读取响应失败: ' + err.message);
}
});
}
read();
})
.catch(function(err) {
showError('网络请求失败: ' + err.message);
});
}
</script>
<?php } ?>