Commit 89c3fe82 authored by liwei's avatar liwei

任务流运维页面

parent bcde79a6
......@@ -855,6 +855,30 @@ export const serviceDevelopmentRoute: AppRouteRecordRaw = {
],
};
/**任务调度*/
export const taskSchedulingRoute: AppRouteRecordRaw = {
path: '/taskScheduling',
name: 'taskScheduling',
component: LAYOUT,
meta: {
title: '任务调度',
icon: '',
hidden: true,
currentActiveMenu: '/taskScheduling',
},
children: [
{
path: 'taskFlowMaintenance/executionDetails',
name: 'executionDetails',
component: () => import('@/views/taskScheduling/taskFlowMaintenance/periodicScheduling/executionDetails.vue'),
meta: {
title: '执行详情',
icon: '',
},
},
],
};
/**实时同步-任务运维*/
export const SyncMaintenanceRoute: AppRouteRecordRaw = {
path: '/realTimeSync',
......@@ -892,6 +916,7 @@ export const basicRoutes = [
sqlExecuteRoute,
shellExecuteRoute,
SyncMaintenanceRoute,
taskSchedulingRoute,
...mainOutRoutes,
REDIRECT_ROUTE,
DataWarehousePlanningRoute,
......
<template>
<BasicDrawer
v-bind="$attrs"
@register="registerDrawer"
showFooter
:title="getTitle"
width="50%"
@ok="handleSubmit"
>
<div>
<div>
<Tabs defaultActiveKey="上游" @change="handleChangeTab">
<TabPane tab="上游" key="上游">
</TabPane>
<TabPane tab="下游" key="下游"></TabPane>
</Tabs>
</div>
</div>
</BasicDrawer>
</template>
<script lang="ts" setup>
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { ref, computed, unref } from 'vue';
import { BasicForm, useForm } from '@/components/Form';
import { Card, Tabs, TabPane, Col, Row,RangePicker,RadioGroup,RadioButton,Select,Collapse } from 'ant-design-vue';
import {tableListColumns} from './taskFlowMaintenance.data';
import {taskListData} from './taskFlowMaintenanceData';
import { BasicDrawer, useDrawerInner } from '@/components/Drawer';
import { BasicTree, TreeItem } from '@/components/Tree';
import {useMessage} from "@/hooks/web/useMessage";
import { Alert } from 'ant-design-vue';
import { useModal } from '@/components/Modal';
import Icon from '@/components/Icon/Icon.vue';
import { detailTreeData } from './taskFlowMaintenanceData'
const [registerLookLogModal, { openModal: openLookLogModal }] = useModal();
const [registerLookAllDataModal, { openModal: openLookAllDataModal }] = useModal();
const [registerVersionModal, { openModal: openVersionModal }] = useModal();
const emit = defineEmits(['success', 'register']);
const { createMessage } = useMessage();
const isUpdate = ref(true);
const roleId = ref('');
const getTitle = computed(() => ('任务流依赖关系'));
const treeData = ref<TreeItem[]>([]);
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
setDrawerProps({ confirmLoading: false,showOkBtn:false,showCancelBtn:false});
});
/**查看版本变更信息*/
function lookVersionButton() {
openVersionModal(true,{})
}
function handleSubmit() {
}
</script>
<style lang="less" scoped>
</style>
<template>
<BasicModal width="40%" v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
<textarea style="width: 100%;margin-top:20px;background-color: rgb(89, 96, 116);color: white" readonly rows="22" v-model="textAreaData"/>
<textarea class="textAreaClass" readonly rows="18" v-model="textAreaData"/>
<a-button class="buttonClass" @click="downLoadButton">下载全部日志</a-button>
</BasicModal>
</template>
<script lang="ts" setup>
......@@ -8,13 +9,26 @@
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { useMessage } from '@/hooks/web/useMessage';
import {exportRoleList} from "@/api/system/role/role";
import {downloadByData} from "@/utils/file/download";
defineOptions({ name: 'AccountModal' });
const emit = defineEmits(['success', 'register']);
const { createMessage } = useMessage();
const getTitle = computed(() => ('查看日志'));
const getTitle = computed(() => ('日志'));
const textAreaData = ref('\n' +
' 源端发生DDL事件,DDL处理策略为自动变更,自动启动源端')
' [2024-01-30 00:00:00.220] flow execution [49030] submitted to scheduler [172.20.23.29:9102] at\n' +
' [FES_WAITING] state\n' +
' [2024-01-30 00:01.877] start on scheduler and create log [/home/zzh/workflow/scheduler/file/get?\n' +
' path=/tmp/log/workflow/workflow-schedule-r20240130/49030.log]\n' +
' [2024-01-30 00:01.957] success to enter priority queue\n' +
' [2024-01-30 00:02.390] used global and workspace params is [WORKSPACE=(aaa=ssdas, workspace=修\n' +
' 改工作区参数-gwx), bxwang工作区参数设置***, usd=d, w=ewew, space=space], GLOBAL=[A=0, test=\n' +
' AAA-gx, bxwang全局参数设置***, www, bxwang加密参数数据库加密***, global2=修改global2, global1=\n' +
' 修改global1, global, 全局变量参数, aaa=123123, Fl-runTime.plusDays(1).date(), T=def call]\n' +
' [2024-01-30 00:02.390] flow started running\n' +
' [2024-01-30 00:03.14.748] finished with [FES_SUCCEEDED] state\n' +
' [2024-01-30 00:03.14.786] successfully updated state [FES_SUCCEEDED]')
//初始化弹框
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
......@@ -26,4 +40,24 @@
closeModal()
}
/**下载全部日志 按钮*/
async function downLoadButton() {
const params = Object.assign({}, {});
const data = await exportRoleList(params);
downloadByData(data, '全部日志' + '.xlsx');
}
</script>
<style lang="less" scoped>
.buttonClass{
margin-top: 10px;
border-color: rgb(41, 147, 249);
color: rgb(41, 147, 249)
}
.textAreaClass{
width: 100%;
margin-top:20px;
background-color: rgb(37, 37, 37);
color: white
}
</style>
<template>
<BasicDrawer
v-bind="$attrs"
@register="registerDrawer"
showFooter
:title="getTitle"
width="50%"
@ok="handleSubmit"
>
<div class="homePage_module">
<Row :gutter="16" class="homePage_left">
<Col :span="24" style="display: flex;justify-content: center">
<div class="card_content1">
<Col :span="4">
<div class="card_item">
<div class="card_itemInfo">
<div ref="chartRef1" style="width:100%;height: 100%"></div>
</div>
</div>
</Col>
<Col :span="4" @click="clickButton(1)" :class="{ 'listItemClass': selectedItem === 1 }">
<div class="card_item">
<div class="card_itemInfo">
<div class="dataTitle">任务数量:4</div>
</div>
</div>
</Col>
<Col :span="4" @click="clickButton(2)" :class="{ 'listItemClass': selectedItem === 2 }">
<div class="card_item">
<Icon icon="ri:hourglass-fill" :size="15" :color="'rgb(108, 99, 178)'" />
<div class="card_itemInfo">
<div class="dataTitle">等待:0</div>
</div>
</div>
</Col>
<Col :span="4" @click="clickButton(3)" :class="{ 'listItemClass': selectedItem === 3 }">
<div class="card_item">
<Icon icon="line-md:loading-twotone-loop" :size="15" :color="'rgb(26, 139, 236)'" />
<div class="card_itemInfo">
<div class="dataTitle">运行中:0</div>
</div>
</div>
</Col>
<Col :span="4" @click="clickButton(4)" :class="{ 'listItemClass': selectedItem === 4 }">
<div class="card_item">
<Icon icon="line-md:close-circle-filled" :size="15" :color="'rgb(54, 189, 143)'" />
<div class="card_itemInfo">
<div class="dataTitle">成功:4</div>
</div>
</div>
</Col>
<Col :span="4" @click="clickButton(5)" :class="{ 'listItemClass': selectedItem === 5 }">
<div class="card_item">
<Icon icon="line-md:minus-circle-filled" :size="15" :color="'rgb(234, 150, 0)'" />
<div class="card_itemInfo">
<div class="dataTitle">失败:0</div>
</div>
</div>
</Col>
<Col :span="4" @click="clickButton(5)" :class="{ 'listItemClass': selectedItem === 5 }">
<div class="card_item">
<Icon icon="line-md:minus-circle-filled" :size="15" :color="'rgb(234, 150, 0)'" />
<div class="card_itemInfo">
<div class="dataTitle">已取消:0</div>
</div>
</div>
</Col>
<Col :span="4" @click="clickButton(5)" :class="{ 'listItemClass': selectedItem === 5 }">
<div class="card_item">
<Icon icon="line-md:minus-circle-filled" :size="15" :color="'rgb(234, 150, 0)'" />
<div class="card_itemInfo">
<div class="dataTitle">跳过:0</div>
</div>
</div>
</Col>
<Col :span="4" @click="clickButton(5)" :class="{ 'listItemClass': selectedItem === 5 }">
<div class="card_item">
<Icon icon="line-md:minus-circle-filled" :size="15" :color="'rgb(234, 150, 0)'" />
<div class="card_itemInfo">
<div class="dataTitle">过滤:0</div>
</div>
</div>
</Col>
<Col :span="4" @click="clickButton(5)" :class="{ 'listItemClass': selectedItem === 5 }">
<div class="card_item">
<Icon icon="line-md:minus-circle-filled" :size="15" :color="'rgb(234, 150, 0)'" />
<div class="card_itemInfo">
<div class="dataTitle">阻塞:0</div>
</div>
</div>
</Col>
</div>
</Col>
</Row>
</div>
<BasicTable @register="registerTable">
<template #toolbar>
<div>
<a-input-search
v-model:value="value"
placeholder="请输入"
style="width: 200px"
@search="onSearch"
/>&nbsp;&nbsp;
任务类型&nbsp;&nbsp;<Select
style="width: 200px"
v-model:value="optionValue"
:options="options"
/>
</div>
<div style="margin-left: 130px">
<a-button type="primary" :disabled="getRowSelection().selectedRowKeys <= 0" @click="handleDeleteIds" style="margin-right: 10px;">取消</a-button>
<a-button type="primary" :disabled="getRowSelection().selectedRowKeys <= 0" @click="batchDownloadButton">批量下载日志</a-button>
</div>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
icon:'teenyicons:location-outline',
onClick: lookLogButton.bind(null, record),
},
{
icon:'ix:log',
onClick: lookLogButton.bind(null, record),
},
{
icon:'codicon:debug-start',
onClick: lookLogButton.bind(null, record),
},
]"
/>
</template>
</template>
</BasicTable>
<!-- 查看日志 弹窗-->
<LookLogModal @register="registerLookLogModal" @success="handleSuccess" />
</BasicDrawer>
</template>
<script lang="ts" setup>
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { ref, computed, unref } from 'vue';
import { BasicForm, useForm } from '@/components/Form';
import { Card, Tabs, TabPane, Col, Row,RangePicker,RadioGroup,RadioButton,Select } from 'ant-design-vue';
import {tableListColumns} from './taskFlowMaintenance.data';
import {taskListData} from './taskFlowMaintenanceData';
import { BasicDrawer, useDrawerInner } from '@/components/Drawer';
import { BasicTree, TreeItem } from '@/components/Tree';
import {useMessage} from "@/hooks/web/useMessage";
import { Alert } from 'ant-design-vue';
import { useModal } from '@/components/Modal';
import Icon from '@/components/Icon/Icon.vue';
import LookLogModal from './LookLogModal.vue'
import {exportRoleList} from "@/api/system/role/role";
import {downloadByData} from "@/utils/file/download";
const [registerLookLogModal, { openModal: openLookLogModal }] = useModal();
const [registerLookAllDataModal, { openModal: openLookAllDataModal }] = useModal();
const [registerVersionModal, { openModal: openVersionModal }] = useModal();
const emit = defineEmits(['success', 'register']);
const { createMessage } = useMessage();
const isUpdate = ref(true);
const roleId = ref('');
const getTitle = computed(() => ('任务列表'));
const treeData = ref<TreeItem[]>([]);
const optionValue = ref('1')
const options = ref([
{
label:'全部',
value:'1',
},
{
label:'version2',
value:'2',
},
{
label:'version3',
value:'3',
}
])
const [registerTable, { reload,getForm,getRowSelection }] = useTable({
title: '',
api: async (params) => {
const response = {
pageNu: "1",
pageSize: "10",
pages: "1",
total: taskListData.length,
code:'',
message:'',
data: [],
};
return { ...response,data: taskListData };
},
columns:tableListColumns,
rowKey: 'id',
rowSelection:true,
useSearchForm: false,
showTableSetting: false,
showIndexColumn:false,
bordered: true,
scroll: { y: 500 },
actionColumn: {
width: 180,
title: '操作',
dataIndex: 'action',
},
});
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
setDrawerProps({ confirmLoading: false,showOkBtn:false,showCancelBtn:false});
});
/**查看版本变更信息*/
function lookVersionButton() {
openVersionModal(true,{})
}
/**查看日志 按钮*/
function lookLogButton() {
openLookLogModal(true,{})
}
/**批量下载 按钮*/
async function batchDownloadButton() {
const params = Object.assign({}, {});
const data = await exportRoleList(params);
downloadByData(data, '全部日志' + '.xlsx');
}
function handleSubmit() {
}
</script>
<style lang="less" scoped>
.homePage_module {
margin-top: 20px;
::v-deep(.ant-card-body) {
display: flex;
justify-content: center;
height: 180px;
}
.homePage_left {
.card_content1 {
width: 70%;
display: flex;
justify-content: center;
align-items: center;
.card_item {
//padding-left: 20px;
display: flex;
align-items: center;
width: 100px;
height: 80px;
border-radius: 10px;
.card_itemInfo {
padding-left: 7px;
.dataTitle {
font-size: 12px;
line-height: 12px;
}
}
}
}
}
}
</style>
<template>
<div style="width: 100%;height: 100%;background-color: white">
<div style="width: 100%;height:35%">
<div class="TopClass">
<div class="eventCenterTitle">
<Icon icon="material-symbols:sync" :size="25" :color="'rgb(121, 74, 235)'" />
gxx1
</div>
<div class="selectCss">
<BasicForm @register="registerForm1">
<template #switch>
<RadioGroup v-model:value="showType" button-style="solid" size="small">
<RadioButton value="table" @click="" ><UnorderedListOutlined/></RadioButton>
<RadioButton value="chart" @click="" ><AppstoreOutlined/></RadioButton>
</RadioGroup>
</template>
</BasicForm>
</div>
</div>
<Divider/>
<div class="contentClass" style="display: flex;margin-top: 20px">
<div>
<img src="src/assets/images/taskFlowMaintenance.png" style="width: 1455px;" />
</div>
<div>
<RadioGroup v-model:value="showType1" button-style="solid" size="small">
<RadioButton value="table" @click="taskListButton"><UnorderedListOutlined style="font-size: 20px"/></RadioButton>
<RadioButton value="chart" @click="relationshipButton"><AppstoreOutlined style="font-size: 20px"/></RadioButton>
</RadioGroup>
</div>
</div>
</div>
<!-- 任务列表 抽屉-->
<TaskListDrawer @register="registerDrawer" @success="handleSuccess" />
<!-- 任务列表 抽屉-->
<DependencyRelationshipDrawer @register="registerDependencyRelationshipDrawer" @success="handleSuccess" />
</div>
</template>
<script lang="ts" setup>
import { Card, Tabs, TabPane, Col, Row,RangePicker,RadioGroup,RadioButton,Tag,List} from 'ant-design-vue';
import Icon from '@/components/Icon/Icon.vue';
import {reactive, unref, onDeactivated, onMounted, ref, watch, Ref, h} from 'vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { PageWrapper } from '@/components/Page';
import { useMessage } from '@/hooks/web/useMessage';
import { useModal } from '@/components/Modal';
import { useGo } from '@/hooks/web/usePage';
import { useRoute } from 'vue-router';
import { router } from '@/router';
import {columns, topFormSchema2, topFormSchema1, mainFormSchema3} from './taskFlowMaintenance.data';
import { tableData,TreeData,treeData2 } from './taskFlowMaintenanceData'
import { BasicForm, useForm } from '@/components/Form';
import { useECharts } from '@/hooks/web/useECharts';
import LookLogModal from './LookLogModal.vue'
import {EllipsisOutlined} from "@ant-design/icons-vue";
import {EventDataNode} from "ant-design-vue/es/vc-tree/interface";
import {BasicTree, ContextMenuItem, TreeActionType, TreeItem} from '@/components/Tree';
import {
UnorderedListOutlined,
AppstoreOutlined,
} from '@ant-design/icons-vue';
import { Divider } from 'ant-design-vue';
import TaskListDrawer from './TaskListDrawer.vue'
import DependencyRelationshipDrawer from './DependencyRelationshipDrawer.vue'
import {useDrawer} from "@/components/Drawer";
defineOptions({ name: 'AccountManagement' });
const { createMessage, createConfirm } = useMessage();
const route = useRoute();
const go = useGo();
const showType = ref('chart')
const showType1 = ref('')
const [registerDrawer, { openDrawer }] = useDrawer();
const [registerDependencyRelationshipDrawer, { openDrawer: openDependencyRelationshipDrawer}] = useDrawer();
const [registerTable, { reload,getForm,getRowSelection }] = useTable({
title: '执行记录',
api: async (params) => {
const response = {
pageNu: "1",
pageSize: "10",
pages: "1",
total: tableData.length,
code:'',
message:'',
data: [],
};
return { ...response,data: tableData };
},
columns,
rowKey: 'id',
rowSelection:true,
useSearchForm: false,
showTableSetting: false,
showIndexColumn:false,
bordered: true,
actionColumn: {
width: 180,
title: '操作',
dataIndex: 'action',
},
});
const [registerForm1, { updateSchema:updateSchema2 }] = useForm({
labelWidth: 100,
schemas: topFormSchema2,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
/**跳转任务运维 按钮*/
function toTaskMaintenanceButton(record){
router.push({
path: '/realTimeSync/taskOperationsMaintenance/index',
query: {}
});
}
/**查看日志 按钮*/
function lookLogButton(record){
}
/**任务列表 按钮*/
function taskListButton(record){
openDrawer(true,{})
}
/**任务流依赖关系 按钮*/
function relationshipButton() {
openDependencyRelationshipDrawer(true,{})
}
function handleOpen(node){
}
onMounted(() => {
});
</script>
<style lang="less" scoped>
.selectCss{
margin-right: 40px;
::v-deep(.ant-select){
width:200px!important;
}
}
.icon {
font-size: 20px !important;
}
.listClass{
::v-deep(.ant-list-item){
padding: 5px 24px 5px 10px!important;
}
::v-deep(.ant-list-item-meta-title){
margin-bottom: -5px!important;
}
}
.titleClass{
height: 40px;
background-color: rgb(233, 236, 247);
font-weight: bold;
font-size: 13px;
display: flex;
align-items: center
}
.inputSearchClass{
width: 200px;
height:40px;
margin-left: 10px;
display: flex;
align-items: center
}
.TopClass{
display: flex;
justify-content: space-between;
height: 30px;
margin-left: 30px;
margin-top: 10px;
margin-bottom: 10px;
.eventCenterTitle{
display: flex;
align-items: center;
color: rgb(109, 181, 250);
font-size: 15px
}
}
::v-deep(.ant-divider){
margin:0px 0px!important;
background-color: rgb(221, 225, 240)!important;
}
</style>
......@@ -196,7 +196,7 @@
</Tabs>
</div>
<div style="width: 100%;height:65%;display: flex;margin-top: 10px">
<div style="width: 25%;">
<div style="width: 25%;height: 500px">
<BasicTree
toolbar
search
......@@ -221,7 +221,7 @@
</template>
</BasicTree>
</div>
<div style="width: 75%;">
<div style="width: 75%;height: 500px">
<div style="display: flex;justify-content: space-between; align-items: center;margin-bottom: 10px;">
<div style="margin-top: 10px;display: flex;margin-left: 10px;align-items: center">
<div>
......@@ -252,13 +252,25 @@
<TableAction
:actions="[
{
label: '跳转任务运维',
icon:'ant-design:file-search-outlined',
onClick: detailButton.bind(null, record),
},
{
icon:'material-symbols-light:not-started-outline',
onClick: lookLogButton.bind(null, record),
// ifShow: record.eventType === '系统异常',
},
{
icon:'ix:error',
onClick: toTaskMaintenanceButton.bind(null, record),
},
{
label: '查看日志',
icon:'jam:stop-sign',
onClick: toTaskMaintenanceButton.bind(null, record),
},
{
icon:'ix:log',
onClick: lookLogButton.bind(null, record),
ifShow: record.eventType === '系统异常',
},
]"
/>
......@@ -438,7 +450,7 @@
showIndexColumn:false,
bordered: true,
actionColumn: {
width: 150,
width: 180,
title: '操作',
dataIndex: 'action',
},
......@@ -476,6 +488,14 @@
});
}
/**跳转详情 按钮*/
function detailButton(record){
router.push({
path: '/taskScheduling/taskFlowMaintenance/executionDetails',
query: {}
});
}
/**查看日志 按钮*/
function lookLogButton(record){
openLookLogModal(true,{})
......
......@@ -125,31 +125,24 @@ export const topFormSchema2: FormSchema[] = [
},
{
field: 'eventType',
label: '调度类型',
label: ' ',
labelWidth:20,
component: 'Select',
componentProps: {
placeholder: '类型',
options: [
{
label: '全部',
label: '调度',
value: '全部',
},
],
},
},
{
field: 'eventType',
label: '发布状态',
component: 'Select',
componentProps: {
placeholder: '类型',
options: [
{
label: '全部',
value: '全部',
},
],
},
field: 'switch',
component: '',
label: '展示切换',
slot: 'switch'
},
];
/**首页-表单3*/
......@@ -212,3 +205,47 @@ export const mainFormSchema3: FormSchema[] = [
colProps: { lg: 8, md: 24 },
},
];
/**详情页-任务列表*/
export const tableListColumns: BasicColumn[] = [
{
title: '任务名称',
dataIndex: 'taskName',
width: 120
},
{
title: '运行状态',
dataIndex: 'runStatus',
width: 120
},
{
title: '执行条件',
dataIndex: 'executionCondition',
width: 120
},
{
title: '运行开始时间',
dataIndex: 'startTime',
width: 120
},
{
title: '运行结束时间',
dataIndex: 'endTime',
width: 120
},
{
title: '运行时长',
dataIndex: 'duration',
width: 120
},
{
title: '执行版本',
dataIndex: 'executionVersion',
width: 120
},
{
title: '执行ID',
dataIndex: 'executionId',
width: 120
}
];
......@@ -207,3 +207,86 @@ export const treeData2:any[] = [
color: 'rgb(138, 101, 235)',
},
]
/**详情页-任务列表数据*/
export const taskListData:any[] = [
{
id:1,
taskName: 'new task',
runStatus: '成功',
executionCondition: '-',
startTime: '2024-01-30 00:00:31',
endTime: '2024-01-30 00:00:33',
duration:'2s 230ms',
executionVersion:'V1',
executionId:'266336'
},
{
id:2,
taskName: 'new task_1',
runStatus: '成功',
executionCondition: '-',
startTime: '2024-01-30 00:00:32',
endTime: '2024-01-30 00:00:32',
duration:'0ms',
executionVersion:'V1',
executionId:'266335'
},
{
id:3,
taskName: 'new task_10',
runStatus: '成功',
executionCondition: '-',
startTime: '2024-01-30 00:00:36',
endTime: '2024-01-30 00:00:36',
duration:'0ms',
executionVersion:'V1',
executionId:'266334'
},
{
id:4,
taskName: 'new task_11',
runStatus: '成功',
executionCondition: '-',
startTime: '2024-01-30 00:00:45',
endTime: '2024-01-30 00:00:45',
duration:'0ms',
executionVersion:'V1',
executionId:'266333'
},
]
/**详情页-任务列表数据*/
export const detailTreeData:any[] = [
{
key: 1,
desc: '',
title: '任务流',
icons: '',
color: '',
children:[
{
key: 2,
desc: 'gxx/jira/test',
title: 'test',
icons: 'pepicons-pop:rewind-time',
color: 'rgb(138, 101, 235)',
},
]
},
{
key: 3,
desc: '',
title: '任务',
icons: '',
color: '',
children:[
{
key: 4,
desc: 'gxx/jira/test',
title: 'test',
icons: 'pepicons-pop:rewind-time',
color: 'rgb(138, 101, 235)',
},
]
},
]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment