文档管理优化
This commit is contained in:
@@ -88,7 +88,7 @@ public class ApiDocumentController {
|
|||||||
*/
|
*/
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@PostMapping(value = "/add")
|
@PostMapping(value = "/add")
|
||||||
public ResponseJson<List<ApiDoc>> add(HttpServletRequest request, ApiDoc apiDoc) {
|
public ResponseJson<Object> add(HttpServletRequest request, ApiDoc apiDoc) {
|
||||||
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
||||||
apiDoc.setYn(1);
|
apiDoc.setYn(1);
|
||||||
apiDoc.setCreateTime(new Date());
|
apiDoc.setCreateTime(new Date());
|
||||||
@@ -145,7 +145,7 @@ public class ApiDocumentController {
|
|||||||
} else {
|
} else {
|
||||||
return DocResponseJson.warn("暂不支持的文档类型");
|
return DocResponseJson.warn("暂不支持的文档类型");
|
||||||
}
|
}
|
||||||
return DocResponseJson.ok();
|
return DocResponseJson.ok(apiDoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<DocManageList v-if="showView === 'list'" @showMembers="showMembers"></DocManageList>
|
<DocManageList v-if="showView === 'list'" @edit="editDoc"></DocManageList>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<DocManageMembers v-if="showView === 'members'" @showDocList="showDocList" :doc="docInfo"></DocManageMembers>
|
<DocManageEdit v-if="showView === 'edit'" @showDocList="showDocList" :doc="docInfo"></DocManageEdit>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { toRefs, ref, reactive, onMounted } from 'vue';
|
import { toRefs, ref, reactive, onMounted } from 'vue';
|
||||||
import DocManageList from "./DocManageList.vue";
|
import DocManageList from "./DocManageList.vue";
|
||||||
import DocManageMembers from "./DocManageMembers.vue";
|
import DocManageEdit from "./DocManageEdit.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {DocManageList, DocManageMembers},
|
components: {DocManageList, DocManageEdit},
|
||||||
setup() {
|
setup() {
|
||||||
let showView = ref('list');
|
let showView = ref('list');
|
||||||
let docInfo = ref({});
|
let docInfo = ref({});
|
||||||
const showMembers = (doc) => {
|
const editDoc = (type, doc) => {
|
||||||
docInfo.value = doc;
|
docInfo.value = doc;
|
||||||
showView.value = 'members';
|
showView.value = type;
|
||||||
};
|
};
|
||||||
const showDocList = () => {
|
const showDocList = () => {
|
||||||
showView.value = 'list';
|
showView.value = 'list';
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
return {
|
return {
|
||||||
showView,
|
showView,
|
||||||
docInfo,
|
docInfo,
|
||||||
showMembers,
|
editDoc,
|
||||||
showDocList,
|
showDocList,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
112
zyplayer-doc-ui/api-ui/src/views/manage/DocManageEdit.vue
Normal file
112
zyplayer-doc-ui/api-ui/src/views/manage/DocManageEdit.vue
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<template>
|
||||||
|
<a-page-header
|
||||||
|
title="编辑"
|
||||||
|
:sub-title="docEdit.name||''"
|
||||||
|
@back="showDocList">
|
||||||
|
<template #extra>
|
||||||
|
</template>
|
||||||
|
</a-page-header>
|
||||||
|
<a-tabs v-model:activeKey="activeEditTab" style="padding: 5px 10px 0;">
|
||||||
|
<a-tab-pane tab="基本信息" key="base" forceRender>
|
||||||
|
<a-spin tip="文档数据加载中..." :spinning="docEditLoading">
|
||||||
|
<EditDocBaseInfo ref="docBaseInfoRef" :doc="docEdit"></EditDocBaseInfo>
|
||||||
|
</a-spin>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane tab="成员管理" key="members">
|
||||||
|
<a-spin tip="文档数据加载中..." :spinning="docEditLoading">
|
||||||
|
<DocManageMembers :doc="docEdit"></DocManageMembers>
|
||||||
|
</a-spin>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane v-if="docEdit.openVisit === 1" tab="开放文档说明" key="instruction" forceRender>
|
||||||
|
<a-spin tip="文档数据加载中..." :spinning="docEditLoading">
|
||||||
|
<EditShareInstruction ref="shareInstructionRef" :doc="docEdit"></EditShareInstruction>
|
||||||
|
</a-spin>
|
||||||
|
</a-tab-pane>
|
||||||
|
<template #rightExtra>
|
||||||
|
<a-button v-if="activeEditTab==='base'" @click="saveBaseInfo" type="primary">
|
||||||
|
<template #icon><save-outlined /></template>
|
||||||
|
保存基本信息
|
||||||
|
</a-button>
|
||||||
|
<a-button v-if="activeEditTab==='instruction'" @click="saveShareInstruction" type="primary">
|
||||||
|
<template #icon><save-outlined /></template>
|
||||||
|
保存开放文档说明
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
</a-tabs>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { toRefs, ref, reactive, onMounted } from 'vue';
|
||||||
|
import {zyplayerApi} from '../../api';
|
||||||
|
import {useStore} from 'vuex';
|
||||||
|
import {getZyplayerApiBaseUrl} from "../../api/request/utils";
|
||||||
|
import {DownOutlined, LinkOutlined, SaveOutlined} from '@ant-design/icons-vue';
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import EditDocBaseInfo from "./components/EditDocBaseInfo.vue";
|
||||||
|
import EditShareInstruction from "./components/EditShareInstruction.vue";
|
||||||
|
import DocManageMembers from "./DocManageMembers.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
emits: ['showDocList'],
|
||||||
|
components: {DownOutlined, LinkOutlined, SaveOutlined, EditShareInstruction, EditDocBaseInfo, DocManageMembers},
|
||||||
|
props: {
|
||||||
|
doc: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props, {emit}) {
|
||||||
|
const store = useStore();
|
||||||
|
const showDocList = () => {
|
||||||
|
emit('showDocList');
|
||||||
|
}
|
||||||
|
let docBaseInfoRef = ref();
|
||||||
|
let shareInstructionRef = ref();
|
||||||
|
let docEdit = ref({});
|
||||||
|
let docEditLoading = ref(false);
|
||||||
|
const saveBaseInfo = async () => {
|
||||||
|
let docNew = await docBaseInfoRef.value.getDoc();
|
||||||
|
docEditLoading.value = true;
|
||||||
|
zyplayerApi.apiDocAdd(docNew).then(res => {
|
||||||
|
message.success('保存成功!');
|
||||||
|
docEditLoading.value = false;
|
||||||
|
store.commit('addDocChangedNum');
|
||||||
|
// 需要返回列表
|
||||||
|
if (res.data.id !== docNew.id) {
|
||||||
|
showDocList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const saveShareInstruction = () => {
|
||||||
|
let docNew = shareInstructionRef.value.getDoc();
|
||||||
|
if (!docNew) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
docEditLoading.value = true;
|
||||||
|
zyplayerApi.apiDocUpdate(docNew).then(res => {
|
||||||
|
message.success('保存成功!');
|
||||||
|
docEditLoading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
let activeEditTab = ref('base');
|
||||||
|
onMounted(() => {
|
||||||
|
docEdit.value = props.doc;
|
||||||
|
docEditLoading.value = true;
|
||||||
|
zyplayerApi.apiDocDetail({id: props.doc.id}).then(res => {
|
||||||
|
docEditLoading.value = false;
|
||||||
|
docEdit.value = res.data;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
activeEditTab,
|
||||||
|
showDocList,
|
||||||
|
saveBaseInfo,
|
||||||
|
saveShareInstruction,
|
||||||
|
docBaseInfoRef,
|
||||||
|
shareInstructionRef,
|
||||||
|
docEdit,
|
||||||
|
docEditLoading,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -34,7 +34,6 @@
|
|||||||
<template v-if="column.dataIndex === 'operation'">
|
<template v-if="column.dataIndex === 'operation'">
|
||||||
<a-button size="small" type="link" @click="editDoc(record)">编辑</a-button>
|
<a-button size="small" type="link" @click="editDoc(record)">编辑</a-button>
|
||||||
<template v-if="record.authType === 1">
|
<template v-if="record.authType === 1">
|
||||||
<a-button size="small" type="link" @click="showMembers(record)">成员管理</a-button>
|
|
||||||
<a-popconfirm title="确定要删除吗?" @confirm="deleteDoc(record)">
|
<a-popconfirm title="确定要删除吗?" @confirm="deleteDoc(record)">
|
||||||
<a-button size="small" type="link" danger>删除</a-button>
|
<a-button size="small" type="link" danger>删除</a-button>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
@@ -43,7 +42,6 @@
|
|||||||
<template #overlay>
|
<template #overlay>
|
||||||
<a-menu @click="handleActionMenuClick($event, record)">
|
<a-menu @click="handleActionMenuClick($event, record)">
|
||||||
<a-menu-item key="shareView"><link-outlined /> 查看开放文档</a-menu-item>
|
<a-menu-item key="shareView"><link-outlined /> 查看开放文档</a-menu-item>
|
||||||
<a-menu-item key="shareInstruction"><edit-outlined /> 编辑开放文档说明</a-menu-item>
|
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</template>
|
</template>
|
||||||
<a-button type="link" size="small">更多<DownOutlined /></a-button>
|
<a-button type="link" size="small">更多<DownOutlined /></a-button>
|
||||||
@@ -64,110 +62,9 @@
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
<a-modal v-model:visible="newDocVisible" :title="docEdit.isNew?'新增文档':'编辑文档'" @ok="handleNewDocOk" :width="800">
|
<a-modal v-model:visible="newDocVisible" :title="docEdit.isNew?'新增文档':'编辑文档'" @ok="handleNewDocOk" :width="850">
|
||||||
<a-form layout="horizontal" ref="newDocFormRef" :rules="newDocRules" :model="docEdit" :label-col="{span: 4}" :wrapper-col="{span: 20}">
|
<EditDocBaseInfo :doc="docEdit"></EditDocBaseInfo>
|
||||||
<a-form-item label="文档名称" required name="name">
|
|
||||||
<a-input placeholder="请输入文档名称" v-model:value="docEdit.name"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="文档类型" required name="docType">
|
|
||||||
<a-radio-group v-model:value="docEdit.docType">
|
|
||||||
<a-radio :value="1">Swagger URL</a-radio>
|
|
||||||
<a-radio :value="2">Swagger JSON</a-radio>
|
|
||||||
<a-radio :value="3">OpenApi URL</a-radio>
|
|
||||||
<a-radio :value="4">OpenApi JSON</a-radio>
|
|
||||||
<a-radio :value="5" disabled>自建API</a-radio>
|
|
||||||
</a-radio-group>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="文档地址" required name="docUrl" v-if="docEdit.docType === 1">
|
|
||||||
<a-input placeholder="请输入文档地址URL" v-model:value="docEdit.docUrl"></a-input>
|
|
||||||
<template #extra>
|
|
||||||
查看文档地址
|
|
||||||
<a-popover title="文档地址支持以下任一格式">
|
|
||||||
<template #content>
|
|
||||||
<p>格式一:http://doc.zyplayer.com/v2/api-docs</p>
|
|
||||||
<p>格式二:http://doc.zyplayer.com/swagger-resources</p>
|
|
||||||
<p>格式三:http://doc.zyplayer.com/swagger-ui.html</p>
|
|
||||||
</template>
|
|
||||||
<a>示例</a>
|
|
||||||
</a-popover>
|
|
||||||
</template>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="文档内容" required name="jsonContent" v-else-if="docEdit.docType === 2">
|
|
||||||
<!-- textarea在内容很多的时候(>300KB)会卡顿,ace不会-->
|
|
||||||
<ace-editor v-model:value="docEdit.jsonContent" lang="json" theme="monokai" width="100%" height="100" :options="aceEditorConfig"></ace-editor>
|
|
||||||
<!-- <a-textarea placeholder="请输入JSON格式的Swagger文档内容" v-model:value="docEdit.jsonContent" :auto-size="{ minRows: 5, maxRows: 10 }"></a-textarea>-->
|
|
||||||
<template #extra>
|
|
||||||
查看文档内容
|
|
||||||
<a-popover title="文档内容说明">
|
|
||||||
<template #content>
|
|
||||||
<div>支持以下格式的Swagger文档内容输入,其中 {"swagger": "2.0"} 为必要属性</div>
|
|
||||||
<div v-highlight>
|
|
||||||
<pre><code class="lang-json">{{swaggerDocDemo}}</code></pre>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<a>说明</a>
|
|
||||||
</a-popover>
|
|
||||||
</template>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="文档地址" required name="docUrl" v-if="docEdit.docType === 3">
|
|
||||||
<a-input placeholder="请输入文档地址URL" v-model:value="docEdit.docUrl"></a-input>
|
|
||||||
<template #extra>
|
|
||||||
查看文档地址
|
|
||||||
<a-popover title="文档地址支持以下任一格式">
|
|
||||||
<template #content>
|
|
||||||
<p>格式一:http://doc.zyplayer.com/v3/api-docs</p>
|
|
||||||
</template>
|
|
||||||
<a>示例</a>
|
|
||||||
</a-popover>
|
|
||||||
</template>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="文档内容" required name="jsonContent" v-else-if="docEdit.docType === 4">
|
|
||||||
<ace-editor v-model:value="docEdit.jsonContent" lang="json" theme="monokai" width="100%" height="100" :options="aceEditorConfig"></ace-editor>
|
|
||||||
<!-- <a-textarea placeholder="请输入JSON格式的OpenApi文档内容" v-model:value="docEdit.jsonContent" :auto-size="{ minRows: 5, maxRows: 10 }"></a-textarea>-->
|
|
||||||
<template #extra>
|
|
||||||
查看文档内容
|
|
||||||
<a-popover title="文档内容说明">
|
|
||||||
<template #content>
|
|
||||||
<div>支持以下格式的OpenApi文档内容输入,其中 {"openapi": "3.x.x"} 为必要属性</div>
|
|
||||||
<div v-highlight>
|
|
||||||
<pre><code class="lang-json">{{openApiDocDemo}}</code></pre>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<a>说明</a>
|
|
||||||
</a-popover>
|
|
||||||
</template>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="目标域名" name="rewriteDomain">
|
|
||||||
<a-input placeholder="请输入目标域名" v-model:value="docEdit.rewriteDomain"></a-input>
|
|
||||||
<template #extra>
|
|
||||||
目标域名
|
|
||||||
<a-popover title="目标域名说明">
|
|
||||||
<template #content>
|
|
||||||
<p>在文档的在线调试界面,访问的域名可以初始为此处录入的域名,而非文档本身的域名地址</p>
|
|
||||||
<p>可便于不同环境间的接口测试,例:http://doc.zyplayer.com</p>
|
|
||||||
</template>
|
|
||||||
<a>说明</a>
|
|
||||||
</a-popover>
|
|
||||||
</template>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="开放访问" required name="openVisit">
|
|
||||||
<a-radio-group v-model:value="docEdit.openVisit">
|
|
||||||
<a-radio :value="0">否</a-radio>
|
|
||||||
<a-radio :value="1">开放访问</a-radio>
|
|
||||||
</a-radio-group>
|
|
||||||
<template #extra>
|
|
||||||
开放访问后无需登录即可通过<a @click="openShareViewWindow(docEdit)">开放文档URL</a>访问该文档信息
|
|
||||||
</template>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="状态" required name="docStatus">
|
|
||||||
<a-radio-group v-model:value="docEdit.docStatus">
|
|
||||||
<a-radio :value="1">启用</a-radio>
|
|
||||||
<a-radio :value="2">禁用</a-radio>
|
|
||||||
</a-radio-group>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</a-modal>
|
</a-modal>
|
||||||
<EditShareInstruction ref="instruction"></EditShareInstruction>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -175,14 +72,14 @@
|
|||||||
import {zyplayerApi} from '../../api';
|
import {zyplayerApi} from '../../api';
|
||||||
import {useStore} from 'vuex';
|
import {useStore} from 'vuex';
|
||||||
import aceEditor from "../../assets/ace-editor";
|
import aceEditor from "../../assets/ace-editor";
|
||||||
import EditShareInstruction from "./components/EditShareInstruction.vue";
|
import EditDocBaseInfo from "./components/EditDocBaseInfo.vue";
|
||||||
import {getZyplayerApiBaseUrl} from "../../api/request/utils";
|
import {getZyplayerApiBaseUrl} from "../../api/request/utils";
|
||||||
import {DownOutlined, LinkOutlined, EditOutlined} from '@ant-design/icons-vue';
|
import {DownOutlined, LinkOutlined, EditOutlined} from '@ant-design/icons-vue';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
emits: ['showMembers'],
|
emits: ['edit'],
|
||||||
components: {aceEditor, EditShareInstruction, DownOutlined, LinkOutlined, EditOutlined},
|
components: {aceEditor, DownOutlined, LinkOutlined, EditOutlined, EditDocBaseInfo},
|
||||||
setup(props, {emit}) {
|
setup(props, {emit}) {
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
let docList = ref([]);
|
let docList = ref([]);
|
||||||
@@ -217,9 +114,9 @@
|
|||||||
const handleNewDocOk = async () => {
|
const handleNewDocOk = async () => {
|
||||||
newDocFormRef.value.validate().then(() => {
|
newDocFormRef.value.validate().then(() => {
|
||||||
zyplayerApi.apiDocAdd(docEdit.value).then(res => {
|
zyplayerApi.apiDocAdd(docEdit.value).then(res => {
|
||||||
searchDocList();
|
|
||||||
newDocVisible.value = false;
|
newDocVisible.value = false;
|
||||||
store.commit('addDocChangedNum');
|
store.commit('addDocChangedNum');
|
||||||
|
emit('edit', 'edit', res.data);
|
||||||
});
|
});
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.log('error', error);
|
console.log('error', error);
|
||||||
@@ -231,14 +128,12 @@
|
|||||||
docType: 1, openVisit: 0, docStatus: 1, isNew: 1
|
docType: 1, openVisit: 0, docStatus: 1, isNew: 1
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
const showMembers = (record) => {
|
|
||||||
emit('showMembers', record);
|
|
||||||
};
|
|
||||||
const editDoc = (record) => {
|
const editDoc = (record) => {
|
||||||
zyplayerApi.apiDocDetail({id: record.id}).then(res => {
|
emit('edit', 'edit', record);
|
||||||
docEdit.value = res.data;
|
// zyplayerApi.apiDocDetail({id: record.id}).then(res => {
|
||||||
newDocVisible.value = true;
|
// docEdit.value = res.data;
|
||||||
});
|
// newDocVisible.value = true;
|
||||||
|
// });
|
||||||
};
|
};
|
||||||
const updateDoc = async (id, docStatus, yn) => {
|
const updateDoc = async (id, docStatus, yn) => {
|
||||||
zyplayerApi.apiDocUpdate({id, docStatus, yn}).then(res => {
|
zyplayerApi.apiDocUpdate({id, docStatus, yn}).then(res => {
|
||||||
@@ -260,11 +155,8 @@
|
|||||||
const handleActionMenuClick = (item, record) => {
|
const handleActionMenuClick = (item, record) => {
|
||||||
if (item.key === 'shareView') {
|
if (item.key === 'shareView') {
|
||||||
openShareViewWindow(record);
|
openShareViewWindow(record);
|
||||||
} else if (item.key === 'shareInstruction') {
|
|
||||||
instruction.value.editDoc(record.id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let instruction = ref();
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
searchDocList();
|
searchDocList();
|
||||||
});
|
});
|
||||||
@@ -280,12 +172,10 @@
|
|||||||
handleNewDocOk,
|
handleNewDocOk,
|
||||||
deleteDoc,
|
deleteDoc,
|
||||||
editDoc,
|
editDoc,
|
||||||
showMembers,
|
|
||||||
handleTableChange,
|
handleTableChange,
|
||||||
openShareViewWindow,
|
openShareViewWindow,
|
||||||
handleActionMenuClick,
|
handleActionMenuClick,
|
||||||
pagination,
|
pagination,
|
||||||
instruction,
|
|
||||||
newDocRules: {
|
newDocRules: {
|
||||||
name: [{required: true, message: '请输入文档名称', trigger: 'change'}],
|
name: [{required: true, message: '请输入文档名称', trigger: 'change'}],
|
||||||
docUrl: [{required: true, message: '请输入文档地址', trigger: 'change'}],
|
docUrl: [{required: true, message: '请输入文档地址', trigger: 'change'}],
|
||||||
@@ -302,35 +192,8 @@
|
|||||||
{title: '状态', dataIndex: 'docStatus', width: 90},
|
{title: '状态', dataIndex: 'docStatus', width: 90},
|
||||||
{title: '文档地址', dataIndex: 'docUrl'},
|
{title: '文档地址', dataIndex: 'docUrl'},
|
||||||
{title: '目标域名', dataIndex: 'rewriteDomain', width: 250},
|
{title: '目标域名', dataIndex: 'rewriteDomain', width: 250},
|
||||||
{title: '操作', dataIndex: 'operation', fixed: 'right', width: 280},
|
{title: '操作', dataIndex: 'operation', fixed: 'right', width: 200},
|
||||||
],
|
],
|
||||||
aceEditorConfig: {
|
|
||||||
wrap: true,
|
|
||||||
autoScrollEditorIntoView: true,
|
|
||||||
enableBasicAutocompletion: true,
|
|
||||||
enableSnippets: true,
|
|
||||||
enableLiveAutocompletion: true,
|
|
||||||
minLines: 10,
|
|
||||||
maxLines: 15,
|
|
||||||
},
|
|
||||||
swaggerDocDemo:
|
|
||||||
'{\n'
|
|
||||||
+ ' "swagger": "2.0",\n'
|
|
||||||
+ ' "info": {},\n'
|
|
||||||
+ ' "host": "doc.zyplayer.com",\n'
|
|
||||||
+ ' "basePath":"/",\n'
|
|
||||||
+ ' "tags": [],\n'
|
|
||||||
+ ' "paths": {},\n'
|
|
||||||
+ ' "definitions": {}\n'
|
|
||||||
+ '}',
|
|
||||||
openApiDocDemo:
|
|
||||||
'{\n'
|
|
||||||
+ ' "openapi": "3.0.3",\n'
|
|
||||||
+ ' "components": {}\n'
|
|
||||||
+ ' "servers": [],\n'
|
|
||||||
+ ' "paths": {},\n'
|
|
||||||
+ ' "info": {},\n'
|
|
||||||
+ '}',
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-page-header
|
<div style="text-align: right;margin: 0 10px 10px 0;">
|
||||||
title="成员管理"
|
<a-button @click="searchDocMemberList" type="primary">查询</a-button>
|
||||||
:sub-title="doc.name||''"
|
<a-button @click="openAddDocMember" :style="{ marginLeft: '8px' }">添加用户</a-button>
|
||||||
@back="showDocList">
|
</div>
|
||||||
<template #extra>
|
|
||||||
<a-button @click="searchDocMemberList" type="primary">查询</a-button>
|
|
||||||
<a-button @click="openAddDocMember" :style="{ marginLeft: '8px' }">添加用户</a-button>
|
|
||||||
</template>
|
|
||||||
</a-page-header>
|
|
||||||
<a-table :dataSource="docMemberList" :columns="docListColumns" size="middle"
|
<a-table :dataSource="docMemberList" :columns="docListColumns" size="middle"
|
||||||
:loading="docMemberListLoading" :pagination="false"
|
:loading="docMemberListLoading" :pagination="false"
|
||||||
@change="handleTableChange"
|
@change="handleTableChange"
|
||||||
@@ -61,7 +56,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { toRefs, ref, reactive, onMounted } from 'vue';
|
import { toRefs, ref, reactive, onMounted, watch } from 'vue';
|
||||||
import {zyplayerApi} from '../../api';
|
import {zyplayerApi} from '../../api';
|
||||||
import {useStore} from 'vuex';
|
import {useStore} from 'vuex';
|
||||||
import {getZyplayerApiBaseUrl} from "../../api/request/utils";
|
import {getZyplayerApiBaseUrl} from "../../api/request/utils";
|
||||||
@@ -79,6 +74,9 @@
|
|||||||
},
|
},
|
||||||
setup(props, {emit}) {
|
setup(props, {emit}) {
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
// watch(() => props.doc, () => {
|
||||||
|
// searchDocMemberList();
|
||||||
|
// });
|
||||||
let docMemberList = ref([]);
|
let docMemberList = ref([]);
|
||||||
let docMemberListLoading = ref(false);
|
let docMemberListLoading = ref(false);
|
||||||
let searchParam = ref({docId: '', pageNum: 1, pageSize: 20});
|
let searchParam = ref({docId: '', pageNum: 1, pageSize: 20});
|
||||||
@@ -98,7 +96,10 @@
|
|||||||
searchParam.value.pageSize = paginationNew.pageSize;
|
searchParam.value.pageSize = paginationNew.pageSize;
|
||||||
searchDocMemberList();
|
searchDocMemberList();
|
||||||
};
|
};
|
||||||
const searchDocMemberList = async () => {
|
const searchDocMemberList = async () => {
|
||||||
|
if (!props.doc.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
docMemberListLoading.value = true;
|
docMemberListLoading.value = true;
|
||||||
searchParam.value.docId = props.doc.id;
|
searchParam.value.docId = props.doc.id;
|
||||||
zyplayerApi.docAuthList(searchParam.value).then(res => {
|
zyplayerApi.docAuthList(searchParam.value).then(res => {
|
||||||
|
|||||||
@@ -0,0 +1,212 @@
|
|||||||
|
<template>
|
||||||
|
<a-form layout="horizontal" ref="newDocFormRef" :rules="newDocRules" :model="docEdit" :label-col="{span: 4}" :wrapper-col="{span: 18}">
|
||||||
|
<a-form-item label="文档名称" required name="name">
|
||||||
|
<a-input placeholder="请输入文档名称" v-model:value="docEdit.name"></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="文档类型" required name="docType">
|
||||||
|
<a-radio-group v-model:value="docEdit.docType">
|
||||||
|
<a-radio :value="1">Swagger URL</a-radio>
|
||||||
|
<a-radio :value="2">Swagger JSON</a-radio>
|
||||||
|
<a-radio :value="3">OpenApi URL</a-radio>
|
||||||
|
<a-radio :value="4">OpenApi JSON</a-radio>
|
||||||
|
<a-radio :value="5" disabled>自建API</a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="文档地址" required name="docUrl" v-if="docEdit.docType === 1">
|
||||||
|
<a-input placeholder="请输入文档地址URL" v-model:value="docEdit.docUrl"></a-input>
|
||||||
|
<template #extra>
|
||||||
|
查看文档地址
|
||||||
|
<a-popover title="文档地址支持以下任一格式">
|
||||||
|
<template #content>
|
||||||
|
<p>格式一:http://doc.zyplayer.com/v2/api-docs</p>
|
||||||
|
<p>格式二:http://doc.zyplayer.com/swagger-resources</p>
|
||||||
|
<p>格式三:http://doc.zyplayer.com/swagger-ui.html</p>
|
||||||
|
</template>
|
||||||
|
<a>示例</a>
|
||||||
|
</a-popover>
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="文档内容" required name="jsonContent" v-else-if="docEdit.docType === 2">
|
||||||
|
<!-- textarea在内容很多的时候(>300KB)会卡顿,ace不会-->
|
||||||
|
<ace-editor v-model:value="docEdit.jsonContent" lang="json" theme="monokai" width="100%" height="100" :options="aceEditorConfig"></ace-editor>
|
||||||
|
<!-- <a-textarea placeholder="请输入JSON格式的Swagger文档内容" v-model:value="docEdit.jsonContent" :auto-size="{ minRows: 5, maxRows: 10 }"></a-textarea>-->
|
||||||
|
<template #extra>
|
||||||
|
查看文档内容
|
||||||
|
<a-popover title="文档内容说明">
|
||||||
|
<template #content>
|
||||||
|
<div>支持以下格式的Swagger文档内容输入,其中 {"swagger": "2.0"} 为必要属性</div>
|
||||||
|
<div v-highlight>
|
||||||
|
<pre><code class="lang-json">{{swaggerDocDemo}}</code></pre>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<a>说明</a>
|
||||||
|
</a-popover>
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="文档地址" required name="docUrl" v-if="docEdit.docType === 3">
|
||||||
|
<a-input placeholder="请输入文档地址URL" v-model:value="docEdit.docUrl"></a-input>
|
||||||
|
<template #extra>
|
||||||
|
查看文档地址
|
||||||
|
<a-popover title="文档地址支持以下任一格式">
|
||||||
|
<template #content>
|
||||||
|
<p>格式一:http://doc.zyplayer.com/v3/api-docs</p>
|
||||||
|
</template>
|
||||||
|
<a>示例</a>
|
||||||
|
</a-popover>
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="文档内容" required name="jsonContent" v-else-if="docEdit.docType === 4">
|
||||||
|
<ace-editor v-model:value="docEdit.jsonContent" lang="json" theme="monokai" width="100%" height="100" :options="aceEditorConfig"></ace-editor>
|
||||||
|
<!-- <a-textarea placeholder="请输入JSON格式的OpenApi文档内容" v-model:value="docEdit.jsonContent" :auto-size="{ minRows: 5, maxRows: 10 }"></a-textarea>-->
|
||||||
|
<template #extra>
|
||||||
|
查看文档内容
|
||||||
|
<a-popover title="文档内容说明">
|
||||||
|
<template #content>
|
||||||
|
<div>支持以下格式的OpenApi文档内容输入,其中 {"openapi": "3.x.x"} 为必要属性</div>
|
||||||
|
<div v-highlight>
|
||||||
|
<pre><code class="lang-json">{{openApiDocDemo}}</code></pre>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<a>说明</a>
|
||||||
|
</a-popover>
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="目标域名" name="rewriteDomain">
|
||||||
|
<a-input placeholder="请输入目标域名" v-model:value="docEdit.rewriteDomain"></a-input>
|
||||||
|
<template #extra>
|
||||||
|
目标域名
|
||||||
|
<a-popover title="目标域名说明">
|
||||||
|
<template #content>
|
||||||
|
<p>在文档的在线调试界面,访问的域名可以初始为此处录入的域名,而非文档本身的域名地址</p>
|
||||||
|
<p>可便于不同环境间的接口测试,例:http://doc.zyplayer.com</p>
|
||||||
|
</template>
|
||||||
|
<a>说明</a>
|
||||||
|
</a-popover>
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="开放访问" required name="openVisit">
|
||||||
|
<a-radio-group v-model:value="docEdit.openVisit">
|
||||||
|
<a-radio :value="0">否</a-radio>
|
||||||
|
<a-radio :value="1">开放访问</a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
<template #extra>
|
||||||
|
开放访问后无需登录即可通过<a @click="openShareViewWindow(docEdit)">开放文档URL</a>访问该文档信息
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="状态" required name="docStatus">
|
||||||
|
<a-radio-group v-model:value="docEdit.docStatus">
|
||||||
|
<a-radio :value="1">启用</a-radio>
|
||||||
|
<a-radio :value="2">禁用</a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { toRefs, ref, reactive, onMounted, watch } from 'vue';
|
||||||
|
import {zyplayerApi} from '../../../api';
|
||||||
|
import {useStore} from 'vuex';
|
||||||
|
import aceEditor from "../../../assets/ace-editor";
|
||||||
|
import EditShareInstruction from "../components/EditShareInstruction.vue";
|
||||||
|
import {getZyplayerApiBaseUrl} from "../../../api/request/utils";
|
||||||
|
import {DownOutlined, LinkOutlined, EditOutlined} from '@ant-design/icons-vue';
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
emits: ['edit'],
|
||||||
|
components: {aceEditor, EditShareInstruction, DownOutlined, LinkOutlined, EditOutlined},
|
||||||
|
props: {
|
||||||
|
doc: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props, {emit}) {
|
||||||
|
const store = useStore();
|
||||||
|
let docEdit = ref({});
|
||||||
|
let newDocFormRef = ref();
|
||||||
|
watch(() => props.doc, () => {
|
||||||
|
editDoc();
|
||||||
|
});
|
||||||
|
const handleNewDocOk = async () => {
|
||||||
|
newDocFormRef.value.validate().then(() => {
|
||||||
|
zyplayerApi.apiDocAdd(docEdit.value).then(res => {
|
||||||
|
// searchDocList();
|
||||||
|
store.commit('addDocChangedNum');
|
||||||
|
});
|
||||||
|
}).catch(error => {
|
||||||
|
console.log('error', error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const editDoc = () => {
|
||||||
|
docEdit.value = props.doc;
|
||||||
|
};
|
||||||
|
const getDoc = async () => {
|
||||||
|
await newDocFormRef.value.validate();
|
||||||
|
return docEdit.value;
|
||||||
|
};
|
||||||
|
const updateDoc = async (id, docStatus, yn) => {
|
||||||
|
zyplayerApi.apiDocUpdate({id, docStatus, yn}).then(res => {
|
||||||
|
// searchDocList();
|
||||||
|
store.commit('addDocChangedNum');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 打开开放文档新窗口
|
||||||
|
const openShareViewWindow = record => {
|
||||||
|
if (!record.shareUuid) {
|
||||||
|
message.warning('请先保存文档后再试');
|
||||||
|
} else if (record.openVisit !== 1) {
|
||||||
|
message.warning('该文档尚未开启开放访问功能,请在编辑页选择开放后再试');
|
||||||
|
} else {
|
||||||
|
window.open(getZyplayerApiBaseUrl() + '/doc-api#/share/home?uuid=' + record.shareUuid);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
editDoc();
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
docEdit,
|
||||||
|
newDocFormRef,
|
||||||
|
handleNewDocOk,
|
||||||
|
editDoc,
|
||||||
|
getDoc,
|
||||||
|
openShareViewWindow,
|
||||||
|
newDocRules: {
|
||||||
|
name: [{required: true, message: '请输入文档名称', trigger: 'change'}],
|
||||||
|
docUrl: [{required: true, message: '请输入文档地址', trigger: 'change'}],
|
||||||
|
jsonContent: [{required: true, message: '请输入JSON格式的swagger文档内容', trigger: 'change'}],
|
||||||
|
docType: [{type: 'number', required: true, message: '请选择文档类型', trigger: 'change'}],
|
||||||
|
openVisit: [{type: 'number', required: true, message: '请选择是否开放访问', trigger: 'change'}],
|
||||||
|
docStatus: [{type: 'number', required: true, message: '请选择文档状态', trigger: 'change'}],
|
||||||
|
},
|
||||||
|
aceEditorConfig: {
|
||||||
|
wrap: true,
|
||||||
|
autoScrollEditorIntoView: true,
|
||||||
|
enableBasicAutocompletion: true,
|
||||||
|
enableSnippets: true,
|
||||||
|
enableLiveAutocompletion: true,
|
||||||
|
minLines: 10,
|
||||||
|
maxLines: 15,
|
||||||
|
},
|
||||||
|
swaggerDocDemo:
|
||||||
|
'{\n'
|
||||||
|
+ ' "swagger": "2.0",\n'
|
||||||
|
+ ' "info": {},\n'
|
||||||
|
+ ' "host": "doc.zyplayer.com",\n'
|
||||||
|
+ ' "basePath":"/",\n'
|
||||||
|
+ ' "tags": [],\n'
|
||||||
|
+ ' "paths": {},\n'
|
||||||
|
+ ' "definitions": {}\n'
|
||||||
|
+ '}',
|
||||||
|
openApiDocDemo:
|
||||||
|
'{\n'
|
||||||
|
+ ' "openapi": "3.0.3",\n'
|
||||||
|
+ ' "components": {}\n'
|
||||||
|
+ ' "servers": [],\n'
|
||||||
|
+ ' "paths": {},\n'
|
||||||
|
+ ' "info": {},\n'
|
||||||
|
+ '}',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -1,53 +1,50 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-modal v-model:visible="editShareInstructionVisible" @ok="handleNewDocOk" width="90%"
|
<mavon-editor ref="mavonEditor" v-model="shareInstruction" :toolbars="toolbars"
|
||||||
:bodyStyle="{height: 'calc(100vh - 300px)'}">
|
:externalLink="false" @imgAdd="addMarkdownImage" :imageFilter="imageFilter"
|
||||||
<template #title>
|
style="height: 100%;"
|
||||||
编辑开放文档说明
|
placeholder="请录入开放文档说明"/>
|
||||||
<a-tooltip placement="bottom">
|
|
||||||
<template #title>此说明文档将展示在开放文档的首页展示,可点击‘查看开放文档’查看效果</template>
|
|
||||||
<info-circle-outlined />
|
|
||||||
</a-tooltip>
|
|
||||||
</template>
|
|
||||||
<mavon-editor ref="mavonEditor" v-model="shareInstruction" :toolbars="toolbars"
|
|
||||||
:externalLink="false" @imgAdd="addMarkdownImage" :imageFilter="imageFilter"
|
|
||||||
style="height: 100%;"
|
|
||||||
placeholder="请录入开放文档说明"/>
|
|
||||||
</a-modal>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { toRefs, ref, reactive, onMounted, nextTick } from 'vue';
|
import { toRefs, ref, reactive, onMounted, nextTick, watch } from 'vue';
|
||||||
import {zyplayerApi} from '../../../api';
|
import {zyplayerApi} from '../../../api';
|
||||||
import {useStore} from 'vuex';
|
import {useStore} from 'vuex';
|
||||||
import aceEditor from "../../../assets/ace-editor";
|
import aceEditor from "../../../assets/ace-editor";
|
||||||
import {getZyplayerApiBaseUrl} from "../../../api/request/utils";
|
import {getZyplayerApiBaseUrl} from "../../../api/request/utils";
|
||||||
import {BranchesOutlined, InfoCircleOutlined} from '@ant-design/icons-vue';
|
import {BranchesOutlined, InfoCircleOutlined} from '@ant-design/icons-vue';
|
||||||
import {mavonEditor, markdownIt} from 'mavon-editor'
|
import {mavonEditor, markdownIt} from 'mavon-editor'
|
||||||
|
import 'mavon-editor/dist/markdown/github-markdown.min.css'
|
||||||
|
import 'mavon-editor/dist/css/index.css'
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {aceEditor, BranchesOutlined, mavonEditor, InfoCircleOutlined},
|
components: {aceEditor, BranchesOutlined, mavonEditor, InfoCircleOutlined},
|
||||||
setup() {
|
props: {
|
||||||
|
doc: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props, {emit}) {
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
let docEdit = ref({});
|
let docEdit = ref({});
|
||||||
let shareInstruction = ref('');
|
let shareInstruction = ref('');
|
||||||
let editShareInstructionVisible = ref(false);
|
watch(() => props.doc, () => {
|
||||||
const handleNewDocOk = async () => {
|
editDoc();
|
||||||
|
});
|
||||||
|
const getDoc = () => {
|
||||||
if (!shareInstruction.value) {
|
if (!shareInstruction.value) {
|
||||||
message.error('请输入开放文档的说明');
|
message.error('请输入开放文档的说明');
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
zyplayerApi.apiDocUpdate({id: docEdit.value.id, shareInstruction: shareInstruction.value}).then(res => {
|
return {
|
||||||
editShareInstructionVisible.value = false;
|
id: docEdit.value.id,
|
||||||
message.success('保存成功!');
|
shareInstruction: shareInstruction.value
|
||||||
});
|
};
|
||||||
};
|
};
|
||||||
const editDoc = async (id) => {
|
const editDoc = async () => {
|
||||||
editShareInstructionVisible.value = true;
|
docEdit.value = props.doc;
|
||||||
zyplayerApi.apiDocDetail({id: id}).then(res => {
|
shareInstruction.value = props.doc.shareInstruction;
|
||||||
docEdit.value = res.data;
|
|
||||||
shareInstruction.value = res.data.shareInstruction;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
const addMarkdownImage = (pos, file) => {
|
const addMarkdownImage = (pos, file) => {
|
||||||
};
|
};
|
||||||
@@ -56,12 +53,12 @@
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
editDoc();
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
editShareInstructionVisible,
|
|
||||||
docEdit,
|
docEdit,
|
||||||
shareInstruction,
|
shareInstruction,
|
||||||
handleNewDocOk,
|
getDoc,
|
||||||
editDoc,
|
editDoc,
|
||||||
imageFilter,
|
imageFilter,
|
||||||
addMarkdownImage,
|
addMarkdownImage,
|
||||||
@@ -89,7 +86,7 @@
|
|||||||
trash: true, // 清空
|
trash: true, // 清空
|
||||||
save: true, // 保存(触发events中的save事件)
|
save: true, // 保存(触发events中的save事件)
|
||||||
/* 1.4.2 */
|
/* 1.4.2 */
|
||||||
navigation: true, // 导航目录
|
navigation: false, // 导航目录
|
||||||
/* 2.1.8 */
|
/* 2.1.8 */
|
||||||
alignleft: true, // 左对齐
|
alignleft: true, // 左对齐
|
||||||
aligncenter: true, // 居中
|
aligncenter: true, // 居中
|
||||||
|
|||||||
Reference in New Issue
Block a user