feat: 碎片详情页支持内联编辑
- 碎片类型详情页新增编辑按钮 - 编辑模式下显示 textarea 和保存/取消按钮 - 保存时调用更新接口并同步本地数据
This commit is contained in:
@@ -3,6 +3,8 @@ import { computed, onMounted, ref } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { getReportDetail, getFragmentDetail, getTaskReview, type ReviewFeedItem } from "@/api/review";
|
||||
import { getSessionDetail } from "@/api/studySessions";
|
||||
import { updateFragments } from "@/api/reportFragments";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
@@ -15,6 +17,11 @@ const content = ref("");
|
||||
const sourceTypeLabel = ref("");
|
||||
const taskNum = ref("");
|
||||
|
||||
// 编辑状态
|
||||
const isEditing = ref(false);
|
||||
const editContent = ref("");
|
||||
const saving = ref(false);
|
||||
|
||||
// 当前会话信息
|
||||
const sessionInfo = ref<{
|
||||
taskName: string;
|
||||
@@ -114,6 +121,42 @@ const goToDetail = (type: string, id: number) => {
|
||||
router.push(`/review/detail/${type}/${id}`);
|
||||
};
|
||||
|
||||
const enterEdit = () => {
|
||||
editContent.value = content.value;
|
||||
isEditing.value = true;
|
||||
};
|
||||
|
||||
const cancelEdit = () => {
|
||||
isEditing.value = false;
|
||||
editContent.value = "";
|
||||
};
|
||||
|
||||
const saveEdit = async () => {
|
||||
if (!editContent.value.trim()) {
|
||||
ElMessage.warning("内容不能为空");
|
||||
return;
|
||||
}
|
||||
if (editContent.value === content.value) {
|
||||
isEditing.value = false;
|
||||
return;
|
||||
}
|
||||
saving.value = true;
|
||||
try {
|
||||
const res = await updateFragments(contentId.value, editContent.value);
|
||||
if (res?.code === 200) {
|
||||
content.value = editContent.value;
|
||||
isEditing.value = false;
|
||||
ElMessage.success("保存成功");
|
||||
} else {
|
||||
ElMessage.error(res?.message || "保存失败");
|
||||
}
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e.message || "请求失败");
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadDetail();
|
||||
});
|
||||
@@ -137,14 +180,38 @@ onMounted(() => {
|
||||
<span v-if="sessionInfo?.startTime" class="meta-time">
|
||||
学习时间:{{ sessionInfo.startTime?.replace("T", " ")?.substring(0, 16) }}
|
||||
</span>
|
||||
<el-button
|
||||
v-if="contentType === 'fragment' && !isEditing"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="enterEdit"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div class="content-body" v-if="content">
|
||||
<p v-for="(line, idx) in content.split('\n')" :key="idx">
|
||||
{{ line || " " }}
|
||||
</p>
|
||||
<!-- 编辑模式 -->
|
||||
<div v-if="isEditing" class="edit-area">
|
||||
<el-input
|
||||
v-model="editContent"
|
||||
type="textarea"
|
||||
:rows="6"
|
||||
placeholder="请输入学习内容"
|
||||
/>
|
||||
<div class="edit-actions">
|
||||
<el-button @click="cancelEdit">取消</el-button>
|
||||
<el-button type="primary" :loading="saving" @click="saveEdit">保存</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="empty-content">暂无内容</div>
|
||||
<!-- 只读模式 -->
|
||||
<template v-else>
|
||||
<div class="content-body" v-if="content">
|
||||
<p v-for="(line, idx) in content.split('\n')" :key="idx">
|
||||
{{ line || " " }}
|
||||
</p>
|
||||
</div>
|
||||
<div v-else class="empty-content">暂无内容</div>
|
||||
</template>
|
||||
</article>
|
||||
|
||||
<!-- 该任务下的所有学习记录 -->
|
||||
@@ -342,4 +409,15 @@ onMounted(() => {
|
||||
color: #b8860b;
|
||||
}
|
||||
|
||||
.edit-area {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.edit-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user