refactor: 重构微应用集成和组件结构

master
钟良源 4 months ago
parent 570b2664cd
commit 1a1281bcdd

@ -9,10 +9,8 @@ import './style.css'
// 初始化 micro-app // 初始化 micro-app
microApp.start({ microApp.start({
'disable-sandbox': true, // 'disable-sandbox': true,
'disable-scopecss': true, // 'disable-scopecss': true,
// 启用虚拟路由系统,隔离子应用路由
// 这样子应用的 React Router 不会受到基座 hash 路由的影响
}) })
const app = createApp(App) const app = createApp(App)

@ -3,9 +3,9 @@
<micro-app <micro-app
iframe iframe
name="label-app" name="label-app"
v-if="baseUrl"
:url="baseUrl" :url="baseUrl"
style="display: block; width: 100%" style="display: block; width: 100%;height: 100%"
:style="{ height: config ? 'fit-content' : '' }"
@mounted="microAppMounted" @mounted="microAppMounted"
router-mode="pure" router-mode="pure"
:disable-scopecss="media_type === '视频' && !config" :disable-scopecss="media_type === '视频' && !config"
@ -206,6 +206,8 @@ onUnmounted(() => {
<style lang="less" scoped> <style lang="less" scoped>
.container-canvas { .container-canvas {
width: 100%;
height: 100%;
background-color: #fff; background-color: #fff;
overflow: auto; overflow: auto;

@ -35,7 +35,7 @@
<!-- 标签设置图片视频音频 --> <!-- 标签设置图片视频音频 -->
<div v-if="activeStep === 'labelSettings'" class="steps-micro"> <div v-if="activeStep === 'labelSettings'" class="steps-micro">
<micro-app iframe name="label-app" :url="baseUrl" style="display: block; width: 100%" @mounted="microAppMounted" /> <micro-app iframe name="label-app" :src="baseUrl" style="display: block; width: 100%;height: 100%" @mounted="microAppMounted" />
</div> </div>
<!-- 标签设置文本 --> <!-- 标签设置文本 -->

@ -3,7 +3,9 @@
<div class="header"> <div class="header">
<div class="header-left"> <div class="header-left">
<div class="back-title" @click="goBack"> <div class="back-title" @click="goBack">
<el-icon style="margin-right: 6px" size="18"><ArrowLeft /></el-icon> <el-icon style="margin-right: 6px" size="18">
<ArrowLeft/>
</el-icon>
<span>{{ task.name }}</span> <span>{{ task.name }}</span>
</div> </div>
<div class="filter-buttons"> <div class="filter-buttons">
@ -22,8 +24,10 @@
</div> </div>
</div> </div>
<div class="action-buttons"> <div class="action-buttons">
<el-button v-if="task.media_type !== 'qa'" link @click="openTagConfig" :icon="Setting" style="margin-right: 10px" <el-button v-if="task.media_type !== 'qa'" link @click="openTagConfig" :icon="Setting"
>标签配置</el-button style="margin-right: 10px"
>标签配置
</el-button
> >
<el-button link @click="openExportDialog" :icon="Printer" style="margin-right: 10px">数据导出</el-button> <el-button link @click="openExportDialog" :icon="Printer" style="margin-right: 10px">数据导出</el-button>
<el-button type="primary" @click="startMarking"></el-button> <el-button type="primary" @click="startMarking"></el-button>
@ -64,7 +68,8 @@
<el-table-column label="数据预览"> <el-table-column label="数据预览">
<template #default="scope"> <template #default="scope">
<audio v-if="task.media_type === 'audio'" :src="scope.row.previewUrl" controls></audio> <audio v-if="task.media_type === 'audio'" :src="scope.row.previewUrl" controls></audio>
<video v-else-if="task.media_type === 'video'" :src="scope.row.previewUrl" controls style="height: 80px"></video> <video v-else-if="task.media_type === 'video'" :src="scope.row.previewUrl" controls
style="height: 80px"></video>
<img v-else-if="task.media_type == 'image'" :src="scope.row.previewUrl" style="height: 80px"/> <img v-else-if="task.media_type == 'image'" :src="scope.row.previewUrl" style="height: 80px"/>
</template> </template>
</el-table-column> </el-table-column>
@ -77,7 +82,8 @@
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column v-if="task.media_type !== 'qa'" align="center" prop="annotated_count" label="标注数量" width="120" /> <el-table-column v-if="task.media_type !== 'qa'" align="center" prop="annotated_count" label="标注数量"
width="120"/>
</el-table> </el-table>
</div> </div>
@ -374,30 +380,36 @@ const outputSample = async (activeTxt: string) => {
padding: 20px; padding: 20px;
background-color: #ffffff; background-color: #ffffff;
border-radius: 4px; border-radius: 4px;
.header { .header {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 20px; margin-bottom: 20px;
.header-left { .header-left {
display: flex; display: flex;
gap: 60px; gap: 60px;
align-items: center; align-items: center;
.back-title { .back-title {
display: flex; display: flex;
align-items: center; align-items: center;
font-size: 18px; font-size: 18px;
cursor: pointer; cursor: pointer;
} }
.filter-buttons { .filter-buttons {
display: flex; display: flex;
gap: 15px; gap: 15px;
.btn-item { .btn-item {
padding: 5px 15px; padding: 5px 15px;
color: rgb(78 89 105 / 100%); color: rgb(78 89 105 / 100%);
cursor: pointer; cursor: pointer;
border-radius: 20px; border-radius: 20px;
transition: background-color 0.4s; transition: background-color 0.4s;
&.active { &.active {
color: rgb(22 93 255 / 100%); color: rgb(22 93 255 / 100%);
background: rgb(237 237 237 / 100%); background: rgb(237 237 237 / 100%);
@ -405,20 +417,24 @@ const outputSample = async (activeTxt: string) => {
} }
} }
} }
.action-buttons { .action-buttons {
el-button { el-button {
margin-left: 10px; margin-left: 10px;
} }
} }
} }
.table-container { .table-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
height: calc(100% - 40px); height: calc(100% - 40px);
.table-content { .table-content {
flex: 1; flex: 1;
overflow: auto; overflow: auto;
.text-ellipsis { .text-ellipsis {
display: inline-block; display: inline-block;
width: 100%; width: 100%;
@ -428,12 +444,14 @@ const outputSample = async (activeTxt: string) => {
vertical-align: middle; vertical-align: middle;
} }
} }
.pagination-box { .pagination-box {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
padding: 10px 0; padding: 10px 0;
} }
} }
.dialog-footer { .dialog-footer {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;

@ -1,25 +1,10 @@
<template> <template>
<div class="flow-app-container"> <div class="flow-app-container">
<micro-app <micro-app name="flow-app" :url="baseUrl" style="display: block; width: 100%;height:100%"/>
v-if="baseUrl"
name="flow-app"
:url="baseUrl"
iframe
style="display: block; width: 100%; height: 100%"
@created="onCreated"
@beforemount="onBeforeMount"
@mounted="onMountedHandler"
@error="onError"
/>
<div v-else class="loading-container">
<el-icon class="is-loading"><Loading /></el-icon>
<span>加载中...</span>
</div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { Loading } from '@element-plus/icons-vue';
import {useRoute} from 'vue-router'; import {useRoute} from 'vue-router';
import {useMicroApptore} from '@/stores/modules/micro-app'; import {useMicroApptore} from '@/stores/modules/micro-app';
import {ElMessage} from 'element-plus'; import {ElMessage} from 'element-plus';
@ -27,85 +12,40 @@ import microAppX from '@micro-zoe/micro-app';
import {useUserStore} from '@/stores/modules/user'; import {useUserStore} from '@/stores/modules/user';
const userStore = useUserStore(); const userStore = useUserStore();
const { getAppDetail } = useMicroApptore();
const route = useRoute();
const baseUrl = ref('');
const postData = reactive({ const postData = reactive({
userStoreData: userStore.$state userStoreData: userStore.$state
}); });
const {getAppDetail} = useMicroApptore();
// micro-app const route = useRoute();
const onCreated = () => { const baseUrl = ref('');
console.log('[flow-app] created');
};
const onBeforeMount = () => {
console.log('[flow-app] beforemount');
};
const onMountedHandler = () => {
console.log('[flow-app] mounted');
};
const onError = (e: CustomEvent) => {
console.error('[flow-app] error:', e.detail);
ElMessage.error('子应用加载失败');
};
onMounted(() => { onMounted(() => {
const agentId = route.params.id; const commonUrl = `agent/${route.params.id}`;
console.log('[flow-app] agentId:', agentId);
if (import.meta.env.VITE_USER_NODE_ENV === 'production') { if (import.meta.env.VITE_USER_NODE_ENV === 'production') {
const appUrl = getAppDetail('flow-app')?.appUrl; const appUrl = getAppDetail('flow-app')?.appUrl; // 线
if (!appUrl) { if (!appUrl) {
ElMessage.warning('微应用路径获取失败'); ElMessage({
return; message: '微应用路径获取失败'
});
} }
baseUrl.value = appUrl + 'agent/' + agentId; // 线
microAppX.setData('flow-app', { baseUrl.value = appUrl ? appUrl + commonUrl : '';
...postData, microAppX.setData('flow-app', {...postData, server_ip: location.origin, isTemplate: route.query.isTemplate}); //
server_ip: location.origin,
isTemplate: route.query.isTemplate,
agentId
});
} else { } else {
// 访 //
baseUrl.value = '/flowapp/agent/' + agentId; baseUrl.value = 'http://localhost:9222/flowapp/' + commonUrl;
console.log('[flow-app] baseUrl:', baseUrl.value); microAppX.setData('flow-app', {...postData, server_ip: undefined, isTemplate: route.query.isTemplate}); // 使
nextTick(() => {
microAppX.setData('flow-app', {
...postData,
server_ip: undefined,
isTemplate: route.query.isTemplate,
agentId
});
});
} }
}); });
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
.flow-app-container { .flow-app-container {
position: absolute;
top: 0;
left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: auto; overflow: auto;
} }
.loading-container {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
gap: 8px;
color: #909399;
font-size: 14px;
}
</style> </style>

@ -56,6 +56,7 @@
} }
.process-content { .process-content {
position: relative;
flex: 1; flex: 1;
overflow: auto; overflow: auto;
padding: 16px; padding: 16px;

Loading…
Cancel
Save