feat: 开始日志模块

master
donghao 3 weeks ago
parent 18dce5efe8
commit 9949a3ff0b

@ -169,7 +169,7 @@ export default defineComponent({
> >
{slots.header?.()} {slots.header?.()}
{slots.default?.() || renderContent()} {slots.default?.() || renderContent()}
{slots.footer?.() || renderFooter()} {slots.footer?.()}
</ElDialog> </ElDialog>
) )
} }

@ -0,0 +1,11 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-08 14:28:02
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-08 14:28:24
* @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Table\index.ts
* @Description:
*/
import baseTable from './src/baseTable'
export const DSTable = baseTable

@ -0,0 +1,104 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-18 14:27:25
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-02-21 15:08:35
* @FilePath: \General-AI-Platform-Web-Client\src\components\CustomTable\src\column.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<el-dialog v-model="dialogVisible" :width="600" title="自定义列">
<!-- footer -->
<template #footer>
<el-row type="flex" justify="center">
<el-button @click="handleCancel"> </el-button>
<el-button type="primary" @click="handleConfirm"> </el-button>
</el-row>
</template>
<!-- body -->
<div class="x-custom-column">
<template v-for="item in items" :key="item.prop || item.type">
<el-checkbox
v-if="!item.type"
v-model="item.show"
:label="item.label"
size="large"
/>
</template>
</div>
</el-dialog>
</template>
<script lang="ts" setup>
import { computed, ref, watch } from "vue";
interface ModalProps {
visible: boolean;
columns: XTableColumn[];
}
type XCustomColumn = XTableColumn & {
show: boolean;
};
const props = withDefaults(defineProps<ModalProps>(), {
visible: false
});
const emit = defineEmits<{
(e: "update:visible", value: boolean): void;
(e: "visibleChange", value: boolean): void;
(e: "change", value: XTableColumn[]): void;
}>();
const dialogVisible = computed({
get: () => props.visible,
set: val => {
emit("update:visible", val);
emit("visibleChange", val);
}
});
const items = ref<XCustomColumn[]>([]);
watch(
() => props.visible,
value => {
if (value) {
items.value = props.columns.map(i => ({
...i,
show: !i.hidden
}));
}
}
);
function handleConfirm() {
const data = items.value.map(i => {
const { show, ...rest } = i;
return {
...rest,
hidden: !show
};
});
emit("change", data);
dialogVisible.value = false;
}
function handleCancel() {
dialogVisible.value = false;
}
</script>
<style lang="scss" scoped>
.x-custom-column {
min-height: 100px;
padding: 10px;
.el-checkbox {
width: 18%;
margin-right: 10px;
}
}
</style>

@ -0,0 +1,153 @@
.baseTable_wrap {
/* 去掉表格整体边框 */
.el-table {
border: none !important;
background-color: transparent;
}
/* 去掉表头下边框 */
.el-table__header-wrapper thead th {
border-bottom: none !important;
border: none !important;
}
/* 去掉单元格边框 */
.el-table td,
.el-table th.is-leaf {
border-bottom: none !important;
border: none !important;
}
/* 去掉纵向分割线 */
.el-table--border::after,
.el-table--group::after,
.el-table::before {
display: none;
}
.el-table--border,
.el-table--group {
border-right: none !important;
border-bottom: none !important;
border: none !important;
}
.el-table td,
.el-table th {
border-right: none !important;
border: none !important;
border-collapse: collapse !important;
}
.el-scrollbar__view {
background: transparent !important;
}
.el-table--large .el-table__cell {
padding: 8.5px 0;
}
.baseTable_box {
cursor: pointer;
.el-table__body {
background: transparent;
border-collapse: collapse !important;
border: none !important;
tr {
color: #fff;
background: transparent;
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
&:hover td {
background: transparent !important;
}
&:hover {
color: #37dbff;
background: linear-gradient(
90deg,
rgba(30, 54, 88, 0) 0%,
#0c4fad 53%,
rgba(65, 117, 190, 0) 100%
);
border-top: 1px solid rgba(69, 174, 250, 0.3);
border-bottom: 1px solid rgba(69, 174, 250, 0.3);
}
&.selected-row {
color: #37dbff;
background: linear-gradient(
90deg,
rgba(30, 54, 88, 0) 0%,
#0c4fad 53%,
rgba(65, 117, 190, 0) 100%
);
border-top: 1px solid rgba(69, 174, 250, 0.3);
border-bottom: 1px solid rgba(69, 174, 250, 0.3);
}
}
}
.el-table__header > thead {
color: #9fb5d7;
background-color: #104284 !important;
tr {
background-color: #104284 !important;
}
th {
background-color: #104284 !important;
}
}
}
.fixed_pagination {
padding: 12px 20px 0;
}
/* full_table */
&.full_table {
.el-table--large .el-table__cell {
padding: 4px 0;
}
.baseTable_box {
cursor: default;
.el-table__body {
border: none !important;
background: linear-gradient(90deg, #082050 0%, #02102a 100%);
tr {
color: #fff;
background: linear-gradient(90deg, #082050 0%, #02102a 100%);
&:nth-child(odd) {
background: linear-gradient(90deg, #082050 0%, #02102a 100%);
}
&:nth-child(even) {
background: linear-gradient(90deg, #102d65 0%, #081736 100%);
}
&:hover {
border: none !important;
}
&:hover td {
background-color: transparent;
}
}
}
.el-table__header > thead {
color: #9fb5d7;
background-color: #104284 !important;
tr {
background-color: #104284 !important;
}
th {
background-color: #104284 !important;
}
}
}
.fixed_pagination {
padding: 28px 20px;
}
}
}
.pagination_box {
margin-top: 50px;
width: 100%;
// position: fixed;
// bottom: 100px;
// right: 40px;
background-color: white;
z-index: 9;
}

@ -0,0 +1,488 @@
import { ElLoading, ElPagination, ElTable, ElTableColumn } from "element-plus";
import BaseColumn from "./baseColumn.vue";
import { isUndefined } from "@/utils/is";
import {
computed,
defineComponent,
nextTick,
reactive,
type PropType
} from "vue";
import "./baseTable.scss";
function getDefaultSort(attrs: Record<string, any>): any {
return attrs["default-sort"] || attrs.defaultSort;
}
export default defineComponent({
name: "XTable",
directives: {
loading: ElLoading.directive
},
inheritAttrs: false,
props: {
/**
*
*/
columns: {
type: Array as PropType<XTableColumn[]>,
required: true
},
/**
*
*/
dataSource: {
type: Array as PropType<XTableData[]>,
required: true
},
/**
* loading
*/
loading: {
type: Boolean,
default: false
},
/**
*
*/
maxHeight: {
type: [Number, String] as PropType<number | "auto">,
default: "auto"
},
/**
*
* always
* false
* true
*/
pageable: {
type: [Boolean, String] as PropType<boolean | "always">,
default: true,
validator(value: boolean | "always") {
return ["always", true, false].includes(value);
}
},
/**
*
*/
pagerLayout: {
type: String,
default: "total, sizes, prev, pager, next, jumper",
validator(value: string) {
return value
.split(",")
.map(item => item.trim())
.every(item =>
["total", "sizes", "prev", "pager", "next", "jumper"].includes(item)
);
}
},
/**
*
*/
total: {
type: Number,
default: 0
},
/**
*
*/
pageSize: {
type: Number,
default: 10
},
/**
*
*/
page: {
type: Number,
default: 1
},
/**
*
*/
pageSizes: {
type: Array as PropType<number[]>,
default() {
return [15, 20, 30, 50];
}
},
/**
* Key
*/
rowKey: {
type: [Function, String] as PropType<
(row: XTableData) => string | string
>,
default: "id"
},
/**
*
*/
visibleColumn: {
type: Boolean,
default: undefined
},
/**
*
*/
isFixedPagination: {
type: Boolean,
default: true
}
// handleDel: {
// type: Function,
// default: () => {}
// }
// customActions: {
// type: Function,
// default: () => {}
// }
},
emits: ["change", "columnChange", "update:visibleColumn", "actions"],
setup(props, { slots, attrs, emit }) {
const nonPropsAttrs = attrs;
const { prop: sortBy, order: sortOrder } = getDefaultSort(attrs) || {};
const tableState = reactive<XTableState>({
tid: 0,
sortBy,
sortOrder
});
const showPagination = computed(() => {
if (props.pageable === "always") return true;
return props.pageable && props.dataSource.length > 0;
});
const mHeight = computed(() => {
if (props.maxHeight === "auto") {
return "auto";
}
return showPagination.value ? props.maxHeight - 44 : props.maxHeight;
});
/**
*
*/
function getSlot(column: XTableColumn, suffix?: string) {
const name = column.prop || column.type;
if (name) {
const key = suffix ? `${name}-${suffix}` : name;
return slots[key];
}
}
/**
*
*/
function onChange(data: XTableChangeData) {
emit("change", data);
}
/**
*
*/
function handlePageNumChange(page: number) {
const { sortBy, sortOrder } = tableState;
const { pageSize } = props;
onChange({
page,
pageSize,
prop: sortBy,
order: sortOrder,
type: "number"
});
}
/**
*
*/
function handlePageSizeChange(pageSize: number) {
const { sortBy, sortOrder } = tableState;
nextTick(() => {
// 下拉框溢出可能导致溢出 body 出现滚动条
// 加个延迟,等下拉隐藏
onChange({
page: 1,
pageSize,
prop: sortBy,
order: sortOrder,
type: "size"
});
});
}
/**
*
*/
function handleTableSortChange({ prop, order }: XTableSort) {
const { pageSize } = props;
onChange({ page: 1, pageSize, prop, order, type: "sort" });
}
/**
*
*/
function handleColumnChange(cols: XTableColumn[]) {
emit("columnChange", cols);
}
/**
*
*/
function handleVisibleChange(val: boolean) {
emit("update:visibleColumn", val);
}
/**
*
*/
function getColumnProps(column: XTableColumn) {
const col = { ...column };
Reflect.deleteProperty(col, "children");
Reflect.deleteProperty(col, "hidden");
col.key = column.key || column.prop || column.type;
col.showOverflowTooltip = col.showOverflowTooltip ?? true;
col.showOverflowTooltip =
column.prop === "action" ? false : column.showOverflowTooltip;
return col;
}
/**
*
*/
function renderTypeColumn(column: XTableColumn) {
if (column.type === "expand") {
return (
<ElTableColumn {...getColumnProps(column)}>
{{
default: (scope: Record<string, any>) => {
const slot = getSlot(column);
return slot?.(scope);
}
}}
</ElTableColumn>
);
}
if (column.type === "action") {
return (
<ElTableColumn {...getColumnProps(column)}>
{{
default: ({ row }: { row: Record<string, any> }) => {
return (
<div>
{slots.actionBar && <div>{slots.actionBar({ row })}</div>}
{/* <ul>
<li
class="flex items-center"
style={{ fontSize: "14px", color: "#E80D0D" }}
onClick={() => handleDel(row)}
>
<i class="iconfont icon-shanchu pr-[8px]"></i>
<el-button type="text">
<span
style={{
fontSize: "14px",
color: "#E80D0D"
}}
>
</span>
</el-button>
</li>
</ul> */}
</div>
);
}
}}
</ElTableColumn>
);
}
return <ElTableColumn {...getColumnProps(column)} />;
}
/**操作按钮事件 */
// function handleDel(row) {
// console.log(row, "handleDel");
// emit("actions", {
// type: "delete",
// data: { ...row }
// });
// }
/**
*
*/
function renderBaseColumn(column: XTableColumn) {
const columnSlots: {
default?: (scope: Record<string, any>) => any;
header?: (scope: Record<string, any>) => any;
} = {};
const slot = getSlot(column);
const headerSlot = getSlot(column, "header");
if (slot) {
columnSlots.default = scope => slot(scope);
}
if (headerSlot) {
columnSlots.header = scope => headerSlot(scope);
}
return (
<ElTableColumn {...getColumnProps(column)}>{columnSlots}</ElTableColumn>
);
}
/**
*
*/
function renderTableColumn(column: XTableColumn) {
if (column.hidden) return;
if (column.type) {
return renderTypeColumn(column);
}
return renderBaseColumn(column);
}
/**
*
*/
function renderColumnChildren(
column: XTableColumn,
children: Required<XTableColumn>["children"]
) {
if (column.hidden) return;
return (
<ElTableColumn {...getColumnProps(column)}>
{children.map(column => renderTableColumn(column))}
</ElTableColumn>
);
}
/**
*
*/
function renderPagination() {
const paginationProps = {
size: "small",
background: false,
total: props.total,
layout: props.pagerLayout,
pageSize: props.pageSize,
pageSizes: props.pageSizes,
currentPage: props.page,
onSizeChange: handlePageSizeChange,
onCurrentChange: handlePageNumChange
};
return (
<div
class={[
"x-table-pagination pagination_wrap",
props.isFixedPagination
? "fixed_pagination"
: "noneFixed_pagination"
]}
>
<ElPagination {...paginationProps} />
</div>
);
}
/**
*
*/
function renderCustomColumn() {
const customColumnProps = {
columns: props.columns,
visible: props.visibleColumn,
onChange: handleColumnChange,
onVisibleChange: handleVisibleChange
};
return <BaseColumn {...customColumnProps} />;
}
return () => {
const tableProps = {
ref: "elTableRef",
...nonPropsAttrs,
maxHeight: mHeight.value,
data: props.dataSource,
rowKey: props.rowKey,
onSortChange: handleTableSortChange
};
const extraSlots: {
append?: () => any;
empty?: () => any;
} = {};
if (slots.append) {
extraSlots.append = () => slots.append?.();
}
if (slots.empty) {
extraSlots.empty = () => slots.empty?.();
}
return (
<div class="x-table baseTable_wrap">
<ElTable
class="baseTable_box"
{...tableProps}
v-loading={props.loading}
v-slots={extraSlots}
>
{props.columns.map(column => {
if (Array.isArray(column.children)) {
return renderColumnChildren(column, column.children);
}
return renderTableColumn(column);
})}
{/* 使用插槽引入操作栏的内容 */}
{/* <ElTableColumn label="">
{{
default: ({ row }: { row: Record<string, any> }) => {
return extraSlots.customActions?.({
row
});
}
}}
</ElTableColumn> */}
{/* <ElTableColumn label="">
<template #default="scope">
<el-button size="small" @click="handleEdit(scope.$index, scope.row)"
>Edit</el-button
>
<el-button
size="small"
type="danger"
@click="handleDelete(scope.$index, scope.row)"
>Delete</el-button>
>
</template>
</ElTableColumn> */}
</ElTable>
{showPagination.value && renderPagination()}
{!isUndefined(props.visibleColumn) && renderCustomColumn()}
</div>
);
};
}
});

@ -0,0 +1,42 @@
import type ElTable from "element-plus/lib/components/table";
import type { ElTableColumn } from "element-plus/lib/components/table";
export {};
type ElTableType = InstanceType<typeof ElTable>;
type ElTableProps = ElTableType["$props"];
type ElTableColumnProps = InstanceType<typeof ElTableColumn>["$props"];
type ElTableSort = Pick<
Required<ElTableProps>["defaultSort"],
"prop" | "order"
>;
type ElTableAction = {
type: "delete" | "update" | string; // 操作类型
confirmType?: "popup" | "modal"; // 确认组件
};
declare global {
type XTableSort = ElTableSort;
interface XTableColumn extends ElTableColumnProps {
children?: XTableColumn[];
hidden?: boolean;
}
interface XTableData {
[key: string]: any;
}
interface XTableState {
tid: number;
sortBy?: XTableSort["prop"];
sortOrder?: XTableSort["order"];
}
interface XTableChangeData extends Partial<XTableSort> {
type: "size" | "number" | "sort";
pageNum: number;
pageSize: number;
}
}

@ -46,21 +46,23 @@
} }
/* 弹框 */ /* 弹框 */
.el-dialog {
--el-dialog-padding-primary: 0; //
}
.ds-dialog { .ds-dialog {
--el-dialog-padding-primary: 0; //
--el-dialog-bg-color: var(--ds-dialog-background-color) !important; //
padding: 0 !important; padding: 0 !important;
overflow: hidden; overflow: hidden;
.el-dialog__header { .el-dialog__header {
background-color: var(--ds-color-primary); background-color: var(--ds-color-primary);
.el-dialog__title{ .el-dialog__title {
color: var(--ds-color-info); color: var(--ds-color-info);
line-height: var(--ds-dialog-header-height); line-height: var(--ds-dialog-header-height);
padding-left: var(--ds-dialog-header-padding); padding-left: var(--ds-dialog-header-padding);
} }
} }
.el-dialog__body {
color: var(--ds-color-info);
}
.el-dialog__footer { .el-dialog__footer {
--el-dialog-padding-primary: 0; // --el-dialog-padding-primary: 0; //

@ -62,7 +62,8 @@ defineOptions({
name: 'TitleBar' name: 'TitleBar'
}) })
interface Emits { interface Emits {
(e: 'setting'): void (e: 'setting'): void;
(e: 'open-log'): void;
} }
const emit = defineEmits<Emits>() const emit = defineEmits<Emits>()
@ -76,6 +77,7 @@ const handleMenuClick = (command) => {
switch (command) { switch (command) {
case 'log': case 'log':
// //
emit('open-log')
break break
case 'communication': case 'communication':
// //

@ -0,0 +1,106 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-08 14:15:11
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-08 14:59:03
* @FilePath: \Robot-Al-Platform-Web\src\renderer\src\views\Design\LogManagement\logList.vue
* @Description: 日志服务
-->
<template>
<DSDialog
v-model="show"
width="800"
@close="handleClose"
class="logList-dialog ds-dialog"
title="日志"
>
<div class="logList-container">
<ul class="logList-sidebar">
<li
class="flex items-center justify-center sidebar-item"
:class="{ active: activeTab.includes(v.value) }"
@click="addSearchType(v)"
v-for="(v, k) in logSearchTypes"
:key="k"
>
<DSButton
:type="activeTab.includes(v.value) ? 'primary' : ''"
size="default"
class="mr-[24px] mb-[24px]"
>{{ v.label }}</DSButton
>
</li>
</ul>
<!-- //TODO -->
</div>
</DSDialog>
</template>
<script setup lang="ts">
import { DSButton } from '@/components/Button'
import { DSDialog } from '@/components/Dialog'
interface logSearchTypeItem {
label: string
value: string //
}
interface Props {
/** 弹窗显隐 */
value: boolean
}
interface Emits {
(e: 'update:value', val: boolean): void
}
const props = withDefaults(defineProps<Props>(), {
value: false
})
const emit = defineEmits<Emits>()
//
const handleClose = () => {
// emits('close');
}
const show = computed({
get() {
return props.value
},
set(val: boolean) {
emit('update:value', val)
}
})
const logSearchTypes: logSearchTypeItem[] = [
{
label: '全部',
value: '0'
},
{
label: '告警',
value: '1'
},
{
label: '错误',
value: '2'
},
{
label: '信息',
value: '3'
}
]
const activeTab = ref<string[]>(['0'])
const addSearchType = (v: logSearchTypeItem) => {
if (activeTab.value.includes(v.value)) {
activeTab.value = activeTab.value.filter((item) => item !== v.value)
} else {
activeTab.value.push(v.value)
}
}
</script>
<style>
@import url('./logList.scss');
</style>

@ -1,49 +0,0 @@
<el-dialog
align-center
v-model="showPermissionDialog"
width="520"
@close="showPermissionDialog = false"
class="settings-dialog ds-dialog"
>
<template #header="{ close, titleId, titleClass }">
<div class="flex items-center justify-between h-full dialog-header pl-[24px]">
<p class="overflow-hidden whitespace-nowrap text-ellipsis">权限分配</p>
</div>
</template>
<div class="p-[24px]">
<el-form
style="max-width: 472px"
:model="permissionFromData"
label-width="auto"
label-position="top"
size="default"
>
<el-form-item label="选择开放给技术员的工具权限" prop="pass">
<el-checkbox label="所有权限"></el-checkbox>
<!-- <el-checkbox
v-model="checkAll"
:indeterminate="isIndeterminate"
@change="handleCheckAllChange"
>
</el-checkbox> -->
<!-- @change="handleCheckedPermissionChange" -->
<!-- // TODO 和UI图调整一致 -->
<el-checkbox-group v-model="permissionFromData.permission">
<el-checkbox
v-for="v in ['权限1', '权限2', '权限3', '权限4', '权限5']"
:key="v"
:label="v"
:value="v"
>
</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
</div>
<template #footer>
<div class="dialog-footer mr-[24px] pb-[24px] pt-[16px]">
<DSButton type="info" @click="resetPermission()" class="mr-[8px]">取消</DSButton>
<DSButton type="primary" @click="submitPermission()" class="">确定</DSButton>
</div>
</template>
</el-dialog>

@ -1,9 +1,6 @@
.settings-dialog { .settings-dialog {
/* Your dialog styles */ /* Your dialog styles */
// background-color: #363940 !important;
background-color: #2d3a4b;
color: #fff;
.settings-container { .settings-container {
display: flex; display: flex;
min-height: 632px; min-height: 632px;
@ -27,21 +24,14 @@
align-items: center; align-items: center;
margin-bottom: 16px; margin-bottom: 16px;
opacity: 0.3; opacity: 0.3;
color: #fff;
&.active { &.active {
opacity: 1; opacity: 1;
} }
} }
// .sidebar-item:hover,
// .sidebar-item.active {
// background-color: #3c4b64;
// }
.settings-content { .settings-content {
flex: 1; flex: 1;
padding: 24px 24px 12px; padding: 24px 24px 12px;
} }
.section { .section {

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-03 11:12:04 * @Date: 2025-07-03 11:12:04
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-08 14:04:49 * @LastEditTime: 2025-07-08 14:50:21
* @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\views\Design\Settings\setPermissions.vue * @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\views\Design\Settings\setPermissions.vue
* @Description: 设置权限 * @Description: 设置权限
--> -->
@ -65,7 +65,6 @@ interface Props {
/** 弹窗显隐 */ /** 弹窗显隐 */
value: boolean value: boolean
info: Record<string, any> info: Record<string, any>
image: any
} }
interface Emits { interface Emits {
(e: 'update:value', val: boolean): void (e: 'update:value', val: boolean): void

@ -2,14 +2,14 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-02 16:17:29 * @Date: 2025-07-02 16:17:29
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-08 14:05:57 * @LastEditTime: 2025-07-08 14:52:43
* @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\views\Design\index.vue * @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\views\Design\index.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
--> -->
<template> <template>
<div class="design-wrap"> <div class="design-wrap">
<div class="design-header"> <div class="design-header">
<HeadCtrl @setting="() => (isOpenSetting = true)" /> <HeadCtrl @setting="() => (isOpenSetting = true)" @open-log="() => (isOpenLog = true)" />
<NavCtrl /> <NavCtrl />
</div> </div>
<div class="flex design-content"> <div class="flex design-content">
@ -27,6 +27,7 @@
</div> </div>
<!-- 弹窗 --> <!-- 弹窗 -->
<SettingList v-model:value="isOpenSetting" /> <SettingList v-model:value="isOpenSetting" />
<LogList v-model:value="isOpenLog" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -37,5 +38,7 @@ import LogicFlowView from './Workflow/logicFlowView.vue'
import OutputView from './Workflow/outputView.vue' import OutputView from './Workflow/outputView.vue'
import ResultsView from './Workflow/resultsView.vue' import ResultsView from './Workflow/resultsView.vue'
import SettingList from './Settings/settingList.vue' import SettingList from './Settings/settingList.vue'
const isOpenSetting = ref<boolean>(false) import LogList from './LogManagement/logList.vue'
const isOpenSetting = ref<boolean>(false) //
const isOpenLog = ref<boolean>(false) //
</script> </script>

Loading…
Cancel
Save