fix: 修复管理端前端 lint 与构建问题

- 收敛 easyflow-ui-admin 的 lint、格式和类型问题

- 修正 demo 页面与管理端前端构建失败点

- 验证 pnpm lint 与 pnpm build 均已通过
This commit is contained in:
2026-04-05 21:39:13 +08:00
parent bb72e19c84
commit 7e7c236c2a
240 changed files with 5151 additions and 4701 deletions

View File

@@ -1,5 +1,5 @@
module.exports = {
"rules": {
"@typescript-eslint/no-explicit-any": ["off"],
}
rules: {
'@typescript-eslint/no-explicit-any': ['off'],
},
};

View File

@@ -1,17 +1,17 @@
<template>
<div ref="divRef" :class="['tinyflow', className]" :style="style" />
<div ref="divRef" :class="['tinyflow', className]" :style="style" />
</template>
<script setup lang="ts">
import {Tinyflow as TinyflowNative, TinyflowOptions} from '@tinyflow-ai/ui';
import { Tinyflow as TinyflowNative, TinyflowOptions } from '@tinyflow-ai/ui';
import '@tinyflow-ai/ui/dist/index.css';
import {onMounted, onUnmounted, ref, watch} from 'vue';
import { onMounted, onUnmounted, ref, watch } from 'vue';
const props = defineProps<
{
className?: string;
style?: Record<string, string>;
} & Omit<TinyflowOptions, 'element'>
{
className?: string;
style?: Record<string, string>;
} & Omit<TinyflowOptions, 'element'>
>();
const divRef = ref<HTMLDivElement | null>(null);
@@ -19,78 +19,84 @@ let tinyflow: TinyflowNative | null = null;
// 安全深拷贝工具函数
function safeDeepClone<T>(obj: T): T {
if (obj === null || typeof obj !== 'object') return obj;
if (obj === null || typeof obj !== 'object') return obj;
try {
return structuredClone(obj);
} catch {
try {
return structuredClone(obj);
return JSON.parse(JSON.stringify(obj));
} catch {
try {
return JSON.parse(JSON.stringify(obj));
} catch {
console.warn('Failed to clone object, returning original (may cause issues)', obj);
return obj;
}
console.warn(
'Failed to clone object, returning original (may cause issues)',
obj,
);
return obj;
}
}
}
onMounted(() => {
if (divRef.value) {
// 净化 props.data避免响应式对象或函数污染
const cleanedProps = { ...props } as any;
if ('data' in cleanedProps && cleanedProps.data != null) {
cleanedProps.data = safeDeepClone(cleanedProps.data);
}
tinyflow = new TinyflowNative({
...cleanedProps,
element: divRef.value
});
if (divRef.value) {
// 净化 props.data避免响应式对象或函数污染
const cleanedProps = { ...props } as any;
if ('data' in cleanedProps && cleanedProps.data != null) {
cleanedProps.data = safeDeepClone(cleanedProps.data);
}
tinyflow = new TinyflowNative({
...cleanedProps,
element: divRef.value,
});
}
});
onUnmounted(() => {
if (tinyflow) {
tinyflow.destroy();
tinyflow = null;
}
if (tinyflow) {
tinyflow.destroy();
tinyflow = null;
}
});
watch(
() => props.theme,
(theme) => {
if (tinyflow) {
tinyflow.setTheme(theme || 'light');
}
() => props.theme,
(theme) => {
if (tinyflow) {
tinyflow.setTheme(theme || 'light');
}
},
);
const getData = () => {
if (tinyflow) {
return tinyflow.getData();
}
console.warn('Tinyflow instance is not initialized');
return null;
if (tinyflow) {
return tinyflow.getData();
}
console.warn('Tinyflow instance is not initialized');
return null;
};
const getInstance = () => {
if (tinyflow) {
return tinyflow;
}
console.warn('Tinyflow instance is not initialized');
return null;
if (tinyflow) {
return tinyflow;
}
console.warn('Tinyflow instance is not initialized');
return null;
};
const focusNode = async (nodeId: string, options?: { duration?: number; zoom?: number }) => {
if (tinyflow) {
return tinyflow.focusNode(nodeId, options);
}
console.warn('Tinyflow instance is not initialized');
return false;
const focusNode = async (
nodeId: string,
options?: { duration?: number; zoom?: number },
) => {
if (tinyflow) {
return tinyflow.focusNode(nodeId, options);
}
console.warn('Tinyflow instance is not initialized');
return false;
};
defineExpose({
getData,
getInstance,
focusNode
getData,
getInstance,
focusNode,
});
</script>

View File

@@ -1,4 +1,4 @@
import {createApp} from 'vue'
import App from './Tinyflow.vue'
import { createApp } from 'vue';
import App from './Tinyflow.vue';
createApp(App).mount('#app')
createApp(App).mount('#app');

View File

@@ -1,24 +1,24 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}

View File

@@ -1,4 +1,7 @@
{
"files": [],
"references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}

View File

@@ -1,24 +1,24 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "node",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Bundler mode */
"moduleResolution": "node",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
},
"include": ["vite.config.ts"]
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
}

View File

@@ -1,39 +1,39 @@
import {defineConfig} from 'vite';
import {resolve} from 'path';
import { defineConfig } from 'vite';
import { resolve } from 'path';
import vue from '@vitejs/plugin-vue';
import dts from 'vite-plugin-dts';
// https://vitejs.dev/config/
export default defineConfig({
build: {
outDir: 'dist',
emptyOutDir: true,
minify: true,
sourcemap: true,
cssCodeSplit: true,
lib: {
entry: resolve(__dirname, 'src/index.ts'),
cssFileName: 'index',
fileName: (format) => {
return format === 'umd' ? 'index.umd.js' : 'index.js';
},
formats: ['es', 'umd'],
name: 'Tinyflow'
},
rollupOptions: {
external: ['vue'], // 排除 Vue 作为外部依赖
output: {
globals: {
vue: 'Vue'
}
}
}
build: {
outDir: 'dist',
emptyOutDir: true,
minify: true,
sourcemap: true,
cssCodeSplit: true,
lib: {
entry: resolve(__dirname, 'src/index.ts'),
cssFileName: 'index',
fileName: (format) => {
return format === 'umd' ? 'index.umd.js' : 'index.js';
},
formats: ['es', 'umd'],
name: 'Tinyflow',
},
plugins: [
vue(),
dts({
rollupTypes: true,
tsconfigPath: './tsconfig.app.json'
})
]
rollupOptions: {
external: ['vue'], // 排除 Vue 作为外部依赖
output: {
globals: {
vue: 'Vue',
},
},
},
},
plugins: [
vue(),
dts({
rollupTypes: true,
tsconfigPath: './tsconfig.app.json',
}),
],
});