This commit is contained in:
@@ -58,9 +58,10 @@ class AliyunTingwuService:
|
||||
self.client = None
|
||||
logger.warning("Aliyun AccessKey configuration missing.")
|
||||
|
||||
def upload_to_oss(self, file_obj, file_name):
|
||||
def upload_to_oss(self, file_obj, file_name, day=7):
|
||||
"""
|
||||
上传文件到 OSS 并返回带签名的 URL (有效期 3 小时)
|
||||
上传文件到 OSS 并返回带签名的 URL
|
||||
默认生成有效期为 7 天 (3600 * 24 * day) 的签名URL,方便评委在一段时间内都能播放。
|
||||
"""
|
||||
if not self.bucket:
|
||||
raise Exception("OSS Client not initialized")
|
||||
@@ -70,8 +71,8 @@ class AliyunTingwuService:
|
||||
# file_obj 应该是打开的文件对象或字节流
|
||||
self.bucket.put_object(file_name, file_obj)
|
||||
|
||||
# 生成签名 URL,有效期 3 小时 (3600 * 3)
|
||||
url = self.bucket.sign_url('GET', file_name, 3600 * 3)
|
||||
# 生成签名 URL,有效期 7 天 (3600 * 24 * 7 = 604800 秒)
|
||||
url = self.bucket.sign_url('GET', file_name, 3600 * 24 * day)
|
||||
return url
|
||||
except Exception as e:
|
||||
logger.error(f"OSS Upload failed: {e}")
|
||||
|
||||
@@ -2,6 +2,23 @@
|
||||
|
||||
{% block title %}项目列表 - 评委系统{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
.markdown-body p { margin-bottom: 0.5em; }
|
||||
.markdown-body ul { list-style-type: disc; padding-left: 1.5em; margin-bottom: 0.5em; }
|
||||
.markdown-body ol { list-style-type: decimal; padding-left: 1.5em; margin-bottom: 0.5em; }
|
||||
.markdown-body strong { font-weight: 600; }
|
||||
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4 { font-weight: 600; margin-top: 1em; margin-bottom: 0.5em; }
|
||||
.markdown-body { overflow: hidden; }
|
||||
.line-clamp-5 {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 5;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="flex flex-col sm:flex-row justify-between items-center mb-8 gap-4">
|
||||
<div>
|
||||
@@ -104,7 +121,12 @@
|
||||
<div class="p-4 bg-white space-y-4">
|
||||
<div>
|
||||
<p class="text-xs font-semibold text-gray-500 uppercase mb-1">AI 总结</p>
|
||||
<p class="text-sm text-gray-800" id="modalAiSummary"></p>
|
||||
<div class="relative">
|
||||
<div class="text-sm text-gray-800 markdown-body line-clamp-5 transition-all duration-300" id="modalAiSummary"></div>
|
||||
<button id="toggleAiSummaryBtn" type="button" onclick="toggleAiSummary()" class="text-xs text-blue-600 hover:text-blue-800 focus:outline-none flex items-center mt-2 hidden">
|
||||
<i class="fas fa-chevron-down mr-1" id="toggleAiSummaryIcon"></i> <span id="toggleAiSummaryText">点击完整显示</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-100 pt-3 relative">
|
||||
<div class="flex justify-between items-center mb-1">
|
||||
@@ -248,7 +270,28 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<script>
|
||||
/**
|
||||
* 切换 AI 总结内容的显示状态(折叠/展开)
|
||||
* 通过添加或移除 line-clamp-5 类来实现截断或完整显示,并更新按钮的文字和图标。
|
||||
*/
|
||||
function toggleAiSummary() {
|
||||
const summaryDiv = document.getElementById('modalAiSummary');
|
||||
const toggleText = document.getElementById('toggleAiSummaryText');
|
||||
const toggleIcon = document.getElementById('toggleAiSummaryIcon');
|
||||
|
||||
if (summaryDiv.classList.contains('line-clamp-5')) {
|
||||
summaryDiv.classList.remove('line-clamp-5');
|
||||
toggleText.innerText = '收起内容';
|
||||
toggleIcon.className = 'fas fa-chevron-up mr-1';
|
||||
} else {
|
||||
summaryDiv.classList.add('line-clamp-5');
|
||||
toggleText.innerText = '点击完整显示';
|
||||
toggleIcon.className = 'fas fa-chevron-down mr-1';
|
||||
}
|
||||
}
|
||||
|
||||
function updateFileName(input) {
|
||||
const display = document.getElementById('fileNameDisplay');
|
||||
if (input.files.length > 0) {
|
||||
@@ -359,7 +402,29 @@ async function viewProject(id) {
|
||||
const aiSection = document.getElementById('aiResultSection');
|
||||
if (data.ai_result) {
|
||||
aiSection.style.display = 'block';
|
||||
document.getElementById('modalAiSummary').innerText = (data.ai_result.summary || '暂无总结').substring(0, 300) + (data.ai_result.summary && data.ai_result.summary.length > 300 ? '...' : '');
|
||||
|
||||
const summaryDiv = document.getElementById('modalAiSummary');
|
||||
const toggleBtn = document.getElementById('toggleAiSummaryBtn');
|
||||
const toggleText = document.getElementById('toggleAiSummaryText');
|
||||
const toggleIcon = document.getElementById('toggleAiSummaryIcon');
|
||||
|
||||
const summaryText = data.ai_result.summary || '暂无总结';
|
||||
summaryDiv.innerHTML = marked.parse(summaryText);
|
||||
|
||||
// Reset to collapsed state
|
||||
summaryDiv.classList.add('line-clamp-5');
|
||||
toggleText.innerText = '点击完整显示';
|
||||
toggleIcon.className = 'fas fa-chevron-down mr-1';
|
||||
|
||||
// Show/hide toggle button based on content height
|
||||
setTimeout(() => {
|
||||
if (summaryDiv.scrollHeight > summaryDiv.clientHeight) {
|
||||
toggleBtn.classList.remove('hidden');
|
||||
} else {
|
||||
toggleBtn.classList.add('hidden');
|
||||
}
|
||||
}, 50);
|
||||
|
||||
document.getElementById('modalAiTrans').innerText = (data.ai_result.transcription || '暂无内容').substring(0, 150) + '...';
|
||||
|
||||
// Store full data for full transcription modal
|
||||
|
||||
Reference in New Issue
Block a user