mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
5.0
This commit is contained in:
@@ -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",
|
||||
|
3
sop-admin/sop-admin-frontend/pnpm-lock.yaml
generated
3
sop-admin/sop-admin-frontend/pnpm-lock.yaml
generated
@@ -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)
|
||||
|
@@ -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 });
|
||||
}
|
||||
};
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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>
|
||||
|
Reference in New Issue
Block a user