1.前端代码拆分整理
2.合并统一配色方案 3.修改所有功能按钮为右上角图标 4.修改附件到文档相关按钮内
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
80
zyplayer-doc-ui/wiki-ui/src/views/page/show/Annex.vue
Normal file
80
zyplayer-doc-ui/wiki-ui/src/views/page/show/Annex.vue
Normal 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>
|
||||
@@ -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 {
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -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>
|
||||
@@ -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">
|
||||
|
||||
55
zyplayer-doc-ui/wiki-ui/src/views/page/show/PageZan.vue
Normal file
55
zyplayer-doc-ui/wiki-ui/src/views/page/show/PageZan.vue
Normal 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>
|
||||
Reference in New Issue
Block a user