feat: 初始提交

This commit is contained in:
anonymous
2025-10-21 09:38:26 +08:00
committed by t59688
parent 2965b8e28f
commit c9fc816fab
175 changed files with 23968 additions and 87 deletions

View File

@@ -0,0 +1,120 @@
<template>
<div v-if="show" class="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm">
<div class="bg-white rounded-2xl shadow-2xl max-w-4xl w-full max-h-[80vh] overflow-hidden flex flex-col">
<!-- 弹窗头部 -->
<div class="flex items-center justify-between p-6 border-b border-gray-200">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-purple-500 rounded-full flex items-center justify-center flex-shrink-0">
<svg class="w-6 h-6 text-white" fill="currentColor" viewBox="0 0 20 20">
<path d="M10 2a6 6 0 00-6 6v3.586l-1.707 1.707A1 1 0 003 15v1a1 1 0 001 1h12a1 1 0 001-1v-1a1 1 0 00-.293-.707L16 11.586V8a6 6 0 00-6-6zM8.05 17a2 2 0 103.9 0H8.05z"></path>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-900">AI 评审详情</h3>
</div>
<button
@click="$emit('close')"
class="p-2 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg transition-colors"
>
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
</svg>
</button>
</div>
<!-- 弹窗内容 -->
<div class="p-6 overflow-y-auto max-h-[calc(80vh-130px)]">
<div v-if="parsedEvaluation" class="space-y-6 text-sm">
<div class="bg-purple-50 border border-purple-200 rounded-xl p-4">
<p class="font-semibold text-purple-800 text-base">🏆 最佳选择版本 {{ parsedEvaluation.best_choice }}</p>
<p class="text-purple-700 mt-2">{{ parsedEvaluation.reason_for_choice }}</p>
</div>
<div class="space-y-4">
<div v-for="(evalResult, versionName) in parsedEvaluation.evaluation" :key="versionName" class="bg-gray-50 p-4 rounded-lg border border-gray-200">
<h5 class="font-bold text-gray-800 text-lg mb-2">版本 {{ String(versionName).replace('version', '') }} 评估</h5>
<div class="prose prose-sm max-w-none text-gray-700 space-y-3">
<div>
<p class="font-semibold text-gray-800">综合评价:</p>
<p>{{ evalResult.overall_review }}</p>
</div>
<div>
<p class="font-semibold text-gray-800">优点:</p>
<ul class="list-disc pl-5 space-y-1">
<li v-for="(pro, i) in evalResult.pros" :key="`pro-${i}`">{{ pro }}</li>
</ul>
</div>
<div>
<p class="font-semibold text-gray-800">缺点:</p>
<ul class="list-disc pl-5 space-y-1">
<li v-for="(con, i) in evalResult.cons" :key="`con-${i}`">{{ con }}</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div
v-else
class="prose prose-sm max-w-none prose-headings:mt-2 prose-headings:mb-1 prose-p:my-1 prose-ul:my-1 prose-ol:my-1 prose-li:my-0 text-gray-800"
v-html="parseMarkdown(evaluation)"
></div>
</div>
<!-- 弹窗底部操作按钮 -->
<div class="flex items-center justify-end p-6 border-t border-gray-200 bg-gray-50">
<button
@click="$emit('close')"
class="px-6 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors"
>
关闭
</button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
interface Props {
show: boolean
evaluation: string | null
}
const props = defineProps<Props>()
defineEmits(['close'])
const parsedEvaluation = computed(() => {
if (!props.evaluation) return null
try {
// First, try to parse the whole string as JSON
let data = JSON.parse(props.evaluation);
// If successful and it's a string, parse it again (for double-encoded JSON)
if (typeof data === 'string') {
data = JSON.parse(data);
}
return data;
} catch (error) {
console.error('Failed to parse evaluation JSON:', error)
return null
}
})
const parseMarkdown = (text: string | null): string => {
if (!text) return ''
let parsed = text
.replace(/\\n/g, '\n')
.replace(/\\"/g, '"')
.replace(/\\'/g, "'")
.replace(/\\\\/g, '\\')
parsed = parsed.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
parsed = parsed.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, '<em>$1</em>')
parsed = parsed.replace(/^([A-Z])\)\s*\*\*(.*?)\*\*(.*)/gm, '<div class="mb-2"><span class="inline-flex items-center justify-center w-6 h-6 bg-indigo-100 text-indigo-600 text-sm font-bold rounded-full mr-2">$1</span><strong>$2</strong>$3</div>')
parsed = parsed.replace(/\n/g, '<br>')
parsed = parsed.replace(/(<br\s*\/?>\s*){2,}/g, '</p><p class="mt-2">')
if (!parsed.includes('<p>')) {
parsed = `<p>${parsed}</p>`
}
return parsed
}
</script>