chore: 无界测试

This commit is contained in:
wangxuefeng 2025-03-17 17:38:03 +08:00
parent d55ae2e97d
commit 32db9d8175
10 changed files with 485 additions and 93 deletions

View File

@ -24,6 +24,7 @@
"@sy/unified-login": "1.0.29",
"@sy/vue3-renderer-adapter": "workspace:*",
"@sy/web-vitals": "workspace:*",
"@sy/wujie-vue3-renderer-adapter": "workspace:*",
"@vben/access": "workspace:*",
"@vben/common-ui": "workspace:*",
"@vben/constants": "workspace:*",

View File

@ -1,6 +1,6 @@
import type { RouteRecordRaw } from 'vue-router';
import RendererAdapter from '@sy/vue3-renderer-adapter';
import WujieVueRendererAdapter from '@sy/wujie-vue3-renderer-adapter';
import { VITE_RENDERER_URL } from '#/constants';
@ -17,16 +17,19 @@ const routes: RouteRecordRaw[] = [
{
path: '/static-file/list',
name: 'StaticFileList',
component: RendererAdapter,
// component: RendererAdapter,
component: WujieVueRendererAdapter,
meta: {
icon: 'ant-design:file-text',
title: '静态文件列表',
},
props: {
url: `${VITE_RENDERER_URL}/?fileId=7pfr394d6&projectId=4`,
// url: `${VITE_RENDERER_URL}/?fileId=7pfr394d6&projectId=4`,
url: `${VITE_RENDERER_URL}`,
accessToken: localStorage.getItem('y-code-access-token'),
fileId: '7pfr394d6',
projectId: '4',
name: 'y-code-renderer',
},
},
],

View File

@ -0,0 +1,188 @@
<script setup lang="ts">
import { getCurrentInstance, onMounted, ref, watch } from 'vue';
import { useQuery } from '@tanstack/vue-query';
import { jsonp, request } from '@vtj/utils';
import { createProvider } from '@vtj/web';
import { ElLoading } from 'element-plus';
import Postmate from 'postmate';
import { LowCodeService } from './service';
const test = window.$wujie?.props; // {data: xxx, methods: xxx}
console.log('test', test);
// sessionStorage
sessionStorage.clear();
//
const renderer = ref();
const lowCodeService = new LowCodeService();
const isLoading = ref(false);
const handshakeCompleted = ref(false);
const accessToken = ref('');
const urlParams = ref(parseUrlParams());
const provider = ref(null);
function parseUrlParams() {
const urlParams = new URLSearchParams(window.location.search);
const params = {
fileId: urlParams.get('fileId') || '',
projectId: Number(urlParams.get('projectId')) || -1,
applicationId: Number(urlParams.get('applicationId')) || -1,
name: urlParams.get('name') || '',
};
console.log('解析URL参数:', params);
return params;
}
// Postmate
const initPostmateHandshake = async () => {
const model = new Postmate.Model({
sayHi: (data: any) => {
console.log('sayHi', data);
},
});
return model.then((parent) => {
console.log('parent', parent);
// accessToken
accessToken.value = parent.model.accessToken || '';
sessionStorage.setItem('y-code-access-token', accessToken.value);
parent.emit('renderer-ready', 'y-code-renderer is ready');
//
if (accessToken.value) {
initRequestConfig(accessToken.value);
}
handshakeCompleted.value = true;
return accessToken.value;
});
};
//
const initRequestConfig = (token: string) => {
request.useRequest((req) => {
req.headers.set('Authorization', `Bearer ${token}`);
return req;
});
};
// -
const initLowCodeEngine = async () => {
//
if (provider.value) return provider.value;
const token =
accessToken.value || sessionStorage.getItem('y-code-access-token') || '';
if (token) {
initRequestConfig(token);
}
const { provider: lowCodeProvider, onReady } = createProvider({
nodeEnv: import.meta.env.NODE_ENV,
service: lowCodeService,
project: { id: urlParams.value.projectId },
adapter: {
request,
jsonp,
},
});
provider.value = { provider: lowCodeProvider, onReady };
return { provider: lowCodeProvider, onReady };
};
//
const getRenderComponent = async () => {
isLoading.value = true;
ElLoading.service({ text: '低代码文件加载中...' });
try {
// 1.
const { provider: lowCodeProvider, onReady } = await initLowCodeEngine();
// 3.
return new Promise<any>((resolve) => {
onReady(async () => {
const instance = getCurrentInstance();
instance?.appContext.app.use(lowCodeProvider);
try {
const renderComponent = await lowCodeProvider.getRenderComponent(
urlParams.value.fileId,
);
console.log('渲染组件获取成功');
resolve(renderComponent);
} catch (error) {
console.error('获取渲染组件失败:', error);
resolve(null);
}
});
});
} catch (error) {
console.error('获取渲染组件过程出错:', error);
return null;
} finally {
isLoading.value = false;
ElLoading.service().close();
}
};
// 使 useQuery 使
const { data: rendererComponent } = useQuery({
queryKey: ['getRenderer'],
queryFn: getRenderComponent,
enabled: false, //
});
// renderer
watch(rendererComponent, (newVal) => {
if (newVal) {
renderer.value = newVal;
console.log('渲染器组件已更新');
}
});
//
watch(handshakeCompleted, (newVal) => {
if (newVal) {
console.log('握手完成,开始获取渲染组件');
getRenderComponent().then((component) => {
if (component) {
renderer.value = component;
}
});
}
});
//
onMounted(async () => {
// 1.
await initLowCodeEngine();
// 2.
getRenderComponent().then((component) => {
if (component) {
renderer.value = component;
}
});
// 3.
initPostmateHandshake().catch((error) => {
console.warn('握手失败:', error);
});
});
</script>
<template>
<div style="padding: 20px">
<component :is="renderer" v-if="renderer" />
<div
v-else-if="!isLoading"
style="margin-top: 50px; color: red; text-align: center"
>
组件加载失败请检查控制台日志
</div>
</div>
</template>

View File

@ -5,12 +5,12 @@ import { useQuery } from '@tanstack/vue-query';
import { jsonp, request } from '@vtj/utils';
import { createProvider } from '@vtj/web';
import { ElLoading } from 'element-plus';
import { Url } from 'licia-es';
import Postmate from 'postmate';
import { LowCodeService } from './service';
console.log('Url', Url);
// wujie props
const wujieProps = window.$wujie?.props || {};
console.log('wujie props:', wujieProps);
// sessionStorage
sessionStorage.clear();
@ -19,49 +19,15 @@ sessionStorage.clear();
const renderer = ref();
const lowCodeService = new LowCodeService();
const isLoading = ref(false);
const handshakeCompleted = ref(false);
const accessToken = ref('');
const urlParams = ref(parseUrlParams());
const accessToken = ref(wujieProps.accessToken || '');
const urlParams = ref({
fileId: wujieProps.fileId || '',
projectId: Number(wujieProps.projectId) || -1,
applicationId: Number(wujieProps.applicationId) || -1,
name: wujieProps.name || '',
});
const provider = ref(null);
// URL
function parseUrlParams() {
const urlParams = new URLSearchParams(window.location.search);
const params = {
fileId: urlParams.get('fileId') || '',
projectId: Number(urlParams.get('projectId')) || -1,
applicationId: Number(urlParams.get('applicationId')) || -1,
name: urlParams.get('name') || '',
};
console.log('解析URL参数:', params);
return params;
}
// Postmate
const initPostmateHandshake = async () => {
const model = new Postmate.Model({
sayHi: (data: any) => {
console.log('sayHi', data);
},
});
return model.then((parent) => {
console.log('parent', parent);
// accessToken
accessToken.value = parent.model.accessToken || '';
sessionStorage.setItem('y-code-access-token', accessToken.value);
parent.emit('renderer-ready', 'y-code-renderer is ready');
//
if (accessToken.value) {
initRequestConfig(accessToken.value);
}
handshakeCompleted.value = true;
return accessToken.value;
});
};
//
const initRequestConfig = (token: string) => {
request.useRequest((req) => {
@ -75,10 +41,10 @@ const initLowCodeEngine = async () => {
//
if (provider.value) return provider.value;
const token =
accessToken.value || sessionStorage.getItem('y-code-access-token') || '';
const token = accessToken.value;
if (token) {
initRequestConfig(token);
sessionStorage.setItem('y-code-access-token', token);
}
const { provider: lowCodeProvider, onReady } = createProvider({
@ -104,7 +70,7 @@ const getRenderComponent = async () => {
// 1.
const { provider: lowCodeProvider, onReady } = await initLowCodeEngine();
// 3.
// 2.
return new Promise<any>((resolve) => {
onReady(async () => {
const instance = getCurrentInstance();
@ -130,7 +96,7 @@ const getRenderComponent = async () => {
}
};
// 使 useQuery 使
// 使 useQuery
const { data: rendererComponent } = useQuery({
queryKey: ['getRenderer'],
queryFn: getRenderComponent,
@ -145,34 +111,20 @@ watch(rendererComponent, (newVal) => {
}
});
//
watch(handshakeCompleted, (newVal) => {
if (newVal) {
console.log('握手完成,开始获取渲染组件');
getRenderComponent().then((component) => {
if (component) {
renderer.value = component;
}
});
}
});
//
onMounted(async () => {
// 1.
await initLowCodeEngine();
//
if (window.$wujie) {
window.$wujie.bus.$emit('ready', 'y-code-renderer is ready');
}
// 2.
//
await initLowCodeEngine();
getRenderComponent().then((component) => {
if (component) {
renderer.value = component;
}
});
// 3.
initPostmateHandshake().catch((error) => {
console.warn('握手失败:', error);
});
});
</script>

View File

@ -0,0 +1,40 @@
{
"name": "@sy/wujie-vue3-renderer-adapter",
"version": "1.0.0-alpha.1",
"description": "wujie-vue3 renderer adapter",
"private": true,
"type": "module",
"scripts": {
"build": "vite build"
},
"alias": {
"#": "./src"
},
"files": [
"dist"
],
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"unpkg": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/types/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"default": "./dist/index.mjs"
}
},
"dependencies": {
"postmate": "catalog:",
"vue": "catalog:",
"wujie-vue3": "1.0.24"
},
"devDependencies": {
"@farmfe/cli": "^1.0.4",
"@farmfe/core": "^1.7.1",
"@types/postmate": "catalog:",
"@vitejs/plugin-vue": "catalog:",
"vite-plugin-dts": "catalog:"
}
}

View File

@ -0,0 +1,62 @@
<script setup lang="ts">
import { onBeforeUnmount, onMounted } from 'vue';
import WujieVue from 'wujie-vue3';
const props = defineProps<{
accessToken?: string;
applicationId: number | string;
fileId: number | string;
name: string;
projectId: number | string;
url: string;
}>();
console.log('props', props);
const { bus } = WujieVue;
//
const subAppProps = {
accessToken: props.accessToken,
applicationId: props.applicationId,
fileId: props.fileId,
projectId: props.projectId,
};
//
const beforeLoad = (appWindow: Window) => {
console.log(`${props.name} 开始加载`, appWindow);
};
const afterMount = (appWindow: Window) => {
console.log(`${props.name} 加载完成`, appWindow);
};
//
const handleMessage = (data: any) => {
console.log('收到子应用消息:', data);
};
onMounted(() => {
bus.$on('message', handleMessage);
});
onBeforeUnmount(() => {
bus.$off('message', handleMessage);
});
</script>
<template>
<div class="low-code-adapter" style="width: 100%; height: 100%">
{{ url }}
<WujieVue width="100%" height="100%" :props="subAppProps" />
</div>
</template>
<style scoped>
.low-code-adapter {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1 @@
export { default } from './adapter.vue';

View File

@ -0,0 +1,29 @@
{
"compilerOptions": {
"target": "ESNext",
"jsx": "preserve",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment",
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"baseUrl": ".",
"module": "ESNext",
"moduleResolution": "Node",
"paths": {
"@/*": ["src/*"]
},
"resolveJsonModule": true,
"types": ["vite/client"],
"strict": true,
"useUnknownInCatchVariables": false,
"declaration": true,
"declarationDir": "dist/types",
"outDir": "dist",
"sourceMap": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"exclude": ["node_modules", "dist"]
}

View File

@ -0,0 +1,68 @@
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import vue from '@vitejs/plugin-vue';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export default defineConfig({
build: {
cssCodeSplit: true,
lib: {
entry: path.resolve(__dirname, 'src/index.ts'),
fileName: (format) => {
switch (format) {
case 'cjs': {
return 'index.cjs';
}
case 'es': {
return 'index.mjs';
}
case 'umd': {
return 'index.js';
}
default: {
return `index.${format}.js`;
}
}
},
formats: ['es', 'cjs', 'umd'],
name: 'RendererAdapter',
},
outDir: 'dist',
rollupOptions: {
external: ['vue'],
output: {
assetFileNames: (assetInfo) => {
if (assetInfo.name === 'style.css') return 'assets/[name][extname]';
return 'assets/[name]-[hash][extname]';
},
globals: {
vue: 'Vue',
},
},
},
sourcemap: true,
},
css: {
extract: false,
modules: {
localsConvention: 'camelCaseOnly',
scopeBehaviour: 'local',
},
},
plugins: [
vue({
css: {
injectCss: true,
},
}),
dts({
insertTypesEntry: true,
outDir: 'dist/types',
staticImport: true,
}),
],
});

92
pnpm-lock.yaml generated
View File

@ -759,6 +759,9 @@ importers:
'@sy/web-vitals':
specifier: workspace:*
version: link:../../packages/web-vitals
'@sy/wujie-vue3-renderer-adapter':
specifier: workspace:*
version: link:../../packages/renderer-adapter/wujie-vue3
'@vben/access':
specifier: workspace:*
version: link:../../packages/effects/access
@ -1939,6 +1942,34 @@ importers:
specifier: 'catalog:'
version: 4.5.3(@types/node@22.13.10)(rollup@4.35.0)(typescript@5.8.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.0))
packages/renderer-adapter/wujie-vue3:
dependencies:
postmate:
specifier: 'catalog:'
version: 1.5.2
vue:
specifier: ^3.5.13
version: 3.5.13(typescript@5.8.2)
wujie-vue3:
specifier: 1.0.24
version: 1.0.24(vue@3.5.13(typescript@5.8.2))
devDependencies:
'@farmfe/cli':
specifier: ^1.0.4
version: 1.0.4
'@farmfe/core':
specifier: ^1.7.1
version: 1.7.1
'@types/postmate':
specifier: 'catalog:'
version: 1.5.4
'@vitejs/plugin-vue':
specifier: 'catalog:'
version: 5.2.2(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))
vite-plugin-dts:
specifier: 'catalog:'
version: 4.5.3(@types/node@22.13.10)(rollup@4.35.0)(typescript@5.8.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(sass@1.85.1)(terser@5.39.0)(yaml@2.7.0))
packages/stores:
dependencies:
'@vben-core/preferences':
@ -4124,22 +4155,22 @@ packages:
resolution: {integrity: sha512-nmG512G8QOABsserleechwHGZxzKSAlggGf9hQX0nltvSwyKNVuB/4o6iFeG2OnjXK253r8p8eSDOZf8PgFdWw==}
engines: {node: '>= 16'}
'@intlify/message-compiler@11.0.0-rc.1':
resolution: {integrity: sha512-TGw2uBfuTFTegZf/BHtUQBEKxl7Q/dVGLoqRIdw8lFsp9g/53sYn5iD+0HxIzdYjbWL6BTJMXCPUHp9PxDTRPw==}
engines: {node: '>= 16'}
'@intlify/message-compiler@11.1.2':
resolution: {integrity: sha512-T/xbNDzi+Yv0Qn2Dfz2CWCAJiwNgU5d95EhhAEf4YmOgjCKktpfpiUSmLcBvK1CtLpPQ85AMMQk/2NCcXnNj1g==}
engines: {node: '>= 16'}
'@intlify/shared@11.0.0-rc.1':
resolution: {integrity: sha512-8tR1xe7ZEbkabTuE/tNhzpolygUn9OaYp9yuYAF4MgDNZg06C3Qny80bes2/e9/Wm3aVkPUlCw6WgU7mQd0yEg==}
'@intlify/message-compiler@12.0.0-alpha.1':
resolution: {integrity: sha512-rS1Lc99D2uaGqWxlrpGPWdgkq2Jox8xxOS9gdIRhuF2CsuJISWQmwd/TjMnWNhwv9olE0aPEBh1323a61Tfp+g==}
engines: {node: '>= 16'}
'@intlify/shared@11.1.2':
resolution: {integrity: sha512-dF2iMMy8P9uKVHV/20LA1ulFLL+MKSbfMiixSmn6fpwqzvix38OIc7ebgnFbBqElvghZCW9ACtzKTGKsTGTWGA==}
engines: {node: '>= 16'}
'@intlify/shared@12.0.0-alpha.1':
resolution: {integrity: sha512-ZZ5rtlUcEnhhFS+MTrl0V1UoN3yRninGawP3f1YituJN9217xJvpqCSLa9t8NLaVwVIxsRcq4lQe48D0SigmBg==}
engines: {node: '>= 16'}
'@intlify/unplugin-vue-i18n@6.0.3':
resolution: {integrity: sha512-9ZDjBlhUHtgjRl23TVcgfJttgu8cNepwVhWvOv3mUMRDAhjW0pur1mWKEUKr1I8PNwE4Gvv2IQ1xcl4RL0nG0g==}
engines: {node: '>= 18'}
@ -12930,6 +12961,14 @@ packages:
utf-8-validate:
optional: true
wujie-vue3@1.0.24:
resolution: {integrity: sha512-QDsjb6q64pfyxBbLxlVm6xbfG9iYXaiCfqhzvn3ybC630Hlzqq2N6aT5c8ByTtqPA9/g9RZ9RKhG/uwFpwhMog==}
peerDependencies:
vue: ^3.5.13
wujie@1.0.24:
resolution: {integrity: sha512-gyuDnyyYEAc8xMSSS+m6lisWe/AyG9A4W2AQRTkCETnX2fkd3ETFhEL+3bKm2OxqgfnDbfY+QeReY6e9CkKZWQ==}
xdg-basedir@5.1.0:
resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==}
engines: {node: '>=12'}
@ -15465,7 +15504,7 @@ snapshots:
'@grpc/grpc-js@1.9.15':
dependencies:
'@grpc/proto-loader': 0.7.13
'@types/node': 22.13.10
'@types/node': 20.17.24
'@grpc/proto-loader@0.7.13':
dependencies:
@ -15646,8 +15685,8 @@ snapshots:
'@intlify/bundle-utils@10.0.0(vue-i18n@11.1.2(vue@3.5.13(typescript@5.8.2)))':
dependencies:
'@intlify/message-compiler': 11.0.0-rc.1
'@intlify/shared': 11.0.0-rc.1
'@intlify/message-compiler': 12.0.0-alpha.1
'@intlify/shared': 12.0.0-alpha.1
acorn: 8.14.1
escodegen: 2.1.0
estree-walker: 2.0.2
@ -15663,20 +15702,20 @@ snapshots:
'@intlify/message-compiler': 11.1.2
'@intlify/shared': 11.1.2
'@intlify/message-compiler@11.0.0-rc.1':
dependencies:
'@intlify/shared': 11.0.0-rc.1
source-map-js: 1.2.1
'@intlify/message-compiler@11.1.2':
dependencies:
'@intlify/shared': 11.1.2
source-map-js: 1.2.1
'@intlify/shared@11.0.0-rc.1': {}
'@intlify/message-compiler@12.0.0-alpha.1':
dependencies:
'@intlify/shared': 12.0.0-alpha.1
source-map-js: 1.2.1
'@intlify/shared@11.1.2': {}
'@intlify/shared@12.0.0-alpha.1': {}
'@intlify/unplugin-vue-i18n@6.0.3(@vue/compiler-dom@3.5.13)(eslint@9.22.0(jiti@2.4.2))(rollup@4.35.0)(typescript@5.8.2)(vue-i18n@11.1.2(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2))':
dependencies:
'@eslint-community/eslint-utils': 4.5.1(eslint@9.22.0(jiti@2.4.2))
@ -16775,11 +16814,11 @@ snapshots:
'@types/connect@3.4.38':
dependencies:
'@types/node': 22.13.10
'@types/node': 20.17.24
'@types/conventional-commits-parser@5.0.1':
dependencies:
'@types/node': 22.13.10
'@types/node': 20.17.24
'@types/css-font-loading-module@0.0.7': {}
@ -16811,13 +16850,13 @@ snapshots:
'@types/http-proxy@1.17.16':
dependencies:
'@types/node': 22.13.10
'@types/node': 20.17.24
'@types/json-schema@7.0.15': {}
'@types/jsonfile@6.1.4':
dependencies:
'@types/node': 22.13.10
'@types/node': 20.17.24
'@types/linkify-it@5.0.0': {}
@ -16895,7 +16934,7 @@ snapshots:
'@types/send@0.17.4':
dependencies:
'@types/mime': 1.3.5
'@types/node': 22.13.10
'@types/node': 20.17.24
'@types/serve-static@1.15.7':
dependencies:
@ -19251,7 +19290,7 @@ snapshots:
dependencies:
is-arguments: 1.2.0
is-date-object: 1.1.0
is-regex: 1.1.4
is-regex: 1.2.1
object-is: 1.1.6
object-keys: 1.1.1
regexp.prototype.flags: 1.5.4
@ -23303,7 +23342,7 @@ snapshots:
'@protobufjs/path': 1.1.2
'@protobufjs/pool': 1.1.0
'@protobufjs/utf8': 1.1.0
'@types/node': 22.13.10
'@types/node': 20.17.24
long: 5.3.1
proxy-from-env@1.1.0: {}
@ -26088,6 +26127,15 @@ snapshots:
ws@8.18.1: {}
wujie-vue3@1.0.24(vue@3.5.13(typescript@5.8.2)):
dependencies:
vue: 3.5.13(typescript@5.8.2)
wujie: 1.0.24
wujie@1.0.24:
dependencies:
'@babel/runtime': 7.26.10
xdg-basedir@5.1.0: {}
xe-utils@3.7.4: {}