1.前端代码拆分整理

2.合并统一配色方案
3.修改所有功能按钮为右上角图标
4.修改附件到文档相关按钮内
This commit is contained in:
Sh1yu
2023-09-20 09:31:38 +08:00
parent 35b4e2806b
commit eda883a9bf
25 changed files with 1382 additions and 1135 deletions

View File

@@ -1,29 +1,30 @@
<template>
<div style="height: 100%" class="page-edit-vue">
<div style="box-sizing: border-box; background: #f5f5f5; overflow: hidden">
<div style="padding: 5px; font-size: 14px; background: #fff">
<el-row>
<el-col :span="16" style="text-align: left">
<el-input v-if="wikiPageEdit.editorType===2" v-model="wikiPageEdit.pageTitle" :maxlength="40" placeholder="请输入标题" class="page-title-input" ></el-input>
</el-col>
<el-col :span="8" style="text-align: right;margin-top: 4px;">
<el-button type="primary" @click="createWikiSave(1)" size="small" :icon="ElIconDocumentChecked">保存并查看</el-button>
<el-button type="success" @click="createWikiSave(0)" size="small" :icon="ElIconCheck">仅保存</el-button>
<el-button @click="createWikiCancel" size="small" :icon="ElIconBack" style="margin-right: 5px">取消</el-button>
</el-col>
</el-row>
</div>
<el-row class="fake-header">
<el-col :span="1">
<el-button @click="turnLeftCollapse" v-if="storeDisplay.showMenu" text :icon="ElIconFold" class="fold-btn"></el-button>
<el-button @click="turnLeftCollapse" v-else text :icon="ElIconExpand" class="fold-btn"></el-button>
</el-col>
<el-col :span="17" style="text-align: left">
<el-input v-if="wikiPageEdit.editorType===2" v-model="wikiPageEdit.pageTitle" :maxlength="40" placeholder="请输入标题" class="page-title-input" ></el-input>
</el-col>
<el-col :span="5" class="title-info-view-right">
<el-button type="primary" @click="createWikiSave(1)" size="large" :icon="ElIconDocumentChecked">保存</el-button>
<el-button @click="createWikiCancel" size="large" :icon="ElIconBack" style="margin-right: 5px">取消</el-button>
</el-col>
</el-row>
<div style="box-sizing: border-box;background: #f5f5f5;overflow: hidden">
<div v-show="wikiPageEdit.editorType === 2" style="padding: 0 10px 10px 10px; background: #fff">
<mavonEditor
ref="mavonEditorRef"
v-model="markdownContent"
:toolbars="toolbars"
:externalLink="false"
style="height: calc(100vh - 155px)"
@save="createWikiSave(0)"
@imgAdd="addMarkdownImage"
placeholder="请录入文档内容"
class="page-content-editor wang-editor-body"
ref="mavonEditorRef"
v-model="markdownContent"
:toolbars="toolbars"
:externalLink="false"
style="height: calc(100vh - 155px)"
@save="createWikiSave(0)"
@imgAdd="addMarkdownImage"
placeholder="请录入文档内容"
class="page-content-editor wang-editor-body"
/>
</div>
<div v-show="wikiPageEdit.editorType === 1">
@@ -39,6 +40,8 @@ import {onBeforeRouteUpdate, useRouter, useRoute} from "vue-router";
import {ElMessageBox, ElMessage} from 'element-plus'
import {
DocumentChecked as ElIconDocumentChecked,
Fold as ElIconFold,
Expand as ElIconExpand,
Check as ElIconCheck,
Back as ElIconBack,
} from '@element-plus/icons-vue'
@@ -48,6 +51,9 @@ import 'mavon-editor/dist/markdown/github-markdown.min.css'
import 'mavon-editor/dist/css/index.css'
import axios from 'axios'
import WangEditor from './editor/WangEditor.vue'
import {useStoreSpaceData} from "@/store/spaceData";
import {useStorePageData} from "@/store/pageData";
import {useStoreDisplay} from "@/store/wikiDisplay";
let editor = ref({});
// 编辑相关
@@ -99,6 +105,9 @@ let toolbars = {
const props = defineProps({
spaceId: Number,
});
let storeSpace = useStoreSpaceData()
let storePage = useStorePageData()
let storeDisplay = useStoreDisplay()
let emit = defineEmits(['loadPageList']);
onBeforeRouteUpdate((to) => {
initQueryParam(to);
@@ -118,7 +127,18 @@ onMounted(() => {
window.onbeforeunload = function () {
that.unlockPage()
}
storeDisplay.showHeader = false
})
const turnLeftCollapse = () => {
storeDisplay.showMenu = !storeDisplay.showMenu
setTimeout(() => {
if (storeDisplay.showMenu) {
storeDisplay.rightAsideWidth = 301
} else {
storeDisplay.rightAsideWidth = 1
}
}, 100)
}
const unlockPage = () => {
// 防止各种事件重复调这个接口,只需要调一次就好了
if (isUnlock.value) return
@@ -133,6 +153,7 @@ const createWikiCancel = () => {
}).then(() => {
unlockPage()
router.back()
storeDisplay.showHeader = true
})
}
let wangEditorRef = ref();
@@ -170,18 +191,27 @@ const createWikiSave = (saveAfter) => {
pageApi.updatePage(param).then((json) => {
ElMessage.success('保存成功!')
// 重新加载左侧列表,跳转到展示页面
emit('loadPageList')
doGetPageList()
pageId.value = json.data.id
if (saveAfter == 1) {
router.push({
path: '/page/show',
query: {pageId: pageId.value},
}).then(()=>{
storeDisplay.showHeader = true
})
} else {
loadPageDetail(pageId.value)
}
})
}
const doGetPageList = () => {
let param = {spaceId: storeSpace.chooseSpaceId}
pageApi.pageList(param).then((json) => {
storePage.wikiPageList = json.data || []
})
}
const loadPageDetail = (pageId) => {
pageApi.pageDetail({id: pageId}).then((json) => {
wikiPage.value = json.data.wikiPage || {}
@@ -282,7 +312,33 @@ const initEditor = () => {
}
</style>
<style lang="scss">
<style lang="scss" scoped>
.fake-header{
color: #333;
height: 60px !important;
border-bottom: 0.5px solid #eaeaea;
.fold-btn {
padding: 28px 19px;
line-height: 28px;
color: #3d3a3a !important;
font-size: 18px;
}
.page-title-input {
margin-top: 10px;
margin-left: 5px;
width: 99%;
height: 50px;
}
.title-info-view-right {
text-align: right;
margin-top: 10px;
font-size: 14px;
color: #454343;
.split {
padding:0 4px;
}
}
}
.page-edit-vue {
.page-content-editor {
ol {
@@ -361,7 +417,8 @@ const initEditor = () => {
.page-edit-vue .page-title-input {
padding-bottom: 10px;
margin-left: 5px;
width: 100%;
margin-right: 5px;
width: 50%;
}
.page-edit-vue .markdown-body table {

View File

@@ -1,57 +1,15 @@
<template>
<div class="page-show-vue">
<div class="page-show-vue" v-if="storePage.pageInfo.editorType !== 0">
<el-row type="border-card" style="height: 100%">
<el-col :span="storePage.commentShow ? 18 : 24" style="padding: 20px;border-right: 1px solid #f1f1f1;height: 100%;overflow: auto;">
<el-row>
<el-col :span="navigationList.length > 0 ? 18 : 24">
<div style="max-width: 1000px; margin: 0 auto; padding-left: 10px">
<div class="wiki-title" ref="wikiTitleRef">{{ wikiPage.name }}</div>
<PageAction/>
<div class="wiki-files">
<el-table v-show="storePage.fileList.length > 0" :data="storePage.fileList" border style="width: 100%; margin-bottom: 5px">
<el-table-column label="文件名" show-overflow-tooltip>
<template v-slot="scope">
<el-link target="_blank" :href="scope.row.fileUrl" type="primary">{{scope.row.fileName }}</el-link>
</template>
</el-table-column>
<el-table-column prop="createUserName" label="创建人" width="110px" show-overflow-tooltip></el-table-column>
<el-table-column label="文件大小" width="120px">
<template v-slot="scope">{{computeFileSize(scope.row.fileSize) }}</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" width="160px"></el-table-column>
<el-table-column prop="downloadNum" label="下载次数" width="90px">
<template v-slot="scope">{{scope.row.downloadNum || 0}}</template>
</el-table-column>
<el-table-column label="操作" width="90px" v-if="wikiPageAuth.canDeleteFile == 1">
<template v-slot="scope">
<el-button @click="deletePageFile(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div ref="pageContentRef" class="wiki-page-content">
<div v-html="pageShowDetail" class="markdown-body" v-if="wikiPage.editorType == 2" v-highlight></div>
<div v-html="pageShowDetail" class="wang-editor-body" v-else></div>
</div>
<div style="margin-top: 40px; font-size: 14px">
<span style="vertical-align: top" class="is-link">
<span v-show="wikiPage.selfZan == 0" @click="zanPage(1)"><img src="../../assets/img/zan.png" style="vertical-align: middle"/> </span>
<span v-show="wikiPage.selfZan == 1" @click="zanPage(0)"><img src="../../assets/img/zan.png" style="vertical-align: middle; transform: rotateX(180deg)"/> </span>
</span>
<span style="margin-left: 10px; vertical-align: top">
<span v-if="wikiPage.selfZan == 0 && wikiPage.zanNum <= 0">成为第一个赞同者</span>
<span v-else-if="wikiPage.selfZan == 0 && wikiPage.zanNum > 0">
<span class="is-link" @click="showZanPageUser">{{ wikiPage.zanNum }}</span>赞了它
</span>
<span v-else-if="wikiPage.selfZan == 1 && wikiPage.zanNum <= 1">我赞了它</span>
<span v-else-if="wikiPage.selfZan == 1 && wikiPage.zanNum > 1">
<span class="is-link" @click="showZanPageUser">我和{{ wikiPage.zanNum - 1 }}个其他人</span>赞了它
</span>
</span>
<span style="margin-left: 10px">
<el-icon style="font-size: 16px; color: #666;vertical-align: middle;"><el-icon-view/></el-icon> {{ wikiPage.viewNum }}次阅读
</span>
</div>
<PageZan></PageZan>
</div>
</el-col>
<el-col :span="navigationList.length > 0 ? 6 : 0" v-if="navigationList.length > 0">
@@ -67,34 +25,21 @@
<el-tab-pane label="评论" name="comment">
<Comment/>
</el-tab-pane>
<el-tab-pane label="附件" name="annex">
<Annex/>
</el-tab-pane>
<el-tab-pane label="修改历史" name="history">
<div class="action-tab-box">
<div v-if="pageHistoryList.length <= 0" class="action-box-empty">
暂无修改历史记录
</div>
<el-timeline v-else>
<el-timeline-item v-for="history in pageHistoryList">
<el-tag :type="pageHistoryChoice.id === history.id ? history.loading === 3 ? 'danger' : 'success' : 'info'" class="history-item" @click="historyClick(history)">
<div>{{ history.createUserName }}</div>
<div>{{ history.createTime }}</div>
</el-tag>
<el-icon class="history-loading-status" v-show="history.loading===1"><el-icon-loading/></el-icon>
<el-icon class="history-loading-status" v-show="history.loading===2"><el-icon-circle-check/></el-icon>
<el-icon class="history-loading-status" v-show="history.loading===3"><el-icon-circle-close/></el-icon>
</el-timeline-item>
</el-timeline>
</div>
<PageHistory
:pageHistoryList="pageHistoryList"
:pageHistoryChoice="pageHistoryChoice"
:pageHistoryDetail="pageHistoryDetail"
@historyClickHandle="historyClickHandle"
@previewPageImage="previewPageImage"
@createNavigationHeading="createNavigationHeading"/>
</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
<!--点赞人员弹窗-->
<el-dialog title="赞了它的人" v-model="zanUserDialogVisible" width="600px">
<el-table :data="zanUserList" border :show-header="false" style="width: 100%; margin-bottom: 5px">
<el-table-column prop="createUserName" label="用户"></el-table-column>
<el-table-column prop="createTime" label="时间"></el-table-column>
</el-table>
</el-dialog>
<el-image-viewer
v-if="showImagePreview"
:url-list="showImagePreviewList"
@@ -132,8 +77,10 @@ import htmlUtil from '../../assets/lib/HtmlUtil.js'
import pageApi from '../../assets/api/page'
import userApi from '../../assets/api/user'
import Navigation from './components/Navigation.vue'
import PageAction from './show/PageAction.vue'
import Annex from './show/Annex.vue'
import PageHistory from './show/PageHistory.vue'
import Comment from './show/Comment.vue'
import PageZan from './show/PageZan.vue'
import {mavonEditor} from 'mavon-editor'
import 'mavon-editor/dist/markdown/github-markdown.min.css'
import 'mavon-editor/dist/css/index.css'
@@ -150,14 +97,10 @@ let wikiPageAuth = ref({});
let pageContent = ref({});
let selfUserId = ref(0);
let uploadFileList = ref([]);
let uploadFormData = ref({pageId: 0});
let zanUserDialogVisible = ref(false);
let zanUserList = ref([]);
let parentPath = ref({});
// 手机扫码
let qrCodeUrl = ref('');
let mobileScanDialogVisible = ref(false);
let uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + '/zyplayer-doc-wiki/page/file/upload');
// 页面权限
let pageAuthDialogVisible = ref(false);
let pageAuthUserList = ref([]);
@@ -196,15 +139,6 @@ onMounted(() => {
initQueryParam(route);
});
const editWiki = () => {
let param = {pageId: parentPath.value.pageId}
pageApi.pageLock(param).then(() => {
router.push({
path: '/page/edit',
query: {pageId: parentPath.value.pageId}
})
})
}
const getSearchUserList = (query) => {
if (query == '') return
pageAuthUserLoading.value = true
@@ -294,39 +228,11 @@ const getPageHistory = (pageId, pageNum) => {
}
})
}
const historyClick = (history) => {
if (pageHistoryChoice.value.id === history.id && !!pageHistoryDetail.value) {
return;
}
const historyClickHandle = (history) => {
pageHistoryChoice.value.loading = 0;
pageHistoryChoice.value = history;
// 缓存一下,但如果历史页面多了而且很大就占内存,也可以每次去拉取,先这样吧
if (history.content) {
history.loading = 2;
pageHistoryDetail.value = history.content;
pageShowDetail.value = history.content;
setTimeout(() => {
previewPageImage();
createNavigationHeading();
}, 500)
} else {
history.loading = 1
pageApi.pageHistoryDetail({id: history.id}).then((json) => {
history.loading = 2;
history.content = json.data || '--';
if (wikiPage.value.editorType === 2) {
history.content = mavonEditor.getMarkdownIt().render(history.content);
}
pageHistoryDetail.value = history.content;
pageShowDetail.value = history.content;
setTimeout(() => {
previewPageImage();
createNavigationHeading();
}, 500);
}).catch(() => {
history.loading = 3;
});
}
pageHistoryDetail.value = history.content;
pageShowDetail.value =history.content;
}
const clearHistory = () => {
pageHistoryChoice.value.loading = 0;
@@ -348,7 +254,6 @@ const loadPageDetail = (pageId) => {
pageContent.value = result.pageContent || {};
storePage.fileList = result.fileList || [];
selfUserId.value = result.selfUserId || 0;
uploadFormData.value = {pageId: wikiPage.value.id};
wikiPageAuth.value = {
canEdit: result.canEdit,
canDelete: result.canDelete,
@@ -371,7 +276,9 @@ const loadPageDetail = (pageId) => {
// 调用父方法展开目录树
emit('changeExpandedKeys', pageId);
setTimeout(() => {
previewPageImage();
if (storePage.pageInfo.editorType !== 0){
previewPageImage();
}
createNavigationHeading();
}, 500);
storePage.pageInfo = wikiPageRes;
@@ -409,33 +316,7 @@ const previewPageImage = () => {
}
})
}
const zanPage = (yn) => {
let param = {yn: yn, pageId: wikiPage.value.id}
pageApi.updatePageZan(param).then(() => {
wikiPage.value.selfZan = yn
wikiPage.value.zanNum = wikiPage.value.zanNum + (yn == 1 ? 1 : -1)
})
}
const showZanPageUser = () => {
zanUserDialogVisible.value = true
zanUserList.value = []
let param = {pageId: wikiPage.value.id}
pageApi.pageZanList(param).then((json) => {
zanUserList.value = json.data
})
}
const deletePageFile = (row) => {
ElMessageBox.confirm('确定要删除此文件吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
let param = {id: row.id};
pageApi.deletePageFile(param).then(() => {
storePage.fileList = storePage.fileList.filter(item => item.id !== row.id);
});
})
}
const getUserHeadBgColor = (userId) => {
let color = page.userHeadColor[userId]
if (!color) {

View File

@@ -150,7 +150,7 @@ defineExpose({setTitle,setPageId, setHtml, getPageData});
.wang-editor-box .wang-editor-content {
padding: 20px 0;
overflow: auto;
height: calc(100vh - 136px);
height: calc(100vh - 156px);
}
.wang-editor-box .w-e-bar-item {
height: 39px;

View File

@@ -0,0 +1,80 @@
<template>
<div class="wiki-file">
<el-upload v-if="storePage.pageAuth.canUploadFile === 1"
:on-success="uploadFileSuccess"
:on-error="uploadFileError"
:before-upload="beforeUpload"
:action="uploadFileUrl"
:data="uploadFormData"
:with-credentials="true" class="action-btn upload-page-file" name="files"
show-file-list multiple :limit="999">
<el-button type="primary" :underline="false" :icon="ElIconUpload" style="margin: 10px;width: 100%"> 上传附件</el-button>
</el-upload>
<el-table v-show="storePage.fileList.length > 0" :data="storePage.fileList" border
style="width: 100%; margin-bottom: 5px">
<el-table-column label="文件名" show-overflow-tooltip>
<template v-slot="scope">
<el-link target="_blank" :href="scope.row.fileUrl" type="primary">{{scope.row.fileName }}
</el-link>
</template>
</el-table-column>
<el-table-column prop="createUserName" label="创建人" width="110px"
show-overflow-tooltip></el-table-column>
<el-table-column label="文件大小" width="120px">
<template v-slot="scope">{{computeFileSize(scope.row.fileSize) }}</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" width="160px"></el-table-column>
<el-table-column prop="downloadNum" label="下载次数" width="90px">
<template v-slot="scope">{{scope.row.downloadNum || 0}}</template>
</el-table-column>
<el-table-column label="操作" width="90px" v-if="storePage.pageAuth.canDeleteFile == 1">
<template v-slot="scope">
<el-button @click="deletePageFile(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script setup>
import {Upload as ElIconUpload} from '@element-plus/icons-vue'
import {useStorePageData} from "@/store/pageData";
let storePage = useStorePageData();
import {ref} from 'vue';
import {ElMessageBox, ElMessage} from 'element-plus';
import pageApi from "@/assets/api/page";
import unitUtil from "@/assets/lib/UnitUtil";
let uploadFormData = ref({pageId: 0});
let uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + '/zyplayer-doc-wiki/page/file/upload');
const beforeUpload = () => {
uploadFormData.value.pageId = storePage.pageInfo.id;
}
const uploadFileError = (err) => {
ElMessage.error('上传失败,' + err);
}
const uploadFileSuccess = (response) => {
if (response.errCode === 200) {
storePage.fileList.push(response.data);
ElMessage.success('上传成功!');
} else {
ElMessage('上传失败:' + (response.errMsg || '未知错误'));
}
}
const deletePageFile = (row) => {
ElMessageBox.confirm('确定要删除此文件吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
let param = {id: row.id};
pageApi.deletePageFile(param).then(() => {
storePage.fileList = storePage.fileList.filter(item => item.id !== row.id);
});
})
}
const computeFileSize = (fileSize) => {
return unitUtil.computeFileSize(fileSize)
}
</script>

View File

@@ -62,7 +62,9 @@ let storePage = useStorePageData();
let storeUser = useStoreUserData();
watch(() => storePage.pageInfo, (newVal) => {
loadCommentList();
if (storePage.pageInfo.editorType !== 0){
loadCommentList();
}
})
onMounted(() => {
loadCommentList();
@@ -146,7 +148,7 @@ const getUserHeadBgColor = (userId) => {
<style lang="scss">
.comment-box {
padding: 8px;
height: calc(100vh - 100px);
height: calc(100vh - 115px);
overflow: auto;
.comment-list {

View File

@@ -23,8 +23,10 @@ import pageApi from "@/assets/api/page";
import {useStorePageData} from "@/store/pageData";
import userApi from "@/assets/api/user";
import QRCode from 'qrcode'
import {useStoreSpaceData} from "@/store/spaceData";
let storePage = useStorePageData();
let storeSpace = useStoreSpaceData();
const route = useRoute();
const router = useRouter();
@@ -53,7 +55,7 @@ const initMobileQrScan = () => {
if (!dataItemEditVisible.value) return;
let routeUrl = router.resolve({
path: '/page/share/mobile/view',
query: {pageId: storePage.pageInfo.id, space: storePage.spaceInfo.uuid}
query: {pageId: storePage.pageInfo.id, space: storeSpace.spaceInfo.uuid}
});
let hostPath = window.location.href.split('#')[0];
setTimeout(() => {

View File

@@ -1,201 +0,0 @@
<template>
<el-row class="page-action-box">
<el-col :span="12" class="page-create-info">
<span v-if="storePage.pageInfo.updateUserName">
{{ storePage.pageInfo.updateUserName }}
<span class="split"></span>
{{ storePage.pageInfo.updateTime }}
<span class="split">修改</span>
</span>
<span v-else class="create-user-time">
{{ storePage.pageInfo.createUserName }}
<span class="split"></span>
{{ storePage.pageInfo.createTime }}
<span class="split">创建</span>
</span>
</el-col>
<el-col :span="12" class="page-action-list">
<el-link v-if="storePage.pageAuth.canEdit === 1" @click="editWiki" type="primary" :underline="false" :icon="ElIconEdit" class="action-btn">编辑</el-link>
<el-link type="primary" :icon="ElIconChatLineRound" :underline="false" @click="showCommentWiki" class="action-btn">评论</el-link>
<el-upload v-if="storePage.pageAuth.canUploadFile === 1"
:on-success="uploadFileSuccess"
:on-error="uploadFileError"
:before-upload="beforeUpload"
:action="uploadFileUrl"
:data="uploadFormData"
:with-credentials="true" class="action-btn upload-page-file" name="files"
show-file-list multiple :limit="999">
<el-link type="primary" :underline="false" :icon="ElIconUpload"> 上传附件</el-link>
</el-upload>
<el-dropdown trigger="click" class="action-btn more-dropdown">
<el-link type="primary" :underline="false">
更多 <el-icon class="el-icon--right"><el-icon-arrow-down/></el-icon>
</el-link>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="showPageHistory" :icon="ElIconTime">查看历史版本</el-dropdown-item>
<el-dropdown-item @click="editWikiAuth" v-if="storePage.pageAuth.canConfigAuth === 1" :icon="ElIconSCheck">权限设置</el-dropdown-item>
<el-dropdown-item @click="showOpenPage" v-if="storePage.spaceInfo.openDoc === 1" :icon="ElIconShare">查看开放文档</el-dropdown-item>
<el-dropdown-item @click="showMobileView" v-if="storePage.spaceInfo.openDoc === 1" :icon="ElIconMobilePhone">手机端查看</el-dropdown-item>
<el-dropdown-item @click="exportWord" :icon="ElIconDownload">导出为Word文档</el-dropdown-item>
<el-dropdown-item @click="deleteWikiPage" v-if="storePage.pageAuth.canDelete === 1" :icon="ElIconDelete">删除</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-col>
<MobileQrScanDialog v-model:visible="mobileScanDialogVisible"/>
<PageAuthDialog v-model:visible="pageAuthDialogVisible"/>
<form method="post" ref="downloadFormRef" :action="downloadFormParam.url" target="_blank">
<input type="hidden" :name="key" :value="val" v-for="(val, key) in downloadFormParam.param"/>
</form>
</el-row>
</template>
<script setup>
import {
ArrowDown as ElIconArrowDown,
View as ElIconView,
Close as ElIconClose,
Delete as ElIconDelete,
Loading as ElIconLoading,
CircleCheck as ElIconCircleCheck,
CircleClose as ElIconCircleClose,
ChatLineRound as ElIconChatLineRound,
Upload as ElIconUpload,
Edit as ElIconEdit,
Timer as ElIconTime,
Stamp as ElIconSCheck,
Share as ElIconShare,
Iphone as ElIconMobilePhone,
Download as ElIconDownload,
} from '@element-plus/icons-vue'
import {toRefs, ref, reactive, onMounted, watch, defineProps, defineEmits, defineExpose, computed} from 'vue';
import {onBeforeRouteUpdate, useRoute, useRouter} from "vue-router";
import { ElMessageBox, ElMessage, ElNotification } from 'element-plus';
import pageApi from '@/assets/api/page'
import PageAuthDialog from './PageAuthDialog.vue'
import MobileQrScanDialog from './MobileQrScanDialog.vue'
import {useStorePageData} from "@/store/pageData";
let storePage = useStorePageData();
let router = useRouter();
const editWiki = () => {
// 锁定页面并进入编辑页面
let param = {pageId: storePage.pageInfo.id};
pageApi.pageLock(param).then(() => {
router.push({path: '/page/edit', query: {pageId: storePage.pageInfo.id}});
});
}
const showCommentWiki = () => {
storePage.commentShow = true;
storePage.commentActiveTab = 'comment';
}
let pageAuthDialogVisible = ref(false);
const editWikiAuth = () => {
pageAuthDialogVisible.value = true;
}
const showPageHistory = () => {
storePage.commentShow = true;
storePage.commentActiveTab = 'history';
}
const showOpenPage = () => {
if (storePage.spaceInfo.openDoc !== 1) {
ElMessage.warning('该空间未开放,无法查看开放文档地址');
} else {
let routeUrl = router.resolve({
path: '/page/share/view',
query: {pageId: storePage.pageInfo.id, space: storePage.spaceInfo.uuid}
});
window.open(routeUrl.href, '_blank');
}
}
const deleteWikiPage = () => {
ElMessageBox.confirm('确定要删除此页面及其所有子页面吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
let param = {pageId: storePage.pageInfo.id};
pageApi.pageDelete(param).then(() => {
// 重新加载左侧列表,跳转到展示页面
// emit('loadPageList'); TODO
router.push({path: '/home', query: {spaceId: storePage.pageInfo.spaceId}});
});
}).catch(() => {});
}
// 下载为Word
let downloadFormRef = ref();
let downloadFormParam = ref({url: 'zyplayer-doc-wiki/page/download', param: {}});
const exportWord = () => {
downloadFormParam.value.param = {pageId: storePage.pageInfo.id};
setTimeout(() => downloadFormRef.value.submit(), 0);
}
// 手机扫码
let mobileScanDialogVisible = ref(false);
const showMobileView = () => {
if (storePage.spaceInfo.openDoc !== 1) {
ElMessage.warning('该空间未开放,无法查看开放文档地址');
} else {
mobileScanDialogVisible.value = true;
}
}
// 上传相关
let uploadFormData = ref({pageId: 0});
let uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + '/zyplayer-doc-wiki/page/file/upload');
const beforeUpload = () => {
uploadFormData.value.pageId = storePage.pageInfo.id;
}
const uploadFileError = (err) => {
ElMessage.error('上传失败,' + err);
}
const uploadFileSuccess = (response) => {
if (response.errCode === 200) {
storePage.fileList.push(response.data);
ElMessage.success('上传成功!');
} else {
ElMessage('上传失败:' + (response.errMsg || '未知错误'));
}
}
</script>
<style scoped lang="scss">
.page-action-box {
padding: 30px 0;
.page-create-info {
font-size: 14px;
color: #888;
.split {
padding: 0 4px;
}
}
.page-action-list {
text-align: right;
}
}
</style>
<style lang="scss">
.page-action-box {
.page-action-list {
.el-icon {
margin-right: 4px;
}
.action-btn + .action-btn {
margin-left: 15px;
}
.upload-page-file {
display: inline;
vertical-align: middle;
}
.more-dropdown {
vertical-align: middle;
}
}
}
</style>

View File

@@ -1,17 +1,24 @@
<template>
<div class="action-tab-box">
<div v-if="pageHistoryList.length <= 0" class="action-box-empty">
<div v-if="props.pageHistoryList.length <= 0" class="action-box-empty">
暂无修改历史记录
</div>
<el-timeline v-else>
<el-timeline-item v-for="history in pageHistoryList">
<el-tag :type="pageHistoryChoice.id === history.id ? history.loading === 3 ? 'danger' : 'success' : 'info'" class="history-item" @click="historyClick(history)">
<el-timeline-item v-for="history in props.pageHistoryList">
<el-tag :type="props.pageHistoryChoice.id === history.id ? history.loading === 3 ? 'danger' : 'success' : 'info'"
class="history-item" @click="historyClick(history)">
<div>{{ history.createUserName }}</div>
<div>{{ history.createTime }}</div>
</el-tag>
<el-icon class="history-loading-status" v-show="history.loading===1"><el-icon-loading/></el-icon>
<el-icon class="history-loading-status" v-show="history.loading===2"><el-icon-circle-check/></el-icon>
<el-icon class="history-loading-status" v-show="history.loading===3"><el-icon-circle-close/></el-icon>
<el-icon class="history-loading-status" v-show="history.loading===1">
<el-icon-loading/>
</el-icon>
<el-icon class="history-loading-status" v-show="history.loading===2">
<el-icon-circle-check/>
</el-icon>
<el-icon class="history-loading-status" v-show="history.loading===3">
<el-icon-circle-close/>
</el-icon>
</el-timeline-item>
</el-timeline>
</div>
@@ -19,30 +26,54 @@
<script setup>
import {
Delete as ElIconDelete,
CircleCheck as ElIconCircleCheck,
CircleClose as ElIconCircleClose,
Loading as ElIconLoading,
} from '@element-plus/icons-vue'
import {toRefs, ref, reactive, onMounted, watch, defineProps, defineEmits, defineExpose, computed} from 'vue';
import {onBeforeRouteUpdate, useRoute, useRouter} from "vue-router";
import { ElMessageBox, ElMessage, ElNotification } from 'element-plus';
import pageApi from '@/assets/api/page'
import {mavonEditor} from "mavon-editor";
import {ref, defineProps, defineEmits} from 'vue';
import {useStorePageData} from "@/store/pageData";
import {useStoreUserData} from "@/store/userData";
let route = useRoute();
let router = useRouter();
let storePage = useStorePageData();
let storeUser = useStoreUserData();
let pageHistoryDetail = ref('');
let pageHistoryChoice = ref({});
let pageHistoryList = ref([]);
let pageHistoryPageNum = ref(1);
watch(() => storePage.pageInfo, (newVal) => {
let props= defineProps({
pageHistoryList:Array,
pageHistoryChoice:Object,
pageHistoryDetail:String,
})
onMounted(() => {
});
let emit = defineEmits(['historyClickHandle','previewPageImage','createNavigationHeading'])
const historyClick = (history) => {
if (props.pageHistoryChoice.id === history.id && !!props.pageHistoryDetail.value) {
return;
}
// 缓存一下,但如果历史页面多了而且很大就占内存,也可以每次去拉取,先这样吧
if (history.content) {
history.loading = 2;
emit('historyClickHandle',history)
setTimeout(() => {
emit('previewPageImage',history)
emit('createNavigationHeading',history)
}, 500)
} else {
history.loading = 1
pageApi.pageHistoryDetail({id: history.id}).then((json) => {
history.loading = 2;
history.content = json.data || '--';
if (storePage.pageInfo.editorType === 2) {
history.content = mavonEditor.getMarkdownIt().render(history.content);
}
emit('historyClickHandle',history)
setTimeout(() => {
emit('previewPageImage',history)
emit('createNavigationHeading',history)
}, 500);
}).catch(() => {
history.loading = 3;
});
}
}
</script>
<style lang="scss">

View File

@@ -0,0 +1,55 @@
<template>
<div style="margin-top: 40px; font-size: 14px">
<span style="vertical-align: top" class="is-link">
<span v-show="storePage.pageInfo.selfZan == 0" @click="zanPage(1)"><img src="../../../assets/img/zan.png" style="vertical-align: middle"/> </span>
<span v-show="storePage.pageInfo.selfZan == 1" @click="zanPage(0)"><img src="../../../assets/img/zan.png" style="vertical-align: middle; transform: rotateX(180deg)"/> </span>
</span>
<span style="margin-left: 10px; vertical-align: top">
<span v-if="storePage.pageInfo.selfZan == 0 && storePage.pageInfo.zanNum <= 0">成为第一个赞同者</span>
<span v-else-if="storePage.pageInfo.selfZan == 0 && storePage.pageInfo.zanNum > 0">
<span class="is-link" @click="showZanPageUser">{{ storePage.pageInfo.zanNum }}</span>赞了它
</span>
<span v-else-if="storePage.pageInfo.selfZan == 1 && storePage.pageInfo.zanNum <= 1">我赞了它</span>
<span v-else-if="storePage.pageInfo.selfZan == 1 && storePage.pageInfo.zanNum > 1">
<span class="is-link" @click="showZanPageUser">我和{{ storePage.pageInfo.zanNum - 1 }}个其他人</span>赞了它
</span>
</span>
<span style="margin-left: 10px">
<el-icon style="font-size: 16px; color: #666;vertical-align: middle;"><el-icon-view/></el-icon> {{ storePage.pageInfo.viewNum }}次阅读
</span>
</div>
<el-dialog title="赞了它的人" v-model="zanUserDialogVisible" width="600px">
<el-table :data="zanUserList" border :show-header="false" style="width: 100%; margin-bottom: 5px">
<el-table-column prop="createUserName" label="用户"></el-table-column>
<el-table-column prop="createTime" label="时间"></el-table-column>
</el-table>
</el-dialog>
</template>
<script setup>
import pageApi from '../../../assets/api/page'
import {ref} from 'vue';
import {useStorePageData} from "@/store/pageData";
import {
View as ElIconView,
} from '@element-plus/icons-vue'
let zanUserList = ref([]);
let zanUserDialogVisible = ref(false);
let storePage = useStorePageData();
const zanPage = (yn) => {
let param = {yn: yn, pageId: storePage.pageInfo.id}
pageApi.updatePageZan(param).then(() => {
storePage.pageInfo.selfZan = yn
storePage.pageInfo.zanNum = storePage.pageInfo.zanNum + (yn == 1 ? 1 : -1)
})
}
const showZanPageUser = () => {
zanUserDialogVisible.value = true
zanUserList.value = []
let param = {pageId: storePage.pageInfo.id}
pageApi.pageZanList(param).then((json) => {
zanUserList.value = json.data
})
}
</script>