Step F6:AE & 风险/问题管理(PV)

This commit is contained in:
Cheng Zhou
2025-12-16 22:17:26 +08:00
parent e047756b9c
commit abb5b0a107
42 changed files with 779 additions and 3 deletions
+101
View File
@@ -0,0 +1,101 @@
<template>
<el-card class="comment-card">
<template #header>
<div class="header">
<span>评论</span>
<el-button v-if="canComment" type="primary" size="small" @click="showInput = !showInput">新增</el-button>
</div>
</template>
<div v-if="showInput" class="input-area">
<el-input v-model="newComment" type="textarea" rows="3" placeholder="输入评论" />
<div class="actions">
<el-button size="small" @click="showInput = false">取消</el-button>
<el-button size="small" type="primary" :loading="loading" @click="submit">提交</el-button>
</div>
</div>
<el-timeline>
<el-timeline-item v-for="c in comments" :key="c.id" :timestamp="c.created_at">
<div class="comment-item">
<strong>{{ c.created_by }}</strong>
<p>{{ c.content }}</p>
</div>
</el-timeline-item>
</el-timeline>
</el-card>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { ElMessage } from "element-plus";
import { fetchComments, createComment } from "../api/comments";
import { useStudyStore } from "../store/study";
interface Props {
studyId: string;
entityType: string;
entityId: string;
canComment?: boolean;
}
const props = defineProps<Props>();
const comments = ref<any[]>([]);
const loading = ref(false);
const newComment = ref("");
const showInput = ref(false);
const study = useStudyStore();
const load = async () => {
if (!props.studyId) return;
loading.value = true;
try {
const { data } = await fetchComments(props.studyId, props.entityType, props.entityId);
comments.value = data.items || data || [];
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || "评论加载失败");
} finally {
loading.value = false;
}
};
const submit = async () => {
if (!newComment.value.trim()) {
ElMessage.warning("请输入评论");
return;
}
if (!study.currentStudy) return;
loading.value = true;
try {
await createComment(study.currentStudy.id, props.entityType, props.entityId, { content: newComment.value });
ElMessage.success("提交成功");
newComment.value = "";
showInput.value = false;
load();
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || "提交失败");
} finally {
loading.value = false;
}
};
onMounted(() => load());
</script>
<style scoped>
.header {
display: flex;
justify-content: space-between;
align-items: center;
}
.input-area {
margin-bottom: 12px;
}
.actions {
margin-top: 8px;
display: flex;
justify-content: flex-end;
gap: 8px;
}
.comment-item p {
margin: 4px 0 0;
}
</style>