feat(note): 添加私密笔记功能
- 新增私密笔记相关样式和图标 - 在笔记列表和详情页面添加私密状态显示 - 实现私密笔记的创建和状态切换功能 - 添加未登录用户查看私密笔记时的提示
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
<el-header class="preview-header">
|
||||
<h2 class="preview-title">
|
||||
{{ selectedFile.title }}
|
||||
<el-icon v-if="selectedFile.isPrivate === 1" class="lock-icon"><Lock /></el-icon>
|
||||
<el-icon class="edit-icon" @click="openRenameDialog(selectedFile, 'file')"><Edit /></el-icon>
|
||||
</h2>
|
||||
<div class="actions">
|
||||
@@ -50,6 +51,9 @@
|
||||
<el-button v-if="showEditor" type="primary" @click="showEditor = !showEditor; previewFile(editData)">返回</el-button>
|
||||
<el-button v-if="showEditor && userStore.isLoggedIn" type="success" @click="handleSave(vditor.getValue())">保存</el-button>
|
||||
<span v-if="showEditor" class="save-status">{{ saveStatus }}</span>
|
||||
<el-button v-if="!showEditor && userStore.isLoggedIn" type="info" @click="showPrivacyDialog = true">
|
||||
{{ selectedFile.isPrivate === 1 ? '设为公开' : '设为私密' }}
|
||||
</el-button>
|
||||
<el-dropdown v-if="!showEditor && userStore.isLoggedIn" @command="handleExport">
|
||||
<el-button type="success">
|
||||
导出<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||
@@ -64,7 +68,12 @@
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</el-header>
|
||||
<div v-if="!showEditor" :key="selectedFile.id" class="markdown-preview"></div>
|
||||
<div v-if="!showEditor" :key="selectedFile.id" class="markdown-preview">
|
||||
<div v-if="selectedFile.isPrivate === 1 && !userStore.isLoggedIn && !selectedFile.content" class="private-note-notice">
|
||||
<el-icon><Lock /></el-icon>
|
||||
<p>这是私密笔记,请登录后查看完整内容</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Vditor 编辑器 -->
|
||||
<div v-show="showEditor" id="vditor" class="vditor" />
|
||||
</div>
|
||||
@@ -109,10 +118,11 @@
|
||||
</el-header>
|
||||
|
||||
<div v-if="groupMarkdownFiles.length > 0" class="file-list">
|
||||
<el-card v-for="file in groupMarkdownFiles" :key="file.id" shadow="hover" class="file-item">
|
||||
<el-card v-for="file in groupMarkdownFiles" :key="file.id" shadow="hover" class="file-item" :class="{ 'private-note': file.isPrivate === 1 }">
|
||||
<div @click="previewFile(file)" class="file-title">
|
||||
<span>{{ file.title }}</span>
|
||||
<span class="file-group-name">{{ file.groupingName }}</span>
|
||||
<el-icon v-if="file.isPrivate === 1 && !userStore.isLoggedIn" class="lock-icon"><Lock /></el-icon>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
@@ -158,6 +168,16 @@
|
||||
style="width: 100%;"
|
||||
></el-cascader>
|
||||
</el-form-item>
|
||||
<el-form-item label="私密笔记">
|
||||
<el-switch
|
||||
v-model="newNoteForm.isPrivate"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
active-text="私密"
|
||||
inactive-text="公开"
|
||||
/>
|
||||
<div class="form-item-help">私密笔记只有登录用户才能查看内容</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="showCreateNoteDialog = false">取消</el-button>
|
||||
@@ -246,6 +266,21 @@
|
||||
<el-button type="primary" @click="handleUpdatePassword">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 修改笔记私密状态对话框 -->
|
||||
<el-dialog v-model="showPrivacyDialog" :title="selectedFile && selectedFile.isPrivate === 1 ? '设为公开笔记' : '设为私密笔记'" width="400px">
|
||||
<div v-if="selectedFile">
|
||||
<p>您确定要将笔记 <strong>"{{ selectedFile.title }}"</strong> {{ selectedFile.isPrivate === 1 ? '设为公开' : '设为私密' }}吗?</p>
|
||||
<div class="privacy-explanation">
|
||||
<el-icon><InfoFilled /></el-icon>
|
||||
<span>{{ selectedFile.isPrivate === 1 ? '公开笔记:所有用户都可以查看内容' : '私密笔记:只有登录用户才能查看内容' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="showPrivacyDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="handlePrivacyChange">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
@@ -274,7 +309,7 @@ import {
|
||||
generateRegistrationCode,
|
||||
updatePassword
|
||||
} from '@/api/CommonApi.js'
|
||||
import { Plus, Fold, Expand, Folder, Document, Search, Edit, Delete, ArrowDown, Clock } from "@element-plus/icons-vue";
|
||||
import { Plus, Fold, Expand, Folder, Document, Search, Edit, Delete, ArrowDown, Clock, Lock, InfoFilled } from "@element-plus/icons-vue";
|
||||
import { useUserStore } from '../stores/user';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
@@ -304,6 +339,7 @@ const showSystemSettingsDialog = ref(false);
|
||||
const isRegistrationEnabled = ref(true);
|
||||
const generatedCode = ref('');
|
||||
const showUpdatePasswordDialog = ref(false);
|
||||
const showPrivacyDialog = ref(false);
|
||||
|
||||
const groupFormRef = ref(null);
|
||||
const newGroupForm = ref({ name: '', parentId: null });
|
||||
@@ -317,7 +353,8 @@ const newNoteForm = ref({
|
||||
title: '',
|
||||
groupingId: null,
|
||||
fileName: '',
|
||||
content: ''
|
||||
content: '',
|
||||
isPrivate: 0
|
||||
});
|
||||
const noteFormRules = ref({
|
||||
title: [{ required: true, message: '请输入笔记标题', trigger: 'blur' }],
|
||||
@@ -494,7 +531,8 @@ const createNote = async () => {
|
||||
title: newNoteForm.value.title,
|
||||
groupingId: groupingId,
|
||||
fileName: newNoteForm.value.title + '.md',
|
||||
content: ''
|
||||
content: '',
|
||||
isPrivate: newNoteForm.value.isPrivate
|
||||
};
|
||||
editData.value = payload;
|
||||
showCreateNoteDialog.value = false;
|
||||
@@ -511,7 +549,7 @@ const createNote = async () => {
|
||||
};
|
||||
|
||||
const resetNoteForm = () => {
|
||||
newNoteForm.value = { id: null, title: '', groupingId: null, fileName: '', content: '' };
|
||||
newNoteForm.value = { id: null, title: '', groupingId: null, fileName: '', content: '', isPrivate: 0 };
|
||||
if (noteFormRef.value) {
|
||||
noteFormRef.value.resetFields();
|
||||
}
|
||||
@@ -571,6 +609,11 @@ const previewFile = async (file) => {
|
||||
content: content
|
||||
};
|
||||
showEditor.value = false; // 确保进入预览模式
|
||||
|
||||
// 如果是私密笔记且用户未登录,显示提示
|
||||
if (file.isPrivate === 1 && !userStore.isLoggedIn) {
|
||||
ElMessage.info('这是私密笔记,请登录后查看完整内容');
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('获取笔记内容失败: ' + error.message);
|
||||
selectedFile.value = null;
|
||||
@@ -587,6 +630,33 @@ const editNote = async (file) => {
|
||||
});
|
||||
};
|
||||
|
||||
// 修改笔记私密状态
|
||||
const handlePrivacyChange = async () => {
|
||||
if (!selectedFile.value) return;
|
||||
|
||||
try {
|
||||
const newPrivacyStatus = selectedFile.value.isPrivate === 1 ? 0 : 1;
|
||||
const payload = {
|
||||
...selectedFile.value,
|
||||
isPrivate: newPrivacyStatus
|
||||
};
|
||||
|
||||
const updatedFile = await updateMarkdown(payload);
|
||||
selectedFile.value = updatedFile;
|
||||
|
||||
// 更新列表中的文件状态
|
||||
const index = groupMarkdownFiles.value.findIndex(file => file.id === selectedFile.value.id);
|
||||
if (index !== -1) {
|
||||
groupMarkdownFiles.value[index] = updatedFile;
|
||||
}
|
||||
|
||||
showPrivacyDialog.value = false;
|
||||
ElMessage.success(`笔记已${newPrivacyStatus === 1 ? '设为私密' : '设为公开'}`);
|
||||
} catch (error) {
|
||||
ElMessage.error('修改笔记状态失败: ' + error.message);
|
||||
}
|
||||
};
|
||||
|
||||
// 图片上传
|
||||
const handleImageUpload=async (files) => {
|
||||
const promise = await uploadImage(files[0]);
|
||||
|
||||
Reference in New Issue
Block a user