184 lines
4.1 KiB
Vue
184 lines
4.1 KiB
Vue
<template>
|
|
<div class="note-editor-container">
|
|
<div class="editor-header">
|
|
<el-input
|
|
v-model="noteTitle"
|
|
placeholder="请输入标题..."
|
|
class="title-input"
|
|
:disabled="loading"
|
|
/>
|
|
<div class="editor-actions">
|
|
<el-button type="primary" :loading="loading" @click="handleSave">
|
|
<el-icon><DocumentChecked /></el-icon>
|
|
{{ isNew ? '创建' : '保存' }}
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="editor-body">
|
|
<UmoEditor v-model="noteContent" />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, watch, onMounted } from 'vue';
|
|
import { ElMessage } from 'element-plus';
|
|
import { DocumentChecked } from '@element-plus/icons-vue';
|
|
import { getNotebookDetail, createNotebook, updateNotebook } from '@/api/notebook';
|
|
|
|
const props = defineProps({
|
|
noteId: {
|
|
type: [Number, String],
|
|
required: true,
|
|
},
|
|
});
|
|
|
|
const emit = defineEmits(['save-success', 'create-success']);
|
|
|
|
const noteTitle = ref('');
|
|
const noteContent = ref('');
|
|
const loading = ref(false);
|
|
const isNew = ref(false);
|
|
|
|
// 加载笔记数据
|
|
const loadNote = async () => {
|
|
if (props.noteId === 'new') {
|
|
isNew.value = true;
|
|
noteTitle.value = '新建笔记';
|
|
noteContent.value = '';
|
|
return;
|
|
}
|
|
|
|
isNew.value = false;
|
|
loading.value = true;
|
|
|
|
try {
|
|
const response = await getNotebookDetail(props.noteId);
|
|
if (response.code === 200) {
|
|
noteTitle.value = response.data.title || '无标题';
|
|
noteContent.value = response.data.content || '';
|
|
} else {
|
|
ElMessage.error('加载笔记失败');
|
|
}
|
|
} catch (error) {
|
|
console.error('加载笔记失败:', error);
|
|
ElMessage.error('加载笔记失败');
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
};
|
|
|
|
// 保存笔记
|
|
const handleSave = async () => {
|
|
if (!noteTitle.value.trim()) {
|
|
ElMessage.warning('请输入标题');
|
|
return;
|
|
}
|
|
|
|
loading.value = true;
|
|
|
|
try {
|
|
if (isNew.value) {
|
|
// 创建新笔记
|
|
const response = await createNotebook({
|
|
title: noteTitle.value,
|
|
content: noteContent.value,
|
|
});
|
|
|
|
if (response.code === 200) {
|
|
ElMessage.success('创建成功');
|
|
isNew.value = false;
|
|
emit('create-success', response.data.id);
|
|
} else {
|
|
ElMessage.error(response.msg || '创建失败');
|
|
}
|
|
} else {
|
|
// 更新现有笔记
|
|
const response = await updateNotebook(props.noteId, {
|
|
title: noteTitle.value,
|
|
content: noteContent.value,
|
|
});
|
|
|
|
if (response.code === 200) {
|
|
ElMessage.success('保存成功');
|
|
emit('save-success');
|
|
} else {
|
|
ElMessage.error(response.msg || '保存失败');
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('保存失败:', error);
|
|
ElMessage.error('保存失败');
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
};
|
|
|
|
// 监听笔记 ID 变化
|
|
watch(
|
|
() => props.noteId,
|
|
() => {
|
|
loadNote();
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
onMounted(() => {
|
|
loadNote();
|
|
});
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.note-editor-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
background: var(--el-bg-color);
|
|
}
|
|
|
|
.editor-header {
|
|
padding: 16px 20px;
|
|
border-bottom: 1px solid var(--el-border-color-lighter);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16px;
|
|
background: var(--el-fill-color-light);
|
|
|
|
.title-input {
|
|
flex: 1;
|
|
|
|
:deep(.el-input__wrapper) {
|
|
background: var(--el-bg-color);
|
|
box-shadow: 0 0 0 1px var(--el-border-color) inset;
|
|
padding: 8px 12px;
|
|
|
|
&:hover {
|
|
box-shadow: 0 0 0 1px var(--el-border-color-hover) inset;
|
|
}
|
|
|
|
&.is-focus {
|
|
box-shadow: 0 0 0 1px var(--el-color-primary) inset;
|
|
}
|
|
}
|
|
|
|
:deep(.el-input__inner) {
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
color: var(--el-text-color-primary);
|
|
}
|
|
}
|
|
|
|
.editor-actions {
|
|
display: flex;
|
|
gap: 8px;
|
|
}
|
|
}
|
|
|
|
.editor-body {
|
|
flex: 1;
|
|
padding: 20px;
|
|
overflow: hidden;
|
|
}
|
|
</style>
|