空间设置和回收站功能开发
This commit is contained in:
@@ -87,7 +87,7 @@ public class WikiPage implements Serializable {
|
|||||||
private Date updateTime;
|
private Date updateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 0=有效 1=删除
|
* 0=有效 1=删除 2=永久删除
|
||||||
*/
|
*/
|
||||||
private Integer delFlag;
|
private Integer delFlag;
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class WikiPageServiceImpl extends ServiceImpl<WikiPageMapper, WikiPage> i
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void deletePageAndSon(WikiPage wikiPage) {
|
private void deletePageAndSon(WikiPage wikiPage) {
|
||||||
wikiPage.setDelFlag(1);
|
wikiPage.setDelFlag(wikiPage.getDelFlag());
|
||||||
this.updateById(wikiPage);
|
this.updateById(wikiPage);
|
||||||
|
|
||||||
QueryWrapper<WikiPage> wrapper = new QueryWrapper<>();
|
QueryWrapper<WikiPage> wrapper = new QueryWrapper<>();
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.dromara.zyplayer.data.service.params;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PageDeleteParam {
|
||||||
|
private Long pageId;
|
||||||
|
private Integer delFlag;
|
||||||
|
private Long spaceId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package org.dromara.zyplayer.data.service.params;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回收站列表参数
|
||||||
|
*
|
||||||
|
* @author 暮光:城中城
|
||||||
|
* @since 2023-05-01
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class PageRecycleListParam implements Serializable {
|
||||||
|
private Long spaceId;
|
||||||
|
private Long pageNum;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package org.dromara.zyplayer.data.service.params;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class RecycleDeletePageParam {
|
||||||
|
private String pageIds;
|
||||||
|
private Long spaceId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package org.dromara.zyplayer.data.service.params;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class RestorePageParam {
|
||||||
|
private String pageIds;
|
||||||
|
}
|
||||||
@@ -6,6 +6,9 @@ export default {
|
|||||||
pageChangeParent: (data) => request({url: '/zyplayer-doc-wiki/page/changeParent', method: 'post', data: Qs.stringify(data)}),
|
pageChangeParent: (data) => request({url: '/zyplayer-doc-wiki/page/changeParent', method: 'post', data: Qs.stringify(data)}),
|
||||||
pageList: (data) => request({url: '/zyplayer-doc-wiki/page/list', method: 'post', data: Qs.stringify(data)}),
|
pageList: (data) => request({url: '/zyplayer-doc-wiki/page/list', method: 'post', data: Qs.stringify(data)}),
|
||||||
updatePage: (data) => request({url: '/zyplayer-doc-wiki/page/update', method: 'post', data: Qs.stringify(data)}),
|
updatePage: (data) => request({url: '/zyplayer-doc-wiki/page/update', method: 'post', data: Qs.stringify(data)}),
|
||||||
|
recyclePageListList: data => request({url: '/zyplayer-doc-wiki/page/recycleList', method: 'post', data: Qs.stringify(data)}),
|
||||||
|
pageRestore: data => request({url: '/zyplayer-doc-wiki/page/restore', method: 'post', data: Qs.stringify(data)}),
|
||||||
|
recycleDeletePage: data => request({url: '/zyplayer-doc-wiki/page/recycleDelete', method: 'post', data: Qs.stringify(data)}),
|
||||||
copyPage: (data) => request({url: '/zyplayer-doc-wiki/page/copy', method: 'post', data: Qs.stringify(data)}),
|
copyPage: (data) => request({url: '/zyplayer-doc-wiki/page/copy', method: 'post', data: Qs.stringify(data)}),
|
||||||
movePage: (data) => request({url: '/zyplayer-doc-wiki/page/move', method: 'post', data: Qs.stringify(data)}),
|
movePage: (data) => request({url: '/zyplayer-doc-wiki/page/move', method: 'post', data: Qs.stringify(data)}),
|
||||||
renamePage: (data) => request({url: '/zyplayer-doc-wiki/page/rename', method: 'post', data: Qs.stringify(data)}),
|
renamePage: (data) => request({url: '/zyplayer-doc-wiki/page/rename', method: 'post', data: Qs.stringify(data)}),
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import NoAuth from './views/common/NoAuth.vue';
|
|||||||
// import Home from './views/home/Home.vue';
|
// import Home from './views/home/Home.vue';
|
||||||
// import MyInfo from './views/user/MyInfo.vue';
|
// import MyInfo from './views/user/MyInfo.vue';
|
||||||
import Show from './views/view/View.vue';
|
import Show from './views/view/View.vue';
|
||||||
|
import Setting from './views/view/Setting.vue';
|
||||||
|
import Recycle from './views/view/Recycle.vue';
|
||||||
import Edit from './views/view/Edit.vue';
|
import Edit from './views/view/Edit.vue';
|
||||||
|
|
||||||
// import spaceManage from './views/space/Manage.vue';
|
// import spaceManage from './views/space/Manage.vue';
|
||||||
@@ -43,10 +45,12 @@ export default createRouter({
|
|||||||
component: PageLayout,
|
component: PageLayout,
|
||||||
children: [
|
children: [
|
||||||
// {path: '/home', name: 'WIKI文档管理', component: NoAuth},
|
// {path: '/home', name: 'WIKI文档管理', component: NoAuth},
|
||||||
{path: '/user/myInfo', name: 'WIKI-我的信息', component: NoAuth},
|
{path: '/user/myInfo', name: '我的信息', component: NoAuth},
|
||||||
{path: '/view/:spaceId?/:pageId?', name: 'WIKI-页面查看', component: Show},
|
{path: '/view/:spaceId?/:pageId?', name: '页面查看', component: Show},
|
||||||
{path: '/edit/:spaceId/:pageId', name: 'WIKI-编辑内容', component: Edit},
|
{path: '/edit/:spaceId/:pageId', name: '页面编辑', component: Edit},
|
||||||
{path: '/space/manage', name: 'WIKI-空间管理', component: NoAuth},
|
{path: '/view/setting/:spaceId', name: '空间设置', component: Setting},
|
||||||
|
{path: '/view/recycle/:spaceId', name: '回收站', component: Recycle},
|
||||||
|
{path: '/space/manage', name: '空间管理', component: NoAuth},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
144
zyplayer-doc-ui/wiki-ui/src/views/view/Recycle.vue
Normal file
144
zyplayer-doc-ui/wiki-ui/src/views/view/Recycle.vue
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
<template>
|
||||||
|
<div class="space-page-recycle-box">
|
||||||
|
<a-flex align="center" justify="space-between" style="margin-bottom: 10px;">
|
||||||
|
<a-space>
|
||||||
|
<a-button @click="restorePageSelected" :disabled="selectedRowKeys.length <= 0" :icon="h(UndoOutlined)">恢复</a-button>
|
||||||
|
<a-button @click="deletePageSelected" :disabled="selectedRowKeys.length <= 0" :icon="h(DeleteOutlined)">彻底删除</a-button>
|
||||||
|
</a-space>
|
||||||
|
<a-button @click="loadPageList" type="primary" :icon="h(SearchOutlined)">查询</a-button>
|
||||||
|
</a-flex>
|
||||||
|
<a-table :dataSource="recyclePageList" :columns="listColumns" :loading="recycleListLoading"
|
||||||
|
:row-selection="{ selectedRowKeys: selectedRowKeys, onChange: selectionChange }" rowKey="id"
|
||||||
|
:pagination="paginationConfig" @change="recyclePageSortChange"
|
||||||
|
size="middle" :scroll="{ y: 'calc(100vh - 220px)' }">
|
||||||
|
<template #bodyCell="{ column, text, record }">
|
||||||
|
<template v-if="column.dataIndex === 'actions'">
|
||||||
|
<a-space>
|
||||||
|
<a-button @click="restorePage(record)" :icon="h(UndoOutlined)">恢复</a-button>
|
||||||
|
<a-button @click="deletePage(record)" :icon="h(DeleteOutlined)">彻底删除</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { UndoOutlined, DeleteOutlined, SearchOutlined } from '@ant-design/icons-vue';
|
||||||
|
import pageApi from "@/assets/api/page";
|
||||||
|
import {toRefs, ref, reactive, onMounted, onBeforeUnmount, watch, h, defineEmits, computed} from 'vue';
|
||||||
|
import {onBeforeRouteUpdate, onBeforeRouteLeave, useRouter, useRoute} from "vue-router";
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import { Modal } from 'ant-design-vue';
|
||||||
|
import { useStoreDisplay } from '@/store/wikiDisplay.js'
|
||||||
|
import { useStorePageData } from '@/store/pageData.js'
|
||||||
|
|
||||||
|
let route = useRoute();
|
||||||
|
let router = useRouter();
|
||||||
|
let storeDisplay = useStoreDisplay();
|
||||||
|
let storePage = useStorePageData();
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
storeDisplay.currentPage = 'recycle';
|
||||||
|
storeDisplay.headerShow = true;
|
||||||
|
loadPageList();
|
||||||
|
});
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
storeDisplay.currentPage = '';
|
||||||
|
});
|
||||||
|
let recycleListParam = ref({
|
||||||
|
pageNum: 1,
|
||||||
|
});
|
||||||
|
let selectedRowKeys = ref([]);
|
||||||
|
const selectionChange = (rowKeys, selectedRows) => {
|
||||||
|
selectedRowKeys.value = rowKeys;
|
||||||
|
}
|
||||||
|
let recycleListTotalCount = ref(0);
|
||||||
|
let recycleListLoading = ref(false);
|
||||||
|
let recyclePageList = ref([]);
|
||||||
|
const loadPageList = () => {
|
||||||
|
recycleListLoading.value = true;
|
||||||
|
let param = {spaceId: route.params.spaceId, ...recycleListParam.value};
|
||||||
|
pageApi.recyclePageListList(param).then(json => {
|
||||||
|
recyclePageList.value = json.data || [];
|
||||||
|
if (recycleListParam.value.pageNum === 1) {
|
||||||
|
recycleListTotalCount.value = json.total || 0;
|
||||||
|
}
|
||||||
|
recycleListLoading.value = false;
|
||||||
|
}).catch(() => {
|
||||||
|
recycleListLoading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
watch(() => recycleListParam.value.pageNum, loadPageList);
|
||||||
|
const restorePageSelected = () => {
|
||||||
|
restorePageConfirm(selectedRowKeys.value.join(','));
|
||||||
|
}
|
||||||
|
const deletePageSelected = () => {
|
||||||
|
deletePageConfirm(selectedRowKeys.value.join(','), route.params.spaceId);
|
||||||
|
}
|
||||||
|
const restorePage = (row) => {
|
||||||
|
restorePageConfirm(row.id);
|
||||||
|
}
|
||||||
|
const deletePage = (row) => {
|
||||||
|
deletePageConfirm(row.id, row.spaceId);
|
||||||
|
}
|
||||||
|
const restorePageConfirm = (ids) => {
|
||||||
|
Modal.confirm({
|
||||||
|
maskClosable: true,
|
||||||
|
title: '提示',
|
||||||
|
content: '确定要恢复此页面吗?如果该页面的父页面也被删除,则需父页面恢复后才可看见此页面',
|
||||||
|
okText: '确认恢复',
|
||||||
|
cancelText: '取消',
|
||||||
|
onOk: () => {
|
||||||
|
pageApi.pageRestore({pageIds: ids}).then(json => {
|
||||||
|
loadPageList();
|
||||||
|
message.success('已恢复');
|
||||||
|
storePage.eventPageUpdate = !storePage.eventPageUpdate;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const deletePageConfirm = (ids, spaceId) => {
|
||||||
|
Modal.confirm({
|
||||||
|
maskClosable: true,
|
||||||
|
title: '提示',
|
||||||
|
content: '确定要彻底删除此页面吗?',
|
||||||
|
okText: '彻底删除',
|
||||||
|
cancelText: '取消',
|
||||||
|
onOk: () => {
|
||||||
|
pageApi.recycleDeletePage({pageIds: ids, spaceId: spaceId}).then(() => {
|
||||||
|
loadPageList();
|
||||||
|
message.success('已删除');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let paginationConfig = ref({
|
||||||
|
total: 0,
|
||||||
|
current: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
showSizeChanger: true,
|
||||||
|
pageSizeOptions: ['20', '50', '100'],
|
||||||
|
showTotal: total => `共${total}条`
|
||||||
|
});
|
||||||
|
const listColumns = computed(() => ([
|
||||||
|
{title: '名字', dataIndex: 'name'},
|
||||||
|
{title: '删除时间', dataIndex: 'updateTime', width: 180},
|
||||||
|
{title: '操作人', dataIndex: 'updateUserName', width: 180},
|
||||||
|
{title: '', dataIndex: 'actions', width: 280}
|
||||||
|
]));
|
||||||
|
const recyclePageSortChange = (pagination, filters, sorter) => {
|
||||||
|
recycleListParam.value.pageNum = pagination.current;
|
||||||
|
recycleListParam.value.pageSize = pagination.pageSize;
|
||||||
|
paginationConfig.value.current = pagination.current;
|
||||||
|
paginationConfig.value.pageSize = pagination.pageSize;
|
||||||
|
loadPageList();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.space-page-recycle-box {
|
||||||
|
padding: 10px 20px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
44
zyplayer-doc-ui/wiki-ui/src/views/view/Setting.vue
Normal file
44
zyplayer-doc-ui/wiki-ui/src/views/view/Setting.vue
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<div class="setting-box">
|
||||||
|
<a-tabs v-model:activeKey="activeTabName">
|
||||||
|
<a-tab-pane tab="基本信息" key="base">
|
||||||
|
<BaseInfo></BaseInfo>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane tab="更多" key="more">
|
||||||
|
<MoreAction></MoreAction>
|
||||||
|
</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import BaseInfo from './setting/BaseInfo.vue'
|
||||||
|
import MoreAction from './setting/MoreAction.vue'
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import {toRefs, ref, reactive, onMounted, onBeforeUnmount, watch, defineEmits, computed} from 'vue';
|
||||||
|
import {useRouter, useRoute} from "vue-router";
|
||||||
|
import { useStoreDisplay } from '@/store/wikiDisplay'
|
||||||
|
import { useStorePageData } from '@/store/pageData'
|
||||||
|
|
||||||
|
let route = useRoute();
|
||||||
|
let router = useRouter();
|
||||||
|
let storeDisplay = useStoreDisplay();
|
||||||
|
let storePage = useStorePageData();
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
storeDisplay.headerShow = true;
|
||||||
|
storeDisplay.currentPage = 'setting';
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
storeDisplay.currentPage = '';
|
||||||
|
});
|
||||||
|
let activeTabName = ref('base');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.setting-box {
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-dropdown :trigger="['click']">
|
<a-dropdown :trigger="['click']" placement="bottom">
|
||||||
<a-button :icon="h(PlusOutlined)" type="text" style="color: #888;"></a-button>
|
<a-button :icon="h(PlusOutlined)" type="text" style="color: #888;"></a-button>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<a-menu>
|
<a-menu>
|
||||||
|
|||||||
@@ -29,15 +29,13 @@
|
|||||||
<div class="space-folder-box" v-if="!props.readOnly">
|
<div class="space-folder-box" v-if="!props.readOnly">
|
||||||
<a-flex align="center" justify="space-between">
|
<a-flex align="center" justify="space-between">
|
||||||
<div class="page-group-tag">
|
<div class="page-group-tag">
|
||||||
<el-tooltip :content="spaceTreeIsClose?'点击展开目录':'点击收起目录'" placement="top">
|
<span class="label">空间目录</span>
|
||||||
<span class="label" @click="changeDropdownStatus">空间目录</span>
|
|
||||||
</el-tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
<AddMenu/>
|
<AddMenu/>
|
||||||
</a-flex>
|
</a-flex>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-show="!spaceTreeIsClose" class="wiki-page-tree-box">
|
<div class="wiki-page-tree-box">
|
||||||
<el-tree ref="wikiPageTreeRef" :current-node-key="props.nowPageId" :data="storePage.pageList"
|
<el-tree ref="wikiPageTreeRef" :current-node-key="props.nowPageId" :data="storePage.pageList"
|
||||||
:default-expanded-keys="wikiPageExpandedKeys" :expand-on-click-node="true"
|
:default-expanded-keys="wikiPageExpandedKeys" :expand-on-click-node="true"
|
||||||
:props="defaultProps" :draggable="!props.readOnly"
|
:props="defaultProps" :draggable="!props.readOnly"
|
||||||
@@ -65,7 +63,7 @@
|
|||||||
<!--操作-->
|
<!--操作-->
|
||||||
<div @click.stop class="page-action-box">
|
<div @click.stop class="page-action-box">
|
||||||
<AddMenu :pageId="data.id"/>
|
<AddMenu :pageId="data.id"/>
|
||||||
<a-dropdown :trigger="['click']" @click="choosePageIdFunc(data.id)">
|
<a-dropdown @click="choosePageIdFunc(data.id)" :trigger="['click']" placement="bottom">
|
||||||
<a-button :icon="h(EllipsisOutlined)" type="text" style="color: #888;"></a-button>
|
<a-button :icon="h(EllipsisOutlined)" type="text" style="color: #888;"></a-button>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<a-menu>
|
<a-menu>
|
||||||
@@ -98,6 +96,19 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-tree>
|
</el-tree>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="wiki-page-footer">
|
||||||
|
<div style="flex: 1;">
|
||||||
|
<a-tooltip title="空间设置" placement="top">
|
||||||
|
<a-button @click="openSetting" :icon="h(SettingOutlined)" class="footer-btn">设置</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
<el-divider direction="vertical" style="margin-top: 8px;"/>
|
||||||
|
<div style="flex: 1;">
|
||||||
|
<a-tooltip title="回收站" placement="top">
|
||||||
|
<a-button @click="openRecycle" :icon="h(DeleteOutlined)" class="footer-btn">回收站</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -113,7 +124,7 @@ import {
|
|||||||
EditTwo as IconParkEditTwo,
|
EditTwo as IconParkEditTwo,
|
||||||
PageTemplate as IconParkPageTemplate,
|
PageTemplate as IconParkPageTemplate,
|
||||||
} from '@icon-park/vue-next'
|
} from '@icon-park/vue-next'
|
||||||
import { EllipsisOutlined, HomeOutlined } from '@ant-design/icons-vue';
|
import { EllipsisOutlined, HomeOutlined, SettingOutlined, DeleteOutlined } from '@ant-design/icons-vue';
|
||||||
import {ref, defineProps, defineEmits, defineExpose, onMounted, h, watch} from 'vue';
|
import {ref, defineProps, defineEmits, defineExpose, onMounted, h, watch} from 'vue';
|
||||||
import {useRouter, useRoute} from "vue-router";
|
import {useRouter, useRoute} from "vue-router";
|
||||||
import pageApi from '@/assets/api/page';
|
import pageApi from '@/assets/api/page';
|
||||||
@@ -276,6 +287,9 @@ const doGetPageList = () => {
|
|||||||
pageApi.pageList({spaceId: spaceId}).then((json) => {
|
pageApi.pageList({spaceId: spaceId}).then((json) => {
|
||||||
storePage.pageList = json.data || [];
|
storePage.pageList = json.data || [];
|
||||||
if (route.path.startsWith('/view')) {
|
if (route.path.startsWith('/view')) {
|
||||||
|
if (route.path.startsWith('/view/setting') || route.path.startsWith('/view/recycle')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// 查看页面
|
// 查看页面
|
||||||
if (storePage.pageList.length <= 0) {
|
if (storePage.pageList.length <= 0) {
|
||||||
router.push({path: `/view/${spaceId}`});
|
router.push({path: `/view/${spaceId}`});
|
||||||
@@ -308,10 +322,6 @@ const handleSearchKeywordsSelect = (item) => {
|
|||||||
searchKeywords.value = '';
|
searchKeywords.value = '';
|
||||||
router.push({path: `/view/${item.spaceId}/${item.pageId}`});
|
router.push({path: `/view/${item.spaceId}/${item.pageId}`});
|
||||||
}
|
}
|
||||||
let spaceTreeIsClose = ref(false);
|
|
||||||
const changeDropdownStatus = () => {
|
|
||||||
spaceTreeIsClose.value = !spaceTreeIsClose.value;
|
|
||||||
}
|
|
||||||
const searchByKeywords = () => {
|
const searchByKeywords = () => {
|
||||||
wikiPageTreeRef.value.filter(searchKeywords.value);
|
wikiPageTreeRef.value.filter(searchKeywords.value);
|
||||||
}
|
}
|
||||||
@@ -337,6 +347,14 @@ const handlePageDrop = (draggingNode, dropNode, dropType, ev) => {
|
|||||||
doGetPageList();
|
doGetPageList();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// 打开设置页面
|
||||||
|
let openSetting = () => {
|
||||||
|
router.push({path: `/view/setting/${storeSpace.chooseSpaceId}`});
|
||||||
|
}
|
||||||
|
// 打开回收站页面
|
||||||
|
let openRecycle = () => {
|
||||||
|
router.push({path: `/view/recycle/${storeSpace.chooseSpaceId}`});
|
||||||
|
}
|
||||||
defineExpose({searchByKeywords});
|
defineExpose({searchByKeywords});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -379,15 +397,10 @@ defineExpose({searchByKeywords});
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
color: #888;
|
color: #888;
|
||||||
cursor: pointer;
|
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: #eee;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,6 +409,7 @@ defineExpose({searchByKeywords});
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
|
height: calc(100vh - 140px);
|
||||||
|
|
||||||
.el-tree-node__content {
|
.el-tree-node__content {
|
||||||
height: 35px;
|
height: 35px;
|
||||||
@@ -437,6 +451,29 @@ defineExpose({searchByKeywords});
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wiki-page-footer {
|
||||||
|
padding: 5px;
|
||||||
|
display: flex;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
|
||||||
|
.footer-btn {
|
||||||
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
color: #666;
|
||||||
|
background: #fafafa;
|
||||||
|
box-shadow: unset;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
background: #fafafa;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #eaeaea;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-autocomplete-popper {
|
.search-autocomplete-popper {
|
||||||
|
|||||||
@@ -17,6 +17,12 @@
|
|||||||
<div class="time">最近修改:{{storePage.pageInfo.updateTime || ''}}</div>
|
<div class="time">最近修改:{{storePage.pageInfo.updateTime || ''}}</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="storeDisplay.currentPage === 'setting'" class="title-setting-box">
|
||||||
|
<div class="setting-title">空间设置</div>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="storeDisplay.currentPage === 'recycle'" class="title-setting-box">
|
||||||
|
<div class="setting-title">回收站</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12" style="text-align: right;">
|
<el-col :span="12" style="text-align: right;">
|
||||||
@@ -51,9 +57,8 @@
|
|||||||
<template #overlay>
|
<template #overlay>
|
||||||
<a-menu>
|
<a-menu>
|
||||||
<a-menu-item @click="showAbout">关于</a-menu-item>
|
<a-menu-item @click="showAbout">关于</a-menu-item>
|
||||||
<a-menu-item @click="showConsole">控制台</a-menu-item>
|
|
||||||
<a-menu-divider />
|
<a-menu-divider />
|
||||||
<a-menu-item @click="userSignOut">退出登录</a-menu-item>
|
<a-menu-item @click="userSignOut" danger>退出登录</a-menu-item>
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</template>
|
</template>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
|
|||||||
66
zyplayer-doc-ui/wiki-ui/src/views/view/setting/BaseInfo.vue
Normal file
66
zyplayer-doc-ui/wiki-ui/src/views/view/setting/BaseInfo.vue
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<template>
|
||||||
|
<div class="setting-base-info-box">
|
||||||
|
<a-card title="基本信息">
|
||||||
|
<template #extra>
|
||||||
|
<a-button @click="onSpaceUpdateSubmit" type="primary">保存设置</a-button>
|
||||||
|
</template>
|
||||||
|
<a-form :model="spaceForm" :rules="spaceFormRules" ref="spaceFormRef" @submit.prevent :label-col="{span: 4}" :wrapper-col="{span: 20}">
|
||||||
|
<a-form-item label="空间名" name="name">
|
||||||
|
<a-input v-model:value="spaceForm.name" placeholder="请输入空间名" :maxlength="25"></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="空间说明" name="spaceExplain">
|
||||||
|
<a-textarea v-model:value="spaceForm.spaceExplain" placeholder="请输入空间说明" :maxlength="250" :autoSize="{ minRows: 6}" type="textarea" resize="none"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {toRefs, ref, reactive, onMounted, onBeforeUnmount, watch, h, defineEmits, computed} from 'vue';
|
||||||
|
import {useRouter, useRoute} from "vue-router";
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import pageApi from "@/assets/api/page";
|
||||||
|
import {useStorePageData} from "@/store/pageData";
|
||||||
|
import {useStoreSpaceData} from "@/store/spaceData";
|
||||||
|
|
||||||
|
let storePage = useStorePageData();
|
||||||
|
let storeSpace = useStoreSpaceData();
|
||||||
|
watch(() => storeSpace.spaceInfo, (newSpace, oldSpace) => {
|
||||||
|
initSpaceForm();
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
initSpaceForm();
|
||||||
|
});
|
||||||
|
let spaceForm = ref({});
|
||||||
|
let spaceFormRules = ref({
|
||||||
|
name: [{required: true, message: '请输入空间名', trigger: 'blur'}],
|
||||||
|
});
|
||||||
|
let spaceFormRef = ref();
|
||||||
|
const initSpaceForm = () => {
|
||||||
|
spaceForm.value = {...storeSpace.spaceInfo};
|
||||||
|
}
|
||||||
|
const onSpaceUpdateSubmit = () => {
|
||||||
|
spaceFormRef.value.validate().then(() => {
|
||||||
|
let param = {
|
||||||
|
id: spaceForm.value.id,
|
||||||
|
name: spaceForm.value.name,
|
||||||
|
spaceExplain: spaceForm.value.spaceExplain,
|
||||||
|
};
|
||||||
|
pageApi.updateSpace(param).then(json => {
|
||||||
|
message.success('修改成功');
|
||||||
|
storeSpace.spaceInfo.name = spaceForm.value.name;
|
||||||
|
storeSpace.spaceInfo.spaceExplain = spaceForm.value.spaceExplain;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.setting-base-info-box {
|
||||||
|
width: 80%;
|
||||||
|
min-width: 400px;
|
||||||
|
max-width: 700px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
108
zyplayer-doc-ui/wiki-ui/src/views/view/setting/MoreAction.vue
Normal file
108
zyplayer-doc-ui/wiki-ui/src/views/view/setting/MoreAction.vue
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<template>
|
||||||
|
<div class="setting-more-action-box">
|
||||||
|
<a-card title="空间管理" style="margin-top: 20px;">
|
||||||
|
<a-form :label-col="{span: 4}" :wrapper-col="{span: 20}">
|
||||||
|
<a-form-item label="删除空间">
|
||||||
|
<div style="width: 100%;">
|
||||||
|
<a-button @click="deleteSpaceInfo" type="primary" danger :icon="h(DeleteOutlined)">删除空间</a-button>
|
||||||
|
<el-alert title="删除该空间及其所有页面,请谨慎操作" show-icon type="warning" :closable="false" style="margin-top: 10px;line-height: normal;"/>
|
||||||
|
</div>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-card>
|
||||||
|
<a-card title="更多信息" class="create-info-card">
|
||||||
|
<a-row class="create-info-line">
|
||||||
|
<a-col :span="12">
|
||||||
|
<div>创建人:{{storeSpace.spaceInfo.createUserName}}</div>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<div>创建时间:{{storeSpace.spaceInfo.createTime}}</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<a-row v-if="storeSpace.spaceInfo.modified" class="create-info-line">
|
||||||
|
<a-col :span="12">
|
||||||
|
<div>修改人:{{storeSpace.spaceInfo.modifyUser}}</div>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<div>修改时间:{{storeSpace.spaceInfo.modified}}</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
SyncOutlined, DeleteOutlined, CopyOutlined, DownOutlined,
|
||||||
|
DownloadOutlined, UploadOutlined, ExclamationCircleOutlined
|
||||||
|
} from '@ant-design/icons-vue';
|
||||||
|
import {toRefs, ref, reactive, onMounted, h, watch, defineEmits, computed} from 'vue';
|
||||||
|
import {useRouter, useRoute} from "vue-router";
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import { Modal } from 'ant-design-vue';
|
||||||
|
import {useStoreDisplay} from '@/store/wikiDisplay.js'
|
||||||
|
import pageApi from "@/assets/api/page";
|
||||||
|
import {useStorePageData} from "@/store/pageData";
|
||||||
|
import {useStoreSpaceData} from "@/store/spaceData";
|
||||||
|
import {useStoreUserData} from "@/store/userData";
|
||||||
|
|
||||||
|
let storeDisplay = useStoreDisplay();
|
||||||
|
let storePage = useStorePageData();
|
||||||
|
let storeSpace = useStoreSpaceData();
|
||||||
|
let storeUser = useStoreUserData();
|
||||||
|
|
||||||
|
let route = useRoute();
|
||||||
|
let router = useRouter();
|
||||||
|
onMounted(() => {
|
||||||
|
});
|
||||||
|
const deleteSpaceInfo = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
maskClosable: true,
|
||||||
|
title: '提示',
|
||||||
|
content: '确定要删除此空间及下面的所有文档吗?',
|
||||||
|
okText: '确定',
|
||||||
|
cancelText: '取消',
|
||||||
|
onOk: () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
Modal.confirm({
|
||||||
|
maskClosable: true,
|
||||||
|
title: '二次确认',
|
||||||
|
content: '这是一个有风险的操作,需要您再次确认,确定要删除此空间及下面的所有文档吗?',
|
||||||
|
okText: '确定删除',
|
||||||
|
cancelText: '我再想想',
|
||||||
|
okType: 'danger',
|
||||||
|
onOk: () => {
|
||||||
|
let param = {id: storeSpace.spaceInfo.id, delFlag: 1};
|
||||||
|
pageApi.updateSpaceAuth(param).then(() => {
|
||||||
|
message.success('删除成功');
|
||||||
|
router.push({path: '/view'});
|
||||||
|
storeSpace.eventSpaceDelete = !storeSpace.eventSpaceDelete;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.setting-more-action-box {
|
||||||
|
width: 80%;
|
||||||
|
min-width: 500px;
|
||||||
|
max-width: 800px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
|
||||||
|
.create-info-card {
|
||||||
|
margin-top: 20px;
|
||||||
|
|
||||||
|
.create-info-line {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -20,6 +20,10 @@ import org.dromara.zyplayer.data.repository.manage.vo.WikiPageTemplateInfoVo;
|
|||||||
import org.dromara.zyplayer.data.repository.support.consts.DocSysType;
|
import org.dromara.zyplayer.data.repository.support.consts.DocSysType;
|
||||||
import org.dromara.zyplayer.data.repository.support.consts.UserMsgType;
|
import org.dromara.zyplayer.data.repository.support.consts.UserMsgType;
|
||||||
import org.dromara.zyplayer.data.service.manage.*;
|
import org.dromara.zyplayer.data.service.manage.*;
|
||||||
|
import org.dromara.zyplayer.data.service.params.PageDeleteParam;
|
||||||
|
import org.dromara.zyplayer.data.service.params.PageRecycleListParam;
|
||||||
|
import org.dromara.zyplayer.data.service.params.RecycleDeletePageParam;
|
||||||
|
import org.dromara.zyplayer.data.service.params.RestorePageParam;
|
||||||
import org.dromara.zyplayer.data.utils.CachePrefix;
|
import org.dromara.zyplayer.data.utils.CachePrefix;
|
||||||
import org.dromara.zyplayer.data.utils.CacheUtil;
|
import org.dromara.zyplayer.data.utils.CacheUtil;
|
||||||
import org.dromara.zyplayer.wiki.controller.vo.WikiPageContentVo;
|
import org.dromara.zyplayer.wiki.controller.vo.WikiPageContentVo;
|
||||||
@@ -78,7 +82,6 @@ public class WikiPageController {
|
|||||||
if (SpaceType.isOthersPrivate(wikiSpaceSel.getType(), currentUser.getUserId(), wikiSpaceSel.getCreateUserId())) {
|
if (SpaceType.isOthersPrivate(wikiSpaceSel.getType(), currentUser.getUserId(), wikiSpaceSel.getCreateUserId())) {
|
||||||
return DocResponseJson.warn("您没有权限查看该空间的文章列表!");
|
return DocResponseJson.warn("您没有权限查看该空间的文章列表!");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<WikiPageTemplateInfoVo> wikiPageList = wikiPageService.wikiPageTemplateInfos(wikiPage.getSpaceId());
|
List<WikiPageTemplateInfoVo> wikiPageList = wikiPageService.wikiPageTemplateInfos(wikiPage.getSpaceId());
|
||||||
Map<Long, List<WikiPageVo>> listMap = wikiPageList.stream().map(WikiPageVo::new).collect(Collectors.groupingBy(WikiPageVo::getParentId));
|
Map<Long, List<WikiPageVo>> listMap = wikiPageList.stream().map(WikiPageVo::new).collect(Collectors.groupingBy(WikiPageVo::getParentId));
|
||||||
List<WikiPageVo> nodePageList = listMap.get(0L);
|
List<WikiPageVo> nodePageList = listMap.get(0L);
|
||||||
@@ -88,7 +91,22 @@ public class WikiPageController {
|
|||||||
}
|
}
|
||||||
return DocResponseJson.ok(nodePageList);
|
return DocResponseJson.ok(nodePageList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/recycleList")
|
||||||
|
public ResponseJson<List<WikiPageVo>> recycleList(PageRecycleListParam param) {
|
||||||
|
return wikiPageWebService.recycleList(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/restore")
|
||||||
|
public ResponseJson<Object> restore(RestorePageParam param) {
|
||||||
|
return wikiPageWebService.restore(param.getPageIds());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/recycleDelete")
|
||||||
|
public ResponseJson<Object> recycleDelete(RecycleDeletePageParam param) {
|
||||||
|
return wikiPageWebService.recycleDelete(param);
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/detail")
|
@PostMapping("/detail")
|
||||||
public ResponseJson<WikiPageContentVo> detail(WikiPage wikiPage) {
|
public ResponseJson<WikiPageContentVo> detail(WikiPage wikiPage) {
|
||||||
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
||||||
@@ -172,28 +190,8 @@ public class WikiPageController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/delete")
|
@PostMapping("/delete")
|
||||||
public ResponseJson<Object> delete(Long pageId) {
|
public ResponseJson<Object> delete(PageDeleteParam param) {
|
||||||
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
wikiPageWebService.delete(param);
|
||||||
WikiPage wikiPageSel = wikiPageService.getById(pageId);
|
|
||||||
// 删除权限判断
|
|
||||||
WikiSpace wikiSpaceSel = wikiSpaceService.getById(wikiPageSel.getSpaceId());
|
|
||||||
String canDelete = wikiPageAuthService.canDelete(wikiSpaceSel, wikiPageSel.getEditType(), wikiPageSel.getId(), currentUser.getUserId());
|
|
||||||
if (canDelete != null) {
|
|
||||||
return DocResponseJson.warn(canDelete);
|
|
||||||
}
|
|
||||||
// 执行删除
|
|
||||||
WikiPage wikiPage = new WikiPage();
|
|
||||||
wikiPage.setId(pageId);
|
|
||||||
wikiPage.setDelFlag(1);
|
|
||||||
wikiPage.setName(wikiPageSel.getName());
|
|
||||||
wikiPage.setUpdateTime(new Date());
|
|
||||||
wikiPage.setUpdateUserId(currentUser.getUserId());
|
|
||||||
wikiPage.setUpdateUserName(currentUser.getUsername());
|
|
||||||
wikiPageService.deletePage(wikiPage);
|
|
||||||
QueryWrapper queryWrapper = new QueryWrapper();
|
|
||||||
queryWrapper.eq("space_id", wikiPageSel.getSpaceId());
|
|
||||||
queryWrapper.eq("page_id", wikiPageSel.getId());
|
|
||||||
wikiPageTemplateService.remove(queryWrapper);
|
|
||||||
return DocResponseJson.ok();
|
return DocResponseJson.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,15 +7,27 @@ import cn.hutool.core.util.URLUtil;
|
|||||||
import cn.hutool.http.HttpResponse;
|
import cn.hutool.http.HttpResponse;
|
||||||
import cn.hutool.http.HttpUtil;
|
import cn.hutool.http.HttpUtil;
|
||||||
import cn.hutool.system.SystemUtil;
|
import cn.hutool.system.SystemUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.dromara.zyplayer.core.json.DocResponseJson;
|
import org.dromara.zyplayer.core.json.DocResponseJson;
|
||||||
import org.dromara.zyplayer.core.json.ResponseJson;
|
import org.dromara.zyplayer.core.json.ResponseJson;
|
||||||
import org.dromara.zyplayer.data.config.security.DocUserDetails;
|
import org.dromara.zyplayer.data.config.security.DocUserDetails;
|
||||||
import org.dromara.zyplayer.data.config.security.DocUserUtil;
|
import org.dromara.zyplayer.data.config.security.DocUserUtil;
|
||||||
import org.dromara.zyplayer.data.repository.manage.entity.WikiPage;
|
import org.dromara.zyplayer.data.repository.manage.entity.WikiPage;
|
||||||
|
import org.dromara.zyplayer.data.repository.manage.entity.WikiPageTemplate;
|
||||||
import org.dromara.zyplayer.data.repository.manage.entity.WikiSpace;
|
import org.dromara.zyplayer.data.repository.manage.entity.WikiSpace;
|
||||||
|
import org.dromara.zyplayer.data.repository.manage.mapper.WikiPageMapper;
|
||||||
import org.dromara.zyplayer.data.service.manage.WikiPageService;
|
import org.dromara.zyplayer.data.service.manage.WikiPageService;
|
||||||
|
import org.dromara.zyplayer.data.service.manage.WikiPageTemplateService;
|
||||||
import org.dromara.zyplayer.data.service.manage.WikiSpaceService;
|
import org.dromara.zyplayer.data.service.manage.WikiSpaceService;
|
||||||
|
import org.dromara.zyplayer.data.service.params.PageDeleteParam;
|
||||||
|
import org.dromara.zyplayer.data.service.params.PageRecycleListParam;
|
||||||
|
import org.dromara.zyplayer.data.service.params.RecycleDeletePageParam;
|
||||||
import org.dromara.zyplayer.data.utils.HtmlUtils;
|
import org.dromara.zyplayer.data.utils.HtmlUtils;
|
||||||
|
import org.dromara.zyplayer.wiki.controller.vo.WikiPageVo;
|
||||||
import org.dromara.zyplayer.wiki.framework.consts.SpaceType;
|
import org.dromara.zyplayer.wiki.framework.consts.SpaceType;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.docx4j.XmlUtils;
|
import org.docx4j.XmlUtils;
|
||||||
@@ -38,7 +50,11 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class WikiPageWebService {
|
public class WikiPageWebService {
|
||||||
@@ -48,6 +64,10 @@ public class WikiPageWebService {
|
|||||||
WikiPageService wikiPageService;
|
WikiPageService wikiPageService;
|
||||||
@Resource
|
@Resource
|
||||||
WikiSpaceService wikiSpaceService;
|
WikiSpaceService wikiSpaceService;
|
||||||
|
@Resource
|
||||||
|
WikiPageMapper wikiPageMapper;
|
||||||
|
@Resource
|
||||||
|
WikiPageTemplateService wikiPageTemplateService;
|
||||||
|
|
||||||
public ResponseJson<Object> download(Long pageId, String content, HttpServletRequest request, HttpServletResponse response) {
|
public ResponseJson<Object> download(Long pageId, String content, HttpServletRequest request, HttpServletResponse response) {
|
||||||
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
||||||
@@ -118,4 +138,104 @@ public class WikiPageWebService {
|
|||||||
}
|
}
|
||||||
return DocResponseJson.warn("导出失败");
|
return DocResponseJson.warn("导出失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取空间已删除的页面
|
||||||
|
*
|
||||||
|
* @author 暮光:城中城
|
||||||
|
* @since 2023-04-29
|
||||||
|
*/
|
||||||
|
public ResponseJson<List<WikiPageVo>> recycleList(PageRecycleListParam param) {
|
||||||
|
// 删除的页面
|
||||||
|
WikiSpace wikiSpaceSel = wikiSpaceService.getById(param.getSpaceId());
|
||||||
|
// 不是空间的协作者返回空列表 TODO 判断权限
|
||||||
|
if (wikiSpaceSel == null) {
|
||||||
|
return DocResponseJson.ok();
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<WikiPage> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(WikiPage::getDelFlag, 1);
|
||||||
|
wrapper.eq(WikiPage::getSpaceId, param.getSpaceId());
|
||||||
|
wrapper.orderByDesc(WikiPage::getUpdateTime).orderByDesc(WikiPage::getId);
|
||||||
|
IPage<WikiPage> page = new Page<>(param.getPageNum(), 20, true);
|
||||||
|
wikiPageService.page(page, wrapper);
|
||||||
|
DocResponseJson<List<WikiPageVo>> responseJson = DocResponseJson.ok();
|
||||||
|
responseJson.setTotal(page.getTotal());
|
||||||
|
if (CollectionUtils.isNotEmpty(page.getRecords())) {
|
||||||
|
responseJson.setData(page.getRecords().stream().map(WikiPageVo::new).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
return responseJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResponseJson<Object> restore(String pageIds) {
|
||||||
|
String[] pageIdArr = StringUtils.split(pageIds, ",");
|
||||||
|
for (String pageId : pageIdArr) {
|
||||||
|
DocResponseJson<Object> restoreRes = this.restore(Long.valueOf(pageId));
|
||||||
|
if (!restoreRes.isOk()) {
|
||||||
|
return restoreRes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DocResponseJson.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocResponseJson<Object> restore(Long pageId) {
|
||||||
|
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
||||||
|
WikiPage wikiPageSel = wikiPageService.getById(pageId);
|
||||||
|
WikiSpace wikiSpaceSel = wikiSpaceService.getById(wikiPageSel.getSpaceId());
|
||||||
|
// 是否具有编辑权限 TODO
|
||||||
|
// if (!userDataAuthService.canEditPage(wikiSpaceSel.getId(), pageId, wikiSpaceSel.getCreateUserId())) {
|
||||||
|
// return DocResponseJson.warn(ErrorEnum.NO_PERMISSION_TO_RESTORE_ARTICLE);
|
||||||
|
// }
|
||||||
|
// 执行恢复操作
|
||||||
|
WikiPage wikiPage = new WikiPage();
|
||||||
|
wikiPage.setId(pageId);
|
||||||
|
wikiPage.setDelFlag(0);
|
||||||
|
wikiPage.setName(wikiPageSel.getName());
|
||||||
|
wikiPage.setUpdateTime(new Date());
|
||||||
|
wikiPage.setUpdateUserId(currentUser.getUserId());
|
||||||
|
wikiPage.setUpdateUserName(currentUser.getUsername());
|
||||||
|
wikiPageService.updateById(wikiPage);
|
||||||
|
// 重置当前分支的所有节点seq值
|
||||||
|
wikiPageMapper.updateChildrenSeq(wikiPageSel.getSpaceId(), wikiPageSel.getParentId());
|
||||||
|
return DocResponseJson.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocResponseJson<Object> delete(PageDeleteParam param) {
|
||||||
|
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
||||||
|
WikiPage wikiPageSel = wikiPageService.getById(param.getPageId());
|
||||||
|
// 删除权限判断 TODO
|
||||||
|
WikiSpace wikiSpaceSel = wikiSpaceService.getById(wikiPageSel.getSpaceId());
|
||||||
|
// String canDelete = wikiPageAuthService.canDelete(wikiSpaceSel, wikiPageSel.getEditType(), wikiPageSel.getId(), currentUser.getUserId());
|
||||||
|
// if (canDelete != null) {
|
||||||
|
// return DocResponseJson.warn(canDelete);
|
||||||
|
// }
|
||||||
|
// 执行删除
|
||||||
|
WikiPage wikiPage = new WikiPage();
|
||||||
|
wikiPage.setId(param.getPageId());
|
||||||
|
wikiPage.setDelFlag(Optional.ofNullable(param.getDelFlag()).orElse(1));
|
||||||
|
wikiPage.setName(wikiPageSel.getName());
|
||||||
|
wikiPage.setUpdateTime(new Date());
|
||||||
|
wikiPage.setUpdateUserId(currentUser.getUserId());
|
||||||
|
wikiPage.setUpdateUserName(currentUser.getUsername());
|
||||||
|
wikiPageService.deletePage(wikiPage);
|
||||||
|
QueryWrapper<WikiPageTemplate> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("space_id", wikiPageSel.getSpaceId());
|
||||||
|
queryWrapper.eq("page_id", wikiPageSel.getId());
|
||||||
|
wikiPageTemplateService.remove(queryWrapper);
|
||||||
|
return DocResponseJson.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResponseJson<Object> recycleDelete(RecycleDeletePageParam param) {
|
||||||
|
String[] pageIdArr = StringUtils.split(param.getPageIds(), ",");
|
||||||
|
for (String pageId : pageIdArr) {
|
||||||
|
PageDeleteParam deleteParam = new PageDeleteParam();
|
||||||
|
deleteParam.setPageId(Long.valueOf(pageId));
|
||||||
|
deleteParam.setSpaceId(param.getSpaceId());
|
||||||
|
deleteParam.setDelFlag(2);
|
||||||
|
DocResponseJson<Object> restoreRes = this.delete(deleteParam);
|
||||||
|
if (!restoreRes.isOk()) {
|
||||||
|
return restoreRes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DocResponseJson.ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user