This commit is contained in:
六如
2024-11-25 00:18:47 +08:00
parent ba384660f1
commit 5e2c3fab46
37 changed files with 939 additions and 86 deletions

View File

@@ -48,6 +48,7 @@
"url": "https://github.com/xiaoxian521"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@pureadmin/descriptions": "1.2.1",
"@pureadmin/table": "3.2.0",
"@pureadmin/utils": "2.4.8",

View File

@@ -8,6 +8,9 @@ importers:
.:
dependencies:
'@element-plus/icons-vue':
specifier: ^2.3.1
version: 2.3.1(vue@3.4.38(typescript@5.5.4))
'@pureadmin/descriptions':
specifier: 1.2.1
version: 1.2.1(echarts@5.5.1)(element-plus@2.8.0(vue@3.4.38(typescript@5.5.4)))(typescript@5.5.4)

View File

@@ -4,7 +4,9 @@ import type { Result } from "@/model";
// 后端请求接口
const apiUrl: any = createUrl({
addApp: "/doc/app/add",
listApp: "/doc/app/list"
listApp: "/doc/app/list",
listDocTree: "/doc/info/tree",
publish: "/doc/info/publish"
});
interface DocApp {
@@ -28,5 +30,19 @@ export const api: any = {
*/
addApp(data: object) {
return http.post<Result<any>, any>(apiUrl.addApp, { data });
},
/**
* 发布
* @param data 表单内容
*/
publish(data: object) {
return http.post<Result<any>, any>(apiUrl.publish, { data });
},
/**
* 查询文档树
* @param data
*/
listDocTree(params: object) {
return http.get<Result<Array<any>>, any>(apiUrl.listDocTree, { params });
}
};

View File

@@ -75,3 +75,9 @@ getPlatformConfig(app).then(async config => {
// .use(useEcharts);
app.mount("#app");
});
// element-plus icon
import * as ElementPlusIconsVue from "@element-plus/icons-vue";
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component);
}

View File

@@ -1,6 +1,12 @@
import { ref } from "vue";
import { computed, ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { api } from "@/api/doc";
import {
type ButtonsCallBackParams,
type PlusColumn,
useTable
} from "plus-pro-components";
import { YesOrNoEnum } from "@/model/enums";
export const tabsData = ref<Array<any>>([
{
@@ -10,9 +16,163 @@ export const tabsData = ref<Array<any>>([
]);
export const activeName = ref(0);
const docAppId = ref(0);
// 表格对象
export const { tableData, buttons: actionButtons } = useTable<any[]>();
export const filterText = ref("");
export const tableRows = computed(() => {
let search = filterText.value;
if (!search) {
return tableData.value;
}
search = search.toLowerCase();
return searchRow(search, tableData.value, searchContent, isFolder);
});
const isFolder = row => {
return row.isFolder === 1;
};
const searchContent = (searchText, row) => {
return (
(row.docName && row.docName.toLowerCase().indexOf(searchText) > -1) ||
(row.docTitle && row.docTitle.toLowerCase().indexOf(searchText) > -1)
);
};
// 表格字段定义
export const tableColumns: PlusColumn[] = [
{
label: "文档标题",
prop: "docTitle"
},
{
label: "接口名",
prop: "docName"
},
{
label: "版本号",
prop: "docVersion"
},
{
label: "描述",
prop: "description"
},
{
label: "发布状态",
prop: "isPublish",
valueType: "select",
width: 100,
options: [
{
label: "已发布",
value: YesOrNoEnum.YES,
color: "green"
},
{
label: "未发布",
value: YesOrNoEnum.NO,
color: "red"
}
],
renderHTML: (value, { row }) => {
if (row.isFolder) {
return "";
}
return value
? `<div style="color:green;">已发布</div>`
: `<div style="color:gray;">未发布</div>`;
}
},
{
width: 160,
label: "添加时间",
prop: "addTime"
},
{
width: 160,
label: "修改时间",
prop: "updateTime"
}
];
// 表格按钮定义
actionButtons.value = [
{
text: row => (row.isPublish ? "下线" : "发布"),
confirm: {
options: { draggable: false },
popconfirmProps: { width: 300 },
message: params => {
const row = params.row;
const opt = row.isPublish ? "下线" : "发布";
const isFolder = row.isFolder;
return isFolder === 1
? `确定要${opt}[${row.docTitle}]下所有接口吗?`
: `确定要${opt}[${row.docTitle}]吗?`;
}
},
props: (row: any) => ({
type: row.isPublish === 1 ? "danger" : "success"
}),
onConfirm(params: ButtonsCallBackParams) {
const data = {
id: params.row.id,
isPublish: params.row.isPublish === 1 ? 0 : 1
};
api.publish(data).then(() => {
ElMessage.success("保存成功");
search();
});
}
},
{
text: "下线",
confirm: {
options: { draggable: false },
popconfirmProps: { width: 300 },
message: params => {
const row = params.row;
const opt = "下线";
return `确定要${opt}[${row.docTitle}]下所有接口吗?`;
}
},
props: {
type: "danger"
},
onConfirm(params: ButtonsCallBackParams) {
const data = {
id: params.row.id,
isPublish: 0
};
api.publish(data).then(() => {
ElMessage.success("下线成功");
search();
});
},
show: (row: any) => row.isFolder === 1
}
];
// 点击查询按钮
export const handleSearch = () => {
search();
};
// 查询
const search = async () => {
loadContent(docAppId.value);
};
export const handleClick = data => {
const id = data.props.name;
activeTab(id);
};
const activeTab = id => {
docAppId.value = id;
loadContent(id);
};
@@ -27,30 +187,78 @@ export const handleAddApp = () => {
const data = {
tornaToken: value
};
api.addApp(data).then(() => {
api.addApp(data).then(resp => {
ElMessage.success("添加成功");
loadTabs(true);
loadTabs(resp.data);
});
})
.catch(() => {});
};
const loadTabs = showLast => {
const loadTabs = docAppId => {
api.listApp().then(resp => {
tabsData.value = resp.data;
const length = tabsData.value.length;
if (length > 0) {
const showData = showLast
? tabsData.value[length - 1]
: tabsData.value[0];
activeName.value = showData.id;
loadContent(showData.id);
let targetId;
for (const id of tabsData.value) {
if (id === docAppId) {
targetId = id;
break;
}
}
if (!targetId) {
targetId = tabsData.value[0].id;
}
activeName.value = targetId;
activeTab(targetId);
}
});
};
const loadContent = id => {
console.log(id);
const searchRow = (search, rows, searchHandler, folderHandler) => {
if (!folderHandler) {
folderHandler = isFolder;
}
const ret = [];
for (const row of rows) {
// 找到分类
if (folderHandler(row)) {
if (searchHandler(search, row)) {
ret.push(row);
} else {
// 分类名字没找到,需要从子文档中找
const children = row.children || [];
const searchedChildren = searchRow(
search,
children,
searchHandler,
folderHandler
);
// 如果子文档中有
if (searchedChildren && searchedChildren.length > 0) {
const rowCopy = Object.assign({}, row);
rowCopy.children = searchedChildren;
ret.push(rowCopy);
}
}
} else {
// 不是分类且被找到
if (searchHandler(search, row)) {
ret.push(row);
}
}
}
return ret;
};
loadTabs(false);
const loadContent = id => {
const data = {
docAppId: id
};
api.listDocTree(data).then(resp => {
tableData.value = resp.data;
});
};
loadTabs(0);

View File

@@ -1,14 +1,32 @@
<script setup lang="ts">
import { activeName, handleClick, handleAddApp, tabsData } from "./index";
import {
activeName,
handleClick,
handleAddApp,
tabsData,
actionButtons,
tableColumns,
tableRows,
filterText,
handleSearch
} from "./index";
import { Search } from "@element-plus/icons-vue";
</script>
<template>
<el-card shadow="never">
<div v-show="tabsData.length === 0">
<el-button type="primary" @click="handleAddApp">添加应用</el-button>
</div>
<el-tabs
v-show="tabsData.length > 0"
v-model="activeName"
type="card"
addable
@tab-click="handleClick"
@tab-add="handleAddApp"
>
<template #add-icon>
<el-icon style="font-size: 20px"><CirclePlusFilled /></el-icon>
</template>
<el-tab-pane
v-for="item in tabsData"
:key="item.id"
@@ -16,8 +34,29 @@ import { activeName, handleClick, handleAddApp, tabsData } from "./index";
:name="item.id"
/>
</el-tabs>
<PlusTable
v-show="tabsData.length > 0"
:columns="tableColumns"
:table-data="tableRows"
:action-bar="{
buttons: actionButtons,
confirmType: 'popconfirm',
width: 120
}"
adaptive
>
<template #title>
<el-input
v-model="filterText"
type="text"
placeholder="过滤,支持接口标题,接口名称"
style="width: 300px"
>
<template #append>
<el-button :icon="Search" @click="handleSearch" />
</template>
</el-input>
</template>
</PlusTable>
</el-card>
<div v-show="tabsData.length === 0" style="margin: 20px">
<el-button type="primary" @click="handleAddApp">添加应用</el-button>
</div>
</template>